Parcourir la source

增加accept4系统调用 (#431)

LoGin il y a 1 an
Parent
commit
c47fe90440
2 fichiers modifiés avec 72 ajouts et 13 suppressions
  1. 58 1
      kernel/src/net/syscall.rs
  2. 14 12
      kernel/src/syscall/mod.rs

+ 58 - 1
kernel/src/net/syscall.rs

@@ -21,6 +21,10 @@ use super::{
     Endpoint, Protocol, ShutdownType, Socket,
 };
 
+/// Flags for socket, socketpair, accept4
+const SOCK_CLOEXEC: FileMode = FileMode::O_CLOEXEC;
+const SOCK_NONBLOCK: FileMode = FileMode::O_NONBLOCK;
+
 impl Syscall {
     /// @brief sys_socket系统调用的实际执行函数
     ///
@@ -332,6 +336,50 @@ impl Syscall {
     ///
     /// @return 成功返回新的文件描述符,失败返回错误码
     pub fn accept(fd: usize, addr: *mut SockAddr, addrlen: *mut u32) -> Result<usize, SystemError> {
+        return Self::do_accept(fd, addr, addrlen, 0);
+    }
+
+    /// sys_accept4 - accept a connection on a socket
+    ///
+    ///
+    /// If flags is 0, then accept4() is the same as accept().  The
+    ///    following values can be bitwise ORed in flags to obtain different
+    ///    behavior:
+    ///
+    /// - SOCK_NONBLOCK
+    ///     Set the O_NONBLOCK file status flag on the open file
+    ///     description (see open(2)) referred to by the new file
+    ///     descriptor.  Using this flag saves extra calls to fcntl(2)
+    ///     to achieve the same result.
+    ///
+    /// - SOCK_CLOEXEC
+    ///     Set the close-on-exec (FD_CLOEXEC) flag on the new file
+    ///     descriptor.  See the description of the O_CLOEXEC flag in
+    ///     open(2) for reasons why this may be useful.
+    pub fn accept4(
+        fd: usize,
+        addr: *mut SockAddr,
+        addrlen: *mut u32,
+        mut flags: u32,
+    ) -> Result<usize, SystemError> {
+        // 如果flags不合法,返回错误
+        if (flags & (!(SOCK_CLOEXEC | SOCK_NONBLOCK)).bits()) != 0 {
+            return Err(SystemError::EINVAL);
+        }
+
+        if SOCK_NONBLOCK != FileMode::O_NONBLOCK && ((flags & SOCK_NONBLOCK.bits()) != 0) {
+            flags = (flags & !SOCK_NONBLOCK.bits()) | FileMode::O_NONBLOCK.bits();
+        }
+
+        return Self::do_accept(fd, addr, addrlen, flags);
+    }
+
+    fn do_accept(
+        fd: usize,
+        addr: *mut SockAddr,
+        addrlen: *mut u32,
+        flags: u32,
+    ) -> Result<usize, SystemError> {
         let socket: Arc<SocketInode> = ProcessManager::current_pcb()
             .get_socket(fd as i32)
             .ok_or(SystemError::EBADF)?;
@@ -344,10 +392,19 @@ impl Syscall {
         // kdebug!("accept: new_socket={:?}", new_socket);
         // Insert the new socket into the file descriptor vector
         let new_socket: Arc<SocketInode> = SocketInode::new(new_socket);
+
+        let mut file_mode = FileMode::O_RDWR;
+        if flags & FileMode::O_NONBLOCK.bits() != 0 {
+            file_mode |= FileMode::O_NONBLOCK;
+        }
+        if flags & FileMode::O_CLOEXEC.bits() != 0 {
+            file_mode |= FileMode::O_CLOEXEC;
+        }
+
         let new_fd = ProcessManager::current_pcb()
             .fd_table()
             .write()
-            .alloc_fd(File::new(new_socket, FileMode::O_RDWR)?, None)?;
+            .alloc_fd(File::new(new_socket, file_mode)?, None)?;
         // kdebug!("accept: new_fd={}", new_fd);
         if !addr.is_null() {
             // kdebug!("accept: write remote_endpoint to user");

+ 14 - 12
kernel/src/syscall/mod.rs

@@ -336,25 +336,22 @@ pub const SYS_READ: usize = 0;
 pub const SYS_WRITE: usize = 1;
 pub const SYS_OPEN: usize = 2;
 pub const SYS_CLOSE: usize = 3;
-#[allow(dead_code)]
 pub const SYS_STAT: usize = 4;
 pub const SYS_FSTAT: usize = 5;
 
-#[allow(dead_code)]
 pub const SYS_POLL: usize = 7;
 pub const SYS_LSEEK: usize = 8;
 pub const SYS_MMAP: usize = 9;
 pub const SYS_MPROTECT: usize = 10;
+
 pub const SYS_MUNMAP: usize = 11;
 pub const SYS_BRK: usize = 12;
 pub const SYS_SIGACTION: usize = 13;
-#[allow(dead_code)]
 pub const SYS_RT_SIGPROCMASK: usize = 14;
-
 pub const SYS_RT_SIGRETURN: usize = 15;
+
 pub const SYS_IOCTL: usize = 16;
 
-#[allow(dead_code)]
 pub const SYS_WRITEV: usize = 20;
 
 pub const SYS_MADVISE: usize = 28;
@@ -404,21 +401,18 @@ pub const SYS_MKDIR: usize = 83;
 
 pub const SYS_GETTIMEOFDAY: usize = 96;
 
-#[allow(dead_code)]
+pub const SYS_GETPPID: usize = 110;
+pub const SYS_GETPGID: usize = 121;
+
 pub const SYS_SIGALTSTACK: usize = 131;
+pub const SYS_MKNOD: usize = 133;
 
-#[allow(dead_code)]
 pub const SYS_ARCH_PRCTL: usize = 158;
 
 pub const SYS_REBOOT: usize = 169;
 
-pub const SYS_GETPPID: usize = 110;
-pub const SYS_GETPGID: usize = 121;
-
 pub const SYS_GETTID: usize = 186;
 
-pub const SYS_MKNOD: usize = 133;
-
 #[allow(dead_code)]
 pub const SYS_TKILL: usize = 200;
 
@@ -433,6 +427,8 @@ pub const SYS_EXIT_GROUP: usize = 231;
 
 pub const SYS_UNLINK_AT: usize = 263;
 
+pub const SYS_ACCEPT4: usize = 288;
+
 pub const SYS_PIPE: usize = 293;
 
 #[allow(dead_code)]
@@ -921,6 +917,12 @@ impl Syscall {
             SYS_LISTEN => Self::listen(args[0], args[1]),
             SYS_SHUTDOWN => Self::shutdown(args[0], args[1]),
             SYS_ACCEPT => Self::accept(args[0], args[1] as *mut SockAddr, args[2] as *mut u32),
+            SYS_ACCEPT4 => Self::accept4(
+                args[0],
+                args[1] as *mut SockAddr,
+                args[2] as *mut u32,
+                args[3] as u32,
+            ),
             SYS_GETSOCKNAME => {
                 Self::getsockname(args[0], args[1] as *mut SockAddr, args[2] as *mut u32)
             }