Browse Source

Add a test for futimens

Xavier L'Heureux 5 years ago
parent
commit
5156a13b3e

+ 1 - 1
src/platform/linux/mod.rs

@@ -4,7 +4,7 @@ use core_io::Write;
 use super::{errno, types::*, Pal};
 use crate::{
     c_str::CStr,
-    header::{dirent::dirent, signal::SIGCHLD},
+    header::{dirent::dirent, signal::SIGCHLD, sys_stat::S_IFIFO},
 };
 // use header::sys_resource::rusage;
 use crate::header::{

+ 23 - 25
src/platform/redox/mod.rs

@@ -318,31 +318,29 @@ impl Pal for Sys {
         let mut redox_buf: redox_stat = redox_stat::default();
         match e(syscall::fstat(fildes as usize, &mut redox_buf)) {
             0 => {
-                unsafe {
-                    if !buf.is_null() {
-                        (*buf).st_dev = redox_buf.st_dev as dev_t;
-                        (*buf).st_ino = redox_buf.st_ino as ino_t;
-                        (*buf).st_nlink = redox_buf.st_nlink as nlink_t;
-                        (*buf).st_mode = redox_buf.st_mode as mode_t;
-                        (*buf).st_uid = redox_buf.st_uid as uid_t;
-                        (*buf).st_gid = redox_buf.st_gid as gid_t;
-                        // TODO st_rdev
-                        (*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 = timespec {
-                            tv_sec: redox_buf.st_atime as time_t,
-                            tv_nsec: redox_buf.st_atime_nsec as c_long,
-                        };
-                        (*buf).st_mtim = timespec {
-                            tv_sec: redox_buf.st_mtime as time_t,
-                            tv_nsec: redox_buf.st_mtime_nsec as c_long,
-                        };
-                        (*buf).st_ctim = timespec {
-                            tv_sec: redox_buf.st_ctime as time_t,
-                            tv_nsec: redox_buf.st_ctime_nsec as c_long,
-                        };
-                    }
+                if let Some(buf) = unsafe { buf.as_mut() } {
+                    buf.st_dev = redox_buf.st_dev as dev_t;
+                    buf.st_ino = redox_buf.st_ino as ino_t;
+                    buf.st_nlink = redox_buf.st_nlink as nlink_t;
+                    buf.st_mode = redox_buf.st_mode as mode_t;
+                    buf.st_uid = redox_buf.st_uid as uid_t;
+                    buf.st_gid = redox_buf.st_gid as gid_t;
+                    // TODO st_rdev
+                    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 = timespec {
+                        tv_sec: redox_buf.st_atime as time_t,
+                        tv_nsec: redox_buf.st_atime_nsec as c_long,
+                    };
+                    buf.st_mtim = timespec {
+                        tv_sec: redox_buf.st_mtime as time_t,
+                        tv_nsec: redox_buf.st_mtime_nsec as c_long,
+                    };
+                    buf.st_ctim = timespec {
+                        tv_sec: redox_buf.st_ctime as time_t,
+                        tv_nsec: redox_buf.st_ctime_nsec as c_long,
+                    };
                 }
                 0
             }

+ 1 - 0
tests/Makefile

@@ -1,5 +1,6 @@
 # Binaries that should generate the same output every time
 EXPECT_NAMES=\
+	futimens \
 	alloca \
 	args \
 	arpainet \

+ 0 - 0
tests/expected/futimens.stderr


+ 0 - 0
tests/expected/futimens.stdout


+ 64 - 0
tests/futimens.c

@@ -0,0 +1,64 @@
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/statvfs.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <stdio.h>
+#include <unistd.h>
+
+int main(int argc, char** argv) {
+  char temp[] = "/tmp/stattest-XXXXXX";
+  const char file[] = "/mkfifo_fifo";
+  int len = sizeof(temp) + sizeof(int);
+  char* path = malloc(len * sizeof(char));
+
+  if (path == NULL) {
+    fprintf(stderr, "Could not allocate: %s\n", strerror(errno));
+    exit(1);
+  }
+
+  strncat(path, mktemp(temp), sizeof(temp));
+  strncat(path, file, sizeof(file));
+  if (mkdir(temp, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) != 0) {
+    fprintf(stderr, "mkdir %s: %s\n", temp, strerror(errno));
+    exit(1);
+  }
+
+  int tmp = open(path, O_CREAT | O_CLOEXEC | O_RDONLY | S_IRWXU | S_IRWXG | S_IRWXO);
+  if (tmp == -1) {
+    fprintf(stderr, "touch %s: %s\n", path, strerror(errno));
+    exit(1);
+  }
+  if (close(tmp) == -1) {
+    fprintf(stderr, "close %s: %s\n", path, strerror(errno));
+    exit(1);
+  }
+
+  int fd = open(path, 0, 0);
+  if (fd == -1) {
+    fprintf(stderr, "open %s: %s\n", path, strerror(errno));
+    exit(1);
+  }
+
+  const struct timespec times[] = { { .tv_sec = 10 }, { .tv_sec = 20 } };
+  if (futimens(fd, times) == -1) {
+    fprintf(stderr, "futimens: %s\n", strerror(errno));
+    exit(1);
+  }
+
+  struct stat sb;
+  if (stat(path, &sb) != 0) {
+    fprintf(stderr, "stat: %s\n", strerror(errno));
+    exit(1);
+  }
+  if (sb.st_mtim.tv_sec != 20 || sb.st_mtim.tv_nsec != 0) {
+    fprintf(stderr, "Wrong modified time: %d.%d\n", sb.st_mtim.tv_sec, sb.st_mtim.tv_nsec);
+    exit(1);
+  }
+  if (sb.st_atim.tv_sec != 10 || sb.st_atim.tv_nsec != 0) {
+    fprintf(stderr, "Wrong accessed time: %d.%d\n", sb.st_atim.tv_sec, sb.st_atim.tv_nsec);
+    exit(1);
+  }
+}