/* Code taken from the OS/2 port of squid */

#ifndef __OS2_SELECT__
#define __OS2_SELECT__

#include <stdlib.h>
#include <sys/errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/select.h>
#include <sys/time.h>

extern named_select;

int ibm_select( int *fds, int n_read, int n_write, int n_exept, long timeout);

int os2_select (int nfds, fd_set *readfds, fd_set *writefds,fd_set *exceptfds,
                struct timeval *timeout)
/* We are using the EMX select() call if non-socket handlers are presented in sets
   and IBM select() otherwise. EMX select() causes high CPU usage in polling loop. */
{
    fd_set *fds[3] = { readfds, writefds, exceptfds };
    int fd_os2[FD_SETSIZE * 3], fd_emx[FD_SETSIZE * 3];
    int n_fd[4], n = 0;
    int i, k, s;

if (named_select) { /* Solo para named.exe */

	for(k = 0; k < 3; k++) {
		n_fd[k] = n;
		if(!fds[k])
		continue;
		for(i = 0; i < nfds; i++) {
		    if(!fds[k]->fds_bits[i>>5]) {
		        i += 31;
		        continue;
		        }
		    if(!FD_ISSET(i, fds[k]))
		    continue;
		    s = _getsockhandle(i);
		    if(s < 0) {
 		       i=select(nfds, readfds, writefds, exceptfds, timeout);
		       return(i);
		       } else {
		       fd_os2[n] = s;
		       fd_emx[n++] = i;
		       }
		}
	}

	n_fd[3] = n;

	s = ibm_select(fd_os2, n_fd[1]-n_fd[0], n_fd[2]-n_fd[1], n_fd[3]-n_fd[2],
                   timeout->tv_usec/1000 + timeout->tv_sec*1000);

	if(s == 0) return 0;     /* Timeout */

	if(s < 0) {			/* Error */
		if(sock_errno() == 10004)		/* SOCEINTR */
		  _setsyserrno(EINTR);
		  /* errno = EINTR; */
		   else
		   _setsyserrno(EINVAL);
		   /* errno = EINVAL; */
		return -1;
	}

	i = 0;
	for(k = 0; k < 3; k++) {
		n = n_fd[k+1];
		for( ; i < n; i++) if(fd_os2[i] < 0) FD_CLR(fd_emx[i], fds[k]);
		}
	return s;

} else { /* Use EMX select() */
	i=select(nfds, readfds, writefds, exceptfds, timeout);
	return(i);
	}

}
#endif __OS2_SELECT__

