[fpc-pascal] re-opening stdout and sdterr

Marc Santhoff M.Santhoff at t-online.de
Sun Nov 16 04:00:59 CET 2008


Am Donnerstag, den 13.11.2008, 20:57 +0100 schrieb Jonas Maebe:
> On 13 Nov 2008, at 01:42, Marc Santhoff wrote:
> 
> > long time ago I had problems with stdxxx being in non-blocking i/o  
> > mode.
> > The suggestion was to close and re-open the channels from the system
> > units init code.
> >
> > I ran into this problem again and would like to know:
> >
> > How can I close and reopen stderr and sdtout from my program?
> 
> close(stderr);
> assign(stderr,'');
> rewrite(stderr);
> 
> close(stdout);
> assign(stdout,'');
> rewrite(stdout);
> 
> This does not enable you to set any particular options on the  
> descriptors though, 

As expected it does work but doesn't change blocking behaviour.

> and I'm not aware of any supported way for doing  
> so (read: a way which is likely to be forward compatible).

Don't get you here, what do you mean by forward compatible?

>  And even if  
> you could get at the file descriptors, there is also no cross-platform  
> functionality that I'm aware of to change their (non-)blocking setting.

No, not cross platform, but I was able to make a solution for FreeBSD 4,
I assume it'll work (with minor modifications) on other unix-like
platforms:

uses unix;

var
  res: longint; // or cint

begin

  res := fpfcntl(TextRec(stderr).Handle, F_GETFL);
  if ((O_NONBLOCK AND res)>0) then
  begin
    res := res AND (NOT O_NONBLOCK);
    res := fpfcntl(TextRec(stderr).Handle, F_SETFL, res);
    if (res=-1) then writeln(stderr, 'ERROR on SETFL');
  end;

This switches the channel to blocking mode and the overrun errors
disappear in this case.

Thanks for your help,
Marc





More information about the fpc-pascal mailing list