add sys_utimensat (#8124)
This commit is contained in:
parent
a289ae1b18
commit
5d16042765
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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(¤t_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
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue