os: add os.execve/3 (extracted from unix_spawn_process); use os.execvp/2 in v.util.launch_tool/3

pull/7716/head^2
Delyan Angelov 2020-12-30 17:57:01 +02:00
parent c943c8a16e
commit b4f02adc32
No known key found for this signature in database
GPG Key ID: 66886C0F12D595ED
3 changed files with 32 additions and 18 deletions

View File

@ -869,7 +869,7 @@ pub fn create(path string) ?File {
} }
} }
// execvp - loads and executes a new child process, in place of the current process. // execvp - loads and executes a new child process, *in place* of the current process.
// The child process executable is located in `cmdpath`. // The child process executable is located in `cmdpath`.
// The arguments, that will be passed to it are in `args`. // The arguments, that will be passed to it are in `args`.
// NB: this function will NOT return when successfull, since // NB: this function will NOT return when successfull, since
@ -883,6 +883,32 @@ pub fn execvp(cmdpath string, args []string) ? {
cargs << charptr(0) cargs << charptr(0)
res := C.execvp(charptr(cmdpath.str), cargs.data) res := C.execvp(charptr(cmdpath.str), cargs.data)
if res == -1 { if res == -1 {
return error(posix_get_error_msg(C.errno)) return error_with_code(posix_get_error_msg(C.errno), C.errno)
}
}
// execve - loads and executes a new child process, *in place* of the current process.
// The child process executable is located in `cmdpath`.
// The arguments, that will be passed to it are in `args`.
// You can pass environment variables to through `envs`.
// NB: this function will NOT return when successfull, since
// the child process will take control over execution.
pub fn execve(cmdpath string, args []string, envs []string) ? {
mut cargv := []charptr{}
mut cenvs := []charptr{}
cargv << charptr(cmdpath.str)
for i in 0 .. args.len {
cargv << charptr(args[i].str)
}
for i in 0 .. envs.len {
cenvs << charptr(envs[i].str)
}
cargv << charptr(0)
cenvs << charptr(0)
res := C.execve(charptr(cmdpath.str), cargv.data, cenvs.data)
// NB: normally execve does not return at all.
// If it returns, then something went wrong...
if res == -1 {
return error_with_code(posix_get_error_msg(C.errno), C.errno)
} }
} }

View File

@ -43,22 +43,10 @@ fn (mut p Process) unix_spawn_process() int {
fd_close(pipeset[3]) fd_close(pipeset[3])
fd_close(pipeset[5]) fd_close(pipeset[5])
} }
mut cargv := []charptr{} execve(p.filename, p.args, p.env) or {
mut cenvs := []charptr{} eprintln(err)
cargv << charptr(p.filename.str) exit(1)
for i in 0 .. p.args.len {
cargv << charptr(p.args[i].str)
} }
for i in 0 .. p.env.len {
cenvs << charptr(p.env[i].str)
}
cargv << charptr(0)
cenvs << charptr(0)
C.execve(charptr(p.filename.str), cargv.data, cenvs.data)
// NB: normally execve does not return at all.
// If it returns, then something went wrong...
eprintln(posix_get_error_msg(C.errno))
exit(1)
return 0 return 0
} }

View File

@ -164,7 +164,7 @@ pub fn launch_tool(is_verbose bool, tool_name string, args []string) {
if is_verbose { if is_verbose {
println('launch_tool running tool command: $tool_command ...') println('launch_tool running tool command: $tool_command ...')
} }
exit(os.system(tool_command)) os.execvp(tool_exe, args)
} }
// NB: should_recompile_tool/2 compares unix timestamps that have 1 second resolution // NB: should_recompile_tool/2 compares unix timestamps that have 1 second resolution