Bug 36381 - freopen of /dev/stdout fails because it can't find /dev/stdout which is a link to /dev/pts/0
Summary: freopen of /dev/stdout fails because it can't find /dev/stdout which is a lin...
Keywords:
Status: CLOSED NOTABUG
Alias: None
Product: Red Hat Linux
Classification: Retired
Component: glibc
Version: 7.0
Hardware: i386
OS: Linux
medium
medium
Target Milestone: ---
Assignee: Jakub Jelinek
QA Contact: Aaron Brown
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2001-04-17 23:42 UTC by Jeffrey Dwoskin
Modified: 2016-11-24 15:02 UTC (History)
1 user (show)

Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Clone Of:
Environment:
Last Closed: 2001-04-17 23:42:32 UTC
Embargoed:


Attachments (Terms of Use)

Description Jeffrey Dwoskin 2001-04-17 23:42:29 UTC
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 07:36:50 UTC
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.