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

2
etc/rc
View File

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

View File

@ -1,11 +1,11 @@
.TH READCLOCK 8 .TH READCLOCK 8
.SH NAME .SH NAME
readclock \- read the AT's real time clock readclock \- read or set a real time clock
.SH SYNOPSIS .SH SYNOPSIS
\fBreadclock\fP [\fB\-nwW2\fP] \fBreadclock\fP [\fB\-nqwW2\fP]
.SH DESCRIPTION .SH DESCRIPTION
.B Readclock .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 the second thing done in
.BR /etc/rc , .BR /etc/rc ,
the first thing is setting the time zone by sourcing 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 Play-act, don't set the time nor change the calibration data, just show what
would be done. would be done.
.TP .TP
.B \-q
Quiet execution. Suppresses all output.
.TP
.B \-w .B \-w
Write the current time to the CMOS clock. Dangerous, see Write the current time to the hardware clock. Dangerous, see
.BR BUGS . .BR BUGS .
Don't forget to use Don't forget to use
.B "TZ=GMT" .B "TZ=GMT"