~ubuntu-branches/ubuntu/feisty/apache2/feisty

« back to all changes in this revision

Viewing changes to srclib/apr/network_io/os2/sendrecv.c

  • Committer: Bazaar Package Importer
  • Author(s): Andreas Barth
  • Date: 2006-12-09 21:05:45 UTC
  • mfrom: (0.6.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20061209210545-h70s0xaqc2v8vqr2
Tags: 2.2.3-3.2
* Non-maintainer upload.
* 043_ajp_connection_reuse: Patch from upstream Bugzilla, fixing a critical
  issue with regard to connection reuse in mod_proxy_ajp.
  Closes: #396265

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright 2000-2005 The Apache Software Foundation or its licensors, as
 
2
 * applicable.
 
3
 *
 
4
 * Licensed under the Apache License, Version 2.0 (the "License");
 
5
 * you may not use this file except in compliance with the License.
 
6
 * You may obtain a copy of the License at
 
7
 *
 
8
 *     http://www.apache.org/licenses/LICENSE-2.0
 
9
 *
 
10
 * Unless required by applicable law or agreed to in writing, software
 
11
 * distributed under the License is distributed on an "AS IS" BASIS,
 
12
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 
13
 * See the License for the specific language governing permissions and
 
14
 * limitations under the License.
 
15
 */
 
16
 
 
17
#include "apr_arch_networkio.h"
 
18
#include "apr_errno.h"
 
19
#include "apr_general.h"
 
20
#include "apr_network_io.h"
 
21
#include "apr_lib.h"
 
22
#include <sys/time.h>
 
23
 
 
24
APR_DECLARE(apr_status_t) apr_socket_send(apr_socket_t *sock, const char *buf,
 
25
                                          apr_size_t *len)
 
26
{
 
27
    apr_ssize_t rv;
 
28
    int fds, err = 0;
 
29
 
 
30
    if (*len > 65536) {
 
31
        *len = 65536;
 
32
    }
 
33
 
 
34
    do {
 
35
        if (!sock->nonblock || err == SOCEWOULDBLOCK) {
 
36
            fds = sock->socketdes;
 
37
            rv = select(&fds, 0, 1, 0, sock->timeout >= 0 ? sock->timeout/1000 : -1);
 
38
 
 
39
            if (rv != 1) {
 
40
                *len = 0;
 
41
                err = sock_errno();
 
42
 
 
43
                if (rv == 0)
 
44
                    return APR_TIMEUP;
 
45
 
 
46
                if (err == SOCEINTR)
 
47
                    continue;
 
48
 
 
49
                return APR_OS2_STATUS(err);
 
50
            }
 
51
        }
 
52
 
 
53
        rv = send(sock->socketdes, buf, (*len), 0);
 
54
        err = rv < 0 ? sock_errno() : 0;
 
55
    } while (err == SOCEINTR || err == SOCEWOULDBLOCK);
 
56
 
 
57
    if (err) {
 
58
        *len = 0;
 
59
        return APR_OS2_STATUS(err);
 
60
    }
 
61
 
 
62
    (*len) = rv;
 
63
    return APR_SUCCESS;
 
64
}
 
65
 
 
66
 
 
67
 
 
68
APR_DECLARE(apr_status_t) apr_socket_recv(apr_socket_t *sock, char *buf,
 
69
                                          apr_size_t *len)
 
70
{
 
71
    apr_ssize_t rv;
 
72
    int fds, err = 0;
 
73
 
 
74
    do {
 
75
        if (!sock->nonblock || (err == SOCEWOULDBLOCK && sock->timeout != 0)) {
 
76
            fds = sock->socketdes;
 
77
            rv = select(&fds, 1, 0, 0, sock->timeout >= 0 ? sock->timeout/1000 : -1);
 
78
 
 
79
            if (rv != 1) {
 
80
                *len = 0;
 
81
                err = sock_errno();
 
82
 
 
83
                if (rv == 0)
 
84
                    return APR_TIMEUP;
 
85
 
 
86
                if (err == SOCEINTR)
 
87
                    continue;
 
88
 
 
89
                return APR_OS2_STATUS(err);
 
90
            }
 
91
        }
 
92
 
 
93
        rv = recv(sock->socketdes, buf, (*len), 0);
 
94
        err = rv < 0 ? sock_errno() : 0;
 
95
    } while (err == SOCEINTR || (err == SOCEWOULDBLOCK && sock->timeout != 0));
 
96
 
 
97
    if (err) {
 
98
        *len = 0;
 
99
        return APR_OS2_STATUS(err);
 
100
    }
 
101
 
 
102
    (*len) = rv;
 
103
    return rv == 0 ? APR_EOF : APR_SUCCESS;
 
104
}
 
105
 
 
106
 
 
107
 
 
108
APR_DECLARE(apr_status_t) apr_socket_sendv(apr_socket_t *sock, 
 
109
                                           const struct iovec *vec, 
 
110
                                           apr_int32_t nvec, apr_size_t *len)
 
111
{
 
112
    apr_status_t rv;
 
113
    struct iovec *tmpvec;
 
114
    int fds, err = 0;
 
115
    int nv_tosend, total = 0;
 
116
 
 
117
    /* Make sure writev() only gets fed 64k at a time */
 
118
    for ( nv_tosend = 0; nv_tosend < nvec && total + vec[nv_tosend].iov_len < 65536; nv_tosend++ ) {
 
119
        total += vec[nv_tosend].iov_len;
 
120
    }
 
121
 
 
122
    tmpvec = alloca(sizeof(struct iovec) * nv_tosend);
 
123
    memcpy(tmpvec, vec, sizeof(struct iovec) * nv_tosend);
 
124
 
 
125
    do {
 
126
        if (!sock->nonblock || err == SOCEWOULDBLOCK) {
 
127
            fds = sock->socketdes;
 
128
            rv = select(&fds, 0, 1, 0, sock->timeout >= 0 ? sock->timeout/1000 : -1);
 
129
 
 
130
            if (rv != 1) {
 
131
                *len = 0;
 
132
                err = sock_errno();
 
133
 
 
134
                if (rv == 0)
 
135
                    return APR_TIMEUP;
 
136
 
 
137
                if (err == SOCEINTR)
 
138
                    continue;
 
139
 
 
140
                return APR_OS2_STATUS(err);
 
141
            }
 
142
        }
 
143
 
 
144
        rv = writev(sock->socketdes, tmpvec, nv_tosend);
 
145
        err = rv < 0 ? sock_errno() : 0;
 
146
    } while (err == SOCEINTR || err == SOCEWOULDBLOCK);
 
147
 
 
148
    if (err) {
 
149
        *len = 0;
 
150
        return APR_OS2_STATUS(err);
 
151
    }
 
152
 
 
153
    *len = rv;
 
154
    return APR_SUCCESS;
 
155
}