diff options
-rw-r--r-- | src/fcntl.rs | 33 | ||||
-rw-r--r-- | test/test_fcntl.rs | 16 | ||||
-rw-r--r-- | test/test_unistd.rs | 5 |
3 files changed, 19 insertions, 35 deletions
diff --git a/src/fcntl.rs b/src/fcntl.rs index f590e361..2adbb6ab 100644 --- a/src/fcntl.rs +++ b/src/fcntl.rs @@ -1,11 +1,11 @@ -use {Error, Result, NixPath}; +use {Result, NixPath}; use errno::Errno; use libc::{self, c_int, c_uint, c_char, size_t, ssize_t}; use sys::stat::Mode; use std::os::raw; use std::os::unix::io::RawFd; -use std::ffi::OsStr; -use std::os::unix::ffi::OsStrExt; +use std::ffi::OsString; +use std::os::unix::ffi::OsStringExt; #[cfg(any(target_os = "android", target_os = "linux"))] use std::ptr; // For splice and copy_file_range @@ -177,36 +177,33 @@ pub fn renameat<P1: ?Sized + NixPath, P2: ?Sized + NixPath>(old_dirfd: Option<Ra Errno::result(res).map(drop) } -fn wrap_readlink_result(buffer: &mut[u8], res: ssize_t) -> Result<&OsStr> { +fn wrap_readlink_result(v: &mut Vec<u8>, res: ssize_t) -> Result<OsString> { match Errno::result(res) { Err(err) => Err(err), Ok(len) => { - if len < 0 { - Err(Error::Sys(Errno::EINVAL)) - } else if (len as usize) > buffer.len() { - Err(Error::Sys(Errno::ENAMETOOLONG)) - } else { - Ok(OsStr::from_bytes(&buffer[..(len as usize)])) - } + unsafe { v.set_len(len as usize) } + Ok(OsString::from_vec(v.to_vec())) } } } -pub fn readlink<'a, P: ?Sized + NixPath>(path: &P, buffer: &'a mut [u8]) -> Result<&'a OsStr> { +pub fn readlink<'a, P: ?Sized + NixPath>(path: &P) -> Result<OsString> { + let mut v = vec![0u8; libc::PATH_MAX as usize]; let res = path.with_nix_path(|cstr| { - unsafe { libc::readlink(cstr.as_ptr(), buffer.as_mut_ptr() as *mut c_char, buffer.len() as size_t) } + unsafe { libc::readlink(cstr.as_ptr(), v.as_mut_ptr() as *mut c_char, v.len() as size_t) } })?; - - wrap_readlink_result(buffer, res) + + wrap_readlink_result(&mut v, res) } -pub fn readlinkat<'a, P: ?Sized + NixPath>(dirfd: RawFd, path: &P, buffer: &'a mut [u8]) -> Result<&'a OsStr> { +pub fn readlinkat<'a, P: ?Sized + NixPath>(dirfd: RawFd, path: &P) -> Result<OsString> { + let mut v = vec![0u8; libc::PATH_MAX as usize]; let res = path.with_nix_path(|cstr| { - unsafe { libc::readlinkat(dirfd, cstr.as_ptr(), buffer.as_mut_ptr() as *mut c_char, buffer.len() as size_t) } + unsafe { libc::readlinkat(dirfd, cstr.as_ptr(), v.as_mut_ptr() as *mut c_char, v.len() as size_t) } })?; - wrap_readlink_result(buffer, res) + wrap_readlink_result(&mut v, res) } /// Computes the raw fd consumed by a function of the form `*at`. diff --git a/test/test_fcntl.rs b/test/test_fcntl.rs index c8773219..1bcf12cb 100644 --- a/test/test_fcntl.rs +++ b/test/test_fcntl.rs @@ -58,20 +58,8 @@ fn test_readlink() { Mode::empty()).unwrap(); let expected_dir = src.to_str().unwrap(); - // When the size of the buffer is bigger than the expected directory length - let mut buf = vec![0; src.to_str().unwrap().len() + 1]; - assert_eq!(readlink(&dst, &mut buf).unwrap().to_str().unwrap(), expected_dir); - assert_eq!(readlinkat(dirfd, "b", &mut buf).unwrap().to_str().unwrap(), expected_dir); - - // When the size of the buffer is equal to the expected directory length - let mut exact_buf = vec![0; src.to_str().unwrap().len()]; - assert_eq!(readlink(&dst, &mut exact_buf).unwrap().to_str().unwrap(), expected_dir); - assert_eq!(readlinkat(dirfd, "b", &mut exact_buf).unwrap().to_str().unwrap(), expected_dir); - - // When the size of the buffer is smaller than the expected directory length - let mut small_buf = vec![0;0]; - assert_eq!(readlink(&dst, &mut small_buf).unwrap().to_str().unwrap(), ""); - assert_eq!(readlinkat(dirfd, "b", &mut small_buf).unwrap().to_str().unwrap(), ""); + assert_eq!(readlink(&dst).unwrap().to_str().unwrap(), expected_dir); + assert_eq!(readlinkat(dirfd, "b").unwrap().to_str().unwrap(), expected_dir); } diff --git a/test/test_unistd.rs b/test/test_unistd.rs index 46196dec..e1e03f3f 100644 --- a/test/test_unistd.rs +++ b/test/test_unistd.rs @@ -576,14 +576,13 @@ fn test_canceling_alarm() { #[test] fn test_symlinkat() { - let mut buf = [0; 1024]; let tempdir = tempfile::tempdir().unwrap(); let target = tempdir.path().join("a"); let linkpath = tempdir.path().join("b"); symlinkat(&target, None, &linkpath).unwrap(); assert_eq!( - readlink(&linkpath, &mut buf).unwrap().to_str().unwrap(), + readlink(&linkpath).unwrap().to_str().unwrap(), target.to_str().unwrap() ); @@ -592,7 +591,7 @@ fn test_symlinkat() { let linkpath = "d"; symlinkat(target, Some(dirfd), linkpath).unwrap(); assert_eq!( - readlink(&tempdir.path().join(linkpath), &mut buf) + readlink(&tempdir.path().join(linkpath)) .unwrap() .to_str() .unwrap(), |