Commit 68ee9c08 by Janne Blomqvist

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.

From-SVN: r187190
parent 9154c662
2012-05-05 Janne Blomqvist <jb@gcc.gnu.org>
* gfortran.texi (GFORTRAN_TMPDIR): Rename to TMPDIR, explain
algorithm for choosing temp directory.
2012-05-04 Tobias Burnus <burnus@net-b.de> 2012-05-04 Tobias Burnus <burnus@net-b.de>
PR fortran/53175 PR fortran/53175
......
...@@ -576,10 +576,10 @@ environment variables. ...@@ -576,10 +576,10 @@ environment variables.
Malformed environment variables are silently ignored. Malformed environment variables are silently ignored.
@menu @menu
* TMPDIR:: Directory for scratch files
* GFORTRAN_STDIN_UNIT:: Unit number for standard input * GFORTRAN_STDIN_UNIT:: Unit number for standard input
* GFORTRAN_STDOUT_UNIT:: Unit number for standard output * GFORTRAN_STDOUT_UNIT:: Unit number for standard output
* GFORTRAN_STDERR_UNIT:: Unit number for standard error * GFORTRAN_STDERR_UNIT:: Unit number for standard error
* GFORTRAN_TMPDIR:: Directory for scratch files
* GFORTRAN_UNBUFFERED_ALL:: Do not buffer I/O for all units. * GFORTRAN_UNBUFFERED_ALL:: Do not buffer I/O for all units.
* GFORTRAN_UNBUFFERED_PRECONNECTED:: Do not buffer I/O for preconnected units. * GFORTRAN_UNBUFFERED_PRECONNECTED:: Do not buffer I/O for preconnected units.
* GFORTRAN_SHOW_LOCUS:: Show location for runtime errors * GFORTRAN_SHOW_LOCUS:: Show location for runtime errors
...@@ -590,6 +590,27 @@ Malformed environment variables are silently ignored. ...@@ -590,6 +590,27 @@ Malformed environment variables are silently ignored.
* GFORTRAN_ERROR_BACKTRACE:: Show backtrace on run-time errors * GFORTRAN_ERROR_BACKTRACE:: Show backtrace on run-time errors
@end menu @end menu
@node TMPDIR
@section @env{TMPDIR}---Directory for scratch files
When opening a file with @code{STATUS='SCRATCH'}, GNU Fortran tries to
create the file in one of the potential directories by testing each
directory in the order below.
@enumerate
@item
The environment variable @env{TMPDIR}, if it exists.
@item
On the MinGW target, the directory returned by the @code{GetTempPath}
function. Alternatively, on the Cygwin target, the @env{TMP} and
@env{TEMP} environment variables, if they exist, in that order.
@item
The @code{P_tmpdir} macro if it is defined, otherwise the directory
@file{/tmp}.
@end enumerate
@node GFORTRAN_STDIN_UNIT @node GFORTRAN_STDIN_UNIT
@section @env{GFORTRAN_STDIN_UNIT}---Unit number for standard input @section @env{GFORTRAN_STDIN_UNIT}---Unit number for standard input
...@@ -611,14 +632,6 @@ This environment variable can be used to select the unit number ...@@ -611,14 +632,6 @@ This environment variable can be used to select the unit number
preconnected to standard error. This must be a positive integer. preconnected to standard error. This must be a positive integer.
The default value is 0. The default value is 0.
@node GFORTRAN_TMPDIR
@section @env{GFORTRAN_TMPDIR}---Directory for scratch files
This environment variable controls where scratch files are
created. If this environment variable is missing,
GNU Fortran searches for the environment variable @env{TMP}, then @env{TEMP}.
If these are missing, the default is @file{/tmp}.
@node GFORTRAN_UNBUFFERED_ALL @node GFORTRAN_UNBUFFERED_ALL
@section @env{GFORTRAN_UNBUFFERED_ALL}---Do not buffer I/O on all units @section @env{GFORTRAN_UNBUFFERED_ALL}---Do not buffer I/O on all units
......
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.
2012-04-22 Tobias Burnus <burnus@net-b.de> 2012-04-22 Tobias Burnus <burnus@net-b.de>
PR fortran/53051 PR fortran/53051
......
...@@ -426,6 +426,9 @@ ...@@ -426,6 +426,9 @@
/* Define to 1 if you have the `getcwd' function. */ /* Define to 1 if you have the `getcwd' function. */
#undef HAVE_GETCWD #undef HAVE_GETCWD
/* Define to 1 if you have the `getegid' function. */
#undef HAVE_GETEGID
/* Define to 1 if you have the `geteuid' function. */ /* Define to 1 if you have the `geteuid' function. */
#undef HAVE_GETEUID #undef HAVE_GETEUID
...@@ -834,6 +837,9 @@ ...@@ -834,6 +837,9 @@
/* Define to 1 if you have the `ynl' function. */ /* Define to 1 if you have the `ynl' function. */
#undef HAVE_YNL #undef HAVE_YNL
/* Define to 1 if you have the `__secure_getenv' function. */
#undef HAVE___SECURE_GETENV
/* Define to the sub-directory in which libtool stores uninstalled libraries. /* Define to the sub-directory in which libtool stores uninstalled libraries.
*/ */
#undef LT_OBJDIR #undef LT_OBJDIR
......
...@@ -2592,6 +2592,8 @@ as_fn_append ac_func_list " getppid" ...@@ -2592,6 +2592,8 @@ as_fn_append ac_func_list " getppid"
as_fn_append ac_func_list " getuid" as_fn_append ac_func_list " getuid"
as_fn_append ac_func_list " geteuid" as_fn_append ac_func_list " geteuid"
as_fn_append ac_func_list " umask" as_fn_append ac_func_list " umask"
as_fn_append ac_func_list " getegid"
as_fn_append ac_func_list " __secure_getenv"
as_fn_append ac_header_list " math.h" as_fn_append ac_header_list " math.h"
# Check that the precious variables saved in the cache have kept the same # Check that the precious variables saved in the cache have kept the same
# value. # value.
...@@ -12319,7 +12321,7 @@ else ...@@ -12319,7 +12321,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF cat > conftest.$ac_ext <<_LT_EOF
#line 12322 "configure" #line 12324 "configure"
#include "confdefs.h" #include "confdefs.h"
#if HAVE_DLFCN_H #if HAVE_DLFCN_H
...@@ -12425,7 +12427,7 @@ else ...@@ -12425,7 +12427,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF cat > conftest.$ac_ext <<_LT_EOF
#line 12428 "configure" #line 12430 "configure"
#include "confdefs.h" #include "confdefs.h"
#if HAVE_DLFCN_H #if HAVE_DLFCN_H
...@@ -16536,6 +16538,10 @@ done ...@@ -16536,6 +16538,10 @@ done
# Check for C99 (and other IEEE) math functions # Check for C99 (and other IEEE) math functions
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sin in -lm" >&5 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sin in -lm" >&5
$as_echo_n "checking for sin in -lm... " >&6; } $as_echo_n "checking for sin in -lm... " >&6; }
......
...@@ -266,7 +266,7 @@ ftruncate chsize chdir getlogin gethostname kill link symlink sleep ttyname \ ...@@ -266,7 +266,7 @@ ftruncate chsize chdir getlogin gethostname kill link symlink sleep ttyname \
alarm access fork execl wait setmode execve pipe dup2 close \ alarm access fork execl wait setmode execve pipe dup2 close \
strcasestr getrlimit gettimeofday stat fstat lstat getpwuid vsnprintf dup \ strcasestr getrlimit gettimeofday stat fstat lstat getpwuid vsnprintf dup \
getcwd localtime_r gmtime_r strerror_r getpwuid_r ttyname_r clock_gettime \ getcwd localtime_r gmtime_r strerror_r getpwuid_r ttyname_r clock_gettime \
readlink getgid getpid getppid getuid geteuid umask) readlink getgid getpid getppid getuid geteuid umask getegid __secure_getenv)
# Check for C99 (and other IEEE) math functions # Check for C99 (and other IEEE) math functions
GCC_CHECK_MATH_FUNC([acosf]) GCC_CHECK_MATH_FUNC([acosf])
......
...@@ -176,6 +176,17 @@ fallback_access (const char *path, int mode) ...@@ -176,6 +176,17 @@ fallback_access (const char *path, int mode)
#endif #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 */ /* Unix and internal stream I/O module */
static const int BUFFER_SIZE = 8192; static const int BUFFER_SIZE = 8192;
...@@ -1026,54 +1037,23 @@ unpack_filename (char *cstring, const char *fstring, int len) ...@@ -1026,54 +1037,23 @@ unpack_filename (char *cstring, const char *fstring, int len)
} }
/* tempfile()-- Generate a temporary filename for a scratch file and /* Helper function for tempfile(). Tries to open a temporary file in
* open it. mkstemp() opens the file for reading and writing, but the the directory specified by tempdir. If successful, the file name is
* library mode prevents anything that is not allowed. The descriptor stored in fname and the descriptor returned. Returns -1 on
* is returned, which is -1 on error. The template is pointed to by failure. */
* opp->file, which is copied into the unit structure
* and freed later. */
static int static int
tempfile (st_parameter_open *opp) tempfile_open (const char *tempdir, char **fname)
{ {
const char *tempdir;
char *template;
const char *slash = "/";
int fd; int fd;
size_t tempdirlen; const char *slash = "/";
#ifndef HAVE_MKSTEMP
int count;
size_t slashlen;
#endif
tempdir = getenv ("GFORTRAN_TMPDIR"); if (!tempdir)
#ifdef __MINGW32__ return -1;
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
/* Check for special case that tempdir contains slash /* Check for the special case that tempdir ends with a slash or
or backslash at end. */ backslash. */
tempdirlen = strlen (tempdir); size_t tempdirlen = strlen (tempdir);
if (*tempdir == 0 || tempdir[tempdirlen - 1] == '/' if (*tempdir == 0 || tempdir[tempdirlen - 1] == '/'
#ifdef __MINGW32__ #ifdef __MINGW32__
|| tempdir[tempdirlen - 1] == '\\' || tempdir[tempdirlen - 1] == '\\'
...@@ -1082,7 +1062,7 @@ tempfile (st_parameter_open *opp) ...@@ -1082,7 +1062,7 @@ tempfile (st_parameter_open *opp)
slash = ""; slash = "";
// Take care that the template is longer in the mktemp() branch. // Take care that the template is longer in the mktemp() branch.
template = xmalloc (tempdirlen + 23); char * template = xmalloc (tempdirlen + 23);
#ifdef HAVE_MKSTEMP #ifdef HAVE_MKSTEMP
snprintf (template, tempdirlen + 23, "%s%sgfortrantmpXXXXXX", snprintf (template, tempdirlen + 23, "%s%sgfortrantmpXXXXXX",
...@@ -1092,8 +1072,8 @@ tempfile (st_parameter_open *opp) ...@@ -1092,8 +1072,8 @@ tempfile (st_parameter_open *opp)
#else /* HAVE_MKSTEMP */ #else /* HAVE_MKSTEMP */
fd = -1; fd = -1;
count = 0; int count = 0;
slashlen = strlen (slash); size_t slashlen = strlen (slash);
do do
{ {
snprintf (template, tempdirlen + 23, "%s%sgfortrantmpaaaXXXXXX", snprintf (template, tempdirlen + 23, "%s%sgfortrantmpaaaXXXXXX",
...@@ -1127,8 +1107,59 @@ tempfile (st_parameter_open *opp) ...@@ -1127,8 +1107,59 @@ tempfile (st_parameter_open *opp)
while (fd == -1 && errno == EEXIST); while (fd == -1 && errno == EEXIST);
#endif /* HAVE_MKSTEMP */ #endif /* HAVE_MKSTEMP */
opp->file = template; *fname = template;
opp->file_len = strlen (template); /* Don't include trailing nul */ 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; return fd;
} }
......
...@@ -584,10 +584,6 @@ iexport_data_proto(filename); ...@@ -584,10 +584,6 @@ iexport_data_proto(filename);
#define gfc_alloca(x) __builtin_alloca(x) #define gfc_alloca(x) __builtin_alloca(x)
/* Directory for creating temporary files. Only used when none of the
following environment variables exist: GFORTRAN_TMPDIR, TMP and TEMP. */
#define DEFAULT_TEMPDIR "/tmp"
/* The default value of record length for preconnected units is defined /* The default value of record length for preconnected units is defined
here. This value can be overriden by an environment variable. here. This value can be overriden by an environment variable.
Default value is 1 Gb. */ Default value is 1 Gb. */
...@@ -776,6 +772,18 @@ internal_proto(show_variables); ...@@ -776,6 +772,18 @@ internal_proto(show_variables);
unit_convert get_unformatted_convert (int); unit_convert get_unformatted_convert (int);
internal_proto(get_unformatted_convert); internal_proto(get_unformatted_convert);
/* Secure getenv() which returns NULL if running as SUID/SGID. */
#ifdef HAVE___SECURE_GETENV
#define secure_getenv __secure_getenv
#elif defined(HAVE_GETUID) && defined(HAVE_GETEUID) \
&& defined(HAVE_GETGID) && defined(HAVE_GETEGID)
#define FALLBACK_SECURE_GETENV
extern char *secure_getenv (const char *);
internal_proto(secure_getenv);
#else
#define secure_getenv getenv
#endif
/* string.c */ /* string.c */
extern int find_option (st_parameter_common *, const char *, gfc_charlen_type, extern int find_option (st_parameter_common *, const char *, gfc_charlen_type,
......
...@@ -56,6 +56,19 @@ variable; ...@@ -56,6 +56,19 @@ variable;
static void init_unformatted (variable *); static void init_unformatted (variable *);
#ifdef FALLBACK_SECURE_GETENV
char *
secure_getenv (const char *name)
{
if ((getuid () == geteuid ()) && (getgid () == getegid ()))
return getenv (name);
else
return NULL;
}
#endif
/* print_spaces()-- Print a particular number of spaces. */ /* print_spaces()-- Print a particular number of spaces. */
static void static void
...@@ -285,9 +298,8 @@ static variable variable_table[] = { ...@@ -285,9 +298,8 @@ static variable variable_table[] = {
"Unit number that will be preconnected to standard error\n" "Unit number that will be preconnected to standard error\n"
"(No preconnection if negative)", 0}, "(No preconnection if negative)", 0},
{"GFORTRAN_TMPDIR", 0, NULL, init_string, show_string, {"TMPDIR", 0, NULL, init_string, show_string,
"Directory for scratch files. Overrides the TMP environment variable\n" "Directory for scratch files.", 0},
"If TMP is not set " DEFAULT_TEMPDIR " is used.", 0},
{"GFORTRAN_UNBUFFERED_ALL", 0, &options.all_unbuffered, init_boolean, {"GFORTRAN_UNBUFFERED_ALL", 0, &options.all_unbuffered, init_boolean,
show_boolean, show_boolean,
......
...@@ -163,7 +163,7 @@ find_addr2line (void) ...@@ -163,7 +163,7 @@ find_addr2line (void)
{ {
#ifdef HAVE_ACCESS #ifdef HAVE_ACCESS
#define A2L_LEN 10 #define A2L_LEN 10
char *path = getenv ("PATH"); char *path = secure_getenv ("PATH");
if (!path) if (!path)
return; return;
size_t n = strlen (path); size_t n = strlen (path);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment