/* * set and clear entries in the select array .. */ static void select_update_selectfds(rb_fde_t *F, short event, PF * handler) { /* Update the read / write set */ if (event & RB_SELECT_READ) { if (handler) { MY_FD_SET(F->fd, &select_readfds); F->pflags |= RB_SELECT_READ; } else { MY_FD_CLR(F->fd, &select_readfds); F->pflags &= ~RB_SELECT_READ; } } if (event & RB_SELECT_WRITE) { if (handler) { MY_FD_SET(F->fd, &select_writefds); F->pflags |= RB_SELECT_WRITE; } else { MY_FD_CLR(F->fd, &select_writefds); F->pflags &= ~RB_SELECT_WRITE; } } if (F->pflags & (RB_SELECT_READ | RB_SELECT_WRITE)) { if (F->fd > rb_maxfd) rb_maxfd = F->fd; } else if (F->fd <= rb_maxfd) { while (rb_maxfd >= 0 && !FD_ISSET(rb_maxfd, &select_readfds) && !FD_ISSET(rb_maxfd, &select_writefds)) rb_maxfd--; } }
unsigned long do_select() { int max = -1, i, rc; struct timeval ts; struct timeval start, end; int fd; MY_FD_ZERO(rdset, rdset_nbytes); for(i = 0; i < ncur - 1; i++) { fd = fds[i]; MY_FD_SET(fd, rdset); } fd = fds[nceil - 1]; MY_FD_SET(fd, rdset); max = fds[nceil - 1] + 1; ts.tv_sec = TIMEOUT_SEC; ts.tv_usec = 0; gettimeofday(&start, NULL); rc = select(max, (fd_set *)rdset, NULL, NULL, &ts); gettimeofday(&end, NULL); switch(rc) { case -1: fprintf(stderr, "select failed: %s\n", strerror(errno)); break; case 0: fprintf(stderr, "select timed out\n"); break; default: //fprintf(stderr, "%d fds are ready for reading.\n", rc); for(i = 0; i < ncur - 1; i++) { fd = fds[i]; if(MY_FD_ISSET(fd, rdset)) { read(fds[i], buf, READ_SIZE); } } fd = fds[nceil - 1]; if(MY_FD_ISSET(fd, rdset)) { read(fds[nceil - 1], buf, READ_SIZE); } break; } return (end.tv_sec - start.tv_sec) * 1000000 + (end.tv_usec - start.tv_usec); }
int USendto(int sfd, const char *const buf, size_t size, int fl, const struct sockaddr_un *const toAddr, int ualen, int tlen) { send_return_t nwrote; int tleft; time_t done, now; fd_set ss; struct timeval tv; int result; DECL_SIGPIPE_VARS if ((buf == NULL) || (size == 0) || (toAddr == NULL) || (tlen <= 0)) { errno = EINVAL; return (-1); } time(&now); done = now + tlen; nwrote = 0; forever { forever { if (now >= done) { errno = ETIMEDOUT; SETWSATIMEOUTERR return (kTimeoutErr); } tleft = (done > now) ? ((int) (done - now)) : 0; errno = 0; MY_FD_ZERO(&ss); #if defined(__DECC) || defined(__DECCXX) #pragma message save #pragma message disable trunclongint #endif MY_FD_SET(sfd, &ss); #if defined(__DECC) || defined(__DECCXX) #pragma message restore #endif tv.tv_sec = (tv_sec_t) tleft; tv.tv_usec = 0; result = select(sfd + 1, NULL, SELECT_TYPE_ARG234 &ss, NULL, SELECT_TYPE_ARG5 &tv); if (result >= 1) { /* ready */ break; } else if (result == 0) { /* timeout */ errno = ETIMEDOUT; SETWSATIMEOUTERR return (kTimeoutErr); } else if (errno != EINTR)
int is_ready() { struct timeval tv; int fd; MY_FD_ZERO(rdset, rdset_nbytes); fd = fds[nceil -1]; MY_FD_SET(fd, rdset); tv.tv_sec = 1; tv.tv_usec = 0; return (1 == select(fd + 1, (fd_set *)rdset, NULL, NULL, &tv)); }
int SRecvfrom(int sfd, char *const buf, size_t size, int fl, struct sockaddr_in *const fromAddr, int tlen) { recv_return_t nread; int tleft; fd_set ss; struct timeval tv; int result; time_t done, now; sockaddr_size_t alen; DECL_SIGPIPE_VARS if ((buf == NULL) || (size == 0) || (fromAddr == NULL) || (tlen <= 0)) { errno = EINVAL; return (-1); } time(&now); done = now + tlen; tleft = (done > now) ? ((int) (done - now)) : 0; nread = 0; forever { alen = (sockaddr_size_t) sizeof(struct sockaddr_in); forever { errno = 0; MY_FD_ZERO(&ss); #if defined(__DECC) || defined(__DECCXX) #pragma message save #pragma message disable trunclongint #endif MY_FD_SET(sfd, &ss); #if defined(__DECC) || defined(__DECCXX) #pragma message restore #endif tv.tv_sec = (tv_sec_t) tleft; tv.tv_usec = 0; result = select(sfd + 1, SELECT_TYPE_ARG234 &ss, NULL, NULL, SELECT_TYPE_ARG5 &tv); if (result >= 1) { /* ready */ break; } else if (result == 0) { /* timeout */ errno = ETIMEDOUT; SETWSATIMEOUTERR return (kTimeoutErr); } else if (errno != EINTR) { return (-1); } }
void SelectSetAdd(SelectSetPtr const ssp, const int fd) { if (fd >= 0) { #if defined(__DECC) || defined(__DECCXX) #pragma message save #pragma message disable trunclongint #endif MY_FD_SET(fd, &ssp->fds); #if defined(__DECC) || defined(__DECCXX) #pragma message restore #endif if (ssp->maxfd < (fd + 1)) ssp->maxfd = (fd + 1); ++ssp->numfds; } } /* SelectSetAdd */
void tcpip_task( void *dummy) { /* wait for an IO signal, find out what is happening and * call the right routine to handle the situation. */ fd_set rfds, *pfds; #ifndef __linux__ fd_set efds; #endif int conn_id, ret, count; #ifndef WIN32 int data; #endif if(dummy){} while(1) { while(!DIM_IO_valid) dim_usleep(1000); list_to_fds( &rfds ); MY_FD_ZERO(&efds); #ifdef WIN32 pfds = &efds; #else pfds = &rfds; #endif MY_FD_SET( DIM_IO_path[0], pfds ); #ifdef __linux__ ret = poll(Pollfds, Pollfd_size, -1); #else ret = select(FD_SETSIZE, &rfds, NULL, &efds, NULL); #endif if(ret <= 0) { printf("poll returned %d, errno %d\n", ret, errno); } if(ret > 0) { if(MY_FD_ISSET(DIM_IO_path[0], pfds) ) { #ifndef WIN32 read(DIM_IO_path[0], &data, 4); DIM_IO_Done = 0; #endif MY_FD_CLR( (unsigned)DIM_IO_path[0], pfds ); } /* { DISABLE_AST */ conn_id = 0; while( (ret = fds_get_entry( &rfds, &conn_id )) > 0 ) { if( Net_conns[conn_id].reading ) { count = 0; do { DISABLE_AST if(Net_conns[conn_id].channel) { do_read( conn_id ); count = get_bytes_to_read(conn_id); } else { count = 0; } ENABLE_AST }while(count > 0 ); } else { DISABLE_AST do_accept( conn_id ); ENABLE_AST } MY_FD_CLR( (unsigned)Net_conns[conn_id].channel, &rfds ); } /* ENABLE_AST } */ #ifndef WIN32 return; #endif }
void Selector::add_fd( int fd, IO_FUNC interest ) { // update max_fd (the highest valid index in fd_set's array) and also // make sure we're not overflowing our fd_set // On Windows, we have to check the individual fd_set to see if it's // full. if( fd > max_fd ) { max_fd = fd; } #if !defined(WIN32) if ( fd < 0 || fd >= fd_select_size() ) { EXCEPT( "Selector::add_fd(): fd %d outside valid range 0-%d", fd, _fd_select_size-1 ); } #endif if(IsDebugLevel(D_DAEMONCORE)) { char *fd_description = describe_fd(fd); dprintf(D_DAEMONCORE | D_VERBOSE, "selector %p adding fd %d (%s)\n", this, fd, fd_description); free(fd_description); } bool new_fd = false; if ((m_single_shot == SINGLE_SHOT_OK) && (m_poll.fd != fd)) { new_fd = true; } m_poll.fd = fd; switch( interest ) { case IO_READ: #if defined(WIN32) if ( save_read_fds->fd_count >= fd_select_size() ) { EXCEPT( "Selector::add_fd(): read fd_set is full" ); } #endif m_poll.events |= POLLIN; MY_FD_SET( fd, save_read_fds ); break; case IO_WRITE: #if defined(WIN32) if ( save_write_fds->fd_count >= fd_select_size() ) { EXCEPT( "Selector::add_fd(): write fd_set is full" ); } #endif m_poll.events |= POLLOUT; MY_FD_SET( fd, save_write_fds ); break; case IO_EXCEPT: #if defined(WIN32) if ( save_except_fds->fd_count >= fd_select_size() ) { EXCEPT( "Selector::add_fd(): except fd_set is full" ); } #endif m_poll.events |= POLLERR; MY_FD_SET( fd, save_except_fds ); break; } if ((m_single_shot == SINGLE_SHOT_VIRGIN) || ((m_single_shot == SINGLE_SHOT_OK) && (new_fd == false))) { m_single_shot = SINGLE_SHOT_OK; } else { m_single_shot = SINGLE_SHOT_SKIP; } }
/* The purpose of this is to provide updates for the progress meters * during lags. Return zero if the operation timed-out. */ int WaitForRemoteOutput(const FTPCIPtr cip) { fd_set ss, ss2; struct timeval tv; int result; int fd; int wsecs; int xferTimeout; int ocancelXfer; xferTimeout = cip->xferTimeout; if (xferTimeout < 1) return (1); fd = cip->dataSocket; if (fd < 0) return (1); if (cip->dataTimedOut > 0) { cip->dataTimedOut++; return (0); /* already timed-out */ } ocancelXfer = cip->cancelXfer; wsecs = 0; cip->stalled = 0; while ((xferTimeout <= 0) || (wsecs < xferTimeout)) { if ((cip->cancelXfer != 0) && (ocancelXfer == 0)) { /* leave cip->stalled -- could have been stalled and then canceled. */ return (1); } MY_FD_ZERO(&ss); #if defined(__DECC) || defined(__DECCXX) #pragma message save #pragma message disable trunclongint #endif MY_FD_SET(fd, &ss); #if defined(__DECC) || defined(__DECCXX) #pragma message restore #endif ss2 = ss; tv.tv_sec = 1; tv.tv_usec = 0; result = select(fd + 1, NULL, SELECT_TYPE_ARG234 &ss, SELECT_TYPE_ARG234 &ss2, &tv); if (result >= 1) { /* ready */ cip->stalled = 0; return (1); } else if (result < 0) { if (errno != EINTR) { cip->stalled = 0; return (1); /* Ready to read error */ } } else { wsecs++; cip->stalled = wsecs; } FTPUpdateIOTimer(cip); } #if !defined(NO_SIGNALS) /* Shouldn't get here -- alarm() should have * went off by now. */ (void) kill(getpid(), SIGALRM); #endif /* NO_SIGNALS */ cip->dataTimedOut++; return (0); /* timed-out */ } /* WaitForRemoteOutput */