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