summaryrefslogtreecommitdiff
path: root/src/unistd.rs
diff options
context:
space:
mode:
authorJohnnie Birch <45402135+jlb6740@users.noreply.github.com>2019-07-24 18:50:04 -0700
committerJohnnie Birch <45402135+jlb6740@users.noreply.github.com>2019-11-03 22:02:54 -0800
commit848825b455c41d42fb29df4954f1cdc604de96b3 (patch)
tree56cb8b102a7f27ac8413967828637f93f011c443 /src/unistd.rs
parent30b04c59a91d83157d5876b31c7ea6b3b2f44340 (diff)
downloadnix-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.rs52
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)