diff --git a/src/header/fcntl/mod.rs b/src/header/fcntl/mod.rs index 28455c94cf..2f23451135 100644 --- a/src/header/fcntl/mod.rs +++ b/src/header/fcntl/mod.rs @@ -80,7 +80,16 @@ pub unsafe extern "C" fn fcntl(fildes: c_int, cmd: c_int, mut __valist: ...) -> /// See . #[unsafe(no_mangle)] pub unsafe extern "C" fn open(path: *const c_char, oflag: c_int, mut __valist: ...) -> c_int { - unsafe { openat(AT_FDCWD, path, oflag, __valist) } + let mode = if oflag & O_CREAT == O_CREAT + /* || oflag & O_TMPFILE == O_TMPFILE */ + { + unsafe { __valist.arg::() } + } else { + 0 + }; + + let path = unsafe { CStr::from_ptr(path) }; + Sys::openat(AT_FDCWD, path, oflag, mode).or_minus_one_errno() } /// See . diff --git a/src/header/sys_stat/mod.rs b/src/header/sys_stat/mod.rs index 0975a20dec..29ca8fa532 100644 --- a/src/header/sys_stat/mod.rs +++ b/src/header/sys_stat/mod.rs @@ -19,38 +19,38 @@ use crate::{ }, }; -pub const S_IFMT: c_int = 0o0_170_000; +pub const S_IFMT: mode_t = 0o0_170_000; -pub const S_IFDIR: c_int = 0o040_000; -pub const S_IFCHR: c_int = 0o020_000; -pub const S_IFBLK: c_int = 0o060_000; -pub const S_IFREG: c_int = 0o100_000; -pub const S_IFIFO: c_int = 0o010_000; -pub const S_IFLNK: c_int = 0o120_000; -pub const S_IFSOCK: c_int = 0o140_000; +pub const S_IFDIR: mode_t = 0o040_000; +pub const S_IFCHR: mode_t = 0o020_000; +pub const S_IFBLK: mode_t = 0o060_000; +pub const S_IFREG: mode_t = 0o100_000; +pub const S_IFIFO: mode_t = 0o010_000; +pub const S_IFLNK: mode_t = 0o120_000; +pub const S_IFSOCK: mode_t = 0o140_000; -pub const S_IRWXU: c_int = 0o0_700; -pub const S_IRUSR: c_int = 0o0_400; -pub const S_IWUSR: c_int = 0o0_200; -pub const S_IXUSR: c_int = 0o0_100; +pub const S_IRWXU: mode_t = 0o0_700; +pub const S_IRUSR: mode_t = 0o0_400; +pub const S_IWUSR: mode_t = 0o0_200; +pub const S_IXUSR: mode_t = 0o0_100; // Defined for compatibility -pub const S_IREAD: c_int = S_IRUSR; -pub const S_IWRITE: c_int = S_IWUSR; -pub const S_IEXEC: c_int = S_IXUSR; +pub const S_IREAD: mode_t = S_IRUSR; +pub const S_IWRITE: mode_t = S_IWUSR; +pub const S_IEXEC: mode_t = S_IXUSR; -pub const S_IRWXG: c_int = 0o0_070; -pub const S_IRGRP: c_int = 0o0_040; -pub const S_IWGRP: c_int = 0o0_020; -pub const S_IXGRP: c_int = 0o0_010; +pub const S_IRWXG: mode_t = 0o0_070; +pub const S_IRGRP: mode_t = 0o0_040; +pub const S_IWGRP: mode_t = 0o0_020; +pub const S_IXGRP: mode_t = 0o0_010; -pub const S_IRWXO: c_int = 0o0_007; -pub const S_IROTH: c_int = 0o0_004; -pub const S_IWOTH: c_int = 0o0_002; -pub const S_IXOTH: c_int = 0o0_001; -pub const S_ISUID: c_int = 0o4_000; -pub const S_ISGID: c_int = 0o2_000; -pub const S_ISVTX: c_int = 0o1_000; +pub const S_IRWXO: mode_t = 0o0_007; +pub const S_IROTH: mode_t = 0o0_004; +pub const S_IWOTH: mode_t = 0o0_002; +pub const S_IXOTH: mode_t = 0o0_001; +pub const S_ISUID: mode_t = 0o4_000; +pub const S_ISGID: mode_t = 0o2_000; +pub const S_ISVTX: mode_t = 0o1_000; pub const UTIME_NOW: c_long = (1 << 30) - 1; pub const UTIME_OMIT: c_long = (1 << 30) - 2; diff --git a/src/header/sys_types_internal/mod.rs b/src/header/sys_types_internal/mod.rs index 4c4cde7e9d..c433558716 100644 --- a/src/header/sys_types_internal/mod.rs +++ b/src/header/sys_types_internal/mod.rs @@ -24,6 +24,10 @@ pub type gid_t = c_int; /// Used for user IDs. pub type uid_t = c_int; /// Used for some file attributes. +#[cfg(target_os = "linux")] +pub type mode_t = c_uint; +/// Used for some file attributes. +#[cfg(not(target_os = "linux"))] pub type mode_t = c_int; /// Used for link counts. pub type nlink_t = c_ulong; diff --git a/src/platform/types.rs b/src/platform/types.rs index 3d14bb29a1..bd964c5185 100644 --- a/src/platform/types.rs +++ b/src/platform/types.rs @@ -91,6 +91,10 @@ pub type regoff_t = size_t; /// The `off_t` type provided in [`sys/types.h`](crate::header::sys_types). pub type off_t = c_longlong; /// The `mode_t` type provided in [`sys/types.h`](crate::header::sys_types). +#[cfg(target_os = "linux")] +pub type mode_t = c_uint; +/// The `mode_t` type provided in [`sys/types.h`](crate::header::sys_types). +#[cfg(not(target_os = "linux"))] pub type mode_t = c_int; /// The `time_t` type provided in [`sys/types.h`](crate::header::sys_types). pub type time_t = c_longlong; diff --git a/tests/Makefile.tests.mk b/tests/Makefile.tests.mk index 7ace459d3a..239e259207 100644 --- a/tests/Makefile.tests.mk +++ b/tests/Makefile.tests.mk @@ -145,6 +145,7 @@ EXPECT_NAMES=\ sys_stat/chmod \ sys_stat/lstat \ sys_stat/fstatat \ + sys_stat/umask \ sys_syslog/syslog \ time/asctime \ time/constants \ diff --git a/tests/expected/bins_dynamic/sys_stat/umask.stdout b/tests/expected/bins_dynamic/sys_stat/umask.stdout new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/expected/bins_static/sys_stat/umask.stdout b/tests/expected/bins_static/sys_stat/umask.stdout new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/sys_stat/umask.c b/tests/sys_stat/umask.c new file mode 100644 index 0000000000..78e5a9bfd9 --- /dev/null +++ b/tests/sys_stat/umask.c @@ -0,0 +1,33 @@ +#include +#include +#include +#include +#include +#include "test_helpers.h" + +int main() { + const char *test_file = "umask.txt"; + struct stat st; + mode_t target_umask = 0022; + mode_t creation_mode = 0666; + mode_t expected_mode = 0644; + + umask(target_umask); + + int fd = open(test_file, O_WRONLY | O_CREAT | O_TRUNC, creation_mode); + ERROR_IF(open, fd, == -1); + close(fd); + + int stat_status = stat(test_file, &st); + ERROR_IF(stat, stat_status, == -1); + UNEXP_IF(stat, stat_status, != 0); + + mode_t actual_mode = st.st_mode & 0777; + UNEXP_IF(mode_check, actual_mode, != expected_mode); + + int unlink_status = unlink(test_file); + ERROR_IF(unlink, unlink_status, == -1); + UNEXP_IF(unlink, unlink_status, != 0); + + return 0; +} \ No newline at end of file