feat: add and fix some syscall

add SysFstatat64 SysInfo SysVfork SysGetrusage
fix up SysDup SysFcntl

Change-Id: If41228da62f406312858921e48e2210e04f16a16
This commit is contained in:
Guangyao Ma 2021-03-31 11:05:43 +08:00
parent ed7c8e4798
commit ce849f2145
6 changed files with 167 additions and 35 deletions

View File

@ -61,13 +61,18 @@ static int AssignProcessFd(const struct fd_table_s *fdt, int minFd)
return VFS_ERROR; return VFS_ERROR;
} }
if (minFd >= fdt->max_fds) {
set_errno(EINVAL);
return VFS_ERROR;
}
/* search unused fd from table */ /* search unused fd from table */
for (int i = minFd; i < fdt->max_fds; i++) { for (int i = minFd; i < fdt->max_fds; i++) {
if (!FD_ISSET(i, fdt->proc_fds)) { if (!FD_ISSET(i, fdt->proc_fds)) {
return i; return i;
} }
} }
set_errno(EMFILE);
return VFS_ERROR; return VFS_ERROR;
} }

View File

@ -181,30 +181,27 @@ static int UserPoll(struct pollfd *fds, nfds_t nfds, int timeout)
return ret; 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; int leastFd = (intptr_t)arg;
if ((sysfd < 0) || (sysfd >= CONFIG_NFILE_DESCRIPTORS)) {
return -EBADF;
}
if (CheckProcessFd(leastFd) != OK) { if (CheckProcessFd(leastFd) != OK) {
return -EINVAL; return -EINVAL;
} }
int procFd = AllocLowestProcessFd(leastFd); int procFd = AllocLowestProcessFd(leastFd);
if (procFd < 0) { if (procFd < 0) {
return -EMFILE; return -EMFILE;
} }
arg = (void *)(UINTPTR)minFd;
ret = fcntl(fd, F_DUPFD, arg); files_refer(sysfd);
if (ret < 0) { AssociateSystemFd(procFd, sysfd);
FreeProcessFd(procFd);
return -get_errno();
}
AssociateSystemFd(procFd, ret);
ret = procFd;
return ret; return procFd;
} }
int SysClose(int fd) int SysClose(int fd)
@ -748,25 +745,20 @@ OUT:
int SysDup(int fd) int SysDup(int fd)
{ {
int ret = -1; 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;
}
int procFd = AllocProcessFd(); int dupfd = AllocProcessFd();
if (procFd < 0) { if (dupfd < 0) {
return -EMFILE; return -EMFILE;
} }
/* Process fd convert to system global fd */ files_refer(sysfd);
fd = GetAssociatedSystemFd(fd); AssociateSystemFd(dupfd, sysfd);
return dupfd;
ret = dup(fd);
if (ret < 0) {
FreeProcessFd(procFd);
return -get_errno();
}
AssociateSystemFd(procFd, ret);
return procFd;
} }
void SysSync(void) void SysSync(void)
@ -817,8 +809,9 @@ int SysFcntl(int fd, int cmd, void *arg)
fd = GetAssociatedSystemFd(fd); fd = GetAssociatedSystemFd(fd);
if (cmd == F_DUPFD) { if (cmd == F_DUPFD) {
return FcntlDupFd(fd, arg, fcntl); return FcntlDupFd(fd, arg);
} }
int ret = fcntl(fd, cmd, arg); int ret = fcntl(fd, cmd, arg);
if (ret < 0) { if (ret < 0) {
return -get_errno(); return -get_errno();
@ -1859,8 +1852,9 @@ int SysFcntl64(int fd, int cmd, void *arg)
fd = GetAssociatedSystemFd(fd); fd = GetAssociatedSystemFd(fd);
if (cmd == F_DUPFD) { if (cmd == F_DUPFD) {
return FcntlDupFd(fd, arg, fcntl64); return FcntlDupFd(fd, arg);
} }
int ret = fcntl64(fd, cmd, arg); int ret = fcntl64(fd, cmd, arg);
if (ret < 0) { if (ret < 0) {
return -get_errno(); return -get_errno();
@ -1995,4 +1989,51 @@ OUT:
} }
return ret; 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 #endif

View File

@ -38,9 +38,11 @@
#include "los_signal.h" #include "los_signal.h"
#include "fs/fs.h" #include "fs/fs.h"
#include "syscall.h" #include "syscall.h"
#include "sysinfo.h"
#ifdef LOSCFG_KERNEL_DYNLOAD #ifdef LOSCFG_KERNEL_DYNLOAD
#include "los_exec_elf.h" #include "los_exec_elf.h"
#endif #endif
#include "sys/resource.h"
#include "sys/times.h" #include "sys/times.h"
#include "sys/utsname.h" #include "sys/utsname.h"
#include "sys/shm.h" #include "sys/shm.h"
@ -73,6 +75,7 @@ extern int SysSchedGetPriorityMax(int policy);
extern int SysSchedRRGetInterval(int pid, struct timespec *tp); extern int SysSchedRRGetInterval(int pid, struct timespec *tp);
extern int SysWait(int pid, USER int *status, int options, void *rusage); extern int SysWait(int pid, USER int *status, int options, void *rusage);
extern int SysFork(void); extern int SysFork(void);
extern int SysVfork(void);
extern unsigned int SysGetPID(void); extern unsigned int SysGetPID(void);
extern unsigned int SysGetPPID(void); extern unsigned int SysGetPPID(void);
extern int SysSetGroupID(unsigned int gid); extern int SysSetGroupID(unsigned int gid);
@ -161,6 +164,7 @@ extern int SysShmDt(const void *shmaddr);
/* misc */ /* misc */
extern int SysUname(struct utsname *name); extern int SysUname(struct utsname *name);
extern int SysInfo(struct sysinfo *info);
/* time */ /* time */
extern int SysNanoSleep(const struct timespec *rqtp, struct timespec *rmtp); 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 SysPipe(int pipefd[2]); /* 2 : pipe fds for read and write */
extern int SysFormat(const char *dev, int sectors, int option); extern int SysFormat(const char *dev, int sectors, int option);
extern int SysFstat64(int fd, struct stat64 *buf); 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 SysFcntl64(int fd, int cmd, void *arg);
extern int SysPoll(struct pollfd *fds, nfds_t nfds, int timeout); extern int SysPoll(struct pollfd *fds, nfds_t nfds, int timeout);
extern int SysPrctl(int option, ...); extern int SysPrctl(int option, ...);
@ -267,5 +272,6 @@ extern char *SysRealpath(const char *path, char *resolvedPath);
extern int SysUmask(int mask); extern int SysUmask(int mask);
extern int SysShellExec(const char *msgName, const char *cmdString); extern int SysShellExec(const char *msgName, const char *cmdString);
extern int SysReboot(int magic, int magic2, int type); extern int SysReboot(int magic, int magic2, int type);
extern int SysGetrusage(int what, struct rusage *ru);
#endif #endif
#endif /* _LOS_SYSCALL_H */ #endif /* _LOS_SYSCALL_H */

View File

@ -30,17 +30,21 @@
*/ */
#include "errno.h" #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_process_pri.h"
#include "los_strncpy_from_user.h"
#ifdef LOSCFG_SHELL #ifdef LOSCFG_SHELL
#include "shcmd.h" #include "shcmd.h"
#include "shmsg.h" #include "shmsg.h"
#endif #endif
#include "sys/utsname.h"
#include "sys/reboot.h"
#include "user_copy.h" #include "user_copy.h"
#include "los_strncpy_from_user.h"
#include "capability_type.h"
#include "capability_api.h"
#ifdef __cplusplus #ifdef __cplusplus
#if __cplusplus #if __cplusplus
@ -67,6 +71,25 @@ int SysUname(struct utsname *name)
return ret; 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) int SysReboot(int magic, int magic2, int type)
{ {
(void)magic; (void)magic;
@ -127,6 +150,54 @@ int SysShellExec(const char *msgName, const char *cmdString)
} }
#endif #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 #ifdef __cplusplus
#if __cplusplus #if __cplusplus
} }

View File

@ -312,6 +312,11 @@ int SysFork(void)
return OsClone(0, 0, 0); return OsClone(0, 0, 0);
} }
int SysVfork(void)
{
return OsClone(CLONE_VFORK, 0, 0);
}
unsigned int SysGetPPID(void) unsigned int SysGetPPID(void)
{ {
return OsCurrProcessGet()->parentProcessID; return OsCurrProcessGet()->parentProcessID;

View File

@ -43,6 +43,7 @@ SYSCALL_HAND_DEF(__NR_unlink, SysUnlink, int, ARG_NUM_1)
SYSCALL_HAND_DEF(__NR_execve, SysExecve, int, ARG_NUM_3) SYSCALL_HAND_DEF(__NR_execve, SysExecve, int, ARG_NUM_3)
#endif #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_chdir, SysChdir, int, ARG_NUM_1)
SYSCALL_HAND_DEF(__NR_chmod, SysChmod, int, ARG_NUM_2) 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 */ 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_stat, SysStat, int, ARG_NUM_2)
SYSCALL_HAND_DEF(__NR_lstat, SysLstat, 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_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_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__llseek, SysLseek64, off64_t, ARG_NUM_5) /* current only support 32bit max 4G file */
SYSCALL_HAND_DEF(__NR__newselect, SysSelect, int, ARG_NUM_5) 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_exit, SysThreadExit, void, ARG_NUM_1)
SYSCALL_HAND_DEF(__NR_fork, SysFork, int, ARG_NUM_0) 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_getpid, SysGetPID, unsigned int, ARG_NUM_0)
SYSCALL_HAND_DEF(__NR_pause, SysPause, 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_join, SysThreadJoin, int, ARG_NUM_1)
SYSCALL_HAND_DEF(__NR_pthread_deatch, SysUserThreadDetach, 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_creat_user_thread, SysCreateUserThread, unsigned int, ARG_NUM_3)
SYSCALL_HAND_DEF(__NR_getrusage, SysGetrusage, int, ARG_NUM_2)