⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hwclock.c

📁 Util-linux 软件包包含许多工具。其中比较重要的是加载、卸载、格式化、分区和管理硬盘驱动器
💻 C
📖 第 1 页 / 共 4 页
字号:
	adjtime_p->last_calib_time = nowtime;  	adjtime_p->last_adj_time = nowtime;  	adjtime_p->not_adjusted = 0;    	adjtime_p->dirty = TRUE;}static voidcalculate_adjustment(const double factor,                     const time_t last_time,                      const double not_adjusted,                     const time_t systime,                     int *adjustment_p,                      double *retro_p,                     const int debug ) {/*----------------------------------------------------------------------------  Do the drift adjustment calculation.  The way we have to set the clock, we need the adjustment in two parts:    1) an integer number of seconds (return as *adjustment_p)           2) a positive fraction of a second (less than 1) (return as *retro_p)  The sum of these two values is the adjustment needed.  Positive means to  advance the clock or insert seconds.  Negative means to retard the clock  or remove seconds.----------------------------------------------------------------------------*/  double exact_adjustment;  exact_adjustment = ((double) (systime - last_time)) * factor / (24 * 60 * 60)                     + not_adjusted;  *adjustment_p = FLOOR(exact_adjustment);    *retro_p = exact_adjustment - (double) *adjustment_p;  if (debug) {    printf (_("Time since last adjustment is %d seconds\n"),            (int) (systime - last_time));    printf (_("Need to insert %d seconds and refer time back "            "%.6f seconds ago\n"),            *adjustment_p, *retro_p);  }}static voidsave_adjtime(const struct adjtime adjtime, const bool testing) {/*-----------------------------------------------------------------------------  Write the contents of the <adjtime> structure to its disk file.  But if the contents are clean (unchanged since read from disk), don't  bother.-----------------------------------------------------------------------------*/  char newfile[412];   /* Stuff to write to disk file */  if (adjtime.dirty) {    /* snprintf is not always available, but this is safe       as long as libc does not use more than 100 positions for %ld or %f */    sprintf(newfile, "%f %ld %f\n%ld\n%s\n",             adjtime.drift_factor,             (long) adjtime.last_adj_time,             adjtime.not_adjusted,             (long) adjtime.last_calib_time,	     (adjtime.local_utc == UTC) ? "UTC" : "LOCAL");    if (testing) {      printf(_("Not updating adjtime file because of testing mode.\n"));      printf(_("Would have written the following to %s:\n%s"),              ADJPATH, newfile);    } else {      FILE *adjfile;      int err = 0;      adjfile = fopen(ADJPATH, "w");      if (adjfile == NULL) {        outsyserr("Could not open file with the clock adjustment parameters "               "in it (" ADJPATH ") for writing");	err = 1;      } else {        if (fputs(newfile, adjfile) < 0) {	  outsyserr("Could not update file with the clock adjustment "		    "parameters (" ADJPATH ") in it");	  err = 1;        }        if (fclose(adjfile) < 0) {          outsyserr("Could not update file with the clock adjustment "		    "parameters (" ADJPATH ") in it");	  err = 1;        }      }      if (err)	fprintf(stderr, _("Drift adjustment parameters not updated.\n"));    }  }}static voiddo_adjustment(struct adjtime *adjtime_p,              const bool hclock_valid, const time_t hclocktime,               const struct timeval read_time,              const bool universal, const bool testing) {/*---------------------------------------------------------------------------  Do the adjustment requested, by 1) setting the Hardware Clock (if   necessary), and 2) updating the last-adjusted time in the adjtime  structure.  Do not update anything if the Hardware Clock does not currently present  a valid time.  arguments <factor> and <last_time> are current values from the adjtime  file.  <hclock_valid> means the Hardware Clock contains a valid time, and that  time is <hclocktime>.  <read_time> is the current system time (to be precise, it is the system   time at the time <hclocktime> was read, which due to computational delay  could be a short time ago).  <universal>: the Hardware Clock is kept in UTC.  <testing>:  We are running in test mode (no updating of clock).  We do not bother to update the clock if the adjustment would be less than  one second.  This is to avoid cumulative error and needless CPU hogging  (remember we use an infinite loop for some timing) if the user runs us  frequently.----------------------------------------------------------------------------*/  if (!hclock_valid) {    fprintf(stderr, _("The Hardware Clock does not contain a valid time, "            "so we cannot adjust it.\n"));    adjtime_p->last_calib_time = 0;  /* calibration startover is required */    adjtime_p->last_adj_time = 0;    adjtime_p->not_adjusted = 0;    adjtime_p->dirty = TRUE;  } else if (adjtime_p->last_adj_time == 0) {    if (debug)      printf("Not setting clock because last adjustment time is zero, "	     "so history is bad.");  } else {    int adjustment;    /* Number of seconds we must insert in the Hardware Clock */    double retro;       /* Fraction of second we have to remove from clock after inserting       <adjustment> whole seconds.       */    calculate_adjustment(adjtime_p->drift_factor,                         adjtime_p->last_adj_time,                         adjtime_p->not_adjusted,                         hclocktime,                         &adjustment, &retro,                         debug );    if (adjustment > 0 || adjustment < -1) {      set_hardware_clock_exact(hclocktime + adjustment,                                time_inc(read_time, -retro),                               universal, testing);      adjtime_p->last_adj_time = hclocktime + adjustment;      adjtime_p->not_adjusted = 0;      adjtime_p->dirty = TRUE;    } else       if (debug)         printf(_("Needed adjustment is less than one second, "               "so not setting clock.\n"));  }}static voiddetermine_clock_access_method(const bool user_requests_ISA) {  ur = NULL;  if (user_requests_ISA)	  ur = probe_for_cmos_clock();  if (!ur)	  ur = probe_for_rtc_clock();  if (!ur)	  ur = probe_for_kd_clock();  if (!ur && !user_requests_ISA)	  ur = probe_for_cmos_clock();  if (debug) {	  if (ur)		  printf(_("Using %s.\n"), ur->interface_name);	  else		  printf(_("No usable clock interface found.\n"));  }}static intmanipulate_clock(const bool show, const bool adjust, const bool noadjfile,                 const bool set, const time_t set_time,                 const bool hctosys, const bool systohc,                  const struct timeval startup_time,                  const bool utc, const bool local_opt,		 const bool testing) {/*---------------------------------------------------------------------------  Do all the normal work of hwclock - read, set clock, etc.  Issue output to stdout and error message to stderr where appropriate.  Return rc == 0 if everything went OK, rc != 0 if not.----------------------------------------------------------------------------*/    struct adjtime adjtime;      /* Contents of the adjtime file, or what they should be. */    int rc;  /* local return code */    bool no_auth;  /* User lacks necessary authorization to access the clock */    no_auth = ur->get_permissions();    if (no_auth)	  return EX_NOPERM;    if (!noadjfile && (adjust || set || systohc || (!utc && !local_opt))) {      rc = read_adjtime(&adjtime);      if (rc)	      return rc;    } else {      /* A little trick to avoid reading the file if we don't have to */      adjtime.dirty = FALSE;       rc = 0;    }    {      const bool universal = hw_clock_is_utc(utc, local_opt, adjtime);      if ((set || systohc || adjust) &&	  (adjtime.local_utc == UTC) != universal) {	adjtime.local_utc = universal ? UTC : LOCAL;	adjtime.dirty = TRUE;      }      rc = synchronize_to_clock_tick();  /* this takes up to 1 second */      if (rc)	      return rc;      {        struct timeval read_time;           /* The time at which we read the Hardware Clock */        bool hclock_valid;          /* The Hardware Clock gives us a valid time, or at least something             close enough to fool mktime().             */        time_t hclocktime;          /* The time the hardware clock had just after we             synchronized to its next clock tick when we started up.             Defined only if hclock_valid is true.             */                gettimeofday(&read_time, NULL);        read_hardware_clock(universal, &hclock_valid, &hclocktime);                 if (show) {          display_time(hclock_valid, hclocktime,                        time_diff(read_time, startup_time));        } else if (set) {          set_hardware_clock_exact(set_time, startup_time, 				      universal, testing);          adjust_drift_factor(&adjtime, set_time, hclock_valid, hclocktime,			      time_diff(read_time, startup_time));        } else if (adjust) {          do_adjustment(&adjtime, hclock_valid, hclocktime,                         read_time, universal, testing);        } else if (systohc) {          struct timeval nowtime, reftime;          /* We can only set_hardware_clock_exact to a whole seconds             time, so we set it with reference to the most recent             whole seconds time.               */          gettimeofday(&nowtime, NULL);          reftime.tv_sec = nowtime.tv_sec;          reftime.tv_usec = 0;                    set_hardware_clock_exact((time_t) reftime.tv_sec, reftime,                                    universal, testing);          adjust_drift_factor(&adjtime, (time_t) reftime.tv_sec, hclock_valid,                               hclocktime, (double) read_time.tv_usec / 1E6);        } else if (hctosys) {          rc = set_system_clock(hclock_valid, hclocktime, testing);          if (rc) {            printf(_("Unable to set system clock.\n"));	    return rc;          }        }        if (!noadjfile)         save_adjtime(adjtime, testing);      }    }    return 0;}static voidmanipulate_epoch(const bool getepoch, const bool setepoch,                  const int epoch_opt, const bool testing) {/*----------------------------------------------------------------------------   Get or set the Hardware Clock epoch value in the kernel, as appropriate.   <getepoch>, <setepoch>, and <epoch> are hwclock invocation options.   <epoch> == -1 if the user did not specify an "epoch" option.-----------------------------------------------------------------------------*/  /*   Maintenance note:  This should work on non-Alpha machines, but the    evidence today (98.03.04) indicates that the kernel only keeps the   epoch value on Alphas.  If that is ever fixed, this function should be   changed.   */#ifndef __alpha__    fprintf(stderr, _("The kernel keeps an epoch value for the Hardware Clock "            "only on an Alpha machine.\nThis copy of hwclock was built for "            "a machine other than Alpha\n(and thus is presumably not running "            "on an Alpha now).  No action taken.\n"));#else    if (getepoch) {      unsigned long epoch;      if (get_epoch_rtc(&epoch, 0))        fprintf(stderr, _("Unable to get the epoch value from the kernel.\n"));      else         printf(_("Kernel is assuming an epoch value of %lu\n"), epoch);    } else if (setepoch) {      if (epoch_opt == -1)        fprintf(stderr, _("To set the epoch value, you must use the 'epoch' "                "option to tell to what value to set it.\n"));      else if (testing)        printf(_("Not setting the epoch to %d - testing only.\n"),	       epoch_opt);      else if (set_epoch_rtc(epoch_opt))        printf(_("Unable to set the epoch value in the kernel.\n"));    }#endif}#if __ia64__#define RTC_DEV "/dev/efirtc"#else#define RTC_DEV "/dev/rtc"#endifstatic voidout_version(void) {	printf(_("%s from %s\n"), MYNAME, util_linux_version);}/*    usage - Output (error and) usage information    This function is called both directly from main to show usage     information and as fatal function from shhopt if some argument is     not understood. In case of normal usage info FMT should be NULL.     In that case the info is printed to stdout. If FMT is given     usage will act like fprintf( stderr, fmt, ... ), show a usage     information and terminate the program afterwards.*/static void usage( const char *fmt, ... ) {  FILE    *usageto;  va_list ap;  usageto = fmt ? stderr : stdout;  fprintf( usageto, _(    "hwclock - query and set the hardware clock (RTC)\n\n"    "Usage: hwclock [function] [options...]\n\n"    "Functions:\n"    "  --help        show this help\n"    "  --show        read hardware clock and print result\n"    "  --set         set the rtc to the time given with --date\n"    "  --hctosys     set the system time from the hardware clock\n"    "  --systohc     set the hardware clock to the current system time\n"    "  --adjust      adjust the rtc to account for systematic drift since \n"    "                the clock was last set or adjusted\n"    "  --getepoch    print out the kernel's hardware clock epoch value\n"    "  --setepoch    set the kernel's hardware clock epoch value to the \n"    "                value given with --epoch\n"    "  --version     print out the version of hwclock to stdout\n"    "\nOptions: \n"    "  --utc         the hardware clock is kept in coordinated universal time\n"    "  --localtime   the hardware clock is kept in local time\n"    "  --directisa   access the ISA bus directly instead of %s\n"    "  --badyear     ignore rtc's year because the bios is broken\n"    "  --date        specifies the time to which to set the hardware clock\n"    "  --epoch=year  specifies the year which is the beginning of the \n"    "                hardware clock's epoch value\n"    "  --noadjfile   do not access /etc/adjtime. Requires the use of\n"    "                either --utc or --localtime\n"    ),RTC_DEV);#ifdef __alpha__  fprintf(usageto, _(    "  --jensen, --arc, --srm, --funky-toy\n"    "                tell hwclock the type of alpha you have (see hwclock(8))\n"    ) );#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -