From 2f4149ea09454b3def6fe8245992f7e26571a1e8 Mon Sep 17 00:00:00 2001 From: Robert Mustacchi Date: Tue, 5 Dec 2017 07:43:54 +0000 Subject: 8893 Want date -r Reviewed by: Yuri Pankov Reviewed by: Cody Mello Approved by: Richard Lowe --- usr/src/cmd/date/date.c | 54 ++++++++++-- usr/src/man/man1/date.1 | 47 ++++++----- usr/src/pkg/manifests/system-test-utiltest.mf | 1 + usr/src/test/util-tests/runfiles/default.run | 1 + usr/src/test/util-tests/tests/Makefile | 2 +- usr/src/test/util-tests/tests/date/Makefile | 40 +++++++++ usr/src/test/util-tests/tests/date/date_test.ksh | 100 +++++++++++++++++++++++ 7 files changed, 217 insertions(+), 28 deletions(-) create mode 100644 usr/src/test/util-tests/tests/date/Makefile create mode 100644 usr/src/test/util-tests/tests/date/date_test.ksh diff --git a/usr/src/cmd/date/date.c b/usr/src/cmd/date/date.c index de5068da54..55e9110d5b 100644 --- a/usr/src/cmd/date/date.c +++ b/usr/src/cmd/date/date.c @@ -27,7 +27,7 @@ * Copyright 2012 Nexenta Systems, Inc. All rights reserved. */ /* - * Copyright (c) 2012, Joyent, Inc. All rights reserved. + * Copyright (c) 2017, Joyent, Inc. */ /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ /* All Rights Reserved */ @@ -56,7 +56,9 @@ #include #include #include +#include #include +#include #include #include @@ -70,10 +72,12 @@ static struct utmpx wtmpx[2] = { {"", "", NTIME_MSG, 0, NEW_TIME, 0, 0, 0} }; static char *usage = - "usage:\tdate [-u] mmddHHMM[[cc]yy][.SS]\n\tdate [-Ru] [+format]\n" + "usage:\tdate [-u] mmddHHMM[[cc]yy][.SS]\n" + "\tdate [-Ru] [-r seconds | filename] [+format]\n" "\tdate -a [-]sss[.fff]\n"; static int uflag = 0; static int Rflag = 0; +static int rflag = 0; static int get_adj(char *, struct timeval *); static int setdate(struct tm *, char *); @@ -85,7 +89,7 @@ main(int argc, char **argv) { struct tm *tp, tm; struct timeval tv; - char *fmt; + char *fmt, *eptr; char fmtbuf[BUFSIZ]; int c, aflag = 0, illflag = 0; struct timespec ts; @@ -97,7 +101,7 @@ main(int argc, char **argv) #endif (void) textdomain(TEXT_DOMAIN); - while ((c = getopt(argc, argv, "a:uR")) != EOF) + while ((c = getopt(argc, argv, "a:uRr:")) != EOF) switch (c) { case 'a': aflag++; @@ -114,6 +118,36 @@ main(int argc, char **argv) case 'R': Rflag++; break; + case 'r': + + /* + * BSD originally used -r to specify a unix time. GNU + * used -r to specify a reference to a file. Now, like + * some BSDs we attempt to parse the time. If we can, + * then we use that, otherwise we fall back and treat it + * like GNU. + */ + rflag++; + errno = 0; + ts.tv_sec = strtol(optarg, &eptr, 0); + if (errno == EINVAL || *eptr != '\0') { + struct stat st; + if (stat(optarg, &st) == 0) { + ts.tv_sec = st.st_mtime; + } else { + (void) fprintf(stderr, + gettext("date: failed to get stat " + "information about %s: %s\n"), + optarg, strerror(errno)); + exit(1); + } + } else if (errno != 0) { + (void) fprintf(stderr, + gettext("date: failed to parse -r " + "argument: %s\n"), optarg); + exit(1); + } + break; default: illflag++; } @@ -121,20 +155,24 @@ main(int argc, char **argv) argc -= optind; argv = &argv[optind]; - /* -a is mutually exclusive with -u and -R */ + /* -a is mutually exclusive with -u, -R, and -r */ if (uflag && aflag) illflag++; if (Rflag && aflag) illflag++; + if (rflag && aflag) + illflag++; if (illflag) { (void) fprintf(stderr, gettext(usage)); exit(1); } - if (clock_gettime(CLOCK_REALTIME, &ts) != 0) { - perror(gettext("date: Failed to obtain system time")); - exit(1); + if (rflag == 0) { + if (clock_gettime(CLOCK_REALTIME, &ts) != 0) { + perror(gettext("date: Failed to obtain system time")); + exit(1); + } } clock_val = ts.tv_sec; diff --git a/usr/src/man/man1/date.1 b/usr/src/man/man1/date.1 index 1b53d6194e..8e2d25a5ba 100644 --- a/usr/src/man/man1/date.1 +++ b/usr/src/man/man1/date.1 @@ -44,14 +44,15 @@ .\" Portions Copyright (c) 1992, X/Open Company Limited All Rights Reserved .\" Copyright (c) 2004, Sun Microsystems, Inc. All Rights Reserved .\" Copyright 2011 Nexenta Systems, Inc. All rights reserved. +.\" Copyright (c) 2017 Joyent, Inc. .\" -.TH DATE 1 "May 1, 2011" +.TH DATE 1 "Dec 6, 2017" .SH NAME date \- write the date and time .SH SYNOPSIS .LP .nf -\fB/usr/bin/date\fR [\fB-u\fR] [\fB-R\fR] [+\fIformat\fR] +\fB/usr/bin/date\fR [\fB-u\fR] [\fB-r\fR \fIseconds\fR | \fIfilename\fR] [\fB-R\fR] [+\fIformat\fR] .fi .LP @@ -66,7 +67,7 @@ date \- write the date and time .LP .nf -\fB/usr/xpg4/bin/date\fR [\fB-u\fR] [\fB-R\fR] [+\fIformat\fR] +\fB/usr/xpg4/bin/date\fR [\fB-u\fR] [\fB-r\fR \fIseconds\fR | \fIfilename\fR] [\fB-R\fR] [+\fIformat\fR] .fi .LP @@ -81,7 +82,6 @@ date \- write the date and time .fi .SH DESCRIPTION -.sp .LP The \fBdate\fR utility writes the date and time to standard output or attempts to set the system date and time. By default, the current date and time is @@ -114,7 +114,6 @@ Fri Dec 23 10:10:42 EST 1988 .sp .SH OPTIONS -.sp .LP The following options are supported: .sp @@ -132,11 +131,22 @@ seconds specified. Only the super-user may adjust the time. .sp .ne 2 .na -\fB\fB-u\fR \fR +\fB\fB-r\fR \fIseconds\fR\fR .ad .RS 24n -Display (or set) the date in Greenwich Mean Time (GMT\(emuniversal time), -bypassing the normal conversion to (or from) local time. +Rather than using the current time, obtain the time based on +\fIseconds\fR. \fIseconds\fR will be treated as time since the UNIX +Epoch (00:00:00 UTC, January 1, 1970). +.RE + +.sp +.ne 2 +.na +\fB\fB-r\fR \fIfilename\fR\fR +.ad +.RS 24n +Rather than using the current time, obtain the time based on +the modification time of \fIfilename\fR. .RE .sp @@ -155,8 +165,17 @@ Change the default format to the format used for mail message headers .in -2 .RE -.SH OPERANDS .sp +.ne 2 +.na +\fB\fB-u\fR \fR +.ad +.RS 24n +Display (or set) the date in Greenwich Mean Time (GMT\(emuniversal time), +bypassing the normal conversion to (or from) local time. +.RE + +.SH OPERANDS .LP The following operands are supported: .sp @@ -359,7 +378,6 @@ Thu Jan 01 00:30:00 GMT 2000 .sp .SH ENVIRONMENT VARIABLES -.sp .LP See \fBenviron\fR(5) for descriptions of the following environment variables that affect the execution of \fBdate\fR: \fBLANG\fR, \fBLC_ALL\fR, @@ -376,7 +394,6 @@ Determine the timezone in which the time and date are written, unless the .RE .SH EXIT STATUS -.sp .LP The following exit values are returned: .sp @@ -398,13 +415,10 @@ An error occurred. .RE .SH ATTRIBUTES -.sp .LP See \fBattributes\fR(5) for descriptions of the following attributes: .SS "/usr/bin/date" -.sp -.sp .TS box; c | c @@ -415,9 +429,7 @@ CSI enabled .TE .SS "/usr/xpg4/bin/date" -.sp -.sp .TS box; c | c @@ -430,11 +442,9 @@ Interface Stability Standard .TE .SH SEE ALSO -.sp .LP \fBstrftime\fR(3C), \fBattributes\fR(5), \fBenviron\fR(5), \fBstandards\fR(5) .SH DIAGNOSTICS -.sp .ne 2 .na \fB\fBno permission\fR \fR @@ -453,7 +463,6 @@ The date set is syntactically incorrect. .RE .SH NOTES -.sp .LP If you attempt to set the current date to one of the dates that the standard and alternate time zones change (for example, the date that daylight time is diff --git a/usr/src/pkg/manifests/system-test-utiltest.mf b/usr/src/pkg/manifests/system-test-utiltest.mf index df0e0cfd4e..714efb203a 100644 --- a/usr/src/pkg/manifests/system-test-utiltest.mf +++ b/usr/src/pkg/manifests/system-test-utiltest.mf @@ -37,6 +37,7 @@ file path=opt/util-tests/bin/print_json mode=0555 file path=opt/util-tests/bin/utiltest mode=0555 file path=opt/util-tests/runfiles/default.run mode=0444 file path=opt/util-tests/tests/allowed-ips mode=0555 +file path=opt/util-tests/tests/date_test mode=0555 file path=opt/util-tests/tests/dis/distest mode=0555 file path=opt/util-tests/tests/dis/i386/32.adx.out mode=0555 file path=opt/util-tests/tests/dis/i386/32.adx.s mode=0555 diff --git a/usr/src/test/util-tests/runfiles/default.run b/usr/src/test/util-tests/runfiles/default.run index 97d5736a20..1b0077b748 100644 --- a/usr/src/test/util-tests/runfiles/default.run +++ b/usr/src/test/util-tests/runfiles/default.run @@ -37,3 +37,4 @@ tests = ['json_00_blank', 'json_01_boolean', 'json_02_numbers', 'json_06_nested', 'json_07_nested_arrays'] [/opt/util-tests/tests/grep_test] +[/opt/util-tests/tests/date_test] diff --git a/usr/src/test/util-tests/tests/Makefile b/usr/src/test/util-tests/tests/Makefile index 58e303b03f..7eb4a5fe6c 100644 --- a/usr/src/test/util-tests/tests/Makefile +++ b/usr/src/test/util-tests/tests/Makefile @@ -15,6 +15,6 @@ # Copyright 2014 Nexenta Systems, Inc. All rights reserved. # -SUBDIRS = dis dladm iconv libnvpair_json libsff printf xargs grep_xpg4 +SUBDIRS = date dis dladm iconv libnvpair_json libsff printf xargs grep_xpg4 include $(SRC)/test/Makefile.com diff --git a/usr/src/test/util-tests/tests/date/Makefile b/usr/src/test/util-tests/tests/date/Makefile new file mode 100644 index 0000000000..d0e97a8f9e --- /dev/null +++ b/usr/src/test/util-tests/tests/date/Makefile @@ -0,0 +1,40 @@ +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright 2017 Joyent, Inc. +# + +include $(SRC)/cmd/Makefile.cmd +include $(SRC)/test/Makefile.com + +ROOTOPTPKG = $(ROOT)/opt/util-tests/tests +PROG = date_test + +ROOTPROG = $(PROG:%=$(ROOTOPTPKG)/%) + +all: + +install: $(ROOTPROG) + +lint: + +clobber: clean + +clean: + +$(CMDS): $(TESTDIR) + +$(ROOTOPTPKG): + $(INS.dir) + +$(ROOTOPTPKG)/%: %.ksh $(ROOTOPTPKG) + $(INS.rename) diff --git a/usr/src/test/util-tests/tests/date/date_test.ksh b/usr/src/test/util-tests/tests/date/date_test.ksh new file mode 100644 index 0000000000..384a02da2f --- /dev/null +++ b/usr/src/test/util-tests/tests/date/date_test.ksh @@ -0,0 +1,100 @@ +#!/bin/ksh +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright (c) 2017, Joyent, Inc. +# + +# +# Basic tests of date -r. +# + +# +# Make sure that we're executing in the C locale and that a given user's +# locale doesn't impact this test. +# +export LANG=C + +date_arg0="$(basename $0)" +date_prog=/usr/bin/date +date_curcmd= + +fatal() +{ + typeset msg="$*" + [[ -z "$msg" ]] && msg="failed" + echo "TEST FAILED: $date_arg0: $msg" >&2 + exit 1 +} + +compare() +{ + typeset time=$1 + typeset exp=$2 + typeset tz=$3 + typeset val ret + + date_curcmd="TZ=$3 $date_prog -r $1" + val=$(TZ=$3 $date_prog -r $1) + ret=$? + if [[ $ret -ne 0 ]]; then + fatal "date not exit zero, exited $ret; command: $date_curcmd" + fi + if [[ -z "$val" ]]; then + fatal "date returned no output; command: $date_curcmd" + fi + + if [[ "$val" != "$exp" ]]; then + fatal "date output mismatch; command: $date_curcmd; expected: " \ + "$exp; found: $val" + fi +} + +if [[ -n $DATE ]]; then + date_prog=$DATE +fi + +# +# date -r supports base 10, hex, and octal +# +compare 0 "Thu Jan 1 00:00:00 UTC 1970" UTC +compare 0 "Wed Dec 31 16:00:00 PST 1969" US/Pacific +compare 0 "Thu Jan 1 09:00:00 JST 1970" Japan +compare 1234567890 "Fri Feb 13 23:31:30 UTC 2009" UTC +compare -1234567890 "Tue Nov 18 00:28:30 UTC 1930" UTC +compare 2147483647 "Tue Jan 19 03:14:07 UTC 2038" UTC +compare -2147483647 "Fri Dec 13 20:45:53 UTC 1901" UTC +compare 558028800 "Mon Sep 7 16:00:00 UTC 1987" UTC +compare 0x2142d800 "Mon Sep 7 16:00:00 UTC 1987" UTC +compare 04120554000 "Mon Sep 7 16:00:00 UTC 1987" UTC + +# +# Test the file related logic +# +touch -t 201712042323.23 $TMPDIR/test.$$ +compare "$TMPDIR/test.$$" "Mon Dec 4 23:23:23 UTC 2017" UTC +rm -f $TMPDIR/test.$$ + +# +# date -r should not work with -a +# +if $date_prog -r 0 -a 10 2>/dev/null; then + fatal "date -r 0 -a 10 exited zero when it should have failed" +fi + +# +# date -r and -R or -u should work together +# +compare "0 -R" "Thu, 01 Jan 1970 02:00:00 +0200" Africa/Cairo +compare "0 -u" "Thu Jan 1 00:00:00 GMT 1970" Europe/Rome + +echo "TEST PASSED: $date_arg0" -- cgit v1.2.3