source: trunk/third/xntp/xntpd/ntp_unixclock.c @ 10832

Revision 10832, 17.1 KB checked in by brlewis, 27 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r10831, which included commits to RCS files with non-trunk default branches.
Line 
1/*
2 * ntp_unixclock.c - routines for reading and adjusting a 4BSD-style
3 *                   system clock.  Emacs has hide-ifdef-mode ...
4 */
5
6#ifdef HAVE_CONFIG_H
7# include <config.h>
8#endif
9
10#include <stdio.h>
11#include <sys/types.h>
12#ifdef HAVE_UNISTD_H
13# include <unistd.h>
14#endif /* HAVE_UNISTD_H */
15#ifdef NLIST_STRUCT
16# include <nlist.h>
17# ifdef NLIST_NAME_UNION
18#  define N_NAME n_un.n_name
19# else /* not NLIST_NAME_UNION */
20#  define N_NAME n_name
21# endif /* not NLIST_NAME_UNION */
22#endif /* NLIST_STRUCT */
23#include <sys/stat.h>
24#include <sys/time.h>
25
26#ifdef HAVE_SYS_PARAM_H
27# include <sys/param.h>
28#endif
29#ifdef HAVE_UTMP_H
30# include <utmp.h>
31#endif
32#ifdef HAVE_SYS_SYSCTL_H
33#include <sys/sysctl.h>
34#endif
35
36#if defined(HAVE_GETBOOTFILE)
37# include <paths.h>
38#endif
39
40#include "ntpd.h"
41#include "ntp_io.h"
42#include "ntp_unixtime.h"
43#include "ntp_stdlib.h"
44
45#if defined(HAVE_LIBKVM)
46# ifdef HAVE_SYS_PROC_H
47#  include <sys/proc.h>
48# endif
49# include <kvm.h>
50# include <limits.h>
51
52# ifndef _POSIX2_LINE_MAX
53#  define _POSIX2_LINE_MAX 2048
54# endif
55#endif  /* HAVE_LIBKVM */
56
57#ifdef HAVE_SYS_TIMEX_H         /* Linux - also HAVE___ADJTIMEX */
58# include <sys/timex.h>
59#endif
60
61#ifdef hz /* Was: RS6000 */
62# undef hz
63#endif /* hz */
64
65extern int debug;
66/*
67 * These routines (init_systime, get_systime, step_systime, adj_systime)
68 * implement an interface between the (more or less) system independent
69 * bits of NTP and the peculiarities of dealing with the Unix system
70 * clock.  These routines will run with good precision fairly independently
71 * of your kernel's value of tickadj.  I couldn't tell the difference
72 * between tickadj==40 and tickadj==5 on a microvax, though I prefer
73 * to set tickadj == 500/hz when in doubt.  At your option you
74 * may compile this so that your system's clock is always slewed to the
75 * correct time even for large corrections.  Of course, all of this takes
76 * a lot of code which wouldn't be needed with a reasonable tickadj and
77 * a willingness to let the clock be stepped occasionally.  Oh well.
78 */
79extern  long adj_precision;     /* adj precision in usec (tickadj) */
80extern  long tvu_maxslew;       /* maximum adjust doable in one sec (usec) */
81
82#ifdef SYS_WINNT
83extern  long units_per_tick;    /* imported from lib/systime.c module */
84#endif /* SYS_WINNT */
85
86extern  u_long tsf_maxslew;     /* same as above, as long format */
87
88extern  l_fp sys_clock_offset;  /* correction for current system time */
89
90#if defined(GDT_SURVEYING)
91extern l_fp gdt_rsadj;          /* running sum of adjustments to time */
92#endif
93
94/*
95 * Import sys_clock (it is updated in get_systime)
96 */
97extern long sys_clock;
98
99/*
100 * Export default_tick and default_tickadj (for ntp_config)
101 */
102u_long default_tick = 0;
103u_long default_tickadj = 0;
104
105static  void    clock_parms     P((u_long *, u_long *));
106
107/*
108 * init_systime - initialize the system clock support code, return
109 *                clock precision.
110 *
111 * Note that this code obtains to kernel variables related to the local
112 * clock, tickadj and tick.  The code knows how the Berkeley adjtime
113 * call works, and assumes these two variables are obtainable and are
114 * used in the same manner.  Tick is supposed to be the number of
115 * microseconds which are added to the system clock at clock interrupt
116 * time when the time isn't being slewed.  Tickadj is supposed to be
117 * the number of microseconds which are added or subtracted from tick when
118 * the time is being slewed.
119 *
120 * If either of these two variables is missing, or is there but is used
121 * for a purpose different than that described, you are SOL and may have
122 * to do some custom kludging.
123 *
124 * This really shouldn't be in here.
125 */
126void
127init_systime()
128{
129        u_long tickadj;
130        u_long tick;
131        u_long hz;
132
133        /*
134         * Obtain the values
135         */
136#if !defined(VMS)
137        clock_parms(&tickadj, &tick);
138#else
139        {
140                extern int get_tickfreq(int *FREQ, int *SYSTICK);
141                int freq,systick,sts;
142
143                sts = get_tickfreq(&freq,&systick);
144                if(!(sts & 1)) lib$stop(sts);
145
146                tick = 1000000/freq;    /* (usec) */
147        }
148        tickadj = tick/10;      /* VMS_{ADJTIME,TICTIME}.C will do up to 10% */
149#endif /* VMS */
150#ifdef  DEBUG
151        if (debug)
152                printf("kernel vars: tickadj = %ld, tick = %ld\n", tickadj, tick);
153#endif
154
155        /*
156         * If tickadj or hz wasn't found, we're doomed.  If hz is
157         * unreasonably small, forget it.
158         */
159        if (tickadj == 0 || tick == 0) {
160                msyslog(LOG_ERR, "tickadj or tick unknown, exiting");
161                exit(3);
162        }
163        if (tick > 65535) {
164                msyslog(LOG_ERR, "tick value of %lu is unreasonably large",
165                    tick);
166                exit(3);
167        }
168
169        /*
170         * Estimate hz from tick
171         */
172#ifndef SYS_VXWORKS
173        hz = 1000000L / tick;
174#else
175    hz =sysClkRateGet();
176#endif
177
178#ifdef SYS_WINNT
179        if ((1000000L % tick) > tick/2)
180                hz += 1;
181#endif /* SYS_WINNT */
182
183        /*
184         * Set adj_precision and the maximum slew based on this.  Note
185         * that maxslew is set slightly shorter than it needs to be as
186         * insurance that all slews requested will complete in one second.
187         */
188#ifdef ADJTIME_IS_ACCURATE
189        adj_precision = 1;
190#else
191# if defined(SCO3_TICKADJ) || defined(SCO5_TICKADJ)
192        adj_precision = tickadj * hz;
193# else
194#  ifndef SYS_WINNT
195        adj_precision = tickadj;
196#  else
197        /* minimum adjustment is one 100 nanosecond unit at each clock tick */
198        adj_precision = (long)(hz * 0.1);
199#  endif /* SYS_WINNT */
200# endif /* not SCO[35]_TICKADJ */
201#endif /* ADJTIME_IS_ACCURATE */
202#ifdef NEED_HPUX_ADJTIME
203        /*
204         * when using adjtimed daemon, need to allow more time
205         * because daemon may not run right away
206         */
207        tvu_maxslew = tickadj * (hz - 3);
208#else
209# if defined(SLEWALWAYS) && !defined(ADJTIME_IS_ACCURATE)
210        /*
211         * give us more time if we are always slewing... just in case
212         */
213        tvu_maxslew = tickadj * (hz - 3);
214# else
215#  if !defined(SYS_WINNT) && !defined(SCO3_TICKADJ) && !defined(SCO5_TICKADJ)
216        tvu_maxslew = tickadj * (hz - 1);
217#  else
218        tvu_maxslew = tickadj * hz;
219#  endif /* SYS_WINTNT */
220# endif /* SLEWALWAYS */
221#endif /* NEED_HPUX_ADJTIME */
222        if (tvu_maxslew > 999990) {
223                /*
224                 * Don't let the maximum slew exceed 1 second in 4.  This
225                 * simplifies calculations a lot since we can then deal
226                 * with less-than-one-second fractions.
227                 */
228                tvu_maxslew = (999990/adj_precision) * adj_precision;
229        }
230        TVUTOTSF(tvu_maxslew, tsf_maxslew);
231        NLOG(NLOG_SYSINFO) /* conditional if clause for conditional syslog */
232          msyslog(LOG_NOTICE, "tickadj = %d, tick = %d, tvu_maxslew = %d, est. hz = %d",
233            tickadj, tick, tvu_maxslew, hz);
234#ifdef DEBUG
235        if (debug)
236                printf(
237        "adj_precision = %ld, tvu_maxslew = %ld, tsf_maxslew = 0.%08lx\n",
238                    adj_precision, tvu_maxslew, tsf_maxslew);
239#endif
240
241        /*
242         * Set the current offset to 0
243         */
244        L_CLR(&sys_clock_offset);
245#if defined(GDT_SURVEYING)
246        /*
247         * Set the current increment
248         */
249
250        L_CLR(&gdt_rsadj);
251#endif /* GDT_SURVEYING */
252}
253
254
255#if !defined(VMS)
256
257# ifndef HZ
258#  define HZ    DEFAULT_HZ
259# endif
260
261# ifdef NLIST_STRUCT
262#  ifdef NLIST_NAME_UNION
263#   define NL_B {{
264#   define NL_E }}
265#  else
266#   define NL_B {
267#   define NL_E }
268#  endif
269# endif
270
271#define K_FILLER_NAME "DavidLetterman"
272
273/*
274 * clock_parms - return the local clock tickadj and tick parameters
275 *
276 */
277
278static void
279clock_parms(ptickadj, ptick)
280     u_long *ptickadj;
281     u_long *ptick;
282{
283  u_long tick;
284  int got_tick = 0;
285  int got_tickadj = 0;
286  int hz = 0;
287  int got_hz = 0;
288# ifdef SYS_WINNT
289  DWORD add, every;
290  BOOL noslew;
291# else /* not SYS_WINNT */
292#  if defined(HAVE_SYSCTL) && defined(CTL_KERN) && defined(KERN_CLOCKRATE)
293  int mib[2];
294  size_t ci_len;
295  struct clockinfo c;
296  int rc;
297#  endif /* HAVE_SYSCTL && CTL_KERN && KERN_CLOCKRATE */
298#  ifndef NOKMEM
299  static struct nlist nl[] =
300  {
301    NL_B
302#   ifdef K_TICKADJ_NAME
303#  define N_TICKADJ 0
304    K_TICKADJ_NAME
305#   else
306    K_FILLER_NAME
307#   endif /* K_TICKADJ_NAME */
308    NL_E,
309    NL_B
310#   ifdef K_TICK_NAME
311#  define N_TICK 1
312    K_TICK_NAME
313#   else
314    K_FILLER_NAME
315#   endif /* K_TICK_NAME */
316    NL_E,
317    NL_B "" NL_E,
318  };
319#   ifdef HAVE_K_OPEN
320#   else /* not HAVE_K_OPEN */
321#    ifdef HAVE_KVM_OPEN
322  register kvm_t *kd;
323#    else /* not HAVE_KVM_OPEN */
324  register int i;
325  int kmem;
326  struct stat stbuf;
327  off_t where;
328#     ifdef HAVE_BOOTFILE
329  const char *kernelname;
330#     else /* not HAVE_BOOTFILE */
331  static char *kernelnames[] =
332  {
333    "/kernel/unix",
334    "/kernel",
335    "/vmunix",
336    "/unix",
337    "/mach",
338    "/hp-ux",
339    "/386bsd",
340    "/netbsd",
341    "/stand/vmunix",
342    "/bsd",
343#      ifdef KERNELFILE
344    KERNELFILE,
345#      endif
346    NULL
347  };
348#     endif /* not HAVE_BOOTFILE */
349#    endif /* not HAVE_KVM_OPEN */
350#   endif /* not HAVE_K_OPEN */
351#  endif /* not NOKMEM */
352# endif /* not SYS_WINNT */
353
354# ifdef SYS_WINNT
355  if (!GetSystemTimeAdjustment(&add, &every, &noslew))
356    {
357      *ptick = 0;
358      *ptickadj = 0;
359      return;
360    }
361  units_per_tick = add;
362# else /* not SYS_WINNT */
363
364#  if defined(HAVE_SYSCTL) && defined(CTL_KERN) && defined(KERN_CLOCKRATE)
365    mib[0] = CTL_KERN;
366    mib[1] = KERN_CLOCKRATE;
367    ci_len = sizeof(c);
368    rc = sysctl(mib, 2, &c, &ci_len, NULL, 0);
369    if (rc == -1)
370    {
371      NLOG(NLOG_SYSINFO) /* conditional if clause for conditional syslog */
372      syslog(LOG_NOTICE, "sysctl returned %d: %m", rc);
373    }
374    *ptick = c.tick;
375    ++got_tick;
376#   ifdef HAVE_TICKADJ_IN_STRUCT_CLOCKINFO
377    *ptickadj = c.tickadj;
378    ++got_tickadj;
379#   endif /* HAVE_TICKADJ_IN_STRUCT_CLOCKINFO */
380#   ifdef HAVE_HZ_IN_STRUCT_CLOCKINFO
381    hz = c.hz;
382    ++got_hz;
383#   endif /* HAVE_HZ_IN_STRUCT_CLOCKINFO */
384#  endif /* HAVE_SYSCTL && CTL_KERN && KERN_CLOCKRATE */
385
386  if (!got_hz)
387  {
388    hz = HZ;
389#  if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
390    hz = (int) sysconf (_SC_CLK_TCK);
391#  endif /* HAVE_SYSCONF && _SC_CLK_TCK */
392#  ifdef OVERRIDE_HZ
393    hz = DEFAULT_HZ;
394#  endif
395    ++got_hz;
396  }
397
398  {
399#  ifndef NOKMEM
400#   ifdef HAVE_K_OPEN /* { */
401    if (K_open((char *)0, O_RDONLY, "/vmunix")!=0)
402      {
403        msyslog(LOG_ERR, "K_open failed");
404        exit(3);
405      }
406    kusenlist(1);
407    if (knlist(nl) != 0)
408      {
409        msyslog(LOG_ERR, "knlist failed");
410        exit(3);
411      }
412#   else  /* } not HAVE_K_OPEN { */
413#    ifdef HAVE_KVM_OPEN /* { */
414    if ((kd = kvm_open(NULL, NULL, NULL, O_RDONLY, NULL)) == NULL)
415      {
416        msyslog(LOG_ERR, "kvm_open failed");
417        exit(3);
418      }
419    if (kvm_nlist(kd, nl) == -1)
420      {
421        msyslog(LOG_ERR, "kvm_nlist failed");
422        exit(3);
423      }
424#    else /* } not HAVE_KVM_OPEN { */
425#     ifdef HAVE_GETBOOTFILE
426    kernelname = getbootfile();
427    if (!kernelname)
428      {
429        msyslog(LOG_ERR, "getbootfile() didn't find kernel name!");
430        exit(3);
431      }
432    else if (stat(kernelname, &stbuf) == -1)
433      {
434        msyslog(LOG_ERR, "stat(%s) failed: %m", kernelname);
435        exit(3);
436      }
437    else if (nlist(kernelname, nl) < 0)
438      {
439        msyslog(LOG_ERR, "nlist(%s) failed: %m", kernelname);
440        exit(3);
441      } 
442#     else /* not HAVE_GETBOOTFILE */
443    for (i = 0; kernelnames[i] != NULL; i++)
444      {
445        if (stat(kernelnames[i], &stbuf) == -1)
446          continue;
447        if (nlist(kernelnames[i], nl) >= 0)
448          break;
449      }
450    if (kernelnames[i] == NULL)
451      {
452        msyslog(LOG_ERR, "Clock init couldn't find kernel object file");
453      }
454#     endif /* not HAVE_GETBOOTFILE */
455    kmem = open("/dev/kmem", O_RDONLY);
456    if (kmem < 0)
457      {
458        msyslog(LOG_ERR, "Can't open /dev/kmem for reading: %m");
459#ifdef  DEBUG
460        if (debug)
461          perror("/dev/kmem");
462#endif
463      }
464#    endif /* } not HAVE_KVM_OPEN */
465#   endif /* } not HAVE_K_OPEN */
466#  endif /* not NOKMEM */
467  }
468# endif /* not SYS_WINNT */
469
470  /* Skippy says we need to know TICK before handling TICKADJ */
471  if (got_tick != 1)
472  {
473# if defined(HAVE_SYS_TIMEX_H) && defined(HAVE___ADJTIMEX)
474    struct timex txc;
475# endif /* HAVE_SYS_TIMEX_H && HAVE___ADJTIMEX */
476
477# if !defined(NOKMEM) && defined(N_TICK)
478#  ifdef HAVE_K_OPEN
479    if (K_read(ptick, sizeof(*ptick), nl[N_TICK].n_value) != sizeof(*ptick))
480      {
481        msyslog(LOG_ERR, "K_read tick failed");
482      }
483    else
484      {
485        if (*ptick) ++got_tick;
486      }
487#  else /* not HAVE_K_OPEN */
488#   ifdef HAVE_KVM_OPEN
489    if (kvm_read(kd, nl[N_TICK].n_value, (char *)ptick, sizeof(*ptick)) !=
490        sizeof(*ptick))
491      {
492        msyslog(LOG_ERR, "kvm_read tick failed");
493      }
494    else
495      {
496        if (*ptick) ++got_tick;
497      }
498#   else /* not HAVE_KVM_OPEN */
499    if ((where = nl[N_TICK].n_value) == 0)
500      {
501        msyslog(LOG_ERR, "Unknown kernel var <%s>",
502               nl[N_TICK].N_NAME);
503      }
504    else
505      {
506        if (lseek(kmem, where, SEEK_SET) == -1)
507          {
508            msyslog(LOG_ERR, "lseek for %s fails: %m",
509                   nl[N_TICK].N_NAME);
510          }
511        else
512          {
513            if (read(kmem, ptick, sizeof(*ptick)) != sizeof(*ptick))
514              {
515                msyslog(LOG_ERR, "read for %s fails: %m",
516                       nl[N_TICK].N_NAME);
517              }
518            else
519              {
520#    ifdef NLIST_EXTRA_INDIRECTION
521                /*
522                 * Aix requires one more round of indirection
523                 * if storage class a pointer.
524                 */
525                if ( nl[N_TICK].n_sclass == 0x6b)
526                  {
527                    if (lseek(kmem, *ptick, SEEK_SET) == -1)
528                      {
529                        msyslog(LOG_ERR, "lseek2 for %s fails: %m",
530                               nl[N_TICK].N_NAME);
531                      }
532                    else
533                      {
534                        if (read(kmem, ptick, sizeof(*ptick)) !=
535                            sizeof(*ptick))
536                          {
537                            msyslog(LOG_ERR, "read2 for %s fails: %m",
538                                   nl[N_TICK].N_NAME);
539                          }
540                        else
541                          {
542                            if (*ptick) ++got_tick;
543                          }
544                      }
545                  }
546#    else /* not NLIST_EXTRA_INDIRECTION */
547                if (*ptick) ++got_tick;
548#    endif /* not NLIST_EXTRA_INDIRECTION */
549              }
550          }
551      }
552#   endif /* not HAVE_KVM_OPEN */
553#  endif /* not HAVE_K_OPEN */
554#  ifdef TICK_NANO
555    if (got_tick)
556      {
557        *ptick /= 1000;
558      }
559#  endif /* TICK_NANO */
560# endif /* not NOKMEM && N_TICK */
561
562    if (!got_tick && default_tick)
563      {
564        *ptick = default_tick;
565        if (*ptick) ++got_tick;
566      }
567
568# ifdef PRESET_TICK
569    if (!got_tick)
570      {
571#  if defined(HAVE_SYS_TIMEX_H) && defined(HAVE___ADJTIMEX)
572#   ifdef MOD_OFFSET
573        txc.modes = 0;
574#   else
575        txc.mode = 0;
576#   endif
577        __adjtimex(&txc);
578#  endif /* HAVE_SYS_TIMEX_H && HAVE___ADJTIMEX */
579        *ptick = (u_long) PRESET_TICK;
580        if (*ptick) ++got_tick;
581      }
582# endif  /* PRESET_TICK */
583
584    if (got_tick != 1)
585      {
586        msyslog(LOG_ERR, "Problem getting tick: %d != 1", got_tick);
587        exit(3);
588      }
589
590    tick = *ptick;              /* This might be used by PRESET_TICKADJ */
591  }
592
593  /* Skippy says we need to know TICK before handling TICKADJ */
594  if (got_tickadj != 1)
595  {
596# if !defined(NOKMEM) && defined(N_TICKADJ)
597    if (nl[N_TICKADJ].n_value == 0)
598      {
599        msyslog(LOG_ERR, "Unknown kernel variable <%s>",
600               nl[N_TICKADJ].N_NAME);
601      }
602    else
603      {
604#  ifdef HAVE_K_OPEN
605        if (K_read(ptickadj, sizeof(*ptickadj), nl[N_TICKADJ].n_value) !=
606            sizeof(*ptickadj))
607          {
608            msyslog(LOG_ERR, "K_read tickadj failed");
609          }
610        else
611          {
612            if (*ptickadj) ++got_tickadj;
613          }
614#  else /* not HAVE_K_OPEN */
615#   ifdef HAVE_KVM_OPEN
616        if (kvm_read(kd, nl[N_TICKADJ].n_value, (char *)ptickadj, sizeof(*ptickadj)) !=
617            sizeof(*ptickadj))
618          {
619            msyslog(LOG_ERR, "kvm_read tickadj failed");
620          }
621        else
622          {
623            if (*ptickadj) ++got_tickadj;
624          }
625#   else /* not HAVE_KVM_OPEN */
626        if ((where = nl[N_TICKADJ].n_value) == 0)
627          {
628            msyslog(LOG_ERR, "Unknown kernel var <%s>",
629                   nl[N_TICKADJ].N_NAME);
630          }
631        else
632          {
633            if (lseek(kmem, where, SEEK_SET) == -1)
634              {
635                msyslog(LOG_ERR, "lseek for %s fails: %m",
636                       nl[N_TICKADJ].N_NAME);
637              }
638            else
639              {
640                if (read(kmem, ptickadj, sizeof(*ptickadj)) !=
641                    sizeof(*ptickadj))
642                  {
643                    msyslog(LOG_ERR, "read for %s fails: %m",
644                           nl[N_TICKADJ].N_NAME);
645                  }
646                else
647                  {
648#    ifdef NLIST_EXTRA_INDIRECTION
649                    /*
650                     * Aix requires one more round of indirection
651                     * if storage class a pointer.
652                     */
653                    if ( nl[N_TICKADJ].n_sclass == 0x6b)
654                      {
655                        if (lseek(kmem, *ptickadj, SEEK_SET) == -1)
656                          {
657                            msyslog(LOG_ERR, "lseek2 for %s fails: %m",
658                                   nl[N_TICKADJ].N_NAME);
659                          }
660                        else
661                          {
662                            if (read(kmem, ptickadj, sizeof(*ptickadj)) !=
663                                sizeof(*ptickadj))
664                              {
665                                msyslog(LOG_ERR, "read2 for %s fails: %m",
666                                       nl[N_TICKADJ].N_NAME);
667                              }
668                            else
669                              {
670                                if (*ptickadj) ++got_tickadj;
671                              }
672                          }
673                      }
674#    else /* not NLIST_EXTRA_INDIRECTION */
675                    if (*ptickadj) ++got_tickadj;
676#    endif /* not NLIST_EXTRA_INDIRECTION */
677                  }
678              }
679          }
680#   endif /* not HAVE_KVM_OPEN */
681#  endif /* not HAVE_K_OPEN */
682      }
683
684#  ifdef TICKADJ_NANO
685    if (got_tickadj)
686      {
687        *ptickadj /= 1000;
688        if  (*ptickadj == 0)
689          {
690            *ptickadj = 1;
691          }
692      }
693#  endif /* TICKADJ_NANO */
694#  ifdef SCO5_TICKADJ
695    if (got_tickadj)
696      {
697        *ptickadj /= (1000 * hz);
698      }
699#  else /* not SCO5_TICKADJ */
700#   ifdef SCO3_TICKADJ
701    if (got_tickadj)
702      {
703        *ptickadj *= (10000 / hz);
704      }
705#   endif /* SCO3_TICKADJ */
706#  endif/* not SCO5_TICKADJ */
707# endif /* not NOKMEM && N_TICKADJ */
708
709    if (!got_tickadj && default_tickadj)
710      {
711        *ptickadj = default_tickadj;
712        if (*ptickadj) ++got_tickadj;
713      }
714
715# ifdef PRESET_TICKADJ
716    if (!got_tickadj)
717      {
718        *ptickadj = (u_long) ((PRESET_TICKADJ) ? PRESET_TICKADJ : 1);
719        if (*ptickadj) ++got_tickadj;
720      }
721# endif /* PRESET_TICKADJ */
722
723    if (got_tickadj != 1)
724      {
725        msyslog(LOG_ERR, "Problem getting tickadj: %d != 1", got_tickadj);
726        exit(3);
727      }
728  }
729
730# ifndef NOKMEM
731#  ifdef HAVE_K_OPEN
732  (void) K_close();
733#  else /* not HAVE_K_OPEN */
734#   ifdef HAVE_KVM_OPEN
735  if (kvm_close(kd) < 0)
736    {
737      msyslog(LOG_ERR, "kvm_close failed");
738      exit(3);
739    }
740#   else /* not HAVE_KVM_OPEN */
741  close(kmem);
742#   endif /* not HAVE_KVM_OPEN */
743#  endif /* not HAVE_K_OPEN */
744# endif /* not NOKMEM */
745
746# ifdef DEBUG
747  if (debug)
748    printf("tick = %ld, tickadj = %ld, hz = %d\n", *ptick, *ptickadj, hz);
749# endif
750}
751#endif /* not VMS */
Note: See TracBrowser for help on using the repository browser.