1 /* clktest.c,v 3.1 1993/07/06 01:05:23 jbj Exp
2 * clktest - test the clock line discipline
4 * usage: clktest -b bps -f -t timeo -s cmd -c char1 -a char2 /dev/whatever
7 #include "clktest-opts.h"
9 #define STREQ(a, b) (*(a) == *(b) && strcmp((a), (b)) == 0)
11 #if defined(ULT_2_0_SUCKS)
13 #define sigmask(m) (1<<(m))
19 CLOCK_LINE_DISCIPLINE_NEEDED_BY_THIS_PROGRAM;
23 ONLY_ONE_CLOCK_LINE_DISCIPLINE_FOR_THIS_PROGRAM;
28 * Mask for blocking SIGIO and SIGALRM
30 #define BLOCKSIGMASK (sigmask(SIGIO)|sigmask(SIGALRM))
32 #define progname clktestOptions.pzProgName
34 struct timeval timeout = { 0 };
39 u_long magic1 = DEFMAGIC;
40 u_long magic2 = DEFMAGIC;
44 int ttflags = RAW|EVENP|ODDP;
46 volatile int wasalarmed;
49 struct timeval lasttv;
51 extern u_long ustotslo[];
52 extern u_long ustotsmid[];
53 extern u_long ustotshi[];
59 * main - parse arguments and handle options
69 struct itimerval itimer;
76 int ct = optionProcess( &clktestOptions, argc, argv );
77 if (HAVE_OPT(COMMAND) && (strlen(OPT_ARG(COMMAND)) == 0)) {
78 fputs( "The command option string must not be empty\n", stderr );
79 USAGE( EXIT_FAILURE );
82 if ((argc -= ct) != 1) {
83 fputs( "Missing tty device name\n", stderr );
84 USAGE( EXIT_FAILURE );
90 strcpy(magic,DEFMAGIC);
93 fd = open(*argv, HAVE_OPT(TIMEOUT) ? O_RDWR : O_RDONLY, 0777);
95 fprintf(stderr, "%s: open(%s): ", progname, *argv);
100 if (ioctl(fd, TIOCEXCL, (char *)0) < 0) {
101 (void) fprintf(stderr, "%s: ioctl(TIOCEXCL): ", progname);
107 * If we have the clock discipline, set the port to raw. Otherwise
110 ttyb.sg_ispeed = ttyb.sg_ospeed = speed;
112 ttyb.sg_erase = (char)magic1;
113 ttyb.sg_kill = (char)magic2;
115 ttyb.sg_flags = (short)ttflags;
116 if (ioctl(fd, TIOCSETP, (char *)&ttyb) < 0) {
117 (void) fprintf(stderr, "%s: ioctl(TIOCSETP): ", progname);
122 if (fcntl(fd, F_SETOWN, getpid()) == -1) {
123 (void) fprintf(stderr, "%s: fcntl(F_SETOWN): ", progname);
132 if (ioctl(fd, TIOCSETD, (char *)&ldisc) < 0) {
133 (void) fprintf(stderr, "%s: ioctl(TIOCSETD): ", progname);
140 if (ioctl(fd, I_POP, 0) >=0 ) ;
141 if (ioctl(fd, I_PUSH, "clk") < 0) {
142 (void) fprintf(stderr, "%s: ioctl(I_PUSH): ", progname);
146 if (ioctl(fd, CLK_SETSTR, magic) < 0) {
147 (void) fprintf(stderr, "%s: ioctl(CLK_SETSTR): ", progname);
154 (void) gettimeofday(&lasttv, (struct timezone *)0);
155 if (HAVE_OPT(TIMEOUT)) {
157 * set non-blocking, async I/O on the descriptor
160 (void) signal(SIGIO, ioready);
161 if (fcntl(fd, F_SETFL, FNDELAY|FASYNC) < 0) {
162 (void) fprintf(stderr, "%s: fcntl(F_SETFL): ",
169 * Set up the alarm interrupt.
172 (void) signal(SIGALRM, alarming);
173 timeout.tv_sec = OPT_VALUE_TIMEOUT;
174 itimer.it_interval = itimer.it_value = timeout;
175 setitimer(ITIMER_REAL, &itimer, (struct itimerval *)0);
183 * doboth - handle both I/O and alarms via SIGIO
195 struct timeval tvzero;
201 omask = sigblock(BLOCKSIGMASK);
202 if (wasalarmed) { /* alarmed? */
211 if (!sawalarm && !sawiosig) {
213 * Nothing to do. Wait for something.
216 if (wasalarmed) { /* alarmed? */
225 (void)sigsetmask(omask);
230 tvzero.tv_sec = tvzero.tv_usec = 0;
232 n = select(fd+1, &fds, (fd_set *)0,
233 (fd_set *)0, &tvzero);
239 (void) fprintf(stderr, "%s: select: ",
255 * doioonly - do I/O. This avoids the use of signals
268 n = select(fd+1, &fds, (fd_set *)0, (fd_set *)0,
269 (struct timeval *)0);
277 * doio - read a buffer full of stuff and print it out
284 register char *rp, *rpend;
288 struct timeval tv, tvd;
292 static char *digits = "0123456789abcdef";
294 rlen = read(fd, raw, sizeof(raw));
296 (void) fprintf(stderr, "%s: read(): ", progname);
301 (void) printf("Zero length read\n");
316 *cp++ = digits[((*rp)>>4) & 0xf];
317 *cp++ = digits[*rp & 0xf];
322 (*rp == (char)magic1 || *rp == (char)magic2)
324 ( strchr( magic, *rp) != NULL )
330 if ((rpend - rp) < sizeof(struct timeval)) {
332 "Too little data (%d): %s\n",
338 for (i = 0; i < 4; i++) {
340 tv.tv_sec |= ((long)*rp++) & 0xff;
343 for (i = 0; i < 4; i++) {
345 tv.tv_usec |= ((long)*rp++) & 0xff;
348 tvd.tv_sec = tv.tv_sec - lasttv.tv_sec;
349 tvd.tv_usec = tv.tv_usec - lasttv.tv_usec;
350 if (tvd.tv_usec < 0) {
351 tvd.tv_usec += 1000000;
355 (void)printf("%lu.%06lu %lu.%06lu %s\n",
356 tv.tv_sec, tv.tv_usec, tvd.tv_sec, tvd.tv_usec,
366 (void)printf("Incomplete data: %s\n", cooked);
372 * doalarm - send a string out the port, if we have one.
381 if (! HAVE_OPT(COMMAND))
384 n = write(fd, cmd, cmdlen);
387 (void) fprintf(stderr, "%s: write(): ", progname);
389 } else if (n < cmdlen) {
390 (void) printf("Short write (%d bytes, should be %d)\n",
397 * alarming - receive alarm interupt
406 * ioready - handle SIGIO interrupt