The process replacement behaviour

Normally, execve() replaces the current process. Method calls don't and can't have that behaviour: the callee does not even have to start a new process.

The modified libc is responsible for emulating the process replacement behaviour. execve() (and the other functions in the `exec' family which use it) will test whether the filename it is given resolves to an executable object or a regular file. This test uses the "Exep" method. Note that this is different to the shell: the shell chooses its behaviour according to whether the command name is a bound variable or not.

If execve() is given an executable object, it invokes it (passing the root directory, file descriptors, etc.). When the method call returns, this means the new process has exited; it gives the exit code. libc's execve() wait for the method call to return, and then exits, using the same exit code.

Plash does not modify libc's wait() and waitpid().

This is slightly unsatisfactory in three respects:

  • It doesn't let P return the correct wait() status code to its parent when the process created by X dies with an unhandled signal (such as SIGSEGV).

  • It doesn't let P notify its parent when the new process is stopped (by SIGSTOP or when the user presses Ctrl-Z).

  • kill() doesn't work as expected: it sends a signal to the process that is waiting, not the process it spawned.

  • There is an extra process hanging around, filling up the process table and taking up memory (and holding onto open file descriptors -- though this could be fixed) but not doing much else.

The solution to this would be to modify wait() and waitpid(). This would not be too bad because they can only be used on child processes. Modifying kill() as well would be trickier and less desirable, because it involves a global namespace of process IDs, and we would like to avoid global namespaces.

Discovering file descriptors

libc's execve() finds out which file descriptor indexes a process has open simply by trying to dup() each index in turn, upto a high index number. If your program uses FDs with big FD numbers (eg. >1000), this may cause problems. Although the Linux `proc' filesystem can be used to find out what file descriptors a process has open, this is not available in the Linux chroot() environment Plash uses to run programs in, and there's no way to use it securely.

Garbage collection

exec-object will exit when the reference to the object it provides is dropped, and it has no more processes to handle.