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 (cf 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.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.