MinGW: How do I temporarily disable stderr in a C(++) program

V

Vince C.

Hi all.

I've installed Bloodshed Dev-C++ on a Windows 2000 SP4 machine. I'm using
MinGW 3.4.2.

I'd like to temporarily disable standard functions to write to stderr, i.e.
for instance redirect stderr to a temporary file (or /dev/null but is there
an equivalent under Windows? Is it "nul:") and then to *restore* the
default stderr so that standard library functions that write to stderr
produce output again.

I've checked freopen to redirect stderr to a file but, strangely enough,
error messages don't go to the file :(.

Also note I'm using stdio and iostream concurrently.

Is there a way to, say, close stderr and restore it later on in the same
program under Windows using standard libraries?

Thanks for any hint or suggestion.

Vince C.
 
K

Kenny McCormack

Hi all.

I've installed Bloodshed Dev-C++ on a Windows 2000 SP4 machine. I'm using
MinGW 3.4.2.

I'd like to temporarily disable standard functions to write to stderr, i.e.
for instance redirect stderr to a temporary file (or /dev/null but is there
an equivalent under Windows? Is it "nul:") and then to *restore* the
default stderr so that standard library functions that write to stderr
produce output again.

Let me be the first of many to wish you all the best of luck and true
happiness, and, oh, yes, to point out that your question is:

Off topic. Not portable. Cant discuss it here. Blah, blah, blah.
--
Useful clc-related links:

http://en.wikipedia.org/wiki/Aspergers
http://en.wikipedia.org/wiki/Clique
http://en.wikipedia.org/wiki/C_programming_language
 
T

Tim Prince

Vince said:
Hi all.

I've installed Bloodshed Dev-C++ on a Windows 2000 SP4 machine. I'm using
MinGW 3.4.2.

I'd like to temporarily disable standard functions to write to stderr, i.e.
for instance redirect stderr to a temporary file (or /dev/null but is there
an equivalent under Windows?
This isn't a Windows help forum. There are many of those. There is
also on-line documentation of windows cmd processor syntax. In this
case, it resembles bash.
 
J

Jens Thoms Toerring

Vince C. said:
I've installed Bloodshed Dev-C++ on a Windows 2000 SP4 machine. I'm using
MinGW 3.4.2.
I'd like to temporarily disable standard functions to write to stderr, i.e.

Can you name a single standard C function that writes to stderr
(of course except those output functions that you tell to write
to stderr - and for those it's already under your control where
they write to)?
for instance redirect stderr to a temporary file (or /dev/null but is there
an equivalent under Windows? Is it "nul:") and then to *restore* the
default stderr so that standard library functions that write to stderr
produce output again.

If you use freopen() to redirect stderr to a file then stderr gets
closed. If you somehow can get it back despite having it closed and
then re-redirect back to that again is a question that you have to
ask in a Windows group.
I've checked freopen to redirect stderr to a file but, strangely enough,
error messages don't go to the file :(.

What exactly did you do? Perhaps it's a buffering issue, i.e.
while stderr is line buffered the writes to new file are block-
buffered and, if your program crashes, the buffer isn't written
to the file?
Also note I'm using stdio and iostream concurrently.

There's no 'iostream' in C, I guess you must be using C++, not C,
and then you should ask in comp.lang.c++.
Is there a way to, say, close stderr and restore it later on in the same
program under Windows using standard libraries?

You would need to have a file name for stderr to be able to that
since the only function for redirection in standard C is freopen()
and this can only redirect to a file given by path, not to a FILE
pointer. If Windows supplies you with something in the file system
for (an already closed) stderr I can't tell, that you again need to
ask in a Windows group. But this solution then is already system
specific for this reason you probably also don't need to care if
the functions you use are standard C functions...

Regards, Jens
 
D

Default User

Jens said:
Can you name a single standard C function that writes to stderr
(of course except those output functions that you tell to write
to stderr - and for those it's already under your control where
they write to)?

perror().




Brian
 
V

Vince C.

Off topic. Not portable. Cant discuss it here. Blah, blah, blah.

Warning: troll behind!


Let me answer with the same terseness:
Off-topic

No! I'm using all but Windows API, only standard C function alls and GPL'd
code so that it runs on BOTH Win* and LINUX systems.
Not portable

Yes! I'm using all portable APIs like GNU getopt() and getopt_long().
Absolutely no Windows API is involved.
Can't discuss it here

Ah? So stderr is no part of C?

I suggest you read once more the C standard functions.

Thanks for your non-help anyways,
Vince C.
 
V

Vince C.

Tim said:
This isn't a Windows help forum.

I'm not that dumb you know... I just posted enough information so that those
who want to help get the most accurate picture of what I'm trying to do and
on what platform.

Vince C.
 
H

Harald van =?UTF-8?B?RMSzaw==?=

Vince said:
Warning: troll behind!

On occasion Kenny'll provide useful answers, but his troll messages are best
ignored. That said, I disagree with your reply to him.
Let me answer with the same terseness:


No! I'm using all but Windows API, only standard C function alls and GPL'd
code so that it runs on BOTH Win* and LINUX systems.

The license of code has nothing whatsoever to do with its portability, and I
fail to see how anyone might disagree. Plus, there are many more systems
than Windows and Linux, multiple processors that they run on, multiple
implementations of the C standard library per operating system, multiple
compilers per operating system, and there are probably other things I left
out.
Yes! I'm using all portable APIs like GNU getopt() and getopt_long().
Absolutely no Windows API is involved.

GNU getopt and getopt_long are not standard C functions. If you're calling
them externally, that's not portable, and it's off-topic here. If you're
including them in your own project, and they're doing something you don't
want, you'll need to show the relevant code.
 
M

Malcolm McLean

Jens Thoms Toerring said:
Can you name a single standard C function that writes to stderr
(of course except those output functions that you tell to write
to stderr - and for those it's already under your control where
they write to)?
assert() will often do so, though it is not obliged to.
 
V

Vince C.

Jens said:
Can you name a single standard C function that writes to stderr
(of course except those output functions that you tell to write
to stderr - and for those it's already under your control where
they write to)?

Functions getopt() and getopt_long(). They write error messages to stderr
whenever an option is not recognized or there is something wrong with the
command line syntax defined by the application.

If you use freopen() to redirect stderr to a file then stderr gets
closed. If you somehow can get it back despite having it closed and
then re-redirect back to that again is a question that you have to
ask in a Windows group.

It should be basically as simple as initializing device stderr when the
program starts, shouldn't it? There is code within stdlib that creates an
__iob[2] array of FILE*, each being stdout, stdin and stderr, respectively.
If my programm succeeds in doing the same, i.e. re-initializing stderr with
the default values, the trick is done. So I asked the question if it was
possible.

Of course my program is (currently) a Windows application but - while I'm
writing it - I'm building a set of functions that I'll be able to reuse
under whatever platform I want, provided it's running GNU code.

What exactly did you do? Perhaps it's a buffering issue, i.e.
while stderr is line buffered the writes to new file are block-
buffered and, if your program crashes, the buffer isn't written
to the file?

I'm trying to create a library of functions that basically runs with C++
code but with a base set of C functions. That base set of C functions
should be able to handle multiple command line argument syntaxes, like
argtable2 but much simpler (for my own usage).

I've read argtable2 uses get_opt() and getopt_long() so is 100% compatible
with GNU getopt() syntax. However if you want multiple command line
syntaxes and are using only getopt() and getopt_long() both functions
output error messages with the syntaxes that don't match - since there
should be only one command line parameter syntax that matches but you have
to check them all in a while loop (for instance) until you find one that
matches, i.e. during which neither getopt() and getopt_long() return any
error message.

Hence I'd like to temporarily disable stderr while I'm checking command line
parameter syntaxes since I might get error messages, which is the normal
behaviour of these functions.

There's no 'iostream' in C, I guess you must be using C++, not C,
and then you should ask in comp.lang.c++.

Yes, I know there is no such iostream in C but iostream uses std* file
descriptors. Hence I suppose I must keep both libraries in sync, i.e. if I
close (or reopen) stderr cerr must be kept in sync so that it "knows" the
stderr file descriptor has changed.

I posted here for it's a C question first. And given the length of this
post, you can easily understand it's a hassle to type it again... ;-)

You would need to have a file name for stderr to be able to that
since the only function for redirection in standard C is freopen()
and this can only redirect to a file given by path, not to a FILE
pointer. If Windows supplies you with something in the file system
for (an already closed) stderr I can't tell, that you again need to
ask in a Windows group. But this solution then is already system
specific for this reason you probably also don't need to care if
the functions you use are standard C functions...

I'd say "no" since the libraries I'm using implement the same code on all
supported platforms (it's GNU code). So it's completely independent from
Windows. The only difference is there is no /dev/null, as when we redirect
output in shell scripts. I think that device is "nul:" under windows (I
remember batch scripts where I used:

do_something_with_possible_error_messages > nul:

The only thing I need to know, I suppose, is how does standard C library
initialize stderr so that I can do the same in my program - provided it's
safe, of course. Hence my question(s)...

Vince C.
 
K

Kenny McCormack

On occasion Kenny'll provide useful answers, but his troll messages are best
ignored. That said, I disagree with your reply to him.


The license of code has nothing whatsoever to do with its portability, and I
fail to see how anyone might disagree. Plus, there are many more systems

Right. The rule is: If it's the slightest bit interesting, it is OT here.
 
J

Jens Thoms Toerring

Functions getopt() and getopt_long(). They write error messages to stderr
whenever an option is not recognized or there is something wrong with the
command line syntax defined by the application.

Neither are standard C functions. But, on the other hand, as already
others have pointed out, there are (at least) the perror() and
assert() function which write to stderr...
It should be basically as simple as initializing device stderr when the
program starts, shouldn't it? There is code within stdlib that creates an
__iob[2] array of FILE*, each being stdout, stdin and stderr, respectively.
If my programm succeeds in doing the same, i.e. re-initializing stderr with
the default values, the trick is done. So I asked the question if it was
possible.

But there's also an operating system in the background, from which
the C library gets the value it uses to initializes stderr with.
And the C library is, of course, limited by what the operating
system does. stdin, stdout and stderr are an abstraction layer
on top of what the operating system supplies. Now the standard
requires that stderr gets closed when you use freopen() to re-
direct it to a file. And at least under Unix (I don't now about
Windows but I could imaging that it's similar) once you have
closed stderr (and thus the underlying file descriptor) there's
no going back.
Of course my program is (currently) a Windows application but - while I'm
writing it - I'm building a set of functions that I'll be able to reuse
under whatever platform I want, provided it's running GNU code.
I'm trying to create a library of functions that basically runs with C++
code but with a base set of C functions. That base set of C functions
should be able to handle multiple command line argument syntaxes, like
argtable2 but much simpler (for my own usage).
I've read argtable2 uses get_opt() and getopt_long() so is 100% compatible
with GNU getopt() syntax. However if you want multiple command line
syntaxes and are using only getopt() and getopt_long() both functions
output error messages with the syntaxes that don't match - since there
should be only one command line parameter syntax that matches but you have
to check them all in a while loop (for instance) until you find one that
matches, i.e. during which neither getopt() and getopt_long() return any
error message.

You can "silence" getopt() (i.e. force it not to write to stderr)
by setting 'opterr' to 0, so there's no need to temporarily redirect
stderr if it's only about the error messages from getopt(). You seem
not to be the first to have had that problem;-)

Regards, Jens
 
K

Keith Thompson

Vince C. said:
Functions getopt() and getopt_long(). They write error messages to stderr
whenever an option is not recognized or there is something wrong with the
command line syntax defined by the application.

getopt() and getopt_long() are not standard C fcuntions, i.e., they're
not mentioned in the C standard.

If you want to see what the C standard actually says, you can grab a
copy of <http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1124.pdf>.
It's a post-C99 draft. (Note that most existing compiler do not fully
support the C99 standard, but the basic stdio stuff hasn't changed
much since C90, which is almost universally supported.
If you use freopen() to redirect stderr to a file then stderr gets
closed. If you somehow can get it back despite having it closed and
then re-redirect back to that again is a question that you have to
ask in a Windows group.

It should be basically as simple as initializing device stderr when the
program starts, shouldn't it? There is code within stdlib that creates an
__iob[2] array of FILE*, each being stdout, stdin and stderr, respectively.
If my programm succeeds in doing the same, i.e. re-initializing stderr with
the default values, the trick is done. So I asked the question if it was
possible.

The C standard says nothing about __iob, or about stdin, stdout, and
stderr being elements of an array.

I don't believe there's any way *in standard C* to redirect stderr to
a specified file, and then direct it back to it's original
destination.

It's likely that there's a way to do it on your platform. To find
out, I suggest posting to comp.unix.programmer. If you want solutions
for both Unix and Windows, you might also post to
comp.os.ms-windows.programmer.win32.
Of course my program is (currently) a Windows application but - while I'm
writing it - I'm building a set of functions that I'll be able to reuse
under whatever platform I want, provided it's running GNU code.

Unix/Linux and Windows are actually quite similar to each other in
many ways. Code that runs under both Unix and Windows is not what we
call "portable" around here; there are a plethora of other systems,
and truly portable C code has to work under all of them.

[...]
Yes, I know there is no such iostream in C but iostream uses std* file
descriptors. Hence I suppose I must keep both libraries in sync, i.e. if I
close (or reopen) stderr cerr must be kept in sync so that it "knows" the
stderr file descriptor has changed.

How do you know that iostream uses std* file descriptors? The C
standard certainly doesn't guarantee this. The C++ standard may or
may not do so, but you'd have to ask in comp.lang.c++.

[...]
The only thing I need to know, I suppose, is how does standard C library
initialize stderr so that I can do the same in my program - provided it's
safe, of course. Hence my question(s)...

Here's what the standard says (C99 7.19.3p7):

At program startup, three text streams are predefined and need not
be opened explicitly -- _standard input_ (for reading conventional
input), _standard output_ (for writing conventional output), and
_standard error_ (for writing diagnostic output). As initially
opened, the standard error stream is not fully buffered; the
standard input and standard output streams are fully buffered if
and only if the stream can be determined not to refer to an
interactive device.

The answer to your question, I think, is entirely
implementation-specific.
 
V

Vince C.

Jens Thoms Toerring wrote:

....
You can "silence" getopt() (i.e. force it not to write to stderr)
by setting 'opterr' to 0, so there's no need to temporarily redirect
stderr if it's only about the error messages from getopt(). You seem
not to be the first to have had that problem;-)

Thanks a lot for taking your time to reply, Jens. This is exactly what I
needed. I'll use opterr. This is much smarter than what I imagined.
 
M

Martin Ambuhl

Vince said:
Functions getopt() and getopt_long(). They write error messages to stderr
whenever an option is not recognized or there is something wrong with the
command line syntax defined by the application.

Neither getopt() or getopt_long() is a standard C function. It might be
useful for you to review what functions are specific to your
implementation and which are standard C functions. This will have been
a useful exercise if you use what you learn to isolate those
non-standard functions into implementation-specific translation units.
The day that you move out of Bill Gates's empire you will be glad that
you have taken these simple precaution. The day that the next version of
your implementation or of the next update to Windows might also be the
day that you are glad you have isolated those non-standard functions.
 
F

Flash Gordon

Vince C. wrote, On 14/07/07 21:16:
Functions getopt() and getopt_long(). They write error messages to stderr
whenever an option is not recognized or there is something wrong with the
command line syntax defined by the application.

Those are not standard C functions.
It should be basically as simple as initializing device stderr when the
program starts, shouldn't it?

Maybe, maybe not.
> There is code within stdlib that creates an
__iob[2] array of FILE*, each being stdout, stdin and stderr, respectively.

Maybe on your implementations, but it is not required to work like that
else where.
If my programm succeeds in doing the same, i.e. re-initializing stderr with
the default values, the trick is done. So I asked the question if it was
possible.

C provides no mechanism for doing it.
Of course my program is (currently) a Windows application but - while I'm
writing it - I'm building a set of functions that I'll be able to reuse
under whatever platform I want, provided it's running GNU code.

Then ask on a GNU group, although I suspect you will find it depends on
the target platform not on whether you are running GNU code. Unless by
running GNU code you are limiting yourself to systems using the GNU
implementation of the standard C library, which I believe would actually
exclude MinGW and 3/4 of the systems on which I've used gcc.
I'm trying to create a library of functions that basically runs with C++
code but with a base set of C functions. That base set of C functions
should be able to handle multiple command line argument syntaxes, like
argtable2 but much simpler (for my own usage).

If C++ is involved you need to ask else where, we don't deal with it here.
I've read argtable2 uses get_opt() and getopt_long() so is 100% compatible
with GNU getopt() syntax. However if you want multiple command line

argtable2, getopt, get_opt and getopt_long are not standard.

Hence I'd like to temporarily disable stderr while I'm checking command line
parameter syntaxes since I might get error messages, which is the normal
behaviour of these functions.

You can't in standard C.
Yes, I know there is no such iostream in C but iostream uses std* file
descriptors. Hence I suppose I must keep both libraries in sync, i.e. if I
close (or reopen) stderr cerr must be kept in sync so that it "knows" the
stderr file descriptor has changed.

I posted here for it's a C question first. And given the length of this
post, you can easily understand it's a hassle to type it again... ;-)

Ah, so hassle for everyone else is OK but hassle for you is not?
I'd say "no" since the libraries I'm using implement the same code on all
supported platforms (it's GNU code). So it's completely independent from
Windows.

That does not follow. I have used Windows specifics in code written with
MinGW and things which will not run on Windows using gcc and glibc.
> The only difference is there is no /dev/null, as when we redirect
output in shell scripts. I think that device is "nul:" under windows (I
remember batch scripts where I used:

do_something_with_possible_error_messages > nul:

All of which is implementation specific. I've programmed on systems
which had neither /dev/null not nul: (or whatever Windows uses), and no
they were not embedded systems.
The only thing I need to know, I suppose, is how does standard C library
initialize stderr so that I can do the same in my program - provided it's
safe, of course. Hence my question(s)...

The answer is as has already been stated implementation specific. So you
need to ask in system specific groups and accept that the answer may be
completely different for Windows using MinGW to Windows using Cygwin to
Windows to Linux to gcc on AIX 4.x to gcc on AIX 5.3 to gcc on SCO 4.x
to gcc on SCO 5.x to...

One off topic hint is that gcc normally uses whatever the normal C
library is on the implementations, so on most implementations it does
not use the GNU implementation of the standard C library.

Yes, there are important differences between what you can do with gcc on
AIX 4.x and AIX 5.3, I know because I have done both and I could do
things with gcc on AIX 5.3 that I could not on AIX 4.x (or had to do
differently, at any rate).
 
K

Kenny McCormack

I'm not that dumb you know... I just posted enough information so that those
who want to help get the most accurate picture of what I'm trying to do and
on what platform.

Part of the problem is that you mentioned GNU and GNU things like
getopt*, which is, in and of itself, enough to set them off.

However, when you mention the 'W' word, you're really rubbing salt in
their wounds. You can't expect to get away with that.
 
K

Kenny McCormack

Neither getopt() or getopt_long() is a standard C function. It might be
useful for you to review what functions are specific to your
implementation and which are standard C functions. This will have been
a useful exercise if you use what you learn to isolate those
non-standard functions into implementation-specific translation units.
The day that you move out of Bill Gates's empire you will be glad that
you have taken these simple precaution. The day that the next version of
your implementation or of the next update to Windows might also be the
day that you are glad you have isolated those non-standard functions.

It's not like adhering to the standard is going to protect you against
the next version of Windows (or, as you observe, the next service pack,
which is essentially the same thing as "the next version"). MS is under
no obligation to adhere to standards (that they do, to some degree at
least, is more or less an accident).

So, the point is that adherence to standards doesn't get you much,
except acceptance in CLC.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,995
Messages
2,570,230
Members
46,817
Latest member
DicWeils

Latest Threads

Top