fix: L1 toybox 命令功能实现
【背景】 解决toybox已支持命令的遗留问题,新增命令功能。 【修改方案】 1. 在内核态对toybox的系统调用进行支持。 【影响】 对现有的产品编译不会有影响。 re #I41N2A Signed-off-by: wangchen <253227059@qq.com>
This commit is contained in:
@@ -29,11 +29,13 @@
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "syscall_pub.h"
|
||||
#ifdef LOSCFG_FS_VFS
|
||||
#include "errno.h"
|
||||
#include "unistd.h"
|
||||
#include "fs/fd_table.h"
|
||||
#include "fs/file.h"
|
||||
#include "fs/fs.h"
|
||||
#include "fs/fs_operation.h"
|
||||
#include "sys/mount.h"
|
||||
#include "los_task_pri.h"
|
||||
@@ -56,29 +58,77 @@
|
||||
#include "sys/statfs.h"
|
||||
|
||||
#define HIGH_SHIFT_BIT 32
|
||||
#define TIMESPEC_TIMES_NUM 2
|
||||
|
||||
static int UserPathCopy(const char *userPath, char **pathBuf)
|
||||
static int CheckNewAttrTime(struct IATTR *attr, struct timespec times[TIMESPEC_TIMES_NUM])
|
||||
{
|
||||
int ret = ENOERR;
|
||||
struct timespec stp = {0};
|
||||
|
||||
if (times) {
|
||||
if (times[0].tv_nsec == UTIME_OMIT) {
|
||||
attr->attr_chg_valid &= ~CHG_ATIME;
|
||||
} else if (times[0].tv_nsec == UTIME_NOW) {
|
||||
ret = clock_gettime(CLOCK_REALTIME, &stp);
|
||||
if (ret < 0) {
|
||||
return -get_errno();
|
||||
}
|
||||
attr->attr_chg_atime = (unsigned int)stp.tv_sec;
|
||||
attr->attr_chg_valid |= CHG_ATIME;
|
||||
} else {
|
||||
attr->attr_chg_atime = (unsigned int)times[0].tv_sec;
|
||||
attr->attr_chg_valid |= CHG_ATIME;
|
||||
}
|
||||
|
||||
if (times[1].tv_nsec == UTIME_OMIT) {
|
||||
attr->attr_chg_valid &= ~CHG_MTIME;
|
||||
} else if (times[1].tv_nsec == UTIME_NOW) {
|
||||
ret = clock_gettime(CLOCK_REALTIME, &stp);
|
||||
if (ret < 0) {
|
||||
return -get_errno();
|
||||
}
|
||||
attr->attr_chg_mtime = (unsigned int)stp.tv_sec;
|
||||
attr->attr_chg_valid |= CHG_MTIME;
|
||||
} else {
|
||||
attr->attr_chg_mtime = (unsigned int)times[1].tv_sec;
|
||||
attr->attr_chg_valid |= CHG_MTIME;
|
||||
}
|
||||
} else {
|
||||
ret = clock_gettime(CLOCK_REALTIME, &stp);
|
||||
if (ret < 0) {
|
||||
return -get_errno();
|
||||
}
|
||||
attr->attr_chg_atime = (unsigned int)stp.tv_sec;
|
||||
attr->attr_chg_mtime = (unsigned int)stp.tv_sec;
|
||||
attr->attr_chg_valid |= CHG_ATIME;
|
||||
attr->attr_chg_valid |= CHG_MTIME;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int GetFullpathNull(int fd, const char *path, char **filePath)
|
||||
{
|
||||
int ret;
|
||||
char *fullPath = NULL;
|
||||
struct file *file = NULL;
|
||||
|
||||
*pathBuf = (char *)LOS_MemAlloc(OS_SYS_MEM_ADDR, PATH_MAX + 1);
|
||||
if (*pathBuf == NULL) {
|
||||
return -ENOMEM;
|
||||
if ((fd != AT_FDCWD) && (path == NULL)) {
|
||||
fd = GetAssociatedSystemFd(fd);
|
||||
ret = fs_getfilep(fd, &file);
|
||||
if (ret < 0) {
|
||||
return -get_errno();
|
||||
}
|
||||
fullPath = file->f_path;
|
||||
} else {
|
||||
ret = GetFullpath(fd, path, &fullPath);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
ret = LOS_StrncpyFromUser(*pathBuf, userPath, PATH_MAX + 1);
|
||||
if (ret < 0) {
|
||||
(void)LOS_MemFree(OS_SYS_MEM_ADDR, *pathBuf);
|
||||
*pathBuf = NULL;
|
||||
return ret;
|
||||
} else if (ret > PATH_MAX) {
|
||||
(void)LOS_MemFree(OS_SYS_MEM_ADDR, *pathBuf);
|
||||
*pathBuf = NULL;
|
||||
return -ENAMETOOLONG;
|
||||
}
|
||||
(*pathBuf)[ret] = '\0';
|
||||
|
||||
return 0;
|
||||
*filePath = fullPath;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int UserIovItemCheck(const struct iovec *iov, const int iovcnt)
|
||||
@@ -2124,6 +2174,37 @@ OUT:
|
||||
return result;
|
||||
}
|
||||
|
||||
int SysUtimensat(int fd, const char *path, struct timespec times[TIMESPEC_TIMES_NUM], int flag)
|
||||
{
|
||||
int ret;
|
||||
int timeLen;
|
||||
struct IATTR attr = {0};
|
||||
char *filePath = NULL;
|
||||
|
||||
timeLen = TIMESPEC_TIMES_NUM * sizeof(struct timespec);
|
||||
CHECK_ASPACE(times, timeLen);
|
||||
DUP_FROM_USER(times, timeLen);
|
||||
ret = CheckNewAttrTime(&attr, times);
|
||||
FREE_DUP(times);
|
||||
if (ret < 0) {
|
||||
goto OUT;
|
||||
}
|
||||
|
||||
ret = GetFullpathNull(fd, path, &filePath);
|
||||
if (ret < 0) {
|
||||
goto OUT;
|
||||
}
|
||||
|
||||
ret = chattr(filePath, &attr);
|
||||
if (ret < 0) {
|
||||
ret = -get_errno();
|
||||
}
|
||||
|
||||
OUT:
|
||||
PointerFree(filePath);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SysChmod(const char *pathname, mode_t mode)
|
||||
{
|
||||
int ret;
|
||||
@@ -2148,6 +2229,112 @@ OUT:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SysFchmodat(int fd, const char *path, mode_t mode, int flag)
|
||||
{
|
||||
int ret;
|
||||
char *pathRet = NULL;
|
||||
char *fullpath = NULL;
|
||||
struct IATTR attr = {
|
||||
.attr_chg_mode = mode,
|
||||
.attr_chg_valid = CHG_MODE,
|
||||
};
|
||||
|
||||
if (path != NULL) {
|
||||
ret = UserPathCopy(path, &pathRet);
|
||||
if (ret != 0) {
|
||||
goto OUT;
|
||||
}
|
||||
}
|
||||
|
||||
if (fd != AT_FDCWD) {
|
||||
/* Process fd convert to system global fd */
|
||||
fd = GetAssociatedSystemFd(fd);
|
||||
}
|
||||
|
||||
ret = vfs_normalize_pathat(fd, pathRet, &fullpath);
|
||||
if (ret < 0) {
|
||||
goto OUT;
|
||||
}
|
||||
|
||||
ret = chattr(fullpath, &attr);
|
||||
if (ret < 0) {
|
||||
ret = -get_errno();
|
||||
}
|
||||
|
||||
OUT:
|
||||
PointerFree(pathRet);
|
||||
PointerFree(fullpath);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SysFchownat(int fd, const char *path, uid_t owner, gid_t group, int flag)
|
||||
{
|
||||
int ret;
|
||||
char *fullpath = NULL;
|
||||
struct IATTR attr = {
|
||||
.attr_chg_valid = 0,
|
||||
};
|
||||
|
||||
ret = GetFullpath(fd, path, &fullpath);
|
||||
if (ret < 0) {
|
||||
goto OUT;
|
||||
}
|
||||
|
||||
if (owner != (uid_t)-1) {
|
||||
attr.attr_chg_uid = owner;
|
||||
attr.attr_chg_valid |= CHG_UID;
|
||||
}
|
||||
if (group != (gid_t)-1) {
|
||||
attr.attr_chg_gid = group;
|
||||
attr.attr_chg_valid |= CHG_GID;
|
||||
}
|
||||
|
||||
ret = chattr(fullpath, &attr);
|
||||
if (ret < 0) {
|
||||
ret = -get_errno();
|
||||
}
|
||||
|
||||
OUT:
|
||||
PointerFree(fullpath);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SysFchown(int fd, uid_t owner, gid_t group)
|
||||
{
|
||||
int ret;
|
||||
int sysFd;
|
||||
struct IATTR attr = {0};
|
||||
attr.attr_chg_valid = 0;
|
||||
struct file *file = NULL;
|
||||
|
||||
sysFd = GetAssociatedSystemFd(fd);
|
||||
if (sysFd < 0) {
|
||||
return -EBADF;
|
||||
}
|
||||
|
||||
ret = fs_getfilep(sysFd, &file);
|
||||
if (ret < 0) {
|
||||
return -get_errno();
|
||||
}
|
||||
|
||||
if (owner != (uid_t)-1) {
|
||||
attr.attr_chg_uid = owner;
|
||||
attr.attr_chg_valid |= CHG_UID;
|
||||
}
|
||||
if (group != (gid_t)-1) {
|
||||
attr.attr_chg_gid = group;
|
||||
attr.attr_chg_valid |= CHG_GID;
|
||||
}
|
||||
ret = chattr(file->f_path, &attr);
|
||||
if (ret < 0) {
|
||||
ret = -get_errno();
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SysChown(const char *pathname, uid_t owner, gid_t group)
|
||||
{
|
||||
int ret;
|
||||
@@ -2218,4 +2405,43 @@ OUT:
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SysFaccessat(int fd, const char *filename, int amode, int flag)
|
||||
{
|
||||
int ret;
|
||||
struct stat buf;
|
||||
struct statfs fsBuf;
|
||||
char *fullDirectory = NULL;
|
||||
|
||||
ret = GetFullpath(fd, filename, &fullDirectory);
|
||||
if (ret < 0) {
|
||||
goto OUT;
|
||||
}
|
||||
|
||||
ret = statfs(fullDirectory, &fsBuf);
|
||||
if (ret != 0) {
|
||||
ret = -get_errno();
|
||||
goto OUT;
|
||||
}
|
||||
|
||||
if ((fsBuf.f_flags & MS_RDONLY) && ((unsigned int)amode & W_OK)) {
|
||||
ret = -EROFS;
|
||||
goto OUT;
|
||||
}
|
||||
|
||||
ret = stat(fullDirectory, &buf);
|
||||
if (ret != 0) {
|
||||
ret = -get_errno();
|
||||
goto OUT;
|
||||
}
|
||||
|
||||
if (VfsPermissionCheck(buf.st_uid, buf.st_gid, buf.st_mode, amode)) {
|
||||
ret = -EACCES;
|
||||
}
|
||||
|
||||
OUT:
|
||||
PointerFree(fullDirectory);
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user