From 08c41c853b092f20cad6f3a3ff9153b3b34564f2 Mon Sep 17 00:00:00 2001 From: Jakub Pastuszek Date: Wed, 11 Oct 2017 09:46:22 +0100 Subject: [PATCH] added unistd::mkfifo #602 --- CHANGELOG.md | 2 ++ src/unistd.rs | 43 +++++++++++++++++++++++++++++++++++++++++++ test/test_unistd.rs | 18 ++++++++++++++++++ 3 files changed, 63 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 664fdaffd1..9617a8a1a0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -34,6 +34,8 @@ This project adheres to [Semantic Versioning](http://semver.org/). ([#773](https://github.com/nix-rust/nix/pull/773)) - Add nix::sys::fallocate ([#768](https:://github.com/nix-rust/nix/pull/768)) +- Added `nix::unistd::mkfifo`. + ([#602](https://github.com/nix-rust/nix/pull/774)) ### Changed - Renamed existing `ptrace` wrappers to encourage namespacing ([#692](https://github.com/nix-rust/nix/pull/692)) diff --git a/src/unistd.rs b/src/unistd.rs index 14da5ffd05..401357d3da 100644 --- a/src/unistd.rs +++ b/src/unistd.rs @@ -438,6 +438,49 @@ pub fn mkdir(path: &P, mode: Mode) -> Result<()> { Errno::result(res).map(drop) } +/// Creates new fifo special file (named pipe) with path `path` and access rights `mode`. +/// +/// # Errors +/// +/// There are several situations where mkfifo might fail: +/// +/// - current user has insufficient rights in the parent directory +/// - the path already exists +/// - the path name is too long (longer than `PATH_MAX`, usually 4096 on linux, 1024 on OS X) +/// +/// For a full list consult +/// [posix specification](http://pubs.opengroup.org/onlinepubs/9699919799/functions/mkfifo.html) +/// +/// # Example +/// +/// ```rust +/// extern crate tempdir; +/// extern crate nix; +/// +/// use nix::unistd; +/// use nix::sys::stat; +/// use tempdir::TempDir; +/// +/// fn main() { +/// let tmp_dir = TempDir::new("test_fifo").unwrap(); +/// let fifo_path = tmp_dir.path().join("foo.pipe"); +/// +/// // create new fifo and give read, write and execute rights to the owner +/// match unistd::mkfifo(&fifo_path, stat::S_IRWXU) { +/// Ok(_) => println!("created {:?}", fifo_path), +/// Err(err) => println!("Error creating fifo: {}", err), +/// } +/// } +/// ``` +#[inline] +pub fn mkfifo(path: &P, mode: Mode) -> Result<()> { + let res = try!(path.with_nix_path(|cstr| { + unsafe { libc::mkfifo(cstr.as_ptr(), mode.bits() as mode_t) } + })); + + Errno::result(res).map(drop) +} + /// Returns the current directory as a PathBuf /// /// Err is returned if the current user doesn't have the permission to read or search a component diff --git a/test/test_unistd.rs b/test/test_unistd.rs index adf735794e..627eb09b0e 100644 --- a/test/test_unistd.rs +++ b/test/test_unistd.rs @@ -85,6 +85,24 @@ fn test_mkstemp_directory() { assert!(mkstemp(&env::temp_dir()).is_err()); } +#[test] +fn test_mkfifo() { + let tempdir = TempDir::new("nix-test_mkfifo").unwrap(); + let mkfifo_fifo = tempdir.path().join("mkfifo_fifo"); + + mkfifo(&mkfifo_fifo, stat::S_IRUSR).unwrap(); + + let stats = stat::stat(&mkfifo_fifo).unwrap(); + let typ = stat::SFlag::from_bits_truncate(stats.st_mode); + assert!(typ == stat::S_IFIFO); +} + +#[test] +fn test_mkfifo_directory() { + // mkfifo should fail if a directory is given + assert!(mkfifo(&env::temp_dir(), stat::S_IRUSR).is_err()); +} + #[test] fn test_getpid() { let pid: ::libc::pid_t = getpid().into();