diff --git a/fs/include/fs/fd_table.h b/fs/include/fs/fd_table.h index ba98fee4600fc45e7e052985e40f562ae06d53db..6d8a7eac3f3d2053c54a6ff2221da7f87df87f71 100644 --- a/fs/include/fs/fd_table.h +++ b/fs/include/fs/fd_table.h @@ -64,6 +64,8 @@ typedef struct ProcessCB LosProcessCB; void files_refer(int fd); +int files_close_internal(int fd, LosProcessCB *processCB); + struct files_struct *dup_fd(struct files_struct *oldf); struct files_struct *alloc_files(void); diff --git a/fs/vfs/include/operation/fs_file.h b/fs/vfs/include/operation/fs_file.h index 8b8f32390e708eb9af5bbdeffde1c645b9c2c2cb..3bfe1df0b2dbb0b0d2602cd468285140f7e1c566 100644 --- a/fs/vfs/include/operation/fs_file.h +++ b/fs/vfs/include/operation/fs_file.h @@ -54,4 +54,8 @@ int CheckProcessFd(int procFd); void FreeProcessFd(int procFd); +int CopyFdToProc(int fd, unsigned int targetPid); + +int CloseProcFd(int fd, unsigned int targetPid); + #endif diff --git a/fs/vfs/operation/fs_file.c b/fs/vfs/operation/fs_file.c index 9b47648d2b8da0b512960666f60f8fa296da63d7..96e66779d94c32cc758b1911dc69fd8a4709b1be 100644 --- a/fs/vfs/operation/fs_file.c +++ b/fs/vfs/operation/fs_file.c @@ -34,6 +34,10 @@ #include "fs/fd_table.h" #include "fs/file.h" #include "fs/fs.h" +#include "mqueue.h" +#ifdef LOSCFG_NET_LWIP_SACK +#include "lwip/sockets.h" +#endif static void FileTableLock(struct fd_table_s *fdt) { @@ -247,7 +251,7 @@ int AllocLowestProcessFd(int minFd) return VFS_ERROR; } - // occupy the fd set + /* occupy the fd set */ FD_SET(procFd, fdt->proc_fds); FileTableUnLock(fdt); @@ -275,7 +279,7 @@ int AllocAndAssocProcessFd(int sysFd, int minFd) return VFS_ERROR; } - // occupy the fd set + /* occupy the fd set */ FD_SET(procFd, fdt->proc_fds); fdt->ft_fds[procFd].sysFd = sysFd; FileTableUnLock(fdt); @@ -303,3 +307,174 @@ int AllocAndAssocSystemFd(int procFd, int minFd) return sysFd; } +static void FdRefer(int sysFd) +{ + if ((sysFd > STDERR_FILENO) && (sysFd < CONFIG_NFILE_DESCRIPTORS)) { + files_refer(sysFd); + } +#if defined(LOSCFG_NET_LWIP_SACK) + if ((sysFd >= CONFIG_NFILE_DESCRIPTORS) && (sysFd < (CONFIG_NFILE_DESCRIPTORS + CONFIG_NSOCKET_DESCRIPTORS))) { + socks_refer(sysFd); + } +#endif +#if defined(LOSCFG_COMPAT_POSIX) + if ((sysFd >= MQUEUE_FD_OFFSET) && (sysFd < (MQUEUE_FD_OFFSET + CONFIG_NQUEUE_DESCRIPTORS))) { + mqueue_refer(sysFd); + } +#endif +} + +static void FdClose(int sysFd, unsigned int targetPid) +{ + UINT32 intSave; + + if ((sysFd > STDERR_FILENO) && (sysFd < CONFIG_NFILE_DESCRIPTORS)) { + LosProcessCB *processCB = OS_PCB_FROM_PID(targetPid); + SCHEDULER_LOCK(intSave); + if (OsProcessIsInactive(processCB)) { + SCHEDULER_UNLOCK(intSave); + return; + } + SCHEDULER_UNLOCK(intSave); + + files_close_internal(sysFd, processCB); + } +#if defined(LOSCFG_NET_LWIP_SACK) + if ((sysFd >= CONFIG_NFILE_DESCRIPTORS) && (sysFd < (CONFIG_NFILE_DESCRIPTORS + CONFIG_NSOCKET_DESCRIPTORS))) { + socks_close(sysFd); + } +#endif +#if defined(LOSCFG_COMPAT_POSIX) + if ((sysFd >= MQUEUE_FD_OFFSET) && (sysFd < (MQUEUE_FD_OFFSET + CONFIG_NQUEUE_DESCRIPTORS))) { + mq_close((mqd_t)sysFd); + } +#endif +} + +static struct fd_table_s *GetProcessFTable(unsigned int pid, sem_t *semId) +{ + UINT32 intSave; + struct files_struct *procFiles = NULL; + LosProcessCB *processCB = OS_PCB_FROM_PID(pid); + + SCHEDULER_LOCK(intSave); + if (OsProcessIsInactive(processCB)) { + SCHEDULER_UNLOCK(intSave); + return NULL; + } + + procFiles = processCB->files; + if (procFiles == NULL || procFiles->fdt == NULL) { + SCHEDULER_UNLOCK(intSave); + return NULL; + } + + *semId = procFiles->fdt->ft_sem; + SCHEDULER_UNLOCK(intSave); + + return procFiles->fdt; +} + +int CopyFdToProc(int fd, unsigned int targetPid) +{ +#if !defined(LOSCFG_NET_LWIP_SACK) && !defined(LOSCFG_COMPAT_POSIX) && !defined(LOSCFG_FS_VFS) + return -ENOSYS; +#else + int sysFd; + struct fd_table_s *fdt = NULL; + int procFd; + sem_t semId; + + if (OS_PID_CHECK_INVALID(targetPid)) { + return -EINVAL; + } + + sysFd = GetAssociatedSystemFd(fd); + if (sysFd < 0) { + return -EBADF; + } + + FdRefer(sysFd); + fdt = GetProcessFTable(targetPid, &semId); + if (fdt == NULL || fdt->ft_fds == NULL) { + FdClose(sysFd, targetPid); + return -EPERM; + } + + /* Take the semaphore (perhaps waiting) */ + if (sem_wait(&semId) != 0) { + /* Target process changed */ + FdClose(sysFd, targetPid); + return -ESRCH; + } + + procFd = AssignProcessFd(fdt, 3); + if (procFd < 0) { + if (sem_post(&semId) == -1) { + PRINT_ERR("sem_post error, errno %d \n", get_errno()); + } + FdClose(sysFd, targetPid); + return -EPERM; + } + + /* occupy the fd set */ + FD_SET(procFd, fdt->proc_fds); + fdt->ft_fds[procFd].sysFd = sysFd; + if (sem_post(&semId) == -1) { + PRINTK("sem_post error, errno %d \n", get_errno()); + } + + return procFd; +#endif +} + +int CloseProcFd(int procFd, unsigned int targetPid) +{ +#if !defined(LOSCFG_NET_LWIP_SACK) && !defined(LOSCFG_COMPAT_POSIX) && !defined(LOSCFG_FS_VFS) + return -ENOSYS; +#else + int sysFd; + struct fd_table_s *fdt = NULL; + sem_t semId; + + if (OS_PID_CHECK_INVALID(targetPid)) { + return -EINVAL; + } + + fdt = GetProcessFTable(targetPid, &semId); + if (fdt == NULL || fdt->ft_fds == NULL) { + return -EPERM; + } + + /* Take the semaphore (perhaps waiting) */ + if (sem_wait(&semId) != 0) { + /* Target process changed */ + return -ESRCH; + } + + if (!IsValidProcessFd(fdt, procFd)) { + if (sem_post(&semId) == -1) { + PRINTK("sem_post error, errno %d \n", get_errno()); + } + return -EPERM; + } + + sysFd = fdt->ft_fds[procFd].sysFd; + if (sysFd < 0) { + if (sem_post(&semId) == -1) { + PRINTK("sem_post error, errno %d \n", get_errno()); + } + return -EPERM; + } + + /* clean the fd set */ + FD_CLR(procFd, fdt->proc_fds); + fdt->ft_fds[procFd].sysFd = -1; + if (sem_post(&semId) == -1) { + PRINTK("sem_post error, errno %d \n", get_errno()); + } + FdClose(sysFd, targetPid); + + return 0; +#endif +} \ No newline at end of file diff --git a/kernel/extended/liteipc/hm_liteipc.c b/kernel/extended/liteipc/hm_liteipc.c index 4d745828931f3b7b680e68ea96af4e40d0a886f8..51dc48dffcae7bee9cb06123dcd386cbbce78757 100644 --- a/kernel/extended/liteipc/hm_liteipc.c +++ b/kernel/extended/liteipc/hm_liteipc.c @@ -32,6 +32,7 @@ #include "hm_liteipc.h" #include "linux/kernel.h" #include +#include "fs_file.h" #include "los_mp.h" #include "los_mux.h" #include "los_process_pri.h" @@ -43,8 +44,8 @@ #include "los_trace_frame.h" #endif #include "los_vm_map.h" -#include "los_vm_phys.h" #include "los_vm_page.h" +#include "los_vm_phys.h" #include "los_vm_lock.h" #define USE_TASKID_AS_HANDLE YES @@ -656,9 +657,22 @@ LITE_OS_SEC_TEXT STATIC BOOL IsTaskAlive(UINT32 taskID) return TRUE; } -LITE_OS_SEC_TEXT STATIC UINT32 HandleFd(SpecialObj *obj, BOOL isRollback) +LITE_OS_SEC_TEXT STATIC UINT32 HandleFd(UINT32 processID, SpecialObj *obj, BOOL isRollback) { - /* now fd is not Isolated between processes, do nothing */ + int ret; + if (isRollback == FALSE) { + ret = CopyFdToProc(obj->content.fd, processID); + if (ret < 0) { + return ret; + } + obj->content.fd = ret; + } else { + ret = CloseProcFd(obj->content.fd, processID); + if (ret < 0) { + return ret; + } + } + return LOS_OK; } @@ -719,7 +733,7 @@ LITE_OS_SEC_TEXT STATIC UINT32 HandleObj(UINT32 dstTid, SpecialObj *obj, BOOL is UINT32 processID = OS_TCB_FROM_TID(dstTid)->processID; switch (obj->type) { case OBJ_FD: - ret = HandleFd(obj, isRollback); + ret = HandleFd(processID, obj, isRollback); break; case OBJ_PTR: ret = HandlePtr(processID, obj, isRollback);