[PATCH: 2.3.99pre6] poll(2) fails with EINVAL too easily

From: Herbert Xu (herbert@gondor.apana.org.au)
Date: Mon May 08 2000 - 22:46:54 EST


Currently poll(2) will fail with EINVAL if n is bigger than
current->files->max_fds. It seems better to replace that with
current->rlim[RLIMIT_NOFILE].rlim_cur as this is what some
applications expect and consistent with the spirit of the
Single Unix specification (where poll(2) is allowed to return
EINVAL if n > OPEN_MAX).

The following patch will do just that.

-- 
Debian GNU/Linux 2.1 is out! ( http://www.debian.org/ )
Email:  Herbert Xu ~{PmV>HI~} <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

attached mail follows:


Package: kernel-source-2.2.14 Version: 2.2.14-5

There is a bug in the kernel implementation of poll. The attached program incorrectly fails with the poll setting errno to EINVAL. Reducing the 900 to 20 causes the poll to succeed, so that's the invalid parameter.

Removing the comments causes the poll to succeed for the full 900 pollfd entries.

I would guess there's a resizable array of fds in the kernel and the 900 opens expands that array (I can say more about this if somebody's willing to fix it). To my understanding, there is no limitation on the number of pollfds supplied to poll(). If I want to fill them all with -1s, that's still a valid call. In my particular application, I might use getrlimit(NOFILE) fds so I allocate enough pollfds at the start, filling the unused ones with -1.

David Marwood

----------------------------------------------------------------

#include <stdio.h> #include <sys/poll.h> #include <string.h> #include <errno.h> #include <assert.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h>

void main(void) { struct pollfd pollfds[900];

/* for (int i = 0; i < 900; i++) { int ret = open("test.cpp", O_RDONLY); printf("ret = %d\n", ret); assert(ret != -1); } */

for (int i = 0; i < 900; i++) pollfds[i].fd = -1;

int err = poll(pollfds, 900, 0);

printf("errno = %d = %s\n", errno, strerror(errno)); }

- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Mon May 15 2000 - 21:00:12 EST