/* exp_poll.c - poll() interface for Expect Written by: Don Libes, NIST, 2/6/90 Design and implementation of this program was paid for by U.S. tax dollars. Therefore it is public domain. However, the author and NIST would appreciate credit if this program or parts of it are used. */ /* This file contains code designed to work on SVR>=3 systems. The logic closely parallels interact_select.c. If your system supports select, you may use that file instead, however some SV systems (e.g., HPUX) implement select incorrectly, so I would recommend using poll. */ #include "exp_conf.h" #include #include #include #ifdef HAVE_UNISTD_H # include #endif #include "tcl.h" #include "exp_global.h" #include "exp_command.h" #include "exp_event.h" static struct pollfd *fds; static int maxfds; /*ARGSUSED*/ void exp_event_disarm(fd) int fd; { } /* this returns a printable representation of a poll revent. I only have */ /* to handle the ones that occurs when event is set to 0. */ static char * bad_poll_type(x) int x; { static char msg[30]; switch (x) { case POLLERR: return("POLLERR"); case POLLHUP: return("POLLHUP"); case POLLNVAL: return("POLLNVAL"); default: sprintf(msg,"unknown poll event (%d)",x); return(msg); } } /* returns status, one of EOF, TIMEOUT, ERROR or DATA */ int exp_get_next_event(interp,masters, n,master_out,timeout,key) Tcl_Interp *interp; int *masters; int n; int *master_out; /* out variable */ int timeout; int key; { static rr = 0; /* round robin ptr */ int msec; /* milliseconds to wait */ int i; /* index into in-array */ int pc; for (i=0;i= n) rr = 0; m = masters[rr]; f = fs + m; if (f->key != key) { f->key = key; f->force_read = FALSE; *master_out = m; return(EXP_DATA_OLD); } else if ((!f->force_read) && (f->size != 0)) { *master_out = m; return(EXP_DATA_OLD); } } msec = ((timeout == -1)?-1:(1000 * timeout)); if (n > maxfds) { if (fds) free((char *)fds); fds = (struct pollfd *)malloc(n*sizeof(struct pollfd)); if (!fds) { fds = 0; exp_error(interp,"failed to malloc %d pollfds",n); return(EXP_TCLERROR); } maxfds = n; } for (i = 0;i < n;i++) { fds[i].fd = masters[i]; fds[i].events = POLLIN; /* apparently, no need to clear revents */ } pc = poll(fds,n,msec); if (pc > 0) { for (i=0;i= n) rr = 0; /* ">" catches previous readys that */ /* used more fds then we're using now */ if (fds[rr].revents) { if (fds[rr].revents & POLLIN) { *master_out = masters[rr]; return(EXP_DATA_NEW); } else { exp_debuglog(interp,"poll[%d].revent = %s\r\n", fds[masters[rr]], bad_poll_type(fds[rr].revents)); return(EXP_EOF); } } } } else if (pc == 0) { return(EXP_TIMEOUT); } else if (errno != EBADF) { /* someone is rotten */ for (i=0;i