📄 ckutio.c
字号:
longjmp(sjbuf,1);
}
/* Set up terminal interrupts on console terminal */
#ifdef UXIII
esctrp() { /* trap console escapes (^\) */
conesc = 1;
signal(SIGQUIT,SIG_IGN); /* ignore until trapped */
}
#endif
#ifdef V7
esctrp() { /* trap console escapes (^\) */
conesc = 1;
signal(SIGQUIT,SIG_IGN); /* ignore until trapped */
}
#endif
#ifdef C70
esctrp() { /* trap console escapes (^\) */
conesc = 1;
signal(SIGQUIT,SIG_IGN); /* ignore until trapped */
}
#endif
/* C O N I N T -- Console Interrupt setter */
conint(f) int (*f)(); { /* Set an interrupt trap. */
if (!isatty(0)) return(0); /* only for real ttys */
if (backgrd) return; /* must ignore signals in bkgrd */
/*
Except for special cases below, ignore keyboard quit signal.
^\ too easily confused with connect escape, and besides, we don't want
to leave lock files around. (Frank Prindle)
*/
signal(SIGQUIT,SIG_IGN);
#ifdef UXIII
signal(SIGQUIT,esctrp); /* console escape in pkt modes */
if (conesc) { /* clear out pending escapes */
conesc = 0;
}
#endif
#ifdef V7
signal(SIGQUIT,esctrp); /* console escape in pkt modes */
if (conesc) { /* clear out pending escapes */
conesc = 0;
}
#endif
if (conif) return; /* Nothing to do if already on. */
/* check if invoked in background -- if so signals set to be ignored */
if (signal(SIGINT,SIG_IGN) == SIG_IGN) {
backgrd = 1; /* means running in background */
#ifdef UXIII
signal(SIGQUIT,SIG_IGN); /* must leave signals ignored */
#endif
#ifdef V7
signal(SIGQUIT,SIG_IGN); /* must leave signals ignored */
#endif
return;
}
signal(SIGINT,f); /* Function to trap to on interrupt. */
signal(SIGHUP,f); /* Or hangup, so lock file cleared. */
conif = 1; /* Flag console interrupts on. */
}
/* C O N N O I -- Reset console terminal interrupts */
connoi() { /* Console-no-interrupts */
if (!isatty(0)) return(0); /* only for real ttys */
if (backgrd) return; /* Ignore signals in background */
signal(SIGINT,SIG_DFL);
signal(SIGHUP,SIG_DFL);
signal(SIGQUIT,SIG_DFL);
conif = 0; /* Flag interrupt trapping off */
}
/* myread() -- For use by systems that can do nonblocking read() calls */
/*
Returns:
-1 if no characters available,
-2 upon error (such as disconnect),
otherwise value of character (0 or greater)
*/
myread() {
static int inbuf_item;
static CHAR inbuf[257];
CHAR readit;
if (ungotn >= 0) {
readit = ungotn;
} else {
if (inbufc > 0) {
readit = inbuf[++inbuf_item];
} else {
if ((inbufc = read(ttyfd,inbuf,256)) == 0) { /* end of file */
/* means carrier dropped on modem connection */
errno = 9999; /* magic number for no carrier */
return(-2); /* end of file has no errno */
}
if (inbufc < 0) { /* Real error */
return(-2);
}
readit = inbuf[inbuf_item = 0];
}
inbufc--;
}
ungotn = -1;
return(readit);
}
myunrd(ch) CHAR ch; { /* push back up to one character */
ungotn = ch;
}
/* I N I T R A W Q -- Set up to read /DEV/KMEM for character count. */
#ifdef V7
/*
Used in Version 7 to simulate Berkeley's FIONREAD ioctl call. This
eliminates blocking on a read, because we can read /dev/kmem to get the
number of characters available for raw input. If your system can't
or you won't let it read /dev/kmem (the world that is) then you must
figure out a different way to do the counting of characters available,
or else replace this by a dummy function that always returns 0.
*/
/*
* Call this routine as: initrawq(tty)
* where tty is the file descriptor of a terminal. It will return
* (as a char *) the kernel-mode memory address of the rawq character
* 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.
*/
#include <a.out.h>
#include <sys/proc.h>
char *initrawq(tty) int tty; {
#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
}
/* More V7-support functions... */
static
err(s) char *s; {
char buf[200];
sprintf(buf, "fatal error in initrawq: %s", s);
perror(buf);
doexit(1);
}
static
catch() {
longjmp(jjbuf, -1);
}
/* G E N B R K -- Simulate a modem break. */
#define BSPEED B150
genbrk(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 V7
/* 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
lseek(kmem[TTY], (long) qaddr[TTY], 0);
x = read(kmem[TTY], &n, sizeof(int));
return((x == sizeof(int))? n: 0);
#else V7
#ifdef UXIII
return(inbufc + (ungotn >= 0) );
#else
#ifdef C70
return(inbufc + (ungotn >= 0) );
#else
#ifdef PROVX1
x = ioctl(ttyfd, TIOCQCNT, &ttbuf);
n = ttbuf.sg_ispeed & 0377;
return((x < 0) ? 0 : n);
#else
return(0);
#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;
CHAR c;
#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 function, or 0 upon end of
file, or -1 if an error occurred. Times out & returns error if not completed
within "timo" seconds.
*/
ttinl(dest,max,timo,eol) int max,timo; char *dest; char eol; {
int x, y;
CHAR c;
if (ttyfd < 0) return(-1); /* Not open. */
if (timo <= 0) { /* Untimed read... */
#ifdef MYREAD
for (x = c = 0; (x < max) && (c != eol); x++) {
while ((y = myread()) == -1) ;
if (y == -2) return(-1);
dest[x] = c = y & 0377;
}
#else
x = read(ttyfd,dest,max); /* Try to read. */
#endif
return(x); /* Return the count. */
}
/* Timed read... */
signal(SIGALRM,timerh); /* Set up timeout action. */
alarm(timo); /* Set the timer. */
if (setjmp(sjbuf)) /* Do this if timer went off. */
x = -1;
else if (kerld) { /* Efficient Kermit line discipline */
x = read(ttyfd,dest,max); /* for 4.2bsd only... */
} else { /* Normal case... */
for (x = c = y = 0; (x < max) && (c != eol); x++) {
#ifdef MYREAD
while ((y = myread()) == -1) /* Use own buffering if we can */
;
if (y == -2) y++;
c = y & 0377;
#else
while ((y = read(ttyfd,&c,1)) == 0) /* Else call system */
; /* ...for each character. */
#endif
if (y < 0) {
alarm(0); /* Error, turn off timer, */
signal(SIGALRM,SIG_DFL); /* and associated interrupt. */
return(y); /* Return the error indication. */
}
dest[x] = c;
}
x++;
}
alarm(0); /* Success, turn off timer, */
signal(SIGALRM,SIG_DFL); /* and associated interrupt. */
return(x); /* Return the count. */
}
/* T T I N C -- Read a character from the communication line */
ttinc(timo) int timo; {
int n = 0;
CHAR ch = 0;
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 );
#else
while ((n = read(ttyfd,&ch,1)) == 0) ; /* Wait for a character. */
return( (n > 0) ? (ch & 0377) : n );
#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++;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -