Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!swrinde!elroy.jpl.nasa.gov!usc!samsung!uunet!auspex!guy From: guy@auspex.auspex.com (Guy Harris) Newsgroups: comp.unix.questions Subject: Re: shell in programs Message-ID: <5236@auspex.auspex.com> Date: 14 Jan 91 20:20:57 GMT References: <346@bria> Distribution: na Organization: Auspex Systems, Santa Clara Lines: 44 >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.)