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