You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by gn...@apache.org on 2020/02/20 14:20:48 UTC

[incubator-nuttx] branch master updated: fcntl: add O_CLOEXEC/FD_CLOEXEC support

This is an automated email from the ASF dual-hosted git repository.

gnutt pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git


The following commit(s) were added to refs/heads/master by this push:
     new d07afc9  fcntl: add O_CLOEXEC/FD_CLOEXEC support
d07afc9 is described below

commit d07afc934e272cbbd63e355d9e12db333b2e2978
Author: chao.an <an...@xiaomi.com>
AuthorDate: Mon Feb 3 22:21:54 2020 +0800

    fcntl: add O_CLOEXEC/FD_CLOEXEC support
---
 fs/vfs/fs_fcntl.c                  | 34 ++++++++++++++++++++++++------
 include/fcntl.h                    |  1 +
 net/socket/net_vfcntl.c            | 42 +++++++++++++++++++++++++++++---------
 net/socket/socket.h                |  2 ++
 sched/group/Make.defs              |  2 ++
 sched/group/group_setuptaskfiles.c |  8 ++++++--
 6 files changed, 71 insertions(+), 18 deletions(-)

diff --git a/fs/vfs/fs_fcntl.c b/fs/vfs/fs_fcntl.c
index e855549..cf52abd 100644
--- a/fs/vfs/fs_fcntl.c
+++ b/fs/vfs/fs_fcntl.c
@@ -113,15 +113,37 @@ int file_vfcntl(FAR struct file *filep, int cmd, va_list ap)
          * that refer to the same file.
          */
 
+        {
+          ret = filep->f_oflags & O_CLOEXEC ? FD_CLOEXEC : 0;
+        }
+        break;
+
       case F_SETFD:
-        /* Set the file descriptor flags defined in <fcntl.h>, that are associated
-         * with fd, to the third argument, arg, taken as type int. If the
-         * FD_CLOEXEC flag in the third argument is 0, the file shall remain open
-         * across the exec functions; otherwise, the file shall be closed upon
-         * successful execution of one  of  the  exec  functions.
+        /* Set the file descriptor flags defined in <fcntl.h>, that are
+         * associated with fd, to the third argument, arg, taken as type int.
+         * If the FD_CLOEXEC flag in the third argument is 0, the file shall
+         * remain open across the exec functions; otherwise, the file shall
+         * be closed upon successful execution of one of the exec functions.
          */
 
-        ret = -ENOSYS;
+        {
+          int oflags = va_arg(ap, int);
+
+          if (oflags & ~FD_CLOEXEC)
+            {
+              ret = -ENOSYS;
+              break;
+            }
+
+          if (oflags & FD_CLOEXEC)
+            {
+              filep->f_oflags |= O_CLOEXEC;
+            }
+          else
+            {
+              filep->f_oflags &= ~O_CLOEXEC;
+            }
+        }
         break;
 
       case F_GETFL:
diff --git a/include/fcntl.h b/include/fcntl.h
index 12ad7bb..82aa91b 100644
--- a/include/fcntl.h
+++ b/include/fcntl.h
@@ -66,6 +66,7 @@
 #define O_DSYNC     O_SYNC          /* Equivalent to OSYNC in NuttX */
 #define O_BINARY    (1 << 8)        /* Open the file in binary (untranslated) mode. */
 #define O_DIRECT    (1 << 9)        /* Avoid caching, write directly to hardware */
+#define O_CLOEXEC   (1 << 10)       /* Close on execute */
 
 /* Unsupported, but required open flags */
 
diff --git a/net/socket/net_vfcntl.c b/net/socket/net_vfcntl.c
index 51592d7..7b44ca3 100644
--- a/net/socket/net_vfcntl.c
+++ b/net/socket/net_vfcntl.c
@@ -110,21 +110,43 @@ int psock_vfcntl(FAR struct socket *psock, int cmd, va_list ap)
         break;
 
       case F_GETFD:
-        /* Get the file descriptor flags defined in <fcntl.h> that are associated
-         * with the file descriptor fd.  File descriptor flags are associated
-         * with a single file descriptor and do not affect other file descriptors
-         * that refer to the same file.
+        /* Get the file descriptor flags defined in <fcntl.h> that are
+         * associated with the file descriptor fd.  File descriptor flags
+         * are associated with a single file descriptor and do not affect
+         * other file descriptors that refer to the same file.
          */
 
+        {
+          ret = _SS_ISCLOEXEC(psock->s_flags) ? FD_CLOEXEC : 0;
+        }
+        break;
+
       case F_SETFD:
-        /* Set the file descriptor flags defined in <fcntl.h>, that are associated
-         * with fd, to the third argument, arg, taken as type int. If the
-         * FD_CLOEXEC flag in the third argument is 0, the file shall remain open
-         * across the exec functions; otherwise, the file shall be closed upon
-         * successful execution of one  of  the  exec  functions.
+        /* Set the file descriptor flags defined in <fcntl.h>, that are
+         * associated with fd, to the third argument, arg, taken as type int.
+         * If the FD_CLOEXEC flag in the third argument is 0, the file shall
+         * remain open across the exec functions; otherwise, the file shall
+         * be closed upon successful execution of one of the exec functions.
          */
 
-         ret = -ENOSYS; /* F_GETFD and F_SETFD not implemented */
+        {
+          int oflags = va_arg(ap, int);
+
+          if (oflags & ~FD_CLOEXEC)
+            {
+              ret = -ENOSYS;
+              break;
+            }
+
+          if (oflags & FD_CLOEXEC)
+            {
+              psock->s_flags |= _SF_CLOEXEC;
+            }
+          else
+            {
+              psock->s_flags &= ~_SF_CLOEXEC;
+            }
+         }
          break;
 
       case F_GETFL:
diff --git a/net/socket/socket.h b/net/socket/socket.h
index ee901b2..5a3cfe3 100644
--- a/net/socket/socket.h
+++ b/net/socket/socket.h
@@ -57,6 +57,7 @@
 
 /* Definitions of 8-bit socket flags */
 
+#define _SF_CLOEXEC         0x04  /* Bit 2: Close on execute */
 #define _SF_NONBLOCK        0x08  /* Bit 3: Don't block if no data (TCP/READ only) */
 #define _SF_LISTENING       0x10  /* Bit 4: SOCK_STREAM is listening */
 #define _SF_BOUND           0x20  /* Bit 5: SOCK_STREAM is bound to an address */
@@ -73,6 +74,7 @@
 
 /* Macro to manage the socket state and flags */
 
+#define _SS_ISCLOEXEC(s)    (((s) & _SF_CLOEXEC)   != 0)
 #define _SS_ISNONBLOCK(s)   (((s) & _SF_NONBLOCK)  != 0)
 #define _SS_ISLISTENING(s)  (((s) & _SF_LISTENING) != 0)
 #define _SS_ISBOUND(s)      (((s) & _SF_BOUND)     != 0)
diff --git a/sched/group/Make.defs b/sched/group/Make.defs
index a803947..d59fce3 100644
--- a/sched/group/Make.defs
+++ b/sched/group/Make.defs
@@ -76,3 +76,5 @@ endif
 
 DEPPATH += --dep-path group
 VPATH += :group
+
+CFLAGS += ${shell $(INCDIR) $(INCDIROPT) "$(CC)" $(TOPDIR)$(DELIM)net}
diff --git a/sched/group/group_setuptaskfiles.c b/sched/group/group_setuptaskfiles.c
index b632c91..21532e5 100644
--- a/sched/group/group_setuptaskfiles.c
+++ b/sched/group/group_setuptaskfiles.c
@@ -41,11 +41,13 @@
 
 #include <sched.h>
 #include <errno.h>
+#include <fcntl.h>
 
 #include <nuttx/fs/fs.h>
 #include <nuttx/net/net.h>
 
 #include "sched/sched.h"
+#include "socket/socket.h"
 #include "group/group.h"
 
 /****************************************************************************
@@ -114,7 +116,8 @@ static inline void sched_dupfiles(FAR struct task_tcb_s *tcb)
        * i-node structure.
        */
 
-      if (parent[i].f_inode)
+      if (parent[i].f_inode &&
+          (parent[i].f_oflags & O_CLOEXEC) == 0)
         {
           /* Yes... duplicate it for the child */
 
@@ -170,7 +173,8 @@ static inline void sched_dupsockets(FAR struct task_tcb_s *tcb)
        * reference count.
        */
 
-      if (parent[i].s_crefs > 0)
+      if (parent[i].s_crefs > 0 &&
+          !_SS_ISCLOEXEC(parent[i].s_flags))
         {
           /* Yes... duplicate it for the child */