Skip to content

Commit

Permalink
Auto merge of #497 - lucab:to-upstream/fchdir, r=posborne
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
homu committed Jan 19, 2017
2 parents 3b07168 + 0a654e7 commit f661106
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 0 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ This project adheres to [Semantic Versioning](http://semver.org/).
([#457](https://github.com/nix-rust/nix/pull/457))
- Added `getpgrp` in `::nix::unistd`
([#491](https://github.com/nix-rust/nix/pull/491))
- Added `fchdir` in `::nix::unistd`
([#497](https://github.com/nix-rust/nix/pull/497))

### Changed
- `epoll_ctl` now could accept None as argument `event`
Expand Down
13 changes: 13 additions & 0 deletions src/unistd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,19 @@ pub fn chdir<P: ?Sized + NixPath>(path: &P) -> Result<()> {
Errno::result(res).map(drop)
}

/// Change the current working directory of the process to the one
/// given as an open file descriptor (see
/// [fchdir(2)](http://man7.org/linux/man-pages/man2/fchdir.2.html)).
///
/// This function may fail in a number of different scenarios. See the man
/// pages for additional details on possible failure cases.
#[inline]
pub fn fchdir(dirfd: RawFd) -> Result<()> {
let res = unsafe { libc::fchdir(dirfd) };

Errno::result(res).map(drop)
}

/// Creates new directory `path` with access rights `mode`.
///
/// # Errors
Expand Down
19 changes: 19 additions & 0 deletions test/test_unistd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use nix::sys::wait::*;
use nix::sys::stat;
use std::iter;
use std::ffi::CString;
use std::fs::File;
use std::io::{Write, Read};
use std::os::unix::prelude::*;
use std::env::current_dir;
Expand Down Expand Up @@ -141,6 +142,24 @@ macro_rules! execve_test_factory(
)
);

#[test]
fn test_fchdir() {
let tmpdir = TempDir::new("test_fchdir").unwrap();
let tmpdir_path = tmpdir.path().canonicalize().unwrap();
let tmpdir_fd = File::open(&tmpdir_path).unwrap().into_raw_fd();
let olddir_path = getcwd().unwrap();
let olddir_fd = File::open(&olddir_path).unwrap().into_raw_fd();

assert!(fchdir(tmpdir_fd).is_ok());
assert_eq!(getcwd().unwrap(), tmpdir_path);

assert!(fchdir(olddir_fd).is_ok());
assert_eq!(getcwd().unwrap(), olddir_path);

assert!(close(olddir_fd).is_ok());
assert!(close(tmpdir_fd).is_ok());
}

#[test]
fn test_getcwd() {
let tmp_dir = TempDir::new("test_getcwd").unwrap();
Expand Down

0 comments on commit f661106

Please sign in to comment.