提交 0f4d5a4b 编写于 作者: O openharmony_ci 提交者: Gitee

!287 feat(vfs): vfs支持FD_CLOEXEC标记

Merge pull request !287 from MGY917/master
......@@ -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
......@@ -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.</li>
*
* @par Dependency:
* <ul><li>fs.h</li></ul>
* @see None
*/
extern int VfsFcntl(int fd, int cmd, ...);
/**
* @ingroup fs
*
......
......@@ -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", "<ref>", "Name");
} else {
pidNum = 1;
pidList = (unsigned int *)malloc(pidNum * sizeof(unsigned int));
......
......@@ -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",
]
......
/*
* 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;
}
/*
* 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;
}
......@@ -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());
......
......@@ -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;
}
......
......@@ -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);
......
......@@ -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
......
......@@ -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;
......
......@@ -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 {
FreeProcessFd(procFd);
}
ERROUT_PATH_FREE:
if (pathRet != NULL) {
LOS_MemFree(OS_SYS_MEM_ADDR, pathRet);
(void)LOS_MemFree(OS_SYS_MEM_ADDR, pathRet);
}
if (procFd >= 0) {
FreeProcessFd(procFd);
}
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();
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册