Exemple #1
0
/* Stolen from Unix Network Programming by Stevens, Fenner, Rudoff p89 */
ssize_t tcp_read(int file_descriptor, void *vptr, size_t n, const struct timeval * ptv)
{
	size_t nleft;
	ssize_t nread;
	char *ptr;
	//printf("NetRead attempt %d bytes Time:(%ld,%ld)\n",(int)n,ptv->tv_sec,ptv->tv_usec ) ;
	ptr = vptr;
	nleft = n;
	while (nleft > 0) {
		int rc;
		fd_set readset;
		struct timeval tv = { ptv->tv_sec, ptv->tv_usec, };

		/* Initialize readset */
		FD_ZERO(&readset);
		FD_SET(file_descriptor, &readset);

		/* Read if it doesn't timeout first */
		rc = select(file_descriptor + 1, &readset, NULL, NULL, &tv);
		if (rc > 0) {
			/* Is there something to read? */
			if (FD_ISSET(file_descriptor, &readset) == 0) {
				return -EIO;	/* error */
			}
			//update_max_delay(pn);
			if ((nread = read(file_descriptor, ptr, nleft)) < 0) {
				if (errno == EINTR) {
					errno = 0;	// clear errno. We never use it anyway.
					nread = 0;	/* and call read() again */
				} else {
					ERROR_DATA("Network data read error\n");
					return (-1);
				}
			} else if (nread == 0) {
				break;			/* EOF */
			}
			//Debug_Bytes( "NETREAD",ptr, nread ) ;
			nleft -= nread;
			ptr += nread;
		} else if (rc < 0) {	/* select error */
			if (errno == EINTR) {
				/* select() was interrupted, try again */
				continue;
			}
			ERROR_DATA("Selection error (network)\n");
			return -EINTR;
		} else {				/* timed out */
			LEVEL_CONNECT("TIMEOUT after %d bytes\n", n - nleft);
			return -EAGAIN;
		}
	}
	return (n - nleft);			/* return >= 0 */
}
Exemple #2
0
/* return < 0 if failure */
ZERO_OR_ERROR tcp_read(FILE_DESCRIPTOR_OR_ERROR file_descriptor, BYTE * buffer, size_t requested_size, const struct timeval * ptv, size_t * chars_in)
{
	size_t to_be_read = requested_size ;

	if ( FILE_DESCRIPTOR_NOT_VALID( file_descriptor ) ) {
		return -EBADF ;
	}

	LEVEL_DEBUG("attempt %d bytes Time: "TVformat,(int)requested_size, TVvar(ptv) ) ;
	*chars_in = 0 ;
	while (to_be_read > 0) {
		int select_result;
		fd_set readset;
		struct timeval tv ;

		/* Initialize readset */
		FD_ZERO(&readset);
		FD_SET(file_descriptor, &readset);

		/* Read if it doesn't timeout first */
		timercpy( &tv, ptv ) ;
		select_result = select(file_descriptor + 1, &readset, NULL, NULL, &tv);
		if (select_result > 0) {
			ssize_t read_result;

			/* Is there something to read? */
			if (FD_ISSET(file_descriptor, &readset) == 0) {
				LEVEL_DEBUG("tcp_error -- nothing avialable to read");
				return -EBADF ;	/* error */
			}
			errno = 0 ;
			read_result = read(file_descriptor, &buffer[*chars_in], to_be_read) ;
			if ( read_result < 0 ) {
				if (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK) {
					read_result = 0;	/* and call read() again */
				} else {
					LEVEL_DATA("Network data read error errno=%d %s", errno, strerror(errno));
					STAT_ADD1(NET_read_errors);
					return -EBADF ;
				}
			} else if (read_result == 0) {
				break;			/* EOF */
			}
			TrafficInFD("NETREAD", &buffer[*chars_in], read_result, file_descriptor ) ;
			to_be_read -= read_result;
			*chars_in += read_result ;
		} else if (select_result < 0) {	/* select error */
			if (errno == EINTR) {
				/* select() was interrupted, try again */
				continue;
			}
			ERROR_DATA("Select error");
			return -EBADF;
		} else {				/* timed out */
			LEVEL_CONNECT("TIMEOUT after %d bytes", requested_size - to_be_read);
			return -EAGAIN;
		}
	}
	LEVEL_DEBUG("read: %d - %d = %d",(int)requested_size, (int) to_be_read, (int) (requested_size-to_be_read) ) ;
	return 0;
}