Pārlūkot izejas kodu

Kernel+Userland: Give sys$recvfd() an options argument for O_CLOEXEC

@bugaevc pointed out that we shouldn't be setting this flag in
userspace, and he's right of course.
Andreas Kling 4 gadi atpakaļ
vecāks
revīzija
781d29a337

+ 1 - 1
Kernel/Process.h

@@ -347,7 +347,7 @@ public:
     int sys$get_stack_bounds(FlatPtr* stack_base, size_t* stack_size);
     int sys$ptrace(Userspace<const Syscall::SC_ptrace_params*>);
     int sys$sendfd(int sockfd, int fd);
-    int sys$recvfd(int sockfd);
+    int sys$recvfd(int sockfd, int options);
     long sys$sysconf(int name);
     int sys$disown(ProcessID);
     void* sys$allocate_tls(size_t);

+ 6 - 2
Kernel/Syscalls/sendfd.cpp

@@ -52,7 +52,7 @@ int Process::sys$sendfd(int sockfd, int fd)
     return local_socket.sendfd(*socket_description, *passing_descriptor);
 }
 
-int Process::sys$recvfd(int sockfd)
+int Process::sys$recvfd(int sockfd, int options)
 {
     REQUIRE_PROMISE(recvfd);
     auto socket_description = file_description(sockfd);
@@ -74,7 +74,11 @@ int Process::sys$recvfd(int sockfd)
     if (received_descriptor_or_error.is_error())
         return received_descriptor_or_error.error();
 
-    m_fds[new_fd].set(*received_descriptor_or_error.value(), 0);
+    u32 fd_flags = 0;
+    if (options & O_CLOEXEC)
+        fd_flags |= FD_CLOEXEC;
+
+    m_fds[new_fd].set(*received_descriptor_or_error.value(), fd_flags);
     return new_fd;
 }
 

+ 3 - 3
Userland/DevTools/UserspaceEmulator/Emulator.cpp

@@ -456,7 +456,7 @@ u32 Emulator::virt_syscall(u32 function, u32 arg1, u32 arg2, u32 arg3)
     case SC_sendfd:
         return virt$sendfd(arg1, arg2);
     case SC_recvfd:
-        return virt$recvfd(arg1);
+        return virt$recvfd(arg1, arg2);
     case SC_open:
         return virt$open(arg1);
     case SC_pipe:
@@ -563,9 +563,9 @@ int Emulator::virt$sendfd(int socket, int fd)
     return syscall(SC_sendfd, socket, fd);
 }
 
-int Emulator::virt$recvfd(int socket)
+int Emulator::virt$recvfd(int socket, int options)
 {
-    return syscall(SC_recvfd, socket);
+    return syscall(SC_recvfd, socket, options);
 }
 
 int Emulator::virt$profiling_enable(pid_t pid)

+ 1 - 1
Userland/DevTools/UserspaceEmulator/Emulator.h

@@ -171,7 +171,7 @@ private:
     int virt$ftruncate(int fd, off_t);
     mode_t virt$umask(mode_t);
     int virt$anon_create(size_t, int);
-    int virt$recvfd(int);
+    int virt$recvfd(int, int);
     int virt$sendfd(int, int);
     int virt$msyscall(FlatPtr);
 

+ 2 - 2
Userland/Libraries/LibC/sys/socket.cpp

@@ -151,9 +151,9 @@ int sendfd(int sockfd, int fd)
     __RETURN_WITH_ERRNO(rc, rc, -1);
 }
 
-int recvfd(int sockfd)
+int recvfd(int sockfd, int options)
 {
-    int rc = syscall(SC_recvfd, sockfd);
+    int rc = syscall(SC_recvfd, sockfd, options);
     __RETURN_WITH_ERRNO(rc, rc, -1);
 }
 }

+ 1 - 1
Userland/Libraries/LibC/sys/socket.h

@@ -152,7 +152,7 @@ int setsockopt(int sockfd, int level, int option, const void*, socklen_t);
 int getsockname(int sockfd, struct sockaddr*, socklen_t*);
 int getpeername(int sockfd, struct sockaddr*, socklen_t*);
 int sendfd(int sockfd, int fd);
-int recvfd(int sockfd);
+int recvfd(int sockfd, int options);
 
 // These three are non-POSIX, but common:
 #define CMSG_ALIGN(x) (((x) + sizeof(void*) - 1) & ~(sizeof(void*) - 1))

+ 1 - 5
Userland/Libraries/LibIPC/Decoder.cpp

@@ -171,15 +171,11 @@ bool Decoder::decode(Dictionary& dictionary)
 bool Decoder::decode([[maybe_unused]] File& file)
 {
 #ifdef __serenity__
-    int fd = recvfd(m_sockfd);
+    int fd = recvfd(m_sockfd, O_CLOEXEC);
     if (fd < 0) {
         dbgln("recvfd: {}", strerror(errno));
         return false;
     }
-    if (fcntl(fd, F_SETFD, FD_CLOEXEC) < 0) {
-        dbgln("fcntl(F_SETFD, FD_CLOEXEC): {}", strerror(errno));
-        return false;
-    }
     file = File(fd, File::ConstructWithReceivedFileDescriptor);
     return true;
 #else