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); } }
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); }
/************************************************************************** write wrapper function -vasc **************************************************************************/ static int write_socket_data(struct connection *pc, struct socket_packet_buffer *buf, int limit) { int start, nput, nblock; if (pc->delayed_disconnect) { if (delayed_disconnect > 0) { return 0; } else { if (close_callback) { (*close_callback)(pc); } return -1; } } for (start=0; buf->ndata-start>limit;) { fd_set writefs, exceptfs; struct timeval tv; MY_FD_ZERO(&writefs); MY_FD_ZERO(&exceptfs); FD_SET(pc->sock, &writefs); FD_SET(pc->sock, &exceptfs); tv.tv_sec = 0; tv.tv_usec = 0; if (fc_select(pc->sock+1, NULL, &writefs, &exceptfs, &tv) <= 0) { if (errno != EINTR) { break; } else { /* EINTR can happen sometimes, especially when compiling with -pg. * Generally we just want to run select again. */ continue; } } if (FD_ISSET(pc->sock, &exceptfs)) { if (delayed_disconnect > 0) { pc->delayed_disconnect = TRUE; return 0; } else { if (close_callback) { (*close_callback)(pc); } return -1; } } if (FD_ISSET(pc->sock, &writefs)) { nblock=MIN(buf->ndata-start, MAX_LEN_PACKET); freelog(LOG_DEBUG,"trying to write %d limit=%d",nblock,limit); if((nput=fc_writesocket(pc->sock, (const char *)buf->data+start, nblock)) == -1) { #ifdef NONBLOCKING_SOCKETS if (errno == EWOULDBLOCK || errno == EAGAIN) { break; } #endif if (delayed_disconnect > 0) { pc->delayed_disconnect = TRUE; return 0; } else { if (close_callback) { (*close_callback)(pc); } return -1; } } start += nput; } } if (start > 0) { buf->ndata -= start; memmove(buf->data, buf->data+start, buf->ndata); pc->last_write = renew_timer_start(pc->last_write, TIMER_USER, TIMER_ACTIVE); } return 0; }
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 }
/* 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 */
/************************************************************************** A wrapper around read_socket_data() which also handles the case the socket becomes writeable and there is still data which should be sent to the server. Returns: -1 : an error occurred - you should close the socket >0 : number of bytes read =0 : no data read, would block **************************************************************************/ static int read_from_connection(struct connection *pc, bool block) { for (;;) { fd_set readfs, writefs, exceptfs; int socket_fd = pc->sock; bool have_data_for_server = (pc->used && pc->send_buffer && pc->send_buffer->ndata > 0); int n; struct timeval tv; tv.tv_sec = 0; tv.tv_usec = 0; MY_FD_ZERO(&readfs); FD_SET(socket_fd, &readfs); MY_FD_ZERO(&exceptfs); FD_SET(socket_fd, &exceptfs); if (have_data_for_server) { MY_FD_ZERO(&writefs); FD_SET(socket_fd, &writefs); n = fc_select(socket_fd + 1, &readfs, &writefs, &exceptfs, block ? NULL : &tv); } else { n = fc_select(socket_fd + 1, &readfs, NULL, &exceptfs, block ? NULL : &tv); } /* the socket is neither readable, writeable nor got an exception */ if (n == 0) { return 0; } if (n == -1) { if (errno == EINTR) { /* EINTR can happen sometimes, especially when compiling with -pg. * Generally we just want to run select again. */ freelog(LOG_DEBUG, "select() returned EINTR"); continue; } freelog(LOG_ERROR, "select() return=%d errno=%d (%s)", n, errno, fc_strerror(fc_get_errno())); return -1; } if (FD_ISSET(socket_fd, &exceptfs)) { return -1; } if (have_data_for_server && FD_ISSET(socket_fd, &writefs)) { flush_connection_send_buffer_all(pc); } if (FD_ISSET(socket_fd, &readfs)) { return read_socket_data(socket_fd, pc->buffer); } } }