diff options
-rw-r--r-- | src/unistd.rs | 20 | ||||
-rw-r--r-- | test/test_unistd.rs | 15 |
2 files changed, 27 insertions, 8 deletions
diff --git a/src/unistd.rs b/src/unistd.rs index 34e9b6a9..f8e17153 100644 --- a/src/unistd.rs +++ b/src/unistd.rs @@ -3,12 +3,13 @@ use {Errno, Error, Result, NixPath}; use fcntl::{fcntl, OFlag, O_NONBLOCK, O_CLOEXEC, FD_CLOEXEC}; use fcntl::FcntlArg::{F_SETFD, F_SETFL}; -use libc::{self, c_char, c_void, c_int, c_uint, size_t, pid_t, off_t, uid_t, gid_t}; +use libc::{self, c_char, c_void, c_int, c_uint, size_t, pid_t, off_t, uid_t, gid_t, mode_t}; use std::mem; use std::ffi::{CString,CStr}; +use std::path::PathBuf; use std::os::unix::io::RawFd; use void::Void; -use std::path::PathBuf; +use sys::stat::Mode; #[cfg(any(target_os = "linux", target_os = "android"))] pub use self::linux::*; @@ -112,10 +113,14 @@ pub fn chdir<P: ?Sized + NixPath>(path: &P) -> Result<()> { Errno::result(res).map(drop) } -// #[inline] -// pub fn mkdir<P: ?Sized + NixPath>(path: &P) -> Result<()> { -// Errno::result(0) -// } +#[inline] +pub fn mkdir<P: ?Sized + NixPath>(path: &P, mode: Mode) -> Result<()> { + let res = try!(path.with_nix_path(|cstr| { + unsafe { libc::mkdir(cstr.as_ptr(), mode.bits() as mode_t) } + })); + + Errno::result(res).map(drop) +} #[inline] pub fn getcwd() -> Result<PathBuf> { @@ -137,7 +142,8 @@ pub fn getcwd() -> Result<PathBuf> { return Ok(PathBuf::from(&s)); } else { let error = Errno::last(); - if error == Errno::ERANGE { + // ERANGE means buffer was too small to store directory name + if error != Errno::ERANGE { return Err(Error::Sys(error)); } } diff --git a/test/test_unistd.rs b/test/test_unistd.rs index 2b6182b6..26746426 100644 --- a/test/test_unistd.rs +++ b/test/test_unistd.rs @@ -3,6 +3,8 @@ extern crate tempdir; use nix::unistd::*; use nix::unistd::ForkResult::*; use nix::sys::wait::*; +use nix::sys::stat; +use std::iter; use std::ffi::CString; use std::io::{Write, Read}; @@ -129,7 +131,18 @@ fn test_getcwd() { } else { "/tmp/" }; - let tmp_dir = TempDir::new_in(base, "test_getcwd").expect("create temp dir").into_path(); + let mut tmp_dir = TempDir::new_in(base, "test_getcwd").expect("create temp dir").into_path(); + assert!(chdir(tmp_dir.as_path()).is_ok()); + assert_eq!(getcwd().unwrap(), tmp_dir); + + // make path 500 chars longer so that buffer doubling in getcwd kicks in. + // Note: One path cannot be longer than 255 bytes (NAME_MAX) + // whole path cannot be longer than PATH_MAX (usually 4096 on linux, 1024 on macos) + for _ in 0..5 { + let newdir = iter::repeat("a").take(100).collect::<String>(); + tmp_dir.push(newdir); + assert!(mkdir(tmp_dir.as_path(), stat::S_IRWXU).is_ok()); + } assert!(chdir(tmp_dir.as_path()).is_ok()); assert_eq!(getcwd().unwrap(), tmp_dir); } |