/* * Wait for I/O on a single descriptor. */ int st_netfd_poll(_st_netfd_t *fd, int how, st_utime_t timeout) { struct pollfd pd; int n; pd.fd = fd->osfd; pd.events = (short) how; pd.revents = 0; if ((n = st_poll(&pd, 1, timeout)) < 0) return -1; if (n == 0) { /* Timed out */ errno = ETIME; return -1; } if (pd.revents & POLLNVAL) { errno = EBADF; return -1; } return 0; }
static void *handle_request(void *arg) { struct pollfd pds[2]; st_netfd_t cli_nfd, rmt_nfd; int sock, n; char buf[IOBUFSIZE]; cli_nfd = (st_netfd_t) arg; pds[0].fd = st_netfd_fileno(cli_nfd); pds[0].events = POLLIN; /* Connect to remote host */ if ((sock = socket(PF_INET, SOCK_STREAM, 0)) < 0) { print_sys_error("socket"); goto done; } if ((rmt_nfd = st_netfd_open_socket(sock)) == NULL) { print_sys_error("st_netfd_open_socket"); close(sock); goto done; } if (st_connect(rmt_nfd, (struct sockaddr *)&rmt_addr, sizeof(rmt_addr), -1) < 0) { print_sys_error("st_connect"); st_netfd_close(rmt_nfd); goto done; } pds[1].fd = sock; pds[1].events = POLLIN; /* Now just pump the data through */ for ( ; ; ) { pds[0].revents = 0; pds[1].revents = 0; if (st_poll(pds, 2, -1) <= 0) { print_sys_error("st_poll"); break; } if (pds[0].revents & POLLIN) { if ((n = (int) st_read(cli_nfd, buf, IOBUFSIZE, -1)) <= 0) break; if (st_write(rmt_nfd, buf, n, -1) != n) break; } if (pds[1].revents & POLLIN) { if ((n = (int) st_read(rmt_nfd, buf, IOBUFSIZE, -1)) <= 0) break; if (st_write(cli_nfd, buf, n, -1) != n) break; } } st_netfd_close(rmt_nfd); done: st_netfd_close(cli_nfd); return NULL; }