/* this file is intentionally ugly */
#ifndef __sio_h
#define __sio_h
#include "config.h"
/* synchronized I/O */
#ifdef HAVE_POLL
#include <sys/types.h>
#include <sys/poll.h>
#else
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#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
syntax highlighted by Code2HTML, v. 0.9.1