📄 ckutio.c
字号:
* count, which may then be read. It has the side-effect of flushing * input on the terminal. *//* * John Mackin, Physiology Dept., University of Sydney (Australia) * ...!decvax!mulga!physiol.su.oz!john * * Permission is hereby granted to do anything with this code, as * long as this comment is retained unmodified and no commercial * advantage is gained. */#ifndef MINIX#include <a.out.h>#include <sys/proc.h>#endifchar *initrawq(tty) int tty; {#ifdef MINIX return(0);#else#ifdef UTS24 return(0);#else#ifdef BSD29 return(0);#else long lseek(); static struct nlist nl[] = { {PROCNAME}, {NPROCNAME}, {""} }; static struct proc *pp; char *malloc(), *qaddr, *p, c; int m, pid, me; NPTYPE xproc; /* Its type is defined in makefile. */ int catch(); me = getpid(); if ((m = open("/dev/kmem", 0)) < 0) err("kmem"); nlist(BOOTNAME, nl); if (nl[0].n_type == 0) err("proc array"); if (nl[1].n_type == 0) err("nproc"); lseek(m, (long)(nl[1].n_value), 0); read (m, &xproc, sizeof(xproc)); signal(SIGALRM, catch); if ((pid = fork()) == 0) { while(1) read(tty, &c, 1); } alarm(2); if(setjmp(jjbuf) == 0) { while(1) read(tty, &c, 1); } signal(SIGALRM, SIG_DFL);#ifdef DIRECT pp = (struct proc *) nl[0].n_value;#else if (lseek(m, (long)(nl[0].n_value), 0) < 0L) err("seek"); if (read(m, &pp, sizeof(pp)) != sizeof(pp)) err("no read of proc ptr");#endif lseek(m, (long)(nl[1].n_value), 0); read(m, &xproc, sizeof(xproc)); if (lseek(m, (long)pp, 0) < 0L) err("Can't seek to proc"); if ((p = malloc(xproc * sizeof(struct proc))) == NULL) err("malloc"); if (read(m,p,xproc * sizeof(struct proc)) != xproc*sizeof(struct proc)) err("read proc table"); for (pp = (struct proc *)p; xproc > 0; --xproc, ++pp) { if (pp -> p_pid == (short) pid) goto iout; } err("no such proc"); iout: close(m); qaddr = (char *)(pp -> p_wchan); free (p); kill(pid, SIGKILL); wait((int *)0); /* Destroy the ZOMBIEs! */ return (qaddr);#endif#endif#endif}/* More V7-support functions... */staticerr(s) char *s; { char buf[200]; sprintf(buf, "fatal error in initrawq: %s", s); perror(buf); doexit(1);}staticcatch() { longjmp(jjbuf, -1);}/* G E N B R K -- Simulate a modem break. */#ifndef MINIX#define BSPEED B150genbrk(fn) int fn; { struct sgttyb ttbuf; int ret, sospeed; ret = ioctl(fn, TIOCGETP, &ttbuf); sospeed = ttbuf.sg_ospeed; ttbuf.sg_ospeed = BSPEED; ret = ioctl(fn, TIOCSETP, &ttbuf); ret = write(fn, "\0\0\0\0\0\0\0\0\0\0\0\0", 8); ttbuf.sg_ospeed = sospeed; ret = ioctl(fn, TIOCSETP, &ttbuf); ret = write(fn, "@", 1); return;}#endif#endif/* T T C H K -- Tell how many characters are waiting in tty input buffer */ttchk() { int x; long n;#ifdef FIONREAD x = ioctl(ttyfd, FIONREAD, &n); /* Berkeley and maybe some others */ debug(F101,"ttchk","",n); return((x < 0) ? 0 : n);#else#ifdef V7#ifdef MINIX return(0);#else lseek(kmem[TTY], (long) qaddr[TTY], 0); /* 7th Edition Unix */ x = read(kmem[TTY], &n, sizeof(int)); return((x == sizeof(int))? n: 0);#endif#else#ifdef UXIII return(inbufc + (ungotn >= 0) ); /* Sys III, Sys V */#else#ifdef PROVX1 x = ioctl(ttyfd, TIOCQCNT, &ttbuf); /* Pro/3xx Venix V.1 */ n = ttbuf.sg_ispeed & 0377; return((x < 0) ? 0 : n);#else#ifdef aegis return(inbufc + (ungotn >= 0) ); /* Apollo Aegis */#else#ifdef C70 return(inbufc + (ungotn >= 0) ); /* etc... */#else return(0);#endif#endif#endif#endif#endif#endif}/* T T X I N -- Get n characters from tty input buffer *//* Returns number of characters actually gotten, or -1 on failure *//* Intended for use only when it is known that n characters are actually *//* Available in the input buffer. */ttxin(n,buf) int n; char *buf; { int x;#ifdef MYREAD for( x = 0; (x > -1) && (x < n); buf[x++] = myread() );#else debug(F101,"ttxin: n","",n); x = read(ttyfd,buf,n); debug(F101," x","",x);#endif if (x > 0) buf[x] = '\0'; if (x < 0) x = -1; return(x);}/* T T O L -- Similar to "ttinl", but for writing. */ttol(s,n) int n; char *s; { int x; if (ttyfd < 0) return(-1); /* Not open. */ x = write(ttyfd,s,n); debug(F111,"ttol",s,n); if (x < 0) debug(F101,"ttol failed","",x); return(x);}/* T T O C -- Output a character to the communication line */ttoc(c) char c; { if (ttyfd < 0) return(-1); /* Not open. */ return(write(ttyfd,&c,1));}/* T T I N L -- Read a record (up to break character) from comm line. *//* If no break character encountered within "max", return "max" characters, with disposition of any remaining characters undefined. Otherwise, return the characters that were read, including the break character, in "dest" and the number of characters read as the value of the function, or 0 upon end of file, or -1 if an error occurred. Times out & returns error if not completed within "timo" seconds.*/#define CTRLC '\03'ttinl(dest,max,timo,eol) int max,timo; CHAR *dest, eol; { int x = 0, ccn = 0, c, i, j, m, n; /* local variables */ if (ttyfd < 0) return(-1); /* Not open. */ m = (ttprty) ? 0177 : 0377; /* Parity stripping mask. */ *dest = '\0'; /* Clear destination buffer */ if (timo) signal(SIGALRM,timerh); /* Enable timer interrupt */ alarm(timo); /* Set it. */ if (setjmp(sjbuf)) { /* Timer went off? */ x = -1; } else { i = 0; /* Next char to process */ j = 0; /* Buffer position */ while (1) { if ((n = ttchk()) > 0) { /* See how many chars have arrived */ if (n > (max - j)) n = max - j; if ((n = ttxin(n,dest+i)) < 0) { /* Get them all at once */ x = -1; break; } } else { /* Or else... */ n = 1; /* just wait for a char */ if ((c = ttinc(0)) == -1) { x = -1; break; } dest[i] = c; /* Got one. */ } j = i + n; /* Remember next buffer position. */ if (j >= max) { debug(F101,"ttinl buffer overflow","",j); x = -1; break; } for (i; i < j; i++) { /* Go thru all chars we just got */ dest[i] &= m; /* Strip any parity */ if (dest[i] == eol) { /* Got eol? */ dest[++i] = '\0'; /* Yes, tie off string, */ alarm(0); /* turn off timers, etc, */ if (timo) signal(SIGALRM,SIG_DFL); /* and return length. */ return(i); } else if ((dest[i] & 0177) == CTRLC) { /* Check for ^C^C */ if (++ccn > 1) { /* If we got 2 in a row, clean up */ alarm(0); /* and exit. */ signal(SIGALRM,SIG_DFL); fprintf(stderr,"^C..."); ttres(); fprintf(stderr,"\n"); return(-2); } } else ccn = 0; /* Not ^C, so reset ^C counter, */ } } } debug(F100,"ttinl timout","",0); /* Get here on timeout. */ debug(F111," with",dest,i); alarm(0); /* Turn off timer */ signal(SIGALRM,SIG_DFL); /* and interrupt, */ return(x); /* and return error code. */}/* T T I N C -- Read a character from the communication line */ttinc(timo) int timo; { int m, n = 0; CHAR ch = 0; m = (ttprty) ? 0177 : 0377; /* Parity stripping mask. */ if (ttyfd < 0) return(-1); /* Not open. */ if (timo <= 0) { /* Untimed. */#ifdef MYREAD /* comm line failure returns -1 thru myread, so no &= 0377 */ while ((n = myread()) == -1) ; /* Wait for a character... */ if (n == -2) n++; return( (n < 0) ? -1 : n & m );#else while ((n = read(ttyfd,&ch,1)) == 0) ; /* Wait for a character. */ return( (n < 0) ? -1 : (ch & 0377) );#endif } signal(SIGALRM,timerh); /* Timed, set up timer. */ alarm(timo); if (setjmp(sjbuf)) { n = -1; } else {#ifdef MYREAD while ((n = myread()) == -1) ; /* If managing own buffer... */ if (n == -2) { n++; } else { ch = n; n = 1; }#else n = read(ttyfd,&ch,1); /* Otherwise call the system. */#endif } alarm(0); /* Turn off timer, */ signal(SIGALRM,SIG_DFL); /* and interrupt. */ return( (n < 0) ? -1 : (ch & m) ); /* Return char or -1. */}/* T T S N D B -- Send a BREAK signal */ttsndb() { int x; long n; char spd; if (ttyfd < 0) return(-1); /* Not open. */#ifdef PROVX1 gtty(ttyfd,&ttbuf); /* Get current tty flags */ spd = ttbuf.sg_ospeed; /* Save speed */ ttbuf.sg_ospeed = B50; /* Change to 50 baud */ stty(ttyfd,&ttbuf); /* ... */ write(ttyfd,brnuls,3); /* Send 3 nulls */ ttbuf.sg_ospeed = spd; /* Restore speed */ stty(ttyfd,&ttbuf); /* ... */ return(0);#else#ifdef aegis sio_$control((short)ttyfd, sio_$send_break, 250, st); return(0);#else#ifdef UXIII if (ioctl(ttyfd,TCSBRK,(char *)0) < 0) { /* Send a BREAK */ perror("Can't send BREAK"); return(-1); } return(0);#else#ifdef ANYBSD n = FWRITE; /* Flush output queue. */ ioctl(ttyfd,TIOCFLUSH,&n); /* Ignore any errors.. */ if (ioctl(ttyfd,TIOCSBRK,(char *)0) < 0) { /* Turn on BREAK */ perror("Can't send BREAK"); return(-1); } x = msleep(275); /* Sleep for so many milliseconds */ if (ioctl(ttyfd,TIOCCBRK,(char *)0) < 0) { /* Turn off BREAK */ perror("BREAK stuck!!!"); doexit(1); /* Get out, closing the line. */ /* with exit status = 1 */ } return(x);#else#ifdef MINIX tcsendbreak(ttyfd, 0);#else#ifdef V7 genbrk(ttyfd); /* Simulate a BREAK */ return(x);#endif#endif#endif#endif#endif#endif}/* M S L E E P -- Millisecond version of sleep(). *//* Intended only for small intervals. For big ones, just use sleep().*/msleep(m) int m; {#ifdef aegis time_$clock_t dur; dur.c2.high16 = 0; dur.c2.low32 = 250 * m; /* one millisecond = 250 four microsecond ticks */ time_$wait(time_$relative, dur, st); return(0);#else #ifdef PROVX1 if (m <= 0) return(0); sleep(-((m * 60 + 500) / 1000)); return(0);#endif#ifdef ANYBSD int t1, t3, t4; if (m <= 0) return(0);#ifndef BSD42/* 2.9 and 4.1 BSD do it this way */ if (ftime(&ftp) < 0) return(-1); /* Get current time. */ t1 = ((ftp.time & 0xff) * 1000) + ftp.millitm; while (1) { ftime(&ftp); /* new time */ t3 = (((ftp.time & 0xff) * 1000) + ftp.millitm) - t1; if (t3 > m) return(t3); }#else/* 4.2 & above can do it with select()... */ if (gettimeofday(&tv, &tz) < 0) return(-1); /* Get current time. */ t1 = tv.tv_sec; /* Seconds */ tv.tv_sec = 0; /* Use select() */ tv.tv_usec = m * 1000; return(select( 0, (int *)0, (int *)0, (int *)0, &tv) );#endif#endif/* The clock-tick business is a pain. Wm. E. Davidsen suggested: *//* #include <sys/param.h> *//* #define CLOCK_TICK 1000/HZ *//* But I don't see the symbol HZ in this file on my VAX. *//* Maybe just for XENIX. */#ifdef UXIII#ifdef XENIX/* Actually, watch out. It's 50 on the AT, 20 on older PCs... */#define CLOCK_TICK 50 /* millisecs per clock tick */#else#ifndef XENIX#define CLOCK_TICK 17 /* 1/60 sec */#endif#endif extern long times(); long t1, t2, tarray[4]; int t3;/* In SCO Xenix 2.1.3 or later, you can use nap((long)m) to do this. */ if (m <= 0) return(0); if ((t1 = times(tarray)) < 0) return(-1); while (1) { if ((t2 = times(tarray)) < 0) return(-1); t3 = ((int)(t2 - t1)) * CLOCK_TICK; if (t3 > m) return(t3); }#endif#ifdef TOWER1 int t1, t3; if (m <= 0) return(0); if (ftime(&ftp) < 0) return(-1); /* Get current time. */ t1 = ((ftp.time & 0xff) * 1000) + ftp.millitm; while (1) { ftime(&ftp); /* new time */ t3 = (((ftp.time & 0xff) * 1000) + ftp.millitm) - t1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -