mirror of https://github.com/RT-Thread/rt-thread
add sys_utimensat (#8124)
This commit is contained in:
parent
a289ae1b18
commit
5d16042765
|
@ -25,6 +25,26 @@
|
||||||
#include <rtatomic.h>
|
#include <rtatomic.h>
|
||||||
#include <rtdevice.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
|
#ifndef DFS_FD_MAX
|
||||||
#define DFS_FD_MAX 16
|
#define DFS_FD_MAX 16
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -31,7 +31,10 @@ struct dfs_partition
|
||||||
|
|
||||||
struct dfs_attr
|
struct dfs_attr
|
||||||
{
|
{
|
||||||
|
unsigned int ia_valid;
|
||||||
mode_t st_mode;
|
mode_t st_mode;
|
||||||
|
struct timespec ia_atime;
|
||||||
|
struct timespec ia_mtime;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct dfs_mnt;
|
struct dfs_mnt;
|
||||||
|
|
|
@ -125,6 +125,113 @@ int openat(int dirfd, const char *path, int flag, ...)
|
||||||
return fd;
|
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,
|
* this function is a POSIX compliant version,
|
||||||
* which will create a new file or rewrite an existing one
|
* 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);
|
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)
|
sysret_t sys_chmod(const char *fileName, mode_t mode)
|
||||||
{
|
{
|
||||||
char *copy_fileName;
|
char *copy_fileName;
|
||||||
|
@ -6661,6 +6700,7 @@ const static struct rt_syscall_def func_table[] =
|
||||||
SYSCALL_SIGN(sys_memfd_create), /* 200 */
|
SYSCALL_SIGN(sys_memfd_create), /* 200 */
|
||||||
SYSCALL_SIGN(sys_ftruncate),
|
SYSCALL_SIGN(sys_ftruncate),
|
||||||
SYSCALL_SIGN(sys_setitimer),
|
SYSCALL_SIGN(sys_setitimer),
|
||||||
|
SYSCALL_SIGN(sys_utimensat),
|
||||||
};
|
};
|
||||||
|
|
||||||
const void *lwp_get_sys_api(rt_uint32_t number)
|
const void *lwp_get_sys_api(rt_uint32_t number)
|
||||||
|
|
Loading…
Reference in New Issue