Skip to content

Commit f2df347

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

File tree

3 files changed

+36
-2
lines changed

3 files changed

+36
-2
lines changed

CHANGELOG.md

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

88
<!--### Added-->
9+
- Added `openat` in `::nix::fcntl`
910

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

src/fcntl.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,15 @@ pub fn open<P: ?Sized + NixPath>(path: &P, oflag: OFlag, mode: Mode) -> Result<R
2626
Errno::result(fd)
2727
}
2828

29+
#[cfg(any(target_os = "linux", target_os = "android"))]
30+
pub fn openat<P: ?Sized + NixPath>(dirfd: RawFd, path: &P, oflag: OFlag, mode: Mode) -> Result<RawFd> {
31+
let fd = try!(path.with_nix_path(|cstr| {
32+
unsafe { libc::openat(dirfd, cstr.as_ptr(), oflag.bits(), mode.bits()) }
33+
}));
34+
35+
Errno::result(fd)
36+
}
37+
2938
pub enum FcntlArg<'a> {
3039
F_DUPFD(RawFd),
3140
F_DUPFD_CLOEXEC(RawFd),

test/test_fcntl.rs

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,35 @@ mod linux_android {
55

66
use libc::loff_t;
77

8-
use nix::fcntl::{SpliceFFlags, splice, tee, vmsplice};
8+
use nix::fcntl::{SpliceFFlags, splice, tee, vmsplice, openat, open, O_PATH, O_RDONLY};
9+
use nix::sys::stat::Mode;
910
use nix::sys::uio::IoVec;
1011
use nix::unistd::{close, pipe, read, write};
1112

12-
use tempfile::tempfile;
13+
use tempfile::{tempfile, NamedTempFile};
14+
15+
#[test]
16+
fn test_openat() {
17+
const CONTENTS: &'static [u8] = b"abcd";
18+
let mut tmp = NamedTempFile::new().unwrap();
19+
tmp.write(CONTENTS).unwrap();
20+
21+
let dirfd = open(tmp.path().parent().unwrap(),
22+
O_PATH,
23+
Mode::empty()).unwrap();
24+
let fd = openat(dirfd,
25+
tmp.path().file_name().unwrap(),
26+
O_RDONLY,
27+
Mode::empty()).unwrap();
28+
29+
let mut buf = [0u8; 1024];
30+
assert_eq!(4, read(fd, &mut buf).unwrap());
31+
assert_eq!(CONTENTS, &buf[0..4]);
32+
33+
close(fd).unwrap();
34+
close(dirfd).unwrap();
35+
}
36+
1337

1438
#[test]
1539
fn test_splice() {

0 commit comments

Comments
 (0)