mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-04-15 04:00:26 +08:00
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
This commit is contained in:
parent
9154c66213
commit
68ee9c0807
@ -1,3 +1,8 @@
|
||||
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>
|
||||
|
||||
PR fortran/53175
|
||||
|
@ -576,10 +576,10 @@ environment variables.
|
||||
Malformed environment variables are silently ignored.
|
||||
|
||||
@menu
|
||||
* TMPDIR:: Directory for scratch files
|
||||
* GFORTRAN_STDIN_UNIT:: Unit number for standard input
|
||||
* GFORTRAN_STDOUT_UNIT:: Unit number for standard output
|
||||
* 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_PRECONNECTED:: Do not buffer I/O for preconnected units.
|
||||
* GFORTRAN_SHOW_LOCUS:: Show location for runtime errors
|
||||
@ -590,6 +590,27 @@ Malformed environment variables are silently ignored.
|
||||
* GFORTRAN_ERROR_BACKTRACE:: Show backtrace on run-time errors
|
||||
@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
|
||||
@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
|
||||
preconnected to standard error. This must be a positive integer.
|
||||
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
|
||||
@section @env{GFORTRAN_UNBUFFERED_ALL}---Do not buffer I/O on all units
|
||||
|
||||
|
@ -1,3 +1,18 @@
|
||||
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>
|
||||
|
||||
PR fortran/53051
|
||||
|
@ -426,6 +426,9 @@
|
||||
/* Define to 1 if you have the `getcwd' function. */
|
||||
#undef HAVE_GETCWD
|
||||
|
||||
/* Define to 1 if you have the `getegid' function. */
|
||||
#undef HAVE_GETEGID
|
||||
|
||||
/* Define to 1 if you have the `geteuid' function. */
|
||||
#undef HAVE_GETEUID
|
||||
|
||||
@ -834,6 +837,9 @@
|
||||
/* Define to 1 if you have the `ynl' function. */
|
||||
#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.
|
||||
*/
|
||||
#undef LT_OBJDIR
|
||||
|
10
libgfortran/configure
vendored
10
libgfortran/configure
vendored
@ -2592,6 +2592,8 @@ as_fn_append ac_func_list " getppid"
|
||||
as_fn_append ac_func_list " getuid"
|
||||
as_fn_append ac_func_list " geteuid"
|
||||
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"
|
||||
# Check that the precious variables saved in the cache have kept the same
|
||||
# value.
|
||||
@ -12319,7 +12321,7 @@ else
|
||||
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
|
||||
lt_status=$lt_dlunknown
|
||||
cat > conftest.$ac_ext <<_LT_EOF
|
||||
#line 12322 "configure"
|
||||
#line 12324 "configure"
|
||||
#include "confdefs.h"
|
||||
|
||||
#if HAVE_DLFCN_H
|
||||
@ -12425,7 +12427,7 @@ else
|
||||
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
|
||||
lt_status=$lt_dlunknown
|
||||
cat > conftest.$ac_ext <<_LT_EOF
|
||||
#line 12428 "configure"
|
||||
#line 12430 "configure"
|
||||
#include "confdefs.h"
|
||||
|
||||
#if HAVE_DLFCN_H
|
||||
@ -16531,6 +16533,10 @@ done
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -266,7 +266,7 @@ ftruncate chsize chdir getlogin gethostname kill link symlink sleep ttyname \
|
||||
alarm access fork execl wait setmode execve pipe dup2 close \
|
||||
strcasestr getrlimit gettimeofday stat fstat lstat getpwuid vsnprintf dup \
|
||||
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
|
||||
GCC_CHECK_MATH_FUNC([acosf])
|
||||
|
@ -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;
|
||||
const char *slash = "/";
|
||||
|
||||
#ifndef HAVE_MKSTEMP
|
||||
int count;
|
||||
size_t slashlen;
|
||||
#endif
|
||||
if (!tempdir)
|
||||
return -1;
|
||||
|
||||
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
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
@ -584,10 +584,6 @@ iexport_data_proto(filename);
|
||||
#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
|
||||
here. This value can be overriden by an environment variable.
|
||||
Default value is 1 Gb. */
|
||||
@ -776,6 +772,18 @@ internal_proto(show_variables);
|
||||
unit_convert get_unformatted_convert (int);
|
||||
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 */
|
||||
|
||||
extern int find_option (st_parameter_common *, const char *, gfc_charlen_type,
|
||||
|
@ -56,6 +56,19 @@ 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. */
|
||||
|
||||
static void
|
||||
@ -285,9 +298,8 @@ static variable variable_table[] = {
|
||||
"Unit number that will be preconnected to standard error\n"
|
||||
"(No preconnection if negative)", 0},
|
||||
|
||||
{"GFORTRAN_TMPDIR", 0, NULL, init_string, show_string,
|
||||
"Directory for scratch files. Overrides the TMP environment variable\n"
|
||||
"If TMP is not set " DEFAULT_TEMPDIR " is used.", 0},
|
||||
{"TMPDIR", 0, NULL, init_string, show_string,
|
||||
"Directory for scratch files.", 0},
|
||||
|
||||
{"GFORTRAN_UNBUFFERED_ALL", 0, &options.all_unbuffered, init_boolean,
|
||||
show_boolean,
|
||||
|
@ -163,7 +163,7 @@ find_addr2line (void)
|
||||
{
|
||||
#ifdef HAVE_ACCESS
|
||||
#define A2L_LEN 10
|
||||
char *path = getenv ("PATH");
|
||||
char *path = secure_getenv ("PATH");
|
||||
if (!path)
|
||||
return;
|
||||
size_t n = strlen (path);
|
||||
|
Loading…
x
Reference in New Issue
Block a user