Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

unix

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?

like image 916
Jackson Tale Avatar asked May 29 '14 13:05

Jackson Tale


2 Answers

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).

like image 58
Seb Mondet Avatar answered Oct 07 '22 11:10

Seb Mondet


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.

like image 31
didierc Avatar answered Oct 07 '22 10:10

didierc