1
0
Fork 0
mirror of git://git.code.sf.net/p/zsh/code synced 2025-10-16 12:21:18 +02:00

27721: rationalise initialisation of file descriptors

This commit is contained in:
Peter Stephenson 2010-02-22 10:12:22 +00:00
parent 349b6649c3
commit 7977ce0747
4 changed files with 69 additions and 42 deletions

View file

@ -187,40 +187,45 @@ zpathmax(char *dir)
#endif /* 0 */
#ifdef HAVE_SYSCONF
/* This is replaced by a macro from system.h if not HAVE_SYSCONF. *
* 0 is returned by sysconf if _SC_OPEN_MAX is unavailable; *
* -1 is returned on error *
* *
* Neither of these should happen, but resort to OPEN_MAX rather *
* than return 0 or -1 just in case. */
/*
* This is replaced by a macro from system.h if not HAVE_SYSCONF.
* 0 is returned by sysconf if _SC_OPEN_MAX is unavailable;
* -1 is returned on error
*
* Neither of these should happen, but resort to OPEN_MAX rather
* than return 0 or -1 just in case.
*
* We'll limit the open maximum to ZSH_INITIAL_OPEN_MAX to
* avoid probing ridiculous numbers of file descriptors.
*/
/**/
mod_export long
zopenmax(void)
{
static long openmax = 0;
long openmax;
if (openmax < 1) {
if ((openmax = sysconf(_SC_OPEN_MAX)) < 1) {
openmax = OPEN_MAX;
} else if (openmax > OPEN_MAX) {
/* On some systems, "limit descriptors unlimited" or the *
* equivalent will set openmax to a huge number. Unless *
* there actually is a file descriptor > OPEN_MAX already *
* open, nothing in zsh requires the true maximum, and in *
* fact it causes inefficiency elsewhere if we report it. *
* So, report the maximum of OPEN_MAX or the largest open *
* descriptor (is there a better way to find that?). */
long i, j = OPEN_MAX;
for (i = j; i < openmax; i += (errno != EINTR)) {
errno = 0;
if (fcntl(i, F_GETFL, 0) < 0 &&
(errno == EBADF || errno == EINTR))
continue;
j = i;
}
openmax = j;
if ((openmax = sysconf(_SC_OPEN_MAX)) < 1) {
openmax = OPEN_MAX;
} else if (openmax > OPEN_MAX) {
/* On some systems, "limit descriptors unlimited" or the *
* equivalent will set openmax to a huge number. Unless *
* there actually is a file descriptor > OPEN_MAX already *
* open, nothing in zsh requires the true maximum, and in *
* fact it causes inefficiency elsewhere if we report it. *
* So, report the maximum of OPEN_MAX or the largest open *
* descriptor (is there a better way to find that?). */
long i, j = OPEN_MAX;
if (openmax > ZSH_INITIAL_OPEN_MAX)
openmax = ZSH_INITIAL_OPEN_MAX;
for (i = j; i < openmax; i += (errno != EINTR)) {
errno = 0;
if (fcntl(i, F_GETFL, 0) < 0 &&
(errno == EBADF || errno == EINTR))
continue;
j = i;
}
openmax = j;
}
return (max_zsh_fd > openmax) ? max_zsh_fd : openmax;
@ -771,7 +776,7 @@ mk_wcwidth(wchar_t ucs)
/* if we arrive here, ucs is not a combining or C0/C1 control character */
return 1 +
return 1 +
(ucs >= 0x1100 &&
(ucs <= 0x115f || /* Hangul Jamo init. consonants */
ucs == 0x2329 || ucs == 0x232a ||

View file

@ -1928,7 +1928,7 @@ closeallelse(struct multio *mn)
int i, j;
long openmax;
openmax = zopenmax();
openmax = fdtable_size;
for (i = 0; i < openmax; i++)
if (mn->pipe != i) {

View file

@ -304,16 +304,22 @@ struct timezone {
# endif
#endif
/*
* The number of file descriptors we'll allocate initially.
* We will reallocate later if necessary.
*/
#define ZSH_INITIAL_OPEN_MAX 64
#ifndef OPEN_MAX
# ifdef NOFILE
# define OPEN_MAX NOFILE
# else
/* so we will just pick something */
# define OPEN_MAX 64
# define OPEN_MAX ZSH_INITIAL_OPEN_MAX
# endif
#endif
#ifndef HAVE_SYSCONF
# define zopenmax() ((long) OPEN_MAX)
# define zopenmax() ((long) (OPEN_MAX > ZSH_INITIAL_OPEN_MAX ? \
ZSH_INITIAL_OPEN_MAX : OPEN_MAX))
#endif
#ifdef HAVE_FCNTL_H

View file

@ -1621,6 +1621,27 @@ adjustwinsize(int from)
}
}
/*
* Ensure the fdtable is large enough for fd, and that the
* maximum fd is set appropriately.
*/
static void
check_fd_table(int fd)
{
if (fd <= max_zsh_fd)
return;
if (fd >= fdtable_size) {
int old_size = fdtable_size;
while (fd >= fdtable_size)
fdtable = zrealloc(fdtable,
(fdtable_size *= 2)*sizeof(*fdtable));
memset(fdtable + old_size, 0,
(fdtable_size - old_size) * sizeof(*fdtable));
}
max_zsh_fd = fd;
}
/* Move a fd to a place >= 10 and mark the new fd in fdtable. If the fd *
* is already >= 10, it is not moved. If it is invalid, -1 is returned. */
@ -1644,12 +1665,7 @@ movefd(int fd)
fd = fe;
}
if(fd != -1) {
if (fd > max_zsh_fd) {
while (fd >= fdtable_size)
fdtable = zrealloc(fdtable,
(fdtable_size *= 2)*sizeof(*fdtable));
max_zsh_fd = fd;
}
check_fd_table(fd);
fdtable[fd] = FDT_INTERNAL;
}
return fd;
@ -1669,12 +1685,12 @@ redup(int x, int y)
if(x < 0)
zclose(y);
else if (x != y) {
while (y >= fdtable_size)
fdtable = zrealloc(fdtable, (fdtable_size *= 2)*sizeof(*fdtable));
if (dup2(x, y) == -1)
if (dup2(x, y) == -1) {
ret = -1;
if ((fdtable[y] = fdtable[x]) && y > max_zsh_fd)
max_zsh_fd = y;
} else {
check_fd_table(y);
fdtable[y] = fdtable[x];
}
zclose(x);
}