]>
git.ipfire.org Git - thirdparty/util-linux.git/blob - hwclock/hwclock.c
4 * clock.c was written by Charles Hedrick, hedrick@cs.rutgers.edu, Apr 1992
5 * Modified for clock adjustments - Rob Hooft <hooft@chem.ruu.nl>, Nov 1992
6 * Improvements by Harald Koenig <koenig@nova.tat.physik.uni-tuebingen.de>
7 * and Alan Modra <alan@spri.levels.unisa.edu.au>.
9 * Major rewrite by Bryan Henderson <bryanh@giraffe-data.com>, 96.09.19.
10 * The new program is called hwclock. New features:
11 * - You can set the hardware clock without also modifying the system clock.
12 * - You can read and set the clock with finer than 1 second precision.
13 * - When you set the clock, hwclock automatically refigures the drift
14 * rate, based on how far off the clock was before you set it.
16 * Reshuffled things, added sparc code, and re-added alpha stuff
17 * by David Mosberger <davidm@azstarnet.com>
18 * and Jay Estabrook <jestabro@amt.tay1.dec.com>
19 * and Martin Ostermann <ost@coments.rwth-aachen.de>, aeb@cwi.nl, 990212.
21 * Fix for Award 2094 bug, Dave Coffin (dcoffin@shore.net) 11/12/98
22 * Change of local time handling, Stefan Ring <e9725446@stud3.tuwien.ac.at>
24 * Distributed under GPL
28 * clock [-u] -r - read hardware clock
29 * clock [-u] -w - write hardware clock from system time
30 * clock [-u] -s - set system time from hardware clock
31 * clock [-u] -a - set system time from hardware clock, adjust the time
32 * to correct for systematic error, and write it back to
34 * -u indicates cmos clock is kept in universal time
35 * -A indicates cmos clock is kept in Alpha ARC console time (0 == 1980)
36 * -J indicates we're dealing with a Jensen (early DEC Alpha PC)
40 * Explanation of `adjusting' (Rob Hooft):
42 * The problem with my machine is that its CMOS clock is 10 seconds
43 * per day slow. With this version of clock.c, and my '/etc/rc.local'
44 * reading '/etc/clock -au' instead of '/etc/clock -u -s', this error
45 * is automatically corrected at every boot.
47 * To do this job, the program reads and writes the file '/etc/adjtime'
48 * to determine the correction, and to save its data. In this file are
51 * 1) the correction in seconds per day. (So if your clock runs 5
52 * seconds per day fast, the first number should read -5.0)
53 * 2) the number of seconds since 1/1/1970 the last time the program
55 * 3) the remaining part of a second which was leftover after the last
58 * Installation and use of this program:
60 * a) create a file '/etc/adjtime' containing as the first and only line:
62 * b) run 'clock -au' or 'clock -a', depending on whether your cmos is in
63 * universal or local time. This updates the second number.
64 * c) set your system time using the 'date' command.
65 * d) update your cmos time using 'clock -wu' or 'clock -w'
66 * e) replace the first number in /etc/adjtime by your correction.
67 * f) put the command 'clock -au' or 'clock -a' in your '/etc/rc.local'
73 #include <sys/ioctl.h>
86 #define MYNAME "hwclock"
87 #define VERSION "2.4c"
89 char *progname
= MYNAME
;
91 /* The struct that holds our hardware access routines */
94 #define FLOOR(arg) ((arg >= 0 ? (int) arg : ((int) arg) - 1));
96 /* Here the information for time adjustments is kept. */
97 #define ADJPATH "/etc/adjtime"
99 /* Store the date here when "badyear" flag is set. */
100 #define LASTDATE "/var/lib/lastdate"
103 /* This is information we keep in the adjtime file that tells us how
104 to do drift corrections. Elements are all straight from the
105 adjtime file, so see documentation of that file for details.
106 Exception is <dirty>, which is an indication that what's in this
107 structure is not what's in the disk file (because it has been
108 updated since read from the disk file).
113 time_t last_adj_time
;
116 time_t last_calib_time
;
117 /* The most recent time that we set the clock from an external
118 authority (as opposed to just doing a drift adjustment) */
120 enum a_local_utc
{LOCAL
, UTC
, UNKNOWN
} local_utc
;
121 /* To which time zone, local or UTC, we most recently set the
126 /* We are running in debug mode, wherein we put a lot of information about
127 what we're doing to standard output. */
130 /* Workaround for Award 4.50g BIOS bug: keep the year in a file. */
132 int epoch_option
= -1;
133 /* User-specified epoch, used when rtc fails to return epoch. */
136 * Almost all Award BIOS's made between 04/26/94 and 05/31/95
137 * have a nasty bug limiting the RTC year byte to the range 94-99.
138 * Any year between 2000 and 2093 gets changed to 2094, every time
139 * you start the system.
140 * With the --badyear option, we write the date to file and hope
141 * that the file is updated at least once a year.
142 * I recommend putting this command "hwclock --badyear" in the monthly
143 * crontab, just to be safe. -- Dave Coffin 11/12/98
146 write_date_to_file (struct tm
*tm
) {
149 if ((fp
= fopen(LASTDATE
,"w"))) {
150 fprintf(fp
,"%02d.%02d.%04d\n", tm
->tm_mday
, tm
->tm_mon
+1,
158 read_date_from_file (struct tm
*tm
) {
159 int last_mday
, last_mon
, last_year
;
162 if ((fp
= fopen(LASTDATE
,"r"))) {
163 if (fscanf (fp
,"%d.%d.%d\n", &last_mday
, &last_mon
, &last_year
) == 3) {
164 tm
->tm_year
= last_year
-1900;
165 if ((tm
->tm_mon
<< 5) + tm
->tm_mday
< ((last_mon
-1) << 5) + last_mday
)
170 write_date_to_file (tm
);
174 time_diff(struct timeval subtrahend
, struct timeval subtractor
) {
175 /*---------------------------------------------------------------------------
176 The difference in seconds between two times in "timeval" format.
177 ----------------------------------------------------------------------------*/
178 return( (subtrahend
.tv_sec
- subtractor
.tv_sec
)
179 + (subtrahend
.tv_usec
- subtractor
.tv_usec
) / 1E6
);
183 static struct timeval
184 time_inc(struct timeval addend
, float increment
) {
185 /*----------------------------------------------------------------------------
186 The time, in "timeval" format, which is <increment> seconds after
187 the time <addend>. Of course, <increment> may be negative.
188 -----------------------------------------------------------------------------*/
189 struct timeval newtime
;
191 newtime
.tv_sec
= addend
.tv_sec
+ (int) increment
;
192 newtime
.tv_usec
= addend
.tv_usec
+ (increment
- (int) increment
) * 1E6
;
194 /* Now adjust it so that the microsecond value is between 0 and 1 million */
195 if (newtime
.tv_usec
< 0) {
196 newtime
.tv_usec
+= 1E6
;
198 } else if (newtime
.tv_usec
>= 1E6
) {
199 newtime
.tv_usec
-= 1E6
;
207 hw_clock_is_utc(const bool utc
, const bool local_opt
,
208 const struct adjtime adjtime
) {
212 ret
= TRUE
; /* --utc explicitly given on command line */
214 ret
= FALSE
; /* --localtime explicitly given */
216 /* get info from adjtime file - default is local */
217 ret
= (adjtime
.local_utc
== UTC
);
219 printf(_("Assuming hardware clock is kept in %s time.\n"),
220 ret
? _("UTC") : _("local"));
227 read_adjtime(struct adjtime
*adjtime_p
, int *rc_p
) {
228 /*----------------------------------------------------------------------------
229 Read the adjustment parameters out of the /etc/adjtime file.
231 Return them as the adjtime structure <*adjtime_p>.
233 If there is no /etc/adjtime file, return defaults.
234 If values are missing from the file, return defaults for them.
236 return *rc_p = 0 if all OK, !=0 otherwise.
238 -----------------------------------------------------------------------------*/
240 int rc
; /* local return code */
241 struct stat statbuf
; /* We don't even use the contents of this. */
243 rc
= stat(ADJPATH
, &statbuf
);
244 if (rc
< 0 && errno
== ENOENT
) {
245 /* He doesn't have a adjtime file, so we'll use defaults. */
246 adjtime_p
->drift_factor
= 0;
247 adjtime_p
->last_adj_time
= 0;
248 adjtime_p
->not_adjusted
= 0;
249 adjtime_p
->last_calib_time
= 0;
250 adjtime_p
->local_utc
= UNKNOWN
;
254 adjfile
= fopen(ADJPATH
, "r"); /* open file for reading */
255 if (adjfile
== NULL
) {
256 outsyserr("cannot open file " ADJPATH
);
259 char line1
[81]; /* String: first line of adjtime file */
260 char line2
[81]; /* String: second line of adjtime file */
261 char line3
[81]; /* String: third line of adjtime file */
263 line1
[0] = '\0'; /* In case fgets fails */
264 fgets(line1
, sizeof(line1
), adjfile
);
265 line2
[0] = '\0'; /* In case fgets fails */
266 fgets(line2
, sizeof(line2
), adjfile
);
267 line3
[0] = '\0'; /* In case fgets fails */
268 fgets(line3
, sizeof(line3
), adjfile
);
272 /* Set defaults in case values are missing from file */
273 adjtime_p
->drift_factor
= 0;
274 adjtime_p
->last_adj_time
= 0;
275 adjtime_p
->not_adjusted
= 0;
276 adjtime_p
->last_calib_time
= 0;
278 sscanf(line1
, "%f %d %f",
279 &adjtime_p
->drift_factor
,
280 (int *) &adjtime_p
->last_adj_time
,
281 &adjtime_p
->not_adjusted
);
283 sscanf(line2
, "%d", (int *) &adjtime_p
->last_calib_time
);
285 if (!strcmp(line3
, "UTC\n"))
286 adjtime_p
->local_utc
= UTC
;
287 else if (!strcmp(line3
, "LOCAL\n"))
288 adjtime_p
->local_utc
= LOCAL
;
290 adjtime_p
->local_utc
= UNKNOWN
;
292 fprintf(stderr
, _("%s: Warning: unrecognized third line in adjtime file\n"),
294 fprintf(stderr
, _("(Expected: `UTC' or `LOCAL' or nothing.)\n"));
300 adjtime_p
->dirty
= FALSE
;
303 printf(_("Last drift adjustment done at %d seconds after 1969\n"),
304 (int) adjtime_p
->last_adj_time
);
305 printf(_("Last calibration done at %d seconds after 1969\n"),
306 (int) adjtime_p
->last_calib_time
);
307 printf(_("Hardware clock is on %s time\n"),
308 (adjtime_p
->local_utc
== LOCAL
) ? _("local") :
309 (adjtime_p
->local_utc
== UTC
) ? _("UTC") : _("unknown"));
316 synchronize_to_clock_tick(int *retcode_p
) {
317 /*-----------------------------------------------------------------------------
318 Wait until the falling edge of the Hardware Clock's update flag so
319 that any time that is read from the clock immediately after we
320 return will be exact.
322 The clock only has 1 second precision, so it gives the exact time only
323 once per second, right on the falling edge of the update flag.
325 We wait (up to one second) either blocked waiting for an rtc device
326 or in a CPU spin loop. The former is probably not very accurate.
328 Return *retcode_p == 0 if it worked, nonzero if it didn't.
330 -----------------------------------------------------------------------------*/
331 if (debug
) printf(_("Waiting for clock tick...\n"));
333 *retcode_p
= ur
->synchronize_to_clock_tick();
335 if (debug
) printf(_("...got clock tick\n"));
341 mktime_tz(struct tm tm
, const bool universal
,
342 bool *valid_p
, time_t *systime_p
) {
343 /*-----------------------------------------------------------------------------
344 Convert a time in broken down format (hours, minutes, etc.) into standard
345 unix time (seconds into epoch). Return it as *systime_p.
347 The broken down time is argument <tm>. This broken down time is either in
348 local time zone or UTC, depending on value of logical argument "universal".
349 True means it is in UTC.
351 If the argument contains values that do not constitute a valid time,
352 and mktime() recognizes this, return *valid_p == false and
353 *systime_p undefined. However, mktime() sometimes goes ahead and
354 computes a fictional time "as if" the input values were valid,
355 e.g. if they indicate the 31st day of April, mktime() may compute
356 the time of May 1. In such a case, we return the same fictional
357 value mktime() does as *systime_p and return *valid_p == true.
359 -----------------------------------------------------------------------------*/
360 time_t mktime_result
; /* The value returned by our mktime() call */
361 char *zone
; /* Local time zone name */
363 /* We use the C library function mktime(), but since it only works on
364 local time zone input, we may have to fake it out by temporarily
365 changing the local time zone to UTC.
367 zone
= (char *) getenv("TZ"); /* remember original time zone */
369 /* Set timezone to UTC */
370 setenv("TZ", "", TRUE
);
371 /* Note: tzset() gets called implicitly by the time code, but only the
372 first time. When changing the environment variable, better call
377 mktime_result
= mktime(&tm
);
378 if (mktime_result
== -1) {
379 /* This apparently (not specified in mktime() documentation) means
380 the 'tm' structure does not contain valid values (however, not
381 containing valid values does _not_ imply mktime() returns -1).
386 printf(_("Invalid values in hardware clock: "
387 "%4d/%.2d/%.2d %.2d:%.2d:%.2d\n"),
388 tm
.tm_year
+1900, tm
.tm_mon
+1, tm
.tm_mday
,
389 tm
.tm_hour
, tm
.tm_min
, tm
.tm_sec
);
392 *systime_p
= mktime_result
;
394 printf(_("Hw clock time : %4d/%.2d/%.2d %.2d:%.2d:%.2d = "
395 "%ld seconds since 1969\n"),
396 tm
.tm_year
+1900, tm
.tm_mon
+1, tm
.tm_mday
,
397 tm
.tm_hour
, tm
.tm_min
, tm
.tm_sec
, (long) *systime_p
);
399 /* now put back the original zone. */
400 if (zone
) setenv("TZ", zone
, TRUE
);
407 read_hardware_clock(const bool universal
, bool *valid_p
, time_t *systime_p
){
408 /*----------------------------------------------------------------------------
409 Read the hardware clock and return the current time via <tm> argument.
411 Use the method indicated by <method> argument to access the hardware clock.
412 -----------------------------------------------------------------------------*/
416 err
= ur
->read_hardware_clock(&tm
);
419 read_date_from_file(&tm
);
422 printf (_("Time read from Hardware Clock: %4d/%.2d/%.2d %02d:%02d:%02d\n"),
423 tm
.tm_year
+1900, tm
.tm_mon
+1, tm
.tm_mday
,
424 tm
.tm_hour
, tm
.tm_min
, tm
.tm_sec
);
425 mktime_tz(tm
, universal
, valid_p
, systime_p
);
430 set_hardware_clock(const time_t newtime
,
431 const bool universal
,
432 const bool testing
) {
433 /*----------------------------------------------------------------------------
434 Set the Hardware Clock to the time <newtime>, in local time zone or UTC,
435 according to <universal>.
436 ----------------------------------------------------------------------------*/
438 struct tm new_broken_time
;
439 /* Time to which we will set Hardware Clock, in broken down format, in
440 the time zone of caller's choice
444 new_broken_time
= *gmtime(&newtime
);
446 new_broken_time
= *localtime(&newtime
);
449 printf(_("Setting Hardware Clock to %.2d:%.2d:%.2d "
450 "= %d seconds since 1969\n"),
451 new_broken_time
.tm_hour
, new_broken_time
.tm_min
,
452 new_broken_time
.tm_sec
, (int) newtime
);
455 printf(_("Clock not changed - testing only.\n"));
459 * Write the real year to a file, then write a fake year
460 * between 1995 and 1998 to the RTC. This way, Award BIOS boots
461 * on 29 Feb 2000 thinking that it's 29 Feb 1996.
463 write_date_to_file (&new_broken_time
);
464 new_broken_time
.tm_year
= 95 + ((new_broken_time
.tm_year
+1) & 3);
466 err
= ur
->set_hardware_clock(&new_broken_time
);
473 set_hardware_clock_exact(const time_t settime
,
474 const struct timeval ref_time
,
475 const bool universal
,
476 const bool testing
) {
477 /*----------------------------------------------------------------------------
478 Set the Hardware Clock to the time "settime", in local time zone or UTC,
479 according to "universal".
481 But correct "settime" and wait for a fraction of a second so that
482 "settime" is the value of the Hardware Clock as of system time
483 "ref_time", which is in the past. For example, if "settime" is
484 14:03:05 and "ref_time" is 12:10:04.5 and the current system
485 time is 12:10:06.0: Wait .5 seconds (to make exactly 2 seconds since
486 "ref_time") and then set the Hardware Clock to 14:03:07, thus
487 getting a precise and retroactive setting of the clock.
489 (Don't be confused by the fact that the system clock and the Hardware
490 Clock differ by two hours in the above example. That's just to remind
491 you that there are two independent time scales here).
493 This function ought to be able to accept set times as fractional times.
494 Idea for future enhancement.
496 -----------------------------------------------------------------------------*/
497 time_t newtime
; /* Time to which we will set Hardware Clock */
498 struct timeval now_time
; /* locally used time */
500 gettimeofday(&now_time
, NULL
);
501 newtime
= settime
+ (int) time_diff(now_time
, ref_time
) + 1;
503 printf(_("Time elapsed since reference time has been %.6f seconds.\n"
504 "Delaying further to reach the next full second.\n"),
505 time_diff(now_time
, ref_time
));
507 /* Now delay some more until Hardware Clock time newtime arrives */
508 do gettimeofday(&now_time
, NULL
);
509 while (time_diff(now_time
, ref_time
) < newtime
- settime
);
511 set_hardware_clock(newtime
, universal
, testing
);
517 display_time(const bool hclock_valid
, const time_t systime
,
518 const float sync_duration
) {
519 /*----------------------------------------------------------------------------
520 Put the time "systime" on standard output in display format.
521 Except if hclock_valid == false, just tell standard output that we don't
522 know what time it is.
524 Include in the output the adjustment "sync_duration".
525 -----------------------------------------------------------------------------*/
527 fprintf(stderr
, _("The Hardware Clock registers contain values that are "
528 "either invalid (e.g. 50th day of month) or beyond the range "
529 "we can handle (e.g. Year 2095).\n"));
535 lt
= localtime(&systime
);
536 strftime(ctime_now
, sizeof(ctime_now
), format
, lt
);
537 printf(_("%s %.6f seconds\n"), ctime_now
, -(sync_duration
));
544 interpret_date_string(const char *date_opt
, time_t * const time_p
) {
545 /*----------------------------------------------------------------------------
546 Interpret the value of the --date option, which is something like
547 "13:05:01". In fact, it can be any of the myriad ASCII strings that specify
548 a time which the "date" program can understand. The date option value in
549 question is our "dateopt" argument.
551 The specified time is in the local time zone.
553 Our output, "*time_p", is a seconds-into-epoch time.
555 We use the "date" program to interpret the date string. "date" must be
556 runnable by issuing the command "date" to the /bin/sh shell. That means
557 in must be in the current PATH.
559 If anything goes wrong (and many things can), we return return code
560 10 and arbitrary *time_p. Otherwise, return code is 0 and *time_p
562 ----------------------------------------------------------------------------*/
565 const char magic
[]="seconds-into-epoch=";
566 char date_command
[100];
567 int retcode
; /* our eventual return code */
568 int rc
; /* local return code */
570 if (date_opt
== NULL
) {
571 fprintf(stderr
, _("No --date option specified.\n"));
573 } else if (strchr(date_opt
, '"') != NULL
) {
574 /* Quotation marks in date_opt would ruin the date command we construct.
576 fprintf(stderr
, _("The value of the --date option is not a valid date.\n"
577 "In particular, it contains quotation marks.\n"));
580 sprintf(date_command
, "date --date=\"%s\" +seconds-into-epoch=%%s",
582 if (debug
) printf(_("Issuing date command: %s\n"), date_command
);
584 date_child_fp
= popen(date_command
, "r");
585 if (date_child_fp
== NULL
) {
586 outsyserr(_("Unable to run 'date' program in /bin/sh shell. "
590 date_resp
[0] = '\0'; /* in case fgets fails */
591 fgets(date_resp
, sizeof(date_resp
), date_child_fp
);
592 if (debug
) printf(_("response from date command = %s\n"), date_resp
);
593 if (strncmp(date_resp
, magic
, sizeof(magic
)-1) != 0) {
594 fprintf(stderr
, _("The date command issued by %s returned "
595 "unexpected results.\n"
596 "The command was:\n %s\nThe response was:\n %s\n"),
597 MYNAME
, date_command
, date_resp
);
600 int seconds_since_epoch
;
601 rc
= sscanf(date_resp
+ sizeof(magic
)-1, "%d", &seconds_since_epoch
);
603 fprintf(stderr
, _("The date command issued by %s returned "
604 "something other than an integer where the converted "
605 "time value was expected.\n"
606 "The command was:\n %s\nThe response was:\n %s\n"),
607 MYNAME
, date_command
, date_resp
);
611 *time_p
= seconds_since_epoch
;
613 printf(_("date string %s equates to %d seconds since 1969.\n"),
614 date_opt
, (int) *time_p
);
617 fclose(date_child_fp
);
626 set_system_clock(const bool hclock_valid
, const time_t newtime
,
627 const bool testing
) {
628 /*----------------------------------------------------------------------------
629 Set the System Clock to time 'newtime'.
631 Also set the kernel time zone value to the value indicated by the
632 TZ environment variable and/or /usr/lib/zoneinfo/, interpreted as
633 tzset() would interpret them.
635 EXCEPT: if hclock_valid is false, just issue an error message
636 saying there is no valid time in the Hardware Clock to which to set
639 If 'testing' is true, don't actually update anything -- just say we
641 -----------------------------------------------------------------------------*/
645 fprintf(stderr
,_("The Hardware Clock does not contain a valid time, so "
646 "we cannot set the System Time from it.\n"));
657 broken
= localtime(&newtime
);
658 #ifdef HAVE_tm_gmtoff
659 minuteswest
= -broken
->tm_gmtoff
/60; /* GNU extension */
661 minuteswest
= timezone
/60;
662 if (broken
->tm_isdst
)
667 printf( _("Calling settimeofday:\n") );
668 printf( _("\ttv.tv_sec = %ld, tv.tv_usec = %ld\n"),
669 (long) tv
.tv_sec
, (long) tv
.tv_usec
);
670 printf( _("\ttz.tz_minuteswest = %d\n"), minuteswest
);
673 printf(_("Not setting system clock because running in test mode.\n"));
676 const struct timezone tz
= { minuteswest
, 0 };
678 rc
= settimeofday(&tv
, &tz
);
681 fprintf(stderr
, _("Must be superuser to set system clock.\n"));
683 outsyserr(_("settimeofday() failed"));
693 adjust_drift_factor(struct adjtime
*adjtime_p
,
694 const time_t nowtime
,
695 const bool hclock_valid
, const time_t hclocktime
) {
696 /*---------------------------------------------------------------------------
697 Update the drift factor in <*adjtime_p> to reflect the fact that the
698 Hardware Clock was calibrated to <nowtime> and before that was set
701 We assume that the user has been doing regular drift adjustments
702 using the drift factor in the adjtime file, so if <nowtime> and
703 <clocktime> are different, that means the adjustment factor isn't
706 We record in the adjtime file the time at which we last calibrated
707 the clock so we can compute the drift rate each time we calibrate.
709 EXCEPT: if <hclock_valid> is false, assume Hardware Clock was not set
710 before to anything meaningful and regular adjustments have not been
711 done, so don't adjust the drift factor.
713 ----------------------------------------------------------------------------*/
716 printf(_("Not adjusting drift factor because the Hardware Clock "
717 "previously contained garbage.\n"));
718 } else if ((hclocktime
- adjtime_p
->last_calib_time
) < 23 * 60 * 60) {
720 printf(_("Not adjusting drift factor because it has been less than a "
721 "day since the last calibration.\n"));
723 const float factor_adjust
=
724 ((float) (nowtime
- hclocktime
)
725 / (hclocktime
- adjtime_p
->last_calib_time
))
729 printf(_("Clock drifted %d seconds in the past %d seconds "
730 "in spite of a drift factor of %f seconds/day.\n"
731 "Adjusting drift factor by %f seconds/day\n"),
732 (int) (nowtime
- hclocktime
),
733 (int) (hclocktime
- adjtime_p
->last_calib_time
),
734 adjtime_p
->drift_factor
,
737 adjtime_p
->drift_factor
+= factor_adjust
;
739 adjtime_p
->last_calib_time
= nowtime
;
741 adjtime_p
->last_adj_time
= nowtime
;
743 adjtime_p
->not_adjusted
= 0;
745 adjtime_p
->dirty
= TRUE
;
751 calculate_adjustment(
753 const time_t last_time
,
754 const float not_adjusted
,
755 const time_t systime
,
759 /*----------------------------------------------------------------------------
760 Do the drift adjustment calculation.
762 The way we have to set the clock, we need the adjustment in two parts:
764 1) an integer number of seconds (return as *adjustment_p)
766 2) a positive fraction of a second (less than 1) (return as *retro_p)
768 The sum of these two values is the adjustment needed. Positive means to
769 advance the clock or insert seconds. Negative means to retard the clock
771 ----------------------------------------------------------------------------*/
772 float exact_adjustment
;
774 exact_adjustment
= ((float) (systime
- last_time
)) * factor
/ (24 * 60 * 60)
776 *adjustment_p
= FLOOR(exact_adjustment
);
778 *retro_p
= exact_adjustment
- (float) *adjustment_p
;
780 printf (_("Time since last adjustment is %d seconds\n"),
781 (int) (systime
- last_time
));
782 printf (_("Need to insert %d seconds and refer time back "
783 "%.6f seconds ago\n"),
784 *adjustment_p
, *retro_p
);
791 save_adjtime(const struct adjtime adjtime
, const bool testing
) {
792 /*-----------------------------------------------------------------------------
793 Write the contents of the <adjtime> structure to its disk file.
795 But if the contents are clean (unchanged since read from disk), don't
797 -----------------------------------------------------------------------------*/
798 char newfile
[412]; /* Stuff to write to disk file */
801 /* snprintf is not always available, but this is safe
802 as long as libc does not use more than 100 positions for %ld or %f */
803 sprintf(newfile
, "%f %ld %f\n%ld\n%s\n",
804 adjtime
.drift_factor
,
805 (long) adjtime
.last_adj_time
,
806 adjtime
.not_adjusted
,
807 (long) adjtime
.last_calib_time
,
808 (adjtime
.local_utc
== UTC
) ? "UTC" : "LOCAL");
811 printf(_("Not updating adjtime file because of testing mode.\n"));
812 printf(_("Would have written the following to %s:\n%s"),
818 adjfile
= fopen(ADJPATH
, "w");
819 if (adjfile
== NULL
) {
820 outsyserr("Could not open file with the clock adjustment parameters "
821 "in it (" ADJPATH
") for writing");
824 if (fputs(newfile
, adjfile
) < 0) {
825 outsyserr("Could not update file with the clock adjustment "
826 "parameters (" ADJPATH
") in it");
829 if (fclose(adjfile
) < 0) {
830 outsyserr("Could not update file with the clock adjustment "
831 "parameters (" ADJPATH
") in it");
836 fprintf(stderr
, _("Drift adjustment parameters not updated.\n"));
844 do_adjustment(struct adjtime
*adjtime_p
,
845 const bool hclock_valid
, const time_t hclocktime
,
846 const struct timeval read_time
,
847 const bool universal
, const bool testing
) {
848 /*---------------------------------------------------------------------------
849 Do the adjustment requested, by 1) setting the Hardware Clock (if
850 necessary), and 2) updating the last-adjusted time in the adjtime
853 Do not update anything if the Hardware Clock does not currently present
856 arguments <factor> and <last_time> are current values from the adjtime
859 <hclock_valid> means the Hardware Clock contains a valid time, and that
860 time is <hclocktime>.
862 <read_time> is the current system time (to be precise, it is the system
863 time at the time <hclocktime> was read, which due to computational delay
864 could be a short time ago).
866 <universal>: the Hardware Clock is kept in UTC.
868 <testing>: We are running in test mode (no updating of clock).
870 We do not bother to update the clock if the adjustment would be less than
871 one second. This is to avoid cumulative error and needless CPU hogging
872 (remember we use an infinite loop for some timing) if the user runs us
875 ----------------------------------------------------------------------------*/
877 fprintf(stderr
, _("The Hardware Clock does not contain a valid time, "
878 "so we cannot adjust it.\n"));
881 /* Number of seconds we must insert in the Hardware Clock */
883 /* Fraction of second we have to remove from clock after inserting
884 <adjustment> whole seconds.
886 calculate_adjustment(adjtime_p
->drift_factor
,
887 adjtime_p
->last_adj_time
,
888 adjtime_p
->not_adjusted
,
892 if (adjustment
> 0 || adjustment
< -1) {
893 set_hardware_clock_exact(hclocktime
+ adjustment
,
894 time_inc(read_time
, -retro
),
896 adjtime_p
->last_adj_time
= hclocktime
+ adjustment
;
897 adjtime_p
->not_adjusted
= 0;
898 adjtime_p
->dirty
= TRUE
;
901 printf(_("Needed adjustment is less than one second, "
902 "so not setting clock.\n"));
909 determine_clock_access_method(const bool user_requests_ISA
) {
913 if (user_requests_ISA
)
914 ur
= probe_for_cmos_clock();
917 ur
= probe_for_rtc_clock();
920 ur
= probe_for_kd_clock();
922 if (!ur
&& !user_requests_ISA
)
923 ur
= probe_for_cmos_clock();
927 printf(_("Using %s.\n"), ur
->interface_name
);
929 printf(_("No usable clock interface found.\n"));
934 manipulate_clock(const bool show
, const bool adjust
,
935 const bool set
, const time_t set_time
,
936 const bool hctosys
, const bool systohc
,
937 const struct timeval startup_time
,
938 const bool utc
, const bool local_opt
,
939 const bool testing
, int *retcode_p
) {
940 /*---------------------------------------------------------------------------
941 Do all the normal work of hwclock - read, set clock, etc.
943 Issue output to stdout and error message to stderr where appropriate.
945 Return rc == 0 if everything went OK, rc != 0 if not.
946 ----------------------------------------------------------------------------*/
947 struct adjtime adjtime
;
948 /* Contents of the adjtime file, or what they should be. */
949 int rc
; /* local return code */
950 bool no_auth
; /* User lacks necessary authorization to access the clock */
952 no_auth
= ur
->get_permissions();
954 if (no_auth
) *retcode_p
= 1;
956 if (adjust
|| set
|| systohc
|| (!utc
&& !local_opt
))
957 read_adjtime(&adjtime
, &rc
);
959 /* A little trick to avoid reading the file if we don't have to */
960 adjtime
.dirty
= FALSE
;
963 if (rc
!= 0) *retcode_p
= 2;
965 const bool universal
= hw_clock_is_utc(utc
, local_opt
, adjtime
);
967 if ((set
|| systohc
|| adjust
) &&
968 (adjtime
.local_utc
== UTC
) != universal
) {
969 adjtime
.local_utc
= universal
? UTC
: LOCAL
;
970 adjtime
.dirty
= TRUE
;
973 synchronize_to_clock_tick(retcode_p
);
974 /* this takes up to 1 second */
975 if (*retcode_p
== 0) {
976 struct timeval read_time
;
977 /* The time at which we read the Hardware Clock */
980 /* The Hardware Clock gives us a valid time, or at least something
981 close enough to fool mktime().
985 /* The time the hardware clock had just after we
986 synchronized to its next clock tick when we started up.
987 Defined only if hclock_valid is true.
990 gettimeofday(&read_time
, NULL
);
991 read_hardware_clock(universal
, &hclock_valid
, &hclocktime
);
994 display_time(hclock_valid
, hclocktime
,
995 time_diff(read_time
, startup_time
));
998 set_hardware_clock_exact(set_time
, startup_time
,
1000 adjust_drift_factor(&adjtime
, set_time
, hclock_valid
, hclocktime
);
1002 } else if (adjust
) {
1003 do_adjustment(&adjtime
, hclock_valid
, hclocktime
,
1004 read_time
, universal
, testing
);
1006 } else if (systohc
) {
1007 struct timeval nowtime
, reftime
;
1008 /* We can only set_hardware_clock_exact to a whole seconds
1009 time, so we set it with reference to the most recent
1012 gettimeofday(&nowtime
, NULL
);
1013 reftime
.tv_sec
= nowtime
.tv_sec
;
1014 reftime
.tv_usec
= 0;
1016 set_hardware_clock_exact((time_t) reftime
.tv_sec
, reftime
,
1017 universal
, testing
);
1019 adjust_drift_factor(&adjtime
, (time_t) reftime
.tv_sec
, hclock_valid
,
1021 } else if (hctosys
) {
1022 rc
= set_system_clock(hclock_valid
, hclocktime
, testing
);
1024 printf(_("Unable to set system clock.\n"));
1026 } else *retcode_p
= 0;
1028 save_adjtime(adjtime
, testing
);
1036 manipulate_epoch(const bool getepoch
, const bool setepoch
,
1037 const int epoch_opt
, const bool testing
) {
1038 /*----------------------------------------------------------------------------
1039 Get or set the Hardware Clock epoch value in the kernel, as appropriate.
1040 <getepoch>, <setepoch>, and <epoch> are hwclock invocation options.
1042 <epoch> == -1 if the user did not specify an "epoch" option.
1044 -----------------------------------------------------------------------------*/
1046 Maintenance note: This should work on non-Alpha machines, but the
1047 evidence today (98.03.04) indicates that the kernel only keeps the
1048 epoch value on Alphas. If that is ever fixed, this function should be
1053 fprintf(stderr
, _("The kernel keeps an epoch value for the Hardware Clock "
1054 "only on an Alpha machine.\nThis copy of hwclock was built for "
1055 "a machine other than Alpha\n(and thus is presumably not running "
1056 "on an Alpha now). No action taken.\n"));
1059 unsigned long epoch
;
1061 if (get_epoch_rtc(&epoch
, 0))
1062 fprintf(stderr
, _("Unable to get the epoch value from the kernel.\n"));
1064 printf(_("Kernel is assuming an epoch value of %lu\n"), epoch
);
1065 } else if (setepoch
) {
1066 if (epoch_opt
== -1)
1067 fprintf(stderr
, _("To set the epoch value, you must use the 'epoch' "
1068 "option to tell to what value to set it.\n"));
1070 printf(_("Not setting the epoch to %d - testing only.\n"),
1072 else if (set_epoch_rtc(epoch_opt
))
1073 printf(_("Unable to set the epoch value in the kernel.\n"));
1079 #define RTC_DEV "/dev/efirtc"
1081 #define RTC_DEV "/dev/rtc"
1085 usage - Output (error and) usage information
1087 This function is called both directly from main to show usage
1088 information and as fatal function from shhopt if some argument is
1089 not understood. In case of normal usage info FMT should be NULL.
1090 In that case the info is printed to stdout. If FMT is given
1091 usage will act like fprintf( stderr, fmt, ... ), show a usage
1092 information and terminate the program afterwards.
1095 usage( const char *fmt
, ... ) {
1099 usageto
= fmt
? stderr
: stdout
;
1101 fprintf( usageto
, _(
1102 "hwclock - query and set the hardware clock (RTC)\n\n"
1103 "Usage: hwclock [function] [options...]\n\n"
1105 " --help show this help\n"
1106 " --show read hardware clock and print result\n"
1107 " --set set the rtc to the time given with --date\n"
1108 " --hctosys set the system time from the hardware clock\n"
1109 " --systohc set the hardware clock to the current system time\n"
1110 " --adjust adjust the rtc to account for systematic drift since \n"
1111 " the clock was last set or adjusted\n"
1112 " --getepoch print out the kernel's hardware clock epoch value\n"
1113 " --setepoch set the kernel's hardware clock epoch value to the \n"
1114 " value given with --epoch\n"
1115 " --version print out the version of hwclock to stdout\n"
1117 " --utc the hardware clock is kept in coordinated universal time\n"
1118 " --localtime the hardware clock is kept in local time\n"
1119 " --directisa access the ISA bus directly instead of %s\n"
1120 " --badyear ignore rtc's year because the bios is broken\n"
1121 " --date specifies the time to which to set the hardware clock\n"
1122 " --epoch=year specifies the year which is the beginning of the \n"
1123 " hardware clock's epoch value\n"
1126 fprintf( usageto
, _(
1127 " --jensen, --arc, --srm, --funky-toy\n"
1128 " tell hwclock the type of alpha you have (see hwclock(8))\n"
1137 vfprintf(stderr
, fmt
, ap
);
1141 exit( fmt
? 99 : 0 );
1145 main(int argc
, char **argv
) {
1147 struct timeval startup_time
;
1148 /* The time we started up, in seconds into the epoch, including fractions.
1150 time_t set_time
; /* Time to which user said to set Hardware Clock */
1152 bool permitted
; /* User is permitted to do the function */
1153 int retcode
; /* Our eventual return code */
1155 int rc
; /* local return code */
1157 /* option_def is the control table for the option parser. These other
1158 variables are the results of parsing the options and their meanings
1159 are given by the option_def. The only exception is <show>, which
1160 may be modified after parsing is complete to effect an implied option.
1162 bool help
, show
, set
, systohc
, hctosys
, adjust
, getepoch
, setepoch
, version
;
1163 bool ARCconsole
, utc
, testing
, directisa
, Jensen
, SRM
, funky_toy
;
1167 const optStruct option_def
[] = {
1168 { 'h', (char *) "help", OPT_FLAG
, &help
, 0 },
1169 { 'r', (char *) "show", OPT_FLAG
, &show
, 0 },
1170 { 0, (char *) "set", OPT_FLAG
, &set
, 0 },
1171 { 'w', (char *) "systohc", OPT_FLAG
, &systohc
, 0 },
1172 { 's', (char *) "hctosys", OPT_FLAG
, &hctosys
, 0 },
1173 { 0, (char *) "getepoch", OPT_FLAG
, &getepoch
, 0 },
1174 { 0, (char *) "setepoch", OPT_FLAG
, &setepoch
, 0 },
1175 { 'a', (char *) "adjust", OPT_FLAG
, &adjust
, 0 },
1176 { 'v', (char *) "version", OPT_FLAG
, &version
, 0 },
1177 { 'V', (char *) "version", OPT_FLAG
, &version
, 0 },
1178 { 0, (char *) "date", OPT_STRING
, &date_opt
, 0 },
1179 { 0, (char *) "epoch", OPT_UINT
, &epoch_option
,0 },
1180 { 'u', (char *) "utc", OPT_FLAG
, &utc
, 0 },
1181 { 0, (char *) "localtime", OPT_FLAG
, &local_opt
, 0 },
1182 { 0, (char *) "badyear", OPT_FLAG
, &badyear
, 0 },
1183 { 0, (char *) "directisa", OPT_FLAG
, &directisa
, 0 },
1184 { 0, (char *) "test", OPT_FLAG
, &testing
, 0 },
1185 { 'D', (char *) "debug", OPT_FLAG
, &debug
, 0 },
1187 { 'A', (char *) "ARC", OPT_FLAG
, &ARCconsole
,0 },
1188 { 'J', (char *) "Jensen", OPT_FLAG
, &Jensen
, 0 },
1189 { 'S', (char *) "SRM", OPT_FLAG
, &SRM
, 0 },
1190 { 'F', (char *) "funky-toy", OPT_FLAG
, &funky_toy
, 0 },
1192 { 0, (char *) NULL
, OPT_END
, NULL
, 0 }
1194 int argc_parse
; /* argc, except we modify it as we parse */
1195 char **argv_parse
; /* argv, except we modify it as we parse */
1197 gettimeofday(&startup_time
, NULL
); /* Remember what time we were invoked */
1199 setlocale(LC_ALL
, "");
1201 /* We need LC_CTYPE and LC_TIME and LC_MESSAGES, but must avoid
1202 LC_NUMERIC since it gives problems when we write to /etc/adjtime.
1203 - gqueri@mail.dotcom.fr */
1204 setlocale(LC_NUMERIC
, "C");
1206 bindtextdomain(PACKAGE
, LOCALEDIR
);
1207 textdomain(PACKAGE
);
1209 /* set option defaults */
1210 help
= show
= set
= systohc
= hctosys
= adjust
= getepoch
= setepoch
=
1211 version
= utc
= local_opt
= ARCconsole
= SRM
= funky_toy
=
1212 directisa
= badyear
= Jensen
= testing
= debug
= FALSE
;
1215 argc_parse
= argc
; argv_parse
= argv
;
1216 optParseOptions(&argc_parse
, argv_parse
, option_def
, 0);
1217 /* Uses and sets argc_parse, argv_parse.
1218 Sets show, systohc, hctosys, adjust, utc, local_opt, version,
1219 testing, debug, set, date_opt, getepoch, setepoch, epoch_option
1221 /* This is an ugly routine - for example, if I give an incorrect
1222 option, it only says "unrecognized option" without telling
1223 me what options are recognized. Rewrite with standard
1224 getopt() and usage() and throw shhopt out. */
1226 if (argc_parse
- 1 > 0) {
1227 usage( _("%s takes no non-option arguments. "
1228 "You supplied %d.\n"),
1229 MYNAME
, argc_parse
- 1);
1235 if (show
+ set
+ systohc
+ hctosys
+ adjust
+
1236 getepoch
+ setepoch
+ version
> 1) {
1237 fprintf(stderr
, _("You have specified multiple function options.\n"
1238 "You can only perform one function at a time.\n"));
1242 if (utc
&& local_opt
) {
1243 fprintf(stderr
, _("%s: The --utc and --localtime options are mutually "
1244 "exclusive. You specified both.\n"), MYNAME
);
1249 set_cmos_epoch(ARCconsole
, SRM
);
1250 set_cmos_access(Jensen
, funky_toy
);
1254 rc
= interpret_date_string(date_opt
, &set_time
); /* (time-consuming) */
1256 fprintf(stderr
, _("No usable set-to time. Cannot set clock.\n"));
1261 if (!(show
| set
| systohc
| hctosys
| adjust
| getepoch
| setepoch
|
1263 show
= 1; /* default to show */
1266 if (getuid() == 0) permitted
= TRUE
;
1268 /* program is designed to run setuid (in some situations) -- be secure! */
1269 if (set
|| hctosys
|| systohc
|| adjust
) {
1271 _("Sorry, only the superuser can change the Hardware Clock.\n"));
1273 } else if (hctosys
) {
1275 _("Sorry, only the superuser can change the System Clock.\n"));
1277 } else if (setepoch
) {
1279 _("Sorry, only the superuser can change "
1280 "the Hardware Clock epoch in the kernel.\n"));
1286 if (!permitted
) retcode
= 2;
1290 printf(MYNAME
" " VERSION
"/%s\n",util_linux_version
);
1291 } else if (getepoch
|| setepoch
) {
1292 manipulate_epoch(getepoch
, setepoch
, epoch_option
, testing
);
1295 printf(MYNAME
" " VERSION
"/%s\n",util_linux_version
);
1296 determine_clock_access_method(directisa
);
1299 _("Cannot access the Hardware Clock via any known method.\n"));
1302 _("Use the --debug option to see the details of our "
1303 "search for an access method.\n"));
1305 manipulate_clock(show
, adjust
, set
, set_time
, hctosys
, systohc
,
1306 startup_time
, utc
, local_opt
, testing
, &rc
);
1312 /* A single routine for greater uniformity */
1314 outsyserr(char *msg
, ...) {
1318 fprintf(stderr
, "%s: ", progname
);
1319 va_start(args
, msg
);
1320 vfprintf(stderr
, msg
, args
);
1322 fprintf(stderr
, ", errno=%d: %s.\n",
1323 errsv
, strerror(errsv
));
1326 /****************************************************************************
1328 History of this program:
1330 98.08.12 BJH Version 2.4
1332 Don't use century byte from Hardware Clock. Add comments telling why.
1335 98.06.20 BJH Version 2.3.
1337 Make --hctosys set the kernel timezone from TZ environment variable
1338 and/or /usr/lib/zoneinfo. From Klaus Ripke (klaus@ripke.com).
1340 98.03.05 BJH. Version 2.2.
1342 Add --getepoch and --setepoch.
1344 Fix some word length things so it works on Alpha.
1346 Make it work when /dev/rtc doesn't have the interrupt functions.
1347 In this case, busywait for the top of a second instead of blocking and
1348 waiting for the update complete interrupt.
1350 Fix a bunch of bugs too numerous to mention.
1352 97.06.01: BJH. Version 2.1. Read and write the century byte (Byte
1353 50) of the ISA Hardware Clock when using direct ISA I/O. Problem
1354 discovered by job (jei@iclnl.icl.nl).
1356 Use the rtc clock access method in preference to the KDGHWCLK method.
1357 Problem discovered by Andreas Schwab <schwab@LS5.informatik.uni-dortmund.de>.
1359 November 1996: Version 2.0.1. Modifications by Nicolai Langfeldt
1360 (janl@math.uio.no) to make it compile on linux 1.2 machines as well
1361 as more recent versions of the kernel. Introduced the NO_CLOCK
1362 access method and wrote feature test code to detect absense of rtc
1366 **************************************************************************
1369 To compile this, you must use GNU compiler optimization (-O option)
1370 in order to make the "extern inline" functions from asm/io.h (inb(),
1371 etc.) compile. If you don't optimize, which means the compiler
1372 will generate no inline functions, the references to these functions
1373 in this program will be compiled as external references. Since you
1374 probably won't be linking with any functions by these names, you will
1375 have unresolved external references when you link.
1377 The program is designed to run setuid superuser, since we need to be
1378 able to do direct I/O. (More to the point: we need permission to
1379 execute the iopl() system call). (However, if you use one of the
1380 methods other than direct ISA I/O to access the clock, no setuid is
1383 Here's some info on how we must deal with the time that elapses while
1384 this program runs: There are two major delays as we run:
1386 1) Waiting up to 1 second for a transition of the Hardware Clock so
1387 we are synchronized to the Hardware Clock.
1389 2) Running the "date" program to interpret the value of our --date
1392 Reading the /etc/adjtime file is the next biggest source of delay and
1395 The user wants to know what time it was at the moment he invoked us,
1396 not some arbitrary time later. And in setting the clock, he is
1397 giving us the time at the moment we are invoked, so if we set the
1398 clock some time later, we have to add some time to that.
1400 So we check the system time as soon as we start up, then run "date"
1401 and do file I/O if necessary, then wait to synchronize with a
1402 Hardware Clock edge, then check the system time again to see how
1403 much time we spent. We immediately read the clock then and (if
1404 appropriate) report that time, and additionally, the delay we measured.
1406 If we're setting the clock to a time given by the user, we wait some
1407 more so that the total delay is an integral number of seconds, then
1408 set the Hardware Clock to the time the user requested plus that
1409 integral number of seconds. N.B. The Hardware Clock can only be set
1410 in integral seconds.
1412 If we're setting the clock to the system clock value, we wait for
1413 the system clock to reach the top of a second, and then set the
1414 Hardware Clock to the system clock's value.
1416 Here's an interesting point about setting the Hardware Clock: On my
1417 machine, when you set it, it sets to that precise time. But one can
1418 imagine another clock whose update oscillator marches on a steady one
1419 second period, so updating the clock between any two oscillator ticks
1420 is the same as updating it right at the earlier tick. To avoid any
1421 complications that might cause, we set the clock as soon as possible
1422 after an oscillator tick.
1425 About synchronizing to the Hardware Clock when reading the time: The
1426 precision of the Hardware Clock counters themselves is one second.
1427 You can't read the counters and find out that is 12:01:02.5. But if
1428 you consider the location in time of the counter's ticks as part of
1429 its value, then its precision is as infinite as time is continuous!
1430 What I'm saying is this: To find out the _exact_ time in the
1431 hardware clock, we wait until the next clock tick (the next time the
1432 second counter changes) and measure how long we had to wait. We
1433 then read the value of the clock counters and subtract the wait time
1434 and we know precisely what time it was when we set out to query the
1437 hwclock uses this method, and considers the Hardware Clock to have
1441 Enhancements needed:
1443 - When waiting for whole second boundary in set_hardware_clock_exact,
1444 fail if we miss the goal by more than .1 second, as could happen if
1445 we get pre-empted (by the kernel dispatcher).
1447 ****************************************************************************/