diff --git a/src/libstd/io/fs.rs b/src/libstd/io/fs.rs index e52c00f8247a8..6f2047bdc8ad6 100644 --- a/src/libstd/io/fs.rs +++ b/src/libstd/io/fs.rs @@ -70,6 +70,8 @@ use vec::Vec; use sys::fs as fs_imp; use sys_common; +pub use libc::{F_OK,R_OK,W_OK,X_OK}; + /// Unconstrained file access type that exposes read and write operations /// /// Can be constructed via `File::open()`, `File::create()`, and @@ -326,6 +328,36 @@ pub fn lstat(path: &Path) -> IoResult { format!("{}; path={}", e, path.display())) } +/// Given a path and access mode, checks whether the calling process can access +/// the path and perform the requested operations. +/// Mode can either be F_OK to check for existence or a bitwise OR of one or +/// more of R_OK, W_OK, and X_OK to test for read, write and execute access +/// respectively. +/// +/// # Example +/// +/// ```rust +/// use std::io::fs; +/// use std::io::fs::{R_OK,W_OK,X_OK}; +/// +/// let p = Path::new("/some/file/path.txt"); +/// match fs::access(&p, R_OK|W_OK|X_OK) { +/// Err(e) => { /* handle error */ } +/// _ => { /* ... */ } +/// } +/// ``` +/// +/// # Error +/// +/// This function will return an error if the user is not allowed to +/// perform the requested operations on the file. +pub fn access(path: &Path, amode: i32) -> IoResult<()> { + fs_imp::access(path, amode) + .update_err("couldn't access path", |e| + format!("{}; path={}; amode={}", e, path.display(), amode)) + +} + /// Rename a file or directory to a new name. /// /// # Example diff --git a/src/libstd/sys/unix/fs.rs b/src/libstd/sys/unix/fs.rs index 4b47b768d600c..3fd6595aa2dce 100644 --- a/src/libstd/sys/unix/fs.rs +++ b/src/libstd/sys/unix/fs.rs @@ -25,6 +25,7 @@ use sys::retry; use sys_common::{keep_going, eof, mkerr_libc}; pub use path::PosixPath as Path; +pub use libc::{F_OK,R_OK,W_OK,X_OK}; pub type fd_t = libc::c_int; @@ -349,6 +350,11 @@ pub fn lstat(p: &Path) -> IoResult { } } +pub fn access(p: &Path, a: i32) -> IoResult<()> { + let p = p.to_c_str(); + mkerr_libc(unsafe { libc::access(p.as_ptr(), a) }) +} + pub fn utime(p: &Path, atime: u64, mtime: u64) -> IoResult<()> { let p = p.to_c_str(); let buf = libc::utimbuf { diff --git a/src/libstd/sys/windows/fs.rs b/src/libstd/sys/windows/fs.rs index 9402c63dcf558..c1c640b356dd4 100644 --- a/src/libstd/sys/windows/fs.rs +++ b/src/libstd/sys/windows/fs.rs @@ -30,6 +30,8 @@ use io::{IoResult, IoError, FileStat, SeekStyle, Seek, Writer, Reader}; use io::{Read, Truncate, SeekCur, SeekSet, ReadWrite, SeekEnd, Append}; pub use path::WindowsPath as Path; +pub use libc::{F_OK,R_OK,W_OK,X_OK}; + pub type fd_t = libc::c_int; pub struct FileDesc { @@ -448,6 +450,11 @@ pub fn lstat(_p: &Path) -> IoResult { Err(super::unimpl()) } +pub fn access(p: &Path, a: i32) -> IoResult<()> { + let p = p.to_c_str(); + mkerr_libc(unsafe { libc::access(p.as_ptr(), a) }) +} + pub fn utime(p: &Path, atime: u64, mtime: u64) -> IoResult<()> { let mut buf = libc::utimbuf { actime: atime as libc::time64_t,