Skip to content

Commit 4a8b3aa

Browse files
Use execvpe when available (#16294)
This is a first step towards migrating to `execvpe` with a pre-created environment pointer. This doesn't change any behaviour yet, but it adds the bindings and provides the field for further enhancements. Co-authored-by: Julien Portalier <[email protected]>
1 parent 6caa9a5 commit 4a8b3aa

File tree

13 files changed

+34
-1
lines changed

13 files changed

+34
-1
lines changed

src/crystal/system/unix/process.cr

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -352,7 +352,25 @@ struct Crystal::System::Process
352352
argv = command_args.map &.check_no_null_byte.to_unsafe
353353
argv << Pointer(UInt8).null
354354

355-
lock_write { LibC.execvp(command, argv) }
355+
lock_write { execvpe(command, argv, LibC.environ) }
356+
end
357+
358+
private def self.execvpe(command, argv, envp)
359+
{% if LibC.has_method?("execvpe") %}
360+
LibC.execvpe(command, argv, envp)
361+
{% else %}
362+
execvpe_impl(command, argv, envp)
363+
{% end %}
364+
end
365+
366+
# Darwin, DragonflyBSD, and FreeBSD < 14 don't have an `execvpe` function, so
367+
# we need to implement it ourselves.
368+
# FIXME: This is a stub implementation which simply sets the environment
369+
# pointer. That's the same behaviour as before, but not correct. Will fix in a
370+
# follow-up.
371+
private def self.execvpe_impl(command, argv, envp)
372+
LibC.environ = envp
373+
LibC.execvp(command, argv)
356374
end
357375

358376
def self.replace(command_args, env, clear_env, input, output, error, chdir)

src/lib_c/aarch64-android/c/unistd.cr

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ lib LibC
2020
fun dup3(__old_fd : Int, __new_fd : Int, __flags : Int) : Int
2121
fun _exit(__status : Int) : NoReturn
2222
fun execvp(__file : Char*, __argv : Char**) : Int
23+
fun execvpe(file : Char*, argv : Char**, envp : Char**) : Int
2324
fun fdatasync(__fd : Int) : Int
2425
@[ReturnsTwice]
2526
fun fork : PidT

src/lib_c/aarch64-linux-gnu/c/unistd.cr

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ lib LibC
2020
fun dup3(fd : Int, fd2 : Int, flags : Int) : Int
2121
fun _exit(status : Int) : NoReturn
2222
fun execvp(file : Char*, argv : Char**) : Int
23+
fun execvpe(file : Char*, argv : Char**, envp : Char**) : Int
2324
fun fdatasync(fd : Int) : Int
2425
@[ReturnsTwice]
2526
fun fork : PidT

src/lib_c/aarch64-linux-musl/c/unistd.cr

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ lib LibC
2020
fun dup3(x0 : Int, x1 : Int, x2 : Int) : Int
2121
fun _exit(x0 : Int) : NoReturn
2222
fun execvp(x0 : Char*, x1 : Char**) : Int
23+
fun execvpe(file : Char*, argv : Char**, envp : Char**) : Int
2324
fun fdatasync(fd : Int) : Int
2425
@[ReturnsTwice]
2526
fun fork : PidT

src/lib_c/arm-linux-gnueabihf/c/unistd.cr

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ lib LibC
2020
fun dup3(fd : Int, fd2 : Int, flags : Int) : Int
2121
fun _exit(status : Int) : NoReturn
2222
fun execvp(file : Char*, argv : Char**) : Int
23+
fun execvpe(file : Char*, argv : Char**, envp : Char**) : Int
2324
fun fdatasync(fd : Int) : Int
2425
@[ReturnsTwice]
2526
fun fork : PidT

src/lib_c/i386-linux-gnu/c/unistd.cr

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ lib LibC
2020
fun dup3(fd : Int, fd2 : Int, flags : Int) : Int
2121
fun _exit(status : Int) : NoReturn
2222
fun execvp(file : Char*, argv : Char**) : Int
23+
fun execvpe(file : Char*, argv : Char**, envp : Char**) : Int
2324
fun fdatasync(fd : Int) : Int
2425
@[ReturnsTwice]
2526
fun fork : PidT

src/lib_c/i386-linux-musl/c/unistd.cr

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ lib LibC
2020
fun dup3(x0 : Int, x1 : Int, x2 : Int) : Int
2121
fun _exit(x0 : Int) : NoReturn
2222
fun execvp(x0 : Char*, x1 : Char**) : Int
23+
fun execvpe(file : Char*, argv : Char**, envp : Char**) : Int
2324
fun fdatasync(x0 : Int) : Int
2425
@[ReturnsTwice]
2526
fun fork : PidT

src/lib_c/x86_64-freebsd/c/unistd.cr

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@ lib LibC
1919
fun dup3(x0 : Int, x1 : Int, x2 : Int) : Int
2020
fun _exit(x0 : Int) : NoReturn
2121
fun execvp(x0 : Char*, x1 : Char**) : Int
22+
# `execvpe` is introduced in FreeBSD 15, but it already seems to be available in 14.
23+
{% unless flag?("freebsd12.0") || flag?("freebsd13.0") %}
24+
fun execvpe(file : Char*, argv : Char**, envp : Char**) : Int
25+
{% end %}
2226
fun fdatasync(fd : Int) : Int
2327
@[ReturnsTwice]
2428
fun fork : PidT

src/lib_c/x86_64-linux-gnu/c/unistd.cr

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ lib LibC
2020
fun dup3(fd : Int, fd2 : Int, flags : Int) : Int
2121
fun _exit(status : Int) : NoReturn
2222
fun execvp(file : Char*, argv : Char**) : Int
23+
fun execvpe(file : Char*, argv : Char**, envp : Char**) : Int
2324
fun fdatasync(fd : Int) : Int
2425
@[ReturnsTwice]
2526
fun fork : PidT

src/lib_c/x86_64-linux-musl/c/unistd.cr

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ lib LibC
2020
fun dup3(x0 : Int, x1 : Int, x2 : Int) : Int
2121
fun _exit(x0 : Int) : NoReturn
2222
fun execvp(x0 : Char*, x1 : Char**) : Int
23+
fun execvpe(file : Char*, argv : Char**, envp : Char**) : Int
2324
fun fdatasync(x0 : Int) : Int
2425
@[ReturnsTwice]
2526
fun fork : PidT

0 commit comments

Comments
 (0)