libc: allocate file descriptor sets on the stack

The 'fd_set' size calculation in the current version of the 'poll()'
function results in an  amount which is smaller than the size of the
'fd_set' data type. With this patch the file descriptor sets get
allocated as plain stack variables.

Fixes #335.
This commit is contained in:
Christian Prochaska 2012-08-22 16:13:59 +02:00 committed by Norman Feske
parent 59a9d1f2b0
commit 7f092be94c
1 changed files with 9 additions and 28 deletions

View File

@ -51,8 +51,7 @@ poll(struct pollfd fds[], nfds_t nfds, int timeout)
{
nfds_t i;
int saved_errno, ret, fd, maxfd = 0;
fd_set *readfds = NULL, *writefds = NULL, *exceptfds = NULL;
size_t nmemb;
fd_set readfds, writefds, exceptfds;
struct timeval tv, *tvp = NULL;
for (i = 0; i < nfds; i++) {
@ -64,27 +63,18 @@ poll(struct pollfd fds[], nfds_t nfds, int timeout)
maxfd = MAX(maxfd, fd);
}
nmemb = howmany(maxfd + 1 , NFDBITS);
if ((readfds = (fd_set *) calloc(nmemb, sizeof(fd_mask))) == NULL ||
(writefds = (fd_set *) calloc(nmemb, sizeof(fd_mask))) == NULL ||
(exceptfds = (fd_set *) calloc(nmemb, sizeof(fd_mask))) == NULL) {
/*saved_errno = ENOMEM;*/
ret = -1;
goto out;
}
/* populate event bit vectors for the events we're interested in */
for (i = 0; i < nfds; i++) {
fd = fds[i].fd;
if (fd == -1)
continue;
if (fds[i].events & POLLIN) {
FD_SET(fd, readfds);
FD_SET(fd, exceptfds);
FD_SET(fd, &readfds);
FD_SET(fd, &exceptfds);
}
if (fds[i].events & POLLOUT) {
FD_SET(fd, writefds);
FD_SET(fd, exceptfds);
FD_SET(fd, &writefds);
FD_SET(fd, &exceptfds);
}
}
@ -94,34 +84,25 @@ poll(struct pollfd fds[], nfds_t nfds, int timeout)
tv.tv_usec = (timeout % 1000) * 1000;
tvp = &tv;
}
ret = select(maxfd + 1, readfds, writefds, exceptfds, tvp);
ret = select(maxfd + 1, &readfds, &writefds, &exceptfds, tvp);
/*saved_errno = errno;*/
/* scan through select results and set poll() flags */
for (i = 0; i < nfds; i++) {
fd = fds[i].fd;
fds[i].revents = 0;
if (fd == -1)
continue;
if (FD_ISSET(fd, readfds)) {
if (FD_ISSET(fd, &readfds)) {
fds[i].revents |= POLLIN;
}
if (FD_ISSET(fd, writefds)) {
if (FD_ISSET(fd, &writefds)) {
fds[i].revents |= POLLOUT;
}
if (FD_ISSET(fd, exceptfds)) {
if (FD_ISSET(fd, &exceptfds)) {
fds[i].revents |= POLLERR;
}
}
out:
if (readfds != NULL)
free(readfds);
if (writefds != NULL)
free(writefds);
if (exceptfds != NULL)
free(exceptfds);
/*
if (ret == -1)
errno = saved_errno;