diff options
-rw-r--r-- | Kernel/Process.cpp | 11 | ||||
-rw-r--r-- | Kernel/Process.h | 2 | ||||
-rw-r--r-- | Kernel/Syscall.cpp | 2 | ||||
-rw-r--r-- | Libraries/LibC/unistd.cpp | 7 | ||||
-rw-r--r-- | Libraries/LibC/unistd.h | 1 |
5 files changed, 17 insertions, 6 deletions
diff --git a/Kernel/Process.cpp b/Kernel/Process.cpp index a428b026ff..6e7f0f73ba 100644 --- a/Kernel/Process.cpp +++ b/Kernel/Process.cpp @@ -1194,20 +1194,25 @@ int Process::alloc_fd(int first_candidate_fd) return fd; } -int Process::sys$pipe(int pipefd[2]) +int Process::sys$pipe(int pipefd[2], int flags) { if (!validate_write_typed(pipefd)) return -EFAULT; if (number_of_open_file_descriptors() + 2 > max_open_file_descriptors()) return -EMFILE; + // Reject flags other than O_CLOEXEC. + if ((flags & O_CLOEXEC) != flags) + return -EINVAL; + + u32 fd_flags = (flags & O_CLOEXEC) ? FD_CLOEXEC : 0; auto fifo = FIFO::create(m_uid); int reader_fd = alloc_fd(); - m_fds[reader_fd].set(fifo->open_direction(FIFO::Direction::Reader)); + m_fds[reader_fd].set(fifo->open_direction(FIFO::Direction::Reader), fd_flags); pipefd[0] = reader_fd; int writer_fd = alloc_fd(); - m_fds[writer_fd].set(fifo->open_direction(FIFO::Direction::Writer)); + m_fds[writer_fd].set(fifo->open_direction(FIFO::Direction::Writer), fd_flags); pipefd[1] = writer_fd; return 0; diff --git a/Kernel/Process.h b/Kernel/Process.h index dfbbfc4771..6c94322a7f 100644 --- a/Kernel/Process.h +++ b/Kernel/Process.h @@ -168,7 +168,7 @@ public: int sys$sigpending(sigset_t*); int sys$getgroups(ssize_t, gid_t*); int sys$setgroups(ssize_t, const gid_t*); - int sys$pipe(int* pipefd); + int sys$pipe(int pipefd[2], int flags); int sys$killpg(int pgrp, int sig); int sys$setgid(gid_t); int sys$setuid(uid_t); diff --git a/Kernel/Syscall.cpp b/Kernel/Syscall.cpp index b378367ea2..48b9313a92 100644 --- a/Kernel/Syscall.cpp +++ b/Kernel/Syscall.cpp @@ -189,7 +189,7 @@ static u32 handle(RegisterDump& regs, u32 function, u32 arg1, u32 arg2, u32 arg3 case Syscall::SC_sigprocmask: return current->process().sys$sigprocmask((int)arg1, (const sigset_t*)arg2, (sigset_t*)arg3); case Syscall::SC_pipe: - return current->process().sys$pipe((int*)arg1); + return current->process().sys$pipe((int*)arg1, (int) arg2); case Syscall::SC_killpg: return current->process().sys$killpg((int)arg1, (int)arg2); case Syscall::SC_setuid: diff --git a/Libraries/LibC/unistd.cpp b/Libraries/LibC/unistd.cpp index 5d9e9bb97d..59207b097d 100644 --- a/Libraries/LibC/unistd.cpp +++ b/Libraries/LibC/unistd.cpp @@ -366,7 +366,12 @@ int getgroups(int size, gid_t list[]) int pipe(int pipefd[2]) { - int rc = syscall(SC_pipe, pipefd); + return pipe2(pipefd, 0); +} + +int pipe2(int pipefd[2], int flags) +{ + int rc = syscall(SC_pipe, pipefd, flags); __RETURN_WITH_ERRNO(rc, rc, -1); } diff --git a/Libraries/LibC/unistd.h b/Libraries/LibC/unistd.h index 567f098c82..00cedd489e 100644 --- a/Libraries/LibC/unistd.h +++ b/Libraries/LibC/unistd.h @@ -86,6 +86,7 @@ int getdtablesize(); int dup(int old_fd); int dup2(int old_fd, int new_fd); int pipe(int pipefd[2]); +int pipe2(int pipefd[2], int flags); unsigned int alarm(unsigned int seconds); int access(const char* pathname, int mode); int isatty(int fd); |