readclock: code clean-up, add -q, manpage updates

- Simplify the message passing between readclock and the driver.

 - Add a -q command line option to suppress warning messages. This
 cuts down on the noise when readclock is called early in the boot
 sequence and a secondary RTC driver (ex TPS95650) isn't up yet.

 - Update the man page to be less i386 centric and add details about
 the new -q option.

Change-Id: If8d7c50a217ca98c1e9fae0ca92521e2e7c893e4
This commit is contained in:
Thomas Cort 2013-08-07 20:06:47 -04:00 committed by Gerrit Code Review
parent bab2a34e1b
commit 7f98bdf040
3 changed files with 43 additions and 67 deletions

View file

@ -16,19 +16,18 @@
#include <minix/rs.h>
#include <sys/ipc.h>
int nflag = 0; /* Tell what, but don't do it. */
int wflag = 0; /* Set the CMOS clock. */
int Wflag = 0; /* Also set the CMOS clock register bits. */
int y2kflag = 0; /* Interpret 1980 as 2000 for clock with Y2K bug. */
void errmsg(char *s);
void get_time(struct tm *t);
void set_time(struct tm *t);
static void readclock(int type, struct tm *t, int flags);
void usage(void);
int quiet = 0;
int
main(int argc, char **argv)
{
int flags = RTCDEV_NOFLAGS;
int nflag = 0; /* Tell what, but don't do it. */
int wflag = 0; /* Set the CMOS clock. */
struct tm time1;
struct tm time2;
struct tm tmnow;
@ -52,10 +51,14 @@ main(int argc, char **argv)
wflag = 1;
break;
case 'W':
Wflag = 1;
flags |= RTCDEV_CMOSREG;
wflag = 1; /* -W implies -w */
break;
case '2':
y2kflag = 1;
flags |= RTCDEV_Y2KBUG;
break;
case 'q':
quiet = 1;
break;
default:
usage();
@ -63,12 +66,10 @@ main(int argc, char **argv)
}
argc--;
}
if (Wflag)
wflag = 1; /* -W implies -w */
/* Read the CMOS real time clock. */
for (i = 0; i < 10; i++) {
get_time(&time1);
readclock(RTCDEV_GET_TIME, &time1, flags);
now = time(NULL);
time1.tm_isdst = -1; /* Do timezone calculations. */
@ -78,7 +79,7 @@ main(int argc, char **argv)
if (rtc != -1)
break;
printf
if (!quiet) printf
("readclock: Invalid time read from CMOS RTC: %d-%02d-%02d %02d:%02d:%02d\n",
time2.tm_year + 1900, time2.tm_mon + 1, time2.tm_mday,
time2.tm_hour, time2.tm_min, time2.tm_sec);
@ -90,10 +91,12 @@ main(int argc, char **argv)
if (!wflag) {
/* Set system time. */
if (nflag) {
printf("stime(%lu)\n", (unsigned long) rtc);
if (!quiet)
printf("stime(%lu)\n", (unsigned long) rtc);
} else {
if (stime(&rtc) < 0) {
errmsg("Not allowed to set time.");
if (!quiet)
errmsg("Not allowed to set time.");
exit(1);
}
}
@ -102,19 +105,20 @@ main(int argc, char **argv)
"%a %b %d %H:%M:%S %Z %Y", &tmnow) != 0) {
if (date[8] == '0')
date[8] = ' ';
printf("%s\n", date);
if (!quiet) printf("%s\n", date);
}
} else {
/* Set the CMOS clock to the system time. */
tmnow = *localtime(&now);
if (nflag) {
printf("%04d-%02d-%02d %02d:%02d:%02d\n",
tmnow.tm_year + 1900,
tmnow.tm_mon + 1,
tmnow.tm_mday,
tmnow.tm_hour, tmnow.tm_min, tmnow.tm_sec);
if (!quiet)
printf("%04d-%02d-%02d %02d:%02d:%02d\n",
tmnow.tm_year + 1900,
tmnow.tm_mon + 1,
tmnow.tm_mday,
tmnow.tm_hour, tmnow.tm_min, tmnow.tm_sec);
} else {
set_time(&tmnow);
readclock(RTCDEV_SET_TIME, &tmnow, flags);
}
}
exit(0);
@ -125,12 +129,12 @@ errmsg(char *s)
{
static char *prompt = "readclock: ";
printf("%s%s\n", prompt, s);
if (!quiet) printf("%s%s\n", prompt, s);
prompt = "";
}
void
get_time(struct tm *t)
static void
readclock(int type, struct tm *t, int flags)
{
int r;
message m;
@ -138,47 +142,16 @@ get_time(struct tm *t)
r = minix_rs_lookup("readclock.drv", &ep);
if (r != 0) {
errmsg("Couldn't locate readclock.drv\n");
if (!quiet) errmsg("Couldn't locate readclock.drv\n");
exit(1);
}
m.RTCDEV_TM = t;
m.RTCDEV_FLAGS = (y2kflag) ? RTCDEV_Y2KBUG : RTCDEV_NOFLAGS;
m.RTCDEV_TM = (char *) t;
m.RTCDEV_FLAGS = flags;
r = _syscall(ep, RTCDEV_GET_TIME, &m);
r = _syscall(ep, type, &m);
if (r != RTCDEV_REPLY || m.RTCDEV_STATUS != 0) {
errmsg("Call to readclock.drv failed\n");
exit(1);
}
}
void
set_time(struct tm *t)
{
int r;
message m;
endpoint_t ep;
r = minix_rs_lookup("readclock.drv", &ep);
if (r != 0) {
errmsg("Couldn't locate readclock.drv\n");
exit(1);
}
m.RTCDEV_TM = t;
m.RTCDEV_FLAGS = RTCDEV_NOFLAGS;
if (y2kflag) {
m.RTCDEV_FLAGS |= RTCDEV_Y2KBUG;
}
if (Wflag) {
m.RTCDEV_FLAGS |= RTCDEV_CMOSREG;
}
r = _syscall(ep, RTCDEV_SET_TIME, &m);
if (r != RTCDEV_REPLY || m.RTCDEV_STATUS != 0) {
errmsg("Call to readclock.drv failed\n");
if (!quiet) errmsg("Call to readclock.drv failed\n");
exit(1);
}
}
@ -186,6 +159,6 @@ set_time(struct tm *t)
void
usage(void)
{
printf("Usage: readclock [-nwW2]\n");
if (!quiet) printf("Usage: readclock [-nqwW2]\n");
exit(1);
}

2
etc/rc
View file

@ -126,7 +126,7 @@ start)
# Start real time clock driver & set system time, otherwise default date.
up readclock.drv
readclock || date 201301010000
readclock -q || date 201301010000
# Initialize files.
>/etc/utmp # /etc/utmp keeps track of logins

View file

@ -1,11 +1,11 @@
.TH READCLOCK 8
.SH NAME
readclock \- read the AT's real time clock
readclock \- read or set a real time clock
.SH SYNOPSIS
\fBreadclock\fP [\fB\-nwW2\fP]
\fBreadclock\fP [\fB\-nqwW2\fP]
.SH DESCRIPTION
.B Readclock
reads the AT's real time clock and sets the machine's time. It is usually
reads the real time clock and sets the operating system time. It is usually
the second thing done in
.BR /etc/rc ,
the first thing is setting the time zone by sourcing
@ -20,8 +20,11 @@ want to run the clock in GMT then you can put
Play-act, don't set the time nor change the calibration data, just show what
would be done.
.TP
.B \-q
Quiet execution. Suppresses all output.
.TP
.B \-w
Write the current time to the CMOS clock. Dangerous, see
Write the current time to the hardware clock. Dangerous, see
.BR BUGS .
Don't forget to use
.B "TZ=GMT"