/*
 * selectExample.c
 *
 * select example ...
 *
 * This is intended as a simple intro to the select call.
 * Basic idea here is that use it to demultipex access to
 * two descriptors, one socket, and one serial terminal
 * simultaneously.
 *
 * On solaris, man -s 3c select
 *
 * On freebsd, man 2 select
 *
 * for more info.  See Steven's programming books for better
 * information.
 * 
 */
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <sys/time.h>

#include <stdio.h>
#include <ctype.h>
#include <errno.h>
#include <signal.h>

/*
 * bit masks for manipulating select masks.
 * (may be available somewhere in include files; look around)
 *
 * On sun: read sys/types.h...
 *
 *	set - set one bit
 *	clr - clear one bit
 *	isset - test one bit
 *	zero - zero the mask
 */
#ifdef OLDMACRODEFSNOTUSEDNOW
#define	FD_SET(n, p)	((p)->fds_bits[0] |= (1<<(n)))
#define	FD_CLR(n, p)	((p)->fds_bits[0] &= ~(1<<(n)))
#define	FD_ISSET(n, p)	((p)->fds_bits[0] & (1<<(n)))
#define FD_ZERO(p)	((p)->fds_bits[0] = 0)
#endif

/*
 * select from socket or tty descriptor
 */
doSelect (sock, tty)
int sock;
int tty;
{
	int noquit = 0;		/* number of connections terminated */
	static struct timeval timeout = { 0 };
	extern int errno;
	int newsock;
	fd_set	readbits;	/* read mask for select input */
	fd_set	readers;	/* mask for current connected sockets */
	int i;
	struct sockaddr_in peer;
	int size;
	int rc;

	while(1) {

		FD_ZERO(&readbits);
		FD_SET(sock, &readbits);
		FD_SET(tty, &readbits);

		/******************************************* 
		 * make select call, timeout set to 0, so we will block
		 */
		rc = select(getdtablesize(), (fd_set *)&readbits, 
				(fd_set *)0, 
				(fd_set *)0, 
				0);
				/*
				&timeout);
				*/

		/* if timeout was used, and occured, select returns 0
		*/
		if ( rc == 0 ) {
			/*
			timeout...
			*/
		}
		else if (rc < 0) {
			/* received a signal like SIGALRM, ignore
			*/
			if (errno == EINTR) {
					continue;
			}
			fprintf(stderr,"select error %s %d\n", __FILE__, __LINE__);
			perror("select");
			exit(1);
		}

		/* 
		 * check tty descriptor, note this could be listen
		 * socket, if paired with TCP,
	         */ 
		if (FD_ISSET(tty, &readbits)) {
			/*
			read on tty...  or possibly accept
			*/
			break;
		}
		if (FD_ISSET(sock, &readbits)) {
			/*
			read on sock...
			*/
			break;
		}
	}
}


