+ 内存管理与按需分页(Demand Paging)
+ 键盘输入
+ 多进程
-+ 31个常见的Linux/POSIX系统调用([附录1](#appendix1))
++ 33个常见的Linux/POSIX系统调用([附录1](#appendix1))
+ 用户模式
+ 信号机制
+ PCI 3.0
2. `unlinkat(2)`
2. `link(2)`
2. `fsync(2)`
+2. `dup(2)`
+2. `dup2(2)`
### LunaixOS自有
{
struct v_file* file;
int pos;
+ int flags;
};
struct v_inode
__LXSYSCALL1(int, close, int, fd)
+__LXSYSCALL2(int, dup2, int, oldfd, int, newfd)
+
+__LXSYSCALL1(int, dup, int, oldfd)
+
+__LXSYSCALL1(int, fsync, int, fildes)
+
#endif /* __LUNAIX_UNISTD_H */
#define __SYSCALL__exit 8
#define __SYSCALL_wait 9
#define __SYSCALL_waitpid 10
+
#define __SYSCALL_sigreturn 11
#define __SYSCALL_sigprocmask 12
#define __SYSCALL_signal 13
#define __SYSCALL_alarm 16
#define __SYSCALL_sigpending 17
#define __SYSCALL_sigsuspend 18
-
#define __SYSCALL_open 19
#define __SYSCALL_close 20
+
#define __SYSCALL_read 21
#define __SYSCALL_write 22
#define __SYSCALL_readdir 23
#define __SYSCALL_readlink 27
#define __SYSCALL_readlinkat 28
#define __SYSCALL_rmdir 29
+
#define __SYSCALL_unlink 30
#define __SYSCALL_unlinkat 31
#define __SYSCALL_link 32
#define __SYSCALL_fsync 33
+#define __SYSCALL_dup 34
+#define __SYSCALL_dup2 35
#define __SYSCALL_MAX 0x100
.long __lxsys_unlinkat
.long __lxsys_link
.long __lxsys_fsync
+ .long __lxsys_dup
+ .long __lxsys_dup2
2:
.rept __SYSCALL_MAX - (2b - 1b)/4
.long 0
return DO_STATUS(errno);
}
-
-#define GET_FD(fd, fd_s) \
- (fd >= 0 && fd < VFS_MAX_FD && (fd_s = __current->fdtable->fds[fd]))
+#define TEST_FD(fd) (fd >= 0 && fd < VFS_MAX_FD)
+#define GET_FD(fd, fd_s) (TEST_FD(fd) && (fd_s = __current->fdtable->fds[fd]))
__DEFINE_LXSYSCALL1(int, close, int, fd)
{
errno = vfs_fsync(fd_s->file);
}
+ return DO_STATUS(errno);
+}
+
+int
+__vfs_dup_fd(struct v_fd* old, struct v_fd** new)
+{
+ int errno = 0;
+ struct v_file* newopened;
+ if (!(errno = vfs_open(old->file->dnode, &newopened))) {
+ *new = cake_grab(fd_pile);
+ **new = (struct v_fd){ .file = newopened,
+ .pos = old->pos,
+ .flags = old->flags };
+ }
+
+ return errno;
+}
+
+__DEFINE_LXSYSCALL2(int, dup2, int, oldfd, int, newfd)
+{
+ if (newfd == oldfd) {
+ return newfd;
+ }
+
+ int errno;
+ struct v_fd *oldfd_s, *newfd_s;
+ if (!GET_FD(oldfd, oldfd_s) || TEST_FD(newfd)) {
+ errno = EBADF;
+ goto done;
+ }
+ newfd_s = __current->fdtable->fds[newfd];
+ if (newfd_s && (errno = vfs_close(newfd_s))) {
+ goto done;
+ }
+
+ if (!(errno = __vfs_dup_fd(oldfd_s, &newfd_s))) {
+ __current->fdtable->fds[newfd] = newfd_s;
+ return newfd;
+ }
+
+done:
+ return DO_STATUS(errno);
+}
+
+__DEFINE_LXSYSCALL1(int, dup, int, oldfd)
+{
+ int errno, newfd;
+ struct v_fd *oldfd_s, *newfd_s;
+ if (!GET_FD(oldfd, oldfd_s)) {
+ errno = EBADF;
+ } else if (!(errno = vfs_alloc_fdslot(&newfd)) &&
+ !(errno = __vfs_dup_fd(oldfd_s, &newfd_s))) {
+ __current->fdtable->fds[newfd] = newfd_s;
+ return newfd;
+ }
+
return DO_STATUS(errno);
}
\ No newline at end of file
pcb->intr_ctx = __current->intr_ctx;
pcb->parent = __current;
+ memcpy(pcb->fdtable, __current->fdtable, sizeof(struct v_fdtable));
region_copy(&__current->mm.regions, &pcb->mm.regions);
setup_proc_mem(pcb, PD_REFERENCED);
proc->state = PS_DESTROY;
llist_delete(&proc->siblings);
+ for (size_t i = 0; i < VFS_MAX_FD; i++) {
+ struct v_fd* fd = proc->fdtable->fds[i];
+ if (fd)
+ vfs_close(fd);
+ }
+
+ vfree(proc->fdtable);
+
struct mm_region *pos, *n;
llist_for_each(pos, n, &proc->mm.regions.head, head)
{