[OT]-ish: Can someone explain this?

2011-07-02 Thread Dirk Koopman

Here is a bit of C code that is part of something much bigger.

#include stdio.h
#include unistd.h

#define GIT_VERSION 1.23-dev
#define GIT_COUNT 73
#define GIT_ID daa3ab8

#define VERSION 1.23

main()
{
	printf(\nThingy version %s (%s-%s-%s) (built %s, %s)\n\n, VERSION, 
GIT_VERSION, GIT_COUNT, GIT_ID, __TIME__, __DATE__);

//  fflush(stdout);
_exit(0);   
}


If one compiles it (cc vtest.c -o vtest) and runs it at a shell prompt, 
one gets:


jim@mike2:~/thingy$ vtest

Thingy version 1.23 (1.23-dev-73-daa3ab8) (built 16:21:49, Jun 30 2011)

jim@mike2:~/thingy$

All is well and seemingly as expected. However now do this:

jim@mike2:~/thingy$ vtest | grep version
jim@mike2:~/thingy$

Stdout appears not to have been have been flushed. Which, after reading 
the man page for _exit is fair enough as it says: The function _exit() 
terminates the calling process immediately.  Any open file descriptors 
belonging to the process are closed. This is, in fact, what is wanted 
in the larger program. This behaviour has only come to light, after 
several years mind, because some (other) poor fool wanted to grab the 
version no for some shell script or other, instead of just checking what 
a user had installed via a shell prompt.


The fix is simply to fflush(stdout), before _exit().

But how come I get output at a shell prompt, and not down a pipe (or a 
redirection either)? What special magic is occurring here?


Dirk






Re: [OT]-ish: Can someone explain this?

2011-07-02 Thread Dominic.Thoreau
It might be because you've got that flush call commented out?

Sent from my iPad

On 2 Jul 2011, at 17:32, Dirk Koopman d...@tobit.co.uk wrote:

 Here is a bit of C code that is part of something much bigger.
 
 #include stdio.h
 #include unistd.h
 
 #define GIT_VERSION 1.23-dev
 #define GIT_COUNT 73
 #define GIT_ID daa3ab8
 
 #define VERSION 1.23
 
 main()
 {
printf(\nThingy version %s (%s-%s-%s) (built %s, %s)\n\n, VERSION, 
 GIT_VERSION, GIT_COUNT, GIT_ID, __TIME__, __DATE__);
 //fflush(stdout);
_exit(0);
 }
 
 
 If one compiles it (cc vtest.c -o vtest) and runs it at a shell prompt, one 
 gets:
 
 jim@mike2:~/thingy$ vtest
 
 Thingy version 1.23 (1.23-dev-73-daa3ab8) (built 16:21:49, Jun 30 2011)
 
 jim@mike2:~/thingy$
 
 All is well and seemingly as expected. However now do this:
 
 jim@mike2:~/thingy$ vtest | grep version
 jim@mike2:~/thingy$
 
 Stdout appears not to have been have been flushed. Which, after reading the 
 man page for _exit is fair enough as it says: The function _exit() 
 terminates the calling process immediately.  Any open file descriptors 
 belonging to the process are closed. This is, in fact, what is wanted in the 
 larger program. This behaviour has only come to light, after several years 
 mind, because some (other) poor fool wanted to grab the version no for some 
 shell script or other, instead of just checking what a user had installed via 
 a shell prompt.
 
 The fix is simply to fflush(stdout), before _exit().
 
 But how come I get output at a shell prompt, and not down a pipe (or a 
 redirection either)? What special magic is occurring here?
 
 Dirk
 
 
 
 



Re: [OT]-ish: Can someone explain this?

2011-07-02 Thread Andrew Suffield
On Sat, Jul 02, 2011 at 05:32:38PM +0100, Dirk Koopman wrote:
 But how come I get output at a shell prompt, and not down a pipe (or
 a redirection either)? What special magic is occurring here?

If:

1. isatty() is true on the underlying fd of the FILE*

and:

2. The string contains \n

then printf calls fflush().

In your first instance, stdout was your terminal, and in the second it
was one end of a pipe.


Re: [OT]-ish: Can someone explain this?

2011-07-02 Thread Randy J. Ray

On 07/02/2011 10:04 AM, Andrew Suffield wrote:

On Sat, Jul 02, 2011 at 05:32:38PM +0100, Dirk Koopman wrote:

But how come I get output at a shell prompt, and not down a pipe (or
a redirection either)? What special magic is occurring here?


If:

1. isatty() is true on the underlying fd of the FILE*

and:

2. The string contains \n

then printf calls fflush().

In your first instance, stdout was your terminal, and in the second it
was one end of a pipe.


That was my first thought, but I wasn't 100% sure. Glad to see I was right, and 
haven't *completely* forgotten my C minutiae...


Randy
--

Randy J. Ray  Sunnyvale, CA  http://www.rjray.org   rj...@blackperl.com
  twitter.com/rjray
Silicon Valley Scale Modelers: http://www.svsm.org