Mail Archives: djgpp-workers/1997/06/09/06:58:52
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 -