Hi,
I’d like to know whether there is a cross-platform way to spawn processes already in the core library or is my only option to call SpawnProcess on Windows and fork+exec on UNIX?
Best regards.
Hi,
I’d like to know whether there is a cross-platform way to spawn processes already in the core library or is my only option to call SpawnProcess on Windows and fork+exec on UNIX?
Best regards.
For very basic uses, there’s also libc.system
.
Other than that, there’s also a more robust process API in core:os/os2
. That’ll eventually replace core:os
, but for now it’s work-in-progress.
Thanks. How much is os2 expected to change?
Another question – why might os2.process_exec
return a .Not_Exist
error?
I’m trying to spawn an ld
subprocess from GNU binutils but I’m getting that error. It’s not obvious to me why since when I run which ld
in the same way it returns the right location of ld
.
Relevant code:
// ...
command: [dynamic]string = { "ld", "-nostdlib", "-o", path_exe }
for path in compiled_libs {
append(&command, path)
}
_, stdout, stderr := os2.process_exec(os2.Process_Desc{
command = command[:],
}, context.allocator) or_return
// ...
Spawning as
from GNU binutils and piping to it went smooth though.
Just checked and the command succeeds through libc.system
.
command_str := strings.join(command[:], " ")
command_cstr := strings.clone_to_cstring(command_str)
ret := libc.system(command_cstr)
assert(ret == 0) // ok
libc.system
will run the command in a shell, which implies PATH
lookup as well as all of the other “features” of a shell (e.g. wildcards, variable substitution, etc.). This can be prone to shell injection if you include untrusted input in the command, for instance.
os2.process_exec
, at least on Linux, will end up forking and calling execveat
, which directly invokes a process by path name. PATH
is a feature of the shell, though it seems as execve
still checks some default system paths, it won’t check any custom ones defined in the PATH
envvar.
Where is your ld
executable at? process_exec
does seem to find ld
on my system, but I have an ld
at /bin/ld
and /usr/bin/ld
–the standard paths.
$ which ld
/nix/store/i53w7x986ifmgzvb8da6zkfms4xzmdrk-gcc-wrapper-13.2.0/bin/ld
$ which as
/nix/store/i53w7x986ifmgzvb8da6zkfms4xzmdrk-gcc-wrapper-13.2.0/bin/as
These are the paths.
What’s curious to me is that as
is successfully spawned through process_start
but ld
isn’t.
Looks like something goes wrong with dup2
in the child process.
I don’t know how reproducible this is but I’m pretty sure it’s a bug is os2
.
$ file $(readlink -e $(which ld))
/nix/store/3zaigavb3ig42pb3rmg0cjr85d77aqwz-binutils-wrapper-2.41/bin/ld: a /nix/store/syl4snn859kpqvn9qh91kr7n9i4dws04-bash-5.2p32/bin/bash script, ASCII text executable
$ file $(readlink -e $(which as))
/nix/store/b2lp2479725x61x2wg58x8ajgfz985w0-binutils-2.41/bin/as: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /nix/store/kpy2cyd05vdr6j1h200av81fnlxl
1jw0-glibc-2.39-52/lib/ld-linux-x86-64.so.2, for GNU/Linux 3.10.0, not stripped
ld
is a f****** bash script??