Path: utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!rutgers!apple!vsi1!wyse!td2cad!mipos3!pinkas From: pinkas@hobbit.intel.com (Israel Pinkas ~) Newsgroups: gnu.emacs Subject: Re: Why programs use the shell to start up a program Message-ID: Date: 24 Mar 89 22:14:01 GMT References: <8903231435.AA11955@galaxy.compass.com> Sender: news@mipos3.intel.com Distribution: gnu Organization: Corporate CAD, INTeL Corporation, Santa Clara, CA Lines: 76 In-reply-to: think!compass!worley@EDDIE.MIT.EDU's message of 23 Mar 89 14:35:49 GMT In article <8903231435.AA11955@galaxy.compass.com> think!compass!worley@EDDIE.MIT.EDU (Dale Worley) writes: > Generally the Un*x convention is that if a program wants to start an > inferior process, it has the shell do it, rather than doing a fork() > and exec() itself. See, for example, the system() call. You might > well wonder why this is done, since it costs time, and probably sets > up an additional process (is that really true?). This is an invalid assertion. There are a number of differences between system() and fork()/exec(). The main ones are that system() invokes a shell to process the command given. The call does not return until the invoked program exits. fork()/exec() start up the specified process in parallel. If IPC is needed, fork() allows pipes to be used. The pipes can also be passed through an exec(). (This is tricky!) > The reason is that > often the "program name" to run is obtained from the user or an > environment variable, and using the shell to process it gives > additional flexibility. If the program name comes from the user, the program can be invoked directly. If it comes from the environment, getenv() is simple enough. > For instance: > > The program may have a text string which is a command to run, complete > with arguments. Then it can leave the problem of parsing the string > (and expanding wild cards, ~s, etc.) to the shell. With all the different variations of exec() available, this should not be a problem. The only issue I see here is parsing the words of a line into arguments. This can almost be done with scanf(). > The program name may not be an absolute path, and thus the problem of > searching the path can be left to the shell. exec?p() does this. > The program name may be an alias (which, remember, the user thinks of > as a "command"). Figuring out aliases can be left to the shell. Since you mention aliases, I assume that you are refering to csh. Since system() invokes csh with the -c flag, prompt is not set. Most users do not define aliases when prompt is not set. (I also son't set most shell variables.) With this in mind, system can't do any better than exec(). > The program name may be a real program name with some switches. For > example, consider setting Emacs's lpr-command to "lpr -Pprinter2". Actually, Emacs' lpr commands use a variable called lpr-switches, which is a list of switches to pass to lpr before the file names. A better example is the mh-e package's mh-lpr-command format, which is a string that is passed to format along with the file name. The return should be a command to execute. (However, I think that both lpr commands use system() to print.) As I mentioned before, parsing the arguments out of a string is not difficult. The hard part may be determining when a space is part of the argument list instead of a separator. On BSD 4.3 systems there are routines for parsing. See string(3) for strspn, strtok. At the very worst, index/strchr can be used. The parsing routine is not difficult, and can be reused. -Israel Pinkas -- -------------------------------------- Disclaimer: The above are my personal opinions, and in no way represent the opinions of Intel Corporation. In no way should the above be taken to be a statement of Intel. UUCP: {amdcad,decwrl,hplabs,oliveb,pur-ee,qantel}!intelca!mipos3!cadev4!pinkas ARPA: pinkas%cadev4.intel.com@relay.cs.net CSNET: pinkas@cadev4.intel.com