diff options
author | Johnnie Birch <45402135+jlb6740@users.noreply.github.com> | 2019-07-24 18:50:04 -0700 |
---|---|---|
committer | Johnnie Birch <45402135+jlb6740@users.noreply.github.com> | 2019-11-03 22:02:54 -0800 |
commit | 848825b455c41d42fb29df4954f1cdc604de96b3 (patch) | |
tree | 56cb8b102a7f27ac8413967828637f93f011c443 /src/unistd.rs | |
parent | 30b04c59a91d83157d5876b31c7ea6b3b2f44340 (diff) | |
download | nix-848825b455c41d42fb29df4954f1cdc604de96b3.zip |
Implment linkat
This adds the linkat function which is part of POSIX:
http://pubs.opengroup.org/onlinepubs/9699919799/functions/linkat.html
and widely implmented on Unix-Family platforms.
Add back trailing whitespace removed on previous force push
Diffstat (limited to 'src/unistd.rs')
-rw-r--r-- | src/unistd.rs | 52 |
1 files changed, 52 insertions, 0 deletions
diff --git a/src/unistd.rs b/src/unistd.rs index b38e463f..b7fe567b 100644 --- a/src/unistd.rs +++ b/src/unistd.rs @@ -1169,6 +1169,58 @@ pub fn isatty(fd: RawFd) -> Result<bool> { } } +/// Flags for `linkat` function. +#[derive(Clone, Copy, Debug)] +pub enum LinkatFlags { + SymlinkFollow, + NoSymlinkFollow, +} + +/// Link one file to another file +/// +/// Creates a new link (directory entry) at `newpath` for the existing file at `oldpath`. In the +/// case of a relative `oldpath`, the path is interpreted relative to the directory associated +/// with file descriptor `olddirfd` instead of the current working directory and similiarly for +/// `newpath` and file descriptor `newdirfd`. In case `flag` is LinkatFlags::SymlinkFollow and +/// `oldpath` names a symoblic link, a new link for the target of the symbolic link is created. +/// If either `olddirfd` or `newdirfd` is `None`, `AT_FDCWD` is used respectively where `oldpath` +/// and/or `newpath` is then interpreted relative to the current working directory of the calling +/// process. If either `oldpath` or `newpath` is absolute, then `dirfd` is ignored. +/// +/// # References +/// See also [linkat(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/linkat.html) +pub fn linkat<P: ?Sized + NixPath>( + olddirfd: Option<RawFd>, + oldpath: &P, + newdirfd: Option<RawFd>, + newpath: &P, + flag: LinkatFlags, +) -> Result<()> { + + let atflag = + match flag { + LinkatFlags::SymlinkFollow => AtFlags::AT_SYMLINK_FOLLOW, + LinkatFlags::NoSymlinkFollow => AtFlags::empty(), + }; + + let res = + oldpath.with_nix_path(|oldcstr| { + newpath.with_nix_path(|newcstr| { + unsafe { + libc::linkat( + at_rawfd(olddirfd), + oldcstr.as_ptr(), + at_rawfd(newdirfd), + newcstr.as_ptr(), + atflag.bits() as libc::c_int + ) + } + }) + })??; + Errno::result(res).map(drop) +} + + /// Remove a directory entry /// /// See also [unlink(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/unlink.html) |