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_network_io.h" 19#include "apr_general.h" 20#include "apr_lib.h" 21#include "apr_strings.h" 22#include <errno.h> 23#include <string.h> 24#include <sys/socket.h> 25#include <netinet/tcp.h> 26#include <netinet/in.h> 27#include <unistd.h> 28#include <netdb.h> 29#include <sys/so_ioctl.h> 30 31 32APR_DECLARE(apr_status_t) apr_socket_timeout_set(apr_socket_t *sock, 33 apr_interval_time_t t) 34{ 35 sock->timeout = t; 36 return APR_SUCCESS; 37} 38 39 40APR_DECLARE(apr_status_t) apr_socket_opt_set(apr_socket_t *sock, 41 apr_int32_t opt, apr_int32_t on) 42{ 43 int one; 44 struct linger li; 45 46 if (on) 47 one = 1; 48 else 49 one = 0; 50 51 if (opt & APR_SO_KEEPALIVE) { 52 if (setsockopt(sock->socketdes, SOL_SOCKET, SO_KEEPALIVE, (void *)&one, sizeof(int)) == -1) { 53 return APR_OS2_STATUS(sock_errno()); 54 } 55 } 56 if (opt & APR_SO_DEBUG) { 57 if (setsockopt(sock->socketdes, SOL_SOCKET, SO_DEBUG, (void *)&one, sizeof(int)) == -1) { 58 return APR_OS2_STATUS(sock_errno()); 59 } 60 } 61 if (opt & APR_SO_REUSEADDR) { 62 if (setsockopt(sock->socketdes, SOL_SOCKET, SO_REUSEADDR, (void *)&one, sizeof(int)) == -1) { 63 return APR_OS2_STATUS(sock_errno()); 64 } 65 } 66 if (opt & APR_SO_SNDBUF) { 67 if (setsockopt(sock->socketdes, SOL_SOCKET, SO_SNDBUF, (void *)&on, sizeof(int)) == -1) { 68 return APR_OS2_STATUS(sock_errno()); 69 } 70 } 71 if (opt & APR_SO_NONBLOCK) { 72 if (ioctl(sock->socketdes, FIONBIO, (caddr_t)&one, sizeof(one)) == -1) { 73 return APR_OS2_STATUS(sock_errno()); 74 } else { 75 sock->nonblock = one; 76 } 77 } 78 if (opt & APR_SO_LINGER) { 79 li.l_onoff = on; 80 li.l_linger = APR_MAX_SECS_TO_LINGER; 81 if (setsockopt(sock->socketdes, SOL_SOCKET, SO_LINGER, (char *) &li, sizeof(struct linger)) == -1) { 82 return APR_OS2_STATUS(sock_errno()); 83 } 84 } 85 if (opt & APR_TCP_NODELAY) { 86 if (setsockopt(sock->socketdes, IPPROTO_TCP, TCP_NODELAY, (void *)&on, sizeof(int)) == -1) { 87 return APR_OS2_STATUS(sock_errno()); 88 } 89 } 90 return APR_SUCCESS; 91} 92 93 94APR_DECLARE(apr_status_t) apr_socket_timeout_get(apr_socket_t *sock, 95 apr_interval_time_t *t) 96{ 97 *t = sock->timeout; 98 return APR_SUCCESS; 99} 100 101 102APR_DECLARE(apr_status_t) apr_socket_opt_get(apr_socket_t *sock, 103 apr_int32_t opt, apr_int32_t *on) 104{ 105 switch(opt) { 106 default: 107 return APR_EINVAL; 108 } 109 return APR_SUCCESS; 110} 111 112 113APR_DECLARE(apr_status_t) apr_socket_atmark(apr_socket_t *sock, int *atmark) 114{ 115 int oobmark; 116 117 if (ioctl(sock->socketdes, SIOCATMARK, (void*)&oobmark, sizeof(oobmark)) < 0) { 118 return APR_OS2_STATUS(sock_errno()); 119 } 120 121 *atmark = (oobmark != 0); 122 123 return APR_SUCCESS; 124} 125 126 127APR_DECLARE(apr_status_t) apr_gethostname(char *buf, apr_int32_t len, 128 apr_pool_t *cont) 129{ 130 if (gethostname(buf, len) == -1) { 131 buf[0] = '\0'; 132 return APR_OS2_STATUS(sock_errno()); 133 } 134 else if (!memchr(buf, '\0', len)) { /* buffer too small */ 135 buf[0] = '\0'; 136 return APR_ENAMETOOLONG; 137 } 138 return APR_SUCCESS; 139} 140