From ce849f2145e1569517c5244c9ffcaebed53f3a66 Mon Sep 17 00:00:00 2001 From: Guangyao Ma Date: Wed, 31 Mar 2021 11:05:43 +0800 Subject: [PATCH] feat: add and fix some syscall add SysFstatat64 SysInfo SysVfork SysGetrusage fix up SysDup SysFcntl Change-Id: If41228da62f406312858921e48e2210e04f16a16 --- fs/vfs/operation/fs_file.c | 7 ++- syscall/fs_syscall.c | 99 +++++++++++++++++++++++++++----------- syscall/los_syscall.h | 6 +++ syscall/misc_syscall.c | 81 +++++++++++++++++++++++++++++-- syscall/process_syscall.c | 5 ++ syscall/syscall_lookup.h | 4 ++ 6 files changed, 167 insertions(+), 35 deletions(-) diff --git a/fs/vfs/operation/fs_file.c b/fs/vfs/operation/fs_file.c index 228fe72f..9b47648d 100755 --- a/fs/vfs/operation/fs_file.c +++ b/fs/vfs/operation/fs_file.c @@ -61,13 +61,18 @@ static int AssignProcessFd(const struct fd_table_s *fdt, int minFd) return VFS_ERROR; } + if (minFd >= fdt->max_fds) { + set_errno(EINVAL); + return VFS_ERROR; + } + /* search unused fd from table */ for (int i = minFd; i < fdt->max_fds; i++) { if (!FD_ISSET(i, fdt->proc_fds)) { return i; } } - + set_errno(EMFILE); return VFS_ERROR; } diff --git a/syscall/fs_syscall.c b/syscall/fs_syscall.c index 1b4034a8..79e0bf76 100644 --- a/syscall/fs_syscall.c +++ b/syscall/fs_syscall.c @@ -181,30 +181,27 @@ static int UserPoll(struct pollfd *fds, nfds_t nfds, int timeout) return ret; } -static int FcntlDupFd(int fd, void *arg, int (*fcntl)(int, int, ...)) +static int FcntlDupFd(int sysfd, void *arg) { - int ret; - int minFd = MIN_START_FD; 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; } - arg = (void *)(UINTPTR)minFd; - ret = fcntl(fd, F_DUPFD, arg); - if (ret < 0) { - FreeProcessFd(procFd); - return -get_errno(); - } - AssociateSystemFd(procFd, ret); - ret = procFd; + files_refer(sysfd); + AssociateSystemFd(procFd, sysfd); - return ret; + return procFd; } int SysClose(int fd) @@ -748,25 +745,20 @@ OUT: int SysDup(int fd) { - int ret = -1; - - int procFd = AllocProcessFd(); - if (procFd < 0) { - return -EMFILE; + int sysfd = GetAssociatedSystemFd(fd); + /* Check if the param is valid, note that: socket fd is not support dup2 */ + if ((sysfd < 0) || (sysfd >= CONFIG_NFILE_DESCRIPTORS)) { + return -EBADF; } - /* Process fd convert to system global fd */ - fd = GetAssociatedSystemFd(fd); - - ret = dup(fd); - if (ret < 0) { - FreeProcessFd(procFd); - return -get_errno(); + int dupfd = AllocProcessFd(); + if (dupfd < 0) { + return -EMFILE; } - AssociateSystemFd(procFd, ret); - - return procFd; + files_refer(sysfd); + AssociateSystemFd(dupfd, sysfd); + return dupfd; } void SysSync(void) @@ -817,8 +809,9 @@ int SysFcntl(int fd, int cmd, void *arg) fd = GetAssociatedSystemFd(fd); if (cmd == F_DUPFD) { - return FcntlDupFd(fd, arg, fcntl); + return FcntlDupFd(fd, arg); } + int ret = fcntl(fd, cmd, arg); if (ret < 0) { return -get_errno(); @@ -1859,8 +1852,9 @@ int SysFcntl64(int fd, int cmd, void *arg) fd = GetAssociatedSystemFd(fd); if (cmd == F_DUPFD) { - return FcntlDupFd(fd, arg, fcntl64); + return FcntlDupFd(fd, arg); } + int ret = fcntl64(fd, cmd, arg); if (ret < 0) { return -get_errno(); @@ -1995,4 +1989,51 @@ OUT: } return ret; } + +int SysFstatat64(int dirfd, const char *restrict path, struct stat *restrict buf, int flag) +{ + int ret; + struct stat bufRet = {0}; + char *pathRet = NULL; + char *fullpath = NULL; + + if (path != NULL) { + ret = UserPathCopy(path, &pathRet); + if (ret != 0) { + goto OUT; + } + } + + if (dirfd != AT_FDCWD) { + /* Process fd convert to system global fd */ + dirfd = GetAssociatedSystemFd(dirfd); + } + + ret = vfs_normalize_pathat(dirfd, pathRet, &fullpath); + if (ret < 0) { + goto OUT; + } + + ret = stat(fullpath, &bufRet); + if (ret < 0) { + ret = -get_errno(); + goto OUT; + } + + ret = LOS_ArchCopyToUser(buf, &bufRet, sizeof(struct stat)); + if (ret != 0) { + ret = -EFAULT; + goto OUT; + } + +OUT: + if (pathRet != NULL) { + LOS_MemFree(OS_SYS_MEM_ADDR, pathRet); + } + + if (fullpath != NULL) { + free(fullpath); + } + return ret; +} #endif diff --git a/syscall/los_syscall.h b/syscall/los_syscall.h index afd74df2..786a1d18 100644 --- a/syscall/los_syscall.h +++ b/syscall/los_syscall.h @@ -38,9 +38,11 @@ #include "los_signal.h" #include "fs/fs.h" #include "syscall.h" +#include "sysinfo.h" #ifdef LOSCFG_KERNEL_DYNLOAD #include "los_exec_elf.h" #endif +#include "sys/resource.h" #include "sys/times.h" #include "sys/utsname.h" #include "sys/shm.h" @@ -73,6 +75,7 @@ extern int SysSchedGetPriorityMax(int policy); extern int SysSchedRRGetInterval(int pid, struct timespec *tp); extern int SysWait(int pid, USER int *status, int options, void *rusage); extern int SysFork(void); +extern int SysVfork(void); extern unsigned int SysGetPID(void); extern unsigned int SysGetPPID(void); extern int SysSetGroupID(unsigned int gid); @@ -161,6 +164,7 @@ extern int SysShmDt(const void *shmaddr); /* misc */ extern int SysUname(struct utsname *name); +extern int SysInfo(struct sysinfo *info); /* time */ extern int SysNanoSleep(const struct timespec *rqtp, struct timespec *rmtp); @@ -242,6 +246,7 @@ extern ssize_t SysWritev(int fd, const struct iovec *iov, int iovcnt); extern int SysPipe(int pipefd[2]); /* 2 : pipe fds for read and write */ extern int SysFormat(const char *dev, int sectors, int option); extern int SysFstat64(int fd, struct stat64 *buf); +extern int SysFstatat64(int fd, const char *restrict path, struct stat *restrict buf, int flag); extern int SysFcntl64(int fd, int cmd, void *arg); extern int SysPoll(struct pollfd *fds, nfds_t nfds, int timeout); extern int SysPrctl(int option, ...); @@ -267,5 +272,6 @@ extern char *SysRealpath(const char *path, char *resolvedPath); extern int SysUmask(int mask); extern int SysShellExec(const char *msgName, const char *cmdString); extern int SysReboot(int magic, int magic2, int type); +extern int SysGetrusage(int what, struct rusage *ru); #endif #endif /* _LOS_SYSCALL_H */ diff --git a/syscall/misc_syscall.c b/syscall/misc_syscall.c index c048dc1c..a61620b3 100755 --- a/syscall/misc_syscall.c +++ b/syscall/misc_syscall.c @@ -30,17 +30,21 @@ */ #include "errno.h" +#include "sysinfo.h" +#include "sys/reboot.h" +#include "sys/resource.h" +#include "sys/times.h" +#include "sys/utsname.h" +#include "time.h" +#include "capability_type.h" +#include "capability_api.h" #include "los_process_pri.h" +#include "los_strncpy_from_user.h" #ifdef LOSCFG_SHELL #include "shcmd.h" #include "shmsg.h" #endif -#include "sys/utsname.h" -#include "sys/reboot.h" #include "user_copy.h" -#include "los_strncpy_from_user.h" -#include "capability_type.h" -#include "capability_api.h" #ifdef __cplusplus #if __cplusplus @@ -67,6 +71,25 @@ int SysUname(struct utsname *name) return ret; } +int SysInfo(struct sysinfo *info) +{ + int ret; + struct sysinfo tmpInfo = { 0 }; + + tmpInfo.totalram = LOS_MemPoolSizeGet(m_aucSysMem1); + tmpInfo.freeram = LOS_MemPoolSizeGet(m_aucSysMem1) - LOS_MemTotalUsedGet(m_aucSysMem1); + tmpInfo.sharedram = 0; + tmpInfo.bufferram = 0; + tmpInfo.totalswap = 0; + tmpInfo.freeswap = 0; + + ret = LOS_ArchCopyToUser(info, &tmpInfo, sizeof(struct sysinfo)); + if (ret != 0) { + return -EFAULT; + } + return 0; +} + int SysReboot(int magic, int magic2, int type) { (void)magic; @@ -127,6 +150,54 @@ int SysShellExec(const char *msgName, const char *cmdString) } #endif +#define USEC_PER_SEC 1000000 + +static void ConvertClocks(struct timeval *time, clock_t clk) +{ + time->tv_usec = (clk % CLOCKS_PER_SEC) * USEC_PER_SEC / CLOCKS_PER_SEC; + time->tv_sec = (clk) / CLOCKS_PER_SEC; +} + +int SysGetrusage(int what, struct rusage *ru) +{ + int ret; + struct tms time; + clock_t usec, sec; + struct rusage kru; + + ret = LOS_ArchCopyFromUser(&kru, ru, sizeof(struct rusage)); + if (ret != 0) { + return -EFAULT; + } + + if (times(&time) == -1) { + return -EFAULT; + } + + switch (what) { + case RUSAGE_SELF: { + usec = time.tms_utime; + sec = time.tms_stime; + break; + } + case RUSAGE_CHILDREN: { + usec = time.tms_cutime; + sec = time.tms_cstime; + break; + } + default: + return -EINVAL; + } + ConvertClocks(&kru.ru_utime, usec); + ConvertClocks(&kru.ru_stime, sec); + + ret = LOS_ArchCopyToUser(ru, &kru, sizeof(struct rusage)); + if (ret != 0) { + return -EFAULT; + } + return 0; +} + #ifdef __cplusplus #if __cplusplus } diff --git a/syscall/process_syscall.c b/syscall/process_syscall.c index ed84aeb5..b304de55 100755 --- a/syscall/process_syscall.c +++ b/syscall/process_syscall.c @@ -312,6 +312,11 @@ int SysFork(void) return OsClone(0, 0, 0); } +int SysVfork(void) +{ + return OsClone(CLONE_VFORK, 0, 0); +} + unsigned int SysGetPPID(void) { return OsCurrProcessGet()->parentProcessID; diff --git a/syscall/syscall_lookup.h b/syscall/syscall_lookup.h index bb72f2b8..9f64594a 100755 --- a/syscall/syscall_lookup.h +++ b/syscall/syscall_lookup.h @@ -43,6 +43,7 @@ SYSCALL_HAND_DEF(__NR_unlink, SysUnlink, int, ARG_NUM_1) SYSCALL_HAND_DEF(__NR_execve, SysExecve, int, ARG_NUM_3) #endif +SYSCALL_HAND_DEF(__NR_sysinfo, SysInfo, int, ARG_NUM_1) SYSCALL_HAND_DEF(__NR_chdir, SysChdir, int, ARG_NUM_1) SYSCALL_HAND_DEF(__NR_chmod, SysChmod, int, ARG_NUM_2) SYSCALL_HAND_DEF(__NR_lseek, SysLseek, off_t, ARG_NUM_7) /* current only support 32bit max 4G file */ @@ -67,6 +68,7 @@ SYSCALL_HAND_DEF(__NR_statfs, SysStatfs, int, ARG_NUM_2) SYSCALL_HAND_DEF(__NR_stat, SysStat, int, ARG_NUM_2) SYSCALL_HAND_DEF(__NR_lstat, SysLstat, int, ARG_NUM_2) SYSCALL_HAND_DEF(__NR_fstat, SysFstat, int, ARG_NUM_2) +SYSCALL_HAND_DEF(__NR_fstatat64, SysFstatat64, int, ARG_NUM_4) SYSCALL_HAND_DEF(__NR_fsync, SysFsync, int, ARG_NUM_1) SYSCALL_HAND_DEF(__NR__llseek, SysLseek64, off64_t, ARG_NUM_5) /* current only support 32bit max 4G file */ SYSCALL_HAND_DEF(__NR__newselect, SysSelect, int, ARG_NUM_5) @@ -115,6 +117,7 @@ SYSCALL_HAND_DEF(__NR_shellexec, SysShellExec, UINT32, ARG_NUM_2) SYSCALL_HAND_DEF(__NR_exit, SysThreadExit, void, ARG_NUM_1) SYSCALL_HAND_DEF(__NR_fork, SysFork, int, ARG_NUM_0) +SYSCALL_HAND_DEF(__NR_vfork, SysVfork, int, ARG_NUM_0) SYSCALL_HAND_DEF(__NR_getpid, SysGetPID, unsigned int, ARG_NUM_0) SYSCALL_HAND_DEF(__NR_pause, SysPause, int, ARG_NUM_0) @@ -236,3 +239,4 @@ SYSCALL_HAND_DEF(__NR_pthread_set_detach, SysUserThreadSetDeatch, int, ARG_NUM_1 SYSCALL_HAND_DEF(__NR_pthread_join, SysThreadJoin, int, ARG_NUM_1) SYSCALL_HAND_DEF(__NR_pthread_deatch, SysUserThreadDetach, int, ARG_NUM_1) SYSCALL_HAND_DEF(__NR_creat_user_thread, SysCreateUserThread, unsigned int, ARG_NUM_3) +SYSCALL_HAND_DEF(__NR_getrusage, SysGetrusage, int, ARG_NUM_2) -- GitLab