mirror of
git://git.code.sf.net/p/zsh/code
synced 2025-01-01 05:16:05 +01:00
50133: use read-ahead and lseek-rewind for efficient line-buffered input
This commit is contained in:
parent
007c7df74a
commit
df0c783f4b
3 changed files with 86 additions and 1 deletions
|
@ -1,5 +1,9 @@
|
|||
2022-04-28 Bart Schaefer <schaefer@zsh.org>
|
||||
|
||||
* 50133 (Bart, PWS, Jun-ichi): Src/input.c, configure.ac: when
|
||||
lseek(2) is available, use it to check for and rewind read-ahead
|
||||
for more efficient line-buffered input.
|
||||
|
||||
* 50126: Etc/BUGS, Src/exec.c: Fix multios in current-shell "exec"
|
||||
|
||||
* 50101: Src/Modules/system.c: sysread -o with param matches doc
|
||||
|
|
24
Src/input.c
24
Src/input.c
|
@ -217,12 +217,34 @@ shinbufrestore(void)
|
|||
static int
|
||||
shingetchar(void)
|
||||
{
|
||||
int nread;
|
||||
int nread, rsize = isset(SHINSTDIN) ? 1 : SHINBUFSIZE;
|
||||
|
||||
if (shinbufptr < shinbufendptr)
|
||||
return STOUC(*shinbufptr++);
|
||||
|
||||
shinbufreset();
|
||||
#ifdef USE_LSEEK
|
||||
if (rsize == 1 && lseek(SHIN, 0, SEEK_CUR) != (off_t)-1)
|
||||
rsize = SHINBUFSIZE;
|
||||
if (rsize > 1) {
|
||||
do {
|
||||
errno = 0;
|
||||
nread = read(SHIN, shinbuffer, rsize);
|
||||
} while (nread < 0 && errno == EINTR);
|
||||
if (nread <= 0)
|
||||
return -1;
|
||||
if (isset(SHINSTDIN) &&
|
||||
(shinbufendptr = memchr(shinbuffer, '\n', nread))) {
|
||||
shinbufendptr++;
|
||||
rsize = (shinbufendptr - shinbuffer);
|
||||
if (nread > rsize &&
|
||||
lseek(SHIN, -(nread - rsize), SEEK_CUR) < 0)
|
||||
zerr("lseek(%d, %d): %e", SHIN, -(nread - rsize), errno);
|
||||
} else
|
||||
shinbufendptr = shinbuffer + nread;
|
||||
return STOUC(*shinbufptr++);
|
||||
}
|
||||
#endif
|
||||
for (;;) {
|
||||
errno = 0;
|
||||
nread = read(SHIN, shinbufendptr, 1);
|
||||
|
|
59
configure.ac
59
configure.ac
|
@ -2209,6 +2209,65 @@ if test x$zsh_cv_sys_fifo = xyes; then
|
|||
AC_DEFINE(HAVE_FIFOS)
|
||||
fi
|
||||
|
||||
dnl -----------
|
||||
dnl check that lseek() correctly reports seekability.
|
||||
dnl -----------
|
||||
AC_CACHE_CHECK(if lseek() correctly reports seekability,
|
||||
zsh_cv_sys_lseek,
|
||||
[AC_RUN_IFELSE([AC_LANG_SOURCE([[
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/stat.h>
|
||||
int main() {
|
||||
int pipefd[2], fd;
|
||||
off_t ret;
|
||||
char* tmpfile = "seekfiletest.tmp";
|
||||
if ((fd = open(tmpfile, O_CREAT, S_IRUSR)) < 0) {
|
||||
fprintf(stderr, "creating file failed\n");
|
||||
return 1;
|
||||
}
|
||||
ret = lseek(fd, 0, SEEK_CUR);
|
||||
close(fd);
|
||||
unlink(tmpfile);
|
||||
if (ret == (off_t)-1) {
|
||||
fprintf(stderr, "lseek on regular file failed\n");
|
||||
return 1;
|
||||
}
|
||||
if (pipe(pipefd) < 0) {
|
||||
fprintf(stderr, "creating pipe failed\n");
|
||||
return 1;
|
||||
}
|
||||
write(pipefd[1], "abcdefgh", 8);
|
||||
ret = lseek(pipefd[0], 0, SEEK_CUR);
|
||||
close(pipefd[0]);
|
||||
close(pipefd[1]);
|
||||
if (ret != (off_t)-1) {
|
||||
fprintf(stderr, "lseek on pipe succeeded\n");
|
||||
return 1;
|
||||
}
|
||||
if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
|
||||
fprintf(stderr, "creating UNIX domain socket failed\n");
|
||||
return 1;
|
||||
}
|
||||
ret = lseek(fd, 0, SEEK_CUR);
|
||||
close(fd);
|
||||
if (ret != (off_t)-1) {
|
||||
fprintf(stderr, "lseek on UNIX domain socket succeeded\n");
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
]])],[zsh_cv_sys_lseek=yes],[zsh_cv_sys_lseek=no],[zsh_cv_sys_lseek=yes])
|
||||
])
|
||||
AH_TEMPLATE([USE_LSEEK],
|
||||
[Define to 1 if lseek() can be used for SHIN.])
|
||||
if test x$zsh_cv_sys_lseek = xyes; then
|
||||
AC_DEFINE(USE_LSEEK)
|
||||
fi
|
||||
|
||||
dnl -----------
|
||||
dnl test for whether link() works
|
||||
dnl for instance, BeOS R4.51 doesn't support hard links yet
|
||||
|
|
Loading…
Reference in a new issue