Skip to content

Commit

Permalink
liblibc: Fix prototype of functions taking char *const argv[]
Browse files Browse the repository at this point in the history
The execv family of functions do not modify their arguments, so they do
not need mutable pointers. The C prototypes take a constant array of
mutable C-strings, but that's a legacy quirk from before C had const
(since C string literals have type `char *`). The Rust prototypes had
`*mut` in the wrong place, anyway: to match the C prototypes, it should
have been `*const *mut c_char`. But it is safe to pass constant strings
(like string literals) to these functions.

getopt is a special case, since GNU getopt modifies its arguments
despite the `const` claim in the prototype. It is apparently only
well-defined to call getopt on the actual argc and argv parameters
passed to main, anyway. Change it to take `*mut *mut c_char` for an
attempt at safety, but probably nobody should be using it from Rust,
since there's no great way to get at the parameters as passed to main.

Also fix the one caller of execvp in libstd, which now no longer needs
an unsafe cast.

Fixes #16290.
  • Loading branch information
geofft committed Jun 20, 2015
1 parent a951569 commit 058a0f0
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 17 deletions.
34 changes: 18 additions & 16 deletions src/liblibc/lib.rs
Expand Up @@ -5493,17 +5493,17 @@ pub mod funcs {
pub fn dup2(src: c_int, dst: c_int) -> c_int;
#[link_name = "_execv"]
pub fn execv(prog: *const c_char,
argv: *mut *const c_char) -> intptr_t;
argv: *const *const c_char) -> intptr_t;
#[link_name = "_execve"]
pub fn execve(prog: *const c_char, argv: *mut *const c_char,
envp: *mut *const c_char)
pub fn execve(prog: *const c_char, argv: *const *const c_char,
envp: *const *const c_char)
-> c_int;
#[link_name = "_execvp"]
pub fn execvp(c: *const c_char,
argv: *mut *const c_char) -> c_int;
argv: *const *const c_char) -> c_int;
#[link_name = "_execvpe"]
pub fn execvpe(c: *const c_char, argv: *mut *const c_char,
envp: *mut *const c_char) -> c_int;
pub fn execvpe(c: *const c_char, argv: *const *const c_char,
envp: *const *const c_char) -> c_int;
#[link_name = "_getcwd"]
pub fn getcwd(buf: *mut c_char, size: size_t) -> *mut c_char;
#[link_name = "_getpid"]
Expand Down Expand Up @@ -5687,12 +5687,12 @@ pub mod funcs {
pub fn dup(fd: c_int) -> c_int;
pub fn dup2(src: c_int, dst: c_int) -> c_int;
pub fn execv(prog: *const c_char,
argv: *mut *const c_char) -> c_int;
pub fn execve(prog: *const c_char, argv: *mut *const c_char,
envp: *mut *const c_char)
argv: *const *const c_char) -> c_int;
pub fn execve(prog: *const c_char, argv: *const *const c_char,
envp: *const *const c_char)
-> c_int;
pub fn execvp(c: *const c_char,
argv: *mut *const c_char) -> c_int;
argv: *const *const 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;
Expand All @@ -5702,7 +5702,9 @@ pub mod funcs {
pub fn getgroups(ngroups_max: c_int, groups: *mut gid_t)
-> c_int;
pub fn getlogin() -> *mut c_char;
pub fn getopt(argc: c_int, argv: *mut *const c_char,
// GNU getopt(3) modifies its arguments despite the
// char * const [] prototype; see the manpage.
pub fn getopt(argc: c_int, argv: *mut *mut c_char,
optstr: *const c_char) -> c_int;
pub fn getpgrp() -> pid_t;
pub fn getpid() -> pid_t;
Expand Down Expand Up @@ -5752,19 +5754,19 @@ pub mod funcs {
pub fn dup(fd: c_int) -> c_int;
pub fn dup2(src: c_int, dst: c_int) -> c_int;
pub fn execv(prog: *const c_char,
argv: *mut *const c_char) -> c_int;
pub fn execve(prog: *const c_char, argv: *mut *const c_char,
envp: *mut *const c_char)
argv: *const *const c_char) -> c_int;
pub fn execve(prog: *const c_char, argv: *const *const c_char,
envp: *const *const c_char)
-> c_int;
pub fn execvp(c: *const c_char,
argv: *mut *const c_char) -> c_int;
argv: *const *const c_char) -> c_int;
pub fn fork() -> pid_t;
pub fn getcwd(buf: *mut c_char, size: size_t) -> *mut c_char;
pub fn getegid() -> gid_t;
pub fn geteuid() -> uid_t;
pub fn getgid() -> gid_t;
pub fn getlogin() -> *mut c_char;
pub fn getopt(argc: c_int, argv: *mut *const c_char,
pub fn getopt(argc: c_int, argv: *const *const c_char,
optstr: *const c_char) -> c_int;
pub fn getuid() -> uid_t;
pub fn getsid(pid: pid_t) -> pid_t;
Expand Down
2 changes: 1 addition & 1 deletion src/libstd/sys/unix/process.rs
Expand Up @@ -313,7 +313,7 @@ impl Process {
if !envp.is_null() {
*sys::os::environ() = envp as *const _;
}
let _ = libc::execvp(*argv, argv as *mut _);
let _ = libc::execvp(*argv, argv);
fail(&mut output)
}

Expand Down

0 comments on commit 058a0f0

Please sign in to comment.