summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjerenkrantz <jerenkrantz@13f79535-47bb-0310-9956-ffa450edef68>2001-07-24 16:37:23 +0000
committerjerenkrantz <jerenkrantz@13f79535-47bb-0310-9956-ffa450edef68>2001-07-24 16:37:23 +0000
commiteb8c1ec39c319b3399587414e270dc5d53a09483 (patch)
treedcfed928db53a97d5d0b921813b363a100dd471f
parent521d174ac08b7a248f79b20fc5dc8ac5358a2aed (diff)
downloadlibapr-eb8c1ec39c319b3399587414e270dc5d53a09483.tar.gz
Bring the Solaris sendfilev() in line with the rest of the code in that
it will block after receiving an EAGAIN instead of before the sendfilev(). However, both Solaris and FreeBSD will return EAGAIN even if the write was successful. This makes it a bit awkward to block after the write (hence why FreeBSD does it the way it does). Other platforms will return EAGAIN without having sent anything - after the wait_for_io returns they need to recall their sendfile. Solaris and FreeBSD can just continue on their merry way. - Update *len to be zero when we get an error - the others seem to do this. - Only wait when it is a timeout not if it is a true non-blocking socket. git-svn-id: http://svn.apache.org/repos/asf/apr/apr/trunk@62011 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r--network_io/unix/sendrecv.c42
1 files changed, 30 insertions, 12 deletions
diff --git a/network_io/unix/sendrecv.c b/network_io/unix/sendrecv.c
index caed10889..a9b0d7db7 100644
--- a/network_io/unix/sendrecv.c
+++ b/network_io/unix/sendrecv.c
@@ -805,24 +805,42 @@ apr_status_t apr_sendfile(apr_socket_t *sock, apr_file_t *file,
sfv[curvec].sfv_len = hdtr->trailers[i].iov_len;
}
- /* If we are in non-blocking mode, we need to make sure we wait until
- * the other side says it is okay. */
- if (apr_is_option_set(sock->netmask, APR_SO_NONBLOCK) == 1 ||
- apr_is_option_set(sock->netmask, APR_SO_TIMEOUT) == 1)
- {
- rv = apr_wait_for_io_or_timeout(sock, 0);
- }
-
/* Actually do the sendfilev */
do {
/* socket, vecs, number of vecs, bytes written */
rv = sendfilev(sock->socketdes, sfv, vecs, &nbytes);
} while (rv == -1 && errno == EINTR);
- /* Solaris returns EAGAIN even though it sent bytes on a non-block sock */
- if (rv == -1 && errno != EAGAIN) {
- rv = errno;
- return rv;
+ /* Solaris returns EAGAIN even though it sent bytes on a non-block sock.
+ * However, if we are on a TIMEOUT socket, we want to block until the
+ * other side has read the data.
+ */
+ if (rv == -1)
+ {
+ if (errno == EAGAIN) {
+ if (apr_is_option_set(sock->netmask, APR_SO_TIMEOUT) == 1)
+ {
+ /* If the wait fails for some reason, we're going to lie to our
+ * caller and say that we didn't write any bytes. That's
+ * untrue.
+ */
+ rv = apr_wait_for_io_or_timeout(sock, 0);
+
+ /* Indicate that we sent zero bytes. */
+ if (rv != APR_SUCCESS)
+ {
+ *len = 0;
+ return rv;
+ }
+ }
+ }
+ else
+ {
+ /* Indicate that we sent zero bytes. */
+ rv = errno;
+ *len = 0;
+ return rv;
+ }
}
/* Update how much we sent */