Skip to content

Commit f661106

Browse files
committed
Auto merge of #497 - lucab:to-upstream/fchdir, r=posborne
unistd: add fchdir(2) This introduces a wrapper for fchdir(2), allowing a process to change directory based on an open file descriptor. The underlying function is available in libc crate since 0.2.20.
2 parents 3b07168 + 0a654e7 commit f661106

File tree

3 files changed

+34
-0
lines changed

3 files changed

+34
-0
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ This project adheres to [Semantic Versioning](http://semver.org/).
2828
([#457](https://github.com/nix-rust/nix/pull/457))
2929
- Added `getpgrp` in `::nix::unistd`
3030
([#491](https://github.com/nix-rust/nix/pull/491))
31+
- Added `fchdir` in `::nix::unistd`
32+
([#497](https://github.com/nix-rust/nix/pull/497))
3133

3234
### Changed
3335
- `epoll_ctl` now could accept None as argument `event`

src/unistd.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,19 @@ pub fn chdir<P: ?Sized + NixPath>(path: &P) -> Result<()> {
249249
Errno::result(res).map(drop)
250250
}
251251

252+
/// Change the current working directory of the process to the one
253+
/// given as an open file descriptor (see
254+
/// [fchdir(2)](http://man7.org/linux/man-pages/man2/fchdir.2.html)).
255+
///
256+
/// This function may fail in a number of different scenarios. See the man
257+
/// pages for additional details on possible failure cases.
258+
#[inline]
259+
pub fn fchdir(dirfd: RawFd) -> Result<()> {
260+
let res = unsafe { libc::fchdir(dirfd) };
261+
262+
Errno::result(res).map(drop)
263+
}
264+
252265
/// Creates new directory `path` with access rights `mode`.
253266
///
254267
/// # Errors

test/test_unistd.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use nix::sys::wait::*;
66
use nix::sys::stat;
77
use std::iter;
88
use std::ffi::CString;
9+
use std::fs::File;
910
use std::io::{Write, Read};
1011
use std::os::unix::prelude::*;
1112
use std::env::current_dir;
@@ -141,6 +142,24 @@ macro_rules! execve_test_factory(
141142
)
142143
);
143144

145+
#[test]
146+
fn test_fchdir() {
147+
let tmpdir = TempDir::new("test_fchdir").unwrap();
148+
let tmpdir_path = tmpdir.path().canonicalize().unwrap();
149+
let tmpdir_fd = File::open(&tmpdir_path).unwrap().into_raw_fd();
150+
let olddir_path = getcwd().unwrap();
151+
let olddir_fd = File::open(&olddir_path).unwrap().into_raw_fd();
152+
153+
assert!(fchdir(tmpdir_fd).is_ok());
154+
assert_eq!(getcwd().unwrap(), tmpdir_path);
155+
156+
assert!(fchdir(olddir_fd).is_ok());
157+
assert_eq!(getcwd().unwrap(), olddir_path);
158+
159+
assert!(close(olddir_fd).is_ok());
160+
assert!(close(tmpdir_fd).is_ok());
161+
}
162+
144163
#[test]
145164
fn test_getcwd() {
146165
let tmp_dir = TempDir::new("test_getcwd").unwrap();

0 commit comments

Comments
 (0)