/* this file is intentionally ugly */ #ifndef __sio_h #define __sio_h #include "config.h" /* synchronized I/O */ #ifdef HAVE_POLL #include #include #else #include #include #include #endif #include "bin.h" #define sio_read 1 #define sio_write 2 #define sio_infinite -1 #define sio_infinity sio_infinite int inline sio_test(bin_t b, int fd) { register int op; #ifdef HAVE_POLL struct pollfd *pf; register int i; int pfnum; pf = (struct pollfd *)caddr(b); if (!pf) return 0; pfnum = (bin_len(b)) / sizeof(struct pollfd); for (i = 0; i < pfnum; i++) { if (pf[i].fd == fd) { op = 0; if (pf[i].revents & (POLLIN|POLLPRI|POLLHUP)) op |= sio_read; if (pf[i].revents & POLLOUT) op |= sio_write; return op; } } return 0; #else fd_set *r, *w; if (caddr(b) == 0) return 0; bin_need(b, sizeof(fd_set) * 2); r = (fd_set *)(caddr(b)); w = (fd_set *)(((char *)caddr(b)) + sizeof(fd_set)); op = 0; if (FD_ISSET(fd, r)) op |= sio_read; if (FD_ISSET(fd, w)) op |= sio_write; return op; #endif } int inline sio_block(bin_t b, int timeout) { #ifdef HAVE_POLL struct pollfd *pf; int pfnum; pf = (struct pollfd *)caddr(b); if (!pf) return 0; pfnum = (bin_len(b)) / sizeof(struct pollfd); return poll(pf, pfnum, timeout); #else fd_set *r, *w; struct timeval tv; int high; if (caddr(b) == 0) return 0; bin_need(b, sizeof(fd_set) * 2); r = (fd_set *)(caddr(b)); w = (fd_set *)(((char *)caddr(b)) + sizeof(fd_set)); high = *(int *)(((char *)caddr(b)) + (sizeof(fd_set)+sizeof(fd_set))); if (timeout < 0) { return select(high+1, r, w, 0, 0); } else { tv.tv_sec = 0; tv.tv_usec = timeout; return select(high+1, r, w, 0, &tv); } #endif } void inline sio_remove(bin_t b, int fd) { #ifdef HAVE_POLL struct pollfd *pf; register int i; int pfnum; pf = (struct pollfd *)caddr(b); if (pf) { pfnum = (bin_len(b)) / sizeof(struct pollfd); for (i = 0; i < pfnum; i++) { if (fd == -1 || pf[i].fd == fd) { pf[i].fd = -1; pf[i].events = 0; pf[i].revents = 0; if (fd != -1) break; } } } #else fd_set *r, *w; register int i; int *high; i = (caddr(b) == 0) ? 1 : 0; bin_need(b, (sizeof(fd_set) * 2) + sizeof(int)); r = (fd_set *)(caddr(b)); w = (fd_set *)(((char *)caddr(b)) + sizeof(fd_set)); high = (int *)(((char *)caddr(b)) + (sizeof(fd_set)+sizeof(fd_set))); if (i || fd == -1) { FD_ZERO(r); FD_ZERO(w); *high = 0; } else { FD_CLR(fd, r); FD_CLR(fd, w); } #endif } void inline sio_flush(bin_t b) { sio_remove(b, -1); } void inline sio_add(bin_t b, int fd, int ops) { #ifdef HAVE_POLL struct pollfd *pf; register int i; int pfnum; if (fd == -1) return; /* search for a -1 */ pf = (struct pollfd *)caddr(b); if (!pf) { i = pfnum = 0; } else { pfnum = (bin_len(b)) / sizeof(struct pollfd); for (i = 0; i < pfnum; i++) { if (pf[i].fd == -1) break; } } if (i == pfnum) { bin_needplus(b, sizeof(struct pollfd)); clen(b) = bin_len(b); /* update length */ pf = (struct pollfd *)caddr(b); } pf[i].fd = fd; pf[i].events = 0; pf[i].revents = 0; if (ops & sio_read) pf[i].events |= (POLLIN|POLLPRI); if (ops & sio_write) pf[i].events |= POLLOUT; #else fd_set *r, *w; register int i; int *high; if (fd == -1) return; i = (caddr(b) == 0) ? 1 : 0; bin_need(b, (sizeof(fd_set) * 2) + sizeof(int)); r = (fd_set *)(caddr(b)); w = (fd_set *)(((char *)caddr(b)) + sizeof(fd_set)); high = (int *)(((char *)caddr(b)) + (sizeof(fd_set)+sizeof(fd_set))); if (i) { FD_ZERO(r); FD_ZERO(w); *high = fd; } else if (fd > *high) *high = fd; if (ops & sio_read) FD_SET(fd, r); if (ops & sio_write) FD_SET(fd, w); #endif } #endif