From ce00b3e2e0c5c0c88fe59fb45a1c25a8ff9e1836 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 19 Oct 2020 07:47:32 -0700 Subject: [PATCH] Use `link` on platforms which lack `linkat`. --- library/std/src/sys/unix/fs.rs | 18 ++++++++++++++---- 1 file 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(()) } -- GitLab