Skip to content

Commit a220ded

Browse files
bors[bot]zmlcc
andauthored
Merge #1133
1133: Implement mkfifoat r=asomers a=zmlcc This adds the `mkfifoat ` function, which is part of POSIX [https://pubs.opengroup.org/onlinepubs/9699919799/functions/mkfifoat.html](https://pubs.opengroup.org/onlinepubs/9699919799/functions/mkfifoat.html) test cases are copied from `mkfifo` Co-authored-by: Zhang Miaolei <[email protected]>
2 parents a491f25 + 4b23433 commit a220ded

File tree

3 files changed

+75
-0
lines changed

3 files changed

+75
-0
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@ This project adheres to [Semantic Versioning](http://semver.org/).
1515
- Added `NixPath::is_empty`.
1616
([#1107](https://github.com/nix-rust/nix/pull/1107))
1717

18+
- Added `mkfifoat`
19+
([#1133](https://github.com/nix-rust/nix/pull/1133))
20+
1821
### Changed
1922
- `Signal::from_c_int` has been replaced by `Signal::try_from`
2023
([#1113](https://github.com/nix-rust/nix/pull/1113))

src/unistd.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -506,6 +506,26 @@ 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+
// mkfifoat is not implemented in OSX or android
519+
#[inline]
520+
#[cfg(not(any(target_os = "macos", target_os = "ios", target_os = "android")))]
521+
pub fn mkfifoat<P: ?Sized + NixPath>(dirfd: Option<RawFd>, path: &P, mode: Mode) -> Result<()> {
522+
let res = path.with_nix_path(|cstr| unsafe {
523+
libc::mkfifoat(at_rawfd(dirfd), cstr.as_ptr(), mode.bits() as mode_t)
524+
})?;
525+
526+
Errno::result(res).map(drop)
527+
}
528+
509529
/// Creates a symbolic link at `path2` which points to `path1`.
510530
///
511531
/// If `dirfd` has a value, then `path2` is relative to directory associated

test/test_unistd.rs

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

101+
#[test]
102+
#[cfg(not(any(target_os = "macos", target_os = "ios", target_os = "android")))]
103+
fn test_mkfifoat_none() {
104+
let tempdir = tempfile::tempdir().unwrap();
105+
let mkfifoat_fifo = tempdir.path().join("mkfifoat_fifo");
106+
107+
mkfifoat(None, &mkfifoat_fifo, Mode::S_IRUSR).unwrap();
108+
109+
let stats = stat::stat(&mkfifoat_fifo).unwrap();
110+
let typ = stat::SFlag::from_bits_truncate(stats.st_mode);
111+
assert_eq!(typ, SFlag::S_IFIFO);
112+
}
113+
114+
#[test]
115+
#[cfg(not(any(target_os = "macos", target_os = "ios", target_os = "android")))]
116+
fn test_mkfifoat() {
117+
let tempdir = tempfile::tempdir().unwrap();
118+
let dirfd = open(tempdir.path(), OFlag::empty(), Mode::empty()).unwrap();
119+
let mkfifoat_name = "mkfifoat_name";
120+
121+
mkfifoat(Some(dirfd), mkfifoat_name, Mode::S_IRUSR).unwrap();
122+
123+
let stats = stat::fstatat(dirfd, mkfifoat_name, fcntl::AtFlags::empty()).unwrap();
124+
let typ = stat::SFlag::from_bits_truncate(stats.st_mode);
125+
assert_eq!(typ, SFlag::S_IFIFO);
126+
}
127+
128+
#[test]
129+
#[cfg(not(any(target_os = "macos", target_os = "ios", target_os = "android")))]
130+
fn test_mkfifoat_directory_none() {
131+
// mkfifoat should fail if a directory is given
132+
assert_eq!(
133+
mkfifoat(None, &env::temp_dir(), Mode::S_IRUSR).is_ok(),
134+
false
135+
);
136+
}
137+
138+
#[test]
139+
#[cfg(not(any(target_os = "macos", target_os = "ios", target_os = "android")))]
140+
fn test_mkfifoat_directory() {
141+
// mkfifoat should fail if a directory is given
142+
let tempdir = tempfile::tempdir().unwrap();
143+
let dirfd = open(tempdir.path(), OFlag::empty(), Mode::empty()).unwrap();
144+
let mkfifoat_dir = "mkfifoat_dir";
145+
stat::mkdirat(dirfd, mkfifoat_dir, Mode::S_IRUSR).unwrap();
146+
147+
assert_eq!(
148+
mkfifoat(Some(dirfd), mkfifoat_dir, Mode::S_IRUSR).is_ok(),
149+
false
150+
);
151+
}
152+
101153
#[test]
102154
fn test_getpid() {
103155
let pid: ::libc::pid_t = getpid().into();

0 commit comments

Comments
 (0)