summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2019-10-07 01:59:29 +0000
committerGitHub <noreply@github.com>2019-10-07 01:59:29 +0000
commita220ded341b826275b4243722af417f55cb23be0 (patch)
tree3543d5410005c791ef0a868bb439bd9d382f2229
parenta491f25f5c6ac65e7d3ea68a4429aa8e9dd29762 (diff)
parent4b23433701bde97697466035c7c7c56cd908edf4 (diff)
downloadnix-a220ded341b826275b4243722af417f55cb23be0.zip
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 <zmlcc@outlook.com>
-rw-r--r--CHANGELOG.md3
-rw-r--r--src/unistd.rs20
-rw-r--r--test/test_unistd.rs52
3 files changed, 75 insertions, 0 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 4a0691d1..e719987d 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -15,6 +15,9 @@ This project adheres to [Semantic Versioning](http://semver.org/).
- Added `NixPath::is_empty`.
([#1107](https://github.com/nix-rust/nix/pull/1107))
+- Added `mkfifoat`
+ ([#1133](https://github.com/nix-rust/nix/pull/1133))
+
### Changed
- `Signal::from_c_int` has been replaced by `Signal::try_from`
([#1113](https://github.com/nix-rust/nix/pull/1113))
diff --git a/src/unistd.rs b/src/unistd.rs
index a269a5c2..886084e8 100644
--- a/src/unistd.rs
+++ b/src/unistd.rs
@@ -506,6 +506,26 @@ pub fn mkfifo<P: ?Sized + NixPath>(path: &P, mode: Mode) -> Result<()> {
Errno::result(res).map(drop)
}
+/// Creates new fifo special file (named pipe) with path `path` and access rights `mode`.
+///
+/// If `dirfd` has a value, then `path` is relative to directory associated with the file descriptor.
+///
+/// If `dirfd` is `None`, then `path` is relative to the current working directory.
+///
+/// # References
+///
+/// [mkfifoat(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/mkfifoat.html).
+// mkfifoat is not implemented in OSX or android
+#[inline]
+#[cfg(not(any(target_os = "macos", target_os = "ios", target_os = "android")))]
+pub fn mkfifoat<P: ?Sized + NixPath>(dirfd: Option<RawFd>, path: &P, mode: Mode) -> Result<()> {
+ let res = path.with_nix_path(|cstr| unsafe {
+ libc::mkfifoat(at_rawfd(dirfd), cstr.as_ptr(), mode.bits() as mode_t)
+ })?;
+
+ Errno::result(res).map(drop)
+}
+
/// Creates a symbolic link at `path2` which points to `path1`.
///
/// If `dirfd` has a value, then `path2` is relative to directory associated
diff --git a/test/test_unistd.rs b/test/test_unistd.rs
index 9e45ceeb..94975049 100644
--- a/test/test_unistd.rs
+++ b/test/test_unistd.rs
@@ -99,6 +99,58 @@ fn test_mkfifo_directory() {
}
#[test]
+#[cfg(not(any(target_os = "macos", target_os = "ios", target_os = "android")))]
+fn test_mkfifoat_none() {
+ let tempdir = tempfile::tempdir().unwrap();
+ let mkfifoat_fifo = tempdir.path().join("mkfifoat_fifo");
+
+ mkfifoat(None, &mkfifoat_fifo, Mode::S_IRUSR).unwrap();
+
+ let stats = stat::stat(&mkfifoat_fifo).unwrap();
+ let typ = stat::SFlag::from_bits_truncate(stats.st_mode);
+ assert_eq!(typ, SFlag::S_IFIFO);
+}
+
+#[test]
+#[cfg(not(any(target_os = "macos", target_os = "ios", target_os = "android")))]
+fn test_mkfifoat() {
+ let tempdir = tempfile::tempdir().unwrap();
+ let dirfd = open(tempdir.path(), OFlag::empty(), Mode::empty()).unwrap();
+ let mkfifoat_name = "mkfifoat_name";
+
+ mkfifoat(Some(dirfd), mkfifoat_name, Mode::S_IRUSR).unwrap();
+
+ let stats = stat::fstatat(dirfd, mkfifoat_name, fcntl::AtFlags::empty()).unwrap();
+ let typ = stat::SFlag::from_bits_truncate(stats.st_mode);
+ assert_eq!(typ, SFlag::S_IFIFO);
+}
+
+#[test]
+#[cfg(not(any(target_os = "macos", target_os = "ios", target_os = "android")))]
+fn test_mkfifoat_directory_none() {
+ // mkfifoat should fail if a directory is given
+ assert_eq!(
+ mkfifoat(None, &env::temp_dir(), Mode::S_IRUSR).is_ok(),
+ false
+ );
+}
+
+#[test]
+#[cfg(not(any(target_os = "macos", target_os = "ios", target_os = "android")))]
+fn test_mkfifoat_directory() {
+ // mkfifoat should fail if a directory is given
+ let tempdir = tempfile::tempdir().unwrap();
+ let dirfd = open(tempdir.path(), OFlag::empty(), Mode::empty()).unwrap();
+ let mkfifoat_dir = "mkfifoat_dir";
+ stat::mkdirat(dirfd, mkfifoat_dir, Mode::S_IRUSR).unwrap();
+
+ assert_eq!(
+ mkfifoat(Some(dirfd), mkfifoat_dir, Mode::S_IRUSR).is_ok(),
+ false
+ );
+}
+
+#[test]
fn test_getpid() {
let pid: ::libc::pid_t = getpid().into();
let ppid: ::libc::pid_t = getppid().into();