From owner-freebsd-bugs Thu Mar 6 22:40: 9 2003 Delivered-To: freebsd-bugs@hub.freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id C195337B401 for ; Thu, 6 Mar 2003 22:40:05 -0800 (PST) Received: from freefall.freebsd.org (freefall.freebsd.org [216.136.204.21]) by mx1.FreeBSD.org (Postfix) with ESMTP id DA76143FE0 for ; Thu, 6 Mar 2003 22:40:04 -0800 (PST) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (gnats@localhost [127.0.0.1]) by freefall.freebsd.org (8.12.6/8.12.6) with ESMTP id h276e4NS010368 for ; Thu, 6 Mar 2003 22:40:04 -0800 (PST) (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.12.6/8.12.6/Submit) id h276e4sC010367; Thu, 6 Mar 2003 22:40:04 -0800 (PST) Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id B6B2737B401 for ; Thu, 6 Mar 2003 22:30:23 -0800 (PST) Received: from triantos.com (mail.triantos.com [66.127.67.82]) by mx1.FreeBSD.org (Postfix) with SMTP id C020A43FA3 for ; Thu, 6 Mar 2003 22:30:22 -0800 (PST) (envelope-from nick@triantos.com) Received: (qmail 90966 invoked from network); 7 Mar 2003 06:31:51 -0000 Received: from router.triantos.com (HELO yoonicksxp) (66.127.67.83) by triantos.com with SMTP; 7 Mar 2003 06:31:51 -0000 Message-Id: <000601c2e473$0c2bbc40$1601a8c0@triantos.com> Date: Thu, 6 Mar 2003 22:30:03 -0800 From: "Nick Triantos" To: Subject: misc/48993: strptime() does not fill in some fields of struct tm Sender: owner-freebsd-bugs@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.org >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 #include 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