forked from Mirrors/freeswitch
small fix to apr for OS X 10.5 for sendfile
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@6096 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
parent
10d7d619f6
commit
de6fc7a06a
@ -148,6 +148,8 @@ apr_status_t apr_socket_recvfrom(apr_sockaddr_t *from, apr_socket_t *sock,
|
||||
apr_size_t *len)
|
||||
{
|
||||
apr_ssize_t rv;
|
||||
|
||||
from->salen = sizeof(from->sa);
|
||||
|
||||
do {
|
||||
rv = recvfrom(sock->socketdes, buf, (*len), flags,
|
||||
@ -172,6 +174,8 @@ apr_status_t apr_socket_recvfrom(apr_sockaddr_t *from, apr_socket_t *sock,
|
||||
return errno;
|
||||
}
|
||||
|
||||
apr_sockaddr_vars_set(from, from->sa.sin.sin_family, ntohs(from->sa.sin.sin_port));
|
||||
|
||||
(*len) = rv;
|
||||
if (rv == 0 && sock->type == SOCK_STREAM) {
|
||||
return APR_EOF;
|
||||
@ -399,6 +403,109 @@ do_select:
|
||||
return rv < 0 ? errno : APR_SUCCESS;
|
||||
}
|
||||
|
||||
#elif defined(DARWIN)
|
||||
|
||||
/* OS/X Release 10.5 or greater */
|
||||
apr_status_t apr_socket_sendfile(apr_socket_t * sock, apr_file_t * file,
|
||||
apr_hdtr_t * hdtr, apr_off_t * offset,
|
||||
apr_size_t * len, apr_int32_t flags)
|
||||
{
|
||||
apr_off_t nbytes = *len;
|
||||
int rv;
|
||||
struct sf_hdtr headerstruct;
|
||||
|
||||
/* Ignore flags for now. */
|
||||
flags = 0;
|
||||
|
||||
if (!hdtr) {
|
||||
hdtr = &no_hdtr;
|
||||
}
|
||||
|
||||
headerstruct.headers = hdtr->headers;
|
||||
headerstruct.hdr_cnt = hdtr->numheaders;
|
||||
headerstruct.trailers = hdtr->trailers;
|
||||
headerstruct.trl_cnt = hdtr->numtrailers;
|
||||
|
||||
/* BSD can send the headers/footers as part of the system call */
|
||||
do {
|
||||
if (sock->options & APR_INCOMPLETE_WRITE) {
|
||||
apr_status_t arv;
|
||||
sock->options &= ~APR_INCOMPLETE_WRITE;
|
||||
arv = apr_wait_for_io_or_timeout(NULL, sock, 0);
|
||||
if (arv != APR_SUCCESS) {
|
||||
*len = 0;
|
||||
return arv;
|
||||
}
|
||||
}
|
||||
if (nbytes) {
|
||||
/* We won't dare call sendfile() if we don't have
|
||||
* header or file bytes to send because nbytes == 0
|
||||
* means send the remaining file to EOF.
|
||||
*/
|
||||
rv = sendfile(file->filedes, /* file to be sent */
|
||||
sock->socketdes, /* socket */
|
||||
*offset, /* where in the file to start */
|
||||
&nbytes, /* number of bytes to write/written */
|
||||
&headerstruct, /* Headers/footers */
|
||||
flags); /* undefined, set to 0 */
|
||||
|
||||
if (rv == -1) {
|
||||
if (errno == EAGAIN) {
|
||||
if (sock->timeout > 0) {
|
||||
sock->options |= APR_INCOMPLETE_WRITE;
|
||||
}
|
||||
/* BSD'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 (nbytes) {
|
||||
/* normal exit for a big file & non-blocking io */
|
||||
(*len) = nbytes;
|
||||
return APR_SUCCESS;
|
||||
}
|
||||
}
|
||||
}
|
||||
else { /* rv == 0 (or the kernel is broken) */
|
||||
if (nbytes == 0) {
|
||||
/* Most likely the file got smaller after the stat.
|
||||
* Return an error so the caller can do the Right Thing.
|
||||
*/
|
||||
(*len) = nbytes;
|
||||
return APR_EOF;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* just trailer bytes... use writev()
|
||||
*/
|
||||
rv = writev(sock->socketdes,
|
||||
hdtr->trailers,
|
||||
hdtr->numtrailers);
|
||||
if (rv > 0) {
|
||||
nbytes = rv;
|
||||
rv = 0;
|
||||
}
|
||||
else {
|
||||
nbytes = 0;
|
||||
}
|
||||
}
|
||||
if ((rv == -1) && (errno == EAGAIN)
|
||||
&& (sock->timeout > 0)) {
|
||||
apr_status_t arv = apr_wait_for_io_or_timeout(NULL, sock, 0);
|
||||
if (arv != APR_SUCCESS) {
|
||||
*len = 0;
|
||||
return arv;
|
||||
}
|
||||
}
|
||||
} while (rv == -1 && (errno == EINTR || errno == EAGAIN));
|
||||
|
||||
(*len) = nbytes;
|
||||
if (rv == -1) {
|
||||
return errno;
|
||||
}
|
||||
return APR_SUCCESS;
|
||||
}
|
||||
|
||||
#elif defined(__FreeBSD__) || defined(__DragonFly__)
|
||||
|
||||
/* Release 3.1 or greater */
|
||||
@ -407,7 +514,10 @@ apr_status_t apr_socket_sendfile(apr_socket_t * sock, apr_file_t * file,
|
||||
apr_size_t * len, apr_int32_t flags)
|
||||
{
|
||||
off_t nbytes = 0;
|
||||
int rv, i;
|
||||
int rv;
|
||||
#if defined(__FreeBSD_version) && __FreeBSD_version < 460001
|
||||
int i;
|
||||
#endif
|
||||
struct sf_hdtr headerstruct;
|
||||
apr_size_t bytes_to_send = *len;
|
||||
|
||||
@ -872,7 +982,9 @@ apr_status_t apr_socket_sendfile(apr_socket_t *sock, apr_file_t *file,
|
||||
for (i = 0; i < hdtr->numheaders; i++, curvec++) {
|
||||
sfv[curvec].sfv_fd = SFV_FD_SELF;
|
||||
sfv[curvec].sfv_flag = 0;
|
||||
sfv[curvec].sfv_off = (apr_off_t)hdtr->headers[i].iov_base;
|
||||
/* Cast to unsigned long to prevent sign extension of the
|
||||
* pointer value for the LFS case; see PR 39463. */
|
||||
sfv[curvec].sfv_off = (unsigned long)hdtr->headers[i].iov_base;
|
||||
sfv[curvec].sfv_len = hdtr->headers[i].iov_len;
|
||||
requested_len += sfv[curvec].sfv_len;
|
||||
}
|
||||
@ -896,7 +1008,7 @@ apr_status_t apr_socket_sendfile(apr_socket_t *sock, apr_file_t *file,
|
||||
for (i = 0; i < hdtr->numtrailers; i++, curvec++) {
|
||||
sfv[curvec].sfv_fd = SFV_FD_SELF;
|
||||
sfv[curvec].sfv_flag = 0;
|
||||
sfv[curvec].sfv_off = (apr_off_t)hdtr->trailers[i].iov_base;
|
||||
sfv[curvec].sfv_off = (unsigned long)hdtr->trailers[i].iov_base;
|
||||
sfv[curvec].sfv_len = hdtr->trailers[i].iov_len;
|
||||
requested_len += sfv[curvec].sfv_len;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user