From e77f551de9f889794fc570ba11293c5cb72f6d24 Mon Sep 17 00:00:00 2001 From: Askar Safin Date: Sun, 25 Feb 2024 20:14:35 +0300 Subject: [PATCH 1/2] Change prototypes for exec* function to match headers. Yes, this makes the prototypes harder to use. And less intuitive. But this makes them match headers, and thus now we can properly test them. This fixes https://github.com/rust-lang/libc/issues/1272 Also we fix return types for some Windows exec* functions --- src/fuchsia/mod.rs | 18 +++++++----------- src/unix/aix/mod.rs | 6 +----- src/unix/bsd/freebsdlike/mod.rs | 6 +----- src/unix/bsd/netbsdlike/mod.rs | 4 ++-- src/unix/haiku/mod.rs | 4 ++-- src/unix/hurd/mod.rs | 10 +++------- src/unix/linux_like/mod.rs | 10 +++------- src/unix/mod.rs | 8 ++++---- src/unix/newlib/mod.rs | 6 +----- src/unix/nto/mod.rs | 4 ++-- src/unix/solarish/solaris.rs | 6 +----- src/windows/mod.rs | 6 +++--- 12 files changed, 30 insertions(+), 58 deletions(-) diff --git a/src/fuchsia/mod.rs b/src/fuchsia/mod.rs index 35991e463669b..b9cdafbe8cb18 100644 --- a/src/fuchsia/mod.rs +++ b/src/fuchsia/mod.rs @@ -3675,13 +3675,13 @@ extern "C" { pub fn execl(path: *const c_char, arg0: *const c_char, ...) -> ::c_int; pub fn execle(path: *const ::c_char, arg0: *const ::c_char, ...) -> ::c_int; pub fn execlp(file: *const ::c_char, arg0: *const ::c_char, ...) -> ::c_int; - pub fn execv(prog: *const c_char, argv: *const *const c_char) -> ::c_int; + pub fn execv(prog: *const c_char, argv: *const *mut c_char) -> ::c_int; pub fn execve( prog: *const c_char, - argv: *const *const c_char, - envp: *const *const c_char, + argv: *const *mut c_char, + envp: *const *mut c_char, ) -> ::c_int; - pub fn execvp(c: *const c_char, argv: *const *const c_char) -> ::c_int; + pub fn execvp(c: *const c_char, argv: *const *mut c_char) -> ::c_int; pub fn fork() -> pid_t; pub fn fpathconf(filedes: ::c_int, name: ::c_int) -> c_long; pub fn getcwd(buf: *mut c_char, size: ::size_t) -> *mut c_char; @@ -4023,14 +4023,10 @@ extern "C" { ) -> ::c_int; pub fn execvpe( file: *const ::c_char, - argv: *const *const ::c_char, - envp: *const *const ::c_char, - ) -> ::c_int; - pub fn fexecve( - fd: ::c_int, - argv: *const *const ::c_char, - envp: *const *const ::c_char, + argv: *const *mut ::c_char, + envp: *const *mut ::c_char, ) -> ::c_int; + pub fn fexecve(fd: ::c_int, argv: *const *mut ::c_char, envp: *const *mut ::c_char) -> ::c_int; pub fn ioctl(fd: ::c_int, request: ::c_int, ...) -> ::c_int; diff --git a/src/unix/aix/mod.rs b/src/unix/aix/mod.rs index a1ab1d4dfb36a..b4b6ecac59bd5 100644 --- a/src/unix/aix/mod.rs +++ b/src/unix/aix/mod.rs @@ -2810,11 +2810,7 @@ extern "C" { ) -> ::c_int; pub fn fattach(fildes: ::c_int, path: *const ::c_char) -> ::c_int; pub fn fdatasync(fd: ::c_int) -> ::c_int; - pub fn fexecve( - fd: ::c_int, - argv: *const *const ::c_char, - envp: *const *const ::c_char, - ) -> ::c_int; + pub fn fexecve(fd: ::c_int, argv: *const *mut ::c_char, envp: *const *mut ::c_char) -> ::c_int; pub fn ffs(value: ::c_int) -> ::c_int; pub fn ffsl(value: ::c_long) -> ::c_int; pub fn ffsll(value: ::c_longlong) -> ::c_int; diff --git a/src/unix/bsd/freebsdlike/mod.rs b/src/unix/bsd/freebsdlike/mod.rs index 79de969c8be6b..5b8d77246978b 100644 --- a/src/unix/bsd/freebsdlike/mod.rs +++ b/src/unix/bsd/freebsdlike/mod.rs @@ -1500,11 +1500,7 @@ extern "C" { pub fn duplocale(base: ::locale_t) -> ::locale_t; pub fn endutxent(); pub fn fchflags(fd: ::c_int, flags: ::c_ulong) -> ::c_int; - pub fn fexecve( - fd: ::c_int, - argv: *const *const ::c_char, - envp: *const *const ::c_char, - ) -> ::c_int; + pub fn fexecve(fd: ::c_int, argv: *const *mut ::c_char, envp: *const *mut ::c_char) -> ::c_int; pub fn futimens(fd: ::c_int, times: *const ::timespec) -> ::c_int; pub fn getdomainname(name: *mut ::c_char, len: ::c_int) -> ::c_int; pub fn getgrent_r( diff --git a/src/unix/bsd/netbsdlike/mod.rs b/src/unix/bsd/netbsdlike/mod.rs index b9780f6f77b6a..f0e1e9ea2d7a3 100644 --- a/src/unix/bsd/netbsdlike/mod.rs +++ b/src/unix/bsd/netbsdlike/mod.rs @@ -750,8 +750,8 @@ extern "C" { pub fn shmctl(shmid: ::c_int, cmd: ::c_int, buf: *mut ::shmid_ds) -> ::c_int; pub fn execvpe( file: *const ::c_char, - argv: *const *const ::c_char, - envp: *const *const ::c_char, + argv: *const *mut ::c_char, + envp: *const *mut ::c_char, ) -> ::c_int; pub fn waitid( idtype: idtype_t, diff --git a/src/unix/haiku/mod.rs b/src/unix/haiku/mod.rs index 50ed271d65e15..a07a5cdc2dd0d 100644 --- a/src/unix/haiku/mod.rs +++ b/src/unix/haiku/mod.rs @@ -1765,8 +1765,8 @@ extern "C" { pub fn recvmsg(fd: ::c_int, msg: *mut ::msghdr, flags: ::c_int) -> ::ssize_t; pub fn execvpe( file: *const ::c_char, - argv: *const *const ::c_char, - environment: *const *const ::c_char, + argv: *const *mut ::c_char, + environment: *const *mut ::c_char, ) -> ::c_int; pub fn getgrgid_r( gid: ::gid_t, diff --git a/src/unix/hurd/mod.rs b/src/unix/hurd/mod.rs index d780e22f78e7b..5cc6992d32cae 100644 --- a/src/unix/hurd/mod.rs +++ b/src/unix/hurd/mod.rs @@ -4202,14 +4202,10 @@ extern "C" { ) -> ::c_int; pub fn execvpe( file: *const ::c_char, - argv: *const *const ::c_char, - envp: *const *const ::c_char, - ) -> ::c_int; - pub fn fexecve( - fd: ::c_int, - argv: *const *const ::c_char, - envp: *const *const ::c_char, + argv: *const *mut ::c_char, + envp: *const *mut ::c_char, ) -> ::c_int; + pub fn fexecve(fd: ::c_int, argv: *const *mut ::c_char, envp: *const *mut ::c_char) -> ::c_int; pub fn daemon(nochdir: ::c_int, noclose: ::c_int) -> ::c_int; diff --git a/src/unix/linux_like/mod.rs b/src/unix/linux_like/mod.rs index 1b435e2353985..d80b00f423eca 100644 --- a/src/unix/linux_like/mod.rs +++ b/src/unix/linux_like/mod.rs @@ -1755,14 +1755,10 @@ extern "C" { pub fn login_tty(fd: ::c_int) -> ::c_int; pub fn execvpe( file: *const ::c_char, - argv: *const *const ::c_char, - envp: *const *const ::c_char, - ) -> ::c_int; - pub fn fexecve( - fd: ::c_int, - argv: *const *const ::c_char, - envp: *const *const ::c_char, + argv: *const *mut ::c_char, + envp: *const *mut ::c_char, ) -> ::c_int; + pub fn fexecve(fd: ::c_int, argv: *const *mut ::c_char, envp: *const *mut ::c_char) -> ::c_int; pub fn getifaddrs(ifap: *mut *mut ::ifaddrs) -> ::c_int; pub fn freeifaddrs(ifa: *mut ::ifaddrs); pub fn bind(socket: ::c_int, address: *const ::sockaddr, address_len: ::socklen_t) -> ::c_int; diff --git a/src/unix/mod.rs b/src/unix/mod.rs index 5da25ca24c173..0b270c0a39bca 100644 --- a/src/unix/mod.rs +++ b/src/unix/mod.rs @@ -840,13 +840,13 @@ extern "C" { pub fn execl(path: *const c_char, arg0: *const c_char, ...) -> ::c_int; pub fn execle(path: *const ::c_char, arg0: *const ::c_char, ...) -> ::c_int; pub fn execlp(file: *const ::c_char, arg0: *const ::c_char, ...) -> ::c_int; - pub fn execv(prog: *const c_char, argv: *const *const c_char) -> ::c_int; + pub fn execv(prog: *const c_char, argv: *const *mut c_char) -> ::c_int; pub fn execve( prog: *const c_char, - argv: *const *const c_char, - envp: *const *const c_char, + argv: *const *mut c_char, + envp: *const *mut c_char, ) -> ::c_int; - pub fn execvp(c: *const c_char, argv: *const *const c_char) -> ::c_int; + pub fn execvp(c: *const c_char, argv: *const *mut c_char) -> ::c_int; pub fn fork() -> pid_t; pub fn fpathconf(filedes: ::c_int, name: ::c_int) -> c_long; pub fn getcwd(buf: *mut c_char, size: ::size_t) -> *mut c_char; diff --git a/src/unix/newlib/mod.rs b/src/unix/newlib/mod.rs index ed787e01868d4..3a9a73c2d5fc8 100644 --- a/src/unix/newlib/mod.rs +++ b/src/unix/newlib/mod.rs @@ -689,11 +689,7 @@ extern "C" { flags: ::c_int, ) -> ::c_int; pub fn memalign(align: ::size_t, size: ::size_t) -> *mut ::c_void; - pub fn fexecve( - fd: ::c_int, - argv: *const *const ::c_char, - envp: *const *const ::c_char, - ) -> ::c_int; + pub fn fexecve(fd: ::c_int, argv: *const *mut ::c_char, envp: *const *mut ::c_char) -> ::c_int; pub fn gettimeofday(tp: *mut ::timeval, tz: *mut ::c_void) -> ::c_int; pub fn getgrgid_r( gid: ::gid_t, diff --git a/src/unix/nto/mod.rs b/src/unix/nto/mod.rs index bfb5c2ee5716d..7e5d228ccf7f7 100644 --- a/src/unix/nto/mod.rs +++ b/src/unix/nto/mod.rs @@ -2935,8 +2935,8 @@ extern "C" { ) -> ::pid_t; pub fn execvpe( file: *const ::c_char, - argv: *const *const ::c_char, - envp: *const *const ::c_char, + argv: *const *mut ::c_char, + envp: *const *mut ::c_char, ) -> ::c_int; pub fn getifaddrs(ifap: *mut *mut ::ifaddrs) -> ::c_int; diff --git a/src/unix/solarish/solaris.rs b/src/unix/solarish/solaris.rs index 80bad281ea705..5ab67884f6a68 100644 --- a/src/unix/solarish/solaris.rs +++ b/src/unix/solarish/solaris.rs @@ -66,11 +66,7 @@ pub const F_DUP2FD_CLOEXEC: ::c_int = 48; pub const F_DUP2FD_CLOFORK: ::c_int = 50; extern "C" { - pub fn fexecve( - fd: ::c_int, - argv: *const *const ::c_char, - envp: *const *const ::c_char, - ) -> ::c_int; + pub fn fexecve(fd: ::c_int, argv: *const *mut ::c_char, envp: *const *mut ::c_char) -> ::c_int; pub fn mincore(addr: *const ::c_void, len: ::size_t, vec: *mut ::c_char) -> ::c_int; diff --git a/src/windows/mod.rs b/src/windows/mod.rs index 3aa810ee68563..a12123ef73db0 100644 --- a/src/windows/mod.rs +++ b/src/windows/mod.rs @@ -460,15 +460,15 @@ extern "C" { prog: *const c_char, argv: *const *const c_char, envp: *const *const c_char, - ) -> ::c_int; + ) -> ::intptr_t; #[link_name = "_execvp"] - pub fn execvp(c: *const c_char, argv: *const *const c_char) -> ::c_int; + pub fn execvp(c: *const c_char, argv: *const *const c_char) -> ::intptr_t; #[link_name = "_execvpe"] pub fn execvpe( c: *const c_char, argv: *const *const c_char, envp: *const *const c_char, - ) -> ::c_int; + ) -> ::intptr_t; #[link_name = "_wexecv"] pub fn wexecv(prog: *const wchar_t, argv: *const *const wchar_t) -> ::intptr_t; #[link_name = "_wexecve"] From 6c15e7fae9264ca7330be5ee5c467e973c09559f Mon Sep 17 00:00:00 2001 From: Askar Safin Date: Sun, 25 Feb 2024 21:34:38 +0300 Subject: [PATCH 2/2] Now we can remove workarounds for exec* from tests. But for unknown reasons we still have to skip "fexecve" for Android --- libc-test/build.rs | 37 ++++--------------------------------- 1 file changed, 4 insertions(+), 33 deletions(-) diff --git a/libc-test/build.rs b/libc-test/build.rs index 201b3d89e309d..1a72e195f23c4 100644 --- a/libc-test/build.rs +++ b/libc-test/build.rs @@ -329,9 +329,6 @@ fn test_apple(target: &str) { cfg.skip_fn(move |name| { // skip those that are manually verified match name { - // FIXME: https://github.com/rust-lang/libc/issues/1272 - "execv" | "execve" | "execvp" => true, - // close calls the close_nocancel system call "close" => true, @@ -525,9 +522,6 @@ fn test_openbsd(target: &str) { cfg.skip_fn(move |name| { match name { - // FIXME: https://github.com/rust-lang/libc/issues/1272 - "execv" | "execve" | "execvp" | "execvpe" => true, - // futex() has volatile arguments, but that doesn't exist in Rust. "futex" => true, @@ -694,14 +688,7 @@ fn test_windows(target: &str) { } }); - cfg.skip_fn(move |name| { - match name { - // FIXME: https://github.com/rust-lang/libc/issues/1272 - "execv" | "execve" | "execvp" | "execvpe" => true, - - _ => false, - } - }); + cfg.skip_fn(|_| false); cfg.generate("../src/lib.rs", "main.rs"); } @@ -974,7 +961,7 @@ fn test_solarish(target: &str) { "cfmakeraw" | "cfsetspeed" => true, // const-ness issues - "execv" | "execve" | "execvp" | "settimeofday" | "sethostname" => true, + "settimeofday" | "sethostname" => true, // Solaris-different "getpwent_r" | "getgrent_r" | "updwtmpx" if is_illumos => true, @@ -1182,8 +1169,6 @@ fn test_netbsd(target: &str) { cfg.skip_fn(move |name| { match name { - // FIXME: https://github.com/rust-lang/libc/issues/1272 - "execv" | "execve" | "execvp" => true, // FIXME: netbsd 10 minimum "getentropy" | "getrandom" => true, @@ -1411,9 +1396,6 @@ fn test_dragonflybsd(target: &str) { cfg.skip_fn(move |name| { // skip those that are manually verified match name { - // FIXME: https://github.com/rust-lang/libc/issues/1272 - "execv" | "execve" | "execvp" | "fexecve" => true, - "getrlimit" | "getrlimit64" | // non-int in 1st arg "setrlimit" | "setrlimit64" | // non-int in 1st arg "prlimit" | "prlimit64" // non-int in 2nd arg @@ -1908,8 +1890,8 @@ fn test_android(target: &str) { cfg.skip_fn(move |name| { // skip those that are manually verified match name { - // FIXME: https://github.com/rust-lang/libc/issues/1272 - "execv" | "execve" | "execvp" | "execvpe" | "fexecve" => true, + // FIXME: for unknown reasons linker unable to find "fexecve" + "fexecve" => true, // There are two versions of the sterror_r function, see // @@ -2487,9 +2469,6 @@ fn test_freebsd(target: &str) { cfg.skip_fn(move |name| { // skip those that are manually verified match name { - // FIXME: https://github.com/rust-lang/libc/issues/1272 - "execv" | "execve" | "execvp" | "execvpe" | "fexecve" => true, - // The `uname` function in the `utsname.h` FreeBSD header is a C // inline function (has no symbol) that calls the `__xuname` symbol. // Therefore the function pointer comparison does not make sense for it. @@ -3089,9 +3068,6 @@ fn test_neutrino(target: &str) { cfg.skip_fn(move |name| { // skip those that are manually verified match name { - // FIXME: https://github.com/rust-lang/libc/issues/1272 - "execv" | "execve" | "execvp" | "execvpe" => true, - // wrong signature "signal" => true, @@ -4168,9 +4144,6 @@ fn test_linux(target: &str) { cfg.skip_fn(move |name| { // skip those that are manually verified match name { - // FIXME: https://github.com/rust-lang/libc/issues/1272 - "execv" | "execve" | "execvp" | "execvpe" | "fexecve" => true, - // There are two versions of the sterror_r function, see // // https://linux.die.net/man/3/strerror_r @@ -4761,8 +4734,6 @@ fn test_haiku(target: &str) { cfg.skip_fn(move |name| { // skip those that are manually verified match name { - // FIXME: https://github.com/rust-lang/libc/issues/1272 - "execv" | "execve" | "execvp" | "execvpe" => true, // FIXME: does not exist on haiku "open_wmemstream" => true, "mlockall" | "munlockall" => true,