github.com/afumu/libc@v0.0.6/musl/src/stat/utimensat.c (about) 1 #include <sys/stat.h> 2 #include <sys/time.h> 3 #include <fcntl.h> 4 #include <errno.h> 5 #include "syscall.h" 6 7 #define IS32BIT(x) !((x)+0x80000000ULL>>32) 8 #define NS_SPECIAL(ns) ((ns)==UTIME_NOW || (ns)==UTIME_OMIT) 9 10 int utimensat(int fd, const char *path, const struct timespec times[2], int flags) 11 { 12 int r; 13 if (times && times[0].tv_nsec==UTIME_NOW && times[1].tv_nsec==UTIME_NOW) 14 times = 0; 15 #ifdef SYS_utimensat_time64 16 r = -ENOSYS; 17 time_t s0=0, s1=0; 18 long ns0=0, ns1=0; 19 if (times) { 20 ns0 = times[0].tv_nsec; 21 ns1 = times[1].tv_nsec; 22 if (!NS_SPECIAL(ns0)) s0 = times[0].tv_sec; 23 if (!NS_SPECIAL(ns1)) s1 = times[1].tv_sec; 24 } 25 if (SYS_utimensat == SYS_utimensat_time64 || !IS32BIT(s0) || !IS32BIT(s1)) 26 r = __syscall(SYS_utimensat_time64, fd, path, times ? 27 ((long long[]){s0, ns0, s1, ns1}) : 0, flags); 28 if (SYS_utimensat == SYS_utimensat_time64 || r!=-ENOSYS) 29 return __syscall_ret(r); 30 if (!IS32BIT(s0) || !IS32BIT(s1)) 31 return __syscall_ret(-ENOTSUP); 32 r = __syscall(SYS_utimensat, fd, path, 33 times ? ((long[]){s0, ns0, s1, ns1}) : 0, flags); 34 #else 35 r = __syscall(SYS_utimensat, fd, path, times, flags); 36 #endif 37 38 #ifdef SYS_futimesat 39 if (r != -ENOSYS || flags) return __syscall_ret(r); 40 long *tv=0, tmp[4]; 41 if (times) { 42 int i; 43 tv = tmp; 44 for (i=0; i<2; i++) { 45 if (times[i].tv_nsec >= 1000000000ULL) { 46 if (NS_SPECIAL(times[i].tv_nsec)) 47 return __syscall_ret(-ENOSYS); 48 return __syscall_ret(-EINVAL); 49 } 50 tmp[2*i+0] = times[i].tv_sec; 51 tmp[2*i+1] = times[i].tv_nsec / 1000; 52 } 53 } 54 55 r = __syscall(SYS_futimesat, fd, path, tv); 56 if (r != -ENOSYS || fd != AT_FDCWD) return __syscall_ret(r); 57 r = __syscall(SYS_utimes, path, tv); 58 #endif 59 return __syscall_ret(r); 60 }