diff --git a/src/header/sys_stat/mod.rs b/src/header/sys_stat/mod.rs index 6925cb5a81..b71a5f4d39 100644 --- a/src/header/sys_stat/mod.rs +++ b/src/header/sys_stat/mod.rs @@ -176,6 +176,15 @@ pub unsafe extern "C" fn mkdir(path: *const c_char, mode: mode_t) -> c_int { Sys::mkdir(path, mode).map(|()| 0).or_minus_one_errno() } +/// See . +#[unsafe(no_mangle)] +pub unsafe extern "C" fn mkfifoat(dirfd: c_int, path: *const c_char, mode: mode_t) -> c_int { + let path = CStr::from_ptr(path); + Sys::mkfifoat(dirfd, path, mode) + .map(|()| 0) + .or_minus_one_errno() +} + /// See . #[unsafe(no_mangle)] pub unsafe extern "C" fn mkfifo(path: *const c_char, mode: mode_t) -> c_int { diff --git a/src/platform/linux/mod.rs b/src/platform/linux/mod.rs index aa5636f684..b42bb4dfc4 100644 --- a/src/platform/linux/mod.rs +++ b/src/platform/linux/mod.rs @@ -527,6 +527,10 @@ impl Pal for Sys { Sys::mknodat(AT_FDCWD, path, mode, dev) } + fn mkfifoat(dir_fd: c_int, path: CStr, mode: mode_t) -> Result<()> { + Sys::mknodat(dir_fd, path, mode | S_IFIFO, 0) + } + fn mkfifo(path: CStr, mode: mode_t) -> Result<()> { Sys::mknod(path, mode | S_IFIFO, 0) } diff --git a/src/platform/pal/mod.rs b/src/platform/pal/mod.rs index 44602a6e9f..60c1c29fda 100644 --- a/src/platform/pal/mod.rs +++ b/src/platform/pal/mod.rs @@ -175,6 +175,8 @@ pub trait Pal { fn mkdir(path: CStr, mode: mode_t) -> Result<()>; + fn mkfifoat(dir_fd: c_int, path: CStr, mode: mode_t) -> Result<()>; + fn mkfifo(path: CStr, mode: mode_t) -> Result<()>; fn mknodat(fildes: c_int, path: CStr, mode: mode_t, dev: dev_t) -> Result<()>; diff --git a/src/platform/redox/mod.rs b/src/platform/redox/mod.rs index ee2ede005f..1b74b5e087 100644 --- a/src/platform/redox/mod.rs +++ b/src/platform/redox/mod.rs @@ -708,6 +708,23 @@ impl Pal for Sys { Ok(()) } + fn mkfifoat(dir_fd: c_int, path_name: CStr, mode: mode_t) -> Result<()> { + let mut dir_path_buf = [0; 4096]; + let res = Sys::fpath(dir_fd, &mut dir_path_buf)?; + + let dir_path = str::from_utf8(&dir_path_buf[..res as usize]).map_err(|_| Errno(EBADR))?; + + let resource_path = + path::canonicalize_using_cwd(Some(&dir_path), &path_name.to_string_lossy()) + // Since parent_dir_path is resolved by fpath, it is more likely that + // the problem was with path. + .ok_or(Errno(ENOENT))?; + Sys::mkfifo( + CStr::borrow(&CString::new(resource_path.as_bytes()).unwrap()), + mode, + ) + } + fn mkfifo(path: CStr, mode: mode_t) -> Result<()> { Sys::mknod(path, syscall::MODE_FIFO as mode_t | (mode & 0o777), 0) } @@ -874,8 +891,8 @@ impl Pal for Sys { // POSIX states that umask should affect the following: // - // open, openat (TODO), creat, mkdir, mkdirat (TODO), - // mkfifo, mkfifoat (TODO), mknod, mknodat (TODO), + // open, openat, creat, mkdir, mkdirat, + // mkfifo, mkfifoat, mknod, mknodat, // mq_open, and sem_open, // // all of which (the ones that exist thus far) currently call this function.