[fpc-pascal]Filter

Thomas Schatzl tom_at_work at yline.com
Sat Sep 22 18:00:18 CEST 2001


From: "Andreas K. Foerster" <AKFoerster at AKFoerster.de>
Subject: Re: [fpc-pascal]Filter

> On Fri, Sep 21, 2001 at 06:56:03PM +0100, Lee, John wrote:
>
> > did I miss something here...if it's windoze then
> >
> > run external program... eg jim > tmp.tmp to redirect o/p
>
> And how do you redirect it from within Pascal?

Call the external program with an appropriate commandline.

Use the CreateProcess() API call from within your program as already
suggested. You may specify (windows-) file handles for the newly created
process to be used as stdin, stdout and stderr. You could try to insert
application defined ones for those. Or see below.

> > open tmp.tmp for i/p eg in reset (with filemode=$40 in windoze) so you
> > can read it whilst jim is writing it
> > (if open fails because tmp.tmp is locked, slweep for 100 msec & retry)
> >
> > err that's it...
>
> Okay, but creating a temporary file is a little primitive, isn't it?

It works while meeting the given requirements. Isn't this most important in
the first case ?

> > Suppose its same idea for lunix + it's variants...
>
> In Linux it's more efficient with Popen.
> With this you can redirect it directly to the program.
>
> That's exactly what I was looking for... but for Windows.

CreateProcess() in conjunction with unnamed pipes can exactly duplicate the
behaviour of popen(). Popen() seems to be a helper function within Linux
using these techniques too, it says so in the manpages.

The general idea is (if I am not completely mistaken, from memory):

--- popen functionality
*create unnamed pipe - you get two file handles, one for reading, one for
writing
*save old stdout + stdin
*set stdout to write handle
*(maybe) change read handle to be non-inheritable (to avoid inheritage of
more file handles than necessary)
*create + run the child process. It automatically inherits all inheritable
handles by default afair (Win32)
*(maybe) restore stdout in main program already at this point and close
write handle. You don't need it anymore in the main process, the child
process automatically gets a copy. This copy will be automatically closed on
process exit.
*return read handle to main program
--- popen ends

*in child program just write as usual to stdout (which is now one end of the
pipe)
*read data from read handle (other end of pipe) or set stdin to the read
handle for more convenient access until child program finishes and no more
data available.

You may use some event synchronization functions to avoid waste of cpu time.
Using threads might not prove a good idea with FPC.

*close pipe handles left open
*restore standard i/o handles in main program if applicable and not done yet

See the MS docs for more information about pipes and process creation.

Regards,
  Thomas







More information about the fpc-pascal mailing list