Skip to content

Commit 8e09e73

Browse files
committed
add support for symlink|symlinkat
1 parent fafc892 commit 8e09e73

File tree

3 files changed

+50
-8
lines changed

3 files changed

+50
-8
lines changed

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
1010
([#611](https://github.com/nix-rust/nix/pull/609)
1111
- Added `AioCb::from_boxed_slice`
1212
([#582](https://github.com/nix-rust/nix/pull/582)
13-
- Added `nix::unistd::{openat, fstatat, readlink, readlinkat, rename, renameat, mknodat, unlinkat, mkdirat, link, linkat}`
13+
- Added `nix::unistd::{openat, fstatat, readlink, readlinkat, rename, renameat, mknodat, unlinkat, mkdirat, link, linkat, symlink, symlinkat}`
1414
([#551](https://github.com/nix-rust/nix/pull/551))
1515
- Added `nix::pty::{grantpt, posix_openpt, ptsname/ptsname_r, unlockpt}`
1616
([#556](https://github.com/nix-rust/nix/pull/556)

src/unistd.rs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -641,6 +641,39 @@ pub fn linkat<P1: ?Sized + NixPath, P2: ?Sized + NixPath>(olddirfd: RawFd, oldpa
641641
Errno::result(res).map(drop)
642642
}
643643

644+
/// Make a new name for a file
645+
/// ([see symlink(2)](http://man7.org/linux/man-pages/man2/symlink.2.html)).
646+
pub fn symlink<P1: ?Sized + NixPath, P2: ?Sized + NixPath>(target: &P1,
647+
linkpath: &P2) -> Result<()> {
648+
let res = try!(try!(target.with_nix_path(|t|
649+
linkpath.with_nix_path(|l|
650+
unsafe {
651+
libc::symlink(t.as_ptr() as *const c_char, l.as_ptr() as *const c_char)
652+
}
653+
)
654+
)));
655+
656+
Errno::result(res).map(drop)
657+
}
658+
659+
/// Make a new name for a file
660+
/// ([see symlinkat(2)](http://man7.org/linux/man-pages/man2/symlinkat.2.html)).
661+
pub fn symlinkat<P1: ?Sized + NixPath, P2: ?Sized + NixPath>(target: &P1,
662+
newdirfd: RawFd,
663+
linkpath: &P2) -> Result<()> {
664+
let res = try!(try!(target.with_nix_path(|t|
665+
linkpath.with_nix_path(|l|
666+
unsafe {
667+
libc::symlinkat(t.as_ptr() as *const c_char,
668+
newdirfd,
669+
l.as_ptr() as *const c_char)
670+
}
671+
)
672+
)));
673+
674+
Errno::result(res).map(drop)
675+
}
676+
644677
pub fn pipe() -> Result<(RawFd, RawFd)> {
645678
unsafe {
646679
let mut fds: [c_int; 2] = mem::uninitialized();

test/test_fcntl.rs

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
use nix::fcntl::{openat, open, OFlag, O_RDONLY, readlink, readlinkat, rename, renameat};
22
use nix::sys::stat::Mode;
3-
use nix::unistd::{close, read};
3+
use nix::unistd::{close, read, symlink, symlinkat};
44
use tempdir::TempDir;
55
use tempfile::NamedTempFile;
66
use std::fs::File;
77
use std::io::prelude::*;
8-
use std::os::unix::fs;
98

109
#[test]
1110
fn test_openat() {
@@ -31,19 +30,29 @@ fn test_openat() {
3130

3231
#[test]
3332
fn test_readlink() {
34-
let tempdir = TempDir::new("nix-test_readdir")
33+
let tempdir = TempDir::new("nix-test_readdlink")
34+
.unwrap_or_else(|e| panic!("tempdir failed: {}", e));
35+
let src = tempdir.path().join("a");
36+
let dst = tempdir.path().join("b");
37+
symlink(src.as_path(), dst.as_path()).unwrap();
38+
39+
let mut buf = vec![0; src.to_str().unwrap().len() + 1];
40+
assert_eq!(readlink(&dst, &mut buf).unwrap().to_str().unwrap(),
41+
src.to_str().unwrap());
42+
}
43+
44+
#[test]
45+
fn test_readlinkat() {
46+
let tempdir = TempDir::new("nix-test_readlinkat")
3547
.unwrap_or_else(|e| panic!("tempdir failed: {}", e));
3648
let src = tempdir.path().join("a");
3749
let dst = tempdir.path().join("b");
38-
println!("a: {:?}, b: {:?}", &src, &dst);
39-
fs::symlink(&src.as_path(), &dst.as_path()).unwrap();
4050
let dirfd = open(tempdir.path(),
4151
OFlag::empty(),
4252
Mode::empty()).unwrap();
53+
symlinkat(src.as_path(), dirfd, dst.file_name().unwrap()).unwrap();
4354

4455
let mut buf = vec![0; src.to_str().unwrap().len() + 1];
45-
assert_eq!(readlink(&dst, &mut buf).unwrap().to_str().unwrap(),
46-
src.to_str().unwrap());
4756
assert_eq!(readlinkat(dirfd, "b", &mut buf).unwrap().to_str().unwrap(),
4857
src.to_str().unwrap());
4958
}

0 commit comments

Comments
 (0)