setmode (long)

Bernard Dautrevaux
Sun Feb 28 23:02:00 GMT 1999

> -----Original Message-----
> From: E. Robert Tisdale [ ]
> Sent: Friday, February 26, 1999 7:27 AM
> To:
> Subject: Re: setmode (long)
> Mumit Khan wrote:
> > I believe Pierre has something here.
> > I took another look at your code,
> > and you're changing the mode of a buffered stream!
> > Could you flush the stream (stream << flush)
> > before changing the mode and see what happens?
> No, I can't just now.
> I sent the computer with Windows 98
> and the DJPP and Cygnus compilers to my brother-in-law.
> You'll have to wait until I can fire up my old Windows 95.
> > I don't believe that your code is well-defined,
> > since changing anything for an underlying descriptor
> > of a buffered stream without flushing
> > is not guaranteed to produce the desired effect.
> Can you tell me where I can get documentation
> for this behavior in setmode?
> I got the file descriptors for standard I/O from
> 0 == (cin.rdbuf())->_fileno
> 1 == (cout.rdbuf())->_fileno
> 2 == (cerr.rdbuf())->_fileno
> because a
> ostdiostream has a
> stdiobuf which is a
> filebuf which is a
> streambuf which is a
> _IO_FILE which has an
> int _fileno.
> Is there a portable way to get file descriptors
> for cin, cout, cerr and clog?
> I suspect that Pierre may indeed have part of the answer
> for his Windows 95 OS and his Emacs shell
> but it doesn't explain why my `test.out' files
> appear to be written in binary mode
> even when the last mode set is text mode.

This has in fact nothing to do with win95/98/...; it's a conceptual
problem. You should *never* twiddle the underlying file descriptor when
using *any* kind of buffered stream! The problem is that the buffered
stream is optimizing out a lot of the calls to the underlying file
descriptor. It may even happen that the buffered stream cache some of
the characteristics of the underlying file descriptor to optimize
performance in its own handling of data :-)

You *may* try to use fflush() before, but you have the same problem with
the iostream, so you may have to flush them. But note that flush only
guarantee that you flush the output buffer of the stream, not that you
flush any internal cache.

Well behaved buffered streams (I don't know for those you use) should
have an fsetmode() (for stdio) or stream::setmode() (for iosteams) call
that do the setmode in the proper way so that you get the expected
result. *Any* other attempt to hack on th efile descriptor of an opened
buffered stream is *guaranteed* to be opened to subtle misbehaviours,
and (for once :-) Micro$oft is not responsible here...



Bernard Dautrevaux
Microprocess Ingéniérie
97 bis, rue de Colombes
Tel:	+33 (0) 1 47 68 80 80
Fax:	+33 (0) 1 47 88 97 85

Want to unsubscribe from this list?
Send a message to

More information about the Cygwin mailing list