Path: utzoo!attcan!uunet!mcsun!ukc!harrier.ukc.ac.uk!rlh2 From: rlh2@ukc.ac.uk (Richard Hesketh) Newsgroups: comp.windows.x Subject: Re: Exec/Fork/Stdout (Eek! Help!) Message-ID: <5211@harrier.ukc.ac.uk> Date: 30 Jul 90 14:45:39 GMT References: <7890@ucrmath.ucr.edu> Reply-To: rlh2@ukc.ac.uk (Richard Hesketh) Organization: Computing Lab, University of Kent at Canterbury, UK. Lines: 65 Summary: Expires: Sender: Followup-To: 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