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