Skip to content

Commit 4fe8418

Browse files
committed
add mkfifoat
1 parent a491f25 commit 4fe8418

File tree

2 files changed

+53
-0
lines changed

2 files changed

+53
-0
lines changed

src/unistd.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -506,6 +506,24 @@ pub fn mkfifo<P: ?Sized + NixPath>(path: &P, mode: Mode) -> Result<()> {
506506
Errno::result(res).map(drop)
507507
}
508508

509+
/// Creates new fifo special file (named pipe) with path `path` and access rights `mode`.
510+
///
511+
/// If `dirfd` has a value, then `path` is relative to directory associated with the file descriptor.
512+
///
513+
/// If `dirfd` is `None`, then `path` is relative to the current working directory.
514+
///
515+
/// # References
516+
///
517+
/// [mkfifoat(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/mkfifoat.html).
518+
#[inline]
519+
pub fn mkfifoat<P: ?Sized + NixPath>(dirfd: Option<RawFd>, path: &P, mode: Mode) -> Result<()> {
520+
let res = path.with_nix_path(|cstr| {
521+
unsafe { libc::mkfifoat(at_rawfd(dirfd), cstr.as_ptr(), mode.bits() as mode_t) }
522+
})?;
523+
524+
Errno::result(res).map(drop)
525+
}
526+
509527
/// Creates a symbolic link at `path2` which points to `path1`.
510528
///
511529
/// If `dirfd` has a value, then `path2` is relative to directory associated

test/test_unistd.rs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,41 @@ fn test_mkfifo_directory() {
9898
assert!(mkfifo(&env::temp_dir(), Mode::S_IRUSR).is_err());
9999
}
100100

101+
#[test]
102+
fn test_mkfifoat() {
103+
let tempdir = tempfile::tempdir().unwrap();
104+
let mkfifoat_fifo = tempdir.path().join("mkfifoat_fifo");
105+
106+
mkfifoat(None, &mkfifoat_fifo, Mode::S_IRUSR).unwrap();
107+
108+
let stats = stat::stat(&mkfifoat_fifo).unwrap();
109+
let typ = stat::SFlag::from_bits_truncate(stats.st_mode);
110+
assert!(typ == SFlag::S_IFIFO);
111+
112+
113+
let dirfd = open(tempdir.path(), OFlag::empty(), Mode::empty()).unwrap();
114+
let mkfifoat_name = "mkfifoat_name";
115+
116+
mkfifoat(Some(dirfd), mkfifoat_name, Mode::S_IRUSR).unwrap();
117+
118+
let stats = stat::fstatat(dirfd, mkfifoat_name, fcntl::AtFlags::empty()).unwrap();
119+
let typ = stat::SFlag::from_bits_truncate(stats.st_mode);
120+
assert!(typ == SFlag::S_IFIFO);
121+
}
122+
123+
#[test]
124+
fn test_mkfifoat_directory() {
125+
// mkfifoat should fail if a directory is given
126+
assert!(mkfifoat(None, &env::temp_dir(), Mode::S_IRUSR).is_err());
127+
128+
let tempdir = tempfile::tempdir().unwrap();
129+
let dirfd = open(tempdir.path(), OFlag::empty(), Mode::empty()).unwrap();
130+
let mkfifoat_dir = "mkfifoat_dir";
131+
stat::mkdirat(dirfd, mkfifoat_dir, Mode::S_IRUSR).unwrap();
132+
133+
assert!(mkfifoat(Some(dirfd), mkfifoat_dir, Mode::S_IRUSR).is_err());
134+
}
135+
101136
#[test]
102137
fn test_getpid() {
103138
let pid: ::libc::pid_t = getpid().into();

0 commit comments

Comments
 (0)