diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 13:54:38 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 13:54:38 +0000 |
commit | 8c1ab65c0f548d20b7f177bdb736daaf603340e1 (patch) | |
tree | df55b7e75bf43f2bf500845b105afe3ac3a5157e /libc-top-half/musl/src/stat | |
parent | Initial commit. (diff) | |
download | wasi-libc-8c1ab65c0f548d20b7f177bdb736daaf603340e1.tar.xz wasi-libc-8c1ab65c0f548d20b7f177bdb736daaf603340e1.zip |
Adding upstream version 0.0~git20221206.8b7148f.upstream/0.0_git20221206.8b7148f
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'libc-top-half/musl/src/stat')
-rw-r--r-- | libc-top-half/musl/src/stat/__xstat.c | 40 | ||||
-rw-r--r-- | libc-top-half/musl/src/stat/chmod.c | 12 | ||||
-rw-r--r-- | libc-top-half/musl/src/stat/fchmod.c | 19 | ||||
-rw-r--r-- | libc-top-half/musl/src/stat/fchmodat.c | 38 | ||||
-rw-r--r-- | libc-top-half/musl/src/stat/fstat.c | 15 | ||||
-rw-r--r-- | libc-top-half/musl/src/stat/fstatat.c | 147 | ||||
-rw-r--r-- | libc-top-half/musl/src/stat/futimens.c | 6 | ||||
-rw-r--r-- | libc-top-half/musl/src/stat/futimesat.c | 31 | ||||
-rw-r--r-- | libc-top-half/musl/src/stat/lchmod.c | 8 | ||||
-rw-r--r-- | libc-top-half/musl/src/stat/lstat.c | 11 | ||||
-rw-r--r-- | libc-top-half/musl/src/stat/mkdir.c | 12 | ||||
-rw-r--r-- | libc-top-half/musl/src/stat/mkdirat.c | 7 | ||||
-rw-r--r-- | libc-top-half/musl/src/stat/mkfifo.c | 6 | ||||
-rw-r--r-- | libc-top-half/musl/src/stat/mkfifoat.c | 6 | ||||
-rw-r--r-- | libc-top-half/musl/src/stat/mknod.c | 12 | ||||
-rw-r--r-- | libc-top-half/musl/src/stat/mknodat.c | 7 | ||||
-rw-r--r-- | libc-top-half/musl/src/stat/stat.c | 11 | ||||
-rw-r--r-- | libc-top-half/musl/src/stat/statvfs.c | 63 | ||||
-rw-r--r-- | libc-top-half/musl/src/stat/umask.c | 7 | ||||
-rw-r--r-- | libc-top-half/musl/src/stat/utimensat.c | 60 |
20 files changed, 518 insertions, 0 deletions
diff --git a/libc-top-half/musl/src/stat/__xstat.c b/libc-top-half/musl/src/stat/__xstat.c new file mode 100644 index 0000000..630936a --- /dev/null +++ b/libc-top-half/musl/src/stat/__xstat.c @@ -0,0 +1,40 @@ +#include <sys/stat.h> + +#if !_REDIR_TIME64 + +int __fxstat(int ver, int fd, struct stat *buf) +{ + return fstat(fd, buf); +} + +int __fxstatat(int ver, int fd, const char *path, struct stat *buf, int flag) +{ + return fstatat(fd, path, buf, flag); +} + +int __lxstat(int ver, const char *path, struct stat *buf) +{ + return lstat(path, buf); +} + +int __xstat(int ver, const char *path, struct stat *buf) +{ + return stat(path, buf); +} + +weak_alias(__fxstat, __fxstat64); +weak_alias(__fxstatat, __fxstatat64); +weak_alias(__lxstat, __lxstat64); +weak_alias(__xstat, __xstat64); + +#endif + +int __xmknod(int ver, const char *path, mode_t mode, dev_t *dev) +{ + return mknod(path, mode, *dev); +} + +int __xmknodat(int ver, int fd, const char *path, mode_t mode, dev_t *dev) +{ + return mknodat(fd, path, mode, *dev); +} diff --git a/libc-top-half/musl/src/stat/chmod.c b/libc-top-half/musl/src/stat/chmod.c new file mode 100644 index 0000000..d4f53c5 --- /dev/null +++ b/libc-top-half/musl/src/stat/chmod.c @@ -0,0 +1,12 @@ +#include <sys/stat.h> +#include <fcntl.h> +#include "syscall.h" + +int chmod(const char *path, mode_t mode) +{ +#ifdef SYS_chmod + return syscall(SYS_chmod, path, mode); +#else + return syscall(SYS_fchmodat, AT_FDCWD, path, mode); +#endif +} diff --git a/libc-top-half/musl/src/stat/fchmod.c b/libc-top-half/musl/src/stat/fchmod.c new file mode 100644 index 0000000..7a503ee --- /dev/null +++ b/libc-top-half/musl/src/stat/fchmod.c @@ -0,0 +1,19 @@ +#include <sys/stat.h> +#include <errno.h> +#include <fcntl.h> +#include "syscall.h" + +int fchmod(int fd, mode_t mode) +{ + int ret = __syscall(SYS_fchmod, fd, mode); + if (ret != -EBADF || __syscall(SYS_fcntl, fd, F_GETFD) < 0) + return __syscall_ret(ret); + + char buf[15+3*sizeof(int)]; + __procfdname(buf, fd); +#ifdef SYS_chmod + return syscall(SYS_chmod, buf, mode); +#else + return syscall(SYS_fchmodat, AT_FDCWD, buf, mode); +#endif +} diff --git a/libc-top-half/musl/src/stat/fchmodat.c b/libc-top-half/musl/src/stat/fchmodat.c new file mode 100644 index 0000000..4ee00b0 --- /dev/null +++ b/libc-top-half/musl/src/stat/fchmodat.c @@ -0,0 +1,38 @@ +#include <sys/stat.h> +#include <fcntl.h> +#include <errno.h> +#include "syscall.h" +#include "kstat.h" + +int fchmodat(int fd, const char *path, mode_t mode, int flag) +{ + if (!flag) return syscall(SYS_fchmodat, fd, path, mode, flag); + + if (flag != AT_SYMLINK_NOFOLLOW) + return __syscall_ret(-EINVAL); + + struct kstat st; + int ret, fd2; + char proc[15+3*sizeof(int)]; + + if ((ret = __syscall(SYS_fstatat, fd, path, &st, flag))) + return __syscall_ret(ret); + if (S_ISLNK(st.st_mode)) + return __syscall_ret(-EOPNOTSUPP); + + if ((fd2 = __syscall(SYS_openat, fd, path, O_RDONLY|O_PATH|O_NOFOLLOW|O_NOCTTY|O_CLOEXEC)) < 0) { + if (fd2 == -ELOOP) + return __syscall_ret(-EOPNOTSUPP); + return __syscall_ret(fd2); + } + + __procfdname(proc, fd2); + ret = __syscall(SYS_fstatat, AT_FDCWD, proc, &st, 0); + if (!ret) { + if (S_ISLNK(st.st_mode)) ret = -EOPNOTSUPP; + else ret = __syscall(SYS_fchmodat, AT_FDCWD, proc, mode); + } + + __syscall(SYS_close, fd2); + return __syscall_ret(ret); +} diff --git a/libc-top-half/musl/src/stat/fstat.c b/libc-top-half/musl/src/stat/fstat.c new file mode 100644 index 0000000..9bbb46d --- /dev/null +++ b/libc-top-half/musl/src/stat/fstat.c @@ -0,0 +1,15 @@ +#define _BSD_SOURCE +#include <sys/stat.h> +#include <errno.h> +#include <fcntl.h> +#include "syscall.h" + +int fstat(int fd, struct stat *st) +{ + if (fd<0) return __syscall_ret(-EBADF); + return fstatat(fd, "", st, AT_EMPTY_PATH); +} + +#if !_REDIR_TIME64 +weak_alias(fstat, fstat64); +#endif diff --git a/libc-top-half/musl/src/stat/fstatat.c b/libc-top-half/musl/src/stat/fstatat.c new file mode 100644 index 0000000..de165b5 --- /dev/null +++ b/libc-top-half/musl/src/stat/fstatat.c @@ -0,0 +1,147 @@ +#define _BSD_SOURCE +#include <sys/stat.h> +#include <string.h> +#include <fcntl.h> +#include <errno.h> +#include <stdint.h> +#include <sys/sysmacros.h> +#include "syscall.h" +#include "kstat.h" + +struct statx { + uint32_t stx_mask; + uint32_t stx_blksize; + uint64_t stx_attributes; + uint32_t stx_nlink; + uint32_t stx_uid; + uint32_t stx_gid; + uint16_t stx_mode; + uint16_t pad1; + uint64_t stx_ino; + uint64_t stx_size; + uint64_t stx_blocks; + uint64_t stx_attributes_mask; + struct { + int64_t tv_sec; + uint32_t tv_nsec; + int32_t pad; + } stx_atime, stx_btime, stx_ctime, stx_mtime; + uint32_t stx_rdev_major; + uint32_t stx_rdev_minor; + uint32_t stx_dev_major; + uint32_t stx_dev_minor; + uint64_t spare[14]; +}; + +static int fstatat_statx(int fd, const char *restrict path, struct stat *restrict st, int flag) +{ + struct statx stx; + + int ret = __syscall(SYS_statx, fd, path, flag, 0x7ff, &stx); + if (ret) return ret; + + *st = (struct stat){ + .st_dev = makedev(stx.stx_dev_major, stx.stx_dev_minor), + .st_ino = stx.stx_ino, + .st_mode = stx.stx_mode, + .st_nlink = stx.stx_nlink, + .st_uid = stx.stx_uid, + .st_gid = stx.stx_gid, + .st_rdev = makedev(stx.stx_rdev_major, stx.stx_rdev_minor), + .st_size = stx.stx_size, + .st_blksize = stx.stx_blksize, + .st_blocks = stx.stx_blocks, + .st_atim.tv_sec = stx.stx_atime.tv_sec, + .st_atim.tv_nsec = stx.stx_atime.tv_nsec, + .st_mtim.tv_sec = stx.stx_mtime.tv_sec, + .st_mtim.tv_nsec = stx.stx_mtime.tv_nsec, + .st_ctim.tv_sec = stx.stx_ctime.tv_sec, + .st_ctim.tv_nsec = stx.stx_ctime.tv_nsec, +#if _REDIR_TIME64 + .__st_atim32.tv_sec = stx.stx_atime.tv_sec, + .__st_atim32.tv_nsec = stx.stx_atime.tv_nsec, + .__st_mtim32.tv_sec = stx.stx_mtime.tv_sec, + .__st_mtim32.tv_nsec = stx.stx_mtime.tv_nsec, + .__st_ctim32.tv_sec = stx.stx_ctime.tv_sec, + .__st_ctim32.tv_nsec = stx.stx_ctime.tv_nsec, +#endif + }; + return 0; +} + +static int fstatat_kstat(int fd, const char *restrict path, struct stat *restrict st, int flag) +{ + int ret; + struct kstat kst; + + if (flag==AT_EMPTY_PATH && fd>=0 && !*path) { + ret = __syscall(SYS_fstat, fd, &kst); + if (ret==-EBADF && __syscall(SYS_fcntl, fd, F_GETFD)>=0) { + ret = __syscall(SYS_fstatat, fd, path, &kst, flag); + if (ret==-EINVAL) { + char buf[15+3*sizeof(int)]; + __procfdname(buf, fd); +#ifdef SYS_stat + ret = __syscall(SYS_stat, buf, &kst); +#else + ret = __syscall(SYS_fstatat, AT_FDCWD, buf, &kst, 0); +#endif + } + } + } +#ifdef SYS_lstat + else if ((fd == AT_FDCWD || *path=='/') && flag==AT_SYMLINK_NOFOLLOW) + ret = __syscall(SYS_lstat, path, &kst); +#endif +#ifdef SYS_stat + else if ((fd == AT_FDCWD || *path=='/') && !flag) + ret = __syscall(SYS_stat, path, &kst); +#endif + else ret = __syscall(SYS_fstatat, fd, path, &kst, flag); + + if (ret) return ret; + + *st = (struct stat){ + .st_dev = kst.st_dev, + .st_ino = kst.st_ino, + .st_mode = kst.st_mode, + .st_nlink = kst.st_nlink, + .st_uid = kst.st_uid, + .st_gid = kst.st_gid, + .st_rdev = kst.st_rdev, + .st_size = kst.st_size, + .st_blksize = kst.st_blksize, + .st_blocks = kst.st_blocks, + .st_atim.tv_sec = kst.st_atime_sec, + .st_atim.tv_nsec = kst.st_atime_nsec, + .st_mtim.tv_sec = kst.st_mtime_sec, + .st_mtim.tv_nsec = kst.st_mtime_nsec, + .st_ctim.tv_sec = kst.st_ctime_sec, + .st_ctim.tv_nsec = kst.st_ctime_nsec, +#if _REDIR_TIME64 + .__st_atim32.tv_sec = kst.st_atime_sec, + .__st_atim32.tv_nsec = kst.st_atime_nsec, + .__st_mtim32.tv_sec = kst.st_mtime_sec, + .__st_mtim32.tv_nsec = kst.st_mtime_nsec, + .__st_ctim32.tv_sec = kst.st_ctime_sec, + .__st_ctim32.tv_nsec = kst.st_ctime_nsec, +#endif + }; + + return 0; +} + +int fstatat(int fd, const char *restrict path, struct stat *restrict st, int flag) +{ + int ret; + if (sizeof((struct kstat){0}.st_atime_sec) < sizeof(time_t)) { + ret = fstatat_statx(fd, path, st, flag); + if (ret!=-ENOSYS) return __syscall_ret(ret); + } + ret = fstatat_kstat(fd, path, st, flag); + return __syscall_ret(ret); +} + +#if !_REDIR_TIME64 +weak_alias(fstatat, fstatat64); +#endif diff --git a/libc-top-half/musl/src/stat/futimens.c b/libc-top-half/musl/src/stat/futimens.c new file mode 100644 index 0000000..360225b --- /dev/null +++ b/libc-top-half/musl/src/stat/futimens.c @@ -0,0 +1,6 @@ +#include <sys/stat.h> + +int futimens(int fd, const struct timespec times[2]) +{ + return utimensat(fd, 0, times, 0); +} diff --git a/libc-top-half/musl/src/stat/futimesat.c b/libc-top-half/musl/src/stat/futimesat.c new file mode 100644 index 0000000..c29b2b7 --- /dev/null +++ b/libc-top-half/musl/src/stat/futimesat.c @@ -0,0 +1,31 @@ +#define _GNU_SOURCE +#include <sys/time.h> +#include <sys/stat.h> +#include <errno.h> +#ifdef __wasilibc_unmodified_upstream // WASI has no syscall +#include "syscall.h" +#endif + +int __futimesat(int dirfd, const char *pathname, const struct timeval times[2]) +{ + struct timespec ts[2]; + if (times) { + int i; + for (i=0; i<2; i++) { +#ifdef __wasilibc_unmodified_upstream // WASI has no syscall + if (times[i].tv_usec >= 1000000ULL) + return __syscall_ret(-EINVAL); +#else + if (times[i].tv_usec >= 1000000ULL) { + errno = EINVAL; + return -1; + } +#endif + ts[i].tv_sec = times[i].tv_sec; + ts[i].tv_nsec = times[i].tv_usec * 1000; + } + } + return utimensat(dirfd, pathname, times ? ts : 0, 0); +} + +weak_alias(__futimesat, futimesat); diff --git a/libc-top-half/musl/src/stat/lchmod.c b/libc-top-half/musl/src/stat/lchmod.c new file mode 100644 index 0000000..f324ba7 --- /dev/null +++ b/libc-top-half/musl/src/stat/lchmod.c @@ -0,0 +1,8 @@ +#define _GNU_SOURCE +#include <sys/stat.h> +#include <fcntl.h> + +int lchmod(const char *path, mode_t mode) +{ + return fchmodat(AT_FDCWD, path, mode, AT_SYMLINK_NOFOLLOW); +} diff --git a/libc-top-half/musl/src/stat/lstat.c b/libc-top-half/musl/src/stat/lstat.c new file mode 100644 index 0000000..6fe004d --- /dev/null +++ b/libc-top-half/musl/src/stat/lstat.c @@ -0,0 +1,11 @@ +#include <sys/stat.h> +#include <fcntl.h> + +int lstat(const char *restrict path, struct stat *restrict buf) +{ + return fstatat(AT_FDCWD, path, buf, AT_SYMLINK_NOFOLLOW); +} + +#if !_REDIR_TIME64 +weak_alias(lstat, lstat64); +#endif diff --git a/libc-top-half/musl/src/stat/mkdir.c b/libc-top-half/musl/src/stat/mkdir.c new file mode 100644 index 0000000..32625b7 --- /dev/null +++ b/libc-top-half/musl/src/stat/mkdir.c @@ -0,0 +1,12 @@ +#include <sys/stat.h> +#include <fcntl.h> +#include "syscall.h" + +int mkdir(const char *path, mode_t mode) +{ +#ifdef SYS_mkdir + return syscall(SYS_mkdir, path, mode); +#else + return syscall(SYS_mkdirat, AT_FDCWD, path, mode); +#endif +} diff --git a/libc-top-half/musl/src/stat/mkdirat.c b/libc-top-half/musl/src/stat/mkdirat.c new file mode 100644 index 0000000..b8bc252 --- /dev/null +++ b/libc-top-half/musl/src/stat/mkdirat.c @@ -0,0 +1,7 @@ +#include <sys/stat.h> +#include "syscall.h" + +int mkdirat(int fd, const char *path, mode_t mode) +{ + return syscall(SYS_mkdirat, fd, path, mode); +} diff --git a/libc-top-half/musl/src/stat/mkfifo.c b/libc-top-half/musl/src/stat/mkfifo.c new file mode 100644 index 0000000..60efcf7 --- /dev/null +++ b/libc-top-half/musl/src/stat/mkfifo.c @@ -0,0 +1,6 @@ +#include <sys/stat.h> + +int mkfifo(const char *path, mode_t mode) +{ + return mknod(path, mode | S_IFIFO, 0); +} diff --git a/libc-top-half/musl/src/stat/mkfifoat.c b/libc-top-half/musl/src/stat/mkfifoat.c new file mode 100644 index 0000000..d3a1f97 --- /dev/null +++ b/libc-top-half/musl/src/stat/mkfifoat.c @@ -0,0 +1,6 @@ +#include <sys/stat.h> + +int mkfifoat(int fd, const char *path, mode_t mode) +{ + return mknodat(fd, path, mode | S_IFIFO, 0); +} diff --git a/libc-top-half/musl/src/stat/mknod.c b/libc-top-half/musl/src/stat/mknod.c new file mode 100644 index 0000000..beebd84 --- /dev/null +++ b/libc-top-half/musl/src/stat/mknod.c @@ -0,0 +1,12 @@ +#include <sys/stat.h> +#include <fcntl.h> +#include "syscall.h" + +int mknod(const char *path, mode_t mode, dev_t dev) +{ +#ifdef SYS_mknod + return syscall(SYS_mknod, path, mode, dev); +#else + return syscall(SYS_mknodat, AT_FDCWD, path, mode, dev); +#endif +} diff --git a/libc-top-half/musl/src/stat/mknodat.c b/libc-top-half/musl/src/stat/mknodat.c new file mode 100644 index 0000000..7c97c91 --- /dev/null +++ b/libc-top-half/musl/src/stat/mknodat.c @@ -0,0 +1,7 @@ +#include <sys/stat.h> +#include "syscall.h" + +int mknodat(int fd, const char *path, mode_t mode, dev_t dev) +{ + return syscall(SYS_mknodat, fd, path, mode, dev); +} diff --git a/libc-top-half/musl/src/stat/stat.c b/libc-top-half/musl/src/stat/stat.c new file mode 100644 index 0000000..ea70efc --- /dev/null +++ b/libc-top-half/musl/src/stat/stat.c @@ -0,0 +1,11 @@ +#include <sys/stat.h> +#include <fcntl.h> + +int stat(const char *restrict path, struct stat *restrict buf) +{ + return fstatat(AT_FDCWD, path, buf, 0); +} + +#if !_REDIR_TIME64 +weak_alias(stat, stat64); +#endif diff --git a/libc-top-half/musl/src/stat/statvfs.c b/libc-top-half/musl/src/stat/statvfs.c new file mode 100644 index 0000000..f65d1b5 --- /dev/null +++ b/libc-top-half/musl/src/stat/statvfs.c @@ -0,0 +1,63 @@ +#include <sys/statvfs.h> +#include <sys/statfs.h> +#include "syscall.h" + +static int __statfs(const char *path, struct statfs *buf) +{ + *buf = (struct statfs){0}; +#ifdef SYS_statfs64 + return syscall(SYS_statfs64, path, sizeof *buf, buf); +#else + return syscall(SYS_statfs, path, buf); +#endif +} + +static int __fstatfs(int fd, struct statfs *buf) +{ + *buf = (struct statfs){0}; +#ifdef SYS_fstatfs64 + return syscall(SYS_fstatfs64, fd, sizeof *buf, buf); +#else + return syscall(SYS_fstatfs, fd, buf); +#endif +} + +weak_alias(__statfs, statfs); +weak_alias(__fstatfs, fstatfs); + +static void fixup(struct statvfs *out, const struct statfs *in) +{ + *out = (struct statvfs){0}; + out->f_bsize = in->f_bsize; + out->f_frsize = in->f_frsize ? in->f_frsize : in->f_bsize; + out->f_blocks = in->f_blocks; + out->f_bfree = in->f_bfree; + out->f_bavail = in->f_bavail; + out->f_files = in->f_files; + out->f_ffree = in->f_ffree; + out->f_favail = in->f_ffree; + out->f_fsid = in->f_fsid.__val[0]; + out->f_flag = in->f_flags; + out->f_namemax = in->f_namelen; +} + +int statvfs(const char *restrict path, struct statvfs *restrict buf) +{ + struct statfs kbuf; + if (__statfs(path, &kbuf)<0) return -1; + fixup(buf, &kbuf); + return 0; +} + +int fstatvfs(int fd, struct statvfs *buf) +{ + struct statfs kbuf; + if (__fstatfs(fd, &kbuf)<0) return -1; + fixup(buf, &kbuf); + return 0; +} + +weak_alias(statvfs, statvfs64); +weak_alias(statfs, statfs64); +weak_alias(fstatvfs, fstatvfs64); +weak_alias(fstatfs, fstatfs64); diff --git a/libc-top-half/musl/src/stat/umask.c b/libc-top-half/musl/src/stat/umask.c new file mode 100644 index 0000000..5ee913e --- /dev/null +++ b/libc-top-half/musl/src/stat/umask.c @@ -0,0 +1,7 @@ +#include <sys/stat.h> +#include "syscall.h" + +mode_t umask(mode_t mode) +{ + return syscall(SYS_umask, mode); +} diff --git a/libc-top-half/musl/src/stat/utimensat.c b/libc-top-half/musl/src/stat/utimensat.c new file mode 100644 index 0000000..730723a --- /dev/null +++ b/libc-top-half/musl/src/stat/utimensat.c @@ -0,0 +1,60 @@ +#include <sys/stat.h> +#include <sys/time.h> +#include <fcntl.h> +#include <errno.h> +#include "syscall.h" + +#define IS32BIT(x) !((x)+0x80000000ULL>>32) +#define NS_SPECIAL(ns) ((ns)==UTIME_NOW || (ns)==UTIME_OMIT) + +int utimensat(int fd, const char *path, const struct timespec times[2], int flags) +{ + int r; + if (times && times[0].tv_nsec==UTIME_NOW && times[1].tv_nsec==UTIME_NOW) + times = 0; +#ifdef SYS_utimensat_time64 + r = -ENOSYS; + time_t s0=0, s1=0; + long ns0=0, ns1=0; + if (times) { + ns0 = times[0].tv_nsec; + ns1 = times[1].tv_nsec; + if (!NS_SPECIAL(ns0)) s0 = times[0].tv_sec; + if (!NS_SPECIAL(ns1)) s1 = times[1].tv_sec; + } + if (SYS_utimensat == SYS_utimensat_time64 || !IS32BIT(s0) || !IS32BIT(s1)) + r = __syscall(SYS_utimensat_time64, fd, path, times ? + ((long long[]){s0, ns0, s1, ns1}) : 0, flags); + if (SYS_utimensat == SYS_utimensat_time64 || r!=-ENOSYS) + return __syscall_ret(r); + if (!IS32BIT(s0) || !IS32BIT(s1)) + return __syscall_ret(-ENOTSUP); + r = __syscall(SYS_utimensat, fd, path, + times ? ((long[]){s0, ns0, s1, ns1}) : 0, flags); +#else + r = __syscall(SYS_utimensat, fd, path, times, flags); +#endif + +#ifdef SYS_futimesat + if (r != -ENOSYS || flags) return __syscall_ret(r); + long *tv=0, tmp[4]; + if (times) { + int i; + tv = tmp; + for (i=0; i<2; i++) { + if (times[i].tv_nsec >= 1000000000ULL) { + if (NS_SPECIAL(times[i].tv_nsec)) + return __syscall_ret(-ENOSYS); + return __syscall_ret(-EINVAL); + } + tmp[2*i+0] = times[i].tv_sec; + tmp[2*i+1] = times[i].tv_nsec / 1000; + } + } + + r = __syscall(SYS_futimesat, fd, path, tv); + if (r != -ENOSYS || fd != AT_FDCWD) return __syscall_ret(r); + r = __syscall(SYS_utimes, path, tv); +#endif + return __syscall_ret(r); +} |