diff --git a/nx/source/runtime/devices/socket.c b/nx/source/runtime/devices/socket.c index 676b2633..43a12a03 100644 --- a/nx/source/runtime/devices/socket.c +++ b/nx/source/runtime/devices/socket.c @@ -4,6 +4,7 @@ #include #include #include +#include #include #include @@ -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; } \ No newline at end of file +void setprotoent(int a) { (void)a; }