From 0f02a324a0d717eb403a295583f2048ab5d2302a Mon Sep 17 00:00:00 2001 From: Julien Portalier Date: Fri, 10 Jan 2025 11:27:05 +0100 Subject: [PATCH 1/2] Add nanosecond precision to File.utime (UNIX) Co-authored-by: Kubo Takehiro --- src/crystal/system/unix/file.cr | 8 ++--- src/lib_c/aarch64-android/c/sys/stat.cr | 1 + src/lib_c/aarch64-linux-gnu/c/fcntl.cr | 1 + src/lib_c/aarch64-linux-gnu/c/sys/stat.cr | 1 + src/lib_c/aarch64-linux-gnu/c/sys/time.cr | 1 - src/lib_c/aarch64-linux-musl/c/fcntl.cr | 1 + src/lib_c/aarch64-linux-musl/c/sys/stat.cr | 1 + src/lib_c/aarch64-linux-musl/c/sys/time.cr | 1 - src/lib_c/arm-linux-gnueabihf/c/fcntl.cr | 1 + src/lib_c/arm-linux-gnueabihf/c/sys/stat.cr | 1 + src/lib_c/arm-linux-gnueabihf/c/sys/time.cr | 1 - src/lib_c/i386-linux-gnu/c/fcntl.cr | 1 + src/lib_c/i386-linux-gnu/c/sys/stat.cr | 1 + src/lib_c/i386-linux-gnu/c/sys/time.cr | 1 - src/lib_c/i386-linux-musl/c/fcntl.cr | 1 + src/lib_c/i386-linux-musl/c/sys/stat.cr | 1 + src/lib_c/i386-linux-musl/c/sys/time.cr | 1 - src/lib_c/x86_64-darwin/c/fcntl.cr | 1 + src/lib_c/x86_64-darwin/c/sys/stat.cr | 1 + src/lib_c/x86_64-dragonfly/c/fcntl.cr | 32 ++++++++++---------- src/lib_c/x86_64-dragonfly/c/sys/stat.cr | 1 + src/lib_c/x86_64-dragonfly/c/sys/time.cr | 1 - src/lib_c/x86_64-freebsd/c/fcntl.cr | 1 + src/lib_c/x86_64-freebsd/c/sys/stat.cr | 1 + src/lib_c/x86_64-freebsd/c/sys/time.cr | 1 - src/lib_c/x86_64-linux-gnu/c/fcntl.cr | 1 + src/lib_c/x86_64-linux-gnu/c/sys/stat.cr | 1 + src/lib_c/x86_64-linux-gnu/c/sys/time.cr | 1 - src/lib_c/x86_64-linux-musl/c/fcntl.cr | 1 + src/lib_c/x86_64-linux-musl/c/sys/stat.cr | 1 + src/lib_c/x86_64-linux-musl/c/sys/time.cr | 1 - src/lib_c/x86_64-netbsd/c/fcntl.cr | 1 + src/lib_c/x86_64-netbsd/c/sys/stat.cr | 1 + src/lib_c/x86_64-netbsd/c/sys/time.cr | 1 - src/lib_c/x86_64-openbsd/c/fcntl.cr | 1 + src/lib_c/x86_64-openbsd/c/sys/stat.cr | 1 + src/lib_c/x86_64-openbsd/c/sys/time.cr | 1 - src/lib_c/x86_64-solaris/c/fcntl.cr | 33 +++++++++++---------- src/lib_c/x86_64-solaris/c/sys/stat.cr | 1 + src/lib_c/x86_64-solaris/c/sys/time.cr | 1 - 40 files changed, 62 insertions(+), 48 deletions(-) diff --git a/src/crystal/system/unix/file.cr b/src/crystal/system/unix/file.cr index a049659e684f..1533dfbe3fce 100644 --- a/src/crystal/system/unix/file.cr +++ b/src/crystal/system/unix/file.cr @@ -185,10 +185,10 @@ module Crystal::System::File end def self.utime(atime : ::Time, mtime : ::Time, filename : String) : Nil - timevals = uninitialized LibC::Timeval[2] - timevals[0] = Crystal::System::Time.to_timeval(atime) - timevals[1] = Crystal::System::Time.to_timeval(mtime) - ret = LibC.utimes(filename, timevals) + timespecs = uninitialized LibC::Timespec[2] + timespecs[0] = Crystal::System::Time.to_timespec(atime) + timespecs[1] = Crystal::System::Time.to_timespec(mtime) + ret = LibC.utimensat(LibC::AT_FDCWD, filename, timespecs, 0) if ret != 0 raise ::File::Error.from_errno("Error setting time on file", file: filename) end diff --git a/src/lib_c/aarch64-android/c/sys/stat.cr b/src/lib_c/aarch64-android/c/sys/stat.cr index 9216942441f3..befbc7653f99 100644 --- a/src/lib_c/aarch64-android/c/sys/stat.cr +++ b/src/lib_c/aarch64-android/c/sys/stat.cr @@ -53,4 +53,5 @@ lib LibC fun mkdir(__path : Char*, __mode : ModeT) : Int fun stat(__path : Char*, __buf : Stat*) : Int fun umask(__mask : ModeT) : ModeT + fun utimensat(fd : Int, path : Char*, times : Timespec[2], flag : Int) : Int end diff --git a/src/lib_c/aarch64-linux-gnu/c/fcntl.cr b/src/lib_c/aarch64-linux-gnu/c/fcntl.cr index e52f375d8dc4..a834cbe0b78e 100644 --- a/src/lib_c/aarch64-linux-gnu/c/fcntl.cr +++ b/src/lib_c/aarch64-linux-gnu/c/fcntl.cr @@ -19,6 +19,7 @@ lib LibC O_RDONLY = 0o0 O_RDWR = 0o2 O_WRONLY = 0o1 + AT_FDCWD = -100 struct Flock l_type : Short diff --git a/src/lib_c/aarch64-linux-gnu/c/sys/stat.cr b/src/lib_c/aarch64-linux-gnu/c/sys/stat.cr index 6a8373908586..df832238046a 100644 --- a/src/lib_c/aarch64-linux-gnu/c/sys/stat.cr +++ b/src/lib_c/aarch64-linux-gnu/c/sys/stat.cr @@ -54,4 +54,5 @@ lib LibC fun mknod(path : Char*, mode : ModeT, dev : DevT) : Int fun stat(file : Char*, buf : Stat*) : Int fun umask(mask : ModeT) : ModeT + fun utimensat(fd : Int, path : Char*, times : Timespec[2], flag : Int) : Int end diff --git a/src/lib_c/aarch64-linux-gnu/c/sys/time.cr b/src/lib_c/aarch64-linux-gnu/c/sys/time.cr index 664de111502a..9e7d921c2728 100644 --- a/src/lib_c/aarch64-linux-gnu/c/sys/time.cr +++ b/src/lib_c/aarch64-linux-gnu/c/sys/time.cr @@ -12,6 +12,5 @@ lib LibC end fun gettimeofday(tv : Timeval*, tz : Void*) : Int - fun utimes(path : Char*, times : Timeval[2]) : Int fun futimens(fd : Int, times : Timespec[2]) : Int end diff --git a/src/lib_c/aarch64-linux-musl/c/fcntl.cr b/src/lib_c/aarch64-linux-musl/c/fcntl.cr index 7664c411a36c..3959fff298df 100644 --- a/src/lib_c/aarch64-linux-musl/c/fcntl.cr +++ b/src/lib_c/aarch64-linux-musl/c/fcntl.cr @@ -19,6 +19,7 @@ lib LibC O_RDONLY = 0o0 O_RDWR = 0o2 O_WRONLY = 0o1 + AT_FDCWD = -100 struct Flock l_type : Short diff --git a/src/lib_c/aarch64-linux-musl/c/sys/stat.cr b/src/lib_c/aarch64-linux-musl/c/sys/stat.cr index db3548e2e378..96938a86c69b 100644 --- a/src/lib_c/aarch64-linux-musl/c/sys/stat.cr +++ b/src/lib_c/aarch64-linux-musl/c/sys/stat.cr @@ -54,4 +54,5 @@ lib LibC fun mknod(x0 : Char*, x1 : ModeT, x2 : DevT) : Int fun stat(x0 : Char*, x1 : Stat*) : Int fun umask(x0 : ModeT) : ModeT + fun utimensat(fd : Int, path : Char*, times : Timespec[2], flag : Int) : Int end diff --git a/src/lib_c/aarch64-linux-musl/c/sys/time.cr b/src/lib_c/aarch64-linux-musl/c/sys/time.cr index 711894a3da7e..5e2e5919812c 100644 --- a/src/lib_c/aarch64-linux-musl/c/sys/time.cr +++ b/src/lib_c/aarch64-linux-musl/c/sys/time.cr @@ -12,6 +12,5 @@ lib LibC end fun gettimeofday(x0 : Timeval*, x1 : Void*) : Int - fun utimes(path : Char*, times : Timeval[2]) : Int fun futimens(fd : Int, times : Timespec[2]) : Int end diff --git a/src/lib_c/arm-linux-gnueabihf/c/fcntl.cr b/src/lib_c/arm-linux-gnueabihf/c/fcntl.cr index e52f375d8dc4..a834cbe0b78e 100644 --- a/src/lib_c/arm-linux-gnueabihf/c/fcntl.cr +++ b/src/lib_c/arm-linux-gnueabihf/c/fcntl.cr @@ -19,6 +19,7 @@ lib LibC O_RDONLY = 0o0 O_RDWR = 0o2 O_WRONLY = 0o1 + AT_FDCWD = -100 struct Flock l_type : Short diff --git a/src/lib_c/arm-linux-gnueabihf/c/sys/stat.cr b/src/lib_c/arm-linux-gnueabihf/c/sys/stat.cr index dec65002e27a..2ed61591c9bb 100644 --- a/src/lib_c/arm-linux-gnueabihf/c/sys/stat.cr +++ b/src/lib_c/arm-linux-gnueabihf/c/sys/stat.cr @@ -55,4 +55,5 @@ lib LibC fun mknod(path : Char*, mode : ModeT, dev : DevT) : Int fun stat(file : Char*, buf : Stat*) : Int fun umask(mask : ModeT) : ModeT + fun utimensat(fd : Int, path : Char*, times : Timespec[2], flag : Int) : Int end diff --git a/src/lib_c/arm-linux-gnueabihf/c/sys/time.cr b/src/lib_c/arm-linux-gnueabihf/c/sys/time.cr index 664de111502a..9e7d921c2728 100644 --- a/src/lib_c/arm-linux-gnueabihf/c/sys/time.cr +++ b/src/lib_c/arm-linux-gnueabihf/c/sys/time.cr @@ -12,6 +12,5 @@ lib LibC end fun gettimeofday(tv : Timeval*, tz : Void*) : Int - fun utimes(path : Char*, times : Timeval[2]) : Int fun futimens(fd : Int, times : Timespec[2]) : Int end diff --git a/src/lib_c/i386-linux-gnu/c/fcntl.cr b/src/lib_c/i386-linux-gnu/c/fcntl.cr index cea8630785da..61eba795f182 100644 --- a/src/lib_c/i386-linux-gnu/c/fcntl.cr +++ b/src/lib_c/i386-linux-gnu/c/fcntl.cr @@ -19,6 +19,7 @@ lib LibC O_RDONLY = 0o0 O_RDWR = 0o2 O_WRONLY = 0o1 + AT_FDCWD = -100 struct Flock l_type : Short diff --git a/src/lib_c/i386-linux-gnu/c/sys/stat.cr b/src/lib_c/i386-linux-gnu/c/sys/stat.cr index 7a6dca15c3ba..e8e178a4de7d 100644 --- a/src/lib_c/i386-linux-gnu/c/sys/stat.cr +++ b/src/lib_c/i386-linux-gnu/c/sys/stat.cr @@ -54,4 +54,5 @@ lib LibC fun mknod(path : Char*, mode : ModeT, dev : DevT) : Int fun stat = stat64(file : Char*, buf : Stat*) : Int fun umask(mask : ModeT) : ModeT + fun utimensat(fd : Int, path : Char*, times : Timespec[2], flag : Int) : Int end diff --git a/src/lib_c/i386-linux-gnu/c/sys/time.cr b/src/lib_c/i386-linux-gnu/c/sys/time.cr index 664de111502a..9e7d921c2728 100644 --- a/src/lib_c/i386-linux-gnu/c/sys/time.cr +++ b/src/lib_c/i386-linux-gnu/c/sys/time.cr @@ -12,6 +12,5 @@ lib LibC end fun gettimeofday(tv : Timeval*, tz : Void*) : Int - fun utimes(path : Char*, times : Timeval[2]) : Int fun futimens(fd : Int, times : Timespec[2]) : Int end diff --git a/src/lib_c/i386-linux-musl/c/fcntl.cr b/src/lib_c/i386-linux-musl/c/fcntl.cr index 27a5cf0c22d3..fa53d4b1e378 100644 --- a/src/lib_c/i386-linux-musl/c/fcntl.cr +++ b/src/lib_c/i386-linux-musl/c/fcntl.cr @@ -19,6 +19,7 @@ lib LibC O_RDONLY = 0o0 O_RDWR = 0o2 O_WRONLY = 0o1 + AT_FDCWD = -100 struct Flock l_type : Short diff --git a/src/lib_c/i386-linux-musl/c/sys/stat.cr b/src/lib_c/i386-linux-musl/c/sys/stat.cr index c8a96f47a329..679cec5ff0f4 100644 --- a/src/lib_c/i386-linux-musl/c/sys/stat.cr +++ b/src/lib_c/i386-linux-musl/c/sys/stat.cr @@ -54,4 +54,5 @@ lib LibC fun mknod(x0 : Char*, x1 : ModeT, x2 : DevT) : Int fun stat(x0 : Char*, x1 : Stat*) : Int fun umask(x0 : ModeT) : ModeT + fun utimensat(fd : Int, path : Char*, times : Timespec[2], flag : Int) : Int end diff --git a/src/lib_c/i386-linux-musl/c/sys/time.cr b/src/lib_c/i386-linux-musl/c/sys/time.cr index 711894a3da7e..5e2e5919812c 100644 --- a/src/lib_c/i386-linux-musl/c/sys/time.cr +++ b/src/lib_c/i386-linux-musl/c/sys/time.cr @@ -12,6 +12,5 @@ lib LibC end fun gettimeofday(x0 : Timeval*, x1 : Void*) : Int - fun utimes(path : Char*, times : Timeval[2]) : Int fun futimens(fd : Int, times : Timespec[2]) : Int end diff --git a/src/lib_c/x86_64-darwin/c/fcntl.cr b/src/lib_c/x86_64-darwin/c/fcntl.cr index cf6ce527a729..42e77a654587 100644 --- a/src/lib_c/x86_64-darwin/c/fcntl.cr +++ b/src/lib_c/x86_64-darwin/c/fcntl.cr @@ -19,6 +19,7 @@ lib LibC O_RDONLY = 0x0000 O_RDWR = 0x0002 O_WRONLY = 0x0001 + AT_FDCWD = -2 struct Flock l_start : OffT diff --git a/src/lib_c/x86_64-darwin/c/sys/stat.cr b/src/lib_c/x86_64-darwin/c/sys/stat.cr index 9176a15083dd..556e29954120 100644 --- a/src/lib_c/x86_64-darwin/c/sys/stat.cr +++ b/src/lib_c/x86_64-darwin/c/sys/stat.cr @@ -56,4 +56,5 @@ lib LibC fun mknod(x0 : Char*, x1 : ModeT, x2 : DevT) : Int fun stat = stat64(x0 : Char*, x1 : Stat*) : Int fun umask(x0 : ModeT) : ModeT + fun utimensat(fd : Int, path : Char*, times : Timespec[2], flag : Int) : Int end diff --git a/src/lib_c/x86_64-dragonfly/c/fcntl.cr b/src/lib_c/x86_64-dragonfly/c/fcntl.cr index c9b832e2e919..2159f77d71cc 100644 --- a/src/lib_c/x86_64-dragonfly/c/fcntl.cr +++ b/src/lib_c/x86_64-dragonfly/c/fcntl.cr @@ -3,22 +3,22 @@ require "./sys/stat" require "./unistd" lib LibC - F_GETFD = 1 - F_SETFD = 2 - F_GETFL = 3 - F_SETFL = 4 - FD_CLOEXEC = 1 - O_CLOEXEC = 0x20000 - O_EXCL = 0x0800 - O_TRUNC = 0x0400 - O_CREAT = 0x0200 - O_NOFOLLOW = 0x0100 - O_SYNC = 0x0080 - O_APPEND = 0x0008 - O_NONBLOCK = 0x0004 - O_RDWR = 0x0002 - O_WRONLY = 0x0001 - O_RDONLY = 0x0000 + F_GETFD = 1 + F_SETFD = 2 + F_GETFL = 3 + F_SETFL = 4 + FD_CLOEXEC = 1 + O_CLOEXEC = 0x20000 + O_TRUNC = 0x0400 + O_CREAT = 0x0200 + O_NOFOLLOW = 0x0100 + O_SYNC = 0x0080 + O_APPEND = 0x0008 + O_NONBLOCK = 0x0004 + O_RDWR = 0x0002 + O_WRONLY = 0x0001 + O_RDONLY = 0x0000 + AT_FDCWD = 0xFFFAFDCD struct Flock l_start : OffT diff --git a/src/lib_c/x86_64-dragonfly/c/sys/stat.cr b/src/lib_c/x86_64-dragonfly/c/sys/stat.cr index 6415607a2bad..14d1ed8350ff 100644 --- a/src/lib_c/x86_64-dragonfly/c/sys/stat.cr +++ b/src/lib_c/x86_64-dragonfly/c/sys/stat.cr @@ -59,4 +59,5 @@ lib LibC fun mknod(x0 : Char*, x1 : ModeT, x2 : DevT) : Int fun stat(x0 : Char*, x1 : Stat*) : Int fun umask(x0 : ModeT) : ModeT + fun utimensat(fd : Int, path : Char*, times : Timespec[2], flag : Int) : Int end diff --git a/src/lib_c/x86_64-dragonfly/c/sys/time.cr b/src/lib_c/x86_64-dragonfly/c/sys/time.cr index 9795c61a3119..c40e74752968 100644 --- a/src/lib_c/x86_64-dragonfly/c/sys/time.cr +++ b/src/lib_c/x86_64-dragonfly/c/sys/time.cr @@ -12,6 +12,5 @@ lib LibC end fun gettimeofday(x0 : Timeval*, x1 : Timezone*) : Int - fun utimes(path : Char*, times : Timeval[2]) : Int fun futimens(fd : Int, times : Timespec[2]) : Int end diff --git a/src/lib_c/x86_64-freebsd/c/fcntl.cr b/src/lib_c/x86_64-freebsd/c/fcntl.cr index d5c507efac29..e0de63751ff7 100644 --- a/src/lib_c/x86_64-freebsd/c/fcntl.cr +++ b/src/lib_c/x86_64-freebsd/c/fcntl.cr @@ -19,6 +19,7 @@ lib LibC O_RDONLY = 0x0000 O_RDWR = 0x0002 O_WRONLY = 0x0001 + AT_FDCWD = -100 struct Flock l_start : OffT diff --git a/src/lib_c/x86_64-freebsd/c/sys/stat.cr b/src/lib_c/x86_64-freebsd/c/sys/stat.cr index 32334987cdb0..59334c508453 100644 --- a/src/lib_c/x86_64-freebsd/c/sys/stat.cr +++ b/src/lib_c/x86_64-freebsd/c/sys/stat.cr @@ -59,4 +59,5 @@ lib LibC fun mknod(x0 : Char*, x1 : ModeT, x2 : DevT) : Int fun stat(x0 : Char*, x1 : Stat*) : Int fun umask(x0 : ModeT) : ModeT + fun utimensat(fd : Int, path : Char*, times : Timespec[2], flag : Int) : Int end diff --git a/src/lib_c/x86_64-freebsd/c/sys/time.cr b/src/lib_c/x86_64-freebsd/c/sys/time.cr index 9795c61a3119..c40e74752968 100644 --- a/src/lib_c/x86_64-freebsd/c/sys/time.cr +++ b/src/lib_c/x86_64-freebsd/c/sys/time.cr @@ -12,6 +12,5 @@ lib LibC end fun gettimeofday(x0 : Timeval*, x1 : Timezone*) : Int - fun utimes(path : Char*, times : Timeval[2]) : Int fun futimens(fd : Int, times : Timespec[2]) : Int end diff --git a/src/lib_c/x86_64-linux-gnu/c/fcntl.cr b/src/lib_c/x86_64-linux-gnu/c/fcntl.cr index 7f46cb647918..4b33c823760f 100644 --- a/src/lib_c/x86_64-linux-gnu/c/fcntl.cr +++ b/src/lib_c/x86_64-linux-gnu/c/fcntl.cr @@ -19,6 +19,7 @@ lib LibC O_RDONLY = 0o0 O_RDWR = 0o2 O_WRONLY = 0o1 + AT_FDCWD = -100 struct Flock l_type : Short diff --git a/src/lib_c/x86_64-linux-gnu/c/sys/stat.cr b/src/lib_c/x86_64-linux-gnu/c/sys/stat.cr index 281f0f160d54..36df0ce15cdc 100644 --- a/src/lib_c/x86_64-linux-gnu/c/sys/stat.cr +++ b/src/lib_c/x86_64-linux-gnu/c/sys/stat.cr @@ -58,4 +58,5 @@ lib LibC fun stat(file : Char*, buf : Stat*) : Int fun __xstat(ver : Int, file : Char*, buf : Stat*) : Int fun umask(mask : ModeT) : ModeT + fun utimensat(fd : Int, path : Char*, times : Timespec[2], flag : Int) : Int end diff --git a/src/lib_c/x86_64-linux-gnu/c/sys/time.cr b/src/lib_c/x86_64-linux-gnu/c/sys/time.cr index 664de111502a..9e7d921c2728 100644 --- a/src/lib_c/x86_64-linux-gnu/c/sys/time.cr +++ b/src/lib_c/x86_64-linux-gnu/c/sys/time.cr @@ -12,6 +12,5 @@ lib LibC end fun gettimeofday(tv : Timeval*, tz : Void*) : Int - fun utimes(path : Char*, times : Timeval[2]) : Int fun futimens(fd : Int, times : Timespec[2]) : Int end diff --git a/src/lib_c/x86_64-linux-musl/c/fcntl.cr b/src/lib_c/x86_64-linux-musl/c/fcntl.cr index 27a5cf0c22d3..fa53d4b1e378 100644 --- a/src/lib_c/x86_64-linux-musl/c/fcntl.cr +++ b/src/lib_c/x86_64-linux-musl/c/fcntl.cr @@ -19,6 +19,7 @@ lib LibC O_RDONLY = 0o0 O_RDWR = 0o2 O_WRONLY = 0o1 + AT_FDCWD = -100 struct Flock l_type : Short diff --git a/src/lib_c/x86_64-linux-musl/c/sys/stat.cr b/src/lib_c/x86_64-linux-musl/c/sys/stat.cr index 921c108cef66..fc2b814ad203 100644 --- a/src/lib_c/x86_64-linux-musl/c/sys/stat.cr +++ b/src/lib_c/x86_64-linux-musl/c/sys/stat.cr @@ -53,4 +53,5 @@ lib LibC fun mknod(x0 : Char*, x1 : ModeT, x2 : DevT) : Int fun stat(x0 : Char*, x1 : Stat*) : Int fun umask(x0 : ModeT) : ModeT + fun utimensat(fd : Int, path : Char*, times : Timespec[2], flag : Int) : Int end diff --git a/src/lib_c/x86_64-linux-musl/c/sys/time.cr b/src/lib_c/x86_64-linux-musl/c/sys/time.cr index 711894a3da7e..5e2e5919812c 100644 --- a/src/lib_c/x86_64-linux-musl/c/sys/time.cr +++ b/src/lib_c/x86_64-linux-musl/c/sys/time.cr @@ -12,6 +12,5 @@ lib LibC end fun gettimeofday(x0 : Timeval*, x1 : Void*) : Int - fun utimes(path : Char*, times : Timeval[2]) : Int fun futimens(fd : Int, times : Timespec[2]) : Int end diff --git a/src/lib_c/x86_64-netbsd/c/fcntl.cr b/src/lib_c/x86_64-netbsd/c/fcntl.cr index 3a1ffe9d85c6..e3ec78a5e70d 100644 --- a/src/lib_c/x86_64-netbsd/c/fcntl.cr +++ b/src/lib_c/x86_64-netbsd/c/fcntl.cr @@ -19,6 +19,7 @@ lib LibC O_RDONLY = 0x0000 O_RDWR = 0x0002 O_WRONLY = 0x0001 + AT_FDCWD = -100 struct Flock l_start : OffT diff --git a/src/lib_c/x86_64-netbsd/c/sys/stat.cr b/src/lib_c/x86_64-netbsd/c/sys/stat.cr index 0da836e1c8eb..62b0db89770e 100644 --- a/src/lib_c/x86_64-netbsd/c/sys/stat.cr +++ b/src/lib_c/x86_64-netbsd/c/sys/stat.cr @@ -55,4 +55,5 @@ lib LibC fun mknod = __mknod50(x0 : Char*, x1 : ModeT, x2 : DevT) : Int fun stat = __stat50(x0 : Char*, x1 : Stat*) : Int fun umask(x0 : ModeT) : ModeT + fun utimensat(fd : Int, path : Char*, times : Timespec[2], flag : Int) : Int end diff --git a/src/lib_c/x86_64-netbsd/c/sys/time.cr b/src/lib_c/x86_64-netbsd/c/sys/time.cr index 3bb54d42c5cd..6a739b4a89db 100644 --- a/src/lib_c/x86_64-netbsd/c/sys/time.cr +++ b/src/lib_c/x86_64-netbsd/c/sys/time.cr @@ -12,6 +12,5 @@ lib LibC end fun gettimeofday = __gettimeofday50(x0 : Timeval*, x1 : Timezone*) : Int - fun utimes = __utimes50(path : Char*, times : Timeval[2]) : Int fun futimens(fd : Int, times : Timespec[2]) : Int end diff --git a/src/lib_c/x86_64-openbsd/c/fcntl.cr b/src/lib_c/x86_64-openbsd/c/fcntl.cr index 6de726e50bf5..1b74e9a75f69 100644 --- a/src/lib_c/x86_64-openbsd/c/fcntl.cr +++ b/src/lib_c/x86_64-openbsd/c/fcntl.cr @@ -19,6 +19,7 @@ lib LibC O_RDONLY = 0x0000 O_RDWR = 0x0002 O_WRONLY = 0x0001 + AT_FDCWD = -100 struct Flock l_start : OffT diff --git a/src/lib_c/x86_64-openbsd/c/sys/stat.cr b/src/lib_c/x86_64-openbsd/c/sys/stat.cr index 4d40ac1479d5..f3e8af683bb4 100644 --- a/src/lib_c/x86_64-openbsd/c/sys/stat.cr +++ b/src/lib_c/x86_64-openbsd/c/sys/stat.cr @@ -54,4 +54,5 @@ lib LibC fun mknod(x0 : Char*, x1 : ModeT, x2 : DevT) : Int fun stat(x0 : Char*, x1 : Stat*) : Int fun umask(x0 : ModeT) : ModeT + fun utimensat(fd : Int, path : Char*, times : Timespec[2], flag : Int) : Int end diff --git a/src/lib_c/x86_64-openbsd/c/sys/time.cr b/src/lib_c/x86_64-openbsd/c/sys/time.cr index 9795c61a3119..c40e74752968 100644 --- a/src/lib_c/x86_64-openbsd/c/sys/time.cr +++ b/src/lib_c/x86_64-openbsd/c/sys/time.cr @@ -12,6 +12,5 @@ lib LibC end fun gettimeofday(x0 : Timeval*, x1 : Timezone*) : Int - fun utimes(path : Char*, times : Timeval[2]) : Int fun futimens(fd : Int, times : Timespec[2]) : Int end diff --git a/src/lib_c/x86_64-solaris/c/fcntl.cr b/src/lib_c/x86_64-solaris/c/fcntl.cr index 6bb34dbdd169..20e8bb699aa1 100644 --- a/src/lib_c/x86_64-solaris/c/fcntl.cr +++ b/src/lib_c/x86_64-solaris/c/fcntl.cr @@ -3,22 +3,23 @@ require "./sys/stat" require "./unistd" lib LibC - F_GETFD = 1 - F_SETFD = 2 - F_GETFL = 3 - F_SETFL = 4 - FD_CLOEXEC = 1 - O_CLOEXEC = 0x800000 - O_CREAT = 0x100 - O_NOFOLLOW = 0x20000 - O_TRUNC = 0x200 - O_EXCL = 0x400 - O_APPEND = 0x08 - O_NONBLOCK = 0x80 - O_SYNC = 0x10 - O_RDONLY = 0 - O_RDWR = 2 - O_WRONLY = 1 + F_GETFD = 1 + F_SETFD = 2 + F_GETFL = 3 + F_SETFL = 4 + FD_CLOEXEC = 1 + O_CLOEXEC = 0x800000 + O_CREAT = 0x100 + O_NOFOLLOW = 0x20000 + O_TRUNC = 0x200 + O_EXCL = 0x400 + O_APPEND = 0x08 + O_NONBLOCK = 0x80 + O_SYNC = 0x10 + O_RDONLY = 0 + O_RDWR = 2 + O_WRONLY = 1 + AT_FDCWD = 0xffd19553 struct Flock l_type : Short diff --git a/src/lib_c/x86_64-solaris/c/sys/stat.cr b/src/lib_c/x86_64-solaris/c/sys/stat.cr index a5a1f3f1c5fc..c1c22c9b1872 100644 --- a/src/lib_c/x86_64-solaris/c/sys/stat.cr +++ b/src/lib_c/x86_64-solaris/c/sys/stat.cr @@ -56,4 +56,5 @@ lib LibC fun mknod(x0 : Char*, x1 : ModeT, x2 : DevT) : Int fun stat(x0 : Char*, x1 : Stat*) : Int fun umask(x0 : ModeT) : ModeT + fun utimensat(x0 : Int, x1 : Char*, x2 : Timespec[2], x3 : Int) : Int end diff --git a/src/lib_c/x86_64-solaris/c/sys/time.cr b/src/lib_c/x86_64-solaris/c/sys/time.cr index 711894a3da7e..5e2e5919812c 100644 --- a/src/lib_c/x86_64-solaris/c/sys/time.cr +++ b/src/lib_c/x86_64-solaris/c/sys/time.cr @@ -12,6 +12,5 @@ lib LibC end fun gettimeofday(x0 : Timeval*, x1 : Void*) : Int - fun utimes(path : Char*, times : Timeval[2]) : Int fun futimens(fd : Int, times : Timespec[2]) : Int end From 5ddced3cf68755ab1240be412ce373b767c1f9f1 Mon Sep 17 00:00:00 2001 From: Julien Portalier Date: Fri, 10 Jan 2025 13:30:56 +0100 Subject: [PATCH 2/2] Fix: fix bindings + utimes fallback The `utimensat` and `futimens` syscalls only appeared in macOS 10.14. To keep some backward compatibility, the x86_64 bindings are fixed to not declare them. We can however assume the syscalls to be present when compiling for aarch64. `Crystal::System::File.utime` now falls back to `utimes` when `futimens` isn't defined. Adds the missing `AT_FDCWD` constant to aarch64-android bindings. Fixes the DragonflyBSD binding. --- src/crystal/system/unix/file.cr | 17 +++++++++++++---- src/lib_c/aarch64-android/c/fcntl.cr | 1 + src/lib_c/aarch64-darwin/c/fcntl.cr | 1 + src/lib_c/aarch64-darwin/c/sys/stat.cr | 1 + src/lib_c/aarch64-darwin/c/sys/time.cr | 3 +-- src/lib_c/x86_64-darwin/c/fcntl.cr | 1 - src/lib_c/x86_64-darwin/c/sys/stat.cr | 1 - src/lib_c/x86_64-dragonfly/c/fcntl.cr | 1 + 8 files changed, 18 insertions(+), 8 deletions(-) diff --git a/src/crystal/system/unix/file.cr b/src/crystal/system/unix/file.cr index 1533dfbe3fce..d95aece69f55 100644 --- a/src/crystal/system/unix/file.cr +++ b/src/crystal/system/unix/file.cr @@ -185,10 +185,19 @@ module Crystal::System::File end def self.utime(atime : ::Time, mtime : ::Time, filename : String) : Nil - timespecs = uninitialized LibC::Timespec[2] - timespecs[0] = Crystal::System::Time.to_timespec(atime) - timespecs[1] = Crystal::System::Time.to_timespec(mtime) - ret = LibC.utimensat(LibC::AT_FDCWD, filename, timespecs, 0) + ret = + {% if LibC.has_method?("utimensat") %} + timespecs = uninitialized LibC::Timespec[2] + timespecs[0] = Crystal::System::Time.to_timespec(atime) + timespecs[1] = Crystal::System::Time.to_timespec(mtime) + LibC.utimensat(LibC::AT_FDCWD, filename, timespecs, 0) + {% else %} + timevals = uninitialized LibC::Timeval[2] + timevals[0] = Crystal::System::Time.to_timeval(atime) + timevals[1] = Crystal::System::Time.to_timeval(mtime) + LibC.utimes(filename, timevals) + {% end %} + if ret != 0 raise ::File::Error.from_errno("Error setting time on file", file: filename) end diff --git a/src/lib_c/aarch64-android/c/fcntl.cr b/src/lib_c/aarch64-android/c/fcntl.cr index bf9b5ac46f13..ae6a11f26cff 100644 --- a/src/lib_c/aarch64-android/c/fcntl.cr +++ b/src/lib_c/aarch64-android/c/fcntl.cr @@ -19,6 +19,7 @@ lib LibC O_RDONLY = 0o0 O_RDWR = 0o2 O_WRONLY = 0o1 + AT_FDCWD = -100 fun fcntl(__fd : Int, __cmd : Int, ...) : Int fun open(__path : Char*, __flags : Int, ...) : Int diff --git a/src/lib_c/aarch64-darwin/c/fcntl.cr b/src/lib_c/aarch64-darwin/c/fcntl.cr index cf6ce527a729..42e77a654587 100644 --- a/src/lib_c/aarch64-darwin/c/fcntl.cr +++ b/src/lib_c/aarch64-darwin/c/fcntl.cr @@ -19,6 +19,7 @@ lib LibC O_RDONLY = 0x0000 O_RDWR = 0x0002 O_WRONLY = 0x0001 + AT_FDCWD = -2 struct Flock l_start : OffT diff --git a/src/lib_c/aarch64-darwin/c/sys/stat.cr b/src/lib_c/aarch64-darwin/c/sys/stat.cr index 9176a15083dd..556e29954120 100644 --- a/src/lib_c/aarch64-darwin/c/sys/stat.cr +++ b/src/lib_c/aarch64-darwin/c/sys/stat.cr @@ -56,4 +56,5 @@ lib LibC fun mknod(x0 : Char*, x1 : ModeT, x2 : DevT) : Int fun stat = stat64(x0 : Char*, x1 : Stat*) : Int fun umask(x0 : ModeT) : ModeT + fun utimensat(fd : Int, path : Char*, times : Timespec[2], flag : Int) : Int end diff --git a/src/lib_c/aarch64-darwin/c/sys/time.cr b/src/lib_c/aarch64-darwin/c/sys/time.cr index f74ab38733f0..5e2e5919812c 100644 --- a/src/lib_c/aarch64-darwin/c/sys/time.cr +++ b/src/lib_c/aarch64-darwin/c/sys/time.cr @@ -12,6 +12,5 @@ lib LibC end fun gettimeofday(x0 : Timeval*, x1 : Void*) : Int - fun utimes(path : Char*, times : Timeval[2]) : Int - fun futimes(fd : Int, times : Timeval[2]) : Int + fun futimens(fd : Int, times : Timespec[2]) : Int end diff --git a/src/lib_c/x86_64-darwin/c/fcntl.cr b/src/lib_c/x86_64-darwin/c/fcntl.cr index 42e77a654587..cf6ce527a729 100644 --- a/src/lib_c/x86_64-darwin/c/fcntl.cr +++ b/src/lib_c/x86_64-darwin/c/fcntl.cr @@ -19,7 +19,6 @@ lib LibC O_RDONLY = 0x0000 O_RDWR = 0x0002 O_WRONLY = 0x0001 - AT_FDCWD = -2 struct Flock l_start : OffT diff --git a/src/lib_c/x86_64-darwin/c/sys/stat.cr b/src/lib_c/x86_64-darwin/c/sys/stat.cr index 556e29954120..9176a15083dd 100644 --- a/src/lib_c/x86_64-darwin/c/sys/stat.cr +++ b/src/lib_c/x86_64-darwin/c/sys/stat.cr @@ -56,5 +56,4 @@ lib LibC fun mknod(x0 : Char*, x1 : ModeT, x2 : DevT) : Int fun stat = stat64(x0 : Char*, x1 : Stat*) : Int fun umask(x0 : ModeT) : ModeT - fun utimensat(fd : Int, path : Char*, times : Timespec[2], flag : Int) : Int end diff --git a/src/lib_c/x86_64-dragonfly/c/fcntl.cr b/src/lib_c/x86_64-dragonfly/c/fcntl.cr index 2159f77d71cc..9f1c643332c3 100644 --- a/src/lib_c/x86_64-dragonfly/c/fcntl.cr +++ b/src/lib_c/x86_64-dragonfly/c/fcntl.cr @@ -9,6 +9,7 @@ lib LibC F_SETFL = 4 FD_CLOEXEC = 1 O_CLOEXEC = 0x20000 + O_EXCL = 0x0800 O_TRUNC = 0x0400 O_CREAT = 0x0200 O_NOFOLLOW = 0x0100