diff options
Diffstat (limited to 'Src')
-rw-r--r-- | Src/builtin.c | 90 | ||||
-rw-r--r-- | Src/utils.c | 99 |
2 files changed, 100 insertions, 89 deletions
diff --git a/Src/builtin.c b/Src/builtin.c index 3b38c2674..7f8e90741 100644 --- a/Src/builtin.c +++ b/Src/builtin.c @@ -3361,94 +3361,6 @@ static int readfd; /* Read a character from readfd, or from the buffer zbuf. Return EOF on end of file/buffer. */ -/**/ -static int -read_poll(int *readchar, int polltty) -{ - int ret = 0; - long mode = -1; - char c; -#ifdef FIONREAD - int val; -#endif -#ifdef HAVE_SELECT - fd_set foofd; - struct timeval expire_tv; -#endif -#ifdef HAS_TIO - struct ttyinfo ti; -#endif - - -#if defined(HAS_TIO) && !defined(__CYGWIN__) - /* - * Under Solaris, at least, reading from the terminal in non-canonical - * mode requires that we use the VMIN mechanism to poll. Any attempt - * to check any other way, or to set the terminal to non-blocking mode - * and poll that way, fails; it will just for canonical mode input. - * We should probably use this mechanism if the user has set non-canonical - * mode, in which case testing here for isatty() and ~ICANON would be - * better than testing whether bin_read() set it, but for now we've got - * enough problems. - * - * Under Cygwin, you won't be surprised to here, this mechanism, - * although present, doesn't work, and we *have* to use ordinary - * non-blocking reads to find out if there is a character present - * in non-canonical mode. - * - * I am assuming Solaris is nearer the UNIX norm. This is not necessarily - * as plausible as it sounds, but it seems the right way to guess. - * pws 2000/06/26 - */ - if (polltty) { - gettyinfo(&ti); - ti.tio.c_cc[VMIN] = 0; - settyinfo(&ti); - } -#else - polltty = 0; -#endif -#ifdef HAVE_SELECT - if (!ret) { - expire_tv.tv_sec = expire_tv.tv_usec = 0; - FD_ZERO(&foofd); - FD_SET(readfd, &foofd); - if (select(readfd+1, (SELECT_ARG_2_T) &foofd, NULL, NULL, &expire_tv) - > 1) - ret = 1; - } -#else -#ifdef FIONREAD - if (!ret) { - ioctl(readfd, FIONREAD, (char *)&val); - if (val) - ret = 1; - } -#endif -#endif - - if (!ret) { - /* - * Final attempt: set non-blocking read and try to read a character. - * Praise Bill, this works under Cygwin (nothing else seems to). - */ - if ((polltty || setblock_fd(0, readfd, &mode)) - && read(readfd, &c, 1) > 0) { - *readchar = STOUC(c); - ret = 1; - } - if (mode != -1) - fcntl(readfd, F_SETFL, mode); - } -#ifdef HAS_TIO - if (polltty) { - ti.tio.c_cc[VMIN] = 1; - settyinfo(&ti); - } -#endif - return ret; -} - /* read: get a line of input, or (for compctl functions) return some * * useful data about the state of the editing line. The -E and -e * * options mean that the result should be sent to stdout. -e means, * @@ -3529,7 +3441,7 @@ bin_read(char *name, char **args, char *ops, int func) } else readfd = izle = 0; - if (ops['t'] && !read_poll(&readchar, keys && !zleactive)) { + if (ops['t'] && !read_poll(readfd, &readchar, keys && !zleactive)) { if (ops['k'] && !zleactive && !isem) settyinfo(&shttyinfo); if (haso) { diff --git a/Src/utils.c b/Src/utils.c index f423795ab..f5242bbaa 100644 --- a/Src/utils.c +++ b/Src/utils.c @@ -1298,6 +1298,105 @@ setblock_stdin(void) return setblock_fd(1, 0, &mode); } +/* + * Check for pending input on fd. If polltty is set, we may need to + * use termio to look for input. As a final resort, go to non-blocking + * input and try to read a character, which in this case will be + * returned in *readchar. + * + * Note that apart from setting (and restoring) non-blocking input, + * this function does not change the input mode. The calling function + * should have set cbreak mode if necessary. + */ + +/**/ +int +read_poll(int fd, int *readchar, int polltty) +{ + int ret = 0; + long mode = -1; + char c; +#ifdef FIONREAD + int val; +#endif +#ifdef HAVE_SELECT + fd_set foofd; + struct timeval expire_tv; +#endif +#ifdef HAS_TIO + struct ttyinfo ti; +#endif + + +#if defined(HAS_TIO) && !defined(__CYGWIN__) + /* + * Under Solaris, at least, reading from the terminal in non-canonical + * mode requires that we use the VMIN mechanism to poll. Any attempt + * to check any other way, or to set the terminal to non-blocking mode + * and poll that way, fails; it will just for canonical mode input. + * We should probably use this mechanism if the user has set non-canonical + * mode, in which case testing here for isatty() and ~ICANON would be + * better than testing whether bin_read() set it, but for now we've got + * enough problems. + * + * Under Cygwin, you won't be surprised to here, this mechanism, + * although present, doesn't work, and we *have* to use ordinary + * non-blocking reads to find out if there is a character present + * in non-canonical mode. + * + * I am assuming Solaris is nearer the UNIX norm. This is not necessarily + * as plausible as it sounds, but it seems the right way to guess. + * pws 2000/06/26 + */ + if (polltty) { + gettyinfo(&ti); + ti.tio.c_cc[VMIN] = 0; + settyinfo(&ti); + } +#else + polltty = 0; +#endif +#ifdef HAVE_SELECT + if (!ret) { + expire_tv.tv_sec = expire_tv.tv_usec = 0; + FD_ZERO(&foofd); + FD_SET(fd, &foofd); + if (select(fd+1, (SELECT_ARG_2_T) &foofd, NULL, NULL, &expire_tv) + > 1) + ret = 1; + } +#else +#ifdef FIONREAD + if (!ret) { + ioctl(fd, FIONREAD, (char *)&val); + if (val) + ret = 1; + } +#endif +#endif + + if (!ret) { + /* + * Final attempt: set non-blocking read and try to read a character. + * Praise Bill, this works under Cygwin (nothing else seems to). + */ + if ((polltty || setblock_fd(0, fd, &mode)) + && read(fd, &c, 1) > 0) { + *readchar = STOUC(c); + ret = 1; + } + if (mode != -1) + fcntl(fd, F_SETFL, mode); + } +#ifdef HAS_TIO + if (polltty) { + ti.tio.c_cc[VMIN] = 1; + settyinfo(&ti); + } +#endif + return ret; +} + /**/ int checkrmall(char *s) |