www.delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp-workers/1997/06/09/06:58:52

Date: Mon, 9 Jun 1997 13:58:28 +0300 (IDT)
From: Eli Zaretskii <eliz AT is DOT elta DOT co DOT il>
To: djgpp-workers AT delorie DOT com
Subject: Bug in `popen'
Message-ID: <Pine.SUN.3.91.970609135234.618K-100000@is>
MIME-Version: 1.0

There is a bug in `popen': it generates a temporary filename using 
`tmpnam', but then attaches an extension to the generated name.  
Therefore, the uniqueness of the name is not guaranteed.  Moreover, it 
only calls `tmpnam' once, and relies on the unique extension to do the 
rest.  But this fails in a nested program when the parent has a `popen' 
call in progress, and the child also calls `popen': the child will 
generate the same name, fail to see that it is already used, and 
overwrite the parent's temp file.

Another situation is when you happen to have a file named `dj100000.0' 
(the first name generated by `popen') in your $TMPDIR.

Here's the necessary patch.

*** src/libc/posix/stdio/popen.c~0	Thu Jun 13 03:44:36 1996
--- src/libc/posix/stdio/popen.c	Mon Jun  9 09:45:04 1997
***************
*** 1,3 ****
--- 1,4 ----
+ /* Copyright (C) 1997 DJ Delorie, see COPYING.DJ for details */
  /* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
  /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
  /*
***************
*** 63,69 ****
  struct pipe_list {
    FILE *fp;
    int fd;
!   char *command, mode[10], temp_name[FILENAME_MAX];
    struct pipe_list *next;
  };
  
--- 64,70 ----
  struct pipe_list {
    FILE *fp;
    int fd;
!   char *command, mode[10], temp_name[L_tmpnam];
    struct pipe_list *next;
  };
  
*************** FILE *
*** 74,84 ****
  popen (const char *cm, const char *md) /* program name, pipe mode */
  {
    struct pipe_list *l1, *l2;
-   static char *tn = NULL;       /* temporary file basename */
- 
-   if (!tn)
-     if ((tn = tmpnam(0)) == NULL)
-       return NULL;
  
    /* make new node */
    if ((l1 = (struct pipe_list *) malloc (sizeof (struct pipe_list))) == NULL)
--- 75,80 ----
*************** popen (const char *cm, const char *md) /
*** 108,114 ****
  
    /* stick in elements we know already */
    strcpy (l1->mode, md);
!   sprintf (l1->temp_name, "%s.%d", tn, l1->fd);
  
    /* if can save the program name, build temp file */
    if ((l1->command = malloc(strlen(cm)+1)))
--- 104,111 ----
  
    /* stick in elements we know already */
    strcpy (l1->mode, md);
!   if (tmpnam (l1->temp_name) == NULL)
!     return NULL;
  
    /* if can save the program name, build temp file */
    if ((l1->command = malloc(strlen(cm)+1)))

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019