Commit 723553bd by Janne Blomqvist

PR 46267 strerror thread safety

From-SVN: r169110
parent 62f9aedc
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
......
......@@ -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
......
......@@ -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"
......
......@@ -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)
......
......@@ -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
......@@ -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).
......
/* 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);
......
/* 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);
......
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