📄 unix.c
字号:
/* unix.c *//* Author: * Steve Kirkendall * 14407 SW Teal Blvd. #C * Beaverton, OR 97005 * kirkenda@cs.pdx.edu *//* This file contains the unix-specific versions the ttyread() functions. * There are actually three versions of ttyread() defined here, because * BSD, SysV, and V7 all need quite different implementations. */#include "config.h"#if ANY_UNIX# include "vi.h"# if BSD/* For BSD, we use select() to wait for characters to become available, * and then do a read() to actually get the characters. We also try to * handle SIGWINCH -- if the signal arrives during the select() call, then * we adjust the o_columns and o_lines variables, and fake a control-L. */# include <sys/types.h># include <sys/time.h>int ttyread(buf, len, time) char *buf; /* where to store the gotten characters */ int len; /* maximum number of characters to read */ int time; /* maximum time to allow for reading */{ fd_set rd; /* the file descriptors that we want to read from */ static tty; /* 'y' if reading from tty, or 'n' if not a tty */ int i; struct timeval t; struct timeval *tp; /* do we know whether this is a tty or not? */ if (!tty) { tty = (isatty(0) ? 'y' : 'n'); } /* compute the timeout value */ if (time) { t.tv_sec = time / 10; t.tv_usec = (time % 10) * 100000L; tp = &t; } else { tp = (struct timeval *)0; } /* loop until we get characters or a definite EOF */ for (;;) { if (tty == 'y') { /* wait until timeout or characters are available */ FD_ZERO(&rd); FD_SET(0, &rd); i = select(1, &rd, (fd_set *)0, (fd_set *)0, tp); } else { /* if reading from a file or pipe, never timeout! * (This also affects the way that EOF is detected) */ i = 1; } /* react accordingly... */ switch (i) { case -1: /* assume we got an EINTR because of SIGWINCH */ if (*o_lines != LINES || *o_columns != COLS) { *o_lines = LINES; *o_columns = COLS;#ifndef CRUNCH if (!wset) { *o_window = LINES - 1; }#endif if (mode != MODE_EX) { /* pretend the user hit ^L */ *buf = ctrl('L'); return 1; } } break; case 0: /* timeout */ return 0; default: /* characters available */ return read(0, buf, len); } }}# else# if M_SYSV/* For System-V or Coherent, we use VMIN/VTIME to implement the timeout. * For no timeout, VMIN should be 1 and VTIME should be 0; for timeout, * VMIN should be 0 and VTIME should be the timeout value. */# include <termio.h>int ttyread(buf, len, time) char *buf; /* where to store the gotten characters */ int len; /* maximum number of characters to read */ int time; /* maximum time to allow for reading */{ struct termio tio; int bytes; /* number of bytes actually read */ /* arrange for timeout */ ioctl(0, TCGETA, &tio); if (time) { tio.c_cc[VMIN] = 0; tio.c_cc[VTIME] = time; } else { tio.c_cc[VMIN] = 1; tio.c_cc[VTIME] = 0; } ioctl(0, TCSETA, &tio); /* Perform the read. Loop if EINTR error happens */ while ((bytes = read(0, buf, len)) < 0) { /* probably EINTR error because a SIGWINCH was received */ if (*o_lines != LINES || *o_columns != COLS) { *o_lines = LINES; *o_columns = COLS;#ifndef CRUNCH if (!wset) { *o_window = LINES - 1; }#endif if (mode != MODE_EX) { /* pretend the user hit ^L */ *buf = ctrl('L'); return 1; } } } /* return the number of bytes read */ return bytes; /* NOTE: The terminal may be left in a timeout-mode after this function * returns. This shouldn't be a problem since Elvis *NEVER* tries to * read from the keyboard except through this function. */}# else /* any other version of UNIX, assume it is V7 compatible *//* For V7 UNIX (including Minix) we set an alarm() before doing a blocking * read(), and assume that the SIGALRM signal will cause the read() function * to give up. */#include <setjmp.h>static jmp_buf env;/*ARGSUSED*/int dummy(signo) int signo;{ longjmp(env, 1);}int ttyread(buf, len, time) char *buf; /* where to store the gotten characters */ int len; /* maximum number of characters to read */ int time; /* maximum time to allow for reading */{ /* arrange for timeout */#if __GNUC__ || _ANSI signal(SIGALRM, (void (*)()) dummy);#else signal(SIGALRM, dummy);#endif alarm(time); /* perform the blocking read */ if (setjmp(env) == 0) { len = read(0, buf, len); } else /* I guess we timed out */ { len = 0; } /* cancel the alarm */#if _ANSI signal(SIGALRM, (void (*)())dummy); /* work around a bug in Minix */#else signal(SIGALRM, dummy); /* work around a bug in Minix */#endif alarm(0); /* return the number of bytes read */ if (len < 0) len = 0; return len;}# endif /* !(M_SYSV || COHERENT) */# endif /* !BSD */#endif /* ANY_UNIX */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -