Browse Source

Implement futimens

jD91mZM2 6 years ago
parent
commit
7ff6940edd

+ 3 - 0
include/bits/sys/stat.h

@@ -8,4 +8,7 @@
 #define S_ISIFO(mode) mode & S_IFMT == S_IFIFO
 #define S_ISLNK(mode) mode & S_IFMT == S_IFLNK
 
+#define st_atime st_atim.tv_sec
+#define st_mtime st_mtim.tv_sec
+
 #endif

+ 0 - 9
include/bits/timespec.h

@@ -1,9 +0,0 @@
-#ifndef _BITS_TIMESPEC_H
-#define _BITS_TIMESPEC_H
-
-typedef struct {
-    time_t tv_sec;
-    long tv_nsec;
-} timespec;
-
-#endif

+ 4 - 0
src/platform/src/linux/mod.rs

@@ -103,6 +103,10 @@ pub fn ftruncate(fildes: c_int, length: off_t) -> c_int {
     e(unsafe { syscall!(FTRUNCATE, fildes, length) }) as c_int
 }
 
+pub fn futimens(fd: c_int, times: *const timespec) -> c_int {
+    e(unsafe { syscall!(UTIMENSAT, fd, ptr::null::<c_char>(), times, 0) }) as c_int
+}
+
 pub fn getcwd(buf: *mut c_char, size: size_t) -> *mut c_char {
     if e(unsafe { syscall!(GETCWD, buf, size) }) == !0 {
         ptr::null_mut()

+ 20 - 3
src/platform/src/redox/mod.rs

@@ -246,9 +246,18 @@ pub fn fstat(fildes: c_int, buf: *mut stat) -> c_int {
                     (*buf).st_rdev = 0;
                     (*buf).st_size = redox_buf.st_size as off_t;
                     (*buf).st_blksize = redox_buf.st_blksize as blksize_t;
-                    (*buf).st_atim = redox_buf.st_atime as time_t;
-                    (*buf).st_mtim = redox_buf.st_mtime as time_t;
-                    (*buf).st_ctim = redox_buf.st_ctime as time_t;
+                    (*buf).st_atim = timespec {
+                        tv_sec: redox_buf.st_atime as time_t,
+                        tv_nsec: 0
+                    };
+                    (*buf).st_mtim = timespec {
+                        tv_sec: redox_buf.st_mtime as time_t,
+                        tv_nsec: 0
+                    };
+                    (*buf).st_ctim = timespec {
+                        tv_sec: redox_buf.st_ctime as time_t,
+                        tv_nsec: 0
+                    };
                 }
             }
             0
@@ -265,6 +274,14 @@ pub fn ftruncate(fd: c_int, len: off_t) -> c_int {
     e(syscall::ftruncate(fd as usize, len as usize)) as c_int
 }
 
+pub fn futimens(fd: c_int, times: *const timespec) -> c_int {
+    let times = [
+        unsafe { redox_timespec::from(&*times) },
+        unsafe { redox_timespec::from(&*times.offset(1)) }
+    ];
+    e(syscall::futimens(fd as usize, &times)) as c_int
+}
+
 pub fn getcwd(buf: *mut c_char, size: size_t) -> *mut c_char {
     let buf_slice = unsafe { slice::from_raw_parts_mut(buf as *mut u8, size as usize) };
     if e(syscall::getcwd(buf_slice)) == !0 {

+ 5 - 5
src/platform/src/types.rs

@@ -112,14 +112,14 @@ pub struct stat {
     pub st_blksize: blksize_t,
     pub st_blocks: blkcnt_t,
 
-    pub st_atim: time_t,
-    pub st_mtim: time_t,
-    pub st_ctim: time_t,
+    pub st_atim: timespec,
+    pub st_mtim: timespec,
+    pub st_ctim: timespec,
 
-    // Compared to glibc, our struct is for some reason 48 bytes too small.
+    // Compared to glibc, our struct is for some reason 24 bytes too small.
     // Accessing atime works, so clearly the struct isn't incorrect...
     // This works.
-    pub _pad: [c_char; 48]
+    pub _pad: [c_char; 24]
 }
 
 pub const AF_INET: c_int = 2;

+ 1 - 1
src/sys_stat/cbindgen.toml

@@ -1,4 +1,4 @@
-sys_includes = ["sys/types.h"]
+sys_includes = ["sys/types.h", "time.h"]
 include_guard = "_SYS_STAT_H"
 trailer = "#include <bits/sys/stat.h>"
 language = "C"

+ 10 - 5
src/sys_stat/src/lib.rs

@@ -45,14 +45,14 @@ pub struct stat {
     pub st_blksize: blksize_t,
     pub st_blocks: blkcnt_t,
 
-    pub st_atim: time_t,
-    pub st_mtim: time_t,
-    pub st_ctim: time_t,
+    pub st_atim: timespec,
+    pub st_mtim: timespec,
+    pub st_ctim: timespec,
 
-    // Compared to glibc, our struct is for some reason 48 bytes too small.
+    // Compared to glibc, our struct is for some reason 24 bytes too small.
     // Accessing atime works, so clearly the struct isn't incorrect...
     // This works.
-    pub _pad: [c_char; 48]
+    pub _pad: [c_char; 24]
 }
 
 #[no_mangle]
@@ -75,6 +75,11 @@ pub extern "C" fn __fxstat(_ver: c_int, fildes: c_int, buf: *mut platform::types
     fstat(fildes, buf)
 }
 
+#[no_mangle]
+pub extern "C" fn futimens(fd: c_int, times: *const timespec) -> c_int {
+    platform::futimens(fd, times)
+}
+
 #[no_mangle]
 pub extern "C" fn lstat(path: *const c_char, buf: *mut platform::types::stat) -> c_int {
     platform::lstat(path, buf)

+ 1 - 1
src/time/cbindgen.toml

@@ -1,4 +1,4 @@
-sys_includes = ["sys/types.h", "bits/timespec.h", "stdint.h", "stddef.h"]
+sys_includes = ["sys/types.h", "stdint.h", "stddef.h"]
 include_guard = "_TIME_H"
 language = "C"
 

+ 8 - 10
src/time/src/lib.rs

@@ -18,13 +18,11 @@ use errno::EIO;
 use helpers::*;
 use platform::types::*;
 
-/*
- *#[repr(C)]
- *pub struct timespec {
- *    pub tv_sec: time_t,
- *    pub tv_nsec: c_long,
- *}
- */
+#[repr(C)]
+pub struct timespec {
+    pub tv_sec: time_t,
+    pub tv_nsec: c_long,
+}
 
 #[repr(C)]
 pub struct tm {
@@ -124,7 +122,7 @@ pub extern "C" fn clock_getres(clock_id: clockid_t, res: *mut timespec) -> c_int
 
 #[no_mangle]
 pub extern "C" fn clock_gettime(clock_id: clockid_t, tp: *mut timespec) -> c_int {
-    platform::clock_gettime(clock_id, tp)
+    platform::clock_gettime(clock_id, tp as *mut platform::types::timespec)
 }
 
 // #[no_mangle]
@@ -331,7 +329,7 @@ pub unsafe extern "C" fn mktime(t: *const tm) -> time_t {
 
 #[no_mangle]
 pub extern "C" fn nanosleep(rqtp: *const timespec, rmtp: *mut timespec) -> c_int {
-    platform::nanosleep(rqtp, rmtp)
+    platform::nanosleep(rqtp as *const platform::types::timespec, rmtp as *mut platform::types::timespec)
 }
 
 #[no_mangle]
@@ -357,7 +355,7 @@ pub extern "C" fn strptime(buf: *const c_char, format: *const c_char, tm: *mut t
 
 #[no_mangle]
 pub extern "C" fn time(tloc: *mut time_t) -> time_t {
-    let mut ts: timespec = Default::default();
+    let mut ts: platform::types::timespec = Default::default();
     platform::clock_gettime(CLOCK_REALTIME, &mut ts);
     unsafe {
         if !tloc.is_null() {

BIN
tests/time/gettimeofday