summaryrefslogtreecommitdiffstats
path: root/libgfortran/io/unix.c
diff options
context:
space:
mode:
authorjb <jb@138bc75d-0d04-0410-961f-82ee72b054a4>2012-05-05 06:30:51 +0000
committerjb <jb@138bc75d-0d04-0410-961f-82ee72b054a4>2012-05-05 06:30:51 +0000
commita291e3b6538a0697986d1a7d22aa220829998bab (patch)
treeac63807666eaf2ebc05379c848806981ba536332 /libgfortran/io/unix.c
parente3168f5bde2d4ceb1543c5ea0c779ee66b5f9a02 (diff)
downloadppe42-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.c125
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;
}
OpenPOWER on IntegriCloud