xref: /kernel/liteos_a/fs/vfs/operation/vfs_procfd.c (revision 0d163575)
10d163575Sopenharmony_ci/*
20d163575Sopenharmony_ci * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
30d163575Sopenharmony_ci * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
40d163575Sopenharmony_ci *
50d163575Sopenharmony_ci * Redistribution and use in source and binary forms, with or without modification,
60d163575Sopenharmony_ci * are permitted provided that the following conditions are met:
70d163575Sopenharmony_ci *
80d163575Sopenharmony_ci * 1. Redistributions of source code must retain the above copyright notice, this list of
90d163575Sopenharmony_ci *    conditions and the following disclaimer.
100d163575Sopenharmony_ci *
110d163575Sopenharmony_ci * 2. Redistributions in binary form must reproduce the above copyright notice, this list
120d163575Sopenharmony_ci *    of conditions and the following disclaimer in the documentation and/or other materials
130d163575Sopenharmony_ci *    provided with the distribution.
140d163575Sopenharmony_ci *
150d163575Sopenharmony_ci * 3. Neither the name of the copyright holder nor the names of its contributors may be used
160d163575Sopenharmony_ci *    to endorse or promote products derived from this software without specific prior written
170d163575Sopenharmony_ci *    permission.
180d163575Sopenharmony_ci *
190d163575Sopenharmony_ci * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
200d163575Sopenharmony_ci * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
210d163575Sopenharmony_ci * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
220d163575Sopenharmony_ci * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
230d163575Sopenharmony_ci * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
240d163575Sopenharmony_ci * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
250d163575Sopenharmony_ci * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
260d163575Sopenharmony_ci * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
270d163575Sopenharmony_ci * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
280d163575Sopenharmony_ci * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
290d163575Sopenharmony_ci * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
300d163575Sopenharmony_ci */
310d163575Sopenharmony_ci
320d163575Sopenharmony_ci#include "fs/file.h"
330d163575Sopenharmony_ci#include "los_process_pri.h"
340d163575Sopenharmony_ci#include "fs/fd_table.h"
350d163575Sopenharmony_ci#include "mqueue.h"
360d163575Sopenharmony_ci#ifdef LOSCFG_NET_LWIP_SACK
370d163575Sopenharmony_ci#include "lwip/sockets.h"
380d163575Sopenharmony_ci#endif
390d163575Sopenharmony_ci
400d163575Sopenharmony_civoid FileTableLock(struct fd_table_s *fdt)
410d163575Sopenharmony_ci{
420d163575Sopenharmony_ci    /* Take the semaphore (perhaps waiting) */
430d163575Sopenharmony_ci    while (sem_wait(&fdt->ft_sem) != 0) {
440d163575Sopenharmony_ci        /*
450d163575Sopenharmony_ci        * The only case that an error should occur here is if the wait was
460d163575Sopenharmony_ci        * awakened by a signal.
470d163575Sopenharmony_ci        */
480d163575Sopenharmony_ci        LOS_ASSERT(errno == EINTR);
490d163575Sopenharmony_ci    }
500d163575Sopenharmony_ci}
510d163575Sopenharmony_ci
520d163575Sopenharmony_civoid FileTableUnLock(struct fd_table_s *fdt)
530d163575Sopenharmony_ci{
540d163575Sopenharmony_ci    int ret = sem_post(&fdt->ft_sem);
550d163575Sopenharmony_ci    if (ret == -1) {
560d163575Sopenharmony_ci        PRINTK("sem_post error, errno %d \n", get_errno());
570d163575Sopenharmony_ci    }
580d163575Sopenharmony_ci}
590d163575Sopenharmony_ci
600d163575Sopenharmony_cistatic int AssignProcessFd(const struct fd_table_s *fdt, int minFd)
610d163575Sopenharmony_ci{
620d163575Sopenharmony_ci    if (minFd >= fdt->max_fds) {
630d163575Sopenharmony_ci        set_errno(EINVAL);
640d163575Sopenharmony_ci        return VFS_ERROR;
650d163575Sopenharmony_ci    }
660d163575Sopenharmony_ci
670d163575Sopenharmony_ci    /* search unused fd from table */
680d163575Sopenharmony_ci    for (int i = minFd; i < fdt->max_fds; i++) {
690d163575Sopenharmony_ci        if (!FD_ISSET(i, fdt->proc_fds)) {
700d163575Sopenharmony_ci            return i;
710d163575Sopenharmony_ci        }
720d163575Sopenharmony_ci    }
730d163575Sopenharmony_ci    set_errno(EMFILE);
740d163575Sopenharmony_ci    return VFS_ERROR;
750d163575Sopenharmony_ci}
760d163575Sopenharmony_ci
770d163575Sopenharmony_cistruct fd_table_s *GetFdTable(void)
780d163575Sopenharmony_ci{
790d163575Sopenharmony_ci    struct fd_table_s *fdt = NULL;
800d163575Sopenharmony_ci    struct files_struct *procFiles = OsCurrProcessGet()->files;
810d163575Sopenharmony_ci
820d163575Sopenharmony_ci    if (procFiles == NULL) {
830d163575Sopenharmony_ci        return NULL;
840d163575Sopenharmony_ci    }
850d163575Sopenharmony_ci
860d163575Sopenharmony_ci    fdt = procFiles->fdt;
870d163575Sopenharmony_ci    if ((fdt == NULL) || (fdt->ft_fds == NULL)) {
880d163575Sopenharmony_ci        return NULL;
890d163575Sopenharmony_ci    }
900d163575Sopenharmony_ci
910d163575Sopenharmony_ci    return fdt;
920d163575Sopenharmony_ci}
930d163575Sopenharmony_ci
940d163575Sopenharmony_cistatic bool IsValidProcessFd(struct fd_table_s *fdt, int procFd)
950d163575Sopenharmony_ci{
960d163575Sopenharmony_ci    if (fdt == NULL) {
970d163575Sopenharmony_ci        return false;
980d163575Sopenharmony_ci    }
990d163575Sopenharmony_ci    if ((procFd < 0) || (procFd >= fdt->max_fds)) {
1000d163575Sopenharmony_ci        return false;
1010d163575Sopenharmony_ci    }
1020d163575Sopenharmony_ci    return true;
1030d163575Sopenharmony_ci}
1040d163575Sopenharmony_ci
1050d163575Sopenharmony_civoid AssociateSystemFd(int procFd, int sysFd)
1060d163575Sopenharmony_ci{
1070d163575Sopenharmony_ci    struct fd_table_s *fdt = GetFdTable();
1080d163575Sopenharmony_ci
1090d163575Sopenharmony_ci    if (!IsValidProcessFd(fdt, procFd)) {
1100d163575Sopenharmony_ci        return;
1110d163575Sopenharmony_ci    }
1120d163575Sopenharmony_ci
1130d163575Sopenharmony_ci    if (sysFd < 0) {
1140d163575Sopenharmony_ci        return;
1150d163575Sopenharmony_ci    }
1160d163575Sopenharmony_ci
1170d163575Sopenharmony_ci    FileTableLock(fdt);
1180d163575Sopenharmony_ci    fdt->ft_fds[procFd].sysFd = sysFd;
1190d163575Sopenharmony_ci    FileTableUnLock(fdt);
1200d163575Sopenharmony_ci}
1210d163575Sopenharmony_ci
1220d163575Sopenharmony_ciint CheckProcessFd(int procFd)
1230d163575Sopenharmony_ci{
1240d163575Sopenharmony_ci    struct fd_table_s *fdt = GetFdTable();
1250d163575Sopenharmony_ci
1260d163575Sopenharmony_ci    if (!IsValidProcessFd(fdt, procFd)) {
1270d163575Sopenharmony_ci        return VFS_ERROR;
1280d163575Sopenharmony_ci    }
1290d163575Sopenharmony_ci
1300d163575Sopenharmony_ci    return OK;
1310d163575Sopenharmony_ci}
1320d163575Sopenharmony_ci
1330d163575Sopenharmony_ciint GetAssociatedSystemFd(int procFd)
1340d163575Sopenharmony_ci{
1350d163575Sopenharmony_ci    struct fd_table_s *fdt = GetFdTable();
1360d163575Sopenharmony_ci
1370d163575Sopenharmony_ci    if (!IsValidProcessFd(fdt, procFd)) {
1380d163575Sopenharmony_ci        return VFS_ERROR;
1390d163575Sopenharmony_ci    }
1400d163575Sopenharmony_ci
1410d163575Sopenharmony_ci    FileTableLock(fdt);
1420d163575Sopenharmony_ci    if (fdt->ft_fds[procFd].sysFd < 0) {
1430d163575Sopenharmony_ci        FileTableUnLock(fdt);
1440d163575Sopenharmony_ci        return VFS_ERROR;
1450d163575Sopenharmony_ci    }
1460d163575Sopenharmony_ci    int sysFd = fdt->ft_fds[procFd].sysFd;
1470d163575Sopenharmony_ci    FileTableUnLock(fdt);
1480d163575Sopenharmony_ci
1490d163575Sopenharmony_ci    return sysFd;
1500d163575Sopenharmony_ci}
1510d163575Sopenharmony_ci
1520d163575Sopenharmony_ci/* Occupy the procFd, there are three circumstances:
1530d163575Sopenharmony_ci * 1.procFd is already associated, we need disassociate procFd with relevant sysfd.
1540d163575Sopenharmony_ci * 2.procFd is not allocated, we occupy it immediately.
1550d163575Sopenharmony_ci * 3.procFd is in open(), close(), dup() process, we return EBUSY immediately.
1560d163575Sopenharmony_ci */
1570d163575Sopenharmony_ciint AllocSpecifiedProcessFd(int procFd)
1580d163575Sopenharmony_ci{
1590d163575Sopenharmony_ci    struct fd_table_s *fdt = GetFdTable();
1600d163575Sopenharmony_ci
1610d163575Sopenharmony_ci    if (!IsValidProcessFd(fdt, procFd)) {
1620d163575Sopenharmony_ci        return -EBADF;
1630d163575Sopenharmony_ci    }
1640d163575Sopenharmony_ci
1650d163575Sopenharmony_ci    FileTableLock(fdt);
1660d163575Sopenharmony_ci    if (fdt->ft_fds[procFd].sysFd >= 0) {
1670d163575Sopenharmony_ci        /* Disassociate procFd */
1680d163575Sopenharmony_ci        fdt->ft_fds[procFd].sysFd = -1;
1690d163575Sopenharmony_ci        FileTableUnLock(fdt);
1700d163575Sopenharmony_ci        return OK;
1710d163575Sopenharmony_ci    }
1720d163575Sopenharmony_ci
1730d163575Sopenharmony_ci    if (FD_ISSET(procFd, fdt->proc_fds)) {
1740d163575Sopenharmony_ci        /* procFd in race condition */
1750d163575Sopenharmony_ci        FileTableUnLock(fdt);
1760d163575Sopenharmony_ci        return -EBUSY;
1770d163575Sopenharmony_ci    } else {
1780d163575Sopenharmony_ci        /* Unused procFd */
1790d163575Sopenharmony_ci        FD_SET(procFd, fdt->proc_fds);
1800d163575Sopenharmony_ci    }
1810d163575Sopenharmony_ci
1820d163575Sopenharmony_ci    FileTableUnLock(fdt);
1830d163575Sopenharmony_ci    return OK;
1840d163575Sopenharmony_ci}
1850d163575Sopenharmony_ci
1860d163575Sopenharmony_civoid FreeProcessFd(int procFd)
1870d163575Sopenharmony_ci{
1880d163575Sopenharmony_ci    struct fd_table_s *fdt = GetFdTable();
1890d163575Sopenharmony_ci
1900d163575Sopenharmony_ci    if (!IsValidProcessFd(fdt, procFd)) {
1910d163575Sopenharmony_ci        return;
1920d163575Sopenharmony_ci    }
1930d163575Sopenharmony_ci
1940d163575Sopenharmony_ci    FileTableLock(fdt);
1950d163575Sopenharmony_ci    FD_CLR(procFd, fdt->proc_fds);
1960d163575Sopenharmony_ci    FD_CLR(procFd, fdt->cloexec_fds);
1970d163575Sopenharmony_ci    fdt->ft_fds[procFd].sysFd = -1;
1980d163575Sopenharmony_ci    FileTableUnLock(fdt);
1990d163575Sopenharmony_ci}
2000d163575Sopenharmony_ci
2010d163575Sopenharmony_ciint DisassociateProcessFd(int procFd)
2020d163575Sopenharmony_ci{
2030d163575Sopenharmony_ci    struct fd_table_s *fdt = GetFdTable();
2040d163575Sopenharmony_ci
2050d163575Sopenharmony_ci    if (!IsValidProcessFd(fdt, procFd)) {
2060d163575Sopenharmony_ci        return VFS_ERROR;
2070d163575Sopenharmony_ci    }
2080d163575Sopenharmony_ci
2090d163575Sopenharmony_ci    FileTableLock(fdt);
2100d163575Sopenharmony_ci    if (fdt->ft_fds[procFd].sysFd < 0) {
2110d163575Sopenharmony_ci        FileTableUnLock(fdt);
2120d163575Sopenharmony_ci        return VFS_ERROR;
2130d163575Sopenharmony_ci    }
2140d163575Sopenharmony_ci    int sysFd = fdt->ft_fds[procFd].sysFd;
2150d163575Sopenharmony_ci    if (procFd >= MIN_START_FD) {
2160d163575Sopenharmony_ci        fdt->ft_fds[procFd].sysFd = -1;
2170d163575Sopenharmony_ci    }
2180d163575Sopenharmony_ci    FileTableUnLock(fdt);
2190d163575Sopenharmony_ci
2200d163575Sopenharmony_ci    return sysFd;
2210d163575Sopenharmony_ci}
2220d163575Sopenharmony_ci
2230d163575Sopenharmony_ciint AllocProcessFd(void)
2240d163575Sopenharmony_ci{
2250d163575Sopenharmony_ci    return AllocLowestProcessFd(MIN_START_FD);
2260d163575Sopenharmony_ci}
2270d163575Sopenharmony_ci
2280d163575Sopenharmony_ciint AllocLowestProcessFd(int minFd)
2290d163575Sopenharmony_ci{
2300d163575Sopenharmony_ci    struct fd_table_s *fdt = GetFdTable();
2310d163575Sopenharmony_ci
2320d163575Sopenharmony_ci    if (fdt == NULL) {
2330d163575Sopenharmony_ci        return VFS_ERROR;
2340d163575Sopenharmony_ci    }
2350d163575Sopenharmony_ci
2360d163575Sopenharmony_ci    /* minFd should be a positive number,and 0,1,2 had be distributed to stdin,stdout,stderr */
2370d163575Sopenharmony_ci    if (minFd < MIN_START_FD) {
2380d163575Sopenharmony_ci        minFd = MIN_START_FD;
2390d163575Sopenharmony_ci    }
2400d163575Sopenharmony_ci
2410d163575Sopenharmony_ci    FileTableLock(fdt);
2420d163575Sopenharmony_ci
2430d163575Sopenharmony_ci    int procFd = AssignProcessFd(fdt, minFd);
2440d163575Sopenharmony_ci    if (procFd == VFS_ERROR) {
2450d163575Sopenharmony_ci        FileTableUnLock(fdt);
2460d163575Sopenharmony_ci        return VFS_ERROR;
2470d163575Sopenharmony_ci    }
2480d163575Sopenharmony_ci
2490d163575Sopenharmony_ci    /* occupy the fd set */
2500d163575Sopenharmony_ci    FD_SET(procFd, fdt->proc_fds);
2510d163575Sopenharmony_ci    FileTableUnLock(fdt);
2520d163575Sopenharmony_ci
2530d163575Sopenharmony_ci    return procFd;
2540d163575Sopenharmony_ci}
2550d163575Sopenharmony_ci
2560d163575Sopenharmony_ciint AllocAndAssocProcessFd(int sysFd, int minFd)
2570d163575Sopenharmony_ci{
2580d163575Sopenharmony_ci    struct fd_table_s *fdt = GetFdTable();
2590d163575Sopenharmony_ci
2600d163575Sopenharmony_ci    if (fdt == NULL) {
2610d163575Sopenharmony_ci        return VFS_ERROR;
2620d163575Sopenharmony_ci    }
2630d163575Sopenharmony_ci
2640d163575Sopenharmony_ci    /* minFd should be a positive number,and 0,1,2 had be distributed to stdin,stdout,stderr */
2650d163575Sopenharmony_ci    if (minFd < MIN_START_FD) {
2660d163575Sopenharmony_ci        minFd = MIN_START_FD;
2670d163575Sopenharmony_ci    }
2680d163575Sopenharmony_ci
2690d163575Sopenharmony_ci    FileTableLock(fdt);
2700d163575Sopenharmony_ci
2710d163575Sopenharmony_ci    int procFd = AssignProcessFd(fdt, minFd);
2720d163575Sopenharmony_ci    if (procFd == VFS_ERROR) {
2730d163575Sopenharmony_ci        FileTableUnLock(fdt);
2740d163575Sopenharmony_ci        return VFS_ERROR;
2750d163575Sopenharmony_ci    }
2760d163575Sopenharmony_ci
2770d163575Sopenharmony_ci    /* occupy the fd set */
2780d163575Sopenharmony_ci    FD_SET(procFd, fdt->proc_fds);
2790d163575Sopenharmony_ci    fdt->ft_fds[procFd].sysFd = sysFd;
2800d163575Sopenharmony_ci    FileTableUnLock(fdt);
2810d163575Sopenharmony_ci
2820d163575Sopenharmony_ci    return procFd;
2830d163575Sopenharmony_ci}
2840d163575Sopenharmony_ci
2850d163575Sopenharmony_ciint AllocAndAssocSystemFd(int procFd, int minFd)
2860d163575Sopenharmony_ci{
2870d163575Sopenharmony_ci    struct fd_table_s *fdt = GetFdTable();
2880d163575Sopenharmony_ci
2890d163575Sopenharmony_ci    if (!IsValidProcessFd(fdt, procFd)) {
2900d163575Sopenharmony_ci        return VFS_ERROR;
2910d163575Sopenharmony_ci    }
2920d163575Sopenharmony_ci
2930d163575Sopenharmony_ci    int sysFd = alloc_fd(minFd);
2940d163575Sopenharmony_ci    if (sysFd < 0) {
2950d163575Sopenharmony_ci        return VFS_ERROR;
2960d163575Sopenharmony_ci    }
2970d163575Sopenharmony_ci
2980d163575Sopenharmony_ci    FileTableLock(fdt);
2990d163575Sopenharmony_ci    fdt->ft_fds[procFd].sysFd = sysFd;
3000d163575Sopenharmony_ci    FileTableUnLock(fdt);
3010d163575Sopenharmony_ci
3020d163575Sopenharmony_ci    return sysFd;
3030d163575Sopenharmony_ci}
3040d163575Sopenharmony_ci
3050d163575Sopenharmony_cistatic void FdRefer(int sysFd)
3060d163575Sopenharmony_ci{
3070d163575Sopenharmony_ci    if ((sysFd > STDERR_FILENO) && (sysFd < CONFIG_NFILE_DESCRIPTORS)) {
3080d163575Sopenharmony_ci        files_refer(sysFd);
3090d163575Sopenharmony_ci    }
3100d163575Sopenharmony_ci#if defined(LOSCFG_NET_LWIP_SACK)
3110d163575Sopenharmony_ci    if ((sysFd >= CONFIG_NFILE_DESCRIPTORS) && (sysFd < (CONFIG_NFILE_DESCRIPTORS + CONFIG_NSOCKET_DESCRIPTORS))) {
3120d163575Sopenharmony_ci        socks_refer(sysFd);
3130d163575Sopenharmony_ci    }
3140d163575Sopenharmony_ci#endif
3150d163575Sopenharmony_ci#if defined(LOSCFG_COMPAT_POSIX)
3160d163575Sopenharmony_ci    if ((sysFd >= MQUEUE_FD_OFFSET) && (sysFd < (MQUEUE_FD_OFFSET + CONFIG_NQUEUE_DESCRIPTORS))) {
3170d163575Sopenharmony_ci        MqueueRefer(sysFd);
3180d163575Sopenharmony_ci    }
3190d163575Sopenharmony_ci#endif
3200d163575Sopenharmony_ci}
3210d163575Sopenharmony_ci
3220d163575Sopenharmony_cistatic void FdClose(int sysFd, unsigned int targetPid)
3230d163575Sopenharmony_ci{
3240d163575Sopenharmony_ci    UINT32 intSave;
3250d163575Sopenharmony_ci
3260d163575Sopenharmony_ci    if ((sysFd > STDERR_FILENO) && (sysFd < CONFIG_NFILE_DESCRIPTORS)) {
3270d163575Sopenharmony_ci        LosProcessCB *processCB = OS_PCB_FROM_PID(targetPid);
3280d163575Sopenharmony_ci        SCHEDULER_LOCK(intSave);
3290d163575Sopenharmony_ci        if (OsProcessIsInactive(processCB)) {
3300d163575Sopenharmony_ci            SCHEDULER_UNLOCK(intSave);
3310d163575Sopenharmony_ci            return;
3320d163575Sopenharmony_ci        }
3330d163575Sopenharmony_ci        SCHEDULER_UNLOCK(intSave);
3340d163575Sopenharmony_ci
3350d163575Sopenharmony_ci        files_close_internal(sysFd, processCB);
3360d163575Sopenharmony_ci    }
3370d163575Sopenharmony_ci#if defined(LOSCFG_NET_LWIP_SACK)
3380d163575Sopenharmony_ci    if ((sysFd >= CONFIG_NFILE_DESCRIPTORS) && (sysFd < (CONFIG_NFILE_DESCRIPTORS + CONFIG_NSOCKET_DESCRIPTORS))) {
3390d163575Sopenharmony_ci        socks_close(sysFd);
3400d163575Sopenharmony_ci    }
3410d163575Sopenharmony_ci#endif
3420d163575Sopenharmony_ci#if defined(LOSCFG_COMPAT_POSIX)
3430d163575Sopenharmony_ci    if ((sysFd >= MQUEUE_FD_OFFSET) && (sysFd < (MQUEUE_FD_OFFSET + CONFIG_NQUEUE_DESCRIPTORS))) {
3440d163575Sopenharmony_ci        mq_close((mqd_t)sysFd);
3450d163575Sopenharmony_ci    }
3460d163575Sopenharmony_ci#endif
3470d163575Sopenharmony_ci}
3480d163575Sopenharmony_ci
3490d163575Sopenharmony_cistatic struct fd_table_s *GetProcessFTable(unsigned int pid, sem_t *semId)
3500d163575Sopenharmony_ci{
3510d163575Sopenharmony_ci    UINT32 intSave;
3520d163575Sopenharmony_ci    struct files_struct *procFiles = NULL;
3530d163575Sopenharmony_ci    LosProcessCB *processCB = OS_PCB_FROM_PID(pid);
3540d163575Sopenharmony_ci
3550d163575Sopenharmony_ci    SCHEDULER_LOCK(intSave);
3560d163575Sopenharmony_ci    if (OsProcessIsInactive(processCB)) {
3570d163575Sopenharmony_ci        SCHEDULER_UNLOCK(intSave);
3580d163575Sopenharmony_ci        return NULL;
3590d163575Sopenharmony_ci    }
3600d163575Sopenharmony_ci
3610d163575Sopenharmony_ci    procFiles = processCB->files;
3620d163575Sopenharmony_ci    if (procFiles == NULL || procFiles->fdt == NULL) {
3630d163575Sopenharmony_ci        SCHEDULER_UNLOCK(intSave);
3640d163575Sopenharmony_ci        return NULL;
3650d163575Sopenharmony_ci    }
3660d163575Sopenharmony_ci
3670d163575Sopenharmony_ci    *semId = procFiles->fdt->ft_sem;
3680d163575Sopenharmony_ci    SCHEDULER_UNLOCK(intSave);
3690d163575Sopenharmony_ci
3700d163575Sopenharmony_ci    return procFiles->fdt;
3710d163575Sopenharmony_ci}
3720d163575Sopenharmony_ci
3730d163575Sopenharmony_ciint CopyFdToProc(int fd, unsigned int targetPid)
3740d163575Sopenharmony_ci{
3750d163575Sopenharmony_ci#if !defined(LOSCFG_NET_LWIP_SACK) && !defined(LOSCFG_COMPAT_POSIX) && !defined(LOSCFG_FS_VFS)
3760d163575Sopenharmony_ci    return -ENOSYS;
3770d163575Sopenharmony_ci#else
3780d163575Sopenharmony_ci    int sysFd;
3790d163575Sopenharmony_ci    struct fd_table_s *fdt = NULL;
3800d163575Sopenharmony_ci    int procFd;
3810d163575Sopenharmony_ci    sem_t semId;
3820d163575Sopenharmony_ci
3830d163575Sopenharmony_ci    if (OS_PID_CHECK_INVALID(targetPid)) {
3840d163575Sopenharmony_ci        return -EINVAL;
3850d163575Sopenharmony_ci    }
3860d163575Sopenharmony_ci
3870d163575Sopenharmony_ci    sysFd = GetAssociatedSystemFd(fd);
3880d163575Sopenharmony_ci    if (sysFd < 0) {
3890d163575Sopenharmony_ci        return -EBADF;
3900d163575Sopenharmony_ci    }
3910d163575Sopenharmony_ci
3920d163575Sopenharmony_ci    FdRefer(sysFd);
3930d163575Sopenharmony_ci    fdt = GetProcessFTable(targetPid, &semId);
3940d163575Sopenharmony_ci    if (fdt == NULL || fdt->ft_fds == NULL) {
3950d163575Sopenharmony_ci        FdClose(sysFd, targetPid);
3960d163575Sopenharmony_ci        return -EPERM;
3970d163575Sopenharmony_ci    }
3980d163575Sopenharmony_ci
3990d163575Sopenharmony_ci    /* Take the semaphore (perhaps waiting) */
4000d163575Sopenharmony_ci    if (sem_wait(&semId) != 0) {
4010d163575Sopenharmony_ci        /* Target process changed */
4020d163575Sopenharmony_ci        FdClose(sysFd, targetPid);
4030d163575Sopenharmony_ci        return -ESRCH;
4040d163575Sopenharmony_ci    }
4050d163575Sopenharmony_ci
4060d163575Sopenharmony_ci    procFd = AssignProcessFd(fdt, 3); // minfd is 3
4070d163575Sopenharmony_ci    if (procFd < 0) {
4080d163575Sopenharmony_ci        if (sem_post(&semId) == -1) {
4090d163575Sopenharmony_ci            PRINT_ERR("sem_post error, errno %d \n", get_errno());
4100d163575Sopenharmony_ci        }
4110d163575Sopenharmony_ci        FdClose(sysFd, targetPid);
4120d163575Sopenharmony_ci        return -EPERM;
4130d163575Sopenharmony_ci    }
4140d163575Sopenharmony_ci
4150d163575Sopenharmony_ci    /* occupy the fd set */
4160d163575Sopenharmony_ci    FD_SET(procFd, fdt->proc_fds);
4170d163575Sopenharmony_ci    fdt->ft_fds[procFd].sysFd = sysFd;
4180d163575Sopenharmony_ci    if (sem_post(&semId) == -1) {
4190d163575Sopenharmony_ci        PRINTK("sem_post error, errno %d \n", get_errno());
4200d163575Sopenharmony_ci    }
4210d163575Sopenharmony_ci
4220d163575Sopenharmony_ci    return procFd;
4230d163575Sopenharmony_ci#endif
4240d163575Sopenharmony_ci}
4250d163575Sopenharmony_ci
4260d163575Sopenharmony_ciint CloseProcFd(int procFd, unsigned int targetPid)
4270d163575Sopenharmony_ci{
4280d163575Sopenharmony_ci#if !defined(LOSCFG_NET_LWIP_SACK) && !defined(LOSCFG_COMPAT_POSIX) && !defined(LOSCFG_FS_VFS)
4290d163575Sopenharmony_ci    return -ENOSYS;
4300d163575Sopenharmony_ci#else
4310d163575Sopenharmony_ci    int sysFd;
4320d163575Sopenharmony_ci    struct fd_table_s *fdt = NULL;
4330d163575Sopenharmony_ci    sem_t semId;
4340d163575Sopenharmony_ci
4350d163575Sopenharmony_ci    if (OS_PID_CHECK_INVALID(targetPid)) {
4360d163575Sopenharmony_ci        return -EINVAL;
4370d163575Sopenharmony_ci    }
4380d163575Sopenharmony_ci
4390d163575Sopenharmony_ci    fdt = GetProcessFTable(targetPid, &semId);
4400d163575Sopenharmony_ci    if (fdt == NULL || fdt->ft_fds == NULL) {
4410d163575Sopenharmony_ci        return -EPERM;
4420d163575Sopenharmony_ci    }
4430d163575Sopenharmony_ci
4440d163575Sopenharmony_ci    /* Take the semaphore (perhaps waiting) */
4450d163575Sopenharmony_ci    if (sem_wait(&semId) != 0) {
4460d163575Sopenharmony_ci        /* Target process changed */
4470d163575Sopenharmony_ci        return -ESRCH;
4480d163575Sopenharmony_ci    }
4490d163575Sopenharmony_ci
4500d163575Sopenharmony_ci    if (!IsValidProcessFd(fdt, procFd)) {
4510d163575Sopenharmony_ci        if (sem_post(&semId) == -1) {
4520d163575Sopenharmony_ci            PRINTK("sem_post error, errno %d \n", get_errno());
4530d163575Sopenharmony_ci        }
4540d163575Sopenharmony_ci        return -EPERM;
4550d163575Sopenharmony_ci    }
4560d163575Sopenharmony_ci
4570d163575Sopenharmony_ci    sysFd = fdt->ft_fds[procFd].sysFd;
4580d163575Sopenharmony_ci    if (sysFd < 0) {
4590d163575Sopenharmony_ci        if (sem_post(&semId) == -1) {
4600d163575Sopenharmony_ci            PRINTK("sem_post error, errno %d \n", get_errno());
4610d163575Sopenharmony_ci        }
4620d163575Sopenharmony_ci        return -EPERM;
4630d163575Sopenharmony_ci    }
4640d163575Sopenharmony_ci
4650d163575Sopenharmony_ci    /* clean the fd set */
4660d163575Sopenharmony_ci    FD_CLR(procFd, fdt->proc_fds);
4670d163575Sopenharmony_ci    FD_CLR(procFd, fdt->cloexec_fds);
4680d163575Sopenharmony_ci    fdt->ft_fds[procFd].sysFd = -1;
4690d163575Sopenharmony_ci    if (sem_post(&semId) == -1) {
4700d163575Sopenharmony_ci        PRINTK("sem_post error, errno %d \n", get_errno());
4710d163575Sopenharmony_ci    }
4720d163575Sopenharmony_ci    FdClose(sysFd, targetPid);
4730d163575Sopenharmony_ci
4740d163575Sopenharmony_ci    return 0;
4750d163575Sopenharmony_ci#endif
4760d163575Sopenharmony_ci}
477