CTRL-C don't close stdout ?

I run an application for which stdout is redirected to a file
(>file.test).
I fwrite() some bytes to stdout so, in the file.
If I kill the program (CTRL-C) the file size is 0.
If, after fwrite(), I fclose(stdout), the file size is correct.

The kernel is supposed to close every file descriptor no?

Is it a normal behaviour?

Thanks,
Alain.

Alain Bonnefoy wrote:

I run an application for which stdout is redirected to a file
(>file.test).
I fwrite() some bytes to stdout so, in the file.
If I kill the program (CTRL-C) the file size is 0.
If, after fwrite(), I fclose(stdout), the file size is correct.

The kernel is supposed to close every file descriptor no?

Is it a normal behaviour?

Thanks,
Alain.

Yes, I believe its “normal” because unless you provide your
own signal handler for SIGINT you end up with abnormal
termination. Under POSIX, abnormal termination does not
require unwritten data to be flushed before a close.

If you intercepted the signal and performed an exit(), this
would cause normal termination and I believe you would see
the data flushed.

Kirk Bailey

“Kirk Bailey” <c23kab@eng.delcoelect.com> wrote in message
news:3C19EF97.447B3C04@eng.delcoelect.com

Alain Bonnefoy wrote:

I run an application for which stdout is redirected to a file
(>file.test).
I fwrite() some bytes to stdout so, in the file.
If I kill the program (CTRL-C) the file size is 0.
If, after fwrite(), I fclose(stdout), the file size is correct.

The kernel is supposed to close every file descriptor no?

Is it a normal behaviour?

Thanks,
Alain.

Yes, I believe its “normal” because unless you provide your
own signal handler for SIGINT you end up with abnormal
termination. Under POSIX, abnormal termination does not
require unwritten data to be flushed before a close.

Or you could set the file descriptor (stdout) to unbuffered mode.

If you intercepted the signal and performed an exit(), this
would cause normal termination and I believe you would see
the data flushed.

Kirk Bailey

Kirk Bailey a écrit :

Alain Bonnefoy wrote:

I run an application for which stdout is redirected to a file
(>file.test).
I fwrite() some bytes to stdout so, in the file.
If I kill the program (CTRL-C) the file size is 0.
If, after fwrite(), I fclose(stdout), the file size is correct.

The kernel is supposed to close every file descriptor no?

Is it a normal behaviour?

Thanks,
Alain.

Yes, I believe its “normal” because unless you provide your
own signal handler for SIGINT you end up with abnormal
termination. Under POSIX, abnormal termination does not
require unwritten data to be flushed before a close.

If you intercepted the signal and performed an exit(), this
would cause normal termination and I believe you would see
the data flushed.

Kirk Bailey

Yeahhhhhhhhhhh, of course, I have to fflush(stdout)!

thanks a lot,
Alain.

Alain Bonnefoy <alain.bonnefoy@icbt.com> wrote:

Kirk Bailey a écrit :
Alain Bonnefoy wrote:

I run an application for which stdout is redirected to a file
(>file.test).
I fwrite() some bytes to stdout so, in the file.
If I kill the program (CTRL-C) the file size is 0.
If, after fwrite(), I fclose(stdout), the file size is correct.

The kernel is supposed to close every file descriptor no?

Is it a normal behaviour?

Yes, I believe its “normal” because unless you provide your
own signal handler for SIGINT you end up with abnormal
termination. Under POSIX, abnormal termination does not
require unwritten data to be flushed before a close.

If you intercepted the signal and performed an exit(), this
would cause normal termination and I believe you would see
the data flushed.

Yeahhhhhhhhhhh, of course, I have to fflush(stdout)!

But remember that neither fflush() nor exit() is signal-safe.


Wojtek Lerch QNX Software Systems Ltd.

Wojtek Lerch a écrit :

Alain Bonnefoy <> alain.bonnefoy@icbt.com> > wrote:
Kirk Bailey a écrit :
Alain Bonnefoy wrote:

I run an application for which stdout is redirected to a file
(>file.test).
I fwrite() some bytes to stdout so, in the file.
If I kill the program (CTRL-C) the file size is 0.
If, after fwrite(), I fclose(stdout), the file size is correct.

The kernel is supposed to close every file descriptor no?

Is it a normal behaviour?

Yes, I believe its “normal” because unless you provide your
own signal handler for SIGINT you end up with abnormal
termination. Under POSIX, abnormal termination does not
require unwritten data to be flushed before a close.

If you intercepted the signal and performed an exit(), this
would cause normal termination and I believe you would see
the data flushed.

Yeahhhhhhhhhhh, of course, I have to fflush(stdout)!

But remember that neither fflush() nor exit() is signal-safe.


Wojtek Lerch QNX Software Systems Ltd.

Ok Wojtek but it’s not a problem in my case as I eventually use it only to
verify a frame format I send to an equipment.

Thanks,
Alain.

Alain Bonnefoy <alain.bonnefoy@icbt.com> wrote:

Kirk Bailey a ecrit :

Alain Bonnefoy wrote:

I run an application for which stdout is redirected to a file
(>file.test).
I fwrite() some bytes to stdout so, in the file.
If I kill the program (CTRL-C) the file size is 0.
If, after fwrite(), I fclose(stdout), the file size is correct.

The kernel is supposed to close every file descriptor no?

Is it a normal behaviour?


Kirk Bailey

Yeahhhhhhhhhhh, of course, I have to fflush(stdout)!

If you’re going to fwrite() then immediately fflush(), why not
just write()?

The only advantage of the FILE functions is for buffering of several
small writes (reads) into one larger one. If you’re flushing the buffer
immediately you aren’t getting anything from the stream i/o, and you’re
costing yourself.

So, why not just use write()?

-David

QNX Training Services
I do not answer technical questions by email.

David Gibbs a écrit :

Alain Bonnefoy <> alain.bonnefoy@icbt.com> > wrote:
Kirk Bailey a ecrit :

Alain Bonnefoy wrote:

I run an application for which stdout is redirected to a file
(>file.test).
I fwrite() some bytes to stdout so, in the file.
If I kill the program (CTRL-C) the file size is 0.
If, after fwrite(), I fclose(stdout), the file size is correct.

The kernel is supposed to close every file descriptor no?

Is it a normal behaviour?


Kirk Bailey

Yeahhhhhhhhhhh, of course, I have to fflush(stdout)!

If you’re going to fwrite() then immediately fflush(), why not
just write()?

The only advantage of the FILE functions is for buffering of several
small writes (reads) into one larger one. If you’re flushing the buffer
immediately you aren’t getting anything from the stream i/o, and you’re
costing yourself.

So, why not just use write()?

-David

QNX Training Services
I do not answer technical questions by email.

Hum well, just because stdout is a FILE * pointer.
But ok, why not use STDOUT_FILENO!

Thanks David.

Alain Bonnefoy <alain.bonnefoy@icbt.com> wrote:

David Gibbs a ecrit :



Hum well, just because stdout is a FILE * pointer.
But ok, why not use STDOUT_FILENO!

True, or you can use 0,1,2. 0 is stdin, 1 is stdout, 2 is stderr. I think
those are pretty well C standard.

-David

QNX Training Services
I do not answer technical questions by email.

David Gibbs <dagibbs@qnx.com> wrote:
: Alain Bonnefoy <alain.bonnefoy@icbt.com> wrote:
:> David Gibbs a ecrit :


:> Hum well, just because stdout is a FILE * pointer.
:> But ok, why not use STDOUT_FILENO!

: True, or you can use 0,1,2. 0 is stdin, 1 is stdout, 2 is stderr. I think
: those are pretty well C standard.

C standard?
I would say Standard in the sense of wellknown.
Do you have chapter and verse handy, of the std?

“David Gibbs” <dagibbs@qnx.com> wrote in message
news:9vnila$e6g$1@nntp.qnx.com

Alain Bonnefoy <> alain.bonnefoy@icbt.com> > wrote:
David Gibbs a ecrit :


Hum well, just because stdout is a FILE * pointer.
But ok, why not use STDOUT_FILENO!

True, or you can use 0,1,2. 0 is stdin, 1 is stdout, 2 is stderr. I
think
those are pretty well C standard.

C standard does define stdin, stdout, stderr. However it doesn’t required
them to be 0,1,2. That’s a UNIX concept.

In fact the C standard doesn’t even include unbuffered function (
open/read/write/close)

-David

QNX Training Services
I do not answer technical questions by email.

“David Gibbs” <dagibbs@qnx.com> wrote in message
news:9vnila$e6g$1@nntp.qnx.com

Alain Bonnefoy <> alain.bonnefoy@icbt.com> > wrote:
David Gibbs a ecrit :

Hum well, just because stdout is a FILE * pointer.
But ok, why not use STDOUT_FILENO!

True, or you can use 0,1,2. 0 is stdin, 1 is stdout, 2 is stderr. I
think
those are pretty well C standard.

I agree that those are very well known numbers. But I like using the

manifest constants just to document what that number represents.


Bill Caroselli – 1(530) 510-7292
Q-TPS Consulting
QTPS@EarthLink.net

“Mario Charest” <mcharest@clipzinformatic.com> wrote in message
news:9vnlbj$sc4$1@inn.qnx.com

“David Gibbs” <> dagibbs@qnx.com> > wrote in message
news:9vnila$e6g$> 1@nntp.qnx.com> …
Alain Bonnefoy <> alain.bonnefoy@icbt.com> > wrote:
David Gibbs a ecrit :


Hum well, just because stdout is a FILE * pointer.
But ok, why not use STDOUT_FILENO!

True, or you can use 0,1,2. 0 is stdin, 1 is stdout, 2 is stderr. I
think
those are pretty well C standard.


C standard does define stdin, stdout, stderr. However it doesn’t required
them to be 0,1,2. That’s a UNIX concept.

In fact the C standard doesn’t even include unbuffered function (
open/read/write/close)

You can use C standard setbuf or setvbuf to turn off buffering, both from
stdio.h.

Tom

Mario Charest a écrit :

“David Gibbs” <> dagibbs@qnx.com> > wrote in message
news:9vnila$e6g$> 1@nntp.qnx.com> …
Alain Bonnefoy <> alain.bonnefoy@icbt.com> > wrote:
David Gibbs a ecrit :


Hum well, just because stdout is a FILE * pointer.
But ok, why not use STDOUT_FILENO!

True, or you can use 0,1,2. 0 is stdin, 1 is stdout, 2 is stderr. I
think
those are pretty well C standard.


C standard does define stdin, stdout, stderr. However it doesn’t required
them to be 0,1,2. That’s a UNIX concept.

In fact the C standard doesn’t even include unbuffered function (
open/read/write/close)

-David

QNX Training Services
I do not answer technical questions by email.

so, I don’t why exactly, but doing fwrite() is not the same as doing write().
In first case, output is not necessarily done in case of abnormal termination
(after return of fwrite() of course!).
In the second case, there is no problem.
Maybe it’s not described in the C standard, but it works like that on QNX6. I
have not enough experience to talk about how that works on other OSes.

Regards,
Alain.

Alain Bonnefoy <alain.bonnefoy@icbt.com> wrote:

so, I don’t why exactly, but doing fwrite() is not the same as doing write().

fwrite() will copy the bytes passed to it into the buffer scheme that
FILE * implies, then IF the buffer is full (or has hit a flush point),
will call write() to send the buffer to the file manager process.

write() will immediately send the data to the file manager process.

fwrite() is client-side buffered I/O. write() is un-buffered on the
client-side. In both cases, the file manager process may buffer (cache)
the data before it hits the hardware. (Some control availabe with things
like O_DYSNC open() flag.)

In first case, output is not necessarily done in case of
abnormal termination (after return of fwrite() of course!).

FILE * buffers are NOT flushed on abnormal termination. They are on
normal termination.

In the second case, there is no problem.
Maybe it’s not described in the C standard, but it works like that on
QNX6. I have not enough experience to talk about how that works on
other OSes.

The above is normal UNIX behaviour. I had encountered it well before
joining QNX… standard gotcha of printf() debugging, want to find where
program is crashing, but getting lots of printfs, so redirect stdout to
a file, and all of a sudden you don’t get the last few printfs before
the program crashes. That was because another normal UNIX behaviour
is that output is line buffered to a terminal (flush on new line) but
“fully” buffered to a file (flush on end of 1024 byte buffer) and doesn’t
flush on abnormal termination.

If you don’t want client-side buffering, don’t use the FILE * calls. They
are less efficient, usually resulting in an extra copy of the data. There
are places where they can be helpful or useful. For instance, you will
get more data onto a flash filesystem if you use larger writes rather than
smaller ones – so if you are generating output for a file on a flash file
system, having your output buffered and delivered in 1k chunks, rather than
as several smaller chunks will make for more efficient storage, without you
having to write the code to do the client-side buffering.

-David

QNX Training Services
I do not answer technical questions by email.

Alain Bonnefoy <alain.bonnefoy@icbt.com> wrote:

so, I don’t why exactly, but doing fwrite() is not the same as doing write().

Of course not – if they were identical, you wouldn’t need both! :wink:

Seriously though, the original reason for having two separate sets of
I/O functions in Unix was efficiency. The overhead of a kernel call (in
Unix) or a message pass (in QNX) is relatively big compared to a memcpy
into a local buffer. Imagine you’re writing in 10-byte chunks to a
filesystem with 512-byte blocks – if you were using write(), the
filesystem would have to actually read most of the file from disk in
order to merge your 10-byte chunk with any old contents of the blocks,
even though you’re about to overwrite the old contents with more 10-byte
chunks!!!

In first case, output is not necessarily done in case of abnormal termination
(after return of fwrite() of course!).

No, because the data still sit in the local buffer, and open streams are
not flushed on an abnormal termination.

In the second case, there is no problem.
Maybe it’s not described in the C standard, but it works like that on QNX6. I
have not enough experience to talk about how that works on other OSes.

It actually is described in the C standard – in pretty vague terms, of
course, because the C standard is trying to be general and does not
assume the existence of things like the write() function. And yes, it
works like that in most other common OSes.


Wojtek Lerch QNX Software Systems Ltd.