📄 syscall.c
字号:
char * kernel_args = NULL; struct sos_process * proc; proc = sos_thread_get_current()->process; retval = sos_syscall_get7args(user_ctxt, (unsigned int*)& user_src, (unsigned int*)& srclen, (unsigned int*)& user_dst, (unsigned int*)& dstlen, (unsigned int*)& user_fstype, (unsigned int*)& mountflags, (unsigned int*)& user_args); if (SOS_OK != retval) break; if (user_src != (sos_uaddr_t)NULL) { retval = sos_memdup_from_user((sos_vaddr_t*) &kernel_src, user_src, srclen, 0); if (SOS_OK != retval) break; } retval = sos_memdup_from_user((sos_vaddr_t*) &kernel_dst, user_dst, dstlen, 0); if (SOS_OK != retval) { if (kernel_src) sos_kfree((sos_vaddr_t)kernel_src); break; } retval = sos_strndup_from_user(& kernel_fstype, user_fstype, 256, 0); if (SOS_OK != retval) { if (kernel_src) sos_kfree((sos_vaddr_t)kernel_src); sos_kfree((sos_vaddr_t)kernel_dst); break; } if (user_args != (sos_uaddr_t)NULL) { retval = sos_strndup_from_user(& kernel_args, user_args, 1024, 0); if (SOS_OK != retval) { if (kernel_src) sos_kfree((sos_vaddr_t)kernel_src); sos_kfree((sos_vaddr_t)kernel_dst); sos_kfree((sos_vaddr_t)kernel_fstype); break; } } retval = sos_fs_mount(proc, kernel_src, srclen, kernel_dst, dstlen, kernel_fstype, mountflags, kernel_args, NULL); if (kernel_src) sos_kfree((sos_vaddr_t)kernel_src); sos_kfree((sos_vaddr_t)kernel_dst); sos_kfree((sos_vaddr_t)kernel_fstype); if (kernel_args) sos_kfree((sos_vaddr_t)kernel_args); } break; case SOS_SYSCALL_ID_UMOUNT: { sos_uaddr_t user_str; sos_size_t len; char * path; struct sos_process * proc; proc = sos_thread_get_current()->process; retval = sos_syscall_get2args(user_ctxt, (unsigned int*)& user_str, (unsigned int*)& len); if (SOS_OK != retval) break; retval = sos_memdup_from_user((sos_vaddr_t*) &path, user_str, len, 0); if (SOS_OK != retval) break; retval = sos_fs_umount(proc, path, len); sos_kfree((sos_vaddr_t)path); } break; case SOS_SYSCALL_ID_SYNC: { sos_fs_sync_all_fs(); retval = SOS_OK; } break; case SOS_SYSCALL_ID_VFSTAT64: { sos_uaddr_t user_str; sos_size_t len; sos_uaddr_t user_vfstat_struct; struct sos_fs_statfs kernel_vfstat_struct; char * path; struct sos_process * proc; proc = sos_thread_get_current()->process; retval = sos_syscall_get3args(user_ctxt, (unsigned int*)& user_str, (unsigned int*)& len, (unsigned int*)& user_vfstat_struct); if (SOS_OK != retval) break; retval = sos_memdup_from_user((sos_vaddr_t*) &path, user_str, len, 0); if (SOS_OK != retval) break; retval = sos_fs_vfstat(proc, path, len, & kernel_vfstat_struct); sos_kfree((sos_vaddr_t)path); if (SOS_OK != retval) break; if (sizeof(kernel_vfstat_struct) != sos_memcpy_to_user(user_vfstat_struct, (sos_vaddr_t) & kernel_vfstat_struct, sizeof(kernel_vfstat_struct))) retval = -SOS_EFAULT; } break; case SOS_SYSCALL_ID_OPEN: { sos_uaddr_t user_str; sos_size_t len; sos_ui32_t open_flags; sos_ui32_t access_rights; char * path; struct sos_fs_opened_file * of; struct sos_process * proc; proc = sos_thread_get_current()->process; retval = sos_syscall_get4args(user_ctxt, (unsigned int*)& user_str, (unsigned int*)& len, (unsigned int*)& open_flags, (unsigned int*)& access_rights); if (SOS_OK != retval) break; retval = sos_memdup_from_user((sos_vaddr_t*) &path, user_str, len, 0); if (SOS_OK != retval) break; retval = sos_fs_open(proc, path, len, open_flags, access_rights, & of); sos_kfree((sos_vaddr_t)path); if (SOS_OK != retval) break; retval = sos_process_register_opened_file(proc, of); if (retval < 0) { sos_fs_close(of); break; } } break; case SOS_SYSCALL_ID_CLOSE: { struct sos_fs_opened_file * of; struct sos_process * proc; int fd; proc = sos_thread_get_current()->process; retval = sos_syscall_get1arg(user_ctxt, (unsigned int*)& fd); if (SOS_OK != retval) break; of = sos_process_get_opened_file(proc, fd); if (NULL == of) { retval = -SOS_EBADF; break; } retval = sos_process_unregister_opened_file(proc, fd); if (SOS_OK != retval) break; retval = sos_fs_close(of); } break; case SOS_SYSCALL_ID_READ: { struct sos_fs_opened_file * of; struct sos_process * proc; sos_uaddr_t uaddr_buf; sos_uaddr_t uaddr_buflen; sos_size_t kernel_buflen; int fd; proc = sos_thread_get_current()->process; retval = sos_syscall_get3args(user_ctxt, (unsigned int*)& fd, (unsigned int*)& uaddr_buf, (unsigned int*)& uaddr_buflen); if (SOS_OK != retval) break; /* Retrieve the value for "buflen" */ retval = sos_memcpy_from_user((sos_vaddr_t)& kernel_buflen, uaddr_buflen, sizeof(kernel_buflen)); if (sizeof(kernel_buflen) != retval) { retval = -SOS_EFAULT; break; } of = sos_process_get_opened_file(proc, fd); if (NULL == of) { retval = -SOS_EBADF; break; } /* Do the actual reading */ retval = sos_fs_read(of, uaddr_buf, & kernel_buflen); /* Send successful number of bytes read to user */ sos_memcpy_to_user(uaddr_buflen, (sos_vaddr_t)& kernel_buflen, sizeof(kernel_buflen)); } break; case SOS_SYSCALL_ID_READDIR: { struct sos_fs_opened_file * of; struct sos_process * proc; sos_uaddr_t uaddr_direntry; struct sos_fs_dirent direntry; int fd; proc = sos_thread_get_current()->process; retval = sos_syscall_get2args(user_ctxt, (unsigned int*)& fd, (unsigned int*)& uaddr_direntry); if (SOS_OK != retval) break; of = sos_process_get_opened_file(proc, fd); if (NULL == of) { retval = -SOS_EBADF; break; } /* Do the actual readdir */ retval = sos_fs_readdir(of, & direntry); if (SOS_OK != retval) break; /* Send direntry structure to user */ if (sizeof(direntry) != sos_memcpy_to_user(uaddr_direntry, (sos_vaddr_t)& direntry, sizeof(direntry))) retval = -SOS_EFAULT; } break; case SOS_SYSCALL_ID_WRITE: { struct sos_fs_opened_file * of; struct sos_process * proc; sos_uaddr_t uaddr_buf; sos_uaddr_t uaddr_buflen; sos_size_t kernel_buflen; int fd; proc = sos_thread_get_current()->process; retval = sos_syscall_get3args(user_ctxt, (unsigned int*)& fd, (unsigned int*)& uaddr_buf, (unsigned int*)& uaddr_buflen); if (SOS_OK != retval) break; /* Retrieve the value for "buflen" */ retval = sos_memcpy_from_user((sos_vaddr_t)& kernel_buflen, uaddr_buflen, sizeof(kernel_buflen)); if (sizeof(kernel_buflen) != retval) { retval = -SOS_EFAULT; break; } of = sos_process_get_opened_file(proc, fd); if (NULL == of) { retval = -SOS_EBADF; break; } /* Do the actual writing */ retval = sos_fs_write(of, uaddr_buf, & kernel_buflen); /* Send successful number of bytes written to user */ sos_memcpy_to_user(uaddr_buflen, (sos_vaddr_t)& kernel_buflen, sizeof(kernel_buflen)); } break; case SOS_SYSCALL_ID_SEEK64: { struct sos_fs_opened_file * of; struct sos_process * proc; sos_uaddr_t uaddr_offset; sos_seek_whence_t whence; sos_lsoffset_t kernel_offset, result_position; int fd; proc = sos_thread_get_current()->process; retval = sos_syscall_get3args(user_ctxt, (unsigned int*)& fd, (unsigned int*)& uaddr_offset, (unsigned int*)& whence); if (SOS_OK != retval) break; /* Retrieve the value for "buflen" */ retval = sos_memcpy_from_user((sos_vaddr_t)& kernel_offset, uaddr_offset, sizeof(kernel_offset)); if (sizeof(kernel_offset) != retval) { retval = -SOS_EFAULT; break; } of = sos_process_get_opened_file(proc, fd); if (NULL == of) { retval = -SOS_EBADF; break; } /* Do the actual seek */ retval = sos_fs_seek(of, kernel_offset, whence, & result_position); /* Send successful number of bytes written to user */ sos_memcpy_to_user(uaddr_offset, (sos_vaddr_t)& result_position, sizeof(kernel_offset)); } break; case SOS_SYSCALL_ID_FTRUNCATE64: { struct sos_fs_opened_file * of; struct sos_process * proc; sos_lsoffset_t length; int fd; proc = sos_thread_get_current()->process; retval = sos_syscall_get2args(user_ctxt, (unsigned int*)& fd, (unsigned int*)& length); if (SOS_OK != retval) break; of = sos_process_get_opened_file(proc, fd); if (NULL == of) { retval = -SOS_EBADF; break; } /* Do the actual trunc */ retval = sos_fs_ftruncate(of, length); } break; case SOS_SYSCALL_ID_FSMMAP: { sos_uaddr_t ptr_hint_uaddr; sos_uaddr_t hint_uaddr; sos_size_t length; sos_ui32_t prot; sos_ui32_t flags; int fd; sos_ui32_t offs64_hi; sos_ui32_t offs64_lo; sos_luoffset_t offset_in_resource; struct sos_fs_opened_file * of; struct sos_process * proc; proc = sos_thread_get_current()->process; retval = sos_syscall_get7args(user_ctxt, (unsigned int*)& ptr_hint_uaddr, (unsigned int*)& length, (unsigned int*)& prot, (unsigned int*)& flags, (unsigned int*)& fd, (unsigned int*)& offs64_hi, (unsigned int*)& offs64_lo); if (SOS_OK != retval) break; of = sos_process_get_opened_file(proc, fd); if (NULL == of) { retval = -SOS_EBADF; break; } /* Compute 64 bits offset value */ offset_in_resource = offs64_hi; offset_in_resource <<= 32; offset_in_resource |= offs64_lo; retval = sos_memcpy_from_user((sos_vaddr_t)& hint_uaddr, ptr_hint_uaddr, sizeof(hint_uaddr)); if (sizeof(hint_uaddr) != retval) { retval = -SOS_EFAULT; break; } retval = sos_fs_mmap(of, & hint_uaddr, length, prot, flags, offset_in_resource); if (SOS_OK == retval) { if (sizeof(hint_uaddr) != sos_memcpy_to_user(ptr_hint_uaddr, (sos_vaddr_t)& hint_uaddr, sizeof(hint_uaddr))) { sos_umem_vmm_unmap(sos_process_get_address_space(proc), hint_uaddr, length); retval = -SOS_EFAULT; } } } break; case SOS_SYSCALL_ID_FSYNC: { struct sos_fs_opened_file * of; struct sos_process * proc; int fd; proc = sos_thread_get_current()->process; retval = sos_syscall_get1arg(user_ctxt, (unsigned int*)& fd); if (SOS_OK != retval) break; of = sos_process_get_opened_file(proc, fd);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -