Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 6 Mar 2003 22:30:03 -0800
From:      "Nick Triantos" <nick@triantos.com>
To:        <FreeBSD-gnats-submit@FreeBSD.org>
Subject:   misc/48993: strptime() does not fill in some fields of struct tm
Message-ID:  <000601c2e473$0c2bbc40$1601a8c0@triantos.com>

next in thread | raw e-mail | index | archive | help

>Number:         48993
>Category:       misc
>Synopsis:       strptime() does not fill in some fields of struct tm
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Thu Mar 06 22:40:04 PST 2003
>Closed-Date:
>Last-Modified:
>Originator:     Nick Triantos
>Release:        FreeBSD 5.0-RELEASE i386
>Organization:
triantos.com
>Environment:
System: FreeBSD yoonicks-bsd.triantos.com 5.0-RELEASE FreeBSD
5.0-RELEASE #0: Thu Jan 16 22:16:53 GMT 2003
root@hollin.btc.adaptec.com:/usr/obj/usr/src/sys/GENERIC i386
using out-of-the box freebsd 5.0 libc


	
>Description:
	
The strptime() function does not fill in the complete 'tm' struct upon
successful return.  This behaviour is different than on Linux and
Windows.  In particular, the tm_wday and tm_yday fields are 0 on exit
from the function.

I found this bug because TMDA (http://www.tmda.net) failed to display
dates correctly.  I debugged through the python, into the python souce,
and eventually into the source for
'/usr/src/lib/libc/stdtime/strptime.c'.

>How-To-Repeat:

Compile this simple program:

#include <time.h>
#include <stdio.h>

char *orig   = "27 Feb 2003 16:45:59";
char *format = "%d %b %Y %H:%M:%S";
struct tm timeobj;

int main(int argc, char *argv[])
{
    printf("orig  : %s\n", orig);
    printf("format: %s\n", format);

    if (strptime(orig, format, &timeobj) == NULL) {
        printf("ERROR: Couldn't parse the string.\n");
        return 1;
    }

    printf("\n");
    printf("timeobj = {\n");
    printf("    tm_sec    = %d\n", timeobj.tm_sec);
    printf("    tm_min    = %d\n", timeobj.tm_min);
    printf("    tm_hour   = %d\n", timeobj.tm_hour);
    printf("    tm_mday   = %d\n", timeobj.tm_mday);
    printf("    tm_mon    = %d (0-11)\n", timeobj.tm_mon);
    printf("    tm_year   = %d (%d)\n", timeobj.tm_year,
timeobj.tm_year+1900);
    printf("    tm_wday   = %d (days since Sun)\n", timeobj.tm_wday);
    printf("    tm_yday   = %d (days since Jan 1)\n", timeobj.tm_yday);
    printf("}\n");

    return 0;
}

>Fix:

Change file /usr/src/lib/libc/stdtime/strptime.c, function strptime() to
match below.  In particular, if (ret && !got_GMT), the function should
call mktime() and localtime_r() to get localtime_r() to fill in the
remaining fields.

- - - - -

strptime(const char * __restrict buf, const char * __restrict fmt,
    struct tm * __restrict tm)
{
	char *ret;

	if (__isthreaded)
		_pthread_mutex_lock(&gotgmt_mutex);

	got_GMT = 0;
	ret = _strptime(buf, fmt, tm);
	if (ret) {
		if (got_GMT) {
			time_t t = timegm(tm);
			localtime_r(&t, tm);
			got_GMT = 0;
		} else {
			time_t t = mktime(tm);
			localtime_r(&t, tm);
		}
	}

	if (__isthreaded)
		_pthread_mutex_unlock(&gotgmt_mutex);

	return ret;
}

>Release-Note:
>Audit-Trail:
>Unformatted:

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?000601c2e473$0c2bbc40$1601a8c0>