Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!samsung!usc!snorkelwacker!mit-eddie!uw-beaver!fluke!gtisqr!roger From: roger@gtisqr.uucp (Roger Droz) Newsgroups: comp.unix.questions Subject: Re: How to issue a C SHELL command within a C program Message-ID: <1990Aug28.214551.6759@gtisqr.uucp> Date: 28 Aug 90 21:45:51 GMT References: <25279.26c7fd35@kuhub.cc.ukans.edu> <852@hls0.hls.oz> <3923@auspex.auspex.com> Organization: Global Tech International Inc. Lines: 71 There have been some excellent responses to this question. Our system has expired the article that first mentioned using execlp(), which I thought was not only the best solution, but a fine example of techinical writing as well. I too, like to use execlp() because of the efficiency of directly invoking the shell of choice without invoking the Bourne shell first, and because it gets around the quoting problem mentioned by Guy Harris in <3923@auspex.auspex.com>. The two cents I want to add to this thread is that the parent process should disable the INT and QUIT signals, so that the user can type ^C (or your favorite INT signal key) to kill the child without killing the parent. The following code is taken from my patches to MicroEMACS 3.10e, which I plan to release on the world in the next week or so: /** Callout to system to perform command **/ /** RLD 07-24-90: modified to use $SHELL */ /** cmd == "" means interactive shell */ int callout(cmd) char * cmd; /* Command to execute */ { int status; char *sh; /* Shell program. */ void (*oldsigint)(), (*oldsigquit)(); extern char *getenv(); /* Get shell path */ sh = getenv("SHELL"); if (!sh) #if BSD || SUN sh = "/bin/csh"; #endif /* BSD || SUN */ #if USG || SMOS || HPUX || XENIX sh = "/bin/sh"; #endif /* USG || SMOS || HPUX || XENIX */ if (fork() == 0) { /* Child decides what to do. */ if (*cmd != '\0') /* Do a command. */ execlp(sh, sh, "-c", cmd, NULL); else /* Fork an interactive shell */ execlp(sh, sh, NULL); exit(1); /* Child shouldn't get here. */ } #if USG || SMOS || HPUX || XENIX /* Parent disables signals and waits. */ oldsigint = signal(SIGINT, SIG_IGN); oldsigquit = signal(SIGQUIT, SIG_IGN); wait(&status); signal(SIGINT, oldsigint); signal(SIGQUIT, oldsigquit); #else /* BSD || SUN */ /* BSD should disable signals while waiting for child too, */ /* but I can't remember how. -- RLD 08-28-90 */ wait(&status); #endif /* USG || SMOS || HPUX || XENIX */ } ____________ Roger Droz UUCP: uw-beaver!gtisqr!roger () () Maverick MICRoSystems / Global Technology International (_______) Mukilteo, WA ( ) | | Disclaimer: "We're all mavericks here: | | Each of us has our own opinions, (___) and the company has yet different ones!"