This patch is to make it so touch -t works with a time stamp ending in ".60". Without this change, "touch -t 200901010800.60 file" would fail. Note that the change below makes a recursive call to posixtime. That may not be the most efficient, but I suspect this case is relatively unusual and I'd much prefer to have code that is obviously correct than code that is optimized for a case that will rarely arise. If anyone can see a cleaner way, please speak up.
FYI, I ran the built-in tests by compiling like this: gcc -I/t -DTEST_POSIXTIME -g -O -Wall -W posixtm.c and running the test like this: sed -n '/^BEGIN-DATA$/,/^END-DATA$/p' posixtm.c|grep -v DATA> in; TZ=UTC0 ./a.out < in |diff -u - in Here's its output: --- - 2009-09-14 14:32:58.934253776 +0200 +++ in 2009-09-14 14:32:58.930840392 +0200 @@ -1,6 +1,6 @@ -12131415.16 13 1260713716 Sun Dec 13 14:15:16 2009 -12131415.16 13 1260713716 Sun Dec 13 14:15:16 2009 -000001010000.00 13 -62167219200 Sat Jan 1 00:00:00 0 +12131415.16 13 1039788916 Fri Dec 13 14:15:16 2002 +12131415.16 13 1039788916 Fri Dec 13 14:15:16 2002 +000001010000.00 13 -62167132800 Sun Jan 1 00:00:00 0000 190112132045.52 13 -2147483648 Fri Dec 13 20:45:52 1901 190112132045.53 13 -2147483647 Fri Dec 13 20:45:53 1901 190112132046.52 13 -2147483588 Fri Dec 13 20:46:52 1901 Note that the first two differences are to be expected. Those tests pass only if 2002 is the current year. However, I don't know about the difference in the 3rd line. Note the s/Sat/Sun/ change. The new number of seconds is 86400 larger than the old one; that's exactly one day's worth of seconds, and hence in line with the Sat/Sun change. I don't yet know if this change is a problem in mktime or due to some intervening fix. First, I'll commit this. Then I'll write a proper test module. Then, maybe, I'll worry about the DoW of Jan 1, year-zero ;-) >From 6c9f1e88ada406b65f6b10098b8c9e60c973e614 Mon Sep 17 00:00:00 2001 From: Jim Meyering <meyer...@redhat.com> Date: Sun, 13 Sep 2009 00:35:49 +0200 Subject: [PATCH] posixtm: don't reject a time with "60" as the number of seconds * lib/posixtm.c (posixtime): The code to reject invalid dates would also reject a time specified with the .60 suffix, whereas POSIX allows that, in order to accommodate leap seconds. Don't reject that. (main): Adjust tests accordingly. * modules/posixtm (Depends-on): Add stpcpy. --- ChangeLog | 10 ++++++++++ lib/posixtm.c | 23 +++++++++++++++++++---- modules/posixtm | 1 + 3 files changed, 30 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 94bac83..dc32b4d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2009-09-13 Jim Meyering <meyer...@redhat.com> + + posixtm: don't reject a time that specify "60" as the number of seconds + * lib/posixtm.c (posixtime): The code to reject invalid dates + would also reject a time specified with the .60 suffix. + But POSIX allows that, in order to accommodate leap seconds. + So don't reject it. + (main): Adjust tests accordingly. + * modules/posixtm (Depends-on): Add stpcpy. + 2009-09-11 Jim Meyering <meyer...@redhat.com> announce-gen: include [$release_type] in emitted Subject: diff --git a/lib/posixtm.c b/lib/posixtm.c index 4d044a3..0a1e779 100644 --- a/lib/posixtm.c +++ b/lib/posixtm.c @@ -1,7 +1,7 @@ /* Parse dates for touch and date. Copyright (C) 1989, 1990, 1991, 1998, 2000, 2001, 2002, 2003, 2004, - 2005, 2006, 2007 Free Software Foundation Inc. + 2005, 2006, 2007, 2009 Free Software Foundation Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -207,14 +207,29 @@ posixtime (time_t *p, const char *s, unsigned int syntax_bits) return false; } - /* Reject dates like "September 31" and times like "25:61". */ + /* Reject dates like "September 31" and times like "25:61". + Do not reject times that specify "60" as the number of seconds. */ if ((tm0.tm_year ^ tm->tm_year) | (tm0.tm_mon ^ tm->tm_mon) | (tm0.tm_mday ^ tm->tm_mday) | (tm0.tm_hour ^ tm->tm_hour) | (tm0.tm_min ^ tm->tm_min) | (tm0.tm_sec ^ tm->tm_sec)) - return false; + { + /* Any mismatch without 60 in the tm_sec field is invalid. */ + if (tm0.tm_sec != 60) + return false; + + { + /* Allow times like 01:35:60 or 23:59:60. */ + time_t dummy; + char buf[16]; + char *b = stpcpy (buf, s); + strcpy (b - 2, "59"); + if (!posixtime (&dummy, buf, syntax_bits)) + return false; + } + } *p = t; return true; @@ -251,13 +266,13 @@ BEGIN-DATA 197001010000.00 13 0 Thu Jan 1 00:00:00 1970 197001010000.01 13 1 Thu Jan 1 00:00:01 1970 197001010001.00 13 60 Thu Jan 1 00:01:00 1970 +197001010000.60 13 60 Thu Jan 1 00:01:00 1970 197001010100.00 13 3600 Thu Jan 1 01:00:00 1970 197001020000.00 13 86400 Fri Jan 2 00:00:00 1970 197002010000.00 13 2678400 Sun Feb 1 00:00:00 1970 197101010000.00 13 31536000 Fri Jan 1 00:00:00 1971 197001000000.00 13 * * 197000010000.00 13 * * -197001010000.60 13 * * 197001010060.00 13 * * 197001012400.00 13 * * 197001320000.00 13 * * diff --git a/modules/posixtm b/modules/posixtm index 06af4c8..425c175 100644 --- a/modules/posixtm +++ b/modules/posixtm @@ -9,6 +9,7 @@ m4/posixtm.m4 Depends-on: mktime stdbool +stpcpy configure.ac: gl_POSIXTM -- 1.6.5.rc1.171.g3f463