简体   繁体   中英

How can one really create a process using Unix.create_process in OCaml?

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM