[comp.lang.c] Controlling stdin and stdouts of other executables

dkeisen@Gang-of-Four.Stanford.EDU (Dave Eisen) (05/02/90)

>)...
>)If all you want to do is IGNORE the error and standard output from your
>)command, then the following should work:
>
>You don't want to close the standard streams, you want to connect them
>to /dev/null, quite a difference!
>

and this is most easily done using the shell's usual redirection operators:

system ("command > /dev/null 2>&1");



--
Dave Eisen                      	    Home: (415) 323-9757
dkeisen@Gang-of-Four.Stanford.EDU           Office: (415) 967-5644
"I drive a brand new BMW and I wear an unusually large shoe..."

chip@tct.uucp (Chip Salzenberg) (05/03/90)

[Unix-specific; followups to comp.unix.questions]

According to dkeisen@Gang-of-Four.Stanford.EDU (Dave Eisen):
>system ("command > /dev/null 2>&1");

Beware system().  It calls /bin/sh to do its dirty work, which is one
reason it's so attractive to novice Unix programmers.  However, if
anything in the command line is non-constant, then system() usally is
a security hole.  Ignoring buffer size issues for the moment,
consider:

	sprintf(buf, "/usr/lib/sendmail -oem '%s' <%s", address, tempfile);
	system(buf);

Looks great, right?  But what if the address is "'; rm -rf $HOME; '"?
Bzzt!  You lose the security sweepstakes.  I hope you have backups...
-- 
Chip Salzenberg at ComDev/TCT   <chip%tct@ateng.com>, <uunet!ateng!tct!chip>

brad@SSD.CSD.HARRIS.COM (Brad Appleton) (05/07/90)

In article <6418@star.cs.vu.nl> maart@cs.vu.nl (Maarten Litmaath) writes:
>
>It's *WRONG* to close an arbitrary program's standard streams!

The program being called is NOT arbitrary, the coder knows which command
is to be called. 

>Suppose the program checks the return value of printf() - if stdout is
>closed, printf() will return EOF, so the program might decide something
>is terribly wrong, and terminate!

But output will still have been (successfully) ignored :-)

>You don't want to close the standard streams, you want to connect them
>to /dev/null, quite a difference!

Agreed! I personally would have connected output to /dev/null myself.
Perhaps I should have posted a solution using "dev/null" instead but I
was trying to give an easy example (which works just fine on my System BTW).
You are right in that I probably should have used /dev/null.

>Bonus: the `0' in the execlp() call should be `(char *) 0'; grrrr, when
>do people ever learn?  :-(

GRRRRRR yourself! I used it the way it was documented for my system!!!!
I originally had used NULL (which is preferred over (char *) 0) instead of
0 but My reference text used 0 (not (char * 0))! My system may be slightly
different than yours, but I did use the proper type according to my FM.
(Of course, it could be a problem in the FM :-)

-=-=-=-=-=-=-=-=-=-=-= "And miles to go before I sleep." =-=-=-=-=-=-=-=-=-=-=-
 Brad Appleton         Harris Computer Systems         brad@ssd.csd.harris.com
 (305) 973-5360        Fort Lauderdale, FL USA        {uunet,novavax}!hcx1!brad
-=-=-=-=-=-=-=-=-=-= Disclaimer: I said it, not my company! -=-=-=-=-=-=-=-=-=-

maart@cs.vu.nl (Maarten Litmaath) (05/09/90)

In article <4077@hcx1.SSD.CSD.HARRIS.COM>,
	brad@SSD.CSD.HARRIS.COM (Brad Appleton) writes:
)In article <6418@star.cs.vu.nl> maart@cs.vu.nl (Maarten Litmaath) writes:
)...
)>Bonus: the `0' in the execlp() call should be `(char *) 0'; grrrr, when
)>do people ever learn?  :-(
)
)GRRRRRR yourself! I used it the way it was documented for my system!!!!

The documentation is wrong.

)I originally had used NULL (which is preferred over (char *) 0) instead of
                                      ^^^^^^^^^
                                      Nonsense.

)0 but My reference text used 0 (not (char * 0))! My system may be slightly
)different than yours, but I did use the proper type according to my FM.
                                         ^^^^^^
The type of the bare `0' is not proper: you're relying on the compiler to
turn it into the proper `(char *) 0'; you would be right to do so *iff* a
complete prototype were in scope.  The problem, however, is execlp() being
a variadic function, hence the following incomplete prototype:

	extern	int	execlp(char *path, char *name, ...);

There isn't a way to specify *every* argument of execlp() is to be a
`char *'.  Printf() on the other hand accepts arguments of various types
(only the first must be a `char *'), yet its prototype looks quite the same:

	extern	int	printf(char *format, ...);

)(Of course, it could be a problem in the FM :-)

You bet.
--
 Antique fairy tale: Little Red Riding Hood. |Maarten Litmaath @ VU Amsterdam:
 Modern fairy tale: Oswald shot Kennedy. |maart@cs.vu.nl, uunet!cs.vu.nl!maart