about summary refs log tree commit diff
diff options
context:
space:
mode:
authorDan Gohman <dev@sunfishcode.online>2020-10-19 07:47:32 -0700
committerDan Gohman <dev@sunfishcode.online>2020-10-18 07:47:32 -0700
commitce00b3e2e0c5c0c88fe59fb45a1c25a8ff9e1836 (patch)
tree2e1097ff2603f8df7ecf1e01f5842a525f1bbbde
parent23a5c214150f462043ab411f87ef297309421d71 (diff)
downloadrust-ce00b3e2e0c5c0c88fe59fb45a1c25a8ff9e1836.tar.gz
rust-ce00b3e2e0c5c0c88fe59fb45a1c25a8ff9e1836.zip
Use `link` on platforms which lack `linkat`.
-rw-r--r--library/std/src/sys/unix/fs.rs18
1 files changed, 14 insertions, 4 deletions
diff --git a/library/std/src/sys/unix/fs.rs b/library/std/src/sys/unix/fs.rs
index 69f6b88a3bc..bf4c9419287 100644
--- a/library/std/src/sys/unix/fs.rs
+++ b/library/std/src/sys/unix/fs.rs
@@ -1067,10 +1067,20 @@ pub fn symlink(src: &Path, dst: &Path) -> io::Result<()> {
 pub fn link(src: &Path, dst: &Path) -> io::Result<()> {
     let src = cstr(src)?;
     let dst = cstr(dst)?;
-    // Use `linkat` with `AT_FDCWD` instead of `link` as `link` leaves it
-    // implementation-defined whether it follows symlinks. Pass 0 as the
-    // `linkat` flags argument so that we don't follow symlinks.
-    cvt(unsafe { libc::linkat(libc::AT_FDCWD, src.as_ptr(), libc::AT_FDCWD, dst.as_ptr(), 0) })?;
+    cfg_if::cfg_if! {
+        if #[cfg(any(target_os = "vxworks", target_os = "redox"))] {
+            // VxWorks and Redox lack `linkat`, so use `link` instead. POSIX
+            // leaves it implementation-defined whether `link` follows symlinks,
+            // so rely on the `symlink_hard_link` test in
+            // library/std/src/fs/tests.rs to check the behavior.
+            cvt(unsafe { libc::link(src.as_ptr(), dst.as_ptr()) })?;
+        } else {
+            // Use `linkat` with `AT_FDCWD` instead of `link` as `linkat` gives
+            // us a flag to specify how symlinks should be handled. Pass 0 as
+            // the flags argument, meaning don't follow symlinks.
+            cvt(unsafe { libc::linkat(libc::AT_FDCWD, src.as_ptr(), libc::AT_FDCWD, dst.as_ptr(), 0) })?;
+        }
+    }
     Ok(())
 }