OCaml's Unix module and ARGV
Be warned: the string array
argument to Unix.create_process
et al. represents the entire argument vector: the first element should be the command name. I didn't expect this, since there is a separate prog
argument to create_process
, and ended up with weird behavior* like,
# open Unix;;
# create_process "sleep" [|"10"|] stdin stdout stderr;;
10: missing operand
Try `10 --help' for more information.
- : int = 22513
This can be a bit insidious—in many cases skipping the first argument will only subtly change the behavior of the child process.
Note that the
prog
argument is what matters in terms of invoking the sub-process---the first element of the argument vector is what just what is passed into the process. Hence,
# create_process "gcc" [|"foo";"--version"|] stdin stdout stderr;;
- : int = 24364
foo (GCC) 4.2.3 (Ubuntu 4.2.3-2ubuntu7)
* Actually, this "weird behavior" is the test that finally made me realize what was going on. The emergent behavior of my app was much more mysterious...
4 comments:
It is a bit weird, but it just follows the behaviour of the system call actually used. execvp(2) and related functions expect the command name as the first argument:
char *args = { prg_name, arg1, NULL };
execvp(prg_name, args);
I guess it affects the program called only if it reads argv.
I concur that the design of the Unix module is quite low-level. I belive a higher-level module would be quite useful for the community -- in particular, at some point, we're going to start looking for such a module for Batteries Included.
vasilis, I'm sure you're right about *why* it's this way, but: (a) the Unix module has an execvp function, create_process is supposed to be "high level", and (b) this pre-condition ought to be documented somewhere, for the benefit of those who aren't familiar with the standard Unix exec functions.
david teller, good luck.
Post a Comment