Skip to content

Commit a7d5f8f

Browse files
committed
Add unistd::{access, faccessat}
1 parent ba5c837 commit a7d5f8f

File tree

1 file changed

+60
-2
lines changed

1 file changed

+60
-2
lines changed

src/unistd.rs

Lines changed: 60 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
//! Safe wrappers around functions found in libc "unistd.h" header
22
33
use {Errno, Error, Result, NixPath};
4-
use fcntl::{fcntl, OFlag, O_CLOEXEC, FD_CLOEXEC};
4+
use fcntl::{fcntl, OFlag, AtFlags, O_CLOEXEC, FD_CLOEXEC};
55
use fcntl::FcntlArg::F_SETFD;
66
use libc::{self, c_char, c_void, c_int, c_uint, size_t, pid_t, off_t, uid_t, gid_t, mode_t};
77
use std::mem;
88
use std::ffi::{CString, CStr, OsString, OsStr};
99
use std::os::unix::ffi::{OsStringExt, OsStrExt};
1010
use std::os::unix::io::RawFd;
11-
use std::path::{PathBuf};
11+
use std::path::PathBuf;
1212
use void::Void;
1313
use sys::stat::Mode;
1414

@@ -819,6 +819,64 @@ pub fn mkstemp<P: ?Sized + NixPath>(template: &P) -> Result<(RawFd, PathBuf)> {
819819
Ok((fd, PathBuf::from(pathname)))
820820
}
821821

822+
libc_bitflags!{
823+
pub flags AccessFlags: c_int {
824+
R_OK,
825+
W_OK,
826+
X_OK,
827+
}
828+
}
829+
830+
pub enum AccessMode {
831+
F_OK,
832+
Flags(AccessFlags),
833+
}
834+
835+
impl AccessMode {
836+
fn to_libc_type(&self) -> c_int {
837+
match self {
838+
&AccessMode::F_OK => libc::F_OK,
839+
&AccessMode::Flags(flags) => flags.bits(),
840+
}
841+
}
842+
}
843+
844+
/// Check whether a file exists or whether the current process can access a file.
845+
///
846+
/// # Example
847+
/// ```
848+
/// use nix::unistd::*;
849+
///
850+
/// let devnull_exists = access("/dev/null", AccessMode::F_OK);
851+
/// assert!(devnull_exists.is_ok());
852+
/// ```
853+
pub fn access<P: ?Sized + NixPath>(path: &P, mode: AccessMode) -> Result<()> {
854+
let res = try!(path.with_nix_path(|path|
855+
unsafe {
856+
libc::access(path.as_ptr(), mode.to_libc_type())
857+
}
858+
));
859+
Errno::result(res).map(drop)
860+
}
861+
862+
/// Check whether a file exists or whether the current process can access a file,
863+
/// relative to a directory file descriptor.
864+
pub fn faccessat<P: ?Sized + NixPath>(dirfd: RawFd,
865+
path: &P,
866+
mode: AccessMode,
867+
flags: AtFlags)
868+
-> Result<()> {
869+
let res = try!(path.with_nix_path(|path|
870+
unsafe {
871+
libc::faccessat(dirfd,
872+
path.as_ptr(),
873+
mode.to_libc_type(),
874+
flags.bits())
875+
}
876+
));
877+
Errno::result(res).map(drop)
878+
}
879+
822880
#[cfg(any(target_os = "linux", target_os = "android"))]
823881
mod linux {
824882
use libc::{self, uid_t, gid_t};

0 commit comments

Comments
 (0)