I have tried
let _ = Unix.create_process "ls" [||] Unix.stdin Unix.stdout Unix.stderr
in utop, it will crash the whole thing.
If I write that into a .ml
and compile and run, it will crash the terminal and my ubuntu will throw a system error.
But why?
The right way to call it is:
let pid = Unix.create_process "ls" [|"ls"|] Unix.stdin Unix.stdout Unix.stderr
The first element of the array must be the "command" name.
On some systems /bin/ls
is a link to some bigger executable that will look at argv.(0)
to know how to behave (c.f. Busybox); so you really need to provide that info.
(You see more often that with /usr/bin/vi
which is now on many systems a sym-link to vim
).
Unix.create_process
actually calls fork
and the does an execvpe
, which itself calls the execv
primitive (in the OCaml C implementation of the Unix
module).
That function then calls cstringvect
(a helper function in the C side of the module implementation), which translates the arg parameters into an array of C string, with last entry set to NULL
. However, execve
and the like expect by convention (see the execve(2)
linux man page) the first entry of that array to be the name of the program:
argv is an array of argument strings passed to the new program. By convention, the first of these strings should contain the filename associated with the file being executed.
That first entry (or rather, the copy it receives) can actually be changed by the program receiving these args, and is displayed by ls
, top
, etc.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With