diff --git a/apps/src/init.c b/apps/src/init.c index dae78ecb..3746db80 100644 --- a/apps/src/init.c +++ b/apps/src/init.c @@ -63,6 +63,6 @@ int main() { msleep(100); } - if (result == child) { return 0; } + if (result == child) return 0; } } diff --git a/apps/src/sh.c b/apps/src/sh.c index ecdd536e..b783290b 100644 --- a/apps/src/sh.c +++ b/apps/src/sh.c @@ -186,7 +186,7 @@ int main() perror("getchar"); return 1; } - if (feof(stdin)) { return 0; } + if (feof(stdin)) return 0; assert(false); // we should never get here } command_concat_char(&shell_command, (char)c); diff --git a/kernel/include/sys/Syscall.h b/kernel/include/sys/Syscall.h index 6014b9f5..4428652b 100644 --- a/kernel/include/sys/Syscall.h +++ b/kernel/include/sys/Syscall.h @@ -26,6 +26,7 @@ #define SYS_pstat 21 #define SYS_getdents 22 #define SYS_stat 23 +#define SYS_dup2 24 struct stat; struct pstat; @@ -59,4 +60,5 @@ void sys_access(Context* context, const char* path, int amode); void sys_fstat(Context* context, int fd, struct stat* buf); void sys_pstat(Context* context, long pid, struct pstat* buf); void sys_getdents(Context* context, int fd, struct luna_dirent* buf, size_t count); -void sys_stat(Context* context, const char* path, struct stat* buf); \ No newline at end of file +void sys_stat(Context* context, const char* path, struct stat* buf); +void sys_dup2(Context* context, int fd, int fd2); \ No newline at end of file diff --git a/kernel/src/sys/Syscall.cpp b/kernel/src/sys/Syscall.cpp index d4271bde..925cf0c8 100644 --- a/kernel/src/sys/Syscall.cpp +++ b/kernel/src/sys/Syscall.cpp @@ -36,6 +36,7 @@ void Syscall::entry(Context* context) case SYS_getdents: sys_getdents(context, (int)context->rdi, (struct luna_dirent*)context->rsi, (size_t)context->rdx); break; + case SYS_dup2: sys_dup2(context, (int)context->rdi, (int)context->rsi); break; default: context->rax = -ENOSYS; break; } VMM::exit_syscall_context(); diff --git a/kernel/src/sys/stdio.cpp b/kernel/src/sys/stdio.cpp index 7b615988..ec806a4b 100644 --- a/kernel/src/sys/stdio.cpp +++ b/kernel/src/sys/stdio.cpp @@ -201,7 +201,7 @@ void sys_read(Context* context, int fd, size_t size, char* buffer) } int err; Descriptor* file = Scheduler::current_task()->descriptor_from_fd(fd, err); - if (!err) + if (!file) { context->rax = -err; return; @@ -270,4 +270,30 @@ void sys_access(Context* context, const char* path, int) // FIXME: Use the amode else context->rax = 0; kfree(kpath); +} + +void sys_dup2(Context* context, int fd, int fd2) +{ + int err; + Descriptor* file1 = Scheduler::current_task()->descriptor_from_fd(fd, err); + if (!file1) + { + context->rax = -err; + return; + } + if (!file1->is_open()) + { + context->rax = -EBADF; + return; + } + Descriptor* file2 = Scheduler::current_task()->descriptor_from_fd(fd2, err); + if (!file2) + { + context->rax = -err; + return; + } + if (file2->is_open()) file2->close(); + *file2 = *file1; + kinfoln("dup2(): overwrote fd %d with fd %d", fd2, fd); + context->rax = fd2; } \ No newline at end of file diff --git a/libs/libc/include/sys/syscall.h b/libs/libc/include/sys/syscall.h index 1be6f6bc..00939aa0 100644 --- a/libs/libc/include/sys/syscall.h +++ b/libs/libc/include/sys/syscall.h @@ -25,5 +25,6 @@ #define SYS_pstat 21 #define SYS_getdents 22 #define SYS_stat 23 +#define SYS_dup2 24 #endif \ No newline at end of file diff --git a/libs/libc/include/unistd.h b/libs/libc/include/unistd.h index 9e3fe966..d6e57abf 100644 --- a/libs/libc/include/unistd.h +++ b/libs/libc/include/unistd.h @@ -63,6 +63,9 @@ extern "C" /* Returns a copy of the file descriptor fd. */ int dup(int fd); + /* Causes the file descriptor fd2 to refer to the file descriptor fd. */ + int dup2(int fd, int fd2); + /* Checks if the current program can access the file or directory at path. */ int access(const char* path, int amode); diff --git a/libs/libc/src/syscall.cpp b/libs/libc/src/syscall.cpp index cb40f378..bd3e1fbe 100644 --- a/libs/libc/src/syscall.cpp +++ b/libs/libc/src/syscall.cpp @@ -25,6 +25,7 @@ extern "C" long syscall(long number, ...) case SYS_access: case SYS_fstat: case SYS_stat: + case SYS_dup2: case SYS_pstat: case SYS_open: { arg arg0 = va_arg(ap, arg); diff --git a/libs/libc/src/unistd.cpp b/libs/libc/src/unistd.cpp index 4d08d28a..a0955254 100644 --- a/libs/libc/src/unistd.cpp +++ b/libs/libc/src/unistd.cpp @@ -73,6 +73,11 @@ extern "C" return fcntl(fd, F_DUPFD, 0); } + int dup2(int fd, int fd2) + { + return (int)syscall(SYS_dup2, fd, fd2); + } + int access(const char* path, int amode) { return (int)syscall(SYS_access, path, amode);