uint32_t syscall_read(uint32_t fd, char* s, int len) { int count = 0; gcd_t *gcd; if (fd != FILEHANDLE_STDIN) { KERNEL_PANIC("Can only read() from standard input."); } gcd = process_get_current_process_entry()->fds[0]; count = gcd->read(gcd, s, len); return count; }
uint32_t syscall_write(uint32_t fd, char* s, int len) { int count; gcd_t *gcd; if (fd != FILEHANDLE_STDOUT) { KERNEL_PANIC("Can only write() to standard output."); } gcd = process_get_current_process_entry()->fds[1]; count = gcd->write(gcd, s, len); return count; }
void* syscall_memlimit(void* new_end){ uint32_t phys_page; interrupt_status_t intr_status; intr_status = _interrupt_disable(); spinlock_acquire(&process_table_slock); process_control_block_t *curr_proc = process_get_current_process_entry(); // checks if the new_end is NULL if (new_end == NULL){ spinlock_release(&process_table_slock); _interrupt_set_state(intr_status); return (void*)curr_proc->heap_end; } // checks if we are trying to shrink the memory, if so we error // and return NULL if ((uint32_t)new_end < curr_proc->heap_end){ spinlock_release(&process_table_slock); _interrupt_set_state(intr_status); return NULL; } // loop where we alloc the physical and the virtual memoery, we also check // if we have enough physical memory. for (uint32_t i = (curr_proc->heap_end / PAGE_SIZE +1); i <= ((uint32_t)new_end / PAGE_SIZE);i++){ // we allocate some physical memory. phys_page = physmem_allocblock(); //check if we got enough physical memory, if we do not we error if (phys_page == 0){ spinlock_release(&process_table_slock); _interrupt_set_state(intr_status); return NULL; } // maps the virtual memory vm_map(thread_get_current_thread_entry()->pagetable, phys_page, i * PAGE_SIZE, 1); } // if nothing fails we at last set heap_end to new_end curr_proc->heap_end = (uint32_t)new_end; spinlock_release(&process_table_slock); _interrupt_set_state(intr_status); return new_end; }
/** * Opens the file identified by pathname for reading and writing. A path name * is a volume name followed by a file name (for instance, [disk1]halt). * * @param pathname Full pathname to file (including mountpoint). * * @return Open file instance which must be later closed with * vfs_close. On error negative value is returned. (VFS_LIMIT, * VFS_NOT_FOUND, VFS_NO_SUCH_FS, etc.) * */ openfile_t vfs_open(const char *pathname) { openfile_t file; int fileid; char volumename[VFS_NAME_LENGTH]; char filename[VFS_NAME_LENGTH]; fs_t *fs = NULL; if (vfs_start_op() != VFS_OK) return VFS_UNUSABLE; if (vfs_parse_pathname(pathname, volumename, filename) != VFS_OK) { vfs_end_op(); return VFS_INVALID_PARAMS; } semaphore_P(vfs_table.sem); semaphore_P(openfile_table.sem); for(file=0; file<CONFIG_MAX_OPEN_FILES; file++) { if(openfile_table.files[file].filesystem == NULL) { break; } } if(file >= CONFIG_MAX_OPEN_FILES) { semaphore_V(openfile_table.sem); semaphore_V(vfs_table.sem); kprintf("VFS: Warning, maximum number of open files exceeded."); vfs_end_op(); return VFS_LIMIT; } fs = vfs_get_filesystem(volumename); if(fs == NULL) { semaphore_V(openfile_table.sem); semaphore_V(vfs_table.sem); vfs_end_op(); return VFS_NO_SUCH_FS; } openfile_table.files[file].filesystem = fs; semaphore_V(openfile_table.sem); semaphore_V(vfs_table.sem); fileid = fs->open(fs, filename); if(fileid < 0) { semaphore_P(openfile_table.sem); openfile_table.files[file].filesystem = NULL; semaphore_V(openfile_table.sem); vfs_end_op(); return fileid; /* negative -> error*/ } openfile_table.files[file].fileid = fileid; openfile_table.files[file].seek_position = 0; vfs_end_op(); process_control_block_t* process = process_get_current_process_entry(); process->open_files[process->open_files_count] = file; process->open_files_count++; return file; }