Executable objects

Executable objects are like files. They respond to the "fsobj_stat" method. You generally can't open them with the "file_open" method -- this will give "Permission denied". They support two methods besides the usual file methods.

// Test whether this is an executable object.
// Executables that are just files will not respond to this.
"Exep"
=> "Okay"

"Exeo" ref/int data
=> "Okay" return_code/int
The data is an array of pairs:
 * ("Argv", x):  x is an array of strings representing argv
 * ("Env.", x):  x is an array of strings representing the environment
   (usually each string is of the form "X=y")
 * ("Fds.", x):  x is an array of (i, FD)
 * ("Root", obj):  obj is the root directory
 * ("Cwd.", string):  pathname of current working directory
   (this can be omitted, in which case process will have no defined cwd)
 * ("Pgid", int):  process group ID to set for the new process
   (this is optional, but reading from the console won't work without
   setting it, and neither will Ctrl-C or Ctrl-Z)
The invocation returns when the process started has exited.  It returns
the exit code that `wait' returns for the process.