Coverage Report

Created: 2023-03-26 06:28

/src/httpd/srclib/apr/support/unix/waitio.c
Line
Count
Source (jump to first uncovered line)
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_arch_file_io.h"
18
#include "apr_arch_networkio.h"
19
#include "apr_poll.h"
20
#include "apr_errno.h"
21
#include "apr_support.h"
22
23
/* The only case where we don't use wait_for_io_or_timeout is on
24
 * pre-BONE BeOS, so this check should be sufficient and simpler */
25
#if !defined(BEOS_R5) && !defined(OS2) && APR_FILES_AS_SOCKETS
26
#define USE_WAIT_FOR_IO
27
#endif
28
29
#ifdef USE_WAIT_FOR_IO
30
31
#ifdef WAITIO_USES_POLL
32
33
#if HAVE_POLL_H
34
#include <poll.h>
35
#elif HAVE_SYS_POLL_H
36
#include <sys/poll.h>
37
#endif
38
39
apr_status_t apr_wait_for_io_or_timeout(apr_file_t *f, apr_socket_t *s,
40
                                        int for_read)
41
0
{
42
0
    struct pollfd pfd;
43
0
    int rc, timeout;
44
45
0
    timeout    = f        ? f->timeout        : s->timeout;
46
0
    pfd.fd     = f        ? f->filedes        : s->socketdes;
47
0
    pfd.events = for_read ? POLLIN            : POLLOUT;
48
49
0
    if (timeout > 0) {
50
0
        timeout = (timeout + 999) / 1000;
51
0
    }
52
0
    do {
53
0
        rc = poll(&pfd, 1, timeout);
54
0
    } while (rc == -1 && errno == EINTR);
55
0
    if (rc == 0) {
56
0
        return APR_TIMEUP;
57
0
    }
58
0
    else if (rc > 0) {
59
0
        return APR_SUCCESS;
60
0
    }
61
0
    else {
62
0
        return errno;
63
0
    }
64
0
}
65
66
#else /* !WAITIO_USES_POLL */
67
68
apr_status_t apr_wait_for_io_or_timeout(apr_file_t *f, apr_socket_t *s,
69
                                        int for_read)
70
{
71
    apr_interval_time_t timeout;
72
    apr_pollfd_t pfd;
73
    int type = for_read ? APR_POLLIN : APR_POLLOUT;
74
    apr_pollset_t *pollset;
75
    apr_status_t status;
76
77
    /* TODO - timeout should be less each time through this loop */
78
    if (f) {
79
        pfd.desc_type = APR_POLL_FILE;
80
        pfd.desc.f = f;
81
82
        pollset = f->pollset;
83
        if (pollset == NULL) {
84
            status = apr_pollset_create(&(f->pollset), 1, f->pool, 0);
85
            if (status != APR_SUCCESS) {
86
                return status;
87
            }
88
            pollset = f->pollset;
89
        }
90
        timeout = f->timeout;
91
    }
92
    else {
93
        pfd.desc_type = APR_POLL_SOCKET;
94
        pfd.desc.s = s;
95
96
        pollset = s->pollset;
97
        timeout = s->timeout;
98
    }
99
    pfd.reqevents = type;
100
101
    /* Remove the object if it was in the pollset, then add in the new
102
     * object with the correct reqevents value. Ignore the status result
103
     * on the remove, because it might not be in there (yet).
104
     */
105
    (void) apr_pollset_remove(pollset, &pfd);
106
107
    /* ### check status code */
108
    (void) apr_pollset_add(pollset, &pfd);
109
110
    do {
111
        int numdesc;
112
        const apr_pollfd_t *pdesc;
113
114
        status = apr_pollset_poll(pollset, timeout, &numdesc, &pdesc);
115
116
        if (numdesc == 1 && (pdesc[0].rtnevents & type) != 0) {
117
            return APR_SUCCESS;
118
        }
119
    } while (APR_STATUS_IS_EINTR(status));
120
121
    return status;
122
}
123
#endif /* WAITIO_USES_POLL */
124
125
#endif /* USE_WAIT_FOR_IO */