static inline int32_t block_read_n(int fd, void* buf, int32_t size, int32_t timeout) { int exit_loop = 0; int revents = 0; int32_t next_to = -1; int32_t read_size = 0; int32_t total_read_size = 0; struct timespec abs_to; abs_to = get_abs_time(timeout); total_read_size = 0; exit_loop = 0; do { next_to = get_rel_time(&abs_to); if((timeout > 0 && next_to <= 0)) { set_errno(MQ_ETIMEDOUT); total_read_size = -1; exit_loop = 1; } else { revents = wait_fd(fd, POLLIN, (timeout <= 0 ? timeout : next_to)); switch (revents) { case POLLIN: do { read_size = read(fd, buf + total_read_size, size - total_read_size); }while(read_size < 0 && errno == EINTR); switch (read_size) { case -1: /* ERROR */ total_read_size = -1; case 0: /* EOF */ exit_loop = 1; break; default: total_read_size += read_size; break; } break; case 0: set_errno(MQ_ETIMEDOUT); total_read_size = -1; exit_loop = 1; break; default: /* other revents or error */ total_read_size = -1; exit_loop = 1; break; } } }while(!exit_loop && (total_read_size < size) && timeout != 0); return total_read_size; }
int do_server (const char *hostname, int port) { int rc, rce, sok, ip = -1; socklen_t length; struct sockaddr_in sin; struct hostent *host; errno = 0; sok = socket (AF_INET, SOCK_STREAM, 0); assert (sok >= 0); #if HAVE_FCNTL rc = fcntl (sok, F_GETFL, 0); if (rc != -1) rc = fcntl (sok, F_SETFL, rc | O_NONBLOCK); #endif assert (rc != -1); sin.sin_family = AF_INET; sin.sin_port = htons (port); if (hostname) ip = htonl (inet_addr (hostname)); if (ip + 1 == 0 && hostname) { host = gethostbyname (hostname); assert (host); sin.sin_addr = *((struct in_addr *) host->h_addr); ip = ntohl (sin.sin_addr.s_addr); } sin.sin_addr.s_addr = htonl (ip); rc = connect (sok, (struct sockaddr *) &sin, sizeof (struct sockaddr)); rce = rc < 0 ? errno : 0; length = sizeof (struct sockaddr); getsockname (sok, (struct sockaddr *) &sin, &length); if (rc >= 0) return sok; #if !defined(EINPROGRESS) #define EINPROGRESS 1 rce = 1; #endif assert (rce == EINPROGRESS); wait_fd (sok, 6, 0); length = sizeof (int); #ifdef SO_ERROR if (getsockopt (sok, SOL_SOCKET, SO_ERROR, (void *)&rc, &length) < 0) #endif rc = errno; assert (!rc); return sok; }
ssize_t timed_read(int sockfd, void* buf, size_t count, int timeout_ms) { ssize_t rv; set_non_blocking(sockfd); do { if (0 <= (rv = wait_fd(sockfd, timeout_ms))) rv = read(sockfd, buf, count); } while (errno == EINTR); set_blocking(sockfd); return rv; }
int read_all_data (int fd, char *buf, int *index, int *reported, int size, int out) { int ret, len; if (fd < 0) return 1; while (1) { ret = wait_fd (fd, 1, 250000); if (!ret) return 0; assert (size > *index + 10); len = read (fd, buf + *index, size - *index); if (!len) return 1; ret = errno; if (len == -1 && ret == ECONNRESET) assert (len > 0); *index += len; assert (*index >= *reported); while (*index - *reported >= 6) { len = get_len (buf + *reported); if (*index - *reported < 6 + len) break; printf ("Received %s (%d,%d) (0x%x,0x%x) from %s (6+%u bytes).\n", buf[*reported + 1] == 2 ? "SNAC" : "FLAP", buf[*reported + 7], buf[*reported + 9], buf[*reported + 7], buf[*reported + 9], out ? "server" : "client", len); *reported += len + 6; } if (*index > *reported) { printf ("Received %d unreported bytes.\n", *index - *reported); for (len = *reported; len < *index; len++) { printf ("<%x|%c> ", buf[len], buf[len]); if (!(len % 8)) printf ("\n"); } if ((len - 1) % 8) printf ("\n"); } } }
int do_accept (int fd) { int sok; struct sockaddr_in sin; socklen_t length; int rc; wait_fd (fd, 1, 0); length = sizeof (sin); sok = accept (fd, (struct sockaddr *)&sin, &length); assert (sok > 0); #if HAVE_FCNTL rc = fcntl (sok, F_GETFL, 0); if (rc != -1) rc = fcntl (sok, F_SETFL, rc | O_NONBLOCK); #endif assert (rc != -1); return sok; }
static inline int32_t nonblock_write_n(int fd, const void* buf, int32_t size, int32_t timeout) { int exit_loop = 0; int revents = 0; int32_t next_to = -1; int32_t write_size = 0; int32_t total_write_size = 0; struct timespec abs_to; abs_to = get_abs_time(timeout); total_write_size = 0; exit_loop = 0; do { write_size = write(fd, buf + total_write_size, size - total_write_size); if(write_size > 0) { total_write_size += write_size; } else if(write_size == 0) /* nothing was writen */ { exit_loop = 1; } else /* write_size < 0 */ { switch(errno) { case EINTR: continue; break; case EAGAIN: next_to = get_rel_time(&abs_to); if((timeout == 0) || (timeout > 0 && next_to <= 0)) { set_errno(MQ_ETIMEDOUT); total_write_size = -1; exit_loop = 1; } else { revents = wait_fd(fd, POLLOUT, (timeout < 0 ? timeout : next_to)); if(revents == POLLOUT) { continue; } else if(revents == 0) { set_errno(MQ_ETIMEDOUT); total_write_size = -1; exit_loop = 1; } else /* other revents or error */ { total_write_size = -1; exit_loop = 1; } } break; default: total_write_size = -1; exit_loop = 1; break; } /* switch(errno) */ } /* write_size < 0 */ }while(!exit_loop && (total_write_size < size) && timeout != 0); return total_write_size; }
static inline int32_t block_write_n(int fd, const void* buf, int32_t size, int32_t timeout) { int exit_loop = 0; int revents = 0; int32_t next_to = -1; int32_t write_size = 0; int32_t total_write_size = 0; struct timespec abs_to; abs_to = get_abs_time(timeout); total_write_size = 0; exit_loop = 0; do { next_to = get_rel_time(&abs_to); if((timeout > 0 && next_to <= 0)) { set_errno(MQ_ETIMEDOUT); total_write_size = -1; exit_loop = 1; } else { revents = wait_fd(fd, POLLOUT, (timeout <= 0 ? timeout : next_to)); if(revents == POLLOUT) { do { write_size = write(fd, buf + total_write_size, size - total_write_size); }while(write_size < 0 && errno == EINTR); if(write_size > 0) { total_write_size += write_size; } else if(write_size == 0) /* nothing was written */ { exit_loop = 1; } else /* write_size < 0 */ { total_write_size = -1; exit_loop = 1; } } else if(revents == 0) { set_errno(MQ_ETIMEDOUT); total_write_size = -1; exit_loop = 1; } else /* other revents or error */ { total_write_size = -1; exit_loop = 1; } } }while(!exit_loop && (total_write_size < size) && timeout != 0); return total_write_size; }
static inline int32_t nonblock_read_n(int fd, void* buf, int32_t size, int32_t timeout) { int exit_loop = 0; int revents = 0; int32_t next_to = -1; int32_t read_size = 0; int32_t total_read_size = 0; struct timespec abs_to; abs_to = get_abs_time(timeout); total_read_size = 0; exit_loop = 0; do { read_size = read(fd, buf + total_read_size, size - total_read_size); switch (read_size) { case -1: switch(errno) { case EINTR: continue; break; case EAGAIN: next_to = get_rel_time(&abs_to); if((timeout == 0) || (timeout > 0 && next_to <= 0)) { set_errno(MQ_ETIMEDOUT); total_read_size = -1; exit_loop = 1; } else { revents = wait_fd(fd, POLLIN, (timeout < 0 ? timeout : next_to)); switch (revents) { case POLLIN: continue; case 0: set_errno(MQ_ETIMEDOUT); total_read_size = -1; exit_loop = 1; break; default: /* other revents or error */ total_read_size = -1; exit_loop = 1; break; } } break; default: total_read_size = -1; exit_loop = 1; break; } /* switch(errno) */ break; case 0: exit_loop = 1; break; default: total_read_size += read_size; break; } }while(!exit_loop && (total_read_size < size) && timeout != 0); return total_read_size; }