Patchwork [libfortran] PR 47431 Thread-safe ctime/fdate intrinsics

login
register
mail settings
Submitter Janne Blomqvist
Date Jan. 25, 2011, 6:16 p.m.
Message ID <AANLkTik4zz1K5gnFGp6_rn-wwKJOM3=StwtUgt0R-hU6@mail.gmail.com>
Download mbox | patch
Permalink /patch/80393/
State New
Headers show

Comments

Janne Blomqvist - Jan. 25, 2011, 6:16 p.m.
Hi,

the attached patch makes the ctime and fdate intrinsics thread-safe by
using ctime_r() if available.

Regtested on x86_64-unknown-linux-gnu, Ok for trunk?

2011-01-25  Janne Blomqvist  <jb@gcc.gnu.org>

	PR libfortran/47431
	* config.h.in: Regenerated.
	* configure: Regenerated.
	* configure.ac: Add check for ctime_r().
	* intrinsics/ctime.c (ctime_r): Fallback implementation.
	(fdate): Use ctime_r() instead of ctime().
	(fdate_sub): Likewise.
	(ctime): Likewise.
	(ctime_sub): Likewise.
Tobias Burnus - Jan. 27, 2011, 6:53 p.m.
On 01/25/2011 07:16 PM, Janne Blomqvist wrote:
> the attached patch makes the ctime and fdate intrinsics thread-safe by
> using ctime_r() if available.
>
> Regtested on x86_64-unknown-linux-gnu, Ok for trunk?
OK. Thanks for the patch. Do not forget the follow up bit of the patch.

Tobias

PS: I think PR 47491 and PR 47375 can be closed as fixed.

> 2011-01-25  Janne Blomqvist<jb@gcc.gnu.org>
>
> 	PR libfortran/47431
> 	* config.h.in: Regenerated.
> 	* configure: Regenerated.
> 	* configure.ac: Add check for ctime_r().
> 	* intrinsics/ctime.c (ctime_r): Fallback implementation.
> 	(fdate): Use ctime_r() instead of ctime().
> 	(fdate_sub): Likewise.
> 	(ctime): Likewise.
> 	(ctime_sub): Likewise.
>
>

Patch

diff --git a/libgfortran/configure.ac b/libgfortran/configure.ac
index 4f137e4..29f2e4f 100644
--- a/libgfortran/configure.ac
+++ b/libgfortran/configure.ac
@@ -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 strerror_r)
+AC_CHECK_FUNCS(localtime_r gmtime_r strerror_r ctime_r)
 
 # Check for glibc backtrace functions
 AC_CHECK_FUNCS(backtrace backtrace_symbols)
diff --git a/libgfortran/intrinsics/ctime.c b/libgfortran/intrinsics/ctime.c
index 98bf29d..e3e4984 100644
--- a/libgfortran/intrinsics/ctime.c
+++ b/libgfortran/intrinsics/ctime.c
@@ -1,8 +1,8 @@ 
 /* Implementation of the CTIME and FDATE g77 intrinsics.
-   Copyright (C) 2005, 2007, 2009 Free Software Foundation, Inc.
+   Copyright (C) 2005, 2007, 2009, 2011 Free Software Foundation, Inc.
    Contributed by Fran├žois-Xavier Coudert <coudert@clipper.ens.fr>
 
-This file is part of the GNU Fortran 95 runtime library (libgfortran).
+This file is part of the GNU Fortran runtime library (libgfortran).
 
 Libgfortran is free software; you can redistribute it and/or
 modify it under the terms of the GNU General Public
@@ -41,16 +41,28 @@  see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 #include <string.h>
 
 
+#ifndef HAVE_CTIME_R
+static char *
+ctime_r (const time_t * timep, char * buf __attribute__((unused)))
+{
+  return ctime (timep);
+}
+#endif
+
+/* ctime_r() buffer size needs to be at least 26 bytes.  */
+#define CSZ 26
+
 extern void fdate (char **, gfc_charlen_type *);
 export_proto(fdate);
 
 void
 fdate (char ** date, gfc_charlen_type * date_len)
 {
-#if defined(HAVE_TIME) && defined(HAVE_CTIME)
+#if defined(HAVE_TIME) && (defined(HAVE_CTIME) || defined(HAVE_CTIME_R))
+  char cbuf[CSZ];
   int i;
   time_t now = time(NULL);
-  *date = ctime (&now);
+  *date = ctime_r (&now, cbuf);
   if (*date != NULL)
     {
       *date = strdup (*date);
@@ -78,15 +90,16 @@  export_proto(fdate_sub);
 void
 fdate_sub (char * date, gfc_charlen_type date_len)
 {
-#if defined(HAVE_TIME) && defined(HAVE_CTIME)
+#if defined(HAVE_TIME) && (defined(HAVE_CTIME) || defined(HAVE_CTIME_R))
+  char cbuf[CSZ];
   int i;
   char *d;
   time_t now = time(NULL);
 #endif
   
   memset (date, ' ', date_len);
-#if defined(HAVE_TIME) && defined(HAVE_CTIME)
-  d = ctime (&now);
+#if defined(HAVE_TIME) && (defined(HAVE_CTIME) || defined(HAVE_CTIME_R))
+  d = ctime_r (&now, cbuf);
   if (d != NULL)
     {
       i = 0;
@@ -104,10 +117,11 @@  export_proto_np(PREFIX(ctime));
 void
 PREFIX(ctime) (char ** date, gfc_charlen_type * date_len, GFC_INTEGER_8 t)
 {
-#if defined(HAVE_CTIME)
+#if defined(HAVE_CTIME) || defined(HAVE_CTIME_R)
+  char cbuf[CSZ];
   time_t now = t;
   int i;
-  *date = ctime (&now);
+  *date = ctime_r (&now, cbuf);
   if (*date != NULL)
     {
       *date = strdup (*date);
@@ -135,15 +149,16 @@  export_proto(ctime_sub);
 void
 ctime_sub (GFC_INTEGER_8 * t, char * date, gfc_charlen_type date_len)
 {
-#if defined(HAVE_CTIME)
+#if defined(HAVE_CTIME) || defined(HAVE_CTIME_R)
+  char cbuf[CSZ];
   int i;
   char *d;
   time_t now = *t;
 #endif
   
   memset (date, ' ', date_len);
-#if defined(HAVE_CTIME)
-  d = ctime (&now);
+#if defined(HAVE_CTIME) || defined(HAVE_CTIME_R)
+  d = ctime_r (&now, cbuf);
   if (d != NULL)
     {
       i = 0;