1226031Sstas/* 2226031Sstas * tickadj - read, and possibly modify, the kernel `tick' and 3226031Sstas * `tickadj' variables, as well as `dosynctodr'. Note that 4226031Sstas * this operates on the running kernel only. I'd like to be 5226031Sstas * able to read and write the binary as well, but haven't 6226031Sstas * mastered this yet. 7226031Sstas * 8226031Sstas * HMS: The #includes here are different from those in xntpd/ntp_unixclock.c 9226031Sstas * These seem "worse". 10226031Sstas */ 11226031Sstas 12226031Sstas#ifdef HAVE_CONFIG_H 13226031Sstas# include <config.h> 14226031Sstas#endif 15226031Sstas 16226031Sstas#include "ntp_types.h" 17226031Sstas#include "l_stdlib.h" 18226031Sstas 19226031Sstas#include <stdio.h> 20226031Sstas#ifdef HAVE_UNISTD_H 21226031Sstas# include <unistd.h> 22226031Sstas#endif /* HAVE_UNISTD_H */ 23226031Sstas 24226031Sstas#ifdef HAVE___ADJTIMEX /* Linux */ 25226031Sstas 26226031Sstas#include <sys/timex.h> 27226031Sstasstruct timex txc; 28226031Sstas 29226031Sstas#if 0 30226031Sstasint 31226031Sstasmain( 32226031Sstas int argc, 33226031Sstas char *argv[] 34226031Sstas ) 35226031Sstas{ 36226031Sstas int c, i; 37226031Sstas int quiet = 0; 38226031Sstas int errflg = 0; 39226031Sstas char *progname; 40226031Sstas extern int ntp_optind; 41226031Sstas extern char *ntp_optarg; 42226031Sstas 43226031Sstas progname = argv[0]; 44226031Sstas if (argc==2 && argv[1][0] != '-') { /* old Linux format, for compatability */ 45226031Sstas if ((i = atoi(argv[1])) > 0) { 46226031Sstas txc.time_tick = i; 47226031Sstas txc.modes = ADJ_TIMETICK; 48226031Sstas } else { 49226031Sstas fprintf(stderr, "Silly value for tick: %s\n", argv[1]); 50226031Sstas errflg++; 51226031Sstas } 52226031Sstas } else { 53226031Sstas while ((c = ntp_getopt(argc, argv, "a:qt:")) != EOF) { 54226031Sstas switch (c) { 55226031Sstas case 'a': 56226031Sstas if ((i=atoi(ntp_optarg)) > 0) { 57226031Sstas txc.tickadj = i; 58226031Sstas txc.modes |= ADJ_TICKADJ; 59226031Sstas } else { 60226031Sstas (void) fprintf(stderr, 61226031Sstas "%s: unlikely value for tickadj: %s\n", 62226031Sstas progname, ntp_optarg); 63226031Sstas errflg++; 64226031Sstas } 65226031Sstas break; 66226031Sstas 67226031Sstas case 'q': 68226031Sstas quiet = 1; 69226031Sstas break; 70226031Sstas 71226031Sstas case 't': 72226031Sstas if ((i=atoi(ntp_optarg)) > 0) { 73226031Sstas txc.time_tick = i; 74226031Sstas txc.modes |= ADJ_TIMETICK; 75226031Sstas } else { 76226031Sstas (void) fprintf(stderr, 77226031Sstas "%s: unlikely value for tick: %s\n", 78226031Sstas progname, ntp_optarg); 79226031Sstas errflg++; 80226031Sstas } 81226031Sstas break; 82226031Sstas 83226031Sstas default: 84226031Sstas fprintf(stderr, 85226031Sstas "Usage: %s [tick_value]\n-or- %s [ -q ] [ -t tick ] [ -a tickadj ]\n", 86226031Sstas progname, progname); 87226031Sstas errflg++; 88226031Sstas break; 89226031Sstas } 90226031Sstas } 91226031Sstas } 92226031Sstas 93226031Sstas if (!errflg) { 94226031Sstas if (__adjtimex(&txc) < 0) 95226031Sstas perror("adjtimex"); 96226031Sstas else if (!quiet) 97226031Sstas printf("tick = %ld\ntick_adj = %d\n", 98226031Sstas txc.time_tick, txc.tickadj); 99226031Sstas } 100226031Sstas 101226031Sstas exit(errflg ? 1 : 0); 102226031Sstas} 103226031Sstas#else 104226031Sstasint 105226031Sstasmain( 106226031Sstas int argc, 107226031Sstas char *argv[] 108226031Sstas ) 109226031Sstas{ 110226031Sstas if (argc > 2) 111226031Sstas { 112226031Sstas fprintf(stderr, "Usage: %s [tick_value]\n", argv[0]); 113226031Sstas exit(-1); 114226031Sstas } 115226031Sstas else if (argc == 2) 116226031Sstas { 117226031Sstas#ifdef ADJ_TIMETICK 118226031Sstas if ( (txc.time_tick = atoi(argv[1])) < 1 ) 119226031Sstas#else 120226031Sstas if ( (txc.tick = atoi(argv[1])) < 1 ) 121226031Sstas#endif 122226031Sstas { 123226031Sstas fprintf(stderr, "Silly value for tick: %s\n", argv[1]); 124226031Sstas exit(-1); 125226031Sstas } 126226031Sstas#ifdef ADJ_TIMETICK 127226031Sstas txc.modes = ADJ_TIMETICK; 128226031Sstas#else 129226031Sstas#ifdef MOD_OFFSET 130226031Sstas txc.modes = ADJ_TICK; 131226031Sstas#else 132226031Sstas txc.mode = ADJ_TICK; 133226031Sstas#endif 134226128Sstas#endif 135226031Sstas } 136226031Sstas else 137226031Sstas { 138226031Sstas#ifdef ADJ_TIMETICK 139226031Sstas txc.modes = 0; 140226031Sstas#else 141226031Sstas#ifdef MOD_OFFSET 142226031Sstas txc.modes = 0; 143226031Sstas#else 144226031Sstas txc.mode = 0; 145226031Sstas#endif 146226031Sstas#endif 147226031Sstas } 148226031Sstas 149226031Sstas if (__adjtimex(&txc) < 0) 150226031Sstas { 151226031Sstas perror("adjtimex"); 152226031Sstas } 153226031Sstas else 154226031Sstas { 155226031Sstas#ifdef ADJ_TIMETICK 156226031Sstas printf("tick = %ld\ntick_adj = %ld\n", txc.time_tick, txc.tickadj); 157226031Sstas#else 158226031Sstas printf("tick = %ld\n", txc.tick); 159226031Sstas#endif 160226031Sstas } 161226031Sstas 162226031Sstas exit(0); 163226031Sstas} 164226031Sstas#endif 165226031Sstas 166226031Sstas#else /* not Linux... kmem tweaking: */ 167226031Sstas 168226031Sstas#ifdef HAVE_SYS_FILE_H 169226031Sstas# include <sys/file.h> 170226031Sstas#endif 171226031Sstas#include <sys/stat.h> 172226031Sstas 173226031Sstas#ifdef HAVE_SYS_PARAM_H 174226031Sstas# include <sys/param.h> 175226031Sstas#endif 176226031Sstas 177226031Sstas#ifdef NLIST_STRUCT 178226031Sstas# include <nlist.h> 179226031Sstas#else /* not NLIST_STRUCT */ /* was defined(SYS_AUX3) || defined(SYS_AUX2) */ 180226031Sstas# include <sys/resource.h> 181226031Sstas# include <sys/file.h> 182226031Sstas# include <a.out.h> 183226031Sstas# include <sys/var.h> 184226031Sstas#endif 185226031Sstas 186226031Sstas#include "ntp_io.h" 187226031Sstas#include "ntp_stdlib.h" 188226031Sstas 189#ifdef hz /* Was: RS6000 */ 190# undef hz 191#endif /* hz */ 192 193#ifdef HAVE_KVM_OPEN 194# include <kvm.h> 195#endif 196 197#ifdef SYS_VXWORKS 198/* vxWorks needs mode flag -casey*/ 199#define open(name, flags) open(name, flags, 0777) 200#endif 201 202#ifndef L_SET /* Was: defined(SYS_PTX) || defined(SYS_IX86OSF1) */ 203# define L_SET SEEK_SET 204#endif 205 206#ifndef HZ 207# define HZ DEFAULT_HZ 208#endif 209 210#define KMEM "/dev/kmem" 211#define STREQ(a, b) (*(a) == *(b) && strcmp((a), (b)) == 0) 212 213char *progname; 214volatile int debug; 215 216int dokmem = 1; 217int writetickadj = 0; 218int writeopttickadj = 0; 219int unsetdosync = 0; 220int writetick = 0; 221int quiet = 0; 222int setnoprintf = 0; 223 224const char *kmem = KMEM; 225const char *file = NULL; 226int fd = -1; 227 228static void getoffsets P((off_t *, off_t *, off_t *, off_t *)); 229static int openfile P((const char *, int)); 230static void writevar P((int, off_t, int)); 231static void readvar P((int, off_t, int *)); 232 233/* 234 * main - parse arguments and handle options 235 */ 236int 237main( 238 int argc, 239 char *argv[] 240 ) 241{ 242 int c; 243 int errflg = 0; 244 off_t tickadj_offset; 245 off_t tick_offset; 246 off_t dosync_offset; 247 off_t noprintf_offset; 248 int tickadj, ktickadj; /* HMS: Why isn't this u_long? */ 249 int tick, ktick; /* HMS: Why isn't this u_long? */ 250 int dosynctodr; 251 int noprintf; 252 int hz; 253 int hz_int, hz_hundredths; 254 int recommend_tickadj; 255 long tmp; 256 257 progname = argv[0]; 258 while ((c = ntp_getopt(argc, argv, "a:Adkpqst:")) != EOF) 259 { 260 switch (c) 261 { 262 case 'a': 263 writetickadj = atoi(ntp_optarg); 264 if (writetickadj <= 0) 265 { 266 (void) fprintf(stderr, 267 "%s: unlikely value for tickadj: %s\n", 268 progname, ntp_optarg); 269 errflg++; 270 } 271 272#if defined SCO5_CLOCK 273 if (writetickadj % HZ) 274 { 275 writetickadj = (writetickadj / HZ) * HZ; 276 (void) fprintf(stderr, 277 "tickadj truncated to: %d\n", writetickadj); 278 } 279#endif /* SCO5_CLOCK */ 280 281 break; 282 case 'A': 283 writeopttickadj = 1; 284 break; 285 case 'd': 286 ++debug; 287 break; 288 case 'k': 289 dokmem = 1; 290 break; 291 case 'p': 292 setnoprintf = 1; 293 break; 294 case 'q': 295 quiet = 1; 296 break; 297 case 's': 298 unsetdosync = 1; 299 break; 300 case 't': 301 writetick = atoi(ntp_optarg); 302 if (writetick <= 0) 303 { 304 (void) fprintf(stderr, 305 "%s: unlikely value for tick: %s\n", 306 progname, ntp_optarg); 307 errflg++; 308 } 309 break; 310 default: 311 errflg++; 312 break; 313 } 314 } 315 if (errflg || ntp_optind != argc) 316 { 317 (void) fprintf(stderr, 318 "usage: %s [-Adkpqs] [-a newadj] [-t newtick]\n", progname); 319 exit(2); 320 } 321 322 getoffsets(&tick_offset, &tickadj_offset, &dosync_offset, &noprintf_offset); 323 324 if (debug) 325 { 326 (void) printf("tick offset = %lu\n", (unsigned long)tick_offset); 327 (void) printf("tickadj offset = %lu\n", (unsigned long)tickadj_offset); 328 (void) printf("dosynctodr offset = %lu\n", (unsigned long)dosync_offset); 329 (void) printf("noprintf offset = %lu\n", (unsigned long)noprintf_offset); 330 } 331 332 if (writetick && (tick_offset == 0)) 333 { 334 (void) fprintf(stderr, 335 "No tick kernel variable\n"); 336 errflg++; 337 } 338 339 if (writeopttickadj && (tickadj_offset == 0)) 340 { 341 (void) fprintf(stderr, 342 "No tickadj kernel variable\n"); 343 errflg++; 344 } 345 346 if (unsetdosync && (dosync_offset == 0)) 347 { 348 (void) fprintf(stderr, 349 "No dosynctodr kernel variable\n"); 350 errflg++; 351 } 352 353 if (setnoprintf && (noprintf_offset == 0)) 354 { 355 (void) fprintf(stderr, 356 "No noprintf kernel variable\n"); 357 errflg++; 358 } 359 360 if (tick_offset != 0) 361 { 362 readvar(fd, tick_offset, &tick); 363#if defined(TICK_NANO) && defined(K_TICK_NAME) 364 if (!quiet) 365 (void) printf("KERNEL %s = %d nsec\n", K_TICK_NAME, tick); 366#endif /* TICK_NANO && K_TICK_NAME */ 367 368#ifdef TICK_NANO 369 tick /= 1000; 370#endif 371 } 372 else 373 { 374 tick = 0; 375 } 376 377 if (tickadj_offset != 0) 378 { 379 readvar(fd, tickadj_offset, &tickadj); 380 381#ifdef SCO5_CLOCK 382 /* scale from nsec/sec to usec/tick */ 383 tickadj /= (1000L * HZ); 384#endif /*SCO5_CLOCK */ 385 386#if defined(TICKADJ_NANO) && defined(K_TICKADJ_NAME) 387 if (!quiet) 388 (void) printf("KERNEL %s = %d nsec\n", K_TICKADJ_NAME, tickadj); 389#endif /* TICKADJ_NANO && K_TICKADJ_NAME */ 390 391#ifdef TICKADJ_NANO 392 tickadj += 999; 393 tickadj /= 1000; 394#endif 395 } 396 else 397 { 398 tickadj = 0; 399 } 400 401 if (dosync_offset != 0) 402 { 403 readvar(fd, dosync_offset, &dosynctodr); 404 } 405 406 if (noprintf_offset != 0) 407 { 408 readvar(fd, noprintf_offset, &noprintf); 409 } 410 411 (void) close(fd); 412 413 if (unsetdosync && dosync_offset == 0) 414 { 415 (void) fprintf(stderr, 416 "%s: can't find %s in namelist\n", 417 progname, 418#ifdef K_DOSYNCTODR_NAME 419 K_DOSYNCTODR_NAME 420#else /* not K_DOSYNCTODR_NAME */ 421 "dosynctodr" 422#endif /* not K_DOSYNCTODR_NAME */ 423 ); 424 exit(1); 425 } 426 427 hz = HZ; 428#if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK) 429 hz = (int) sysconf (_SC_CLK_TCK); 430#endif /* not HAVE_SYSCONF && _SC_CLK_TCK */ 431#ifdef OVERRIDE_HZ 432 hz = DEFAULT_HZ; 433#endif 434 ktick = tick; 435#ifdef PRESET_TICK 436 tick = PRESET_TICK; 437#endif /* PRESET_TICK */ 438#ifdef TICKADJ_NANO 439 tickadj /= 1000; 440 if (tickadj == 0) 441 tickadj = 1; 442#endif 443 ktickadj = tickadj; 444#ifdef PRESET_TICKADJ 445 tickadj = (PRESET_TICKADJ) ? PRESET_TICKADJ : 1; 446#endif /* PRESET_TICKADJ */ 447 448 if (!quiet) 449 { 450 if (tick_offset != 0) 451 { 452 (void) printf("KERNEL tick = %d usec (from %s kernel variable)\n", 453 ktick, 454#ifdef K_TICK_NAME 455 K_TICK_NAME 456#else 457 "<this can't happen>" 458#endif 459 ); 460 } 461#ifdef PRESET_TICK 462 (void) printf("PRESET tick = %d usec\n", tick); 463#endif /* PRESET_TICK */ 464 if (tickadj_offset != 0) 465 { 466 (void) printf("KERNEL tickadj = %d usec (from %s kernel variable)\n", 467 ktickadj, 468#ifdef K_TICKADJ_NAME 469 K_TICKADJ_NAME 470#else 471 "<this can't happen>" 472#endif 473 ); 474 } 475#ifdef PRESET_TICKADJ 476 (void) printf("PRESET tickadj = %d usec\n", tickadj); 477#endif /* PRESET_TICKADJ */ 478 if (dosync_offset != 0) 479 { 480 (void) printf("dosynctodr is %s\n", dosynctodr ? "on" : "off"); 481 } 482 if (noprintf_offset != 0) 483 { 484 (void) printf("kernel level printf's: %s\n", 485 noprintf ? "off" : "on"); 486 } 487 } 488 489 if (tick <= 0) 490 { 491 (void) fprintf(stderr, "%s: the value of tick is silly!\n", 492 progname); 493 exit(1); 494 } 495 496 hz_int = (int)(1000000L / (long)tick); 497 hz_hundredths = (int)((100000000L / (long)tick) - ((long)hz_int * 100L)); 498 if (!quiet) 499 { 500 (void) printf("KERNEL hz = %d\n", hz); 501 (void) printf("calculated hz = %d.%02d Hz\n", hz_int, 502 hz_hundredths); 503 } 504 505#if defined SCO5_CLOCK 506 recommend_tickadj = 100; 507#else /* SCO5_CLOCK */ 508 tmp = (long) tick * 500L; 509 recommend_tickadj = (int)(tmp / 1000000L); 510 if (tmp % 1000000L > 0) 511 { 512 recommend_tickadj++; 513 } 514 515#ifdef MIN_REC_TICKADJ 516 if (recommend_tickadj < MIN_REC_TICKADJ) 517 { 518 recommend_tickadj = MIN_REC_TICKADJ; 519 } 520#endif /* MIN_REC_TICKADJ */ 521#endif /* SCO5_CLOCK */ 522 523 524 if ((!quiet) && (tickadj_offset != 0)) 525 { 526 (void) printf("recommended value of tickadj = %d us\n", 527 recommend_tickadj); 528 } 529 530 if ( writetickadj == 0 531 && !writeopttickadj 532 && !unsetdosync 533 && writetick == 0 534 && !setnoprintf) 535 { 536 exit(errflg ? 1 : 0); 537 } 538 539 if (writetickadj == 0 && writeopttickadj) 540 { 541 writetickadj = recommend_tickadj; 542 } 543 544 fd = openfile(file, O_WRONLY); 545 546 if (setnoprintf && (noprintf_offset != 0)) 547 { 548 if (!quiet) 549 { 550 (void) fprintf(stderr, "setting noprintf: "); 551 (void) fflush(stderr); 552 } 553 writevar(fd, noprintf_offset, 1); 554 if (!quiet) 555 { 556 (void) fprintf(stderr, "done!\n"); 557 } 558 } 559 560 if ((writetick > 0) && (tick_offset != 0)) 561 { 562 if (!quiet) 563 { 564 (void) fprintf(stderr, "writing tick, value %d: ", 565 writetick); 566 (void) fflush(stderr); 567 } 568 writevar(fd, tick_offset, writetick); 569 if (!quiet) 570 { 571 (void) fprintf(stderr, "done!\n"); 572 } 573 } 574 575 if ((writetickadj > 0) && (tickadj_offset != 0)) 576 { 577 if (!quiet) 578 { 579 (void) fprintf(stderr, "writing tickadj, value %d: ", 580 writetickadj); 581 (void) fflush(stderr); 582 } 583 584#ifdef SCO5_CLOCK 585 /* scale from usec/tick to nsec/sec */ 586 writetickadj *= (1000L * HZ); 587#endif /* SCO5_CLOCK */ 588 589 writevar(fd, tickadj_offset, writetickadj); 590 if (!quiet) 591 { 592 (void) fprintf(stderr, "done!\n"); 593 } 594 } 595 596 if (unsetdosync && (dosync_offset != 0)) 597 { 598 if (!quiet) 599 { 600 (void) fprintf(stderr, "zeroing dosynctodr: "); 601 (void) fflush(stderr); 602 } 603 writevar(fd, dosync_offset, 0); 604 if (!quiet) 605 { 606 (void) fprintf(stderr, "done!\n"); 607 } 608 } 609 (void) close(fd); 610 return(errflg ? 1 : 0); 611} 612 613/* 614 * getoffsets - read the magic offsets from the specified file 615 */ 616static void 617getoffsets( 618 off_t *tick_off, 619 off_t *tickadj_off, 620 off_t *dosync_off, 621 off_t *noprintf_off 622 ) 623{ 624 625#ifndef NOKMEM 626# ifndef HAVE_KVM_OPEN 627 const char **kname; 628# endif 629#endif 630 631#ifndef NOKMEM 632# ifdef NLIST_NAME_UNION 633# define NL_B {{ 634# define NL_E }} 635# else 636# define NL_B { 637# define NL_E } 638# endif 639#endif 640 641#define K_FILLER_NAME "DavidLetterman" 642 643#ifdef NLIST_EXTRA_INDIRECTION 644 int i; 645#endif 646 647#ifndef NOKMEM 648 static struct nlist nl[] = 649 { 650 NL_B 651#ifdef K_TICKADJ_NAME 652#define N_TICKADJ 0 653 K_TICKADJ_NAME 654#else 655 K_FILLER_NAME 656#endif 657 NL_E, 658 NL_B 659#ifdef K_TICK_NAME 660#define N_TICK 1 661 K_TICK_NAME 662#else 663 K_FILLER_NAME 664#endif 665 NL_E, 666 NL_B 667#ifdef K_DOSYNCTODR_NAME 668#define N_DOSYNC 2 669 K_DOSYNCTODR_NAME 670#else 671 K_FILLER_NAME 672#endif 673 NL_E, 674 NL_B 675#ifdef K_NOPRINTF_NAME 676#define N_NOPRINTF 3 677 K_NOPRINTF_NAME 678#else 679 K_FILLER_NAME 680#endif 681 NL_E, 682 NL_B "" NL_E, 683 }; 684 685#ifndef HAVE_KVM_OPEN 686 static const char *kernels[] = 687 { 688#ifdef HAVE_GETBOOTFILE 689 NULL, /* *** SEE BELOW! *** */ 690#endif 691 "/kernel/unix", 692 "/kernel", 693 "/vmunix", 694 "/unix", 695 "/mach", 696 "/hp-ux", 697 "/386bsd", 698 "/netbsd", 699 "/stand/vmunix", 700 "/bsd", 701 NULL 702 }; 703#endif /* not HAVE_KVM_OPEN */ 704 705#ifdef HAVE_KVM_OPEN 706 /* 707 * Solaris > 2.5 doesn't have a kernel file. Use the kvm_* interface 708 * to read the kernel name list. -- stolcke 3/4/96 709 */ 710 kvm_t *kvm_handle = kvm_open(NULL, NULL, NULL, O_RDONLY, progname); 711 712 if (kvm_handle == NULL) 713 { 714 (void) fprintf(stderr, 715 "%s: kvm_open failed\n", 716 progname); 717 exit(1); 718 } 719 if (kvm_nlist(kvm_handle, nl) == -1) 720 { 721 (void) fprintf(stderr, 722 "%s: kvm_nlist failed\n", 723 progname); 724 exit(1); 725 } 726 kvm_close(kvm_handle); 727#else /* not HAVE_KVM_OPEN */ 728#ifdef HAVE_GETBOOTFILE /* *** SEE HERE! *** */ 729 if (kernels[0] == NULL) 730 { 731 char * cp = (char *)getbootfile(); 732 733 if (cp) 734 { 735 kernels[0] = cp; 736 } 737 else 738 { 739 kernels[0] = "/Placeholder"; 740 } 741 } 742#endif /* HAVE_GETBOOTFILE */ 743 for (kname = kernels; *kname != NULL; kname++) 744 { 745 struct stat stbuf; 746 747 if (stat(*kname, &stbuf) == -1) 748 { 749 continue; 750 } 751 if (nlist(*kname, nl) >= 0) 752 { 753 break; 754 } 755 else 756 { 757 (void) fprintf(stderr, 758 "%s: nlist didn't find needed symbols from <%s>: %s\n", 759 progname, *kname, strerror(errno)); 760 } 761 } 762 if (*kname == NULL) 763 { 764 (void) fprintf(stderr, 765 "%s: Couldn't find the kernel\n", 766 progname); 767 exit(1); 768 } 769#endif /* HAVE_KVM_OPEN */ 770 771 if (dokmem) 772 { 773 file = kmem; 774 775 fd = openfile(file, O_RDONLY); 776#ifdef NLIST_EXTRA_INDIRECTION 777 /* 778 * Go one more round of indirection. 779 */ 780 for (i = 0; i < (sizeof(nl) / sizeof(struct nlist)); i++) 781 { 782 if ((nl[i].n_value) && (nl[i].n_sclass == 0x6b)) 783 { 784 readvar(fd, nl[i].n_value, &nl[i].n_value); 785 } 786 } 787#endif /* NLIST_EXTRA_INDIRECTION */ 788 } 789#endif /* not NOKMEM */ 790 791 *tickadj_off = 0; 792 *tick_off = 0; 793 *dosync_off = 0; 794 *noprintf_off = 0; 795 796#if defined(N_TICKADJ) 797 *tickadj_off = nl[N_TICKADJ].n_value; 798#endif 799 800#if defined(N_TICK) 801 *tick_off = nl[N_TICK].n_value; 802#endif 803 804#if defined(N_DOSYNC) 805 *dosync_off = nl[N_DOSYNC].n_value; 806#endif 807 808#if defined(N_NOPRINTF) 809 *noprintf_off = nl[N_NOPRINTF].n_value; 810#endif 811 return; 812} 813 814#undef N_TICKADJ 815#undef N_TICK 816#undef N_DOSYNC 817#undef N_NOPRINTF 818 819 820/* 821 * openfile - open the file, check for errors 822 */ 823static int 824openfile( 825 const char *name, 826 int mode 827 ) 828{ 829 int ifd; 830 831 ifd = open(name, mode); 832 if (ifd < 0) 833 { 834 (void) fprintf(stderr, "%s: open %s: ", progname, name); 835 perror(""); 836 exit(1); 837 } 838 return ifd; 839} 840 841 842/* 843 * writevar - write a variable into the file 844 */ 845static void 846writevar( 847 int ofd, 848 off_t off, 849 int var 850 ) 851{ 852 853 if (lseek(ofd, off, L_SET) == -1) 854 { 855 (void) fprintf(stderr, "%s: lseek fails: ", progname); 856 perror(""); 857 exit(1); 858 } 859 if (write(ofd, (char *)&var, sizeof(int)) != sizeof(int)) 860 { 861 (void) fprintf(stderr, "%s: write fails: ", progname); 862 perror(""); 863 exit(1); 864 } 865 return; 866} 867 868 869/* 870 * readvar - read a variable from the file 871 */ 872static void 873readvar( 874 int ifd, 875 off_t off, 876 int *var 877 ) 878{ 879 int i; 880 881 if (lseek(ifd, off, L_SET) == -1) 882 { 883 (void) fprintf(stderr, "%s: lseek fails: ", progname); 884 perror(""); 885 exit(1); 886 } 887 i = read(ifd, (char *)var, sizeof(int)); 888 if (i < 0) 889 { 890 (void) fprintf(stderr, "%s: read fails: ", progname); 891 perror(""); 892 exit(1); 893 } 894 if (i != sizeof(int)) 895 { 896 (void) fprintf(stderr, "%s: read expected %d, got %d\n", 897 progname, (int)sizeof(int), i); 898 exit(1); 899 } 900 return; 901} 902#endif /* not Linux */ 903