Apache HTTPD
sendrecv.c
Go to the documentation of this file.
1/* Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache License, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. 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_private.h"
18#if BEOS_BONE /* BONE uses the unix code - woohoo */
19#include "../unix/sendrecv.c"
20#else
21#include "apr_arch_networkio.h"
22#include "apr_time.h"
23
25{
26 struct timeval tv, *tvptr;
28 int srv;
29
30 do {
31 FD_ZERO(&fdset);
33 if (sock->timeout < 0) {
34 tvptr = NULL;
35 }
36 else {
37 tv.tv_sec = sock->timeout / APR_USEC_PER_SEC;
38 tv.tv_usec = sock->timeout % APR_USEC_PER_SEC;
39 tvptr = &tv;
40 }
41 srv = select(sock->socketdes + 1,
42 for_read ? &fdset : NULL,
43 for_read ? NULL : &fdset,
44 NULL,
45 tvptr);
46 /* TODO - timeout should be smaller on repeats of this loop */
47 } while (srv == -1 && errno == EINTR);
48
49 if (srv == 0) {
50 return APR_TIMEUP;
51 }
52 else if (srv < 0) {
53 return errno;
54 }
55 return APR_SUCCESS;
56}
57
58#define SEND_WAIT APR_USEC_PER_SEC / 10
59
62{
63 apr_ssize_t rv;
64
65 do {
66 rv = send(sock->socketdes, buf, (*len), 0);
67 } while (rv == -1 && errno == EINTR);
68
69 if (rv == -1 && errno == EWOULDBLOCK && sock->timeout > 0) {
71 apr_int32_t zzz = 0;
72
73 do {
74 rv = send(sock->socketdes, buf, (*len), 0);
75 if (rv == -1 && errno == EWOULDBLOCK){
77 zzz += snooze_val;
79 /* have we passed our timeout value */
81 break;
82 }
83 } while (rv == -1 && (errno == EINTR || errno == EWOULDBLOCK));
84 }
85 if (rv == -1) {
86 *len = 0;
87 return errno;
88 }
89 (*len) = rv;
90
91 return APR_SUCCESS;
92}
93
96{
97 apr_ssize_t rv;
98
99 do {
100 rv = recv(sock->socketdes, buf, (*len), 0);
101 } while (rv == -1 && errno == EINTR);
102
103 if (rv == -1 && errno == EWOULDBLOCK && sock->timeout > 0) {
105 if (arv != APR_SUCCESS) {
106 *len = 0;
107 return arv;
108 }
109 else {
110 do {
111 rv = recv(sock->socketdes, buf, (*len), 0);
112 } while (rv == -1 && errno == EINTR);
113 }
114 }
115 if (rv == -1) {
116 (*len) = 0;
117 return errno;
118 }
119 (*len) = rv;
120 if (rv == 0)
121 return APR_EOF;
122 return APR_SUCCESS;
123}
124
125/* BeOS doesn't have writev for sockets so we use the following instead...
126 */
128 const struct iovec *vec,
130{
131 *len = vec[0].iov_len;
132 return apr_socket_send(sock, vec[0].iov_base, len);
133}
134
137 apr_int32_t flags, const char *buf,
139{
140 apr_ssize_t rv;
141
142 do {
143 rv = sendto(sock->socketdes, buf, (*len), flags,
144 (const struct sockaddr*)&where->sa,
145 where->salen);
146 } while (rv == -1 && errno == EINTR);
147
148 if (rv == -1 && (errno == EAGAIN || errno == EWOULDBLOCK)
149 && sock->timeout != 0) {
151 if (arv != APR_SUCCESS) {
152 *len = 0;
153 return arv;
154 } else {
155 do {
156 rv = sendto(sock->socketdes, buf, (*len), flags,
157 (const struct sockaddr*)&where->sa,
158 where->salen);
159 } while (rv == -1 && errno == EINTR);
160 }
161 }
162 if (rv == -1) {
163 *len = 0;
164 return errno;
165 }
166 *len = rv;
167 return APR_SUCCESS;
168}
169
172 apr_int32_t flags, char *buf,
174{
175 apr_ssize_t rv;
176
177 if (from == NULL){
178 return APR_ENOMEM;
179 /* Not sure if this is correct. Maybe we should just allocate
180 the memory??
181 */
182 }
183
184 do {
185 rv = recvfrom(sock->socketdes, buf, (*len), flags,
186 (struct sockaddr*)&from->sa, &from->salen);
187 } while (rv == -1 && errno == EINTR);
188
189 if (rv == -1 && (errno == EAGAIN || errno == EWOULDBLOCK) &&
190 sock->timeout != 0) {
192 if (arv != APR_SUCCESS) {
193 *len = 0;
194 return arv;
195 } else {
196 do {
197 rv = recvfrom(sock->socketdes, buf, (*len), flags,
198 (struct sockaddr*)&from->sa, &from->salen);
199 } while (rv == -1 && errno == EINTR);
200 }
201 }
202 if (rv == -1) {
203 (*len) = 0;
204 return errno;
205 }
206
207 from->port = ntohs(from->sa.sin.sin_port);
208
209 (*len) = rv;
210 if (rv == 0)
211 return APR_EOF;
212
213 return APR_SUCCESS;
214}
215
216#endif /* ! BEOS_BONE */
const char apr_size_t len
Definition ap_regex.h:187
#define select
#define recvfrom
#define sendto
#define recv
#define send
APR Time Library.
#define SEND_WAIT
Definition sendrecv.c:58
static apr_status_t wait_for_io_or_timeout(apr_socket_t *sock, int for_read)
Definition sendrecv.c:24
const unsigned char * buf
Definition util_md5.h:50
#define APR_EOF
Definition apr_errno.h:461
#define APR_ENOMEM
Definition apr_errno.h:683
#define APR_TIMEUP
Definition apr_errno.h:450
const char apr_ssize_t int flags
Definition apr_encode.h:168
const void apr_status_t(*) apr_status_t(* APR_DECLARE)(void) apr_pool_pre_cleanup_register(apr_pool_t *p
Definition apr_pools.h:646
apr_size_t size
#define APR_SUCCESS
Definition apr_errno.h:225
int apr_status_t
Definition apr_errno.h:44
apr_seek_where_t where
const struct iovec * vec
const struct iovec apr_size_t nvec
apr_sockaddr_t * sockaddr
apr_socket_t * sock
#define APR_USEC_PER_SEC
Definition apr_time.h:60
return NULL
Definition mod_so.c:359
union apr_sockaddr_t::@55 sa
struct sockaddr_in sin
apr_socklen_t salen
apr_interval_time_t timeout
apr_status_t apr_socket_sendto(apr_socket_t *sock, apr_sockaddr_t *where, apr_int32_t flags, const char *buf, apr_size_t *len)
Definition sendrecv.c:112
apr_status_t apr_socket_recvfrom(apr_sockaddr_t *from, apr_socket_t *sock, apr_int32_t flags, char *buf, apr_size_t *len)
Definition sendrecv.c:146
apr_status_t apr_socket_send(apr_socket_t *sock, const char *buf, apr_size_t *len)
Definition sendrecv.c:30
apr_status_t apr_socket_sendv(apr_socket_t *sock, const struct iovec *vec, apr_int32_t nvec, apr_size_t *len)
Definition sendrecv.c:194
apr_status_t apr_socket_recv(apr_socket_t *sock, char *buf, apr_size_t *len)
Definition sendrecv.c:70