View | Details | Raw Unified | Return to bug 43244
Collapse All | Expand All

(-)network_io/unix/sockdup.c (+134 lines)
Line 0 Link Here
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_networkio.h"
18
#include "apr_strings.h"
19
#include "apr_portable.h"
20
#include "apr_thread_mutex.h"
21
#include "apr_arch_inherit.h"
22
23
static apr_sockaddr_t *sockaddr_dup(apr_sockaddr_t *oldaddr,
24
                                    apr_pool_t *p)
25
{
26
    apr_sockaddr_t *newaddr = apr_pcalloc(p, sizeof(*newaddr));
27
    if (!newaddr) {
28
        return NULL;
29
    }
30
    newaddr->pool = p;
31
    newaddr->hostname = apr_pstrdup(p, oldaddr->hostname);
32
    newaddr->servname = apr_pstrdup(p, oldaddr->servname);
33
    newaddr->port = oldaddr->port;
34
    newaddr->family = oldaddr->family;
35
    newaddr->salen = oldaddr->salen;
36
    newaddr->ipaddr_len = oldaddr->ipaddr_len;
37
    newaddr->addr_str_len = oldaddr->addr_str_len;
38
    newaddr->ipaddr_ptr = apr_pmemdup(p, oldaddr->ipaddr_ptr, oldaddr->ipaddr_len);
39
    newaddr->sa = oldaddr->sa;
40
    if (oldaddr->next) {
41
        newaddr->next = sockaddr_dup(oldaddr->next, p);
42
    } else {
43
        newaddr->next = NULL;
44
    }
45
    return newaddr;
46
}
47
48
static apr_status_t socket_dup(apr_socket_t **new_socket, 
49
                             apr_socket_t *old_socket, apr_pool_t *p,
50
                             int which_dup)
51
{
52
    int rv;
53
    
54
    if (which_dup == 2) {
55
        if ((*new_socket) == NULL) {
56
            /* We can't dup2 unless we have a valid new_socket */
57
            return APR_EINVAL;
58
        }
59
        rv = dup2(old_socket->socketdes, (*new_socket)->socketdes);
60
    } else {
61
        rv = dup(old_socket->socketdes);
62
    }
63
64
    if (rv == -1)
65
        return errno;
66
    
67
    if (which_dup == 1) {
68
        (*new_socket) = (apr_socket_t *)apr_pcalloc(p, sizeof(apr_socket_t));
69
        (*new_socket)->pool = p;
70
        (*new_socket)->socketdes = rv;
71
    }
72
73
    (*new_socket)->type = old_socket->type;
74
    (*new_socket)->protocol = old_socket->protocol;
75
    (*new_socket)->local_addr = sockaddr_dup(old_socket->local_addr, p);
76
    (*new_socket)->remote_addr = sockaddr_dup(old_socket->remote_addr, p);
77
    (*new_socket)->timeout = old_socket->timeout;
78
#ifndef HAVE_POLL
79
    (*new_socket)->connected = old_socket->connected;
80
#endif
81
    (*new_socket)->local_port_unknown = old_socket->local_port_unknown;
82
    (*new_socket)->local_interface_unknown = old_socket->local_interface_unknown;
83
    (*new_socket)->remote_addr_unknown = old_socket->remote_addr_unknown;
84
    
85
    /* apr_socket_dup2() retains the original cleanup, reflecting 
86
     * the existing inherit and nocleanup flags.  This means, 
87
     * that apr_socket_dup2() cannot be called against an apr_socket_t
88
     * already closed with apr_socket_close, because the expected
89
     * cleanup was already killed.
90
     */
91
    if (which_dup == 2) {
92
        return APR_SUCCESS;
93
    }
94
    
95
    (*new_socket)->options = old_socket->options;
96
    /* The user must call APR_DECLARE_INHERIT_SET(s) on the dupped 
97
     * apr_socket_t when desired.
98
     */
99
#ifndef WAITIO_USES_POLL
100
    /* Start out with no pollset.  apr_wait_for_io_or_timeout() will
101
     * initialize the pollset if needed.
102
     */
103
    (*new_socket)->pollset = NULL;
104
#endif
105
    return APR_SUCCESS;
106
}
107
108
APR_DECLARE(apr_status_t) apr_socket_dup(apr_socket_t **new_socket,
109
                                       apr_socket_t *old_socket, apr_pool_t *p)
110
{
111
    return socket_dup(new_socket, old_socket, p, 1);
112
}
113
114
APR_DECLARE(apr_status_t) apr_socket_dup2(apr_socket_t *new_socket,
115
                                        apr_socket_t *old_socket, apr_pool_t *p)
116
{
117
    return socket_dup(&new_socket, old_socket, p, 2);
118
}
119
120
APR_DECLARE(apr_status_t) apr_socket_setaside(apr_socket_t **new_socket,
121
                                            apr_socket_t *old_socket,
122
                                            apr_pool_t *p)
123
{
124
    *new_socket = (apr_socket_t *)apr_palloc(p, sizeof(apr_socket_t));
125
    memcpy(*new_socket, old_socket, sizeof(apr_socket_t));
126
    (*new_socket)->pool = p;
127
    (*new_socket)->local_addr = sockaddr_dup(old_socket->local_addr, p);
128
    (*new_socket)->remote_addr = sockaddr_dup(old_socket->remote_addr, p);
129
    old_socket->socketdes = -1;
130
#ifndef WAITIO_USES_POLL
131
    (*new_socket)->pollset = NULL;
132
#endif
133
    return APR_SUCCESS;
134
}
(-)include/apr_network_io.h (+39 lines)
Lines 576-581 Link Here
576
                                   char *buf, apr_size_t *len);
576
                                   char *buf, apr_size_t *len);
577
577
578
/**
578
/**
579
 * Duplicate the specified socket descriptor.
580
 * @param new_socket The structure to duplicate into. 
581
 * @param old_socket The socket to duplicate.
582
 * @param p The pool to use for the new socket.
583
 * @remark *new_socket must point to a valid apr_socket_t, or point to NULL.
584
 */         
585
APR_DECLARE(apr_status_t) apr_socket_dup(apr_socket_t **new_socket,
586
                                         apr_socket_t *old_socket,
587
                                         apr_pool_t *p);
588
589
/**
590
 * Duplicate the specified socket descriptor and close the original
591
 * @param new_socket The old socket that is to be closed and reused
592
 * @param old_socket The socket to duplicate
593
 * @param p        The pool to use for the new socket
594
 *
595
 * @remark new_socket MUST point at a valid apr_socket_t. It cannot be NULL.
596
 */
597
APR_DECLARE(apr_status_t) apr_socket_dup2(apr_socket_t *new_socket,
598
                                          apr_socket_t *old_socket,
599
                                          apr_pool_t *p);
600
601
/**
602
 * Move the specified socket descriptor to a new pool
603
 * @param new_socket Pointer in which to return the new apr_socket_t
604
 * @param old_socket The socket to move
605
 * @param p        The pool to which the descriptor is to be moved
606
 * @remark Unlike apr_socket_dup2(), this function doesn't do an
607
 *         OS dup() operation on the underlying descriptor; it just
608
 *         moves the descriptor's apr_socket_t wrapper to a new pool.
609
 * @remark The new pool need not be an ancestor of old_socket's pool.
610
 * @remark After calling this function, old_socket may not be used
611
 */
612
APR_DECLARE(apr_status_t) apr_socket_setaside(apr_socket_t **new_socket,
613
                                              apr_socket_t *old_socket,
614
                                              apr_pool_t *p);
615
616
/**
579
 * Setup socket options for the specified socket
617
 * Setup socket options for the specified socket
580
 * @param sock The socket to set up.
618
 * @param sock The socket to set up.
581
 * @param opt The option we would like to configure.  One of:
619
 * @param opt The option we would like to configure.  One of:
Lines 597-602 Link Here
597
 * </PRE>
635
 * </PRE>
598
 * @param on Value for the option.
636
 * @param on Value for the option.
599
 */
637
 */
638
600
APR_DECLARE(apr_status_t) apr_socket_opt_set(apr_socket_t *sock,
639
APR_DECLARE(apr_status_t) apr_socket_opt_set(apr_socket_t *sock,
601
                                             apr_int32_t opt, apr_int32_t on);
640
                                             apr_int32_t opt, apr_int32_t on);
602
641

Return to bug 43244