diff --git a/CHANGELOG.md b/CHANGELOG.md index 36b528ca91..f989c6800c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,8 @@ This project adheres to [Semantic Versioning](http://semver.org/). ([#739](https://github.com/nix-rust/nix/pull/739)) - Added nix::sys::ptrace::detach. ([#749](https://github.com/nix-rust/nix/pull/749)) +- Added `nix::unistd::mkdirat` + ([#754](https://github.com/nix-rust/nix/pull/754)) ### 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 fad51272e0..23b38e805c 100644 --- a/src/unistd.rs +++ b/src/unistd.rs @@ -441,6 +441,16 @@ pub fn mkdir(path: &P, mode: Mode) -> Result<()> { Errno::result(res).map(drop) } +/// Create a directory +/// ([posix specification)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/mkdirat.html)). +pub fn mkdirat(dirfd: RawFd, pathname: &P, mode: Mode) -> Result<()> { + let res = try!(pathname.with_nix_path(|cstr| { + unsafe { libc::mkdirat(dirfd, 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..c2e220dbc8 100644 --- a/test/test_unistd.rs +++ b/test/test_unistd.rs @@ -1,5 +1,6 @@ extern crate tempdir; +use nix::fcntl; use nix::unistd::*; use nix::unistd::ForkResult::*; use nix::sys::wait::*; @@ -104,6 +105,22 @@ mod linux_android { } } +#[test] +fn test_mkdirat() { + let tempdir = TempDir::new("nix-test_mkdirat").unwrap(); + let path = tempdir.path().join("test_path"); + + let dirfd = fcntl::open(tempdir.path(), + fcntl::OFlag::empty(), + stat::Mode::empty()); + + mkdirat(dirfd.unwrap(), + &path.file_name(), + stat::Mode::empty()).unwrap(); + + assert!(path.exists()); +} + macro_rules! execve_test_factory( ($test_name:ident, $syscall:ident, $exe: expr) => ( #[test]