@@ -14,6 +14,8 @@ use crate::sys_common::{AsInner, FromInner};
14
14
15
15
use libc:: { c_int, mode_t} ;
16
16
17
+ #[ cfg( any( target_os = "macos" , all( target_os = "linux" , target_env = "gnu" ) ) ) ]
18
+ use libc:: c_char;
17
19
#[ cfg( any( target_os = "linux" , target_os = "emscripten" , target_os = "android" ) ) ]
18
20
use libc:: dirfd;
19
21
#[ cfg( any( target_os = "linux" , target_os = "emscripten" ) ) ]
@@ -92,7 +94,7 @@ cfg_has_statx! {{
92
94
// Default `stat64` contains no creation time.
93
95
unsafe fn try_statx(
94
96
fd: c_int,
95
- path: * const libc :: c_char,
97
+ path: * const c_char,
96
98
flags: i32 ,
97
99
mask: u32 ,
98
100
) -> Option <io:: Result <FileAttr >> {
@@ -107,7 +109,7 @@ cfg_has_statx! {{
107
109
syscall! {
108
110
fn statx(
109
111
fd: c_int,
110
- pathname: * const libc :: c_char,
112
+ pathname: * const c_char,
111
113
flags: c_int,
112
114
mask: libc:: c_uint,
113
115
statxbuf: * mut libc:: statx
@@ -752,7 +754,7 @@ impl File {
752
754
cfg_has_statx ! {
753
755
if let Some ( ret) = unsafe { try_statx(
754
756
fd,
755
- b"\0 " as * const _ as * const libc :: c_char,
757
+ b"\0 " as * const _ as * const c_char,
756
758
libc:: AT_EMPTY_PATH | libc:: AT_STATX_SYNC_AS_STAT ,
757
759
libc:: STATX_ALL ,
758
760
) } {
@@ -1083,15 +1085,28 @@ pub fn link(original: &Path, link: &Path) -> io::Result<()> {
1083
1085
let link = cstr ( link) ?;
1084
1086
cfg_if:: cfg_if! {
1085
1087
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.
1090
1093
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
+ } ;
1091
1107
} 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.
1095
1110
cvt( unsafe { libc:: linkat( libc:: AT_FDCWD , original. as_ptr( ) , libc:: AT_FDCWD , link. as_ptr( ) , 0 ) } ) ?;
1096
1111
}
1097
1112
}
@@ -1274,7 +1289,7 @@ pub fn copy(from: &Path, to: &Path) -> io::Result<u64> {
1274
1289
fn fclonefileat(
1275
1290
srcfd: libc:: c_int,
1276
1291
dst_dirfd: libc:: c_int,
1277
- dst: * const libc :: c_char,
1292
+ dst: * const c_char,
1278
1293
flags: libc:: c_int
1279
1294
) -> libc:: c_int
1280
1295
}
0 commit comments