diff options
author | Ted Unangst <tedu@cvs.openbsd.org> | 2019-01-21 21:35:59 +0000 |
---|---|---|
committer | Ted Unangst <tedu@cvs.openbsd.org> | 2019-01-21 21:35:59 +0000 |
commit | 94c9630d492c7ccefe64eb134c567b681c5df8ef (patch) | |
tree | 7b17996101677f0d7ecb4431bb8b86a53853aa70 /lib | |
parent | 491a489b5452a566dc12d9951f40fcffda39db22 (diff) |
strftime can print epoch seconds with %s, so allow strptime to parse it.
ok cheloha
Diffstat (limited to 'lib')
-rw-r--r-- | lib/libc/time/strptime.3 | 8 | ||||
-rw-r--r-- | lib/libc/time/strptime.c | 38 |
2 files changed, 42 insertions, 4 deletions
diff --git a/lib/libc/time/strptime.3 b/lib/libc/time/strptime.3 index 6b66d06aa0c..8872a8e7aaf 100644 --- a/lib/libc/time/strptime.3 +++ b/lib/libc/time/strptime.3 @@ -1,4 +1,4 @@ -.\" $OpenBSD: strptime.3,v 1.25 2016/02/08 20:05:43 tedu Exp $ +.\" $OpenBSD: strptime.3,v 1.26 2019/01/21 21:35:58 tedu Exp $ .\" .\" Copyright (c) 1997, 1998, 2005, 2008 The NetBSD Foundation, Inc. .\" All rights reserved. @@ -26,7 +26,7 @@ .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE .\" POSSIBILITY OF SUCH DAMAGE. .\" -.Dd $Mdocdate: February 8 2016 $ +.Dd $Mdocdate: January 21 2019 $ .Dt STRPTIME 3 .Os .Sh NAME @@ -145,6 +145,9 @@ the time as %H:%M. .It Cm \&%S the seconds [0,60]; leading zeros are permitted but not required. +.It Cm \&%s +the number of seconds since the Epoch, UTC (see +.Xr mktime 3 ) . .It Cm \&%t any whitespace. .It Cm \&%T @@ -301,6 +304,7 @@ function conforms to The .Ql \&%G , .Ql \&%g , +.Ql \&%s , .Ql \&%u , .Ql \&%V , .Ql \&%Y , diff --git a/lib/libc/time/strptime.c b/lib/libc/time/strptime.c index 2932575860d..a1cbbdbb8e3 100644 --- a/lib/libc/time/strptime.c +++ b/lib/libc/time/strptime.c @@ -1,4 +1,4 @@ -/* $OpenBSD: strptime.c,v 1.22 2016/05/23 00:05:15 guenther Exp $ */ +/* $OpenBSD: strptime.c,v 1.23 2019/01/21 21:35:58 tedu Exp $ */ /* $NetBSD: strptime.c,v 1.12 1998/01/20 21:39:40 mycroft Exp $ */ /*- * Copyright (c) 1997, 1998, 2005, 2008 The NetBSD Foundation, Inc. @@ -30,6 +30,7 @@ #include <ctype.h> #include <locale.h> +#include <stdint.h> #include <string.h> #include <time.h> @@ -71,6 +72,7 @@ static const int mon_lengths[2][MONSPERYEAR] = { { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } }; +static int _conv_num64(const unsigned char **, int64_t *, int64_t, int64_t); static int _conv_num(const unsigned char **, int *, int, int); static int leaps_thru_end_of(const int y); static char *_strptime(const char *, const char *, struct tm *, int); @@ -333,7 +335,16 @@ literal: if (!(_conv_num(&bp, &tm->tm_sec, 0, 61))) return (NULL); break; - + case 's': /* Seconds since epoch */ + { + int64_t i64; + if (!(_conv_num64(&bp, &i64, 0, INT64_MAX))) + return (NULL); + if (!gmtime_r(&i64, tm)) + return (NULL); + fields = 0xffff; /* everything */ + } + break; case 'U': /* The week of year, beginning on sunday. */ case 'W': /* The week of year, beginning on monday. */ _LEGAL_ALT(_ALT_O); @@ -660,6 +671,29 @@ _conv_num(const unsigned char **buf, int *dest, int llim, int ulim) return (1); } +static int +_conv_num64(const unsigned char **buf, int64_t *dest, int64_t llim, int64_t ulim) +{ + int result = 0; + int64_t rulim = ulim; + + if (**buf < '0' || **buf > '9') + return (0); + + /* we use rulim to break out of the loop when we run out of digits */ + do { + result *= 10; + result += *(*buf)++ - '0'; + rulim /= 10; + } while ((result * 10 <= ulim) && rulim && **buf >= '0' && **buf <= '9'); + + if (result < llim || result > ulim) + return (0); + + *dest = result; + return (1); +} + static const u_char * _find_string(const u_char *bp, int *tgt, const char * const *n1, const char * const *n2, int c) |