mirror of
https://github.com/RT-Thread/rt-thread.git
synced 2026-09-24 05:04:10 +08:00
add sys_utimensat (#8124)
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user