⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sockets.c

📁 apache的软件linux版本
💻 C
📖 第 1 页 / 共 2 页
字号:
/* Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements.  See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License.  You may obtain a copy of the License at * *     http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */#include "apr_arch_networkio.h"#include "apr_network_io.h"#include "apr_general.h"#include "apr_lib.h"#include "apr_portable.h"#include "apr_strings.h"#include <string.h>#include "apr_arch_inherit.h"#include "apr_arch_misc.h"static char generic_inaddr_any[16] = {0}; /* big enough for IPv4 or IPv6 */static apr_status_t socket_cleanup(void *sock){    apr_socket_t *thesocket = sock;    if (thesocket->socketdes != INVALID_SOCKET) {        if (closesocket(thesocket->socketdes) == SOCKET_ERROR) {            return apr_get_netos_error();        }        thesocket->socketdes = INVALID_SOCKET;    }#if APR_HAS_SENDFILE    if (thesocket->overlapped) {        CloseHandle(thesocket->overlapped->hEvent);        thesocket->overlapped = NULL;    }#endif    return APR_SUCCESS;}static void set_socket_vars(apr_socket_t *sock, int family, int type, int protocol){    sock->type = type;    sock->protocol = protocol;    apr_sockaddr_vars_set(sock->local_addr, family, 0);    apr_sockaddr_vars_set(sock->remote_addr, family, 0);}                                                                                                  static void alloc_socket(apr_socket_t **new, apr_pool_t *p){    *new = (apr_socket_t *)apr_pcalloc(p, sizeof(apr_socket_t));    (*new)->cntxt = p;    (*new)->local_addr = (apr_sockaddr_t *)apr_pcalloc((*new)->cntxt,                                                       sizeof(apr_sockaddr_t));    (*new)->local_addr->pool = p;    (*new)->remote_addr = (apr_sockaddr_t *)apr_pcalloc((*new)->cntxt,                                                        sizeof(apr_sockaddr_t));    (*new)->remote_addr->pool = p;}APR_DECLARE(apr_status_t) apr_socket_protocol_get(apr_socket_t *sock,                                                  int *protocol){    *protocol = sock->protocol;    return APR_SUCCESS;}APR_DECLARE(apr_status_t) apr_socket_create_ex(apr_socket_t **new, int family,                                               int type, int protocol,                                                apr_pool_t *cont){    int downgrade = (family == AF_UNSPEC);    if (family == AF_UNSPEC) {#if APR_HAVE_IPV6        family = AF_INET6;#else        family = AF_INET;#endif    }    alloc_socket(new, cont);    /* For right now, we are not using socket groups.  We may later.     * No flags to use when creating a socket, so use 0 for that parameter as well.     */    (*new)->socketdes = socket(family, type, protocol);#if APR_HAVE_IPV6    if ((*new)->socketdes == INVALID_SOCKET && downgrade) {        family = AF_INET;        (*new)->socketdes = socket(family, type, protocol);    }#endif    if ((*new)->socketdes == INVALID_SOCKET) {        return apr_get_netos_error();    }#ifdef WIN32    /* Socket handles are never truly inheritable, there are too many     * bugs associated.  WSADuplicateSocket will copy them, but for our     * purposes, always transform the socket() created as a non-inherited     * handle     */#if APR_HAS_UNICODE_FS && !defined(_WIN32_WCE)    IF_WIN_OS_IS_UNICODE {        /* A different approach.  Many users report errors such as          * (32538)An operation was attempted on something that is not          * a socket.  : Parent: WSADuplicateSocket failed...         *         * This appears that the duplicated handle is no longer recognized         * as a socket handle.  SetHandleInformation should overcome that         * problem by not altering the handle identifier.  But this won't         * work on 9x - it's unsupported.         */        SetHandleInformation((HANDLE) (*new)->socketdes,                              HANDLE_FLAG_INHERIT, 0);    }#endif#if APR_HAS_ANSI_FS || defined(_WIN32_WCE)    ELSE_WIN_OS_IS_ANSI {        HANDLE hProcess = GetCurrentProcess();        HANDLE dup;        if (DuplicateHandle(hProcess, (HANDLE) (*new)->socketdes, hProcess,                             &dup, 0, FALSE, DUPLICATE_SAME_ACCESS)) {            closesocket((*new)->socketdes);            (*new)->socketdes = (SOCKET) dup;        }    }#endif#endif /* def WIN32 */    set_socket_vars(*new, family, type, protocol);    (*new)->timeout = -1;    (*new)->disconnected = 0;    apr_pool_cleanup_register((*new)->cntxt, (void *)(*new),                         socket_cleanup, apr_pool_cleanup_null);    return APR_SUCCESS;} APR_DECLARE(apr_status_t) apr_socket_create(apr_socket_t **new, int family,                                            int type, apr_pool_t *cont){    return apr_socket_create_ex(new, family, type, 0, cont);}APR_DECLARE(apr_status_t) apr_socket_shutdown(apr_socket_t *thesocket,                                              apr_shutdown_how_e how){    int winhow = 0;#ifdef SD_RECEIVE    switch (how) {        case APR_SHUTDOWN_READ: {            winhow = SD_RECEIVE;            break;        }        case APR_SHUTDOWN_WRITE: {            winhow = SD_SEND;            break;        }        case APR_SHUTDOWN_READWRITE: {            winhow = SD_BOTH;            break;        }        default:            return APR_BADARG;    }#endif    if (shutdown(thesocket->socketdes, winhow) == 0) {        return APR_SUCCESS;    }    else {        return apr_get_netos_error();    }}APR_DECLARE(apr_status_t) apr_socket_close(apr_socket_t *thesocket){    apr_pool_cleanup_kill(thesocket->cntxt, thesocket, socket_cleanup);    return socket_cleanup(thesocket);}APR_DECLARE(apr_status_t) apr_socket_bind(apr_socket_t *sock,                                          apr_sockaddr_t *sa){    if (bind(sock->socketdes,              (struct sockaddr *)&sa->sa,              sa->salen) == -1) {        return apr_get_netos_error();    }    else {        sock->local_addr = sa;        if (sock->local_addr->sa.sin.sin_port == 0) {            sock->local_port_unknown = 1; /* ephemeral port */        }        return APR_SUCCESS;    }}APR_DECLARE(apr_status_t) apr_socket_listen(apr_socket_t *sock,                                            apr_int32_t backlog){    if (listen(sock->socketdes, backlog) == SOCKET_ERROR)        return apr_get_netos_error();    else        return APR_SUCCESS;}APR_DECLARE(apr_status_t) apr_socket_accept(apr_socket_t **new,                                             apr_socket_t *sock, apr_pool_t *p){    SOCKET s;    struct sockaddr sa;    int salen = sizeof(sock->remote_addr->sa);    /* Don't allocate the memory until after we call accept. This allows       us to work with nonblocking sockets. */    s = accept(sock->socketdes, (struct sockaddr *)&sa, &salen);    if (s == INVALID_SOCKET) {        return apr_get_netos_error();    }    alloc_socket(new, p);    set_socket_vars(*new, sock->local_addr->sa.sin.sin_family, SOCK_STREAM,                     sock->protocol);    (*new)->timeout = -1;       (*new)->disconnected = 0;    (*new)->socketdes = s;    /* XXX next line looks bogus w.r.t. AF_INET6 support */    (*new)->remote_addr->salen = sizeof((*new)->remote_addr->sa);    memcpy (&(*new)->remote_addr->sa, &sa, salen);    *(*new)->local_addr = *sock->local_addr;    /* The above assignment just overwrote the pool entry. Setting the local_addr        pool for the accepted socket back to what it should be.  Otherwise all        allocations for this socket will come from a server pool that is not       freed until the process goes down.*/    (*new)->local_addr->pool = p;    /* fix up any pointers which are no longer valid */    if (sock->local_addr->sa.sin.sin_family == AF_INET) {        (*new)->local_addr->ipaddr_ptr = &(*new)->local_addr->sa.sin.sin_addr;    }#if APR_HAVE_IPV6    else if (sock->local_addr->sa.sin.sin_family == AF_INET6) {        (*new)->local_addr->ipaddr_ptr = &(*new)->local_addr->sa.sin6.sin6_addr;    }#endif    (*new)->remote_addr->port = ntohs((*new)->remote_addr->sa.sin.sin_port);    if (sock->local_port_unknown) {        /* not likely for a listening socket, but theoretically possible :) */        (*new)->local_port_unknown = 1;    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -