PR 46267 strerror thread safety

From-SVN: r169110
This commit is contained in:
Janne Blomqvist 2011-01-22 00:42:17 +02:00
parent 62f9aedcd0
commit 723553bdc1
8 changed files with 74 additions and 29 deletions

View File

@ -1,3 +1,17 @@
2011-01-22 Janne Blomqvist <jb@gcc.gnu.org>
PR libfortran/46267
* config.h.in: Regenerated.
* configure: Regenerated.
* configure.ac: Check presence of strerror_r.
* intrinsics/gerror.c (gerror): Use gf_strerror, modify logic.
* io/unix.c (get_oserror): Remove.
* libgfortran.h (gf_strerror): Add prototype.
(get_oserror): Remove prototype.
* runtime/error.c (gf_strerror): New function.
(os_error): Use gf_strerror instead of get_oserror.
(generate_errror): Likewise.
2011-01-17 Janne Blomqvist <jb@gcc.gnu.org>
PR libfortran/47296

View File

@ -708,6 +708,9 @@
/* Define to 1 if you have the `strerror' function. */
#undef HAVE_STRERROR
/* Define to 1 if you have the `strerror_r' function. */
#undef HAVE_STRERROR_R
/* Define to 1 if you have the <strings.h> header file. */
#undef HAVE_STRINGS_H

View File

@ -15636,7 +15636,7 @@ _ACEOF
fi
done
for ac_func in localtime_r gmtime_r
for ac_func in localtime_r gmtime_r strerror_r
do :
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"

View File

@ -249,7 +249,7 @@ AC_CHECK_FUNCS(chdir strerror getlogin gethostname kill link symlink perror)
AC_CHECK_FUNCS(sleep time ttyname signal alarm ctime clock access fork execl)
AC_CHECK_FUNCS(wait setmode execvp pipe dup2 close fdopen strcasestr getrlimit)
AC_CHECK_FUNCS(gettimeofday stat fstat lstat getpwuid vsnprintf dup getcwd)
AC_CHECK_FUNCS(localtime_r gmtime_r)
AC_CHECK_FUNCS(localtime_r gmtime_r strerror_r)
# Check for glibc backtrace functions
AC_CHECK_FUNCS(backtrace backtrace_symbols)

View File

@ -43,16 +43,17 @@ PREFIX(gerror) (char * msg, gfc_charlen_type msg_len)
int p_len;
char *p;
memset (msg, ' ', msg_len); /* Blank the string. */
p = strerror (errno);
if (p == NULL)
return;
p = gf_strerror (errno, msg, msg_len);
p_len = strlen (p);
if (msg_len < p_len)
memcpy (msg, p, msg_len);
else
memcpy (msg, p, p_len);
/* The returned pointer p might or might not be the same as the msg
argument. */
if (p != msg)
{
if (msg_len < p_len)
p_len = msg_len;
memcpy (msg, p, p_len);
}
if (msg_len > p_len)
memset (&msg[p_len], ' ', msg_len - p_len);
}
#endif

View File

@ -256,16 +256,6 @@ flush_if_preconnected (stream * s)
}
/* get_oserror()-- Get the most recent operating system error. For
* unix, this is errno. */
const char *
get_oserror (void)
{
return strerror (errno);
}
/********************************************************************
Raw I/O functions (read, write, seek, tell, truncate, close).

View File

@ -1,5 +1,6 @@
/* Common declarations for all of libgfortran.
Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
2011
Free Software Foundation, Inc.
Contributed by Paul Brook <paul@nowt.org>, and
Andy Vaught <andy@xena.eas.asu.edu>
@ -738,9 +739,6 @@ extern void internal_error (st_parameter_common *, const char *)
__attribute__ ((noreturn));
internal_proto(internal_error);
extern const char *get_oserror (void);
internal_proto(get_oserror);
extern const char *translate_error (int);
internal_proto(translate_error);
@ -756,6 +754,9 @@ internal_proto(notify_std);
extern notification notification_std(int);
internal_proto(notification_std);
extern char *gf_strerror (int, char *, size_t);
internal_proto(gf_strerror);
/* fpu.c */
extern void set_fpu (void);

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2002, 2003, 2005, 2006, 2007, 2009, 2010
/* Copyright (C) 2002, 2003, 2005, 2006, 2007, 2009, 2010, 2011
Free Software Foundation, Inc.
Contributed by Andy Vaught
@ -141,6 +141,36 @@ gfc_xtoa (GFC_UINTEGER_LARGEST n, char *buffer, size_t len)
return p;
}
/* Hopefully thread-safe wrapper for a strerror_r() style function. */
char *
gf_strerror (int errnum,
char * buf __attribute__((unused)),
size_t buflen __attribute__((unused)))
{
#ifdef HAVE_STRERROR_R
/* TODO: How to prevent the compiler warning due to strerror_r of
the untaken branch having the wrong return type? */
if (__builtin_classify_type (strerror_r (0, buf, 0)) == 5)
{
/* GNU strerror_r() */
return strerror_r (errnum, buf, buflen);
}
else
{
/* POSIX strerror_r () */
strerror_r (errnum, buf, buflen);
return buf;
}
#else
/* strerror () is not necessarily thread-safe, but should at least
be available everywhere. */
return strerror (errnum);
#endif
}
/* show_locus()-- Print a line number and filename describing where
* something went wrong */
@ -192,6 +222,8 @@ recursion_check (void)
}
#define STRERR_MAXSZ 256
/* os_error()-- Operating system error. We get a message from the
* operating system, show it and leave. Some operating system errors
* are caught and processed by the library. If not, we come here. */
@ -199,8 +231,10 @@ recursion_check (void)
void
os_error (const char *message)
{
char errmsg[STRERR_MAXSZ];
recursion_check ();
st_printf ("Operating system error: %s\n%s\n", get_oserror (), message);
st_printf ("Operating system error: %s\n%s\n",
gf_strerror (errno, errmsg, STRERR_MAXSZ), message);
sys_exit (1);
}
iexport(os_error);
@ -389,6 +423,7 @@ translate_error (int code)
void
generate_error (st_parameter_common *cmp, int family, const char *message)
{
char errmsg[STRERR_MAXSZ];
/* If there was a previous error, don't mask it with another
error message, EOF or EOR condition. */
@ -402,7 +437,8 @@ generate_error (st_parameter_common *cmp, int family, const char *message)
if (message == NULL)
message =
(family == LIBERROR_OS) ? get_oserror () : translate_error (family);
(family == LIBERROR_OS) ? gf_strerror (errno, errmsg, STRERR_MAXSZ) :
translate_error (family);
if (cmp->flags & IOPARM_HAS_IOMSG)
cf_strcpy (cmp->iomsg, cmp->iomsg_len, message);