diff --git a/fs/include/fs/fd_table.h b/fs/include/fs/fd_table.h
index 6d8a7eac..2f2db323 100644
--- a/fs/include/fs/fd_table.h
+++ b/fs/include/fs/fd_table.h
@@ -46,6 +46,7 @@ struct fd_table_s {
unsigned int max_fds;
struct file_table_s *ft_fds; /* process fd array associate with system fd */
fd_set *proc_fds;
+ fd_set *cloexec_fds;
sem_t ft_sem; /* manage access to the file table */
};
@@ -70,7 +71,7 @@ struct files_struct *dup_fd(struct files_struct *oldf);
struct files_struct *alloc_files(void);
-void delete_files(LosProcessCB *processCB, struct files_struct *files);
+void delete_files(struct files_struct *files);
struct files_struct *create_files_snapshot(const struct files_struct *oldf);
@@ -79,4 +80,10 @@ void delete_files_snapshot(struct files_struct *files);
int alloc_fd(int minfd);
void alloc_std_fd(struct fd_table_s *fdt);
+
+void FileTableLock(struct fd_table_s *fdt);
+
+void FileTableUnLock(struct fd_table_s *fdt);
+
+struct fd_table_s *GetFdTable(void);
#endif
diff --git a/fs/include/fs/fs_operation.h b/fs/include/fs/fs_operation.h
index fec8cfa6..2b99cb0b 100644
--- a/fs/include/fs/fs_operation.h
+++ b/fs/include/fs/fs_operation.h
@@ -33,6 +33,7 @@
#define FS_OPERATION_H
#include "fs/file.h"
+#include "fs/fd_table.h"
#ifdef __cplusplus
#if __cplusplus
@@ -137,6 +138,11 @@ extern int update_file_path(const char *old_path, const char *new_path);
void los_vfs_init(void);
+void CloseOnExec(struct files_struct *files);
+void SetCloexecFlag(int procFd);
+bool CheckCloexecFlag(int procFd);
+void ClearCloexecFlag(int procFd);
+
void clear_fd(int fd);
/**
@@ -304,7 +310,23 @@ extern int los_set_systime_status(BOOL b_status);
struct IATTR;
extern int chattr(const char *pathname, struct IATTR *attr);
+#define CONTINE_NUTTX_FCNTL 0XFF0F
+/**
+ * @ingroup fs
+ *
+ * @par Description:
+ * The VfsFcntl function shall manipulate file descriptor.
+ *
+ * @retval #0 On success.
+ * @retval #-1 On failure with errno set.
+ * @retval CONTINE_NUTTX_FCNTL doesn't support some cmds in VfsFcntl, needs to continue going through Nuttx vfs operation.
+ *
+ * @par Dependency:
+ *
+ * @see None
+ */
+extern int VfsFcntl(int fd, int cmd, ...);
/**
* @ingroup fs
*
diff --git a/fs/proc/os_adapt/fd_proc.c b/fs/proc/os_adapt/fd_proc.c
index 5914a324..b0ff2ba4 100644
--- a/fs/proc/os_adapt/fd_proc.c
+++ b/fs/proc/os_adapt/fd_proc.c
@@ -75,7 +75,7 @@ static void FillFdInfo(struct SeqBuf *seqBuf, struct filelist *fileList, unsigne
}
if (hasPrivilege) {
- (void)LosBufPrintf(seqBuf, "%u\t%d\t%d\t%s\n", pid, fd, sysFd, name);
+ (void)LosBufPrintf(seqBuf, "%u\t%d\t%6d <%d>\t%s\n", pid, fd, sysFd, filp->f_refcount, name);
} else {
(void)LosBufPrintf(seqBuf, "%u\t%d\t%s\n", pid, fd, name);
}
@@ -101,7 +101,7 @@ static int FdProcFill(struct SeqBuf *seqBuf, void *v)
}
pidNum = LOS_GetUsedPIDList(pidList, pidMaxNum);
hasPrivilege = true;
- (void)LosBufPrintf(seqBuf, "Pid\tFd\tSysFd\tName\n");
+ (void)LosBufPrintf(seqBuf, "%s\t%s\t%6s %s\t%s\n", "Pid", "Fd", "SysFd", "[", "Name");
} else {
pidNum = 1;
pidList = (unsigned int *)malloc(pidNum * sizeof(unsigned int));
diff --git a/fs/vfs/BUILD.gn b/fs/vfs/BUILD.gn
index 1cd4859e..441b907a 100644
--- a/fs/vfs/BUILD.gn
+++ b/fs/vfs/BUILD.gn
@@ -33,20 +33,22 @@ module_switch = defined(LOSCFG_FS_VFS)
module_name = get_path_info(rebase_path("."), "name")
kernel_module(module_name) {
sources = [
- "operation/fs_chattr.c",
- "operation/fs_check.c",
- "operation/fs_fallocate.c",
- "operation/fs_fallocate64.c",
- "operation/fs_file.c",
- "operation/fs_file_mapping.c",
- "operation/fs_init.c",
- "operation/fs_other.c",
- "operation/fs_preadv.c",
- "operation/fs_pwritev.c",
- "operation/fs_readv.c",
- "operation/fs_utime.c",
- "operation/fs_writev.c",
"operation/fullpath.c",
+ "operation/vfs_chattr.c",
+ "operation/vfs_check.c",
+ "operation/vfs_cloexec.c",
+ "operation/vfs_fallocate.c",
+ "operation/vfs_fallocate64.c",
+ "operation/vfs_fcntl.c",
+ "operation/vfs_file_mapping.c",
+ "operation/vfs_init.c",
+ "operation/vfs_other.c",
+ "operation/vfs_preadv.c",
+ "operation/vfs_procfd.c",
+ "operation/vfs_pwritev.c",
+ "operation/vfs_readv.c",
+ "operation/vfs_utime.c",
+ "operation/vfs_writev.c",
"vfs_cmd/vfs_shellcmd.c",
]
diff --git a/fs/vfs/operation/fs_chattr.c b/fs/vfs/operation/vfs_chattr.c
similarity index 100%
rename from fs/vfs/operation/fs_chattr.c
rename to fs/vfs/operation/vfs_chattr.c
diff --git a/fs/vfs/operation/fs_check.c b/fs/vfs/operation/vfs_check.c
similarity index 100%
rename from fs/vfs/operation/fs_check.c
rename to fs/vfs/operation/vfs_check.c
diff --git a/fs/vfs/operation/vfs_cloexec.c b/fs/vfs/operation/vfs_cloexec.c
new file mode 100644
index 00000000..0943aa7a
--- /dev/null
+++ b/fs/vfs/operation/vfs_cloexec.c
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2021-2021 Huawei Device Co., Ltd. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+#include "fs/file.h"
+#include "fs/fs_operation.h"
+#include "fs/fd_table.h"
+#include "unistd.h"
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+void CloseOnExec(struct files_struct *files)
+{
+ int sysFd;
+ if ((files == NULL) || (files->fdt == NULL)) {
+ return;
+ }
+
+ for (int i = 0; i < files->fdt->max_fds; i++) {
+ if (FD_ISSET(i, files->fdt->proc_fds) &&
+ FD_ISSET(i, files->fdt->cloexec_fds)) {
+ sysFd = DisassociateProcessFd(i);
+ close(sysFd);
+ FreeProcessFd(i);
+ }
+ }
+}
+
+void SetCloexecFlag(int procFd)
+{
+ struct fd_table_s *fdt = GetFdTable();
+ if (fdt == NULL) {
+ return;
+ }
+
+ FileTableLock(fdt);
+ FD_SET(procFd, fdt->cloexec_fds);
+ FileTableUnLock(fdt);
+ return;
+}
+
+bool CheckCloexecFlag(int procFd)
+{
+ bool isCloexec = 0;
+ struct fd_table_s *fdt = GetFdTable();
+ if (fdt == NULL) {
+ return false;
+ }
+
+ FileTableLock(fdt);
+ isCloexec = FD_ISSET(procFd, fdt->cloexec_fds);
+ FileTableUnLock(fdt);
+ return isCloexec;
+}
+
+void ClearCloexecFlag(int procFd)
+{
+ struct fd_table_s *fdt = GetFdTable();
+ if (fdt == NULL) {
+ return;
+ }
+
+ FileTableLock(fdt);
+ FD_CLR(procFd, fdt->cloexec_fds);
+ FileTableUnLock(fdt);
+ return;
+}
diff --git a/fs/vfs/operation/fs_fallocate.c b/fs/vfs/operation/vfs_fallocate.c
similarity index 100%
rename from fs/vfs/operation/fs_fallocate.c
rename to fs/vfs/operation/vfs_fallocate.c
diff --git a/fs/vfs/operation/fs_fallocate64.c b/fs/vfs/operation/vfs_fallocate64.c
similarity index 100%
rename from fs/vfs/operation/fs_fallocate64.c
rename to fs/vfs/operation/vfs_fallocate64.c
diff --git a/fs/vfs/operation/vfs_fcntl.c b/fs/vfs/operation/vfs_fcntl.c
new file mode 100644
index 00000000..11ec6b7a
--- /dev/null
+++ b/fs/vfs/operation/vfs_fcntl.c
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2021-2021 Huawei Device Co., Ltd. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+#include "fs/file.h"
+#include "fs/fd_table.h"
+#include "fs/fs_operation.h"
+#include "sys/types.h"
+#include "sys/uio.h"
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+static int FcntlDupFd(int procfd, int leastFd)
+{
+ int sysfd = GetAssociatedSystemFd(procfd);
+ if ((sysfd < 0) || (sysfd >= CONFIG_NFILE_DESCRIPTORS)) {
+ return -EBADF;
+ }
+
+ if (CheckProcessFd(leastFd) != OK) {
+ return -EINVAL;
+ }
+
+ int dupFd = AllocLowestProcessFd(leastFd);
+ if (dupFd < 0) {
+ return -EMFILE;
+ }
+
+ files_refer(sysfd);
+ AssociateSystemFd(dupFd, sysfd);
+
+ return dupFd;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+int VfsFcntl(int procfd, int cmd, ...)
+{
+ va_list ap;
+ int ret = 0;
+
+ va_start(ap, cmd);
+ switch (cmd) {
+ case F_DUPFD:
+ {
+ int arg = va_arg(ap, int);
+ ret = FcntlDupFd(procfd, arg);
+ }
+ break;
+ case F_GETFD:
+ {
+ bool isCloexec = CheckCloexecFlag(procfd);
+ ret = isCloexec ? FD_CLOEXEC : 0;
+ }
+ break;
+ case F_SETFD:
+ {
+ int oflags = va_arg(ap, int);
+ if (oflags & FD_CLOEXEC) {
+ SetCloexecFlag(procfd);
+ } else {
+ ClearCloexecFlag(procfd);
+ }
+ }
+ break;
+ default:
+ ret = CONTINE_NUTTX_FCNTL;
+ break;
+ }
+
+ va_end(ap);
+ return ret;
+}
diff --git a/fs/vfs/operation/fs_file_mapping.c b/fs/vfs/operation/vfs_file_mapping.c
similarity index 100%
rename from fs/vfs/operation/fs_file_mapping.c
rename to fs/vfs/operation/vfs_file_mapping.c
diff --git a/fs/vfs/operation/fs_init.c b/fs/vfs/operation/vfs_init.c
similarity index 100%
rename from fs/vfs/operation/fs_init.c
rename to fs/vfs/operation/vfs_init.c
diff --git a/fs/vfs/operation/fs_other.c b/fs/vfs/operation/vfs_other.c
similarity index 100%
rename from fs/vfs/operation/fs_other.c
rename to fs/vfs/operation/vfs_other.c
diff --git a/fs/vfs/operation/fs_preadv.c b/fs/vfs/operation/vfs_preadv.c
similarity index 100%
rename from fs/vfs/operation/fs_preadv.c
rename to fs/vfs/operation/vfs_preadv.c
diff --git a/fs/vfs/operation/fs_file.c b/fs/vfs/operation/vfs_procfd.c
similarity index 98%
rename from fs/vfs/operation/fs_file.c
rename to fs/vfs/operation/vfs_procfd.c
index 1e600bbb..a8d4c3ed 100644
--- a/fs/vfs/operation/fs_file.c
+++ b/fs/vfs/operation/vfs_procfd.c
@@ -37,7 +37,7 @@
#include "lwip/sockets.h"
#endif
-static void FileTableLock(struct fd_table_s *fdt)
+void FileTableLock(struct fd_table_s *fdt)
{
/* Take the semaphore (perhaps waiting) */
while (sem_wait(&fdt->ft_sem) != 0) {
@@ -49,7 +49,7 @@ static void FileTableLock(struct fd_table_s *fdt)
}
}
-static void FileTableUnLock(struct fd_table_s *fdt)
+void FileTableUnLock(struct fd_table_s *fdt)
{
int ret = sem_post(&fdt->ft_sem);
if (ret == -1) {
@@ -78,7 +78,7 @@ static int AssignProcessFd(const struct fd_table_s *fdt, int minFd)
return VFS_ERROR;
}
-static struct fd_table_s *GetFdTable(void)
+struct fd_table_s *GetFdTable(void)
{
struct fd_table_s *fdt = NULL;
struct files_struct *procFiles = OsCurrProcessGet()->files;
@@ -197,6 +197,7 @@ void FreeProcessFd(int procFd)
FileTableLock(fdt);
FD_CLR(procFd, fdt->proc_fds);
+ FD_CLR(procFd, fdt->cloexec_fds);
fdt->ft_fds[procFd].sysFd = -1;
FileTableUnLock(fdt);
}
@@ -467,6 +468,7 @@ int CloseProcFd(int procFd, unsigned int targetPid)
/* clean the fd set */
FD_CLR(procFd, fdt->proc_fds);
+ FD_CLR(procFd, fdt->cloexec_fds);
fdt->ft_fds[procFd].sysFd = -1;
if (sem_post(&semId) == -1) {
PRINTK("sem_post error, errno %d \n", get_errno());
diff --git a/fs/vfs/operation/fs_pwritev.c b/fs/vfs/operation/vfs_pwritev.c
similarity index 100%
rename from fs/vfs/operation/fs_pwritev.c
rename to fs/vfs/operation/vfs_pwritev.c
diff --git a/fs/vfs/operation/fs_readv.c b/fs/vfs/operation/vfs_readv.c
similarity index 100%
rename from fs/vfs/operation/fs_readv.c
rename to fs/vfs/operation/vfs_readv.c
diff --git a/fs/vfs/operation/fs_utime.c b/fs/vfs/operation/vfs_utime.c
similarity index 100%
rename from fs/vfs/operation/fs_utime.c
rename to fs/vfs/operation/vfs_utime.c
diff --git a/fs/vfs/operation/fs_writev.c b/fs/vfs/operation/vfs_writev.c
similarity index 100%
rename from fs/vfs/operation/fs_writev.c
rename to fs/vfs/operation/vfs_writev.c
diff --git a/fs/vfs/vnode.c b/fs/vfs/vnode.c
index 3adc7245..ae00e893 100644
--- a/fs/vfs/vnode.c
+++ b/fs/vfs/vnode.c
@@ -367,7 +367,6 @@ int VnodeLookup(const char *path, struct Vnode **result, uint32_t flags)
int ret = PreProcess(path, &startVnode, &normalizedPath);
if (ret != LOS_OK) {
- PRINT_ERR("[VFS]lookup failed, invalid path=%s err = %d\n", path, ret);
goto OUT_FREE_PATH;
}
diff --git a/kernel/base/core/los_process.c b/kernel/base/core/los_process.c
index a4bf395c..4664ac07 100644
--- a/kernel/base/core/los_process.c
+++ b/kernel/base/core/los_process.c
@@ -39,6 +39,7 @@
#include "asm/page.h"
#ifdef LOSCFG_FS_VFS
#include "fs/fd_table.h"
+#include "fs/fs_operation.h"
#endif
#include "time.h"
#include "user_copy.h"
@@ -290,7 +291,7 @@ LITE_OS_SEC_TEXT VOID OsProcessResourcesToFree(LosProcessCB *processCB)
#ifdef LOSCFG_FS_VFS
if (OsProcessIsUserMode(processCB)) {
- delete_files(processCB, processCB->files);
+ delete_files(processCB->files);
}
processCB->files = NULL;
#endif
@@ -1306,8 +1307,8 @@ LITE_OS_SEC_TEXT UINT32 OsExecRecycleAndInit(LosProcessCB *processCB, const CHAR
LOS_VmSpaceFree(oldSpace);
#ifdef LOSCFG_FS_VFS
- delete_files(OsCurrProcessGet(), (struct files_struct *)oldFiles);
- alloc_std_fd(OsCurrProcessGet()->files->fdt);
+ CloseOnExec((struct files_struct *)oldFiles);
+ delete_files_snapshot((struct files_struct *)oldFiles);
#endif
OsSwtmrRecycle(processCB->processID);
diff --git a/kernel/extended/dynload/src/los_exec_elf.c b/kernel/extended/dynload/src/los_exec_elf.c
index 44b34395..8a776fc6 100644
--- a/kernel/extended/dynload/src/los_exec_elf.c
+++ b/kernel/extended/dynload/src/los_exec_elf.c
@@ -82,7 +82,6 @@ STATIC INT32 OsGetRealPath(const CHAR *fileName, CHAR *buf, UINT32 maxLen)
return LOS_OK;
ERR_FILE:
- PRINT_ERR("No such file or directory: %s\n", fileName);
return -ENOENT;
}
#endif
diff --git a/kernel/extended/dynload/src/los_load_elf.c b/kernel/extended/dynload/src/los_load_elf.c
index f36ff3f9..20f87e5c 100644
--- a/kernel/extended/dynload/src/los_load_elf.c
+++ b/kernel/extended/dynload/src/los_load_elf.c
@@ -33,6 +33,7 @@
#include "fcntl.h"
#include "fs/fd_table.h"
#include "fs/file.h"
+#include "fs/fs_operation.h"
#include "los_config.h"
#include "los_vm_map.h"
#include "los_vm_syscall.h"
@@ -56,6 +57,10 @@ static int OsELFOpen(const CHAR *fileName, INT32 oflags)
return -EMFILE;
}
+ if (oflags & O_CLOEXEC) {
+ SetCloexecFlag(procFd);
+ }
+
ret = open(fileName, oflags);
if (ret < 0) {
FreeProcessFd(procFd);
@@ -186,7 +191,7 @@ STATIC INT32 OsReadEhdr(const CHAR *fileName, ELFInfo *elfInfo, BOOL isExecFile)
return -ENOENT;
}
- ret = OsELFOpen(fileName, O_RDONLY | O_EXECVE);
+ ret = OsELFOpen(fileName, O_RDONLY | O_EXECVE | O_CLOEXEC);
if (ret < 0) {
PRINT_ERR("%s[%d], Failed to open ELF file: %s!\n", __FUNCTION__, __LINE__, fileName);
return ret;
diff --git a/syscall/fs_syscall.c b/syscall/fs_syscall.c
index b5bd5876..7cdd7e86 100644
--- a/syscall/fs_syscall.c
+++ b/syscall/fs_syscall.c
@@ -52,7 +52,6 @@
#include "los_vm_map.h"
#include "los_memory.h"
#include "los_strncpy_from_user.h"
-#include "fs/file.h"
#include "capability_type.h"
#include "capability_api.h"
#include "sys/statfs.h"
@@ -229,29 +228,6 @@ static int UserPoll(struct pollfd *fds, nfds_t nfds, int timeout)
return ret;
}
-static int FcntlDupFd(int sysfd, void *arg)
-{
- int leastFd = (intptr_t)arg;
-
- if ((sysfd < 0) || (sysfd >= CONFIG_NFILE_DESCRIPTORS)) {
- return -EBADF;
- }
-
- if (CheckProcessFd(leastFd) != OK) {
- return -EINVAL;
- }
-
- int procFd = AllocLowestProcessFd(leastFd);
- if (procFd < 0) {
- return -EMFILE;
- }
-
- files_refer(sysfd);
- AssociateSystemFd(procFd, sysfd);
-
- return procFd;
-}
-
int SysClose(int fd)
{
int ret;
@@ -303,9 +279,8 @@ ssize_t SysWrite(int fd, const void *buf, size_t nbytes)
}
/* Process fd convert to system global fd */
- fd = GetAssociatedSystemFd(fd);
-
- ret = write(fd, buf, nbytes);
+ int sysfd = GetAssociatedSystemFd(fd);
+ ret = write(sysfd, buf, nbytes);
if (ret < 0) {
return -get_errno();
}
@@ -322,7 +297,7 @@ int SysOpen(const char *path, int oflags, ...)
if (path != NULL) {
ret = UserPathCopy(path, &pathRet);
if (ret != 0) {
- goto ERROUT_PATH_FREE;
+ return ret;
}
}
@@ -332,6 +307,10 @@ int SysOpen(const char *path, int oflags, ...)
goto ERROUT;
}
+ if (oflags & O_CLOEXEC) {
+ SetCloexecFlag(procFd);
+ }
+
if ((unsigned int)oflags & O_DIRECTORY) {
ret = do_opendir(pathRet, oflags);
} else {
@@ -357,17 +336,12 @@ int SysOpen(const char *path, int oflags, ...)
return procFd;
ERROUT:
- if (ret >= 0) {
- AssociateSystemFd(procFd, ret);
- ret = procFd;
- } else {
+ if (pathRet != NULL) {
+ (void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet);
+ }
+ if (procFd >= 0) {
FreeProcessFd(procFd);
}
-ERROUT_PATH_FREE:
- if (pathRet != NULL) {
- LOS_MemFree(OS_SYS_MEM_ADDR, pathRet);
- }
-
return ret;
}
@@ -922,13 +896,13 @@ int SysIoctl(int fd, int req, void *arg)
int SysFcntl(int fd, int cmd, void *arg)
{
/* Process fd convert to system global fd */
- fd = GetAssociatedSystemFd(fd);
+ int sysfd = GetAssociatedSystemFd(fd);
- if (cmd == F_DUPFD) {
- return FcntlDupFd(fd, arg);
+ int ret = VfsFcntl(fd, cmd, arg);
+ if (ret == CONTINE_NUTTX_FCNTL) {
+ ret = fcntl(sysfd, cmd, arg);
}
- int ret = fcntl(fd, cmd, arg);
if (ret < 0) {
return -get_errno();
}
@@ -1010,6 +984,9 @@ int SysDup2(int fd1, int fd2)
files_refer(sysfd1);
AssociateSystemFd(fd2, sysfd1);
+
+ /* if fd1 is not equal to fd2, the FD_CLOEXEC flag associated with fd2 shall be cleared */
+ ClearCloexecFlag(fd2);
return fd2;
}
@@ -1421,9 +1398,9 @@ ssize_t SysWritev(int fd, const struct iovec *iov, int iovcnt)
struct iovec *iovRet = NULL;
/* Process fd convert to system global fd */
- fd = GetAssociatedSystemFd(fd);
+ int sysfd = GetAssociatedSystemFd(fd);
if ((iov == NULL) || (iovcnt <= 0) || (iovcnt > IOV_MAX)) {
- ret = writev(fd, iov, iovcnt);
+ ret = writev(sysfd, iov, iovcnt);
return -get_errno();
}
@@ -1437,7 +1414,7 @@ ssize_t SysWritev(int fd, const struct iovec *iov, int iovcnt)
goto OUT_FREE;
}
- ret = writev(fd, iovRet, valid_iovcnt);
+ ret = writev(sysfd, iovRet, valid_iovcnt);
if (ret < 0) {
ret = -get_errno();
}
@@ -1700,6 +1677,10 @@ int SysOpenat(int dirfd, const char *path, int oflags, ...)
goto ERROUT;
}
+ if (oflags & O_CLOEXEC) {
+ SetCloexecFlag(procFd);
+ }
+
if (dirfd != AT_FDCWD) {
/* Process fd convert to system global fd */
dirfd = GetAssociatedSystemFd(dirfd);
@@ -2094,13 +2075,13 @@ int SysFstat64(int fd, struct stat64 *buf)
int SysFcntl64(int fd, int cmd, void *arg)
{
/* Process fd convert to system global fd */
- fd = GetAssociatedSystemFd(fd);
+ int sysfd = GetAssociatedSystemFd(fd);
- if (cmd == F_DUPFD) {
- return FcntlDupFd(fd, arg);
+ int ret = VfsFcntl(fd, cmd, arg);
+ if (ret == CONTINE_NUTTX_FCNTL) {
+ ret = fcntl64(sysfd, cmd, arg);
}
- int ret = fcntl64(fd, cmd, arg);
if (ret < 0) {
return -get_errno();
}
]