xapian-core  2.0.0
socket_utils.h
Go to the documentation of this file.
1 
4 /* Copyright (C) 2006-2023 Olly Betts
5  * Copyright (C) 2008 Lemur Consulting Ltd
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, see
19  * <https://www.gnu.org/licenses/>.
20  */
21 
22 #ifndef XAPIAN_INCLUDED_SOCKET_UTILS_H
23 #define XAPIAN_INCLUDED_SOCKET_UTILS_H
24 
25 #include "safenetdb.h"
26 #include "safeunistd.h"
27 
28 #include <cerrno>
29 
30 #ifdef __WIN32__
31 
32 # include "safewinsock2.h"
33 
34 # include <xapian/error.h>
35 
37 extern HANDLE fd_to_handle(int fd);
38 
40 extern void close_fd_or_socket(int fd);
41 
55 struct WinsockInitializer {
56  WinsockInitializer() {
57  WSADATA wsadata;
58  int wsaerror = WSAStartup(MAKEWORD(2, 2), &wsadata);
59  // FIXME - should we check the returned information in wsadata to check
60  // that we have a version of winsock which is recent enough for us?
61 
62  if (wsaerror != 0) {
63  throw Xapian::NetworkError("Failed to initialize winsock", wsaerror);
64  }
65  }
66 
67  ~WinsockInitializer() {
68  WSACleanup();
69  }
70 };
71 
80 inline int socket_errno() {
81  int wsa_err = WSAGetLastError();
82  switch (wsa_err) {
83 # ifdef EADDRINUSE
84  case WSAEADDRINUSE: return EADDRINUSE;
85 # endif
86 # ifdef ETIMEDOUT
87  case WSAETIMEDOUT: return ETIMEDOUT;
88 # endif
89 # ifdef EINPROGRESS
90  case WSAEINPROGRESS: return EINPROGRESS;
91 # endif
92  default: return wsa_err;
93  }
94 }
95 
96 /* Newer compilers define these, in which case we map to those already defined
97  * values in socket_errno() above.
98  */
99 # ifndef EADDRINUSE
100 # define EADDRINUSE WSAEADDRINUSE
101 # endif
102 # ifndef ETIMEDOUT
103 # define ETIMEDOUT WSAETIMEDOUT
104 # endif
105 # ifndef EINPROGRESS
106 # define EINPROGRESS WSAEINPROGRESS
107 # endif
108 
109 // We must call closesocket() (instead of just close()) under __WIN32__ or
110 // else the socket remains in the CLOSE_WAIT state.
111 # define CLOSESOCKET(S) closesocket(S)
112 
113 #else
114 
115 // For INET_ADDRSTRLEN and INET6_ADDRSTRLEN.
116 #include <arpa/inet.h>
117 
118 // There's no distinction between sockets and other fds on UNIX.
119 inline void close_fd_or_socket(int fd) { close(fd); }
120 
121 inline int socket_errno() { return errno; }
122 
123 # define CLOSESOCKET(S) close(S)
124 
125 #endif
126 
135 void set_socket_timeouts(int fd, double timeout);
136 
137 constexpr size_t PRETTY_IP6_LEN =
138  (INET6_ADDRSTRLEN > INET_ADDRSTRLEN ? INET6_ADDRSTRLEN : INET_ADDRSTRLEN);
139 
140 int pretty_ip6(const void* p, char* buf);
141 
142 #endif // XAPIAN_INCLUDED_SOCKET_UTILS_H
Indicates a problem communicating with a remote database.
Definition: error.h:791
PositionList * p
Hierarchy of classes which Xapian can throw as exceptions.
int close(FD &fd)
Definition: fd.h:63
include <netdb.h>, with portability workarounds.
<unistd.h>, but with compat.
include <winsock2.h> but working around problems.
void set_socket_timeouts(int fd, double timeout)
Attempt to set socket-level timeouts.
Definition: socket_utils.cc:69
void close_fd_or_socket(int fd)
Definition: socket_utils.h:119
int pretty_ip6(const void *p, char *buf)
constexpr size_t PRETTY_IP6_LEN
Definition: socket_utils.h:137
int socket_errno()
Definition: socket_utils.h:121