int sock_init(char *ip, int port, struct sockaddr_in *addr) { int sockfd = -1; int optval = 1; if ( port < 1024) return NG; bzero(addr, sizeof(struct sockaddr)); sockfd = x_socket(AF_INET, SOCK_DGRAM, 0); addr->sin_family = AF_INET; addr->sin_port = htons(port); if (ip == NULL) { addr->sin_addr.s_addr = htonl(INADDR_ANY); x_bind(sockfd, (SA *)addr, sizeof(struct sockaddr)); printf("bind OK\n"); } else { Inet_pton(AF_INET, ip, &(addr->sin_addr)); x_connect(sockfd, (SA *)addr, sizeof(struct sockaddr)); } x_setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(int)); return sockfd; }
/* this avoids blocking without using non-blocking i/o */ static int wait_for_it(int sd, int timeoutseconds) { fd_set readfds; struct timeval tv; int ready_descriptors; int maxfd; int xfd; struct timeval time_now; struct timeval time_out; gettimeofday(&time_now, NULL); memcpy(&time_out, &time_now, sizeof(struct timeval)); time_out.tv_sec += timeoutseconds; xfd = x_socket(); maxfd = max(sd, xfd); do { do { ProcessPendingEvents(); gettimeofday(&time_now, NULL); tv.tv_sec = max(time_out.tv_sec - time_now.tv_sec + 1, (time_t) 0); /* sloppy, but bfd */ tv.tv_usec = 0; /* select will return if we have X stuff or we have comm stuff on sd */ FD_ZERO(&readfds); FD_SET(sd, &readfds); // FD_SET(xfd, &readfds); ready_descriptors = select(maxfd + 1, &readfds, NULL, NULL, &tv); // DMA(DEBUG_INFO, // "select %d/%d returned %d descriptor, %d\n", // sd, timeoutseconds, ready_descriptors, FD_ISSET(sd, &readfds)); } while(tv.tv_sec > 0 && (!FD_ISSET(sd, &readfds) || (errno == EINTR && ready_descriptors == -1))); FD_ZERO(&readfds); FD_SET(sd, &readfds); tv.tv_sec = 0; tv.tv_usec = 0; ready_descriptors = select(sd + 1, &readfds, NULL, NULL, &tv); } while (ready_descriptors == -1 && errno == EINTR); if (ready_descriptors == 0) { DMA(DEBUG_INFO, "select timed out after %d seconds on socket: %d\n", timeoutseconds, sd); return (0); } else if (ready_descriptors == -1) { DMA(DEBUG_ERROR, "select failed on socket %d: %s\n", sd, strerror(errno)); return (0); } return (FD_ISSET(sd, &readfds)); }