diff --git a/kernel/include/fs/FileDescriptor.h b/kernel/include/fs/FileDescriptor.h index 28b02a20..482c8604 100644 --- a/kernel/include/fs/FileDescriptor.h +++ b/kernel/include/fs/FileDescriptor.h @@ -55,6 +55,11 @@ struct Descriptor return m_close_on_exec; } + void set_close_on_exec(bool value) + { + m_close_on_exec = value; + } + Descriptor(const Descriptor& other); Descriptor(); diff --git a/kernel/src/sys/stdio.cpp b/kernel/src/sys/stdio.cpp index df1276d1..8b0d0c84 100644 --- a/kernel/src/sys/stdio.cpp +++ b/kernel/src/sys/stdio.cpp @@ -29,6 +29,10 @@ #define FCNTL_DUPFD 0 #define FCNTL_ISTTY 1 +#define FCNTL_GETFD 2 +#define FCNTL_SETFD 3 + +#define FD_CLOEXEC 1 void sys_fcntl(Context* context, int fd, int command, uintptr_t arg) { @@ -42,12 +46,13 @@ void sys_fcntl(Context* context, int fd, int command, uintptr_t arg) } if (command == FCNTL_DUPFD) { - if ((int)arg < 0 || (int)arg >= TASK_MAX_FDS) + int minfd = (int)arg; + if (minfd < 0 || minfd >= TASK_MAX_FDS) { context->rax = -EINVAL; return; } - int dupfd = current_task->alloc_fd_greater_than_or_equal((int)arg); + int dupfd = current_task->alloc_fd_greater_than_or_equal(minfd); if (dupfd < 0) { context->rax = -EMFILE; @@ -66,6 +71,22 @@ void sys_fcntl(Context* context, int fd, int command, uintptr_t arg) context->rax = -ENOTTY; return; } + else if (command == FCNTL_GETFD) + { + int flags = 0; + if (file->close_on_exec()) context->rax |= FD_CLOEXEC; + context->rax = flags; + return; + } + else if (command == FCNTL_SETFD) + { + int flags = (int)arg; + if (flags & FD_CLOEXEC) file->set_close_on_exec(true); + else + file->set_close_on_exec(false); + context->rax = 0; + return; + } else { context->rax = -EINVAL; diff --git a/libs/libc/include/fcntl.h b/libs/libc/include/fcntl.h index 6d27ec4b..7aeaeae1 100644 --- a/libs/libc/include/fcntl.h +++ b/libs/libc/include/fcntl.h @@ -26,6 +26,13 @@ #define F_DUPFD 0 /* Is a file descriptor a TTY? */ #define F_ISTTY 1 +/* Get the file descriptor flags. */ +#define F_GETFD 2 +/* Set the file descriptor flags. */ +#define F_SETFD 3 + +/* Close the file descriptor on a call to execve(). */ +#define FD_CLOEXEC 1 #ifdef __cplusplus extern "C"