90
82
static int hwaudit_on;
93
#define MYNAME "hwclock"
95
char *progname = MYNAME;
97
85
/* The struct that holds our hardware access routines */
98
86
struct clock_ops *ur;
100
88
#define FLOOR(arg) ((arg >= 0 ? (int) arg : ((int) arg) - 1));
102
/* Here the information for time adjustments is kept. */
103
#define ADJPATH "/etc/adjtime"
105
90
const char *adj_file_name = NULL;
107
/* Store the date here when "badyear" flag is set. */
108
#define LASTDATE "/var/lib/lastdate"
111
/* This is information we keep in the adjtime file that tells us how
112
to do drift corrections. Elements are all straight from the
113
adjtime file, so see documentation of that file for details.
114
Exception is <dirty>, which is an indication that what's in this
115
structure is not what's in the disk file (because it has been
116
updated since read from the disk file).
122
time_t last_adj_time;
126
time_t last_calib_time;
127
/* The most recent time that we set the clock from an external
128
authority (as opposed to just doing a drift adjustment) */
131
enum a_local_utc {LOCAL, UTC, UNKNOWN} local_utc;
132
/* To which time zone, local or UTC, we most recently set the
94
* This is information we keep in the adjtime file that tells us how
95
* to do drift corrections. Elements are all straight from the
96
* adjtime file, so see documentation of that file for details.
97
* Exception is <dirty>, which is an indication that what's in this
98
* structure is not what's in the disk file (because it has been
99
* updated since read from the disk file).
104
time_t last_adj_time;
107
time_t last_calib_time;
109
* The most recent time that we set the clock from an external
110
* authority (as opposed to just doing a drift adjustment)
113
enum a_local_utc { LOCAL, UTC, UNKNOWN } local_utc;
115
* To which time zone, local or UTC, we most recently set the
120
/* Long only options. */
122
OPT_SET = CHAR_MAX + 1,
138
* We are running in debug mode, wherein we put a lot of information about
139
* what we're doing to standard output.
137
/* We are running in debug mode, wherein we put a lot of information about
138
what we're doing to standard output. */
143
/* Workaround for Award 4.50g BIOS bug: keep the year in a file. */
141
/* Workaround for Award 4.50g BIOS bug: keep the year in a file. */
143
int epoch_option = -1;
144
/* User-specified epoch, used when rtc fails to return epoch. */
147
* Almost all Award BIOS's made between 04/26/94 and 05/31/95
148
* have a nasty bug limiting the RTC year byte to the range 94-99.
149
* Any year between 2000 and 2093 gets changed to 2094, every time
150
* you start the system.
151
* With the --badyear option, we write the date to file and hope
152
* that the file is updated at least once a year.
153
* I recommend putting this command "hwclock --badyear" in the monthly
154
* crontab, just to be safe. -- Dave Coffin 11/12/98
157
write_date_to_file (struct tm *tm) {
160
if ((fp = fopen(LASTDATE,"w"))) {
161
fprintf(fp,"%02d.%02d.%04d\n", tm->tm_mday, tm->tm_mon+1,
169
read_date_from_file (struct tm *tm) {
170
int last_mday, last_mon, last_year;
173
if ((fp = fopen(LASTDATE,"r"))) {
174
if (fscanf (fp,"%d.%d.%d\n", &last_mday, &last_mon, &last_year) == 3) {
175
tm->tm_year = last_year-1900;
176
if ((tm->tm_mon << 5) + tm->tm_mday < ((last_mon-1) << 5) + last_mday)
181
write_date_to_file (tm);
185
time_diff(struct timeval subtrahend, struct timeval subtractor) {
186
/*---------------------------------------------------------------------------
187
The difference in seconds between two times in "timeval" format.
188
----------------------------------------------------------------------------*/
189
return (subtrahend.tv_sec - subtractor.tv_sec)
190
+ (subtrahend.tv_usec - subtractor.tv_usec) / 1E6;
194
static struct timeval
195
time_inc(struct timeval addend, double increment) {
196
/*----------------------------------------------------------------------------
197
The time, in "timeval" format, which is <increment> seconds after
198
the time <addend>. Of course, <increment> may be negative.
199
-----------------------------------------------------------------------------*/
200
struct timeval newtime;
202
newtime.tv_sec = addend.tv_sec + (int) increment;
203
newtime.tv_usec = addend.tv_usec + (increment - (int) increment) * 1E6;
205
/* Now adjust it so that the microsecond value is between 0 and 1 million */
206
if (newtime.tv_usec < 0) {
207
newtime.tv_usec += 1E6;
209
} else if (newtime.tv_usec >= 1E6) {
210
newtime.tv_usec -= 1E6;
146
/* User-specified epoch, used when rtc fails to return epoch. */
147
unsigned long epoch_option = -1;
150
* Almost all Award BIOS's made between 04/26/94 and 05/31/95 have a nasty
151
* bug limiting the RTC year byte to the range 94-99. Any year between 2000
152
* and 2093 gets changed to 2094, every time you start the system.
154
* With the --badyear option, we write the date to file and hope that the
155
* file is updated at least once a year. I recommend putting this command
156
* "hwclock --badyear" in the monthly crontab, just to be safe.
158
* -- Dave Coffin 11/12/98
160
static void write_date_to_file(struct tm *tm)
164
if ((fp = fopen(_PATH_LASTDATE, "w"))) {
165
fprintf(fp, "%02d.%02d.%04d\n", tm->tm_mday, tm->tm_mon + 1,
169
warn(_("cannot write %s"), _PATH_LASTDATE);
172
static void read_date_from_file(struct tm *tm)
174
int last_mday, last_mon, last_year;
177
if ((fp = fopen(_PATH_LASTDATE, "r"))) {
178
if (fscanf(fp, "%d.%d.%d\n", &last_mday, &last_mon, &last_year)
180
tm->tm_year = last_year - 1900;
181
if ((tm->tm_mon << 5) + tm->tm_mday <
182
((last_mon - 1) << 5) + last_mday)
187
write_date_to_file(tm);
191
* The difference in seconds between two times in "timeval" format.
193
double time_diff(struct timeval subtrahend, struct timeval subtractor)
195
return (subtrahend.tv_sec - subtractor.tv_sec)
196
+ (subtrahend.tv_usec - subtractor.tv_usec) / 1E6;
200
* The time, in "timeval" format, which is <increment> seconds after the
201
* time <addend>. Of course, <increment> may be negative.
203
static struct timeval time_inc(struct timeval addend, double increment)
205
struct timeval newtime;
207
newtime.tv_sec = addend.tv_sec + (int)increment;
208
newtime.tv_usec = addend.tv_usec + (increment - (int)increment) * 1E6;
211
* Now adjust it so that the microsecond value is between 0 and 1
214
if (newtime.tv_usec < 0) {
215
newtime.tv_usec += 1E6;
217
} else if (newtime.tv_usec >= 1E6) {
218
newtime.tv_usec -= 1E6;
218
225
hw_clock_is_utc(const bool utc, const bool local_opt,
219
const struct adjtime adjtime) {
226
const struct adjtime adjtime)
224
232
else if (local_opt)
225
233
ret = FALSE; /* --localtime explicitly given */
227
/* get info from adjtime file - default is local */
228
ret = (adjtime.local_utc == UTC);
235
/* get info from adjtime file - default is UTC */
236
ret = (adjtime.local_utc != LOCAL);
230
238
printf(_("Assuming hardware clock is kept in %s time.\n"),
231
239
ret ? _("UTC") : _("local"));
238
read_adjtime(struct adjtime *adjtime_p) {
239
/*----------------------------------------------------------------------------
240
Read the adjustment parameters out of the /etc/adjtime file.
242
Return them as the adjtime structure <*adjtime_p>.
243
If there is no /etc/adjtime file, return defaults.
244
If values are missing from the file, return defaults for them.
246
return value 0 if all OK, !=0 otherwise.
248
-----------------------------------------------------------------------------*/
250
int rc; /* local return code */
251
struct stat statbuf; /* We don't even use the contents of this. */
253
rc = stat(adj_file_name, &statbuf);
254
if (rc < 0 && errno == ENOENT) {
255
/* He doesn't have a adjtime file, so we'll use defaults. */
256
adjtime_p->drift_factor = 0;
257
adjtime_p->last_adj_time = 0;
258
adjtime_p->not_adjusted = 0;
259
adjtime_p->last_calib_time = 0;
260
adjtime_p->local_utc = UNKNOWN;
261
adjtime_p->dirty = FALSE; /* don't create a zero adjfile */
266
adjfile = fopen(adj_file_name, "r"); /* open file for reading */
267
if (adjfile == NULL) {
268
outsyserr("cannot open file %s", adj_file_name);
273
char line1[81]; /* String: first line of adjtime file */
274
char line2[81]; /* String: second line of adjtime file */
275
char line3[81]; /* String: third line of adjtime file */
278
if (!fgets(line1, sizeof(line1), adjfile))
279
line1[0] = '\0'; /* In case fgets fails */
280
if (!fgets(line2, sizeof(line2), adjfile))
281
line2[0] = '\0'; /* In case fgets fails */
282
if (!fgets(line3, sizeof(line3), adjfile))
283
line3[0] = '\0'; /* In case fgets fails */
287
/* Set defaults in case values are missing from file */
288
adjtime_p->drift_factor = 0;
289
adjtime_p->last_adj_time = 0;
290
adjtime_p->not_adjusted = 0;
291
adjtime_p->last_calib_time = 0;
294
sscanf(line1, "%lf %ld %lf",
295
&adjtime_p->drift_factor,
297
&adjtime_p->not_adjusted);
298
adjtime_p->last_adj_time = timeval;
300
sscanf(line2, "%ld", &timeval);
301
adjtime_p->last_calib_time = timeval;
303
if (!strcmp(line3, "UTC\n"))
304
adjtime_p->local_utc = UTC;
305
else if (!strcmp(line3, "LOCAL\n"))
306
adjtime_p->local_utc = LOCAL;
308
adjtime_p->local_utc = UNKNOWN;
311
_("%s: Warning: unrecognized third line in adjtime file\n"),
313
fprintf(stderr, _("(Expected: `UTC' or `LOCAL' or nothing.)\n"));
317
adjtime_p->dirty = FALSE;
320
printf(_("Last drift adjustment done at %ld seconds after 1969\n"),
321
(long) adjtime_p->last_adj_time);
322
printf(_("Last calibration done at %ld seconds after 1969\n"),
323
(long) adjtime_p->last_calib_time);
324
printf(_("Hardware clock is on %s time\n"),
325
(adjtime_p->local_utc == LOCAL) ? _("local") :
326
(adjtime_p->local_utc == UTC) ? _("UTC") : _("unknown"));
244
* Read the adjustment parameters out of the /etc/adjtime file.
246
* Return them as the adjtime structure <*adjtime_p>. If there is no
247
* /etc/adjtime file, return defaults. If values are missing from the file,
248
* return defaults for them.
250
* return value 0 if all OK, !=0 otherwise.
252
static int read_adjtime(struct adjtime *adjtime_p)
255
int rc; /* local return code */
256
struct stat statbuf; /* We don't even use the contents of this. */
257
char line1[81]; /* String: first line of adjtime file */
258
char line2[81]; /* String: second line of adjtime file */
259
char line3[81]; /* String: third line of adjtime file */
262
rc = stat(adj_file_name, &statbuf);
263
if (rc < 0 && errno == ENOENT) {
264
/* He doesn't have a adjtime file, so we'll use defaults. */
265
adjtime_p->drift_factor = 0;
266
adjtime_p->last_adj_time = 0;
267
adjtime_p->not_adjusted = 0;
268
adjtime_p->last_calib_time = 0;
269
adjtime_p->local_utc = UNKNOWN;
270
adjtime_p->dirty = FALSE; /* don't create a zero adjfile */
275
adjfile = fopen(adj_file_name, "r"); /* open file for reading */
276
if (adjfile == NULL) {
277
warn("cannot open file %s", adj_file_name);
282
if (!fgets(line1, sizeof(line1), adjfile))
283
line1[0] = '\0'; /* In case fgets fails */
284
if (!fgets(line2, sizeof(line2), adjfile))
285
line2[0] = '\0'; /* In case fgets fails */
286
if (!fgets(line3, sizeof(line3), adjfile))
287
line3[0] = '\0'; /* In case fgets fails */
291
/* Set defaults in case values are missing from file */
292
adjtime_p->drift_factor = 0;
293
adjtime_p->last_adj_time = 0;
294
adjtime_p->not_adjusted = 0;
295
adjtime_p->last_calib_time = 0;
298
sscanf(line1, "%lf %ld %lf",
299
&adjtime_p->drift_factor,
300
&timeval, &adjtime_p->not_adjusted);
301
adjtime_p->last_adj_time = timeval;
303
sscanf(line2, "%ld", &timeval);
304
adjtime_p->last_calib_time = timeval;
306
if (!strcmp(line3, "UTC\n")) {
307
adjtime_p->local_utc = UTC;
308
} else if (!strcmp(line3, "LOCAL\n")) {
309
adjtime_p->local_utc = LOCAL;
311
adjtime_p->local_utc = UNKNOWN;
313
warnx(_("Warning: unrecognized third line in adjtime file\n"
314
"(Expected: `UTC' or `LOCAL' or nothing.)"));
318
adjtime_p->dirty = FALSE;
322
("Last drift adjustment done at %ld seconds after 1969\n"),
323
(long)adjtime_p->last_adj_time);
324
printf(_("Last calibration done at %ld seconds after 1969\n"),
325
(long)adjtime_p->last_calib_time);
326
printf(_("Hardware clock is on %s time\n"),
327
(adjtime_p->local_utc ==
328
LOCAL) ? _("local") : (adjtime_p->local_utc ==
329
UTC) ? _("UTC") : _("unknown"));
334
synchronize_to_clock_tick(void) {
335
/*-----------------------------------------------------------------------------
336
Wait until the falling edge of the Hardware Clock's update flag so
337
that any time that is read from the clock immediately after we
338
return will be exact.
340
The clock only has 1 second precision, so it gives the exact time only
341
once per second, right on the falling edge of the update flag.
343
We wait (up to one second) either blocked waiting for an rtc device
344
or in a CPU spin loop. The former is probably not very accurate.
346
Return 0 if it worked, nonzero if it didn't.
347
-----------------------------------------------------------------------------*/
336
* Wait until the falling edge of the Hardware Clock's update flag so that
337
* any time that is read from the clock immediately after we return will be
340
* The clock only has 1 second precision, so it gives the exact time only
341
* once per second, right on the falling edge of the update flag.
343
* We wait (up to one second) either blocked waiting for an rtc device or in
344
* a CPU spin loop. The former is probably not very accurate.
346
* Return 0 if it worked, nonzero if it didn't.
348
static int synchronize_to_clock_tick(void)
350
if (debug) printf(_("Waiting for clock tick...\n"));
353
printf(_("Waiting for clock tick...\n"));
352
355
rc = ur->synchronize_to_clock_tick();
368
* Convert a time in broken down format (hours, minutes, etc.) into standard
369
* unix time (seconds into epoch). Return it as *systime_p.
371
* The broken down time is argument <tm>. This broken down time is either
372
* in local time zone or UTC, depending on value of logical argument
373
* "universal". True means it is in UTC.
375
* If the argument contains values that do not constitute a valid time, and
376
* mktime() recognizes this, return *valid_p == false and *systime_p
377
* undefined. However, mktime() sometimes goes ahead and computes a
378
* fictional time "as if" the input values were valid, e.g. if they indicate
379
* the 31st day of April, mktime() may compute the time of May 1. In such a
380
* case, we return the same fictional value mktime() does as *systime_p and
381
* return *valid_p == true.
367
384
mktime_tz(struct tm tm, const bool universal,
368
bool *valid_p, time_t *systime_p) {
369
/*-----------------------------------------------------------------------------
370
Convert a time in broken down format (hours, minutes, etc.) into standard
371
unix time (seconds into epoch). Return it as *systime_p.
373
The broken down time is argument <tm>. This broken down time is either in
374
local time zone or UTC, depending on value of logical argument "universal".
375
True means it is in UTC.
377
If the argument contains values that do not constitute a valid time,
378
and mktime() recognizes this, return *valid_p == false and
379
*systime_p undefined. However, mktime() sometimes goes ahead and
380
computes a fictional time "as if" the input values were valid,
381
e.g. if they indicate the 31st day of April, mktime() may compute
382
the time of May 1. In such a case, we return the same fictional
383
value mktime() does as *systime_p and return *valid_p == true.
385
-----------------------------------------------------------------------------*/
386
time_t mktime_result; /* The value returned by our mktime() call */
387
char *zone; /* Local time zone name */
389
/* We use the C library function mktime(), but since it only works on
390
local time zone input, we may have to fake it out by temporarily
391
changing the local time zone to UTC.
393
zone = getenv("TZ"); /* remember original time zone */
395
/* Set timezone to UTC */
396
setenv("TZ", "", TRUE);
397
/* Note: tzset() gets called implicitly by the time code, but only the
398
first time. When changing the environment variable, better call
403
mktime_result = mktime(&tm);
404
if (mktime_result == -1) {
405
/* This apparently (not specified in mktime() documentation) means
406
the 'tm' structure does not contain valid values (however, not
407
containing valid values does _not_ imply mktime() returns -1).
412
printf(_("Invalid values in hardware clock: "
413
"%4d/%.2d/%.2d %.2d:%.2d:%.2d\n"),
414
tm.tm_year+1900, tm.tm_mon+1, tm.tm_mday,
415
tm.tm_hour, tm.tm_min, tm.tm_sec);
418
*systime_p = mktime_result;
420
printf(_("Hw clock time : %4d/%.2d/%.2d %.2d:%.2d:%.2d = "
421
"%ld seconds since 1969\n"),
422
tm.tm_year+1900, tm.tm_mon+1, tm.tm_mday,
423
tm.tm_hour, tm.tm_min, tm.tm_sec, (long) *systime_p);
425
/* now put back the original zone. */
426
if (zone) setenv("TZ", zone, TRUE);
385
bool * valid_p, time_t * systime_p)
387
time_t mktime_result; /* The value returned by our mktime() call */
388
char *zone; /* Local time zone name */
391
* We use the C library function mktime(), but since it only works
392
* on local time zone input, we may have to fake it out by
393
* temporarily changing the local time zone to UTC.
395
zone = getenv("TZ"); /* remember original time zone */
397
/* Set timezone to UTC */
398
setenv("TZ", "", TRUE);
400
* Note: tzset() gets called implicitly by the time code,
401
* but only the first time. When changing the environment
402
* variable, better call tzset() explicitly.
406
mktime_result = mktime(&tm);
407
if (mktime_result == -1) {
409
* This apparently (not specified in mktime() documentation)
410
* means the 'tm' structure does not contain valid values
411
* (however, not containing valid values does _not_ imply
412
* mktime() returns -1).
417
printf(_("Invalid values in hardware clock: "
418
"%4d/%.2d/%.2d %.2d:%.2d:%.2d\n"),
419
tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
420
tm.tm_hour, tm.tm_min, tm.tm_sec);
423
*systime_p = mktime_result;
426
("Hw clock time : %4d/%.2d/%.2d %.2d:%.2d:%.2d = "
427
"%ld seconds since 1969\n"), tm.tm_year + 1900,
428
tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min,
429
tm.tm_sec, (long)*systime_p);
431
/* now put back the original zone. */
433
setenv("TZ", zone, TRUE);
440
* Read the hardware clock and return the current time via <tm> argument.
442
* Use the method indicated by <method> argument to access the hardware
433
read_hardware_clock(const bool universal, bool *valid_p, time_t *systime_p){
434
/*----------------------------------------------------------------------------
435
Read the hardware clock and return the current time via <tm> argument.
437
Use the method indicated by <method> argument to access the hardware clock.
438
-----------------------------------------------------------------------------*/
442
err = ur->read_hardware_clock(&tm);
447
read_date_from_file(&tm);
450
printf (_("Time read from Hardware Clock: %4d/%.2d/%.2d %02d:%02d:%02d\n"),
451
tm.tm_year+1900, tm.tm_mon+1, tm.tm_mday,
452
tm.tm_hour, tm.tm_min, tm.tm_sec);
453
mktime_tz(tm, universal, valid_p, systime_p);
446
read_hardware_clock(const bool universal, bool * valid_p, time_t * systime_p)
451
err = ur->read_hardware_clock(&tm);
456
read_date_from_file(&tm);
460
("Time read from Hardware Clock: %4d/%.2d/%.2d %02d:%02d:%02d\n"),
461
tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour,
462
tm.tm_min, tm.tm_sec);
463
mktime_tz(tm, universal, valid_p, systime_p);
469
* Set the Hardware Clock to the time <newtime>, in local time zone or UTC,
470
* according to <universal>.
460
473
set_hardware_clock(const time_t newtime,
461
const bool universal,
462
const bool testing) {
463
/*----------------------------------------------------------------------------
464
Set the Hardware Clock to the time <newtime>, in local time zone or UTC,
465
according to <universal>.
466
----------------------------------------------------------------------------*/
468
struct tm new_broken_time;
469
/* Time to which we will set Hardware Clock, in broken down format, in
470
the time zone of caller's choice
474
new_broken_time = *gmtime(&newtime);
476
new_broken_time = *localtime(&newtime);
479
printf(_("Setting Hardware Clock to %.2d:%.2d:%.2d "
480
"= %ld seconds since 1969\n"),
481
new_broken_time.tm_hour, new_broken_time.tm_min,
482
new_broken_time.tm_sec, (long) newtime);
485
printf(_("Clock not changed - testing only.\n"));
489
* Write the real year to a file, then write a fake year
490
* between 1995 and 1998 to the RTC. This way, Award BIOS boots
491
* on 29 Feb 2000 thinking that it's 29 Feb 1996.
493
write_date_to_file (&new_broken_time);
494
new_broken_time.tm_year = 95 + ((new_broken_time.tm_year+1) & 3);
496
err = ur->set_hardware_clock(&new_broken_time);
474
const bool universal, const bool testing)
476
struct tm new_broken_time;
478
* Time to which we will set Hardware Clock, in broken down format,
479
* in the time zone of caller's choice
483
new_broken_time = *gmtime(&newtime);
485
new_broken_time = *localtime(&newtime);
488
printf(_("Setting Hardware Clock to %.2d:%.2d:%.2d "
489
"= %ld seconds since 1969\n"),
490
new_broken_time.tm_hour, new_broken_time.tm_min,
491
new_broken_time.tm_sec, (long)newtime);
494
printf(_("Clock not changed - testing only.\n"));
498
* Write the real year to a file, then write a fake
499
* year between 1995 and 1998 to the RTC. This way,
500
* Award BIOS boots on 29 Feb 2000 thinking that
503
write_date_to_file(&new_broken_time);
504
new_broken_time.tm_year =
505
95 + ((new_broken_time.tm_year + 1) & 3);
507
ur->set_hardware_clock(&new_broken_time);
512
* Set the Hardware Clock to the time "sethwtime", in local time zone or
513
* UTC, according to "universal".
515
* Wait for a fraction of a second so that "sethwtime" is the value of the
516
* Hardware Clock as of system time "refsystime", which is in the past. For
517
* example, if "sethwtime" is 14:03:05 and "refsystime" is 12:10:04.5 and
518
* the current system time is 12:10:06.0: Wait .5 seconds (to make exactly 2
519
* seconds since "refsystime") and then set the Hardware Clock to 14:03:07,
520
* thus getting a precise and retroactive setting of the clock.
522
* (Don't be confused by the fact that the system clock and the Hardware
523
* Clock differ by two hours in the above example. That's just to remind you
524
* that there are two independent time scales here).
526
* This function ought to be able to accept set times as fractional times.
527
* Idea for future enhancement.
503
530
set_hardware_clock_exact(const time_t sethwtime,
504
const struct timeval refsystime,
505
const bool universal,
506
const bool testing) {
507
/*----------------------------------------------------------------------------
508
Set the Hardware Clock to the time "sethwtime", in local time zone or UTC,
509
according to "universal".
511
Wait for a fraction of a second so that "sethwtime" is the value of
512
the Hardware Clock as of system time "refsystime", which is in the past.
513
For example, if "sethwtime" is 14:03:05 and "refsystime" is 12:10:04.5
514
and the current system time is 12:10:06.0: Wait .5 seconds (to make
515
exactly 2 seconds since "refsystime") and then set the Hardware Clock
516
to 14:03:07, thus getting a precise and retroactive setting of the clock.
518
(Don't be confused by the fact that the system clock and the Hardware
519
Clock differ by two hours in the above example. That's just to remind
520
you that there are two independent time scales here).
522
This function ought to be able to accept set times as fractional times.
523
Idea for future enhancement.
524
-----------------------------------------------------------------------------*/
527
struct timeval beginsystime, nowsystime;
531
gettimeofday(&beginsystime, NULL);
532
tdiff = time_diff(beginsystime, refsystime);
533
newhwtime = sethwtime + (int) (tdiff + 0.5);
535
printf(_("Time elapsed since reference time has been %.6f seconds.\n"
536
"Delaying further to reach the new time.\n"), tdiff);
539
* Now delay some more until Hardware Clock time newhwtime arrives. The 0.5 s
540
* is because the Hardware Clock always sets to your set time plus 500 ms
541
* (because it is designed to update to the next second precisely 500 ms
542
* after you finish the setting).
545
gettimeofday(&nowsystime, NULL);
546
tdiff = time_diff(nowsystime, beginsystime);
548
goto time_resync; /* probably backward time reset */
550
goto time_resync; /* probably forward time reset */
551
beginsystime = nowsystime;
552
tdiff = time_diff(nowsystime, refsystime);
553
} while (newhwtime == sethwtime + (int) (tdiff + 0.5));
555
set_hardware_clock(newhwtime, universal, testing);
531
const struct timeval refsystime,
532
const bool universal, const bool testing)
534
time_t newhwtime = sethwtime;
535
struct timeval beginsystime, nowsystime;
540
* Now delay some more until Hardware Clock time newhwtime arrives.
541
* The 0.5 s is because the Hardware Clock always sets to your set
542
* time plus 500 ms (because it is designed to update to the next
543
* second precisely 500 ms after you finish the setting).
547
gettimeofday(&beginsystime, NULL);
548
tdiff = time_diff(beginsystime, refsystime);
549
newhwtime = sethwtime + (int)(tdiff + 0.5);
552
("Time elapsed since reference time has been %.6f seconds.\n"
553
"Delaying further to reach the new time.\n"),
558
gettimeofday(&nowsystime, NULL);
559
tdiff = time_diff(nowsystime, beginsystime);
561
time_resync = 1; /* probably backward time reset */
565
time_resync = 1; /* probably forward time reset */
568
beginsystime = nowsystime;
569
tdiff = time_diff(nowsystime, refsystime);
570
} while (newhwtime == sethwtime + (int)(tdiff + 0.5));
572
set_hardware_clock(newhwtime, universal, testing);
576
* Put the time "systime" on standard output in display format. Except if
577
* hclock_valid == false, just tell standard output that we don't know what
580
* Include in the output the adjustment "sync_duration".
561
583
display_time(const bool hclock_valid, const time_t systime,
562
const double sync_duration) {
563
/*----------------------------------------------------------------------------
564
Put the time "systime" on standard output in display format.
565
Except if hclock_valid == false, just tell standard output that we don't
566
know what time it is.
568
Include in the output the adjustment "sync_duration".
569
-----------------------------------------------------------------------------*/
571
fprintf(stderr, _("The Hardware Clock registers contain values that are "
572
"either invalid (e.g. 50th day of month) or beyond the range "
573
"we can handle (e.g. Year 2095).\n"));
579
lt = localtime(&systime);
580
strftime(ctime_now, sizeof(ctime_now), format, lt);
581
printf(_("%s %.6f seconds\n"), ctime_now, -(sync_duration));
584
const double sync_duration)
588
("The Hardware Clock registers contain values that are "
589
"either invalid (e.g. 50th day of month) or beyond the range "
590
"we can handle (e.g. Year 2095)."));
596
lt = localtime(&systime);
597
strftime(ctime_now, sizeof(ctime_now), format, lt);
598
printf(_("%s %.6f seconds\n"), ctime_now, -(sync_duration));
588
interpret_date_string(const char *date_opt, time_t * const time_p) {
589
/*----------------------------------------------------------------------------
590
Interpret the value of the --date option, which is something like
591
"13:05:01". In fact, it can be any of the myriad ASCII strings that specify
592
a time which the "date" program can understand. The date option value in
593
question is our "dateopt" argument.
595
The specified time is in the local time zone.
597
Our output, "*time_p", is a seconds-into-epoch time.
599
We use the "date" program to interpret the date string. "date" must be
600
runnable by issuing the command "date" to the /bin/sh shell. That means
601
in must be in the current PATH.
603
If anything goes wrong (and many things can), we return return code
604
10 and arbitrary *time_p. Otherwise, return code is 0 and *time_p
606
----------------------------------------------------------------------------*/
603
* Interpret the value of the --date option, which is something like
604
* "13:05:01". In fact, it can be any of the myriad ASCII strings that
605
* specify a time which the "date" program can understand. The date option
606
* value in question is our "dateopt" argument.
608
* The specified time is in the local time zone.
610
* Our output, "*time_p", is a seconds-into-epoch time.
612
* We use the "date" program to interpret the date string. "date" must be
613
* runnable by issuing the command "date" to the /bin/sh shell. That means
614
* in must be in the current PATH.
616
* If anything goes wrong (and many things can), we return return code 10
617
* and arbitrary *time_p. Otherwise, return code is 0 and *time_p is valid.
619
static int interpret_date_string(const char *date_opt, time_t * const time_p)
607
621
FILE *date_child_fp;
608
622
char date_resp[100];
609
const char magic[]="seconds-into-epoch=";
623
const char magic[] = "seconds-into-epoch=";
610
624
char date_command[100];
611
int retcode; /* our eventual return code */
612
int rc; /* local return code */
625
int retcode; /* our eventual return code */
626
int rc; /* local return code */
614
628
if (date_opt == NULL) {
615
fprintf(stderr, _("No --date option specified.\n"));
629
warnx(_("No --date option specified."));
619
633
/* prevent overflow - a security risk */
620
634
if (strlen(date_opt) > sizeof(date_command) - 50) {
621
fprintf(stderr, _("--date argument too long\n"));
635
warnx(_("--date argument too long"));
625
639
/* Quotes in date_opt would ruin the date command we construct. */
626
640
if (strchr(date_opt, '"') != NULL) {
628
_("The value of the --date option is not a valid date.\n"
629
"In particular, it contains quotation marks.\n"));
642
("The value of the --date option is not a valid date.\n"
643
"In particular, it contains quotation marks."));
698
* Set the System Clock to time 'newtime'.
700
* Also set the kernel time zone value to the value indicated by the TZ
701
* environment variable and/or /usr/lib/zoneinfo/, interpreted as tzset()
702
* would interpret them.
704
* EXCEPT: if hclock_valid is false, just issue an error message saying
705
* there is no valid time in the Hardware Clock to which to set the system
708
* If 'testing' is true, don't actually update anything -- just say we would
686
712
set_system_clock(const bool hclock_valid, const time_t newtime,
687
const bool testing) {
688
/*----------------------------------------------------------------------------
689
Set the System Clock to time 'newtime'.
691
Also set the kernel time zone value to the value indicated by the
692
TZ environment variable and/or /usr/lib/zoneinfo/, interpreted as
693
tzset() would interpret them.
695
EXCEPT: if hclock_valid is false, just issue an error message
696
saying there is no valid time in the Hardware Clock to which to set
699
If 'testing' is true, don't actually update anything -- just say we
701
-----------------------------------------------------------------------------*/
705
fprintf(stderr, _("The Hardware Clock does not contain a valid time, so "
706
"we cannot set the System Time from it.\n"));
717
broken = localtime(&newtime);
718
#ifdef HAVE_TM_GMTOFF
719
minuteswest = -broken->tm_gmtoff/60; /* GNU extension */
721
minuteswest = timezone/60;
722
if (broken->tm_isdst)
727
printf(_("Calling settimeofday:\n"));
728
printf(_("\ttv.tv_sec = %ld, tv.tv_usec = %ld\n"),
729
(long) tv.tv_sec, (long) tv.tv_usec);
730
printf(_("\ttz.tz_minuteswest = %d\n"), minuteswest);
733
printf(_("Not setting system clock because running in test mode.\n"));
736
const struct timezone tz = { minuteswest, 0 };
738
rc = settimeofday(&tv, &tz);
740
if (errno == EPERM) {
742
_("Must be superuser to set system clock.\n"));
745
outsyserr(_("settimeofday() failed"));
756
set_system_clock_timezone(const bool universal, const bool testing) {
757
/*----------------------------------------------------------------------------
758
Reset the System Clock from local time to UTC, based on its current
759
value and the timezone unless universal is TRUE.
761
Also set the kernel time zone value to the value indicated by the
762
TZ environment variable and/or /usr/lib/zoneinfo/, interpreted as
763
tzset() would interpret them.
765
If 'testing' is true, don't actually update anything -- just say we
767
-----------------------------------------------------------------------------*/
774
gettimeofday(&tv, NULL);
776
struct tm broken_time;
779
broken_time = *gmtime(&tv.tv_sec);
780
strftime(ctime_now, sizeof(ctime_now), "%Y/%m/%d %H:%M:%S", &broken_time);
781
printf(_("Current system time: %ld = %s\n"), (long) tv.tv_sec, ctime_now);
784
broken = localtime(&tv.tv_sec);
785
#ifdef HAVE_TM_GMTOFF
786
minuteswest = -broken->tm_gmtoff/60; /* GNU extension */
788
minuteswest = timezone/60;
789
if (broken->tm_isdst)
793
gettimeofday(&tv, NULL);
795
tv.tv_sec += minuteswest * 60;
798
struct tm broken_time;
801
broken_time = *gmtime(&tv.tv_sec);
802
strftime(ctime_now, sizeof(ctime_now), "%Y/%m/%d %H:%M:%S", &broken_time);
804
printf(_("Calling settimeofday:\n"));
805
printf(_("\tUTC: %s\n"), ctime_now);
806
printf(_("\ttv.tv_sec = %ld, tv.tv_usec = %ld\n"),
807
(long) tv.tv_sec, (long) tv.tv_usec);
808
printf(_("\ttz.tz_minuteswest = %d\n"), minuteswest);
811
printf(_("Not setting system clock because running in test mode.\n"));
814
const struct timezone tz = { minuteswest, 0 };
816
rc = settimeofday(&tv, &tz);
818
if (errno == EPERM) {
820
_("Must be superuser to set system clock.\n"));
823
outsyserr(_("settimeofday() failed"));
719
("The Hardware Clock does not contain a valid time, so "
720
"we cannot set the System Time from it."));
731
broken = localtime(&newtime);
732
#ifdef HAVE_TM_GMTOFF
733
minuteswest = -broken->tm_gmtoff / 60; /* GNU extension */
735
minuteswest = timezone / 60;
736
if (broken->tm_isdst)
741
printf(_("Calling settimeofday:\n"));
742
printf(_("\ttv.tv_sec = %ld, tv.tv_usec = %ld\n"),
743
(long)tv.tv_sec, (long)tv.tv_usec);
744
printf(_("\ttz.tz_minuteswest = %d\n"), minuteswest);
748
("Not setting system clock because running in test mode.\n"));
751
const struct timezone tz = { minuteswest, 0 };
753
rc = settimeofday(&tv, &tz);
755
if (errno == EPERM) {
757
("Must be superuser to set system clock."));
760
warn(_("settimeofday() failed"));
771
* Reset the System Clock from local time to UTC, based on its current value
772
* and the timezone unless universal is TRUE.
774
* Also set the kernel time zone value to the value indicated by the TZ
775
* environment variable and/or /usr/lib/zoneinfo/, interpreted as tzset()
776
* would interpret them.
778
* If 'testing' is true, don't actually update anything -- just say we would
781
static int set_system_clock_timezone(const bool universal, const bool testing)
789
gettimeofday(&tv, NULL);
791
struct tm broken_time;
794
broken_time = *gmtime(&tv.tv_sec);
795
strftime(ctime_now, sizeof(ctime_now), "%Y/%m/%d %H:%M:%S",
797
printf(_("Current system time: %ld = %s\n"), (long)tv.tv_sec,
801
broken = localtime(&tv.tv_sec);
802
#ifdef HAVE_TM_GMTOFF
803
minuteswest = -broken->tm_gmtoff / 60; /* GNU extension */
805
minuteswest = timezone / 60;
806
if (broken->tm_isdst)
810
gettimeofday(&tv, NULL);
812
tv.tv_sec += minuteswest * 60;
815
struct tm broken_time;
818
broken_time = *gmtime(&tv.tv_sec);
819
strftime(ctime_now, sizeof(ctime_now), "%Y/%m/%d %H:%M:%S",
822
printf(_("Calling settimeofday:\n"));
823
printf(_("\tUTC: %s\n"), ctime_now);
824
printf(_("\ttv.tv_sec = %ld, tv.tv_usec = %ld\n"),
825
(long)tv.tv_sec, (long)tv.tv_usec);
826
printf(_("\ttz.tz_minuteswest = %d\n"), minuteswest);
830
("Not setting system clock because running in test mode.\n"));
833
const struct timezone tz = { minuteswest, 0 };
835
rc = settimeofday(&tv, &tz);
837
if (errno == EPERM) {
839
("Must be superuser to set system clock."));
842
warn(_("settimeofday() failed"));
852
* Update the drift factor in <*adjtime_p> to reflect the fact that the
853
* Hardware Clock was calibrated to <nowtime> and before that was set to
856
* We record in the adjtime file the time at which we last calibrated the
857
* clock so we can compute the drift rate each time we calibrate.
859
* EXCEPT: if <hclock_valid> is false, assume Hardware Clock was not set
860
* before to anything meaningful and regular adjustments have not been done,
861
* so don't adjust the drift factor.
833
864
adjust_drift_factor(struct adjtime *adjtime_p,
834
const time_t nowtime,
835
const bool hclock_valid,
836
const time_t hclocktime,
837
const double sync_delay) {
838
/*------------------------------------------------------------------------
839
Update the drift factor in <*adjtime_p> to reflect the fact that the
840
Hardware Clock was calibrated to <nowtime> and before that was set
843
We record in the adjtime file the time at which we last calibrated
844
the clock so we can compute the drift rate each time we calibrate.
846
EXCEPT: if <hclock_valid> is false, assume Hardware Clock was not set
847
before to anything meaningful and regular adjustments have not been
848
done, so don't adjust the drift factor.
849
------------------------------------------------------------------------*/
865
const time_t nowtime,
866
const bool hclock_valid,
867
const time_t hclocktime, const double sync_delay)
850
869
if (!hclock_valid) {
852
871
printf(_("Not adjusting drift factor because the "
928
946
adjtime_p->dirty = TRUE;
950
* Do the drift adjustment calculation.
952
* The way we have to set the clock, we need the adjustment in two parts:
954
* 1) an integer number of seconds (return as *adjustment_p)
955
* 2) a positive fraction of a second (less than 1) (return as *retro_p)
957
* The sum of these two values is the adjustment needed. Positive means to
958
* advance the clock or insert seconds. Negative means to retard the clock
934
962
calculate_adjustment(const double factor,
935
const time_t last_time,
936
const double not_adjusted,
937
const time_t systime,
940
/*----------------------------------------------------------------------------
941
Do the drift adjustment calculation.
943
The way we have to set the clock, we need the adjustment in two parts:
945
1) an integer number of seconds (return as *adjustment_p)
947
2) a positive fraction of a second (less than 1) (return as *retro_p)
949
The sum of these two values is the adjustment needed. Positive means to
950
advance the clock or insert seconds. Negative means to retard the clock
952
----------------------------------------------------------------------------*/
953
double exact_adjustment;
955
exact_adjustment = ((double) (systime - last_time)) * factor / (24 * 60 * 60)
957
*adjustment_p = FLOOR(exact_adjustment);
959
*retro_p = exact_adjustment - (double) *adjustment_p;
961
printf (_("Time since last adjustment is %d seconds\n"),
962
(int) (systime - last_time));
963
printf (_("Need to insert %d seconds and refer time back "
964
"%.6f seconds ago\n"),
965
*adjustment_p, *retro_p);
972
save_adjtime(const struct adjtime adjtime, const bool testing) {
973
/*-----------------------------------------------------------------------------
974
Write the contents of the <adjtime> structure to its disk file.
976
But if the contents are clean (unchanged since read from disk), don't
978
-----------------------------------------------------------------------------*/
979
char newfile[412]; /* Stuff to write to disk file */
982
/* snprintf is not always available, but this is safe
983
as long as libc does not use more than 100 positions for %ld or %f */
984
sprintf(newfile, "%f %ld %f\n%ld\n%s\n",
985
adjtime.drift_factor,
986
(long) adjtime.last_adj_time,
987
adjtime.not_adjusted,
988
(long) adjtime.last_calib_time,
989
(adjtime.local_utc == UTC) ? "UTC" : "LOCAL");
992
printf(_("Not updating adjtime file because of testing mode.\n"));
993
printf(_("Would have written the following to %s:\n%s"),
994
adj_file_name, newfile);
999
adjfile = fopen(adj_file_name, "w");
1000
if (adjfile == NULL) {
1001
outsyserr(_("Could not open file with the clock adjustment parameters "
1002
"in it (%s) for writing"), adj_file_name);
1005
if (fputs(newfile, adjfile) < 0) {
1006
outsyserr(_("Could not update file with the clock adjustment "
1007
"parameters (%s) in it"), adj_file_name);
1010
if (fclose(adjfile) < 0) {
1011
outsyserr(_("Could not update file with the clock adjustment "
1012
"parameters (%s) in it"), adj_file_name);
1017
fprintf(stderr, _("Drift adjustment parameters not updated.\n"));
963
const time_t last_time,
964
const double not_adjusted,
965
const time_t systime, int *adjustment_p, double *retro_p)
967
double exact_adjustment;
970
((double)(systime - last_time)) * factor / (24 * 60 * 60)
972
*adjustment_p = FLOOR(exact_adjustment);
974
*retro_p = exact_adjustment - (double)*adjustment_p;
976
printf(_("Time since last adjustment is %d seconds\n"),
977
(int)(systime - last_time));
978
printf(_("Need to insert %d seconds and refer time back "
979
"%.6f seconds ago\n"), *adjustment_p, *retro_p);
984
* Write the contents of the <adjtime> structure to its disk file.
986
* But if the contents are clean (unchanged since read from disk), don't
989
static void save_adjtime(const struct adjtime adjtime, const bool testing)
991
char newfile[412]; /* Stuff to write to disk file */
995
* snprintf is not always available, but this is safe as
996
* long as libc does not use more than 100 positions for %ld
999
sprintf(newfile, "%f %ld %f\n%ld\n%s\n",
1000
adjtime.drift_factor,
1001
(long)adjtime.last_adj_time,
1002
adjtime.not_adjusted,
1003
(long)adjtime.last_calib_time,
1004
(adjtime.local_utc == UTC) ? "UTC" : "LOCAL");
1008
("Not updating adjtime file because of testing mode.\n"));
1009
printf(_("Would have written the following to %s:\n%s"),
1010
adj_file_name, newfile);
1015
adjfile = fopen(adj_file_name, "w");
1016
if (adjfile == NULL) {
1018
("Could not open file with the clock adjustment parameters "
1019
"in it (%s) for writing"), adj_file_name);
1022
if (fputs(newfile, adjfile) < 0) {
1024
("Could not update file with the clock adjustment "
1025
"parameters (%s) in it"),
1029
if (fclose(adjfile) < 0) {
1031
("Could not update file with the clock adjustment "
1032
"parameters (%s) in it"),
1039
("Drift adjustment parameters not updated."));
1045
* Do the adjustment requested, by 1) setting the Hardware Clock (if
1046
* necessary), and 2) updating the last-adjusted time in the adjtime
1049
* Do not update anything if the Hardware Clock does not currently present a
1052
* Arguments <factor> and <last_time> are current values from the adjtime
1055
* <hclock_valid> means the Hardware Clock contains a valid time, and that
1056
* time is <hclocktime>.
1058
* <read_time> is the current system time (to be precise, it is the system
1059
* time at the time <hclocktime> was read, which due to computational delay
1060
* could be a short time ago).
1062
* <universal>: the Hardware Clock is kept in UTC.
1064
* <testing>: We are running in test mode (no updating of clock).
1066
* We do not bother to update the clock if the adjustment would be less than
1067
* one second. This is to avoid cumulative error and needless CPU hogging
1068
* (remember we use an infinite loop for some timing) if the user runs us
1025
1072
do_adjustment(struct adjtime *adjtime_p,
1026
const bool hclock_valid, const time_t hclocktime,
1027
const struct timeval read_time,
1028
const bool universal, const bool testing) {
1029
/*---------------------------------------------------------------------------
1030
Do the adjustment requested, by 1) setting the Hardware Clock (if
1031
necessary), and 2) updating the last-adjusted time in the adjtime
1034
Do not update anything if the Hardware Clock does not currently present
1037
arguments <factor> and <last_time> are current values from the adjtime
1040
<hclock_valid> means the Hardware Clock contains a valid time, and that
1041
time is <hclocktime>.
1043
<read_time> is the current system time (to be precise, it is the system
1044
time at the time <hclocktime> was read, which due to computational delay
1045
could be a short time ago).
1047
<universal>: the Hardware Clock is kept in UTC.
1049
<testing>: We are running in test mode (no updating of clock).
1051
We do not bother to update the clock if the adjustment would be less than
1052
one second. This is to avoid cumulative error and needless CPU hogging
1053
(remember we use an infinite loop for some timing) if the user runs us
1056
----------------------------------------------------------------------------*/
1057
if (!hclock_valid) {
1058
fprintf(stderr, _("The Hardware Clock does not contain a valid time, "
1059
"so we cannot adjust it.\n"));
1060
adjtime_p->last_calib_time = 0; /* calibration startover is required */
1061
adjtime_p->last_adj_time = 0;
1062
adjtime_p->not_adjusted = 0;
1063
adjtime_p->dirty = TRUE;
1064
} else if (adjtime_p->last_adj_time == 0) {
1066
printf(_("Not setting clock because last adjustment time is zero, "
1067
"so history is bad."));
1070
/* Number of seconds we must insert in the Hardware Clock */
1072
/* Fraction of second we have to remove from clock after inserting
1073
<adjustment> whole seconds.
1075
calculate_adjustment(adjtime_p->drift_factor,
1076
adjtime_p->last_adj_time,
1077
adjtime_p->not_adjusted,
1079
&adjustment, &retro);
1080
if (adjustment > 0 || adjustment < -1) {
1081
set_hardware_clock_exact(hclocktime + adjustment,
1082
time_inc(read_time, -retro),
1083
universal, testing);
1084
adjtime_p->last_adj_time = hclocktime + adjustment;
1085
adjtime_p->not_adjusted = 0;
1086
adjtime_p->dirty = TRUE;
1089
printf(_("Needed adjustment is less than one second, "
1090
"so not setting clock.\n"));
1097
determine_clock_access_method(const bool user_requests_ISA) {
1101
if (user_requests_ISA)
1102
ur = probe_for_cmos_clock();
1105
ur = probe_for_rtc_clock();
1108
ur = probe_for_kd_clock();
1110
if (!ur && !user_requests_ISA)
1111
ur = probe_for_cmos_clock();
1115
printf(_("Using %s.\n"), ur->interface_name);
1117
printf(_("No usable clock interface found.\n"));
1073
const bool hclock_valid, const time_t hclocktime,
1074
const struct timeval read_time,
1075
const bool universal, const bool testing)
1077
if (!hclock_valid) {
1078
warnx(_("The Hardware Clock does not contain a valid time, "
1079
"so we cannot adjust it."));
1080
adjtime_p->last_calib_time = 0; /* calibration startover is required */
1081
adjtime_p->last_adj_time = 0;
1082
adjtime_p->not_adjusted = 0;
1083
adjtime_p->dirty = TRUE;
1084
} else if (adjtime_p->last_adj_time == 0) {
1087
("Not setting clock because last adjustment time is zero, "
1088
"so history is bad."));
1091
/* Number of seconds we must insert in the Hardware Clock */
1094
* Fraction of second we have to remove from clock after
1095
* inserting <adjustment> whole seconds.
1097
calculate_adjustment(adjtime_p->drift_factor,
1098
adjtime_p->last_adj_time,
1099
adjtime_p->not_adjusted,
1100
hclocktime, &adjustment, &retro);
1101
if (adjustment > 0 || adjustment < -1) {
1102
set_hardware_clock_exact(hclocktime + adjustment,
1103
time_inc(read_time, -retro),
1104
universal, testing);
1105
adjtime_p->last_adj_time = hclocktime + adjustment;
1106
adjtime_p->not_adjusted = 0;
1107
adjtime_p->dirty = TRUE;
1109
printf(_("Needed adjustment is less than one second, "
1110
"so not setting clock.\n"));
1114
static void determine_clock_access_method(const bool user_requests_ISA)
1118
if (user_requests_ISA)
1119
ur = probe_for_cmos_clock();
1123
ur = probe_for_rtc_clock();
1127
ur = probe_for_kd_clock();
1129
if (!ur && !user_requests_ISA)
1130
ur = probe_for_cmos_clock();
1134
printf(_("Using %s.\n"), ur->interface_name);
1136
printf(_("No usable clock interface found.\n"));
1141
* Do all the normal work of hwclock - read, set clock, etc.
1143
* Issue output to stdout and error message to stderr where appropriate.
1145
* Return rc == 0 if everything went OK, rc != 0 if not.
1122
1148
manipulate_clock(const bool show, const bool adjust, const bool noadjfile,
1123
const bool set, const time_t set_time,
1124
const bool hctosys, const bool systohc, const bool systz,
1125
const struct timeval startup_time,
1126
const bool utc, const bool local_opt,
1127
const bool testing, const bool predict) {
1128
/*---------------------------------------------------------------------------
1129
Do all the normal work of hwclock - read, set clock, etc.
1131
Issue output to stdout and error message to stderr where appropriate.
1133
Return rc == 0 if everything went OK, rc != 0 if not.
1134
----------------------------------------------------------------------------*/
1135
struct adjtime adjtime;
1136
/* Contents of the adjtime file, or what they should be. */
1137
int rc; /* local return code */
1138
bool no_auth; /* User lacks necessary authorization to access the clock */
1140
if (!systz && !predict) {
1141
no_auth = ur->get_permissions();
1146
if (!noadjfile && (adjust || set || systohc || (!utc && !local_opt) || predict)) {
1147
rc = read_adjtime(&adjtime);
1151
/* A little trick to avoid reading the file if we don't have to */
1152
adjtime.dirty = FALSE;
1157
const bool universal = hw_clock_is_utc(utc, local_opt, adjtime);
1159
if ((set || systohc || adjust) &&
1160
(adjtime.local_utc == UTC) != universal) {
1161
adjtime.local_utc = universal ? UTC : LOCAL;
1162
adjtime.dirty = TRUE;
1166
struct timeval read_time;
1167
/* The time at which we read the Hardware Clock */
1169
bool hclock_valid = FALSE;
1170
/* The Hardware Clock gives us a valid time, or at least something
1171
close enough to fool mktime().
1174
time_t hclocktime = 0;
1175
/* The time the hardware clock had just after we
1176
synchronized to its next clock tick when we started up.
1177
Defined only if hclock_valid is true.
1149
const bool set, const time_t set_time,
1150
const bool hctosys, const bool systohc, const bool systz,
1151
const struct timeval startup_time,
1152
const bool utc, const bool local_opt,
1153
const bool testing, const bool predict)
1155
/* Contents of the adjtime file, or what they should be. */
1156
struct adjtime adjtime;
1158
/* Set if user lacks necessary authorization to access the clock */
1160
/* The time at which we read the Hardware Clock */
1161
struct timeval read_time;
1163
* The Hardware Clock gives us a valid time, or at
1164
* least something close enough to fool mktime().
1166
bool hclock_valid = FALSE;
1168
* The time the hardware clock had just after we
1169
* synchronized to its next clock tick when we
1170
* started up. Defined only if hclock_valid is true.
1172
time_t hclocktime = 0;
1173
/* local return code */
1176
if (!systz && !predict) {
1177
no_auth = ur->get_permissions();
1183
&& (adjust || set || systohc || (!utc && !local_opt) || predict)) {
1184
rc = read_adjtime(&adjtime);
1188
/* A little trick to avoid reading the file if we don't have to */
1189
adjtime.dirty = FALSE;
1193
universal = hw_clock_is_utc(utc, local_opt, adjtime);
1195
if ((set || systohc || adjust) &&
1196
(adjtime.local_utc == UTC) != universal) {
1197
adjtime.local_utc = universal ? UTC : LOCAL;
1198
adjtime.dirty = TRUE;
1180
1201
if (show || adjust || hctosys || (!noadjfile && !systz && !predict)) {
1181
/* data from HW-clock are required */
1182
rc = synchronize_to_clock_tick();
1184
/* 2 = synchronization timeout. We don't error out if the user is
1185
attempting to set the RTC - the RTC could be functioning but
1186
contain invalid time data so we still want to allow a user to set
1190
if (rc && rc != 2 && !set && !systohc)
1192
gettimeofday(&read_time, NULL);
1194
/* If we can't synchronize to a clock tick, we likely can't read
1195
from the RTC so don't bother reading it again. */
1197
rc = read_hardware_clock(universal, &hclock_valid, &hclocktime);
1198
if (rc && !set && !systohc)
1202
/* data from HW-clock are required */
1203
rc = synchronize_to_clock_tick();
1206
* 2 = synchronization timeout. We don't
1207
* error out if the user is attempting to
1208
* set the RTC - the RTC could be
1209
* functioning but contain invalid time data
1210
* so we still want to allow a user to set
1213
if (rc && rc != 2 && !set && !systohc)
1215
gettimeofday(&read_time, NULL);
1218
* If we can't synchronize to a clock tick,
1219
* we likely can't read from the RTC so
1220
* don't bother reading it again.
1223
rc = read_hardware_clock(universal,
1224
&hclock_valid, &hclocktime);
1225
if (rc && !set && !systohc)
1204
display_time(hclock_valid, hclocktime,
1205
time_diff(read_time, startup_time));
1207
set_hardware_clock_exact(set_time, startup_time,
1208
universal, testing);
1210
adjust_drift_factor(&adjtime, set_time, hclock_valid, hclocktime,
1211
time_diff(read_time, startup_time));
1212
} else if (adjust) {
1213
do_adjustment(&adjtime, hclock_valid, hclocktime,
1214
read_time, universal, testing);
1215
} else if (systohc) {
1216
struct timeval nowtime, reftime;
1217
/* We can only set_hardware_clock_exact to a whole seconds
1218
time, so we set it with reference to the most recent
1221
gettimeofday(&nowtime, NULL);
1222
reftime.tv_sec = nowtime.tv_sec;
1223
reftime.tv_usec = 0;
1225
set_hardware_clock_exact((time_t) reftime.tv_sec, reftime,
1226
universal, testing);
1228
adjust_drift_factor(&adjtime, (time_t) reftime.tv_sec, hclock_valid,
1229
hclocktime, (double) read_time.tv_usec / 1E6);
1230
} else if (hctosys) {
1231
rc = set_system_clock(hclock_valid, hclocktime, testing);
1233
printf(_("Unable to set system clock.\n"));
1231
display_time(hclock_valid, hclocktime,
1232
time_diff(read_time, startup_time));
1234
set_hardware_clock_exact(set_time, startup_time,
1235
universal, testing);
1237
adjust_drift_factor(&adjtime, set_time,
1240
time_diff(read_time, startup_time));
1241
} else if (adjust) {
1242
do_adjustment(&adjtime, hclock_valid,
1243
hclocktime, read_time, universal, testing);
1244
} else if (systohc) {
1245
struct timeval nowtime, reftime;
1247
* We can only set_hardware_clock_exact to a
1248
* whole seconds time, so we set it with
1249
* reference to the most recent whole
1252
gettimeofday(&nowtime, NULL);
1253
reftime.tv_sec = nowtime.tv_sec;
1254
reftime.tv_usec = 0;
1255
set_hardware_clock_exact((time_t)
1257
reftime, universal, testing);
1259
adjust_drift_factor(&adjtime, (time_t)
1261
hclock_valid, hclocktime, (double)
1262
read_time.tv_usec / 1E6);
1263
} else if (hctosys) {
1264
rc = set_system_clock(hclock_valid, hclocktime, testing);
1266
printf(_("Unable to set system clock.\n"));
1236
1269
} else if (systz) {
1237
rc = set_system_clock_timezone(universal, testing);
1239
printf(_("Unable to set system clock.\n"));
1242
} else if (predict) {
1246
calculate_adjustment(adjtime.drift_factor,
1247
adjtime.last_adj_time,
1248
adjtime.not_adjusted,
1250
&adjustment, &retro);
1252
printf(_("At %ld seconds after 1969, RTC is predicted to read %ld seconds after 1969.\n"),
1253
set_time, set_time + adjustment);
1255
display_time(TRUE, set_time + adjustment, -retro);
1258
save_adjtime(adjtime, testing);
1266
manipulate_epoch(const bool getepoch, const bool setepoch,
1267
const int epoch_opt, const bool testing) {
1268
/*----------------------------------------------------------------------------
1269
Get or set the Hardware Clock epoch value in the kernel, as appropriate.
1270
<getepoch>, <setepoch>, and <epoch> are hwclock invocation options.
1272
<epoch> == -1 if the user did not specify an "epoch" option.
1274
-----------------------------------------------------------------------------*/
1276
Maintenance note: This should work on non-Alpha machines, but the
1277
evidence today (98.03.04) indicates that the kernel only keeps the
1278
epoch value on Alphas. If that is ever fixed, this function should be
1283
fprintf(stderr, _("The kernel keeps an epoch value for the Hardware Clock "
1284
"only on an Alpha machine.\nThis copy of hwclock was built for "
1285
"a machine other than Alpha\n(and thus is presumably not running "
1286
"on an Alpha now). No action taken.\n"));
1289
unsigned long epoch;
1291
if (get_epoch_rtc(&epoch, 0))
1292
fprintf(stderr, _("Unable to get the epoch value from the kernel.\n"));
1294
printf(_("Kernel is assuming an epoch value of %lu\n"), epoch);
1295
} else if (setepoch) {
1296
if (epoch_opt == -1)
1297
fprintf(stderr, _("To set the epoch value, you must use the 'epoch' "
1298
"option to tell to what value to set it.\n"));
1300
printf(_("Not setting the epoch to %d - testing only.\n"),
1302
else if (set_epoch_rtc(epoch_opt))
1303
printf(_("Unable to set the epoch value in the kernel.\n"));
1309
#define RTC_DEV "/dev/efirtc"
1311
#define RTC_DEV "/dev/rtc"
1316
printf(_("%s from %s\n"), MYNAME, PACKAGE_STRING);
1320
usage - Output (error and) usage information
1322
This function is called both directly from main to show usage
1323
information and as fatal function from shhopt if some argument is
1324
not understood. In case of normal usage info FMT should be NULL.
1325
In that case the info is printed to stdout. If FMT is given
1326
usage will act like fprintf( stderr, fmt, ... ), show a usage
1327
information and terminate the program afterwards.
1330
usage( const char *fmt, ... ) {
1334
usageto = fmt ? stderr : stdout;
1336
fprintf( usageto, _(
1337
"hwclock - query and set the hardware clock (RTC)\n\n"
1338
"Usage: hwclock [function] [options...]\n\n"
1340
" -h | --help show this help\n"
1341
" -r | --show read hardware clock and print result\n"
1342
" --set set the rtc to the time given with --date\n"
1343
" -s | --hctosys set the system time from the hardware clock\n"
1344
" -w | --systohc set the hardware clock to the current system time\n"
1345
" --systz set the system time based on the current timezone\n"
1346
" --adjust adjust the rtc to account for systematic drift since\n"
1347
" the clock was last set or adjusted\n"
1348
" --getepoch print out the kernel's hardware clock epoch value\n"
1349
" --setepoch set the kernel's hardware clock epoch value to the \n"
1350
" value given with --epoch\n"
1351
" --predict predict rtc reading at time given with --date\n"
1352
" -v | --version print out the version of hwclock to stdout\n"
1354
" -u | --utc the hardware clock is kept in UTC\n"
1355
" --localtime the hardware clock is kept in local time\n"
1356
" -f | --rtc=path special /dev/... file to use instead of default\n"
1357
" --directisa access the ISA bus directly instead of %s\n"
1358
" --badyear ignore rtc's year because the bios is broken\n"
1359
" --date specifies the time to which to set the hardware clock\n"
1360
" --epoch=year specifies the year which is the beginning of the \n"
1361
" hardware clock's epoch value\n"
1362
" --noadjfile do not access /etc/adjtime. Requires the use of\n"
1363
" either --utc or --localtime\n"
1364
" --adjfile=path specifies the path to the adjust file (default is\n"
1366
" --test do everything except actually updating the hardware\n"
1367
" clock or anything else\n"
1368
" -D | --debug debug mode\n"
1373
" -J|--jensen, -A|--arc, -S|--srm, -F|--funky-toy\n"
1374
" tell hwclock the type of alpha you have (see hwclock(8))\n"
1383
vfprintf(stderr, fmt, ap);
1387
hwclock_exit(fmt ? EX_USAGE : 0);
1390
static const struct option longopts[] = {
1391
{ "adjust", 0, 0, 'a' },
1392
{ "help", 0, 0, 'h' },
1393
{ "show", 0, 0, 'r' },
1394
{ "hctosys", 0, 0, 's' },
1395
{ "utc", 0, 0, 'u' },
1396
{ "version", 0, 0, 'v' },
1397
{ "systohc", 0, 0, 'w' },
1398
{ "debug", 0, 0, 'D' },
1400
{ "ARC", 0, 0, 'A' },
1401
{ "arc", 0, 0, 'A' },
1402
{ "Jensen", 0, 0, 'J' },
1403
{ "jensen", 0, 0, 'J' },
1404
{ "SRM", 0, 0, 'S' },
1405
{ "srm", 0, 0, 'S' },
1406
{ "funky-toy", 0, 0, 'F'},
1408
{ "set", 0, 0, 128 },
1409
{ "getepoch", 0, 0, 129 },
1410
{ "setepoch", 0, 0, 130 },
1411
{ "noadjfile", 0, 0, 131 },
1412
{ "localtime", 0, 0, 132 },
1413
{ "badyear", 0, 0, 133 },
1414
{ "directisa", 0, 0, 134 },
1415
{ "test", 0, 0, 135 },
1416
{ "date", 1, 0, 136 },
1417
{ "epoch", 1, 0, 137 },
1418
{ "rtc", 1, 0, 'f' },
1419
{ "adjfile", 1, 0, 138 },
1420
{ "systz", 0, 0, 139 },
1421
{ "predict-hc", 0, 0, 140 },
1270
rc = set_system_clock_timezone(universal, testing);
1272
printf(_("Unable to set system clock.\n"));
1275
} else if (predict) {
1279
calculate_adjustment(adjtime.drift_factor,
1280
adjtime.last_adj_time,
1281
adjtime.not_adjusted,
1282
set_time, &adjustment, &retro);
1285
("At %ld seconds after 1969, RTC is predicted to read %ld seconds after 1969.\n"),
1286
set_time, set_time + adjustment);
1288
display_time(TRUE, set_time + adjustment, -retro);
1291
save_adjtime(adjtime, testing);
1296
* Get or set the Hardware Clock epoch value in the kernel, as appropriate.
1297
* <getepoch>, <setepoch>, and <epoch> are hwclock invocation options.
1299
* <epoch> == -1 if the user did not specify an "epoch" option.
1303
* Maintenance note: This should work on non-Alpha machines, but the
1304
* evidence today (98.03.04) indicates that the kernel only keeps the epoch
1305
* value on Alphas. If that is ever fixed, this function should be changed.
1309
manipulate_epoch(const bool getepoch __attribute__ ((__unused__)),
1310
const bool setepoch __attribute__ ((__unused__)),
1311
const unsigned long epoch_opt __attribute__ ((__unused__)),
1312
const bool testing __attribute__ ((__unused__)))
1314
warnx(_("The kernel keeps an epoch value for the Hardware Clock "
1315
"only on an Alpha machine.\nThis copy of hwclock was built for "
1316
"a machine other than Alpha\n(and thus is presumably not running "
1317
"on an Alpha now). No action taken."));
1321
manipulate_epoch(const bool getepoch,
1322
const bool setepoch,
1323
const unsigned long epoch_opt,
1327
unsigned long epoch;
1329
if (get_epoch_rtc(&epoch, 0))
1331
("Unable to get the epoch value from the kernel."));
1333
printf(_("Kernel is assuming an epoch value of %lu\n"),
1335
} else if (setepoch) {
1336
if (epoch_opt == -1)
1338
("To set the epoch value, you must use the 'epoch' "
1339
"option to tell to what value to set it."));
1342
("Not setting the epoch to %d - testing only.\n"),
1344
else if (set_epoch_rtc(epoch_opt))
1346
("Unable to set the epoch value in the kernel.\n"));
1349
# endif /* __alpha__ */
1350
#endif /* __linux__ */
1352
static void out_version(void)
1354
printf(_("%s from %s\n"), program_invocation_short_name, PACKAGE_STRING);
1358
* usage - Output (error and) usage information
1360
* This function is called both directly from main to show usage information
1361
* and as fatal function from shhopt if some argument is not understood. In
1362
* case of normal usage info FMT should be NULL. In that case the info is
1363
* printed to stdout. If FMT is given usage will act like fprintf( stderr,
1364
* fmt, ... ), show a usage information and terminate the program
1367
static void usage(const char *fmt, ...)
1372
usageto = fmt ? stderr : stdout;
1374
fputs(_("\nUsage:\n"), usageto);
1375
fputs(_(" hwclock [function] [option...]\n"), usageto);
1377
fputs(_("\nFunctions:\n"), usageto);
1378
fputs(_(" -h, --help show this help text and exit\n"
1379
" -r, --show read hardware clock and print result\n"
1380
" --set set the RTC to the time given with --date\n"), usageto);
1381
fputs(_(" -s, --hctosys set the system time from the hardware clock\n"
1382
" -w, --systohc set the hardware clock from the current system time\n"
1383
" --systz set the system time based on the current timezone\n"
1384
" --adjust adjust the RTC to account for systematic drift since\n"
1385
" the clock was last set or adjusted\n"), usageto);
1387
fputs(_(" --getepoch print out the kernel's hardware clock epoch value\n"
1388
" --setepoch set the kernel's hardware clock epoch value to the \n"
1389
" value given with --epoch\n"), usageto);
1391
fputs(_(" --predict predict RTC reading at time given with --date\n"
1392
" -V, --version display version information and exit\n"), usageto);
1394
fputs(_("\nOptions:\n"), usageto);
1395
fputs(_(" -u, --utc the hardware clock is kept in UTC\n"
1396
" --localtime the hardware clock is kept in local time\n"), usageto);
1398
fputs(_(" -f, --rtc <file> special /dev/... file to use instead of default\n"), usageto);
1401
" --directisa access the ISA bus directly instead of %s\n"
1402
" --badyear ignore RTC's year because the BIOS is broken\n"
1403
" --date <time> specifies the time to which to set the hardware clock\n"
1404
" --epoch <year> specifies the year which is the beginning of the\n"
1405
" hardware clock's epoch value\n"), _PATH_RTC_DEV);
1407
" --noadjfile do not access %s; this requires the use of\n"
1408
" either --utc or --localtime\n"
1409
" --adjfile <file> specifies the path to the adjust file;\n"
1410
" the default is %s\n"), _PATH_ADJPATH, _PATH_ADJPATH);
1411
fputs(_(" --test do not update anything, just show what would happen\n"
1412
" -D, --debug debugging mode\n" "\n"), usageto);
1414
fputs(_(" -J|--jensen, -A|--arc, -S|--srm, -F|--funky-toy\n"
1415
" tell hwclock the type of Alpha you have (see hwclock(8))\n"
1423
vfprintf(stderr, fmt, ap);
1427
hwclock_exit(fmt ? EX_USAGE : EX_OK);
1667
1717
if (!permitted)
1668
1718
hwclock_exit(EX_NOPERM);
1670
1721
if (getepoch || setepoch) {
1671
1722
manipulate_epoch(getepoch, setepoch, epoch_option, testing);
1723
hwclock_exit(EX_OK);
1677
1730
if (!systz && !predict) {
1678
1731
determine_clock_access_method(directisa);
1681
_("Cannot access the Hardware Clock via "
1682
"any known method.\n"));
1733
warnx(_("Cannot access the Hardware Clock via "
1734
"any known method."));
1685
_("Use the --debug option to see the "
1686
"details of our search for an access "
1736
warnx(_("Use the --debug option to see the "
1737
"details of our search for an access "
1739
hwclock_exit(EX_SOFTWARE);
1692
1743
rc = manipulate_clock(show, adjust, noadjfile, set, set_time,
1693
hctosys, systohc, systz, startup_time, utc,
1694
local_opt, testing, predict);
1744
hctosys, systohc, systz, startup_time, utc,
1745
local_opt, testing, predict);
1695
1746
hwclock_exit(rc);
1696
return rc; /* Not reached */
1699
/* A single routine for greater uniformity */
1701
outsyserr(char *msg, ...) {
1705
fprintf(stderr, "%s: ", progname);
1706
va_start(args, msg);
1707
vfprintf(stderr, msg, args);
1709
fprintf(stderr, ", errno=%d: %s.\n",
1710
errsv, strerror(errsv));
1747
return rc; /* Not reached */
1714
1750
#ifdef HAVE_LIBAUDIT
1716
hwaudit_exit(int status)
1752
* hwclock_exit calls either this function or plain exit depending
1753
* HAVE_LIBAUDIT see also clock.h
1755
void __attribute__((__noreturn__)) hwaudit_exit(int status)
1718
1757
if (hwaudit_on) {
1719
1758
audit_log_user_message(hwaudit_fd, AUDIT_USYS_CONFIG,
1720
"changing system time", NULL, NULL, NULL, status ? 0 : 1);
1759
"changing system time", NULL, NULL, NULL,
1721
1761
close(hwaudit_fd);
1727
/****************************************************************************
1729
History of this program:
1731
98.08.12 BJH Version 2.4
1733
Don't use century byte from Hardware Clock. Add comments telling why.
1736
98.06.20 BJH Version 2.3.
1738
Make --hctosys set the kernel timezone from TZ environment variable
1739
and/or /usr/lib/zoneinfo. From Klaus Ripke (klaus@ripke.com).
1741
98.03.05 BJH. Version 2.2.
1743
Add --getepoch and --setepoch.
1745
Fix some word length things so it works on Alpha.
1747
Make it work when /dev/rtc doesn't have the interrupt functions.
1748
In this case, busywait for the top of a second instead of blocking and
1749
waiting for the update complete interrupt.
1751
Fix a bunch of bugs too numerous to mention.
1753
97.06.01: BJH. Version 2.1. Read and write the century byte (Byte
1754
50) of the ISA Hardware Clock when using direct ISA I/O. Problem
1755
discovered by job (jei@iclnl.icl.nl).
1757
Use the rtc clock access method in preference to the KDGHWCLK method.
1758
Problem discovered by Andreas Schwab <schwab@LS5.informatik.uni-dortmund.de>.
1760
November 1996: Version 2.0.1. Modifications by Nicolai Langfeldt
1761
(janl@math.uio.no) to make it compile on linux 1.2 machines as well
1762
as more recent versions of the kernel. Introduced the NO_CLOCK
1763
access method and wrote feature test code to detect absense of rtc
1767
**************************************************************************
1770
To compile this, you must use GNU compiler optimization (-O option)
1771
in order to make the "extern inline" functions from asm/io.h (inb(),
1772
etc.) compile. If you don't optimize, which means the compiler
1773
will generate no inline functions, the references to these functions
1774
in this program will be compiled as external references. Since you
1775
probably won't be linking with any functions by these names, you will
1776
have unresolved external references when you link.
1778
The program is designed to run setuid superuser, since we need to be
1779
able to do direct I/O. (More to the point: we need permission to
1780
execute the iopl() system call). (However, if you use one of the
1781
methods other than direct ISA I/O to access the clock, no setuid is
1784
Here's some info on how we must deal with the time that elapses while
1785
this program runs: There are two major delays as we run:
1787
1) Waiting up to 1 second for a transition of the Hardware Clock so
1788
we are synchronized to the Hardware Clock.
1790
2) Running the "date" program to interpret the value of our --date
1793
Reading the /etc/adjtime file is the next biggest source of delay and
1796
The user wants to know what time it was at the moment he invoked us,
1797
not some arbitrary time later. And in setting the clock, he is
1798
giving us the time at the moment we are invoked, so if we set the
1799
clock some time later, we have to add some time to that.
1801
So we check the system time as soon as we start up, then run "date"
1802
and do file I/O if necessary, then wait to synchronize with a
1803
Hardware Clock edge, then check the system time again to see how
1804
much time we spent. We immediately read the clock then and (if
1805
appropriate) report that time, and additionally, the delay we measured.
1807
If we're setting the clock to a time given by the user, we wait some
1808
more so that the total delay is an integral number of seconds, then
1809
set the Hardware Clock to the time the user requested plus that
1810
integral number of seconds. N.B. The Hardware Clock can only be set
1811
in integral seconds.
1813
If we're setting the clock to the system clock value, we wait for
1814
the system clock to reach the top of a second, and then set the
1815
Hardware Clock to the system clock's value.
1817
Here's an interesting point about setting the Hardware Clock: On my
1818
machine, when you set it, it sets to that precise time. But one can
1819
imagine another clock whose update oscillator marches on a steady one
1820
second period, so updating the clock between any two oscillator ticks
1821
is the same as updating it right at the earlier tick. To avoid any
1822
complications that might cause, we set the clock as soon as possible
1823
after an oscillator tick.
1826
About synchronizing to the Hardware Clock when reading the time: The
1827
precision of the Hardware Clock counters themselves is one second.
1828
You can't read the counters and find out that is 12:01:02.5. But if
1829
you consider the location in time of the counter's ticks as part of
1830
its value, then its precision is as infinite as time is continuous!
1831
What I'm saying is this: To find out the _exact_ time in the
1832
hardware clock, we wait until the next clock tick (the next time the
1833
second counter changes) and measure how long we had to wait. We
1834
then read the value of the clock counters and subtract the wait time
1835
and we know precisely what time it was when we set out to query the
1838
hwclock uses this method, and considers the Hardware Clock to have
1842
Enhancements needed:
1844
- When waiting for whole second boundary in set_hardware_clock_exact,
1845
fail if we miss the goal by more than .1 second, as could happen if
1846
we get pre-empted (by the kernel dispatcher).
1848
****************************************************************************/
1768
* History of this program:
1770
* 98.08.12 BJH Version 2.4
1772
* Don't use century byte from Hardware Clock. Add comments telling why.
1774
* 98.06.20 BJH Version 2.3.
1776
* Make --hctosys set the kernel timezone from TZ environment variable
1777
* and/or /usr/lib/zoneinfo. From Klaus Ripke (klaus@ripke.com).
1779
* 98.03.05 BJH. Version 2.2.
1781
* Add --getepoch and --setepoch.
1783
* Fix some word length things so it works on Alpha.
1785
* Make it work when /dev/rtc doesn't have the interrupt functions. In this
1786
* case, busywait for the top of a second instead of blocking and waiting
1787
* for the update complete interrupt.
1789
* Fix a bunch of bugs too numerous to mention.
1791
* 97.06.01: BJH. Version 2.1. Read and write the century byte (Byte 50) of
1792
* the ISA Hardware Clock when using direct ISA I/O. Problem discovered by
1793
* job (jei@iclnl.icl.nl).
1795
* Use the rtc clock access method in preference to the KDGHWCLK method.
1796
* Problem discovered by Andreas Schwab <schwab@LS5.informatik.uni-dortmund.de>.
1798
* November 1996: Version 2.0.1. Modifications by Nicolai Langfeldt
1799
* (janl@math.uio.no) to make it compile on linux 1.2 machines as well as
1800
* more recent versions of the kernel. Introduced the NO_CLOCK access method
1801
* and wrote feature test code to detect absense of rtc headers.
1803
***************************************************************************
1806
* To compile this, you must use GNU compiler optimization (-O option) in
1807
* order to make the "extern inline" functions from asm/io.h (inb(), etc.)
1808
* compile. If you don't optimize, which means the compiler will generate no
1809
* inline functions, the references to these functions in this program will
1810
* be compiled as external references. Since you probably won't be linking
1811
* with any functions by these names, you will have unresolved external
1812
* references when you link.
1814
* The program is designed to run setuid superuser, since we need to be able
1815
* to do direct I/O. (More to the point: we need permission to execute the
1816
* iopl() system call). (However, if you use one of the methods other than
1817
* direct ISA I/O to access the clock, no setuid is required).
1819
* Here's some info on how we must deal with the time that elapses while
1820
* this program runs: There are two major delays as we run:
1822
* 1) Waiting up to 1 second for a transition of the Hardware Clock so
1823
* we are synchronized to the Hardware Clock.
1824
* 2) Running the "date" program to interpret the value of our --date
1827
* Reading the /etc/adjtime file is the next biggest source of delay and
1830
* The user wants to know what time it was at the moment he invoked us, not
1831
* some arbitrary time later. And in setting the clock, he is giving us the
1832
* time at the moment we are invoked, so if we set the clock some time
1833
* later, we have to add some time to that.
1835
* So we check the system time as soon as we start up, then run "date" and
1836
* do file I/O if necessary, then wait to synchronize with a Hardware Clock
1837
* edge, then check the system time again to see how much time we spent. We
1838
* immediately read the clock then and (if appropriate) report that time,
1839
* and additionally, the delay we measured.
1841
* If we're setting the clock to a time given by the user, we wait some more
1842
* so that the total delay is an integral number of seconds, then set the
1843
* Hardware Clock to the time the user requested plus that integral number
1844
* of seconds. N.B. The Hardware Clock can only be set in integral seconds.
1846
* If we're setting the clock to the system clock value, we wait for the
1847
* system clock to reach the top of a second, and then set the Hardware
1848
* Clock to the system clock's value.
1850
* Here's an interesting point about setting the Hardware Clock: On my
1851
* machine, when you set it, it sets to that precise time. But one can
1852
* imagine another clock whose update oscillator marches on a steady one
1853
* second period, so updating the clock between any two oscillator ticks is
1854
* the same as updating it right at the earlier tick. To avoid any
1855
* complications that might cause, we set the clock as soon as possible
1856
* after an oscillator tick.
1858
* About synchronizing to the Hardware Clock when reading the time: The
1859
* precision of the Hardware Clock counters themselves is one second. You
1860
* can't read the counters and find out that is 12:01:02.5. But if you
1861
* consider the location in time of the counter's ticks as part of its
1862
* value, then its precision is as infinite as time is continuous! What I'm
1863
* saying is this: To find out the _exact_ time in the hardware clock, we
1864
* wait until the next clock tick (the next time the second counter changes)
1865
* and measure how long we had to wait. We then read the value of the clock
1866
* counters and subtract the wait time and we know precisely what time it
1867
* was when we set out to query the time.
1869
* hwclock uses this method, and considers the Hardware Clock to have
1870
* infinite precision.
1872
* TODO: Enhancements needed:
1874
* - When waiting for whole second boundary in set_hardware_clock_exact,
1875
* fail if we miss the goal by more than .1 second, as could happen if we
1876
* get pre-empted (by the kernel dispatcher).