[comp.windows.x] Exec/Fork/Stdout

yakker@ucrmath.ucr.edu (matt robinson) (07/30/90)

I have been working on a program in X windows that needs to
fork off a child process, exec the process, and send the data
from stdout/stderr back to the parent, and produce it into
a window.  Now, the hard part about this is that I'M LOST! :)

If anyone can offer any assistance, the problem (more specifically)
is this:  I have a compiler that produces specific error messages
that need to be displayed to the user.  In order to do this, we 
want to take the stdout and stderr and give it back to the window,
at the same time executing the compiler, and having it produce its
own code.  I assume (I might be wrong..) that the exec'd process
needs to be forked off as a child, which will return the messages
to the parent using pipes.  If anyone can show some example (in any
degree) on what can be done to accomplish this, I would be in their
debt.  If you have a piece of code to show this, that would be even
more helpful.  Thanks for your time.

Matt D. Robinson
yakker@ucrmath.ucr.edu
3023yakk@ucsbuxa.ucsb.edu

rlh2@ukc.ac.uk (Richard Hesketh) (07/30/90)

In article <7890@ucrmath.ucr.edu> yakker@ucrmath.ucr.edu (matt robinson) writes:

>If anyone can offer any assistance, the problem (more specifically)
>is this:  I have a compiler that produces specific error messages
>that need to be displayed to the user.  In order to do this, we 
>want to take the stdout and stderr and give it back to the window,
>at the same time executing the compiler, and having it produce its
>own code.

This sounds perfectly reasonable and as I mentioned in a previous method
this is being a more popular method of creating interfaces by separating
the computational part in a separate process.

>           I assume (I might be wrong..) that the exec'd process
>needs to be forked off as a child, which will return the messages
>to the parent using pipes.

You are infact right.

>                             If anyone can show some example (in any
>degree) on what can be done to accomplish this, I would be in their
>debt.  If you have a piece of code to show this, that would be even
>more helpful.  Thanks for your time.

Okay, here's how I do it in the Xt Toolkit...

Open two pipes (one for stdout and one for stderr).  Fork off a child
process, in the child "dup2" the stdout and stderr on to the
write ends of the pipes and close the read ends.

Back in the parent, save the child process id. and set a SIGCHLD
signal handler to clean up when it dies.  close the write-able ends of
the two pipes.

Now we make the readable ends of these pipes new event sources by
using XtAppAddInput() ..

	id = XtAppAddInput(app_context, stdout_pipe_descriptor,
			XtInputReadMask, processing_routine,
			(XtPointer)client_data);

Then you trundle back off to the MainLoop routine again ..
when output appears from the child process, they will appear as
events and the "processing_routine" will be called.  In this routine
you need to make a "read" on the pipe.  I normally just read a large
chunk (say 512 bytes), process it and fall back into the MainLoop.
The smaller the chunk the less disruption to the user interface.

When the child dies you can only really safely set a flag which is checked
in the pipe "processing_routine" (this routine will still be called
when the pipe is closed on the child's end .. and all your reads will
return 0); thus when this flag is set and the read on the pipe returns 0
you have read all the data from the child and reached EOF.  You should
then remove this extra event source using XtRemoveInput() and don't forget to
close the pipes (or you will soon run out of file descriptors 8-) !

And is basically all you need to do (I think) 8-}

>Matt D. Robinson

Richard Hesketh   :   @nsfnet-relay.ac.uk:rlh2@ukc.ac.uk
		  :   rlh2@ukc.ac.uk    ..!mcsun!ukc!rlh2
---                                               
Computing Lab., University of Kent at Canterbury,
Canterbury, Kent, CT2 7NF, United Kingdom.    Tel: +44 227 764000 ext 7620/3682

liebman@xrxedds.UUCP (Chris Liebman) (07/31/90)

|> 
|> When the child dies you can only really safely set a flag which is checked
|> in the pipe "processing_routine" (this routine will still be called
|> when the pipe is closed on the child's end .. and all your reads will
|> return 0); thus when this flag is set and the read on the pipe returns 0
|> you have read all the data from the child and reached EOF.  You should
|> then remove this extra event source using XtRemoveInput() and don't
forget to

I think that there is a race condition here.  How do you know that you
will see the SIGCHLD first?   Instead of checking the SIGCHLD flag in
the pipe "processing_routine" I used my own maon loop and checked
wwhen the next event comes in.  The only side effect is that the pipe
hangs arround a little longer.

|> Richard Hesketh   :   @nsfnet-relay.ac.uk:rlh2@ukc.ac.uk
|> 		  :   rlh2@ukc.ac.uk    ..!mcsun!ukc!rlh2
|> ---                                               
|> Computing Lab., University of Kent at Canterbury,
|> Canterbury, Kent, CT2 7NF, United Kingdom.    Tel: +44 227 764000 ext
7620/3682


Chris Liebman
UUCP:		...!uunet!xrxedds!liebman
ARPA:		liebman.Herndon@Xerox.Com liebman@arisia.xerox.com
ATT:		1-(703)-787-2032
XNS:		liebman:Herndon:xerox
INTELNET:	8*440-2032

liebman@xrxedds.UUCP (Chris Liebman) (07/31/90)

In article <684@alpo.UUCP>, I said:
|> 
|> the pipe "processing_routine" I used my own maon loop and checked
					       ^^^^
						Should read "main" loop.

This is what I get for getting up in the morning, should have waited
till noon!!! :^)

Chris Liebman
UUCP:		...!uunet!xrxedds!liebman
ARPA:		liebman.Herndon@Xerox.Com liebman@arisia.xerox.com
ATT:		1-(703)-787-2032
XNS:		liebman:Herndon:xerox
INTELNET:	8*440-2032