trawick 01/05/03 15:38:02
Modified: . CHANGES
test sendfile.c
network_io/unix sendrecv.c
Log:
fix a problem with the FreeBSD flavor of apr_sendfile(); we could
return APR_EAGAIN+bytes sent for a non-blocking socket
Revision Changes Path
1.101 +3 -0 apr/CHANGES
Index: CHANGES
===================================================================
RCS file: /home/cvs/apr/CHANGES,v
retrieving revision 1.100
retrieving revision 1.101
diff -u -r1.100 -r1.101
--- CHANGES 2001/05/02 02:54:11 1.100
+++ CHANGES 2001/05/03 22:37:54 1.101
@@ -1,5 +1,8 @@
Changes with APR b1
+ *) Fix a problem with the FreeBSD flavor of apr_sendfile() where we
+ could return APR_EAGAIN+bytes_sent. [Jeff Trawick]
+
*) Fix a problem on unixware where clearing h_errno wouldn't work.
Use set_h_errno() instead. PR #7651 [Jeff Trawick]
1.13 +1 -0 apr/test/sendfile.c
Index: sendfile.c
===================================================================
RCS file: /home/cvs/apr/test/sendfile.c,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -r1.12 -r1.13
--- sendfile.c 2001/03/31 22:37:13 1.12
+++ sendfile.c 2001/05/03 22:37:58 1.13
@@ -373,6 +373,7 @@
printf("apr_sendfile()->%d, sent %ld bytes\n", rv, (long)tmplen);
if (rv) {
if (APR_STATUS_IS_EAGAIN(rv)) {
+ assert(tmplen == 0);
nsocks = 1;
tmprv = apr_poll(pfd, &nsocks, -1);
assert(!tmprv);
1.65 +12 -6 apr/network_io/unix/sendrecv.c
Index: sendrecv.c
===================================================================
RCS file: /home/cvs/apr/network_io/unix/sendrecv.c,v
retrieving revision 1.64
retrieving revision 1.65
diff -u -r1.64 -r1.65
--- sendrecv.c 2001/03/31 13:25:45 1.64
+++ sendrecv.c 2001/05/03 22:38:00 1.65
@@ -376,11 +376,6 @@
return rv < 0 ? errno : APR_SUCCESS;
}
-/* These are just demos of how the code for the other OSes.
- * I haven't tested these, but they're right in terms of interface.
- * I just wanted to see what types of vars would be required from other
OSes.
- */
-
#elif defined(__FreeBSD__)
/* Release 3.1 or greater */
@@ -423,6 +418,10 @@
* first chunk of data twice, once in the first call and once in the
* second. If we are using a timed write, then we check to make sure
* we can send data before trying to send it.
+ *
+ * JLT: doing this first doesn't eliminate the possibility that
+ * we get -1/EAGAIN/nbytes>0; AFAICT it just means extra
syscalls
+ * from time to time
*/
apr_status_t arv = wait_for_io_or_timeout(sock, 0);
if (arv != APR_SUCCESS) {
@@ -444,6 +443,13 @@
&headerstruct, /* Headers/footers */
&nbytes, /* number of bytes written */
flags); /* undefined, set to 0 */
+ /* FreeBSD's sendfile can return -1/EAGAIN even if it
+ * sent bytes. Sanitize the result so we get normal EAGAIN
+ * semantics w.r.t. bytes sent.
+ */
+ if (rv == -1 && errno == EAGAIN && nbytes) {
+ rv = 0;
+ }
}
else {
/* just trailer bytes... use writev()
@@ -462,7 +468,7 @@
} while (rv == -1 && errno == EINTR);
(*len) = nbytes;
- if (rv == -1 && (errno != EAGAIN || (errno == EAGAIN && sock->timeout <
0))) {
+ if (rv == -1) {
return errno;
}
return APR_SUCCESS;