shell in programs

Guy Harris guy at auspex.auspex.com
Tue Jan 15 07:20:57 AEST 1991


>Another way is to use the fork() exec() yourself, such as:
>
>	if ( fork() )
>		wait(NULL);
>	else
>		execl("/bin/sh","sh","-c","cp myfile yourfile");

Which doesn't buy you very much over "system()" - in fact, it may buy
you less; "system()":

	1) ignores SIGINT and SIGQUIT, which may be a win if the user
	   ^C's the program;

	2) exits if the "execl" fails;

	3) properly provides the terminating "(char *)NULL" argument to
	   "execl"'s argument list;

	4) keeps waiting until the newly-created process exits, so that
	   if you have other child processes (sometimes some shells give
	   you child processes that you *don't* create yourself, so even
	   if your program hasn't forked before, it may have child
	   processes if it's part of a pipeline);

	5) picks up the exit status from the command.

2) and 3) may just be due to the code being a quick-and-dirty example,
but *real* code should do both.  5) isn't a problem if the program
doesn't care whether the command succeeds - but make sure you *really*
have no reason to care, i.e. the program can get its work done
regardless of whether the command succeeds.  1) may not be a problem. 
4), however, is something people *have* been bitten by.

Another advantage of using "system()" is that you don't have to write
code to worry about all of the above.

The one advantage to *not* using it is that you may want to run the
command under an effective user ID other than the one your program is
running under (for example, if your program is set-UID, has an
interactive interface, and lets the user run an arbitrary command), or
may want to change its environment variables, or something like that. 
(If you just want to capture its output into a pipe, or send output down
a pipe to be its input, take a look at "popen()", bearing in mind that
it doesn't do anything with the user IDs either.)



More information about the Comp.unix.questions mailing list