svn commit: samba r7046 - in trunk/source/lib: .

jra at samba.org jra at samba.org
Sat May 28 00:07:54 GMT 2005


Author: jra
Date: 2005-05-28 00:07:54 +0000 (Sat, 28 May 2005)
New Revision: 7046

WebSVN: http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=7046

Log:
Ensure read_data_until processes errors correctly. Use version of select
that ignores EINTR.
Jeremy.

Modified:
   trunk/source/lib/util_sock.c


Changeset:
Modified: trunk/source/lib/util_sock.c
===================================================================
--- trunk/source/lib/util_sock.c	2005-05-27 23:53:09 UTC (rev 7045)
+++ trunk/source/lib/util_sock.c	2005-05-28 00:07:54 UTC (rev 7046)
@@ -263,7 +263,8 @@
 }
 
 /****************************************************************************
- Read data from the client, reading exactly N bytes. 
+ Read data from the client, reading exactly N bytes, or until endtime timeout.
+ Use with a non-blocking socket if endtime != NULL.
 ****************************************************************************/
 
 ssize_t read_data_until(int fd,char *buffer,size_t N, const struct timeval *endtime)
@@ -278,20 +279,32 @@
 		if (endtime != NULL) {
 			fd_set r_fds;
 			struct timeval timeout;
-			int res;
+			int selrtn;
 
-			FD_ZERO(&r_fds);
-			FD_SET(fd, &r_fds);
-
 			if (!timeout_until(&timeout, endtime)) {
 				DEBUG(10,("read_data_until: read timed out\n"));
 				smb_read_error = READ_TIMEOUT;
 				return -1;
 			}
 
-			res = sys_select(fd+1, &r_fds, NULL, NULL, &timeout);
-			if (res <= 0)
+			FD_ZERO(&r_fds);
+			FD_SET(fd, &r_fds);
+
+			/* Select but ignore EINTR. */
+			selrtn = sys_select_intr(fd+1, &r_fds, NULL, NULL, &timeout);
+			if (selrtn == -1) {
+				/* something is wrong. Maybe the socket is dead? */
+				DEBUG(0,("read_data_until: select error = %s.\n", strerror(errno) ));
+				smb_read_error = READ_ERROR;
 				return -1;
+			}
+		
+			/* Did we timeout ? */
+			if (selrtn == 0) {
+				DEBUG(10,("read_data_until: select timed out.\n"));
+				smb_read_error = READ_TIMEOUT;
+				return -1;
+			}
 		}
 
 		ret = sys_read(fd,buffer + total,N - total);
@@ -303,6 +316,10 @@
 		}
 
 		if (ret == -1) {
+			if (errno == EAGAIN) {
+				/* Non-blocking socket with no data available. Try select again. */
+				continue;
+			}
 			DEBUG(0,("read_data_until: read failure for %d. Error = %s\n", (int)(N - total), strerror(errno) ));
 			smb_read_error = READ_ERROR;
 			return -1;
@@ -448,13 +465,14 @@
 			struct timeval timeout;
 			int res;
 
+			if (!timeout_until(&timeout, endtime))
+				return -1;
+
 			FD_ZERO(&w_fds);
 			FD_SET(fd, &w_fds);
 
-			if (!timeout_until(&timeout, endtime))
-				return -1;
-
-			res = sys_select(fd+1, NULL, &w_fds, NULL, &timeout);
+			/* select but ignore EINTR. */
+			res = sys_select_intr(fd+1, NULL, &w_fds, NULL, &timeout);
 			if (res <= 0)
 				return -1;
 		}



More information about the samba-cvs mailing list