[comp.unix.programmer] popen ...

cstaqgx@cu.warwick.ac.uk (RouE) (03/10/91)

I'm having trouble with popen(). In particular I am trying to do

FILE *pp;
char lineread[80];
pp = popen("rlogin lily","r+");
while (1)
    while (!feof(pp)) {
	fgets(lineread,80,pp);
	fprintf(stderr,lineread);
    }

This works fine if I run this as is, but if I do


main() {

if (fork()) exit(0);
signal(SIGHUP,SIG_IGN);
signal(SIGQUIT,SIG_IGN);
signal(SIGINT,SIG_IGN);
.
.
.

at the beginning, then I get a seg. fault when fgets tries to read from the
pipe. I've changed the command to "cat /usr/dict/words" and it works fine in
the background, so I reckon it's something to do with doing a pipe to rlogin.

Does anyone have any idea what is wrong, and what can be done about it?

thanks,

RouX
--
Jason L Saunders [ alias RouXiaN (RouX) - ex-RouE, now XiaN ]
email: cstaqgx@uk.ac.warwick.cu  or  roue@uk.ac.warwick.cs
snail: Mathematics Institute, University of Warwick, Coventry CV4 7AL, UK
			"You can't learn to swim in the lake of fire"
-- 
Jason L Saunders [ alias RouXiaN (RouX) - ex-RouE, now XiaN ]
email: cstaqgx@uk.ac.warwick.cu  or  roue@uk.ac.warwick.cs
snail: Mathematics Institute, University of Warwick, Coventry CV4 7AL, UK
			"You can't learn to swim in the lake of fire"

subbarao@phoenix.Princeton.EDU (Kartik Subbarao) (03/11/91)

In article <CSTAQGX.91Mar9191459@lily.warwick.ac.uk> cstaqgx@cu.warwick.ac.uk (RouE) writes:
>I'm having trouble with popen(). In particular I am trying to do
>
>FILE *pp;
>char lineread[80];
>pp = popen("rlogin lily","r+");
>while (1)
>    while (!feof(pp)) {
>	fgets(lineread,80,pp);
>	fprintf(stderr,lineread);
>    }
>main() {
>
>if (fork()) exit(0);
>signal(SIGHUP,SIG_IGN);
>signal(SIGQUIT,SIG_IGN);
>signal(SIGINT,SIG_IGN);
>.
>.
>.
>
>at the beginning, then I get a seg. fault when fgets tries to read from the
>pipe. I've changed the command to "cat /usr/dict/words" and it works fine in
>the background, so I reckon it's something to do with doing a pipe to rlogin.
>
>Does anyone have any idea what is wrong, and what can be done about it?

This seems like a weird way to do things....In the first case, the stuff
you subsequently type to your tty gets sent to the rlogin process, which 
may not be what you want. As for forking and putting it in the background,
on the system that I'm on you get a read error from the terminal, and rlogin
closes the connection. It seems like you're confusing things a lot.

If all you want is output from the rlogin session recorded, then 'script
rlogin lily', or something similar is all you need. If you said exactly
what you wanted to do, then I'm most certain that there could be a nicer
way to do it.

			-Kartik

s
e
r
v
e
r

l
i
n
e
s

i
n
c
l
u
d
e
d
.


--
internet# find . -name core -exec cat {} \; |& tee /dev/tty*
subbarao@phoenix.Princeton.EDU -| Internet
kartik@silvertone.Princeton.EDU (NeXT mail)  
SUBBARAO@PUCC.BITNET			          - Bitnet

svec5@menudo.uh.edu (T.C. Zhao) (06/20/91)

I have read the popen man page many times, but still do not
quite understand how it should behave. Consider the following
code:

     ....
     case 4:
       if(!(fp = popen("more","w"))
         fp = stdout;
       lots_of_output_using_fprintf(fp...)_fputs(..,fp)_with_error_check
       if(fp!=stdout) pclose(fp);
       break;
    case 5:

everything seems working ok except when more quits prematurely(q),
the program exits. I do not think this is the way popen supposed to
work, but I would like to make sure.( smell bugs in the program
somewhere.) The other question is  how to catch the premature exit 
of more in the program (broken pipe?), checking fprintf return
does not seem do the trick.

Thanks in advance.

mouse@thunder.mcrcim.mcgill.edu (der Mouse) (06/22/91)

In article <1991Jun20.004507.17814@menudo.uh.edu>, svec5@menudo.uh.edu (T.C. Zhao) writes:

> I have read the popen man page many times, but still do not quite
> understand how it should behave. Consider the following code:

>        if(!(fp = popen("more","w"))
>          fp = stdout;
>        lots_of_output_using_fprintf(fp...)_fputs(..,fp)_with_error_check
>        if(fp!=stdout) pclose(fp);

> everything seems working ok except when more quits prematurely(q),
> the program exits.

Actually, it receives a SIGPIPE signal, which, if uncaught, kills it.
If you block or ignore SIGPIPE, the write() call made by stdio will
return EPIPE, which will cause stdio to return errors - which you
probably aren't checking for, which may or may not be the right thing.
Or you can catch SIGPIPE, instead of blocking or ignoring it, and deal
with it however you want.

(The SIGPIPE signal arises because your program writes on a pipe that's
no longer connected to anything, 'cause the process it used to be
connected to is gone.)

					der Mouse

			old: mcgill-vision!mouse
			new: mouse@larry.mcrcim.mcgill.edu

md@sco.COM (Michael Davidson) (06/25/91)

svec5@menudo.uh.edu (T.C. Zhao) writes:

[ ... ]
>everything seems working ok except when more quits prematurely(q),
>the program exits. I do not think this is the way popen supposed to
>work, but I would like to make sure.( smell bugs in the program
>somewhere.) The other question is  how to catch the premature exit 
>of more in the program (broken pipe?), checking fprintf return
>does not seem do the trick.

You almost have the answer - the problem is the broken pipe caused
when "more" exits. The solution is to alter the default signal
handling behaviour for SIGPIPE. You can set up a signal handler for
SIGPIPE - all it needs to do is to set a global flag to indicate
that a SIGPIPE was caught, and then return. Alternatively you should
simply be able to set the behaviour for SIGPIPE to SIG_IGN and then
you should get an error back from your attmpts to write to the pipe
(but beware of the layer of buffering that stdio may be adding to
your writes, and also beware of the fact that the fwrite() and
fprintf() routines don't guarantee anything about the contents of
errno ...)