diff --git a/src/platform/linux/mod.rs b/src/platform/linux/mod.rs index 0009bd99a86adba03489a14039179088989d038e..c0fb4e9a9d6c212b8db6b0b9da55217bdfd64608 100644 --- a/src/platform/linux/mod.rs +++ b/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::{ diff --git a/src/platform/redox/mod.rs b/src/platform/redox/mod.rs index 56c6b9e22280e556d1346c4deb0da77b5c7949d7..7f360c8670c1634bc2fc62bc0f0c9f90234722bc 100644 --- a/src/platform/redox/mod.rs +++ b/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 } diff --git a/tests/Makefile b/tests/Makefile index 9061aa6016578a85f6cb74b7b5cf61893eb25d59..1ff9e0be74d0c7e474dd756f3bedd48e0e01a566 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -1,5 +1,6 @@ # Binaries that should generate the same output every time EXPECT_NAMES=\ + futimens \ alloca \ args \ arpainet \ diff --git a/tests/expected/futimens.stderr b/tests/expected/futimens.stderr new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/tests/expected/futimens.stdout b/tests/expected/futimens.stdout new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/tests/futimens.c b/tests/futimens.c new file mode 100644 index 0000000000000000000000000000000000000000..e28499523de2691e2ae7c779494689623bc71d00 --- /dev/null +++ b/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); + } +}