Question

Test platform is 32 bit x64 Linux, coreutils 8.5.

In the source code of base64, fwrite will use stdout to output the base64 encoded string

  1. When I use ltrace to print all the libc call, we can see that stdout is equal to 0xb772da20

    __libc_start_main(0x8048eb0, 2, 0xbf892f74, 0x804cb50, 0x804cbc0 <unfinished ...>
    
    strrchr("base64", '/')                                                         = NULL
    setlocale(6, "")                                                               = "en_US.UTF-8"
    bindtextdomain("coreutils", "/usr/share/locale")                               =      "/usr/share/locale"
    textdomain("coreutils")                                                        = "coreutils"
    __cxa_atexit(0x804a3b0, 0, 0, 0xbf892f74, 2)                                   = 0
    getopt_long(2, 0xbf892f74, "diw:", 0x0804d1a0, NULL)                           = -1
    fopen64("testbase64", "rb")                                                    = 0x8591878
    fileno(0x8591878)                                                              = 3
    posix_fadvise64(3, 0, 0, 0, 0)                                                 = 0
    fread_unlocked(0xbf89225c, 1, 3072, 0x8591878)                                 = 900
    fwrite_unlocked("Ly8gcXVpY2tTb3J0LmMKI2luY2x1ZGUg"..., 1, 76, 0xb772da20)      = 76
    
  2. When I modify the code of base64 like this:

    int main (int argc, char **argv)
    {
    
      printf("%p \n", stdout);
      int opt;
      FILE *input_fh;
      const char *infile;
      .....
    

The output is still 0xb772da20 , it is strange to me as this is the first line of base64.c.

I grep in the lib folder of coreutils

grep stdout *.h

and I don't see any predefine of stdout.

Could anyone give me some help about why stdout will be defined as "0xb772da20" , not 1, not 0?

Was it helpful?

Solution

According to stdout(3), the stdout is a pointer (to some FILE opaque structure), because it is a file stream. It is not a file descriptor. Its file descriptor is STDOUT_FILENO which indeed is 1.

On my Gnu libc Linux system, I have near line 169 of /usr/include/stdio.h :

/* Standard streams.  */
extern struct _IO_FILE *stdin;      /* Standard input stream.  */
extern struct _IO_FILE *stdout;     /* Standard output stream.  */
extern struct _IO_FILE *stderr;     /* Standard error output stream.  */
/* C89/C99 say they're macros.  Make them happy.  */
#define stdin stdin
#define stdout stdout
#define stderr stderr

Before that (line 48) there is

typedef struct _IO_FILE FILE;

See also this answer to a related question.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top