Browse Source

Merge remote-tracking branch 'origin/truncate-n-mkfifo'

Jeremy Soller 5 years ago
parent
commit
2e5d4a4d25

+ 13 - 3
src/header/unistd/mod.rs

@@ -5,7 +5,7 @@ use core::{convert::TryFrom, mem, ptr, slice};
 use crate::{
     c_str::CStr,
     header::{
-        errno, limits, stdlib::getenv, sys_ioctl, sys_time, sys_utsname, termios, time::timespec,
+        errno, fcntl, limits, stdlib::getenv, sys_ioctl, sys_time, sys_utsname, termios, time::timespec,
     },
     platform::{self, types::*, Pal, Sys},
 };
@@ -649,9 +649,19 @@ pub extern "C" fn tcsetpgrp(fd: c_int, pgrp: pid_t) -> c_int {
     pgrp
 }
 
-// #[no_mangle]
+#[no_mangle]
 pub extern "C" fn truncate(path: *const c_char, length: off_t) -> c_int {
-    unimplemented!();
+    let file = unsafe { CStr::from_ptr(path) };
+    let fd = Sys::open(file, fcntl::O_WRONLY, 0);
+    if fd < 0 {
+        return -1;
+    }
+
+    let res = ftruncate(fd, length);
+
+    Sys::close(fd);
+
+    res
 }
 
 #[no_mangle]

+ 2 - 2
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::{
@@ -292,7 +292,7 @@ impl Pal for Sys {
     }
 
     fn mkfifo(path: &CStr, mode: mode_t) -> c_int {
-        e(unsafe { syscall!(MKNODAT, AT_FDCWD, path.as_ptr(), mode, 0) }) as c_int
+        e(unsafe { syscall!(MKNODAT, AT_FDCWD, path.as_ptr(), mode | S_IFIFO, 0) }) as c_int
     }
 
     unsafe fn mmap(

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

@@ -319,31 +319,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
             }

+ 3 - 0
tests/Makefile

@@ -13,6 +13,7 @@ EXPECT_NAMES=\
 	fcntl/create \
 	fcntl/fcntl \
 	fnmatch \
+	futimens \
 	libgen \
 	locale \
 	math \
@@ -102,6 +103,8 @@ EXPECT_NAMES=\
 	wchar/wcstod \
 	wchar/wcstok \
 	wchar/wcstol
+	# TODO: Fix these
+	# mkfifo
 
 # Binaries that may generate varied output
 NAMES=\

+ 0 - 0
tests/expected/futimens.stderr


+ 0 - 0
tests/expected/futimens.stdout


+ 0 - 0
tests/expected/mkfifo.stderr


+ 0 - 0
tests/expected/mkfifo.stdout


+ 67 - 0
tests/futimens.c

@@ -0,0 +1,67 @@
+#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);
+  }
+  // Access times are not flushed to disk, so this check can't be (currently) performed
+  /*
+   * 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);
+   * }
+   */
+}

+ 40 - 0
tests/mkfifo.c

@@ -0,0 +1,40 @@
+#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>
+
+int main(int argc, char** argv) {
+  char temp[] = "/tmp/stattest-XXXXXX";
+  const char file[] = "/mkfifo_fifo";
+  int len = sizeof(temp) + sizeof(file);
+  char* path = malloc(len * sizeof(char));
+
+  if (path == NULL) {
+    fprintf(stderr, "Could not allocate: %s\n", strerror(errno));
+    exit(1);
+  }
+
+  path = strncat(path, mktemp(temp), sizeof(temp));
+  path = 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);
+  }
+  if (mkfifo(path, S_IRUSR) == -1) {
+    fprintf(stderr, "mkfifo %s: %s\n", path, strerror(errno));
+    exit(1);
+  }
+  struct stat sb;
+  if (stat(path, &sb) != 0) {
+    fprintf(stderr, "stat: %s\n", strerror(errno));
+    exit(1);
+  }
+  if (!(sb.st_mode & S_IFIFO)) {
+    fprintf(stderr, "Not a FIFO: %d\n", sb.st_mode);
+    exit(1);
+  }
+}

+ 4 - 0
tests/unistd/ftruncate.c

@@ -17,4 +17,8 @@ int main(void) {
     int c = close(fd);
     ERROR_IF(close, c, == -1);
     UNEXP_IF(close, c, != 0);
+
+    status = truncate("ftruncate.out", 100);
+    ERROR_IF(truncate, status, == -1);
+    UNEXP_IF(truncate, status, != 0);
 }