From f2df347e56bac25adb680084e85f21d8d929dea7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Thalheim?= Date: Wed, 8 Mar 2017 00:11:36 +0100 Subject: [PATCH] add support for `openat` --- CHANGELOG.md | 1 + src/fcntl.rs | 9 +++++++++ test/test_fcntl.rs | 28 ++++++++++++++++++++++++++-- 3 files changed, 36 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9bcef57a70..982b3b7fe9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ This project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased] +- Added `openat` in `::nix::fcntl` ### Changed - Marked `sys::mman::{ mmap, munmap, madvise, munlock, msync }` as unsafe. diff --git a/src/fcntl.rs b/src/fcntl.rs index e224d3b107..c9a3486fa4 100644 --- a/src/fcntl.rs +++ b/src/fcntl.rs @@ -26,6 +26,15 @@ pub fn open(path: &P, oflag: OFlag, mode: Mode) -> Result(dirfd: RawFd, path: &P, oflag: OFlag, mode: Mode) -> Result { + let fd = try!(path.with_nix_path(|cstr| { + unsafe { libc::openat(dirfd, cstr.as_ptr(), oflag.bits(), mode.bits()) } + })); + + Errno::result(fd) +} + pub enum FcntlArg<'a> { F_DUPFD(RawFd), F_DUPFD_CLOEXEC(RawFd), diff --git a/test/test_fcntl.rs b/test/test_fcntl.rs index ca2e89a338..a90d4b0048 100644 --- a/test/test_fcntl.rs +++ b/test/test_fcntl.rs @@ -5,11 +5,35 @@ mod linux_android { use libc::loff_t; - use nix::fcntl::{SpliceFFlags, splice, tee, vmsplice}; + use nix::fcntl::{SpliceFFlags, splice, tee, vmsplice, openat, open, O_PATH, O_RDONLY}; + use nix::sys::stat::Mode; use nix::sys::uio::IoVec; use nix::unistd::{close, pipe, read, write}; - use tempfile::tempfile; + use tempfile::{tempfile, NamedTempFile}; + + #[test] + fn test_openat() { + const CONTENTS: &'static [u8] = b"abcd"; + let mut tmp = NamedTempFile::new().unwrap(); + tmp.write(CONTENTS).unwrap(); + + let dirfd = open(tmp.path().parent().unwrap(), + O_PATH, + Mode::empty()).unwrap(); + let fd = openat(dirfd, + tmp.path().file_name().unwrap(), + O_RDONLY, + Mode::empty()).unwrap(); + + let mut buf = [0u8; 1024]; + assert_eq!(4, read(fd, &mut buf).unwrap()); + assert_eq!(CONTENTS, &buf[0..4]); + + close(fd).unwrap(); + close(dirfd).unwrap(); + } + #[test] fn test_splice() {