diff options
author | jb <jb@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-05-05 06:30:51 +0000 |
---|---|---|
committer | jb <jb@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-05-05 06:30:51 +0000 |
commit | a291e3b6538a0697986d1a7d22aa220829998bab (patch) | |
tree | ac63807666eaf2ebc05379c848806981ba536332 /libgfortran/io/unix.c | |
parent | e3168f5bde2d4ceb1543c5ea0c779ee66b5f9a02 (diff) | |
download | ppe42-gcc-a291e3b6538a0697986d1a7d22aa220829998bab.tar.gz ppe42-gcc-a291e3b6538a0697986d1a7d22aa220829998bab.zip |
Fix handling of temporary files.
2012-05-05 Janne Blomqvist <jb@gcc.gnu.org>
* gfortran.texi (GFORTRAN_TMPDIR): Rename to TMPDIR, explain
algorithm for choosing temp directory.
2012-05-05 Janne Blomqvist <jb@gcc.gnu.org>
* config.h.in: Regenerated.
* configure: Regenerated.
* configure.ac: Add checks for getegid and __secure_getenv.
* io/unix.c (P_tmpdir): Fallback definition for macro.
(tempfile_open): New function.
(tempfile): Use secure_getenv, call tempfile_open to try each
directory in turn.
* libgfortran.h (DEFAULT_TMPDIR): Remove macro.
(secure_getenv): New macro/prototype.
* runtime/environ.c (secure_getenv): New function.
(variable_table): Rename GFORTRAN_TMPDIR to TMPDIR.
* runtime/main.c (find_addr2line): Use secure_getenv.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@187190 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libgfortran/io/unix.c')
-rw-r--r-- | libgfortran/io/unix.c | 125 |
1 files changed, 78 insertions, 47 deletions
diff --git a/libgfortran/io/unix.c b/libgfortran/io/unix.c index 185936f109d..c81163f2563 100644 --- a/libgfortran/io/unix.c +++ b/libgfortran/io/unix.c @@ -176,6 +176,17 @@ fallback_access (const char *path, int mode) #endif +/* Fallback directory for creating temporary files. P_tmpdir is + defined on many POSIX platforms. */ +#ifndef P_tmpdir +#ifdef _P_tmpdir +#define P_tmpdir _P_tmpdir /* MinGW */ +#else +#define P_tmpdir "/tmp" +#endif +#endif + + /* Unix and internal stream I/O module */ static const int BUFFER_SIZE = 8192; @@ -1026,54 +1037,23 @@ unpack_filename (char *cstring, const char *fstring, int len) } -/* tempfile()-- Generate a temporary filename for a scratch file and - * open it. mkstemp() opens the file for reading and writing, but the - * library mode prevents anything that is not allowed. The descriptor - * is returned, which is -1 on error. The template is pointed to by - * opp->file, which is copied into the unit structure - * and freed later. */ +/* Helper function for tempfile(). Tries to open a temporary file in + the directory specified by tempdir. If successful, the file name is + stored in fname and the descriptor returned. Returns -1 on + failure. */ static int -tempfile (st_parameter_open *opp) +tempfile_open (const char *tempdir, char **fname) { - const char *tempdir; - char *template; - const char *slash = "/"; int fd; - size_t tempdirlen; - -#ifndef HAVE_MKSTEMP - int count; - size_t slashlen; -#endif + const char *slash = "/"; - tempdir = getenv ("GFORTRAN_TMPDIR"); -#ifdef __MINGW32__ - if (tempdir == NULL) - { - char buffer[MAX_PATH + 1]; - DWORD ret; - ret = GetTempPath (MAX_PATH, buffer); - /* If we are not able to get a temp-directory, we use - current directory. */ - if (ret > MAX_PATH || !ret) - buffer[0] = 0; - else - buffer[ret] = 0; - tempdir = strdup (buffer); - } -#else - if (tempdir == NULL) - tempdir = getenv ("TMP"); - if (tempdir == NULL) - tempdir = getenv ("TEMP"); - if (tempdir == NULL) - tempdir = DEFAULT_TEMPDIR; -#endif + if (!tempdir) + return -1; - /* Check for special case that tempdir contains slash - or backslash at end. */ - tempdirlen = strlen (tempdir); + /* Check for the special case that tempdir ends with a slash or + backslash. */ + size_t tempdirlen = strlen (tempdir); if (*tempdir == 0 || tempdir[tempdirlen - 1] == '/' #ifdef __MINGW32__ || tempdir[tempdirlen - 1] == '\\' @@ -1082,7 +1062,7 @@ tempfile (st_parameter_open *opp) slash = ""; // Take care that the template is longer in the mktemp() branch. - template = xmalloc (tempdirlen + 23); + char * template = xmalloc (tempdirlen + 23); #ifdef HAVE_MKSTEMP snprintf (template, tempdirlen + 23, "%s%sgfortrantmpXXXXXX", @@ -1092,8 +1072,8 @@ tempfile (st_parameter_open *opp) #else /* HAVE_MKSTEMP */ fd = -1; - count = 0; - slashlen = strlen (slash); + int count = 0; + size_t slashlen = strlen (slash); do { snprintf (template, tempdirlen + 23, "%s%sgfortrantmpaaaXXXXXX", @@ -1127,8 +1107,59 @@ tempfile (st_parameter_open *opp) while (fd == -1 && errno == EEXIST); #endif /* HAVE_MKSTEMP */ - opp->file = template; - opp->file_len = strlen (template); /* Don't include trailing nul */ + *fname = template; + return fd; +} + + +/* tempfile()-- Generate a temporary filename for a scratch file and + * open it. mkstemp() opens the file for reading and writing, but the + * library mode prevents anything that is not allowed. The descriptor + * is returned, which is -1 on error. The template is pointed to by + * opp->file, which is copied into the unit structure + * and freed later. */ + +static int +tempfile (st_parameter_open *opp) +{ + const char *tempdir; + char *fname; + int fd = -1; + + tempdir = secure_getenv ("TMPDIR"); + fd = tempfile_open (tempdir, &fname); +#ifdef __MINGW32__ + if (fd == -1) + { + char buffer[MAX_PATH + 1]; + DWORD ret; + ret = GetTempPath (MAX_PATH, buffer); + /* If we are not able to get a temp-directory, we use + current directory. */ + if (ret > MAX_PATH || !ret) + buffer[0] = 0; + else + buffer[ret] = 0; + tempdir = strdup (buffer); + fd = tempfile_open (tempdir, &fname); + } +#elif defined(__CYGWIN__) + if (fd == -1) + { + tempdir = secure_getenv ("TMP"); + fd = tempfile_open (tempdir, &fname); + } + if (fd == -1) + { + tempdir = secure_getenv ("TEMP"); + fd = tempfile_open (tempdir, &fname); + } +#endif + if (fd == -1) + fd = tempfile_open (P_tmpdir, &fname); + + opp->file = fname; + opp->file_len = strlen (fname); /* Don't include trailing nul */ return fd; } |