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 <assert.h>
#include <errno.h>
#include <fcntl.h>
#include <nuttx/fs/fs.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;
int fd2;
@ -66,6 +67,11 @@ int file_dup(FAR struct file *filep, int minfd)
/* 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,
filep2.f_pos, filep2.f_priv, minfd, false);
if (fd2 < 0)
@ -102,7 +108,7 @@ int dup(int fd)
/* Let file_dup() do the real work */
ret = file_dup(filep, 0);
ret = file_dup(filep, 0, 0);
if (ret < 0)
{
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 */
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;

View File

@ -100,6 +100,7 @@
#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_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() */

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

View File

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

View File

@ -114,7 +114,7 @@ static int psock_fifo_read(FAR struct socket *psock, FAR void *buf,
#ifdef CONFIG_NET_LOCAL_SCM
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;
struct cmsghdr *cmsg;
@ -157,7 +157,7 @@ static void local_recvctl(FAR struct local_conn_s *conn,
peer->lc_cfpcount : count;
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]);
kmm_free(peer->lc_cfps[i]);
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 &&
msg->msg_controllen > sizeof(struct cmsghdr))
{
local_recvctl(psock->s_conn, msg);
local_recvctl(psock->s_conn, msg, flags);
}
#endif /* CONFIG_NET_LOCAL_SCM */