add sys_utimensat (#8124)

This commit is contained in:
xiao-mang 2023-10-13 19:21:49 +08:00 committed by GitHub
parent a289ae1b18
commit 5d16042765
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 170 additions and 0 deletions

View File

@ -25,6 +25,26 @@
#include <rtatomic.h>
#include <rtdevice.h>
#ifndef ATTR_ATIME_SET
#define ATTR_ATIME_SET (1 << 7)
#endif
#ifndef ATTR_MTIME_SET
#define ATTR_MTIME_SET (1 << 8)
#endif
#ifndef AT_SYMLINK_NOFOLLOW
#define AT_SYMLINK_NOFOLLOW 0x100
#endif
#ifndef UTIME_NOW
#define UTIME_NOW 0x3fffffff
#endif
#ifndef UTIME_OMIT
#define UTIME_OMIT 0x3ffffffe
#endif
#ifndef DFS_FD_MAX
#define DFS_FD_MAX 16
#endif

View File

@ -31,7 +31,10 @@ struct dfs_partition
struct dfs_attr
{
unsigned int ia_valid;
mode_t st_mode;
struct timespec ia_atime;
struct timespec ia_mtime;
};
struct dfs_mnt;

View File

@ -125,6 +125,113 @@ int openat(int dirfd, const char *path, int flag, ...)
return fd;
}
int utimensat(int __fd, const char *__path, const struct timespec __times[2], int __flags)
{
int ret;
struct stat buffer;
struct dfs_file *d;
char *fullpath;
struct dfs_attr attr;
time_t current_time;
char *link_fn = (char *)rt_malloc(DFS_PATH_MAX);
int err;
if (__path == NULL)
{
return -EFAULT;
}
if (__path[0] == '/' || __fd == AT_FDCWD)
{
if (stat(__path, &buffer) < 0)
{
return -ENOENT;
}
else
{
fullpath = (char*)__path;
}
}
else
{
if (__fd != AT_FDCWD)
{
d = fd_get(__fd);
if (!d || !d->vnode)
{
return -EBADF;
}
fullpath = dfs_dentry_full_path(d->dentry);
if (!fullpath)
{
rt_set_errno(-ENOMEM);
return -1;
}
}
}
//update time
attr.ia_valid = ATTR_ATIME_SET | ATTR_MTIME_SET;
time(&current_time);
if (UTIME_NOW == __times[0].tv_nsec)
{
attr.ia_atime.tv_sec = current_time;
}
else if (UTIME_OMIT != __times[0].tv_nsec)
{
attr.ia_atime.tv_sec = __times[0].tv_sec;
}
else
{
attr.ia_valid &= ~ATTR_ATIME_SET;
}
if (UTIME_NOW == __times[1].tv_nsec)
{
attr.ia_mtime.tv_sec = current_time;
}
else if (UTIME_OMIT == __times[1].tv_nsec)
{
attr.ia_mtime.tv_sec = __times[1].tv_sec;
}
else
{
attr.ia_valid &= ~ATTR_MTIME_SET;
}
if (dfs_file_lstat(fullpath, &buffer) == 0)
{
if (S_ISLNK(buffer.st_mode) && (__flags != AT_SYMLINK_NOFOLLOW))
{
if (link_fn)
{
err = dfs_file_readlink(fullpath, link_fn, DFS_PATH_MAX);
if (err < 0)
{
rt_free(link_fn);
return -ENOENT;
}
else
{
fullpath = link_fn;
if (dfs_file_stat(fullpath, &buffer) != 0)
{
rt_free(link_fn);
return -ENOENT;
}
}
}
}
}
attr.st_mode = buffer.st_mode;
ret = dfs_file_setattr(fullpath, &attr);
rt_free(link_fn);
return ret;
}
/**
* this function is a POSIX compliant version,
* which will create a new file or rewrite an existing one

View File

@ -6135,6 +6135,45 @@ sysret_t sys_ftruncate(int fd, off_t length)
return (ret < 0 ? GET_ERRNO() : ret);
}
sysret_t sys_utimensat(int __fd, const char *__path, const struct timespec __times[2], int __flags)
{
#ifdef RT_USING_DFS_V2
#ifdef ARCH_MM_MMU
int ret = -1;
rt_size_t len = 0;
char *kpath = RT_NULL;
len = lwp_user_strlen(__path);
if (len <= 0)
{
return -EINVAL;
}
kpath = (char *)kmem_get(len + 1);
if (!kpath)
{
return -ENOMEM;
}
lwp_get_from_user(kpath, (void *)__path, len + 1);
ret = utimensat(__fd, kpath, __times, __flags);
kmem_put(kpath);
return ret;
#else
if (!lwp_user_accessable((void *)__path, 1))
{
return -EFAULT;
}
int ret = utimensat(__fd, __path, __times, __flags);
return ret;
#endif
#else
return -1;
#endif
}
sysret_t sys_chmod(const char *fileName, mode_t mode)
{
char *copy_fileName;
@ -6661,6 +6700,7 @@ const static struct rt_syscall_def func_table[] =
SYSCALL_SIGN(sys_memfd_create), /* 200 */
SYSCALL_SIGN(sys_ftruncate),
SYSCALL_SIGN(sys_setitimer),
SYSCALL_SIGN(sys_utimensat),
};
const void *lwp_get_sys_api(rt_uint32_t number)