Skip to content

Commit 3bfc899

Browse files
Fix linker error
This makes `fs::hard_link` use weak! for some platforms, thereby preventing a linker error.
1 parent 19579c6 commit 3bfc899

File tree

1 file changed

+26
-11
lines changed
  • library/std/src/sys/unix

1 file changed

+26
-11
lines changed

library/std/src/sys/unix/fs.rs

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ use crate::sys_common::{AsInner, FromInner};
1414

1515
use libc::{c_int, mode_t};
1616

17+
#[cfg(any(target_os = "macos", all(target_os = "linux", target_env = "gnu")))]
18+
use libc::c_char;
1719
#[cfg(any(target_os = "linux", target_os = "emscripten", target_os = "android"))]
1820
use libc::dirfd;
1921
#[cfg(any(target_os = "linux", target_os = "emscripten"))]
@@ -92,7 +94,7 @@ cfg_has_statx! {{
9294
// Default `stat64` contains no creation time.
9395
unsafe fn try_statx(
9496
fd: c_int,
95-
path: *const libc::c_char,
97+
path: *const c_char,
9698
flags: i32,
9799
mask: u32,
98100
) -> Option<io::Result<FileAttr>> {
@@ -107,7 +109,7 @@ cfg_has_statx! {{
107109
syscall! {
108110
fn statx(
109111
fd: c_int,
110-
pathname: *const libc::c_char,
112+
pathname: *const c_char,
111113
flags: c_int,
112114
mask: libc::c_uint,
113115
statxbuf: *mut libc::statx
@@ -752,7 +754,7 @@ impl File {
752754
cfg_has_statx! {
753755
if let Some(ret) = unsafe { try_statx(
754756
fd,
755-
b"\0" as *const _ as *const libc::c_char,
757+
b"\0" as *const _ as *const c_char,
756758
libc::AT_EMPTY_PATH | libc::AT_STATX_SYNC_AS_STAT,
757759
libc::STATX_ALL,
758760
) } {
@@ -1083,15 +1085,28 @@ pub fn link(original: &Path, link: &Path) -> io::Result<()> {
10831085
let link = cstr(link)?;
10841086
cfg_if::cfg_if! {
10851087
if #[cfg(any(target_os = "vxworks", target_os = "redox", target_os = "android"))] {
1086-
// VxWorks, Redox, and old versions of Android lack `linkat`, so use
1087-
// `link` instead. POSIX leaves it implementation-defined whether
1088-
// `link` follows symlinks, so rely on the `symlink_hard_link` test
1089-
// in library/std/src/fs/tests.rs to check the behavior.
1088+
// VxWorks and Redox lack `linkat`, so use `link` instead. POSIX leaves
1089+
// it implementation-defined whether `link` follows symlinks, so rely on the
1090+
// `symlink_hard_link` test in library/std/src/fs/tests.rs to check the behavior.
1091+
// Android has `linkat` on newer versions, but we happen to know `link`
1092+
// always has the correct behavior, so it's here as well.
10901093
cvt(unsafe { libc::link(original.as_ptr(), link.as_ptr()) })?;
1094+
} else if #[cfg(target_os = "macos")] {
1095+
// On MacOS, older versions (<=10.9) lack support for linkat while newer
1096+
// versions have it. We want to use linkat if it is available, so we use weak!
1097+
// to check. `linkat` is preferable to `link` ecause it gives us a flag to
1098+
// specify how symlinks should be handled. We pass 0 as the flags argument,
1099+
// meaning it shouldn't follow symlinks.
1100+
weak!(fn linkat(c_int, *const c_char, c_int, *const c_char, c_int) -> c_int);
1101+
1102+
if let Some(f) = linkat.get() {
1103+
cvt(unsafe { f(libc::AT_FDCWD, original.as_ptr(), libc::AT_FDCWD, link.as_ptr(), 0) })?;
1104+
} else {
1105+
cvt(unsafe { libc::link(original.as_ptr(), link.as_ptr()) })?;
1106+
};
10911107
} else {
1092-
// Use `linkat` with `AT_FDCWD` instead of `link` as `linkat` gives
1093-
// us a flag to specify how symlinks should be handled. Pass 0 as
1094-
// the flags argument, meaning don't follow symlinks.
1108+
// Where we can, use `linkat` instead of `link`; see the comment above
1109+
// this one for details on why.
10951110
cvt(unsafe { libc::linkat(libc::AT_FDCWD, original.as_ptr(), libc::AT_FDCWD, link.as_ptr(), 0) })?;
10961111
}
10971112
}
@@ -1274,7 +1289,7 @@ pub fn copy(from: &Path, to: &Path) -> io::Result<u64> {
12741289
fn fclonefileat(
12751290
srcfd: libc::c_int,
12761291
dst_dirfd: libc::c_int,
1277-
dst: *const libc::c_char,
1292+
dst: *const c_char,
12781293
flags: libc::c_int
12791294
) -> libc::c_int
12801295
}

0 commit comments

Comments
 (0)