PageRenderTime 27ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 0ms

/contrib/ntp/util/tickadj.c

https://github.com/okuoku/freebsd-head
C | 902 lines | 773 code | 94 blank | 35 comment | 142 complexity | ee5f48cb18a7be54e1fcf1c57b01eb6a MD5 | raw file
  1. /*
  2. * tickadj - read, and possibly modify, the kernel `tick' and
  3. * `tickadj' variables, as well as `dosynctodr'. Note that
  4. * this operates on the running kernel only. I'd like to be
  5. * able to read and write the binary as well, but haven't
  6. * mastered this yet.
  7. *
  8. * HMS: The #includes here are different from those in xntpd/ntp_unixclock.c
  9. * These seem "worse".
  10. */
  11. #ifdef HAVE_CONFIG_H
  12. # include <config.h>
  13. #endif
  14. #include "ntp_types.h"
  15. #include "l_stdlib.h"
  16. #include <stdio.h>
  17. #ifdef HAVE_UNISTD_H
  18. # include <unistd.h>
  19. #endif /* HAVE_UNISTD_H */
  20. #ifdef HAVE___ADJTIMEX /* Linux */
  21. #include <sys/timex.h>
  22. struct timex txc;
  23. #if 0
  24. int
  25. main(
  26. int argc,
  27. char *argv[]
  28. )
  29. {
  30. int c, i;
  31. int quiet = 0;
  32. int errflg = 0;
  33. char *progname;
  34. extern int ntp_optind;
  35. extern char *ntp_optarg;
  36. progname = argv[0];
  37. if (argc==2 && argv[1][0] != '-') { /* old Linux format, for compatability */
  38. if ((i = atoi(argv[1])) > 0) {
  39. txc.time_tick = i;
  40. txc.modes = ADJ_TIMETICK;
  41. } else {
  42. fprintf(stderr, "Silly value for tick: %s\n", argv[1]);
  43. errflg++;
  44. }
  45. } else {
  46. while ((c = ntp_getopt(argc, argv, "a:qt:")) != EOF) {
  47. switch (c) {
  48. case 'a':
  49. if ((i=atoi(ntp_optarg)) > 0) {
  50. txc.tickadj = i;
  51. txc.modes |= ADJ_TICKADJ;
  52. } else {
  53. (void) fprintf(stderr,
  54. "%s: unlikely value for tickadj: %s\n",
  55. progname, ntp_optarg);
  56. errflg++;
  57. }
  58. break;
  59. case 'q':
  60. quiet = 1;
  61. break;
  62. case 't':
  63. if ((i=atoi(ntp_optarg)) > 0) {
  64. txc.time_tick = i;
  65. txc.modes |= ADJ_TIMETICK;
  66. } else {
  67. (void) fprintf(stderr,
  68. "%s: unlikely value for tick: %s\n",
  69. progname, ntp_optarg);
  70. errflg++;
  71. }
  72. break;
  73. default:
  74. fprintf(stderr,
  75. "Usage: %s [tick_value]\n-or- %s [ -q ] [ -t tick ] [ -a tickadj ]\n",
  76. progname, progname);
  77. errflg++;
  78. break;
  79. }
  80. }
  81. }
  82. if (!errflg) {
  83. if (__adjtimex(&txc) < 0)
  84. perror("adjtimex");
  85. else if (!quiet)
  86. printf("tick = %ld\ntick_adj = %d\n",
  87. txc.time_tick, txc.tickadj);
  88. }
  89. exit(errflg ? 1 : 0);
  90. }
  91. #else
  92. int
  93. main(
  94. int argc,
  95. char *argv[]
  96. )
  97. {
  98. if (argc > 2)
  99. {
  100. fprintf(stderr, "Usage: %s [tick_value]\n", argv[0]);
  101. exit(-1);
  102. }
  103. else if (argc == 2)
  104. {
  105. #ifdef ADJ_TIMETICK
  106. if ( (txc.time_tick = atoi(argv[1])) < 1 )
  107. #else
  108. if ( (txc.tick = atoi(argv[1])) < 1 )
  109. #endif
  110. {
  111. fprintf(stderr, "Silly value for tick: %s\n", argv[1]);
  112. exit(-1);
  113. }
  114. #ifdef ADJ_TIMETICK
  115. txc.modes = ADJ_TIMETICK;
  116. #else
  117. #ifdef MOD_OFFSET
  118. txc.modes = ADJ_TICK;
  119. #else
  120. txc.mode = ADJ_TICK;
  121. #endif
  122. #endif
  123. }
  124. else
  125. {
  126. #ifdef ADJ_TIMETICK
  127. txc.modes = 0;
  128. #else
  129. #ifdef MOD_OFFSET
  130. txc.modes = 0;
  131. #else
  132. txc.mode = 0;
  133. #endif
  134. #endif
  135. }
  136. if (__adjtimex(&txc) < 0)
  137. {
  138. perror("adjtimex");
  139. }
  140. else
  141. {
  142. #ifdef ADJ_TIMETICK
  143. printf("tick = %ld\ntick_adj = %ld\n", txc.time_tick, txc.tickadj);
  144. #else
  145. printf("tick = %ld\n", txc.tick);
  146. #endif
  147. }
  148. exit(0);
  149. }
  150. #endif
  151. #else /* not Linux... kmem tweaking: */
  152. #ifdef HAVE_SYS_FILE_H
  153. # include <sys/file.h>
  154. #endif
  155. #include <sys/stat.h>
  156. #ifdef HAVE_SYS_PARAM_H
  157. # include <sys/param.h>
  158. #endif
  159. #ifdef NLIST_STRUCT
  160. # include <nlist.h>
  161. #else /* not NLIST_STRUCT */ /* was defined(SYS_AUX3) || defined(SYS_AUX2) */
  162. # include <sys/resource.h>
  163. # include <sys/file.h>
  164. # include <a.out.h>
  165. # include <sys/var.h>
  166. #endif
  167. #include "ntp_io.h"
  168. #include "ntp_stdlib.h"
  169. #ifdef hz /* Was: RS6000 */
  170. # undef hz
  171. #endif /* hz */
  172. #ifdef HAVE_KVM_OPEN
  173. # include <kvm.h>
  174. #endif
  175. #ifdef SYS_VXWORKS
  176. /* vxWorks needs mode flag -casey*/
  177. #define open(name, flags) open(name, flags, 0777)
  178. #endif
  179. #ifndef L_SET /* Was: defined(SYS_PTX) || defined(SYS_IX86OSF1) */
  180. # define L_SET SEEK_SET
  181. #endif
  182. #ifndef HZ
  183. # define HZ DEFAULT_HZ
  184. #endif
  185. #define KMEM "/dev/kmem"
  186. #define STREQ(a, b) (*(a) == *(b) && strcmp((a), (b)) == 0)
  187. char *progname;
  188. volatile int debug;
  189. int dokmem = 1;
  190. int writetickadj = 0;
  191. int writeopttickadj = 0;
  192. int unsetdosync = 0;
  193. int writetick = 0;
  194. int quiet = 0;
  195. int setnoprintf = 0;
  196. const char *kmem = KMEM;
  197. const char *file = NULL;
  198. int fd = -1;
  199. static void getoffsets P((off_t *, off_t *, off_t *, off_t *));
  200. static int openfile P((const char *, int));
  201. static void writevar P((int, off_t, int));
  202. static void readvar P((int, off_t, int *));
  203. /*
  204. * main - parse arguments and handle options
  205. */
  206. int
  207. main(
  208. int argc,
  209. char *argv[]
  210. )
  211. {
  212. int c;
  213. int errflg = 0;
  214. off_t tickadj_offset;
  215. off_t tick_offset;
  216. off_t dosync_offset;
  217. off_t noprintf_offset;
  218. int tickadj, ktickadj; /* HMS: Why isn't this u_long? */
  219. int tick, ktick; /* HMS: Why isn't this u_long? */
  220. int dosynctodr;
  221. int noprintf;
  222. int hz;
  223. int hz_int, hz_hundredths;
  224. int recommend_tickadj;
  225. long tmp;
  226. progname = argv[0];
  227. while ((c = ntp_getopt(argc, argv, "a:Adkpqst:")) != EOF)
  228. {
  229. switch (c)
  230. {
  231. case 'a':
  232. writetickadj = atoi(ntp_optarg);
  233. if (writetickadj <= 0)
  234. {
  235. (void) fprintf(stderr,
  236. "%s: unlikely value for tickadj: %s\n",
  237. progname, ntp_optarg);
  238. errflg++;
  239. }
  240. #if defined SCO5_CLOCK
  241. if (writetickadj % HZ)
  242. {
  243. writetickadj = (writetickadj / HZ) * HZ;
  244. (void) fprintf(stderr,
  245. "tickadj truncated to: %d\n", writetickadj);
  246. }
  247. #endif /* SCO5_CLOCK */
  248. break;
  249. case 'A':
  250. writeopttickadj = 1;
  251. break;
  252. case 'd':
  253. ++debug;
  254. break;
  255. case 'k':
  256. dokmem = 1;
  257. break;
  258. case 'p':
  259. setnoprintf = 1;
  260. break;
  261. case 'q':
  262. quiet = 1;
  263. break;
  264. case 's':
  265. unsetdosync = 1;
  266. break;
  267. case 't':
  268. writetick = atoi(ntp_optarg);
  269. if (writetick <= 0)
  270. {
  271. (void) fprintf(stderr,
  272. "%s: unlikely value for tick: %s\n",
  273. progname, ntp_optarg);
  274. errflg++;
  275. }
  276. break;
  277. default:
  278. errflg++;
  279. break;
  280. }
  281. }
  282. if (errflg || ntp_optind != argc)
  283. {
  284. (void) fprintf(stderr,
  285. "usage: %s [-Adkpqs] [-a newadj] [-t newtick]\n", progname);
  286. exit(2);
  287. }
  288. getoffsets(&tick_offset, &tickadj_offset, &dosync_offset, &noprintf_offset);
  289. if (debug)
  290. {
  291. (void) printf("tick offset = %lu\n", (unsigned long)tick_offset);
  292. (void) printf("tickadj offset = %lu\n", (unsigned long)tickadj_offset);
  293. (void) printf("dosynctodr offset = %lu\n", (unsigned long)dosync_offset);
  294. (void) printf("noprintf offset = %lu\n", (unsigned long)noprintf_offset);
  295. }
  296. if (writetick && (tick_offset == 0))
  297. {
  298. (void) fprintf(stderr,
  299. "No tick kernel variable\n");
  300. errflg++;
  301. }
  302. if (writeopttickadj && (tickadj_offset == 0))
  303. {
  304. (void) fprintf(stderr,
  305. "No tickadj kernel variable\n");
  306. errflg++;
  307. }
  308. if (unsetdosync && (dosync_offset == 0))
  309. {
  310. (void) fprintf(stderr,
  311. "No dosynctodr kernel variable\n");
  312. errflg++;
  313. }
  314. if (setnoprintf && (noprintf_offset == 0))
  315. {
  316. (void) fprintf(stderr,
  317. "No noprintf kernel variable\n");
  318. errflg++;
  319. }
  320. if (tick_offset != 0)
  321. {
  322. readvar(fd, tick_offset, &tick);
  323. #if defined(TICK_NANO) && defined(K_TICK_NAME)
  324. if (!quiet)
  325. (void) printf("KERNEL %s = %d nsec\n", K_TICK_NAME, tick);
  326. #endif /* TICK_NANO && K_TICK_NAME */
  327. #ifdef TICK_NANO
  328. tick /= 1000;
  329. #endif
  330. }
  331. else
  332. {
  333. tick = 0;
  334. }
  335. if (tickadj_offset != 0)
  336. {
  337. readvar(fd, tickadj_offset, &tickadj);
  338. #ifdef SCO5_CLOCK
  339. /* scale from nsec/sec to usec/tick */
  340. tickadj /= (1000L * HZ);
  341. #endif /*SCO5_CLOCK */
  342. #if defined(TICKADJ_NANO) && defined(K_TICKADJ_NAME)
  343. if (!quiet)
  344. (void) printf("KERNEL %s = %d nsec\n", K_TICKADJ_NAME, tickadj);
  345. #endif /* TICKADJ_NANO && K_TICKADJ_NAME */
  346. #ifdef TICKADJ_NANO
  347. tickadj += 999;
  348. tickadj /= 1000;
  349. #endif
  350. }
  351. else
  352. {
  353. tickadj = 0;
  354. }
  355. if (dosync_offset != 0)
  356. {
  357. readvar(fd, dosync_offset, &dosynctodr);
  358. }
  359. if (noprintf_offset != 0)
  360. {
  361. readvar(fd, noprintf_offset, &noprintf);
  362. }
  363. (void) close(fd);
  364. if (unsetdosync && dosync_offset == 0)
  365. {
  366. (void) fprintf(stderr,
  367. "%s: can't find %s in namelist\n",
  368. progname,
  369. #ifdef K_DOSYNCTODR_NAME
  370. K_DOSYNCTODR_NAME
  371. #else /* not K_DOSYNCTODR_NAME */
  372. "dosynctodr"
  373. #endif /* not K_DOSYNCTODR_NAME */
  374. );
  375. exit(1);
  376. }
  377. hz = HZ;
  378. #if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
  379. hz = (int) sysconf (_SC_CLK_TCK);
  380. #endif /* not HAVE_SYSCONF && _SC_CLK_TCK */
  381. #ifdef OVERRIDE_HZ
  382. hz = DEFAULT_HZ;
  383. #endif
  384. ktick = tick;
  385. #ifdef PRESET_TICK
  386. tick = PRESET_TICK;
  387. #endif /* PRESET_TICK */
  388. #ifdef TICKADJ_NANO
  389. tickadj /= 1000;
  390. if (tickadj == 0)
  391. tickadj = 1;
  392. #endif
  393. ktickadj = tickadj;
  394. #ifdef PRESET_TICKADJ
  395. tickadj = (PRESET_TICKADJ) ? PRESET_TICKADJ : 1;
  396. #endif /* PRESET_TICKADJ */
  397. if (!quiet)
  398. {
  399. if (tick_offset != 0)
  400. {
  401. (void) printf("KERNEL tick = %d usec (from %s kernel variable)\n",
  402. ktick,
  403. #ifdef K_TICK_NAME
  404. K_TICK_NAME
  405. #else
  406. "<this can't happen>"
  407. #endif
  408. );
  409. }
  410. #ifdef PRESET_TICK
  411. (void) printf("PRESET tick = %d usec\n", tick);
  412. #endif /* PRESET_TICK */
  413. if (tickadj_offset != 0)
  414. {
  415. (void) printf("KERNEL tickadj = %d usec (from %s kernel variable)\n",
  416. ktickadj,
  417. #ifdef K_TICKADJ_NAME
  418. K_TICKADJ_NAME
  419. #else
  420. "<this can't happen>"
  421. #endif
  422. );
  423. }
  424. #ifdef PRESET_TICKADJ
  425. (void) printf("PRESET tickadj = %d usec\n", tickadj);
  426. #endif /* PRESET_TICKADJ */
  427. if (dosync_offset != 0)
  428. {
  429. (void) printf("dosynctodr is %s\n", dosynctodr ? "on" : "off");
  430. }
  431. if (noprintf_offset != 0)
  432. {
  433. (void) printf("kernel level printf's: %s\n",
  434. noprintf ? "off" : "on");
  435. }
  436. }
  437. if (tick <= 0)
  438. {
  439. (void) fprintf(stderr, "%s: the value of tick is silly!\n",
  440. progname);
  441. exit(1);
  442. }
  443. hz_int = (int)(1000000L / (long)tick);
  444. hz_hundredths = (int)((100000000L / (long)tick) - ((long)hz_int * 100L));
  445. if (!quiet)
  446. {
  447. (void) printf("KERNEL hz = %d\n", hz);
  448. (void) printf("calculated hz = %d.%02d Hz\n", hz_int,
  449. hz_hundredths);
  450. }
  451. #if defined SCO5_CLOCK
  452. recommend_tickadj = 100;
  453. #else /* SCO5_CLOCK */
  454. tmp = (long) tick * 500L;
  455. recommend_tickadj = (int)(tmp / 1000000L);
  456. if (tmp % 1000000L > 0)
  457. {
  458. recommend_tickadj++;
  459. }
  460. #ifdef MIN_REC_TICKADJ
  461. if (recommend_tickadj < MIN_REC_TICKADJ)
  462. {
  463. recommend_tickadj = MIN_REC_TICKADJ;
  464. }
  465. #endif /* MIN_REC_TICKADJ */
  466. #endif /* SCO5_CLOCK */
  467. if ((!quiet) && (tickadj_offset != 0))
  468. {
  469. (void) printf("recommended value of tickadj = %d us\n",
  470. recommend_tickadj);
  471. }
  472. if ( writetickadj == 0
  473. && !writeopttickadj
  474. && !unsetdosync
  475. && writetick == 0
  476. && !setnoprintf)
  477. {
  478. exit(errflg ? 1 : 0);
  479. }
  480. if (writetickadj == 0 && writeopttickadj)
  481. {
  482. writetickadj = recommend_tickadj;
  483. }
  484. fd = openfile(file, O_WRONLY);
  485. if (setnoprintf && (noprintf_offset != 0))
  486. {
  487. if (!quiet)
  488. {
  489. (void) fprintf(stderr, "setting noprintf: ");
  490. (void) fflush(stderr);
  491. }
  492. writevar(fd, noprintf_offset, 1);
  493. if (!quiet)
  494. {
  495. (void) fprintf(stderr, "done!\n");
  496. }
  497. }
  498. if ((writetick > 0) && (tick_offset != 0))
  499. {
  500. if (!quiet)
  501. {
  502. (void) fprintf(stderr, "writing tick, value %d: ",
  503. writetick);
  504. (void) fflush(stderr);
  505. }
  506. writevar(fd, tick_offset, writetick);
  507. if (!quiet)
  508. {
  509. (void) fprintf(stderr, "done!\n");
  510. }
  511. }
  512. if ((writetickadj > 0) && (tickadj_offset != 0))
  513. {
  514. if (!quiet)
  515. {
  516. (void) fprintf(stderr, "writing tickadj, value %d: ",
  517. writetickadj);
  518. (void) fflush(stderr);
  519. }
  520. #ifdef SCO5_CLOCK
  521. /* scale from usec/tick to nsec/sec */
  522. writetickadj *= (1000L * HZ);
  523. #endif /* SCO5_CLOCK */
  524. writevar(fd, tickadj_offset, writetickadj);
  525. if (!quiet)
  526. {
  527. (void) fprintf(stderr, "done!\n");
  528. }
  529. }
  530. if (unsetdosync && (dosync_offset != 0))
  531. {
  532. if (!quiet)
  533. {
  534. (void) fprintf(stderr, "zeroing dosynctodr: ");
  535. (void) fflush(stderr);
  536. }
  537. writevar(fd, dosync_offset, 0);
  538. if (!quiet)
  539. {
  540. (void) fprintf(stderr, "done!\n");
  541. }
  542. }
  543. (void) close(fd);
  544. return(errflg ? 1 : 0);
  545. }
  546. /*
  547. * getoffsets - read the magic offsets from the specified file
  548. */
  549. static void
  550. getoffsets(
  551. off_t *tick_off,
  552. off_t *tickadj_off,
  553. off_t *dosync_off,
  554. off_t *noprintf_off
  555. )
  556. {
  557. #ifndef NOKMEM
  558. # ifndef HAVE_KVM_OPEN
  559. const char **kname;
  560. # endif
  561. #endif
  562. #ifndef NOKMEM
  563. # ifdef NLIST_NAME_UNION
  564. # define NL_B {{
  565. # define NL_E }}
  566. # else
  567. # define NL_B {
  568. # define NL_E }
  569. # endif
  570. #endif
  571. #define K_FILLER_NAME "DavidLetterman"
  572. #ifdef NLIST_EXTRA_INDIRECTION
  573. int i;
  574. #endif
  575. #ifndef NOKMEM
  576. static struct nlist nl[] =
  577. {
  578. NL_B
  579. #ifdef K_TICKADJ_NAME
  580. #define N_TICKADJ 0
  581. K_TICKADJ_NAME
  582. #else
  583. K_FILLER_NAME
  584. #endif
  585. NL_E,
  586. NL_B
  587. #ifdef K_TICK_NAME
  588. #define N_TICK 1
  589. K_TICK_NAME
  590. #else
  591. K_FILLER_NAME
  592. #endif
  593. NL_E,
  594. NL_B
  595. #ifdef K_DOSYNCTODR_NAME
  596. #define N_DOSYNC 2
  597. K_DOSYNCTODR_NAME
  598. #else
  599. K_FILLER_NAME
  600. #endif
  601. NL_E,
  602. NL_B
  603. #ifdef K_NOPRINTF_NAME
  604. #define N_NOPRINTF 3
  605. K_NOPRINTF_NAME
  606. #else
  607. K_FILLER_NAME
  608. #endif
  609. NL_E,
  610. NL_B "" NL_E,
  611. };
  612. #ifndef HAVE_KVM_OPEN
  613. static const char *kernels[] =
  614. {
  615. #ifdef HAVE_GETBOOTFILE
  616. NULL, /* *** SEE BELOW! *** */
  617. #endif
  618. "/kernel/unix",
  619. "/kernel",
  620. "/vmunix",
  621. "/unix",
  622. "/mach",
  623. "/hp-ux",
  624. "/386bsd",
  625. "/netbsd",
  626. "/stand/vmunix",
  627. "/bsd",
  628. NULL
  629. };
  630. #endif /* not HAVE_KVM_OPEN */
  631. #ifdef HAVE_KVM_OPEN
  632. /*
  633. * Solaris > 2.5 doesn't have a kernel file. Use the kvm_* interface
  634. * to read the kernel name list. -- stolcke 3/4/96
  635. */
  636. kvm_t *kvm_handle = kvm_open(NULL, NULL, NULL, O_RDONLY, progname);
  637. if (kvm_handle == NULL)
  638. {
  639. (void) fprintf(stderr,
  640. "%s: kvm_open failed\n",
  641. progname);
  642. exit(1);
  643. }
  644. if (kvm_nlist(kvm_handle, nl) == -1)
  645. {
  646. (void) fprintf(stderr,
  647. "%s: kvm_nlist failed\n",
  648. progname);
  649. exit(1);
  650. }
  651. kvm_close(kvm_handle);
  652. #else /* not HAVE_KVM_OPEN */
  653. #ifdef HAVE_GETBOOTFILE /* *** SEE HERE! *** */
  654. if (kernels[0] == NULL)
  655. {
  656. char * cp = (char *)getbootfile();
  657. if (cp)
  658. {
  659. kernels[0] = cp;
  660. }
  661. else
  662. {
  663. kernels[0] = "/Placeholder";
  664. }
  665. }
  666. #endif /* HAVE_GETBOOTFILE */
  667. for (kname = kernels; *kname != NULL; kname++)
  668. {
  669. struct stat stbuf;
  670. if (stat(*kname, &stbuf) == -1)
  671. {
  672. continue;
  673. }
  674. if (nlist(*kname, nl) >= 0)
  675. {
  676. break;
  677. }
  678. else
  679. {
  680. (void) fprintf(stderr,
  681. "%s: nlist didn't find needed symbols from <%s>: %s\n",
  682. progname, *kname, strerror(errno));
  683. }
  684. }
  685. if (*kname == NULL)
  686. {
  687. (void) fprintf(stderr,
  688. "%s: Couldn't find the kernel\n",
  689. progname);
  690. exit(1);
  691. }
  692. #endif /* HAVE_KVM_OPEN */
  693. if (dokmem)
  694. {
  695. file = kmem;
  696. fd = openfile(file, O_RDONLY);
  697. #ifdef NLIST_EXTRA_INDIRECTION
  698. /*
  699. * Go one more round of indirection.
  700. */
  701. for (i = 0; i < (sizeof(nl) / sizeof(struct nlist)); i++)
  702. {
  703. if ((nl[i].n_value) && (nl[i].n_sclass == 0x6b))
  704. {
  705. readvar(fd, nl[i].n_value, &nl[i].n_value);
  706. }
  707. }
  708. #endif /* NLIST_EXTRA_INDIRECTION */
  709. }
  710. #endif /* not NOKMEM */
  711. *tickadj_off = 0;
  712. *tick_off = 0;
  713. *dosync_off = 0;
  714. *noprintf_off = 0;
  715. #if defined(N_TICKADJ)
  716. *tickadj_off = nl[N_TICKADJ].n_value;
  717. #endif
  718. #if defined(N_TICK)
  719. *tick_off = nl[N_TICK].n_value;
  720. #endif
  721. #if defined(N_DOSYNC)
  722. *dosync_off = nl[N_DOSYNC].n_value;
  723. #endif
  724. #if defined(N_NOPRINTF)
  725. *noprintf_off = nl[N_NOPRINTF].n_value;
  726. #endif
  727. return;
  728. }
  729. #undef N_TICKADJ
  730. #undef N_TICK
  731. #undef N_DOSYNC
  732. #undef N_NOPRINTF
  733. /*
  734. * openfile - open the file, check for errors
  735. */
  736. static int
  737. openfile(
  738. const char *name,
  739. int mode
  740. )
  741. {
  742. int ifd;
  743. ifd = open(name, mode);
  744. if (ifd < 0)
  745. {
  746. (void) fprintf(stderr, "%s: open %s: ", progname, name);
  747. perror("");
  748. exit(1);
  749. }
  750. return ifd;
  751. }
  752. /*
  753. * writevar - write a variable into the file
  754. */
  755. static void
  756. writevar(
  757. int ofd,
  758. off_t off,
  759. int var
  760. )
  761. {
  762. if (lseek(ofd, off, L_SET) == -1)
  763. {
  764. (void) fprintf(stderr, "%s: lseek fails: ", progname);
  765. perror("");
  766. exit(1);
  767. }
  768. if (write(ofd, (char *)&var, sizeof(int)) != sizeof(int))
  769. {
  770. (void) fprintf(stderr, "%s: write fails: ", progname);
  771. perror("");
  772. exit(1);
  773. }
  774. return;
  775. }
  776. /*
  777. * readvar - read a variable from the file
  778. */
  779. static void
  780. readvar(
  781. int ifd,
  782. off_t off,
  783. int *var
  784. )
  785. {
  786. int i;
  787. if (lseek(ifd, off, L_SET) == -1)
  788. {
  789. (void) fprintf(stderr, "%s: lseek fails: ", progname);
  790. perror("");
  791. exit(1);
  792. }
  793. i = read(ifd, (char *)var, sizeof(int));
  794. if (i < 0)
  795. {
  796. (void) fprintf(stderr, "%s: read fails: ", progname);
  797. perror("");
  798. exit(1);
  799. }
  800. if (i != sizeof(int))
  801. {
  802. (void) fprintf(stderr, "%s: read expected %d, got %d\n",
  803. progname, (int)sizeof(int), i);
  804. exit(1);
  805. }
  806. return;
  807. }
  808. #endif /* not Linux */