Bug 36381 - freopen of /dev/stdout fails because it can't find /dev/stdout which is a link to /dev/pts/0
freopen of /dev/stdout fails because it can't find /dev/stdout which is a lin...
Status: CLOSED NOTABUG
Product: Red Hat Linux
Classification: Retired
Component: glibc (Show other bugs)
7.0
i386 Linux
medium Severity medium
: ---
: ---
Assigned To: Jakub Jelinek
Aaron Brown
:
Depends On:
Blocks:
  Show dependency treegraph
 
Reported: 2001-04-17 19:42 EDT by Jeffrey Dwoskin
Modified: 2016-11-24 10:02 EST (History)
1 user (show)

See Also:
Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of:
Environment:
Last Closed: 2001-04-17 19:42:32 EDT
Type: ---
Regression: ---
Mount Type: ---
Documentation: ---
CRM:
Verified Versions:
Category: ---
oVirt Team: ---
RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: ---


Attachments (Terms of Use)

  None (edit)
Description Jeffrey Dwoskin 2001-04-17 19:42:29 EDT
From Bugzilla Helper:
User-Agent: Mozilla/4.76 [en] (Win95; U)


When stdout has been redirected, and you try to set it back to the normal output using freopen("/dev/stdout", "w", stdout), an error is returned 
saying that /dev/stdout could not be found. /dev/stdout is a link ( /dev/stdout -> ../proc/self/fd/1 -> /dev/pts/0 ). If instead I run
 freopen(" /dev/pts/0", "w", stdout) it works fine. 

Reproducible: Always
Steps to Reproduce: Run the following c program:
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int main()
{
  char *buf;
  long maxlen;
  int myfile;
      
  maxlen = pathconf("/dev", _PC_PATH_MAX) + pathconf("/dev/stdout", _PC_NAME_MAX); 
  
  buf =(char*)malloc(maxlen+1);
  
  strncpy(buf, "/dev/stdout", strlen("/dev/stdout")+1);

  freopen ("/tmp/jeff", "w", stdout);
  printf ("testing...to /tmp/jeff\n");

  myfile = open(buf, O_WRONLY);
  stdout = fdopen(myfile, "w");
  
  printf("testing to stdout\n");
  exit(0);
  
}

Actual Results:  "testing...to /tmp/jeff" gets written to /tmp/jeff, but "testing to stdout" gets lost

Expected Results:  "testing to stdout" should have been printed to the terminal

If I change the following line:
    strncpy(buf, "/dev/stdout", strlen("/dev/stdout")+1);
to:
 strncpy(buf, "/dev/pts/0", strlen("/dev/pts/0")+1);

then it works fine
Comment 1 Jakub Jelinek 2001-04-18 03:36:50 EDT
This program is flawed. /dev/stdout is your stdout at the point when you access
it, ie. it is say /dev/pts/0 at the beginning of the program, but
after the freopen it is /tmp/jeff, so you are basically opening /tmp/jeff
once again and writing into the same file using 2 different file descriptors.
As both are buffered and you did not use freopen in the second case (ie.
stdout pointing to /tmp/jeff was not closed first), you cannot rely on which
stream will be closed first on shutdown (and thus which write will be first
and which one will be second).
I'd suggest you either to dup the stdout fileno before doing freopen and
fclose/fdopen it afterwards, or readlink twice before doing the freopen
and then open that. Be aware that using /dev/stdout is not too portable.

Note You need to log in before you can comment on or make changes to this bug.