X-Authentication-Warning: delorie.com: mail set sender to djgpp-workers-bounces using -f Date: Thu, 06 Jan 2005 00:16:24 -0700 From: Brian Inglis Subject: *time_r patch To: DJGPP-workers Message-id: Organization: Systematic Software MIME-version: 1.0 X-Mailer: Forte Agent 1.93/32.576 English (American) Content-type: text/plain; charset=us-ascii Content-Transfer-Encoding: 8bit X-MIME-Autoconverted: from quoted-printable to 8bit by delorie.com id j067GaOm006363 Reply-To: djgpp-workers AT delorie DOT com Here's a patch to src/libc/ansi/ctime.c, src/libc/ansi/ctime.txh, and include/libc/stubs.h to add POSIX thread safe functions asctime_r(), ctime_r(), gmtime_r(), and localtime_r(). Index: include/time.h =================================================================== RCS file: /cvs/djgpp/djgpp/include/time.h,v retrieving revision 1.8 diff -u -p -r1.8 time.h --- include/time.h 16 Feb 2003 04:01:49 -0000 1.8 +++ include/time.h 6 Jan 2005 07:00:14 -0000 @@ -1,3 +1,4 @@ +/* Copyright (C) 2005 DJ Delorie, see COPYING.DJ for details */ /* Copyright (C) 2003 DJ Delorie, see COPYING.DJ for details */ /* Copyright (C) 2000 DJ Delorie, see COPYING.DJ for details */ /* Copyright (C) 1999 DJ Delorie, see COPYING.DJ for details */ @@ -73,6 +74,11 @@ extern char *tzname[2]; void tzset(void); +char *asctime_r(const struct tm * __restrict__ _tptr, char * __restrict__ _buf); +char *ctime_r(const time_t *_cal, char *_buf); +struct tm *gmtime_r(const time_t * __restrict__ _tod, struct tm * __restrict__ _tptr); +struct tm *localtime_r(const time_t * __restrict__ _tod, struct tm * __restrict__ _tptr); + #ifndef _POSIX_SOURCE #define tm_zone __tm_zone Index: include/libc/stubs.h =================================================================== RCS file: /cvs/djgpp/djgpp/include/libc/stubs.h,v retrieving revision 1.15 diff -u -p -r1.15 stubs.h --- include/libc/stubs.h 7 May 2004 08:10:30 -0000 1.15 +++ include/libc/stubs.h 6 Jan 2005 07:00:14 -0000 @@ -1,3 +1,4 @@ +/* Copyright (C) 2005 DJ Delorie, see COPYING.DJ for details */ /* Copyright (C) 2002 DJ Delorie, see COPYING.DJ for details */ /* Copyright (C) 1997 DJ Delorie, see COPYING.DJ for details */ /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ @@ -17,8 +18,10 @@ extern "C" { /* POSIX functions (for when compiling an ANSI function) */ #define access __access +#define asctime_r __asctime_r #define chdir __chdir #define close __close +#define ctime_r __ctime_r #define dup __dup #define dup2 __dup2 #define fdopen __fdopen @@ -26,7 +29,9 @@ extern "C" { #define fstatvfs __fstatvfs #define getcwd __getcwd #define glob __glob +#define gmtime_r __gmtime_r #define isatty __isatty +#define localtime_r __localtime_r #define lseek __lseek #define mkdir __mkdir #define open __open Index: src/libc/ansi/time/ctime.c =================================================================== RCS file: /cvs/djgpp/djgpp/src/libc/ansi/time/ctime.c,v retrieving revision 1.9 diff -u -p -r1.9 ctime.c --- src/libc/ansi/time/ctime.c 30 Nov 2002 06:35:57 -0000 1.9 +++ src/libc/ansi/time/ctime.c 6 Jan 2005 07:00:19 -0000 @@ -1,3 +1,4 @@ +/* Copyright (C) 2005 DJ Delorie, see COPYING.DJ for details */ /* Copyright (C) 1998 DJ Delorie, see COPYING.DJ for details */ /* Copyright (C) 1997 DJ Delorie, see COPYING.DJ for details */ /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ @@ -1054,12 +1055,19 @@ localsub(const time_t * const timep, con } struct tm * +localtime_r( const time_t * __restrict__ timep, struct tm * __restrict__ tm) +{ + + localsub(timep, 0L, tm); + return tm; +} + +struct tm * localtime(const time_t * const timep) { static struct tm tm; - localsub(timep, 0L, &tm); - return &tm; + return localtime_r(timep, &tm); } /* @@ -1101,12 +1109,19 @@ gmtsub(const time_t * const timep, const } struct tm * +gmtime_r(const time_t * __restrict__ timep, struct tm * __restrict__ tm) +{ + + gmtsub(timep, 0L, tm); + return tm; +} + +struct tm * gmtime(const time_t * const timep) { static struct tm tm; - gmtsub(timep, 0L, &tm); - return &tm; + return gmtime_r(timep, &tm); } /* Return the year which is DAYS away from the year Y0. */ @@ -1240,7 +1255,7 @@ timesub(const time_t * const timep, cons */ char * -asctime(const struct tm *timeptr) +asctime_r(const struct tm * __restrict__ timeptr, char * __restrict__ result) { static const char wday_name[DAYSPERWEEK][3] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" @@ -1249,7 +1264,6 @@ asctime(const struct tm *timeptr) "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; - static char result[26]; (void) sprintf(result, "%.3s %.3s%3d %02d:%02d:%02d %d\n", wday_name[timeptr->tm_wday], @@ -1261,6 +1275,22 @@ asctime(const struct tm *timeptr) } char * +asctime(const struct tm *timeptr) +{ + static char result[26]; + + return asctime_r( timeptr, result); +} + +char * +ctime_r(const time_t *timep, char *result) +{ + struct tm tm; + + return asctime_r(localtime_r(timep, &tm), result); +} + +char * ctime(const time_t * const timep) { return asctime(localtime(timep)); Index: src/libc/ansi/time/ctime.txh =================================================================== RCS file: /cvs/djgpp/djgpp/src/libc/ansi/time/ctime.txh,v retrieving revision 1.10 diff -u -p -r1.10 ctime.txh --- src/libc/ansi/time/ctime.txh 5 Mar 2003 19:42:31 -0000 1.10 +++ src/libc/ansi/time/ctime.txh 6 Jan 2005 07:00:19 -0000 @@ -13,6 +13,7 @@ char *ctime(const time_t *cal); This function returns an ASCII representation of the time in @var{cal}. This is equivalent to @code{asctime(localtime(cal))}. @xref{asctime}. @xref{localtime}. +@xref{ctime_r}. @subheading Return Value @@ -23,8 +24,39 @@ The ascii representation of the time. @portability ansi, posix @c ---------------------------------------------------------------------- +@node ctime_r, time +@findex ctime_r +@subheading Syntax + +@example +#include + +char *ctime_r(const time_t *cal, char *buf); +@end example + +@subheading Description + +This function returns an ASCII representation of the time in @var{cal} +into the character buffer @var{buf} which must be at least 26 bytes long. +This is equivalent to @code{asctime_r(localtime_r(cal,&tm), buf)}, +where @var{tm} is automatically/dynamically allocated. +@xref{asctime_r}. +@xref{localtime_r}. +@xref{ctime}. + +@subheading Return Value + +A pointer to the character buffer passed as the second argument, +containing the character representation of the time. + +@subheading Portability + +@portability !ansi, posix + +@c ---------------------------------------------------------------------- @node asctime, time @findex asctime +@tindex tm AT r{ structure} @subheading Syntax @example @@ -46,6 +78,7 @@ Sun Jan 01 12:34:56 1993\n\0 The string pointed to is in a static buffer and will be overwritten with each call to asctime. The data should be copied if it needs to be preserved. +@xref{asctime_r}. The layout of the @code{struct tm} structure is like this: @@ -82,6 +115,46 @@ printf("The current time is %s", asctime @end example @c ---------------------------------------------------------------------- +@node asctime_r, time +@findex asctime_r +@subheading Syntax + +@example +#include + +char *asctime_r(const struct tm * restrict tptr, char * restrict buf); +@end example + +@subheading Description + +This function returns an ASCII representation, +as generated by @ref{asctime}, +of the broken down calendar time from @var{tptr}, +as produced by @ref{gmtime}, @ref{gmtime_r}, @ref{localtime}, +@ref{localtime_r}, or @ref{mktime}, +into the character buffer @var{buf}, which must be at least 26 bytes long. + +@subheading Return Value + +A pointer to the character buffer passed as the second argument, +containing the character representation of the time. + +@subheading Portability + +@portability !ansi, posix + +@subheading Example + +@example +time_t now; +struct tm tm; +char buf[26]; + +time(&now); +printf("The current time is %s", asctime_r(localtime_r(&now,&tm),buf)); +@end example + +@c ---------------------------------------------------------------------- @node gmtime, time @findex gmtime @tindex tm AT r{ structure} @@ -96,6 +169,8 @@ struct tm *gmtime(const time_t *tod); @subheading Description Converts the time represented by @var{tod} into a structure. +@xref{gmtime_r}. +@xref{localtime}. The return structure has this format: @@ -133,6 +208,43 @@ t = gmtime(&x); @end example @c ---------------------------------------------------------------------- +@node gmtime_r, time +@findex gmtime_r +@subheading Syntax + +@example +#include + +struct tm *gmtime_r(const time_t * restrict tod, struct tm * restrict tptr); +@end example + +@subheading Description + +Converts the time represented by @var{tod} into +a broken down calendar time structure @var{tptr}. +See @ref{gmtime}, for the description of @code{struct tm}. +@xref{localtime_r}. + +@subheading Return Value + +A pointer to the structure passed as the second argument, +containing the broken down calendar time. + +@subheading Portability + +@portability !ansi, posix + +@subheading Example + +@example +time_t x; +struct tm *t; +struct tm tm; +time(&x); +t = gmtime_r(&x, &tm); +@end example + +@c ---------------------------------------------------------------------- @node localtime, time @findex localtime @subheading Syntax @@ -148,6 +260,7 @@ struct tm *localtime(const time_t *tod); Converts the time represented by @var{tod} into a structure, correcting for the local timezone. See @ref{gmtime}, for the description of @code{struct tm}. +@xref{localtime_r} @subheading Return Value @@ -158,6 +271,34 @@ A pointer to a static structure which is @portability ansi, posix @c ---------------------------------------------------------------------- +@node localtime_r, time +@findex localtime_r +@subheading Syntax + +@example +#include + +struct tm *localtime_r(const time_t * restrict tod, struct tm * restrict tptr); +@end example + +@subheading Description + +Converts the time represented by @var{tod} into structure @var{tptr}, +correcting for the local timezone. +See @ref{gmtime}, for the description of @code{struct tm}. +@xref{localtime}. +@xref{gmtime_r}. + +@subheading Return Value + +A pointer to the structure passed as the second argument, +containing the broken down calendar time. + +@subheading Portability + +@portability !ansi, posix + +@c ---------------------------------------------------------------------- @node mktime, time @findex mktime @vindex TZ AT r{ environment variable, and time since 1970} Index: tests/libc/ansi/time/makefile =================================================================== RCS file: /cvs/djgpp/djgpp/tests/libc/ansi/time/makefile,v retrieving revision 1.3 diff -u -p -r1.3 makefile --- tests/libc/ansi/time/makefile 8 Nov 2003 12:19:41 -0000 1.3 +++ tests/libc/ansi/time/makefile 6 Jan 2005 07:00:23 -0000 @@ -1,4 +1,5 @@ TOP=../.. +SRC += ctime.c SRC += mktime.c SRC += strftime.c Index: tests/libc/ansi/time/ctime.c =================================================================== RCS file: /cvs/djgpp/djgpp/tests/libc/ansi/time/ctime.c,v diff -u -p ctime.c --- /dev/null 2005-01-05 23:24:37.000000000 -0700 +++ time.c 2005-01-05 23:24:16.000000000 -0700 @@ -0,0 +1,49 @@ +/* ctime.c - basic ISO and POSIX time function calls */ + +#include +#include +#include + +int +main( void ) +{ + const char *tz[] = { "AZOT-1AZOST", "WET0WEST", "CET1CEST" }; + unsigned z; + int o; + + for (z = 0; z < sizeof tz / sizeof *tz; ++z) + { + setenv( "TZ", tz[z], 1); + + for (o = 0; o <= 4; ++o) + { + time_t t; + struct tm * tmp; + struct tm tm; + char buf[BUFSIZ]; + + t = time( &t ); + t = 1024*1024*1024/4*3*o; + printf( "time( %10u ) = %s\n", t, getenv( "TZ" )); + tmp = gmtime( &t ); + printf( "gmtime( %10u ) = %s", t, asctime( tmp )); + tmp = localtime( &t ); + printf( "localtime( %10u ) = %s", t, asctime( tmp )); + printf( "ctime( %10u ) = %s", t, ctime( &t )); + t = mktime( tmp ); + strftime( buf, sizeof buf, "%c%n", tmp); + printf( "strftime( %10u ) = %s", t, buf); + printf( "difftime( %10u, 0) = %.0fs\n", t, difftime( t, 0)); + + t = 1024*1024*1024/4*3*o; + tmp = gmtime_r( &t, &tm); + printf( "gmtime_r( %10u, t) = %s", t, asctime_r( tmp, buf)); + tmp = localtime_r( &t, &tm); + printf( "localtime_r( %10u, t) = %s", t, asctime_r( tmp, buf)); + printf( "ctime_r( %10u, s) = %s\n", t, ctime_r( &t, buf)); + } + } + + return 0; + +} /* main() */ -- Thanks. Take care, Brian Inglis Business: +1(403)547-8816 Brian DOT Inglis AT SystematicSW DOT ab DOT ca Residence: +1(403)239-6520 BWInglis AT Shaw DOT ca