ping@cubmol.bio.columbia.edu (Shiping Zhang) (01/12/91)
In article <!_P+_!_@irie.ais.org> garath@ais.org (Scott Grosch) writes: > If I make a C program on this account, is there any way to have the >program execute a shell command if a certain part of the program is reached? How about system(3)? -ping
mike@bria.UUCP (Michael Stefanik) (01/12/91)
In article <!_P+_!_@irie.ais.org> ais.org!garath (Scott Grosch) writes: > > If I make a C program on this account, is there any way to have the >program execute a shell command if a certain part of the program is reached? > A quick and dirty way is to use the system() subroutine, ie: system("cp myfile yourfile"); Another way is to use the fork() exec() yourself, such as: if ( fork() ) wait(NULL); else execl("/bin/sh","sh","-c","cp myfile yourfile"); -- Michael Stefanik, Systems Engineer (JOAT), Briareus Corporation UUCP: ...!uunet!bria!mike -- technoignorami (tek'no-ig'no-ram`i) a group of individuals that are constantly found to be saying things like "Well, it works on my DOS machine ..."
guy@auspex.auspex.com (Guy Harris) (01/15/91)
>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.)
guy@auspex.auspex.com (Guy Harris) (01/17/91)
>Another advantage to *not* using system() is > "There is an enormous amount of overhead associated with each system > call. The starting program has to fork and exec the shell, and then > the shell has to fork and exec the requested program..." [1] Yes, but if the person wants to run an arbitrary shell command - and that's what it sounded like the original poster wanted to do - you have to run the shell anyway (or precisely duplicate its actions, which seems like a waste).
lwall@jpl-devvax.JPL.NASA.GOV (Larry Wall) (01/17/91)
In article <5302@auspex.auspex.com> guy@auspex.auspex.com (Guy Harris) writes:
: >Another advantage to *not* using system() is
: > "There is an enormous amount of overhead associated with each system
: > call. The starting program has to fork and exec the shell, and then
: > the shell has to fork and exec the requested program..." [1]
:
: Yes, but if the person wants to run an arbitrary shell command - and
: that's what it sounded like the original poster wanted to do - you have
: to run the shell anyway (or precisely duplicate its actions, which seems
: like a waste).
One typical tradeoff is to use the shell if the command contains any shell
metacharacters, and execute the program directly otherwise. Perl and many
make programs do this.
Larry Wall
lwall@jpl-devvax.jpl.nasa.gov
guy@auspex.auspex.com (Guy Harris) (01/19/91)
>No big problem if it doesn't. Just catch the ENOEXEC and do the shell call >you would have done anyway. Or, if you also want to run a command and have the system search $PATH to see which one to run, if appropriate, rather than having to give a full pathname, use "execvp()" which does the path search *and* the catching of ENOEXEC for you....