summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.md2
-rw-r--r--src/unistd.rs25
-rw-r--r--test/test_unistd.rs17
3 files changed, 44 insertions, 0 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index b09bc709..c52fd527 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -22,6 +22,8 @@ This project adheres to [Semantic Versioning](http://semver.org/).
- Added `nix::unistd:seteuid` and `nix::unistd::setegid` for those platforms that do
not support `setresuid` nor `setresgid` respectively.
([#1044](https://github.com/nix-rust/nix/pull/1044))
+- Added a `access` wrapper
+ ([#1045](https://github.com/nix-rust/nix/pull/1045))
### Changed
- `PollFd` event flags renamed to `PollFlags` ([#1024](https://github.com/nix-rust/nix/pull/1024/))
diff --git a/src/unistd.rs b/src/unistd.rs
index c3b2b61e..f855c0af 100644
--- a/src/unistd.rs
+++ b/src/unistd.rs
@@ -2334,3 +2334,28 @@ mod setres {
Errno::result(res).map(drop)
}
}
+
+libc_bitflags!{
+ /// Options for access()
+ pub struct AccessFlags : c_int {
+ /// Test for existence of file.
+ F_OK;
+ /// Test for read permission.
+ R_OK;
+ /// Test for write permission.
+ W_OK;
+ /// Test for execute (search) permission.
+ X_OK;
+ }
+}
+
+/// Checks the file named by `path` for accessibility according to the flags given by `amode`
+/// See [access(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/access.html)
+pub fn access<P: ?Sized + NixPath>(path: &P, amode: AccessFlags) -> Result<()> {
+ let res = path.with_nix_path(|cstr| {
+ unsafe {
+ libc::access(cstr.as_ptr(), amode.bits)
+ }
+ })?;
+ Errno::result(res).map(drop)
+}
diff --git a/test/test_unistd.rs b/test/test_unistd.rs
index 3fb50535..3f13883c 100644
--- a/test/test_unistd.rs
+++ b/test/test_unistd.rs
@@ -4,6 +4,7 @@ use nix::unistd::ForkResult::*;
use nix::sys::signal::{SaFlags, SigAction, SigHandler, SigSet, Signal, sigaction};
use nix::sys::wait::*;
use nix::sys::stat::{self, Mode, SFlag};
+use nix::errno::Errno;
use std::{env, iter};
use std::ffi::CString;
use std::fs::{self, File};
@@ -574,3 +575,19 @@ fn test_symlinkat() {
target
);
}
+
+#[test]
+fn test_access_not_existing() {
+ let tempdir = tempfile::tempdir().unwrap();
+ let dir = tempdir.path().join("does_not_exist.txt");
+ assert_eq!(access(&dir, AccessFlags::F_OK).err().unwrap().as_errno().unwrap(),
+ Errno::ENOENT);
+}
+
+#[test]
+fn test_access_file_exists() {
+ let tempdir = tempfile::tempdir().unwrap();
+ let path = tempdir.path().join("does_exist.txt");
+ let _file = File::create(path.clone()).unwrap();
+ assert!(access(&path, AccessFlags::R_OK | AccessFlags::W_OK).is_ok());
+}