diff --git a/fs/proc/include/internal.h b/fs/proc/include/internal.h index 03df8ec9021b1309bd52fb7c87617ffc735d139a..fadc4b628444c0ff2f6c3138cae81bb273034018 100644 --- a/fs/proc/include/internal.h +++ b/fs/proc/include/internal.h @@ -65,6 +65,8 @@ extern void ProcUptimeInit(void); extern void ProcFsCacheInit(void); +extern void ProcFdInit(void); + #ifdef __cplusplus #if __cplusplus } diff --git a/fs/proc/os_adapt/fd_proc.c b/fs/proc/os_adapt/fd_proc.c new file mode 100644 index 0000000000000000000000000000000000000000..5914a32451d02151eb048429911d12130b45b38e --- /dev/null +++ b/fs/proc/os_adapt/fd_proc.c @@ -0,0 +1,142 @@ +/* + * 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. + */ + +#include "proc_fs.h" + +#include +#include "fs/file.h" +#include "vfs_config.h" +#include "internal.h" + +#include "fs/fd_table.h" +#include "los_process.h" +#include "capability_api.h" +#include "capability_type.h" + + +/* + * Template: Pid Fd [SysFd ] Name + */ +static void FillFdInfo(struct SeqBuf *seqBuf, struct filelist *fileList, unsigned int pid, bool hasPrivilege) +{ + int fd; + int sysFd; + char *name = NULL; + struct file *filp = NULL; + + struct fd_table_s *fdt = LOS_GetFdTable(pid); + if ((fdt == NULL) || (fdt->proc_fds == NULL)) { + return; + } + + (void)sem_wait(&fdt->ft_sem); + + for (fd = MIN_START_FD; fd < fdt->max_fds; fd++) { + if (FD_ISSET(fd, fdt->proc_fds)) { + sysFd = fdt->ft_fds[fd].sysFd; + if (sysFd < CONFIG_NFILE_DESCRIPTORS) { + filp = &fileList->fl_files[sysFd]; + name = filp->f_path; + } else if (sysFd < (CONFIG_NFILE_DESCRIPTORS + CONFIG_NSOCKET_DESCRIPTORS)) { + name = "(socks)"; + } else if (sysFd < (FD_SETSIZE + CONFIG_NTIME_DESCRIPTORS)) { + name = "(timer)"; + } else if (sysFd < (MQUEUE_FD_OFFSET + CONFIG_NQUEUE_DESCRIPTORS)) { + name = "(mqueue)"; + } else { + name = "(unknown)"; + } + + if (hasPrivilege) { + (void)LosBufPrintf(seqBuf, "%u\t%d\t%d\t%s\n", pid, fd, sysFd, name); + } else { + (void)LosBufPrintf(seqBuf, "%u\t%d\t%s\n", pid, fd, name); + } + } + } + + (void)sem_post(&fdt->ft_sem); +} + +static int FdProcFill(struct SeqBuf *seqBuf, void *v) +{ + int pidNum; + bool hasPrivilege; + unsigned int pidMaxNum; + unsigned int *pidList = NULL; + + /* privilege user */ + if (IsCapPermit(CAP_DAC_READ_SEARCH)) { + pidMaxNum = LOS_GetSystemProcessMaximum(); + pidList = (unsigned int *)malloc(pidMaxNum * sizeof(unsigned int)); + if (pidList == NULL) { + return -ENOMEM; + } + pidNum = LOS_GetUsedPIDList(pidList, pidMaxNum); + hasPrivilege = true; + (void)LosBufPrintf(seqBuf, "Pid\tFd\tSysFd\tName\n"); + } else { + pidNum = 1; + pidList = (unsigned int *)malloc(pidNum * sizeof(unsigned int)); + if (pidList == NULL) { + return -ENOMEM; + } + pidList[0] = LOS_GetCurrProcessID(); + hasPrivilege = false; + (void)LosBufPrintf(seqBuf, "Pid\tFd\tName\n"); + } + + struct filelist *fileList = &tg_filelist; + (void)sem_wait(&fileList->fl_sem); + + for (int i = 0; i < pidNum; i++) { + FillFdInfo(seqBuf, fileList, pidList[i], hasPrivilege); + } + + free(pidList); + (void)sem_post(&fileList->fl_sem); + return 0; +} + +static const struct ProcFileOperations FD_PROC_FOPS = { + .read = FdProcFill, +}; + +void ProcFdInit(void) +{ + struct ProcDirEntry *pde = CreateProcEntry("fd", 0, NULL); + if (pde == NULL) { + PRINT_ERR("creat /proc/fd error.\n"); + return; + } + + pde->procFileOps = &FD_PROC_FOPS; +} + diff --git a/fs/proc/os_adapt/proc_init.c b/fs/proc/os_adapt/proc_init.c index ef111c7cb725bbac60c305623b897dd57f9cc994..34c2d63afaffdeed432f43e50349ed5487c6eb31 100644 --- a/fs/proc/os_adapt/proc_init.c +++ b/fs/proc/os_adapt/proc_init.c @@ -65,6 +65,7 @@ void ProcFsInit(void) ProcUptimeInit(); ProcKernelTraceInit(); ProcFsCacheInit(); + ProcFdInit(); } LOS_MODULE_INIT(ProcFsInit, LOS_INIT_LEVEL_KMOD_EXTENDED); diff --git a/kernel/base/core/los_process.c b/kernel/base/core/los_process.c index d6699b4665b7d5e1fff115ec31206f74e8bbcd31..0f7c4b355caa925e4edbb3f5fb1137ce27d85ce2 100644 --- a/kernel/base/core/los_process.c +++ b/kernel/base/core/los_process.c @@ -1794,6 +1794,52 @@ LITE_OS_SEC_TEXT VOID LOS_Exit(INT32 status) OsProcessExit(OsCurrTaskGet(), (UINT32)status); } +LITE_OS_SEC_TEXT INT32 LOS_GetUsedPIDList(UINT32 *pidList, INT32 pidMaxNum) +{ + LosProcessCB *pcb = NULL; + INT32 num = 0; + UINT32 intSave; + UINT32 pid = 1; + + if (pidList == NULL) { + return 0; + } + SCHEDULER_LOCK(intSave); + while (OsProcessIDUserCheckInvalid(pid) == false) { + pcb = OS_PCB_FROM_PID(pid); + pid++; + if (OsProcessIsUnused(pcb)) { + continue; + } + pidList[num] = pcb->processID; + num++; + if (num >= pidMaxNum) { + break; + } + } + SCHEDULER_UNLOCK(intSave); + return num; +} + +#ifdef LOSCFG_FS_VFS +LITE_OS_SEC_TEXT struct fd_table_s *LOS_GetFdTable(UINT32 pid) +{ + LosProcessCB *pcb = NULL; + struct files_struct *files = NULL; + + if (OS_PID_CHECK_INVALID(pid)) { + return NULL; + } + pcb = OS_PCB_FROM_PID(pid); + files = pcb->files; + if (files == NULL) { + return NULL; + } + + return files->fdt; +} +#endif + LITE_OS_SEC_TEXT UINT32 LOS_GetCurrProcessID(VOID) { return OsCurrProcessGet()->processID; diff --git a/kernel/include/los_process.h b/kernel/include/los_process.h index cf47c3cc0af72e24a8f56f906852358ad4c398f8..cc3342ab0d1b0d81152b61bb5eaef40e17f7b4d5 100644 --- a/kernel/include/los_process.h +++ b/kernel/include/los_process.h @@ -34,6 +34,10 @@ #include "los_task.h" +#ifdef LOSCFG_FS_VFS +#include "fs/fd_table.h" +#endif + #ifdef __cplusplus #if __cplusplus extern "C" { @@ -68,6 +72,12 @@ extern BOOL LOS_CheckInGroups(UINT32 gid); extern INT32 LOS_GetUserID(VOID); extern INT32 LOS_GetGroupID(VOID); +extern INT32 LOS_GetUsedPIDList(UINT32 *pidList, INT32 pidMaxNum); + +#ifdef LOSCFG_FS_VFS +struct fd_table_s *LOS_GetFdTable(UINT32 pid); +#endif + #ifdef __cplusplus #if __cplusplus }