
David Roundy wrote:
It would be nice to be able to run "user-interactive" commands such as text editors in a safe and consistent manner.
Are you referring to the case where you let the child inherit the parent's stdin/stdout, and suspend the parent for the duration of the child (e.g. system("$EDITOR ..."))? Or running the child on a slave pseudo-tty?
I'm thinking of suspending the parent. Certainly having two programs try to read from stdin would be a nightmare.
Right; the way that's normally done in C is with system(), plus saving and restoring the tty state if you've been messing with it (e.g. using curses; although that won't actually matter for a child program which itself uses curses, as it will set up the tty itself). For your purposes, runProcess + waitForProcess is probably the way to go. Except that runProcess appears to be missing the usual signal handling. system() ignores SIGINT and SIGQUIT in the parent, and resets them to their defaults in the child; it also blocks SIGCHLD in the parent. runProcess may need to do something similar; it should probably at least reset SIGINT and SIGQUIT in the child, in case they are ignored in the parent. The parent can set up its own signal handling, but the only place it can control the child's signal handling is between the fork() and the exec(), so if runProcess doesn't do it, it won't get done. FWIW, runInteractiveProcess isn't what you're looking for. That explicitly sets up pipes for stdin/stdout/stderr; i.e. it's meant for running a "slave" process, with the caller providing its input and consuming its output (like popen(), only more so).
I'm not clear from your code whether there will be a problem with passing stdin and stdout to runProcess. If the process closes stdin, will it be closed for me?
I would expect so; once a descriptor is close()d, you can't "unclose" it.
Hmmmm. So either we'd have to dup stdin and stdout before passing them, or hope that the program doesn't close them (and the duping *could* be done by runInteractiveProcess, if we wanted it to actively support this usage).
I think that I misunderstood you here. If the child process closes the
descriptors, that won't affect the parent, as fork() automatically
duplicates all descriptors. I was referring to the case where the
parent had closed some of the descriptors prior to calling runProcess.
--
Glynn Clements