Reduce usage of malloc in select and poll. Fix poll not acceping -1 fds

This commit is contained in:
TuxSH 2018-09-21 13:54:41 +02:00 committed by yellows8
parent fba43b0f10
commit 052fb34397

View File

@ -4,6 +4,7 @@
#include <ctype.h>
#include <string.h>
#include <malloc.h>
#include <alloca.h>
#include <sys/iosupport.h>
#include <sys/select.h>
@ -24,6 +25,8 @@
#include "services/nifm.h"
#include "result.h"
__attribute__((weak)) size_t __nx_pollfd_sb_max_fds = 64;
int _convert_errno(int bsdErrno);
__thread int h_errno;
@ -261,7 +264,10 @@ int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struc
++numfds;
}
pollinfo = (struct pollfd*)malloc(numfds * sizeof(struct pollfd));
if(numfds <= __nx_pollfd_sb_max_fds)
pollinfo = (struct pollfd *)alloca(numfds * sizeof(struct pollfd));
else
pollinfo = (struct pollfd *)malloc(numfds * sizeof(struct pollfd));
if(pollinfo == NULL) {
errno = ENOMEM;
return -1;
@ -271,7 +277,11 @@ int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struc
if((readfds && FD_ISSET(i, readfds))
|| (writefds && FD_ISSET(i, writefds))
|| (exceptfds && FD_ISSET(i, exceptfds))) {
pollinfo[j].fd = i;
pollinfo[j].fd = _socketGetFd(i);
if(pollinfo[j].fd == -1) {
rc = -1;
goto cleanup;
}
pollinfo[j].events = 0;
pollinfo[j].revents = 0;
@ -285,14 +295,12 @@ int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struc
}
if(timeout)
rc = poll(pollinfo, numfds, timeout->tv_sec*1000 + timeout->tv_usec/1000);
rc = _socketParseBsdResult(NULL, bsdPoll(pollinfo, numfds, timeout->tv_sec*1000 + timeout->tv_usec/1000));
else
rc = poll(pollinfo, numfds, -1);
rc = _socketParseBsdResult(NULL, bsdPoll(pollinfo, numfds, -1));
if(rc < 0) {
free(pollinfo);
return rc;
}
if(rc < 0)
goto cleanup;
for(i = 0, j = 0, rc = 0; i < nfds; ++i) {
found = 0;
@ -328,8 +336,9 @@ int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struc
}
}
free(pollinfo);
cleanup:
if(numfds > __nx_pollfd_sb_max_fds)
free(pollinfo);
return rc;
}
@ -343,7 +352,10 @@ int poll(struct pollfd *fds, nfds_t nfds, int timeout) {
return -1;
}
fds2 = (struct pollfd *)malloc(nfds * sizeof(struct pollfd));
if(nfds <= __nx_pollfd_sb_max_fds)
fds2 = (struct pollfd *)alloca(nfds * sizeof(struct pollfd));
else
fds2 = (struct pollfd *)malloc(nfds * sizeof(struct pollfd));
if(fds2 == NULL) {
errno = ENOMEM;
return -1;
@ -352,10 +364,14 @@ int poll(struct pollfd *fds, nfds_t nfds, int timeout) {
for(nfds_t i = 0; i < nfds; i++) {
fds2[i].events = fds[i].events;
fds2[i].revents = fds[i].revents;
fds2[i].fd = _socketGetFd(fds[i].fd);
if(fds2[i].fd == -1) {
ret = -1;
break;
if(fds[i].fd < 0) {
fds2[i].fd = -1;
} else {
fds2[i].fd = _socketGetFd(fds[i].fd);
if(fds2[i].fd == -1) {
ret = -1;
break;
}
}
}
@ -368,7 +384,8 @@ int poll(struct pollfd *fds, nfds_t nfds, int timeout) {
}
}
free(fds2);
if(nfds > __nx_pollfd_sb_max_fds)
free(fds2);
return ret;
}
@ -1617,4 +1634,4 @@ struct servent *getservbyport(int a, const char *s) { (void)a; (void)s; h_errno
struct servent *getservent(void) { h_errno = NO_RECOVERY; errno = ENOSYS; return NULL; }
void sethostent(int a) { (void)a;}
void setnetent(int a) { (void)a;}
void setprotoent(int a) { (void)a; }
void setprotoent(int a) { (void)a; }