1 /*
2     OWFS -- One-Wire filesystem
3     OWHTTPD -- One-Wire Web Server
4     Written 2003 Paul H Alfille
5     email: paul.alfille@gmail.com
6     Released under the GPL
7     See the header file: ow.h for full attribution
8     1wire/iButton system from Dallas Semiconductor
9 */
10 
11 /* ow_net holds the network utility routines. Many stolen unashamedly from Steven's Book */
12 /* Much modification by Christian Magnusson especially for Valgrind and embedded */
13 /* non-threaded fixes by Jerry Scharf */
14 
15 #include <config.h>
16 #include "owfs_config.h"
17 #include "ow.h"
18 
19 /* Read "n" bytes from a descriptor. */
20 /* Stolen from Unix Network Programming by Stevens, Fenner, Rudoff p89 */
tcp_read(int file_descriptor,void * vptr,size_t n,const struct timeval * ptv)21 ssize_t tcp_read(int file_descriptor, void *vptr, size_t n, const struct timeval * ptv)
22 {
23 	size_t nleft;
24 	ssize_t nread;
25 	char *ptr;
26 	//printf("NetRead attempt %d bytes Time:(%ld,%ld)\n",(int)n,ptv->tv_sec,ptv->tv_usec ) ;
27 	ptr = vptr;
28 	nleft = n;
29 	while (nleft > 0) {
30 		int rc;
31 		fd_set readset;
32 		struct timeval tv = { ptv->tv_sec, ptv->tv_usec, };
33 
34 		/* Initialize readset */
35 		FD_ZERO(&readset);
36 		FD_SET(file_descriptor, &readset);
37 
38 		/* Read if it doesn't timeout first */
39 		rc = select(file_descriptor + 1, &readset, NULL, NULL, &tv);
40 		if (rc > 0) {
41 			/* Is there something to read? */
42 			if (FD_ISSET(file_descriptor, &readset) == 0) {
43 				return -EIO;	/* error */
44 			}
45 			//update_max_delay(pn);
46 			if ((nread = read(file_descriptor, ptr, nleft)) < 0) {
47 				if (errno == EINTR) {
48 					errno = 0;	// clear errno. We never use it anyway.
49 					nread = 0;	/* and call read() again */
50 				} else {
51 					ERROR_DATA("Network data read error\n");
52 					return (-1);
53 				}
54 			} else if (nread == 0) {
55 				break;			/* EOF */
56 			}
57 			//Debug_Bytes( "NETREAD",ptr, nread ) ;
58 			nleft -= nread;
59 			ptr += nread;
60 		} else if (rc < 0) {	/* select error */
61 			if (errno == EINTR) {
62 				/* select() was interrupted, try again */
63 				continue;
64 			}
65 			ERROR_DATA("Selection error (network)\n");
66 			return -EINTR;
67 		} else {				/* timed out */
68 			LEVEL_CONNECT("TIMEOUT after %d bytes\n", n - nleft);
69 			return -EAGAIN;
70 		}
71 	}
72 	return (n - nleft);			/* return >= 0 */
73 }
74