vfs: Suppoprt F_DUPFD_CLOEXEC and MSG_CMSG_CLOEXEC

https://pubs.opengroup.org/onlinepubs/9699919799/functions/fcntl.html
https://linux.die.net/man/2/recvmsg

Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
This commit is contained in:
Xiang Xiao 2023-01-30 22:12:30 +08:00 committed by Petro Karashchenko
parent b026072fbe
commit d92dc45a80
6 changed files with 57 additions and 41 deletions

View File

@ -28,6 +28,7 @@
#include <sched.h> #include <sched.h>
#include <assert.h> #include <assert.h>
#include <errno.h> #include <errno.h>
#include <fcntl.h>
#include <nuttx/fs/fs.h> #include <nuttx/fs/fs.h>
#include "inode/inode.h" #include "inode/inode.h"
@ -49,7 +50,7 @@
* *
****************************************************************************/ ****************************************************************************/
int file_dup(FAR struct file *filep, int minfd) int file_dup(FAR struct file *filep, int minfd, bool cloexec)
{ {
struct file filep2; struct file filep2;
int fd2; int fd2;
@ -66,6 +67,11 @@ int file_dup(FAR struct file *filep, int minfd)
/* Then allocate a new file descriptor for the inode */ /* Then allocate a new file descriptor for the inode */
if (cloexec)
{
filep2.f_oflags |= O_CLOEXEC;
}
fd2 = file_allocate(filep2.f_inode, filep2.f_oflags, fd2 = file_allocate(filep2.f_inode, filep2.f_oflags,
filep2.f_pos, filep2.f_priv, minfd, false); filep2.f_pos, filep2.f_priv, minfd, false);
if (fd2 < 0) if (fd2 < 0)
@ -102,7 +108,7 @@ int dup(int fd)
/* Let file_dup() do the real work */ /* Let file_dup() do the real work */
ret = file_dup(filep, 0); ret = file_dup(filep, 0, 0);
if (ret < 0) if (ret < 0)
{ {
goto err; goto err;

View File

@ -71,7 +71,13 @@ static int file_vfcntl(FAR struct file *filep, int cmd, va_list ap)
{ {
/* Does not set the errno variable in the event of a failure */ /* Does not set the errno variable in the event of a failure */
ret = file_dup(filep, va_arg(ap, int)); ret = file_dup(filep, va_arg(ap, int), false);
}
break;
case F_DUPFD_CLOEXEC:
{
ret = file_dup(filep, va_arg(ap, int), true);
} }
break; break;

View File

@ -100,6 +100,7 @@
#define F_GETPATH 15 /* Get the path of the file descriptor(BSD/macOS) */ #define F_GETPATH 15 /* Get the path of the file descriptor(BSD/macOS) */
#define F_ADD_SEALS 16 /* Add the bit-mask argument arg to the set of seals of the inode */ #define F_ADD_SEALS 16 /* Add the bit-mask argument arg to the set of seals of the inode */
#define F_GET_SEALS 17 /* Get (as the function result) the current set of seals of the inode */ #define F_GET_SEALS 17 /* Get (as the function result) the current set of seals of the inode */
#define F_DUPFD_CLOEXEC 18 /* Duplicate file descriptor with close-on-exit set. */
/* For posix fcntl() and lockf() */ /* For posix fcntl() and lockf() */

View File

@ -814,7 +814,7 @@ int file_allocate(FAR struct inode *inode, int oflags, off_t pos,
* *
****************************************************************************/ ****************************************************************************/
int file_dup(FAR struct file *filep, int minfd); int file_dup(FAR struct file *filep, int minfd, bool cloexec);
/**************************************************************************** /****************************************************************************
* Name: file_dup2 * Name: file_dup2

View File

@ -108,22 +108,25 @@
* recognized by Linux, not all are supported by NuttX. * recognized by Linux, not all are supported by NuttX.
*/ */
#define MSG_OOB 0x0001 /* Process out-of-band data. */ #define MSG_OOB 0x000001 /* Process out-of-band data. */
#define MSG_PEEK 0x0002 /* Peek at incoming messages. */ #define MSG_PEEK 0x000002 /* Peek at incoming messages. */
#define MSG_DONTROUTE 0x0004 /* Don't use local routing. */ #define MSG_DONTROUTE 0x000004 /* Don't use local routing. */
#define MSG_CTRUNC 0x0008 /* Control data lost before delivery. */ #define MSG_CTRUNC 0x000008 /* Control data lost before delivery. */
#define MSG_PROXY 0x0010 /* Supply or ask second address. */ #define MSG_PROXY 0x000010 /* Supply or ask second address. */
#define MSG_TRUNC 0x0020 #define MSG_TRUNC 0x000020
#define MSG_DONTWAIT 0x0040 /* Enable nonblocking IO. */ #define MSG_DONTWAIT 0x000040 /* Enable nonblocking IO. */
#define MSG_EOR 0x0080 /* End of record. */ #define MSG_EOR 0x000080 /* End of record. */
#define MSG_WAITALL 0x0100 /* Wait for a full request. */ #define MSG_WAITALL 0x000100 /* Wait for a full request. */
#define MSG_FIN 0x0200 #define MSG_FIN 0x000200
#define MSG_SYN 0x0400 #define MSG_SYN 0x000400
#define MSG_CONFIRM 0x0800 /* Confirm path validity. */ #define MSG_CONFIRM 0x000800 /* Confirm path validity. */
#define MSG_RST 0x1000 #define MSG_RST 0x001000
#define MSG_ERRQUEUE 0x2000 /* Fetch message from error queue. */ #define MSG_ERRQUEUE 0x002000 /* Fetch message from error queue. */
#define MSG_NOSIGNAL 0x4000 /* Do not generate SIGPIPE. */ #define MSG_NOSIGNAL 0x004000 /* Do not generate SIGPIPE. */
#define MSG_MORE 0x8000 /* Sender will send more. */ #define MSG_MORE 0x008000 /* Sender will send more. */
#define MSG_CMSG_CLOEXEC 0x100000 /* Set close_on_exit for file
* descriptor received through SCM_RIGHTS.
*/
/* Protocol levels supported by get/setsockopt(): */ /* Protocol levels supported by get/setsockopt(): */

View File

@ -114,7 +114,7 @@ static int psock_fifo_read(FAR struct socket *psock, FAR void *buf,
#ifdef CONFIG_NET_LOCAL_SCM #ifdef CONFIG_NET_LOCAL_SCM
static void local_recvctl(FAR struct local_conn_s *conn, static void local_recvctl(FAR struct local_conn_s *conn,
FAR struct msghdr *msg) FAR struct msghdr *msg, int flags)
{ {
FAR struct local_conn_s *peer; FAR struct local_conn_s *peer;
struct cmsghdr *cmsg; struct cmsghdr *cmsg;
@ -157,7 +157,7 @@ static void local_recvctl(FAR struct local_conn_s *conn,
peer->lc_cfpcount : count; peer->lc_cfpcount : count;
for (i = 0; i < count; i++) for (i = 0; i < count; i++)
{ {
fds[i] = file_dup(peer->lc_cfps[i], 0); fds[i] = file_dup(peer->lc_cfps[i], 0, !!(flags & MSG_CMSG_CLOEXEC));
file_close(peer->lc_cfps[i]); file_close(peer->lc_cfps[i]);
kmm_free(peer->lc_cfps[i]); kmm_free(peer->lc_cfps[i]);
peer->lc_cfps[i] = NULL; peer->lc_cfps[i] = NULL;
@ -496,7 +496,7 @@ ssize_t local_recvmsg(FAR struct socket *psock, FAR struct msghdr *msg,
if (len >= 0 && msg->msg_control && if (len >= 0 && msg->msg_control &&
msg->msg_controllen > sizeof(struct cmsghdr)) msg->msg_controllen > sizeof(struct cmsghdr))
{ {
local_recvctl(psock->s_conn, msg); local_recvctl(psock->s_conn, msg, flags);
} }
#endif /* CONFIG_NET_LOCAL_SCM */ #endif /* CONFIG_NET_LOCAL_SCM */