Kernel+LibC: Support passing O_CLOEXEC to pipe()

In the userspace, this mimics the Linux pipe2() syscall;
in the kernel, the Process::sys$pipe() now always accepts
a flags argument, the no-argument pipe() syscall is now a
userspace wrapper over pipe2().
This commit is contained in:
Sergey Bugaev 2019-08-05 15:29:05 +03:00 committed by Andreas Kling
parent 55d7810fab
commit 9c3b1ca0c6
Notes: sideshowbarker 2024-07-19 12:52:24 +09:00
5 changed files with 17 additions and 6 deletions

View file

@ -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;

View file

@ -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);

View file

@ -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:

View file

@ -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);
}

View file

@ -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);