re-opening stdout and sdterr

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

re-opening stdout and sdterr

Marc Santhoff
Hi,

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?

I want to have some code that is working for sure, regardless of which
os and compilerversion is used to translate it.

TIA,
Marc


_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: re-opening stdout and sdterr

Marc Santhoff
Am Donnerstag, den 13.11.2008, 01:42 +0100 schrieb Marc Santhoff:

> Hi,
>
> 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?
>
> I want to have some code that is working for sure, regardless of which
> os and compilerversion is used to translate it.

Don't get me wrong because I formulated somewhat misleading: I'm not
asking anyone to write code.

What I need is the knowledge how to access and maybe switch the mode of
the system i/o channels.

Marc


_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: re-opening stdout and sdterr

Jonas Maebe-2
In reply to this post by Marc Santhoff

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, and I'm not aware of any supported way for doing  
so (read: a way which is likely to be 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.


Jonas
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: re-opening stdout and sdterr

Marc Santhoff
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


_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal