[comp.lang.c] help with popen

merce@iguana.uucp (Jim Mercer) (02/06/91)

a snippet of code:


	char	*p_value;
	FILE	*F_pipe;
...
[	p_value points to "no_such_file"   ]

	F_pipe = popen(p_value, "r");
	if (F_pipe == NULL)
		{
		fprintf(stderr, "failure opening pipe (%s)\n", p_value);
		return(!OK);
		}
...
	pclose(F_pipe);

intention:

open a pipe to a process, use fgets to read input, warn user on pipe failure.

question:

when i run this on my 3b1, CTIX (SysV 2+ sort of),
i get "sh: no_such_file: not found" on stderr.
but, according to the if, F_pipe is not NULL.

works fine if p_value points to an existing command.

according to my documentation (Advanced Programmer's Guide to Unix System V,
McGraw-Hill), "popen() returns NULL if _command_ cannot be started".

am i doing something wrong?
is my popen() broken?

-- 
[ Jim Mercer   work: jim@lsuc.on.ca  home: merce@iguana.uucp  +1 519 570-3467 ]
[     "I am pro-military.  I am not pro-war.  There is a big difference"      ]
[                             -- Louise Mandrell (Toronto Sun)                ]

gwyn@smoke.brl.mil (Doug Gwyn) (02/07/91)

In article <1991Feb6.053237.11051@iguana.uucp> merce@iguana.uucp (Jim Mercer) writes:
>is my popen() broken?

No, because popen() DID successfully start up "sh -c no_such_file";
when you examine the status from pclose() you should see that the
command did not succeed, however.

brad@SSD.CSD.HARRIS.COM (Brad Appleton) (02/09/91)

In article <15104@smoke.brl.mil> gwyn@smoke.brl.mil (Doug Gwyn) writes:
>In article <1991Feb6.053237.11051@iguana.uucp> merce@iguana.uucp (Jim Mercer) writes:
>>is my popen() broken?
>
>No, because popen() DID successfully start up "sh -c no_such_file";
>when you examine the status from pclose() you should see that the
>command did not succeed, however.

This is quite correct. However, in many cases it is important to know if the
pipe was succesfully opened before attempting to write to it. In such cases,
you may want to catch the SIGPIPE signal (which occurs when a pipe is broken).
Youll need to write a test character to the pipe, and then flush it, before
seeing if your pipe fails. Something like the following should work:

     FILE *pipe_fp;
     int (*broken_pipe_handler)();
            .
            .
            .
     signal( SIGPIPE, broken_pipe_handler );
     pipe_fp = popen( program_name, "w" );

     if ( !pipe_fp ) {
        perror( "popen failed" );
        exit( 1 );
     }
     else {
        fputc( '\n', pipe_fp );    /* use newline as the test-character */
        fflush( pipe_fp );
        signal( SIGPIPE, SIG_IGN );  /* if we get here, assume it's alright
                                      * to reset the default SIGPIPE handler
                                      * (this may or may not be safe to do).
                                      */
     }
            .
            .
            .

If anyone would like, I have an example of such code that uses popen to open
a pager (such as "less"). If the pipe is broken, it tries to use "more" and
if all else fails, then it just uses stdout.

Other solutions are welcome!!!

Oh yeah - this is all Unix-specific of course!
______________________ "And miles to go before I sleep." ______________________
 Brad Appleton           brad@ssd.csd.harris.com       Harris Computer Systems
                             uunet!hcx1!brad           Fort Lauderdale, FL USA
~~~~~~~~~~~~~~~~~~~~ Disclaimer: I said it, not my company! ~~~~~~~~~~~~~~~~~~~