X-Git-Url: https://scm.lunaixsky.com/lunaix-os.git/blobdiff_plain/ac9c5346f3f10ac7adf3772521fa4d18f17c97c7..5be90ccccd441b1a38dbbf4fc99c7375cede8d8d:/lunaix-os/kernel/fs/vfs.c diff --git a/lunaix-os/kernel/fs/vfs.c b/lunaix-os/kernel/fs/vfs.c index de08cec..05741d8 100644 --- a/lunaix-os/kernel/fs/vfs.c +++ b/lunaix-os/kernel/fs/vfs.c @@ -478,9 +478,8 @@ __DEFINE_LXSYSCALL2(int, open, const char*, path, int, options) 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) { @@ -813,5 +812,61 @@ __DEFINE_LXSYSCALL1(int, fsync, int, fildes) 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