[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Minios-devel] [UNIKRAFT/LWIP PATCH 8/8] Provide poll() and select() wrappers around lwip versions
This takes the vfscore-provided file descriptors, translates them into lwip file descriptors, and will run the lwip versions on those sockets. If any of the file descriptors provided isn't an LWIP socket, the call will fail with a return of -1, errno EBADF. Signed-off-by: Florian Schmidt <florian.schmidt@xxxxxxxxx> --- exportsyms.uk | 2 +- sockets.c | 137 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 138 insertions(+), 1 deletion(-) diff --git a/exportsyms.uk b/exportsyms.uk index b17b5e1..1720e00 100644 --- a/exportsyms.uk +++ b/exportsyms.uk @@ -9,7 +9,7 @@ listen lwip_ioctl lwip_htonl lwip_htons -lwip_select +poll recv recvfrom select diff --git a/sockets.c b/sockets.c index 7f4b6f3..294de3d 100644 --- a/sockets.c +++ b/sockets.c @@ -335,6 +335,143 @@ EXIT: return ret; } +int poll(struct pollfd fds[], nfds_t nfds, int timeout) +{ + unsigned int i; + struct sock_net_file *file; + struct pollfd lwip_fds[nfds]; + + for (i = 0; i < nfds; i++) { + if (fds[i].fd < 0) + lwip_fds[i].fd = fds[i].fd; + else { + file = sock_net_file_get(fds[i].fd); + if (PTRISERR(file)) { + LWIP_DEBUGF(SOCKETS_DEBUG, + ("failed to identify socket descriptor\n")); + /* Setting the errno */ + SOCK_NET_SET_ERRNO(PTR2ERR(file)); + return -1; + } + lwip_fds[i].fd = file->sock_fd; + lwip_fds[i].events = fds[i].events; + } + } + + lwip_poll(lwip_fds, nfds, timeout); + + for (i = 0; i < nfds; i++) { + if (fds[i].fd < 0) + fds[i].revents = 0; + else + fds[i].revents = lwip_fds[i].revents; + } + return 0; +} + +int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, + struct timeval *timeout) +{ + uint64_t nsecs; + fd_set rd, wr, xc; + int i, ret, maxfd; + struct sock_net_file *file; + + if (nfds == 0 && timeout != NULL) { + nsecs = timeout->tv_sec * 1000000000; + nsecs += timeout->tv_usec * 1000; + uk_sched_thread_sleep(nsecs); + return 0; + } + + /* translate the public (vfscore) fds into lwIP socket fds */ + FD_ZERO(&rd); + FD_ZERO(&wr); + FD_ZERO(&xc); + maxfd = 0; + for (i = 0; i < nfds; i++) { + if (readfds && FD_ISSET(i, readfds)) { + maxfd = i; + file = sock_net_file_get(i); + if (PTRISERR(file)) { + LWIP_DEBUGF(SOCKETS_DEBUG, + ("failed to identify socket descriptor\n")); + ret = -1; + /* Setting the errno */ + SOCK_NET_SET_ERRNO(PTR2ERR(file)); + goto EXIT; + } + FD_SET(file->sock_fd, &rd); + } + if (writefds && FD_ISSET(i, writefds)) { + maxfd = i; + file = sock_net_file_get(i); + if (PTRISERR(file)) { + LWIP_DEBUGF(SOCKETS_DEBUG, + ("failed to identify socket descriptor\n")); + ret = -1; + /* Setting the errno */ + SOCK_NET_SET_ERRNO(PTR2ERR(file)); + goto EXIT; + } + FD_SET(file->sock_fd, &wr); + } + if (exceptfds && FD_ISSET(i, exceptfds)) { + maxfd = i; + file = sock_net_file_get(i); + if (PTRISERR(file)) { + LWIP_DEBUGF(SOCKETS_DEBUG, + ("failed to identify socket descriptor\n")); + ret = -1; + /* Setting the errno */ + SOCK_NET_SET_ERRNO(PTR2ERR(file)); + goto EXIT; + } + FD_SET(file->sock_fd, &xc); + } + } + + ret = lwip_select(maxfd+1, &rd, &wr, &xc, timeout); + if (ret < 0) + return ret; + + /* translate back from lwIP socket fds to public (vfscore) fds. + * But there's no way to go from lwIP to vfscore, so iterate over + * everything again. Check which ones were set originally, and if + * they aren't also set in lwip_select()'s return, clear them. + */ + for (i = 0; i < nfds; i++) { + if (readfds && FD_ISSET(i, readfds)) { + /* This lookup can't fail, or it would already have + * failed during the translation above. + */ + file = sock_net_file_get(i); + if (!FD_ISSET(file->sock_fd, &rd)) + FD_CLR(i, readfds); + } + if (writefds && FD_ISSET(i, writefds)) { + /* This lookup can't fail, or it would already have + * failed during the translation above. + */ + file = sock_net_file_get(i); + if (!FD_ISSET(file->sock_fd, &wr)) + FD_CLR(i, writefds); + } + if (exceptfds && FD_ISSET(i, exceptfds)) { + /* This lookup can't fail, or it would already have + * failed during the translation above. + */ + file = sock_net_file_get(i); + if (!FD_ISSET(file->sock_fd, &xc)) + FD_CLR(i, exceptfds); + } + } + return 0; + +EXIT: + return ret; +} + int shutdown(int s, int how) { int ret = 0; -- 2.21.0 _______________________________________________ Minios-devel mailing list Minios-devel@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/mailman/listinfo/minios-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |