ExtFunc long CurTimeval(void) { struct timeval tv; gettimeofday(&tv, NULL); tv.tv_sec -= baseTimeval.tv_sec; tv.tv_usec -= baseTimeval.tv_usec; return GetTimeval(&tv); }
static long SetITimer1(long interval, long value) { struct itimerval it, old; SetTimeval(&it.it_interval, interval); SetTimeval(&it.it_value, value); if (setitimer(ITIMER_REAL, &it, &old) < 0) die("setitimer"); signal(SIGALRM, CatchAlarm); return GetTimeval(&old.it_value); }
static int Poll(AG_NetSocketSet *nsInput, AG_NetSocketSet *nsRead, AG_NetSocketSet *nsWrite, AG_NetSocketSet *nsExcept, Uint32 timeout) { fd_set readFds, writeFds, exceptFds; AG_NetSocket *ns; struct timeval tv; int maxfd = 0, count; long rv; TAILQ_FOREACH(ns, nsInput, sockets) if (ns->poll != 0 && ns->fd > maxfd) maxfd = ns->fd; poll: if (nsRead) { TAILQ_INIT(nsRead); FD_ZERO(&readFds); } if (nsWrite) { TAILQ_INIT(nsWrite); FD_ZERO(&writeFds); } if (nsExcept) { TAILQ_INIT(nsExcept); FD_ZERO(&exceptFds); } TAILQ_FOREACH(ns, nsInput, sockets) { if (nsRead && (ns->poll & AG_NET_POLL_READ)) FD_SET(ns->fd, &readFds); if (nsWrite && (ns->poll & AG_NET_POLL_WRITE)) FD_SET(ns->fd, &writeFds); if (nsExcept && (ns->poll & AG_NET_POLL_EXCEPTIONS)) FD_SET(ns->fd, &exceptFds); } if (timeout != 0) { GetTimeval(&tv, timeout); } AG_MutexLock(&agNetWin32Lock); rv = select(maxfd+1, nsRead ? &readFds : NULL, nsWrite ? &writeFds : NULL, nsExcept ? &exceptFds : NULL, (timeout != 0) ? &tv : NULL); if (rv == SOCKET_ERROR) { if (WSAGetLastError() == WSAEINTR) { AG_MutexUnlock(&agNetWin32Lock); goto poll; } AG_SetError("select: failed (%d)", WSAGetLastError()); count = -1; goto out; } else if (rv == 0) { count = 0; goto out; } count = 0; TAILQ_FOREACH(ns, nsInput, sockets) { if (nsRead && FD_ISSET(ns->fd, &readFds)) { TAILQ_INSERT_TAIL(nsRead, ns, read); count++; } if (nsWrite && FD_ISSET(ns->fd, &writeFds)) { TAILQ_INSERT_TAIL(nsWrite, ns, write); count++; } if (nsExcept && FD_ISSET(ns->fd, &exceptFds)) { TAILQ_INSERT_TAIL(nsExcept, ns, except); count++; } } out: AG_MutexUnlock(&agNetWin32Lock); return (count); }
static int Poll(AG_NetSocketSet *nsInput, AG_NetSocketSet *nsRead, AG_NetSocketSet *nsWrite, AG_NetSocketSet *nsExcept, Uint32 timeout) { #ifdef HAVE_SELECT fd_set readFds, writeFds, exceptFds; AG_NetSocket *ns; struct timeval tv; int maxfd = 0, rv, count; TAILQ_FOREACH(ns, nsInput, sockets) if (ns->poll != 0 && ns->fd > maxfd) maxfd = ns->fd; poll: if (nsRead) { TAILQ_INIT(nsRead); FD_ZERO(&readFds); } if (nsWrite) { TAILQ_INIT(nsWrite); FD_ZERO(&writeFds); } if (nsExcept) { TAILQ_INIT(nsExcept); FD_ZERO(&exceptFds); } TAILQ_FOREACH(ns, nsInput, sockets) { if (nsRead && (ns->poll & AG_NET_POLL_READ)) FD_SET(ns->fd, &readFds); if (nsWrite && (ns->poll & AG_NET_POLL_WRITE)) FD_SET(ns->fd, &writeFds); if (nsExcept && (ns->poll & AG_NET_POLL_EXCEPTIONS)) FD_SET(ns->fd, &exceptFds); } if (timeout != 0) { GetTimeval(&tv, timeout); } rv = select(maxfd+1, nsRead ? &readFds : NULL, nsWrite ? &writeFds : NULL, nsExcept ? &exceptFds : NULL, (timeout != 0) ? &tv : NULL); if (rv == -1) { if (errno == EINTR) { goto poll; } AG_SetError("select: %s", strerror(errno)); return (-1); } else if (rv == 0) { return (0); } count = 0; TAILQ_FOREACH(ns, nsInput, sockets) { if (nsRead && FD_ISSET(ns->fd, &readFds)) { TAILQ_INSERT_TAIL(nsRead, ns, read); count++; } if (nsWrite && FD_ISSET(ns->fd, &writeFds)) { TAILQ_INSERT_TAIL(nsWrite, ns, write); count++; } if (nsExcept && FD_ISSET(ns->fd, &exceptFds)) { TAILQ_INSERT_TAIL(nsExcept, ns, except); count++; } } return (count); #else AG_SetError("select() is not available"); return (-1); #endif /* !HAVE_SELECT */ }
static int SetOption(AG_NetSocket *ns, enum ag_net_socket_option so, const void *p) { #ifdef HAVE_SETSOCKOPT int rv = 0; switch (so) { case AG_NET_BACKLOG: ns->listenBacklog = *(const int *)p; break; case AG_NET_DEBUG: case AG_NET_REUSEADDR: case AG_NET_KEEPALIVE: case AG_NET_DONTROUTE: case AG_NET_BROADCAST: case AG_NET_SNDBUF: case AG_NET_RCVBUF: case AG_NET_SNDLOWAT: case AG_NET_RCVLOWAT: rv = setsockopt(ns->fd, SOL_SOCKET, agSockOptionMap[so], p, sizeof(int)); break; case AG_NET_SNDTIMEO: case AG_NET_RCVTIMEO: { Uint32 Tms = *(const Uint32 *)p; struct timeval tv; GetTimeval(&tv, Tms); rv = setsockopt(ns->fd, SOL_SOCKET, agSockOptionMap[so], &tv, sizeof(struct timeval)); } break; #ifdef HAVE_SO_OOBINLINE case AG_NET_OOBINLINE: rv = setsockopt(ns->fd, SOL_SOCKET, SO_OOBINLINE, p, sizeof(int)); break; #endif #ifdef HAVE_SO_REUSEPORT case AG_NET_REUSEPORT: rv = setsockopt(ns->fd, SOL_SOCKET, SO_REUSEPORT, p, sizeof(int)); break; #endif #ifdef HAVE_SO_TIMESTAMP case AG_NET_TIMESTAMP: rv = setsockopt(ns->fd, SOL_SOCKET, SO_TIMESTAMP, p, sizeof(int)); break; #endif #ifdef HAVE_SO_NOSIGPIPE case AG_NET_NOSIGPIPE: rv = setsockopt(ns->fd, SOL_SOCKET, SO_NOSIGPIPE, p, sizeof(int)); break; #endif #ifdef HAVE_SO_LINGER case AG_NET_LINGER: { int val = *(const int *)p; struct linger ling; ling.l_onoff = (val > 0); ling.l_linger = val; rv = setsockopt(ns->fd, SOL_SOCKET, SO_LINGER, &ling, sizeof(struct linger)); } break; #endif #ifdef HAVE_SO_ACCEPTFILTER case AG_NET_ACCEPTFILTER: { const AG_NetAcceptFilter *naf = (const AG_NetAcceptFilter *)p; struct accept_filter_arg afa; Strlcpy(afa.af_name, naf->name, sizeof(afa.af_name)); Strlcpy(afa.af_arg, naf->arg, sizeof(afa.af_arg)); rv = setsockopt(ns->fd, SOL_SOCKET, SO_ACCEPTFILTER, &afa, sizeof(struct accept_filter_arg)); } break; #endif default: AG_SetError("Bad socket option"); return (-1); } if (rv != 0) { AG_SetError("setsockopt: %s", strerror(errno)); return (-1); } return (0); #else AG_SetError("setsockopt() is not available"); return (-1); #endif /* !HAVE_SETSOCKOPT */ }