]> gcc.gnu.org Git - gcc.git/commitdiff
PR 46267 strerror thread safety
authorJanne Blomqvist <jb@gcc.gnu.org>
Fri, 21 Jan 2011 22:42:17 +0000 (00:42 +0200)
committerJanne Blomqvist <jb@gcc.gnu.org>
Fri, 21 Jan 2011 22:42:17 +0000 (00:42 +0200)
From-SVN: r169110

libgfortran/ChangeLog
libgfortran/config.h.in
libgfortran/configure
libgfortran/configure.ac
libgfortran/intrinsics/gerror.c
libgfortran/io/unix.c
libgfortran/libgfortran.h
libgfortran/runtime/error.c

index cab2d1501e0ab5a62aa3a04792202e25c5755174..6aa03e640eac5b0806d56d2062848db56fe5451a 100644 (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
index bd6db109c63d72e57214c5ac4654e5a1be73eed3..c5a2d8a1dc111a19f262786f061e4eda18d9e2fa 100644 (file)
 /* 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
 
index b8f0a7174a9ebfdfc11b2c219762f368bf6011a8..ec63cdb1e9109f320946816daa16a1f38f2f5a18 100755 (executable)
@@ -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"
index 7b28f12743395f347864ea1451b37c29fb04ccbd..4f137e43253f33b03a92b38f440d725a3c6221c3 100644 (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)
index ccb5c3efd415128b155b50af91d610f772549011..6feadc9b7c74f6446de0876cc50a29e3b7674bc8 100644 (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
index fa64e20b02662b2f28284059d659cb576bbad0f6..950b7a25b1faf23a416a913185104af9f5a2493a 100644 (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).
 
index ac8649235aea3484edddbef29c56d0fdfbe4c73b..c9d3f371eabe9e08921dae8d66e71e0edde32839 100644 (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);
index 1baf9d35d1ff4c12074bce066ce15feeb0334417..06c144ae153e2916f50fc9529700573daa5e8206 100644 (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);
This page took 0.093413 seconds and 5 git commands to generate.