|
1 | | -use {Errno, Result, NixPath}; |
2 | | -use libc::{self, c_int, c_uint}; |
| 1 | +use {Error, Errno, Result, NixPath}; |
| 2 | +use libc::{self, c_int, c_uint, c_char, size_t, ssize_t}; |
3 | 3 | use sys::stat::Mode; |
4 | 4 | use std::os::unix::io::RawFd; |
| 5 | +use std::ffi::OsStr; |
| 6 | +use std::os::unix::ffi::OsStrExt; |
5 | 7 |
|
6 | 8 | #[cfg(any(target_os = "linux", target_os = "android"))] |
7 | 9 | use sys::uio::IoVec; // For vmsplice |
@@ -49,10 +51,40 @@ pub fn openat<P: ?Sized + NixPath>(dirfd: RawFd, path: &P, oflag: OFlag, mode: M |
49 | 51 | let fd = try!(path.with_nix_path(|cstr| { |
50 | 52 | unsafe { libc::openat(dirfd, cstr.as_ptr(), oflag.bits(), mode.bits() as c_uint) } |
51 | 53 | })); |
52 | | - |
53 | 54 | Errno::result(fd) |
54 | 55 | } |
55 | 56 |
|
| 57 | +fn wrap_readlink_result<'a>(buffer: &'a mut[u8], res: ssize_t) |
| 58 | + -> Result<&'a OsStr> { |
| 59 | + match Errno::result(res) { |
| 60 | + Err(err) => Err(err), |
| 61 | + Ok(len) => { |
| 62 | + if (len as usize) >= buffer.len() { |
| 63 | + Err(Error::Sys(Errno::ENAMETOOLONG)) |
| 64 | + } else { |
| 65 | + Ok(OsStr::from_bytes(&buffer[..(len as usize)])) |
| 66 | + } |
| 67 | + } |
| 68 | + } |
| 69 | +} |
| 70 | + |
| 71 | +pub fn readlink<'a, P: ?Sized + NixPath>(path: &P, buffer: &'a mut [u8]) -> Result<&'a OsStr> { |
| 72 | + let res = try!(path.with_nix_path(|cstr| { |
| 73 | + unsafe { libc::readlink(cstr.as_ptr(), buffer.as_mut_ptr() as *mut c_char, buffer.len() as size_t) } |
| 74 | + })); |
| 75 | + |
| 76 | + wrap_readlink_result(buffer, res) |
| 77 | +} |
| 78 | + |
| 79 | + |
| 80 | +pub fn readlinkat<'a, P: ?Sized + NixPath>(dirfd: RawFd, path: &P, buffer: &'a mut [u8]) -> Result<&'a OsStr> { |
| 81 | + let res = try!(path.with_nix_path(|cstr| { |
| 82 | + unsafe { libc::readlinkat(dirfd, cstr.as_ptr(), buffer.as_mut_ptr() as *mut c_char, buffer.len() as size_t) } |
| 83 | + })); |
| 84 | + |
| 85 | + wrap_readlink_result(buffer, res) |
| 86 | +} |
| 87 | + |
56 | 88 | pub enum FcntlArg<'a> { |
57 | 89 | F_DUPFD(RawFd), |
58 | 90 | F_DUPFD_CLOEXEC(RawFd), |
|
0 commit comments