From d1e20b191d130c9e29d4f93fd1dfa58e19cd9bdf Mon Sep 17 00:00:00 2001 From: Steve Lau Date: Tue, 25 Oct 2022 08:01:48 +0800 Subject: [PATCH] expose both basename(3) on Linux with glibc --- libc-test/build.rs | 16 ++++++++++++++++ libc-test/semver/linux-gnu.txt | 3 ++- src/unix/linux_like/linux/gnu/mod.rs | 7 ++++++- 3 files changed, 24 insertions(+), 2 deletions(-) diff --git a/libc-test/build.rs b/libc-test/build.rs index 08c07e6776131..85d6d17f84641 100644 --- a/libc-test/build.rs +++ b/libc-test/build.rs @@ -3417,6 +3417,22 @@ fn test_linux(target: &str) { // it can't be changed from struct. "pthread_sigqueue" => true, + // There are two versions of basename(3) on Linux with glibc, see + // + // https://man7.org/linux/man-pages/man3/basename.3.html + // + // If libgen.h is included, then the POSIX version will be available; + // If _GNU_SOURCE is defined and string.h is included, then the GNU one + // will be used. + // + // libc exposes both of them, providing a prefix to differentiate between + // them. + // + // Because the name with prefix is not a valid symbol in C, we have to + // skip the tests. + "posix_basename" if gnu => true, + "gnu_basename" if gnu => true, + _ => false, } }); diff --git a/libc-test/semver/linux-gnu.txt b/libc-test/semver/linux-gnu.txt index deec042d59780..bf663a193014b 100644 --- a/libc-test/semver/linux-gnu.txt +++ b/libc-test/semver/linux-gnu.txt @@ -659,4 +659,5 @@ ctime_r strftime strptime dirname -basename \ No newline at end of file +posix_basename +gnu_basename \ No newline at end of file diff --git a/src/unix/linux_like/linux/gnu/mod.rs b/src/unix/linux_like/linux/gnu/mod.rs index b6cc36a588f8b..98a58a2acb866 100644 --- a/src/unix/linux_like/linux/gnu/mod.rs +++ b/src/unix/linux_like/linux/gnu/mod.rs @@ -1348,7 +1348,12 @@ extern "C" { pub fn strptime(s: *const ::c_char, format: *const ::c_char, tm: *mut ::tm) -> *mut ::c_char; pub fn dirname(path: *mut ::c_char) -> *mut ::c_char; - pub fn basename(path: *mut ::c_char) -> *mut ::c_char; + /// POSIX version of `basename(3)`, defined in `libgen.h`. + #[link_name = "__xpg_basename"] + pub fn posix_basename(path: *mut ::c_char) -> *mut ::c_char; + /// GNU version of `basename(3)`, defined in `string.h`. + #[link_name = "basename"] + pub fn gnu_basename(path: *const ::c_char) -> *mut ::c_char; } extern "C" {