[comp.unix] Pipes Signals Interprocess-I/O

lanzo%mercutio@steinmetz.UUCP (Mark Lanzo) (12/17/87)

I'm working on an application where I have a process fork off a 2nd process
and maintain communications with the subprocess via a pipe (or more accurately,
via 2 pipes--one for parent-to-child writes, the other for child-to-parent).

The problem that I am running into is that I need to be able to detect when 
the child process writes to the pipe; and I need the I/O to be as unbuffered
as possible.  I need the ability to detect writes asynchronously as well as
synchronously.

I have tried using "fcntl(fd,F_SETFL,FASYNC)" as well as setting up an
interrupt handler to handle SIGIO signals (via "sigvec(2)"), and this works
fine when I'm reading from the terminal, but does not seem to work at all
when I try it from a pipe.

My intent was for an interrupt routine to be triggered whenever the child
process wrote into the pipe; but I never get a SIGIO signal when data is
written into the pipe.

I can manually examine the pipe to see if any data is waiting to be read (by
the master process) using "ioctl(FIONREAD)", but even this does not work
reliably since I don't detect that anything was written until the child 
process flushes its end of the pipe.  I need to know when it writes something
to the pipe, not when the buffer is full (4K bytes?).

One major constraint is that I don't necessarily have access to the source
code of the child process--the code I'm working on (the master process) has
to work with any existing program out there.

For reference, my basic setup looks goes like:

     call "pipe" to open a pipe which is for writing from parent-to-child
     call "pipe" to open a pipe for writing from child-to-parent
     use fcntl to set FASYNC mode on all descriptors.
     fork process:

	child				 
        -------                          
	disconnect unused ends of pipes:
	    close parent-to-child write end
	    close child-to-parent read	end
	use close/dup etc to make pipe ends be stdin & stdout.
	set unbuffered I/O mode on stdin, stdout, stderr
	exec subprocess...

    
        parent                            
	----------			   
	disconnect unused ends of pipes:
	    close child-to-parent write end 
	    close parent-to-child read end
	set up signal handler for SIGIO interrupts.
	sit in loop waiting for signals (sigpause(2))--
	    SIGIO handler does ioctl(FIONREAD) to check pipe, then reads data.

Well, the SIGIO handler works fine to detect input from places like stdin, but
never sees anything coming down the pipe.  When it gets invoked (generally
by me banging on the <RETURN> key causing an interrupt from stdin), it 
does find that there is data available in the pipe (as well as stdin) and
has no problem reading it.


Does anyone out there know how I can fix this problem?

Also:  Is there a way that I can determine WHICH file descriptor caused
a SIGIO interrupt to be invoked, or by which I can set up a different
interrupt handler for each descriptor?


Oh yeah, almost forgot:
    I'm using Ultrix 1.2 (going to 2.0 soon), but I'm interesting in solutions
which are as portable as possible between various flavors of Unix.

	    Thanks in advance,

		    Mark Lanzo
                    mercutio!lanzo

andrew@frip.gwd.tek.com (Andrew Klossner) (01/14/88)

[These answers apply to Berkeley-derived Unices ...]

	"Well, the SIGIO handler works fine to detect input from places
	like stdin, but never sees anything coming down the pipe."

The man page for fcntl(2) says that SIGIO only happens for
terminal-class files.

	"Is there a way that I can determine WHICH file descriptor
	caused a SIGIO interrupt to be invoked?"

Not directly, but you can find out at any time which fd's have input
ready with select(2).
-- 
  -=- Andrew Klossner   (decvax!tektronix!tekecs!andrew)       [UUCP]
                        (andrew%tekecs.tek.com@relay.cs.net)   [ARPA]

julian@acp.OZ (Julian Elischer) (01/16/88)

In article <2951@mcdchg.UUCP>, lanzo%mercutio@steinmetz.UUCP (Mark Lanzo) writes:
> I'm working on an application where I have a process fork off a 2nd process
   lines deleted
> The problem that I am running into is that I need to be able to detect when 
> the child process writes to the pipe; and I need the I/O to be as unbuffered
> as possible.  I need the ability to detect writes asynchronously as well as
> synchronously.

I may be wrong, but I think that I recently read that doing a STAT
sometimes gives you the number of chars waiting in a pipe.
you will have to check yourself but it might solve th problem
If you're still waiting.. others might comment on this
as I can think of uses for this myself and cannot find reference to this
any more.
p.s. sorry for the late response but our feed has been down for 3 weeks
PLUS always allow 1 week for news in W. Australia.

julian elischer
UUCP: {lots of places,uunet,mcvax}!munnari!acp.oz!julian
ACSNET:	julian@acp.oz