Skip to content

Commit 2b0c63f

Browse files
committed
add support for openat
1 parent 0eef651 commit 2b0c63f

File tree

3 files changed

+57
-0
lines changed

3 files changed

+57
-0
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ This project adheres to [Semantic Versioning](http://semver.org/).
66
## [Unreleased]
77

88
<!--### Added-->
9+
- Added `openat` in `::nix::unistd`
10+
([#497](https://github.com/nix-rust/nix/pull/551))
911

1012
### Changed
1113
- Marked `sys::mman::{ mmap, munmap, madvise, munlock, msync }` as unsafe.

src/fcntl.rs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,25 @@ mod ffi {
1818
pub const F_GET_SEALS: c_int = 1034;
1919
}
2020

21+
#[cfg(not(any(target_os = "ios", target_os = "macos")))]
22+
libc_bitflags!{
23+
pub flags AtFlags: c_int {
24+
AT_SYMLINK_NOFOLLOW,
25+
#[cfg(any(target_os = "linux", target_os = "android"))]
26+
AT_NO_AUTOMOUNT,
27+
#[cfg(any(target_os = "linux", target_os = "android"))]
28+
AT_EMPTY_PATH
29+
}
30+
}
31+
32+
#[cfg(any(target_os = "ios", target_os = "macos"))]
33+
bitflags!(
34+
pub flags AtFlags: c_int {
35+
// hack because bitflags require one entry
36+
const EMPTY = 0x0
37+
}
38+
);
39+
2140
pub fn open<P: ?Sized + NixPath>(path: &P, oflag: OFlag, mode: Mode) -> Result<RawFd> {
2241
let fd = try!(path.with_nix_path(|cstr| {
2342
unsafe { libc::open(cstr.as_ptr(), oflag.bits(), mode.bits() as c_uint) }
@@ -26,6 +45,14 @@ pub fn open<P: ?Sized + NixPath>(path: &P, oflag: OFlag, mode: Mode) -> Result<R
2645
Errno::result(fd)
2746
}
2847

48+
pub fn openat<P: ?Sized + NixPath>(dirfd: RawFd, path: &P, oflag: OFlag, mode: Mode) -> Result<RawFd> {
49+
let fd = try!(path.with_nix_path(|cstr| {
50+
unsafe { libc::openat(dirfd, cstr.as_ptr(), oflag.bits(), mode.bits() as c_uint) }
51+
}));
52+
53+
Errno::result(fd)
54+
}
55+
2956
pub enum FcntlArg<'a> {
3057
F_DUPFD(RawFd),
3158
F_DUPFD_CLOEXEC(RawFd),

test/test_fcntl.rs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,31 @@
1+
use nix::fcntl::{openat, open, O_PATH, O_RDONLY};
2+
use nix::sys::stat::Mode;
3+
use nix::unistd::{close, read};
4+
use tempfile::NamedTempFile;
5+
use std::io::prelude::*;
6+
7+
#[test]
8+
fn test_openat() {
9+
const CONTENTS: &'static [u8] = b"abcd";
10+
let mut tmp = NamedTempFile::new().unwrap();
11+
tmp.write(CONTENTS).unwrap();
12+
13+
let dirfd = open(tmp.path().parent().unwrap(),
14+
O_PATH,
15+
Mode::empty()).unwrap();
16+
let fd = openat(dirfd,
17+
tmp.path().file_name().unwrap(),
18+
O_RDONLY,
19+
Mode::empty()).unwrap();
20+
21+
let mut buf = [0u8; 1024];
22+
assert_eq!(4, read(fd, &mut buf).unwrap());
23+
assert_eq!(CONTENTS, &buf[0..4]);
24+
25+
close(fd).unwrap();
26+
close(dirfd).unwrap();
27+
}
28+
129
#[cfg(any(target_os = "linux", target_os = "android"))]
230
mod linux_android {
331
use std::io::prelude::*;

0 commit comments

Comments
 (0)