1 #ifndef _BABELTRACE_COMPAT_SOCKET_H
2 #define _BABELTRACE_COMPAT_SOCKET_H
5 * Copyright (C) 2015-2017 Michael Jeanson <mjeanson@efficios.com>
6 * 2015 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
8 * Permission is hereby granted, free of charge, to any person obtaining a copy
9 * of this software and associated documentation files (the "Software"), to deal
10 * in the Software without restriction, including without limitation the rights
11 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 * copies of the Software, and to permit persons to whom the Software is
13 * furnished to do so, subject to the following conditions:
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
33 #define BT_INVALID_SOCKET INVALID_SOCKET
34 #define BT_SOCKET_ERROR SOCKET_ERROR
35 #define BT_SOCKET SOCKET
38 int bt_socket_init(int log_level
)
44 /* Request winsock 2.2 support */
45 verreq
= MAKEWORD(2, 2);
47 ret
= WSAStartup(verreq
, &wsa
);
49 #ifdef BT_LOG_WRITE_CUR_LVL
50 BT_LOG_WRITE_CUR_LVL(BT_LOG_ERROR
, log_level
, BT_LOG_TAG
,
51 "Winsock init failed with error: %d", ret
);
56 if (LOBYTE(wsa
.wVersion
) != 2 || HIBYTE(wsa
.wVersion
) != 2) {
57 #ifdef BT_LOG_WRITE_CUR_LVL
58 BT_LOG_WRITE_CUR_LVL(BT_LOG_ERROR
, log_level
, BT_LOG_TAG
,
59 "Could not init winsock 2.2 support");
70 int bt_socket_fini(void)
76 int bt_socket_send(int sockfd
, const void *buf
, size_t len
, int flags
)
78 return send(sockfd
, buf
, len
, flags
);
82 int bt_socket_recv(int sockfd
, void *buf
, size_t len
, int flags
)
84 return recv(sockfd
, buf
, len
, flags
);
88 int bt_socket_close(int fd
)
90 return closesocket(fd
);
94 bool bt_socket_interrupted(void)
96 /* There is no equivalent to EINTR in winsock 2.2 */
101 const char *bt_socket_errormsg(void)
104 int error
= WSAGetLastError();
108 errstr
= "Call interrupted";
114 errstr
= "Bad access";
117 errstr
= "Bad argument";
120 errstr
= "Invalid arguments";
123 errstr
= "Out of file descriptors";
126 errstr
= "Call would block";
130 errstr
= "Blocking call in progress";
133 errstr
= "Descriptor is not a socket";
135 case WSAEDESTADDRREQ
:
136 errstr
= "Need destination address";
139 errstr
= "Bad message size";
142 errstr
= "Bad protocol";
145 errstr
= "Protocol option is unsupported";
147 case WSAEPROTONOSUPPORT
:
148 errstr
= "Protocol is unsupported";
150 case WSAESOCKTNOSUPPORT
:
151 errstr
= "Socket is unsupported";
154 errstr
= "Operation not supported";
156 case WSAEAFNOSUPPORT
:
157 errstr
= "Address family not supported";
159 case WSAEPFNOSUPPORT
:
160 errstr
= "Protocol family not supported";
163 errstr
= "Address already in use";
165 case WSAEADDRNOTAVAIL
:
166 errstr
= "Address not available";
169 errstr
= "Network down";
172 errstr
= "Network unreachable";
175 errstr
= "Network has been reset";
177 case WSAECONNABORTED
:
178 errstr
= "Connection was aborted";
181 errstr
= "Connection was reset";
184 errstr
= "No buffer space";
187 errstr
= "Socket is already connected";
190 errstr
= "Socket is not connected";
193 errstr
= "Socket has been shut down";
195 case WSAETOOMANYREFS
:
196 errstr
= "Too many references";
199 errstr
= "Timed out";
201 case WSAECONNREFUSED
:
202 errstr
= "Connection refused";
207 case WSAENAMETOOLONG
:
208 errstr
= "Name too long";
211 errstr
= "Host down";
213 case WSAEHOSTUNREACH
:
214 errstr
= "Host unreachable";
217 errstr
= "Not empty";
220 errstr
= "Process limit reached";
223 errstr
= "Too many users";
226 errstr
= "Bad quota";
229 errstr
= "Something is stale";
232 errstr
= "Remote error";
235 errstr
= "Disconnected";
238 /* Extended Winsock errors */
240 errstr
= "Winsock library is not ready";
242 case WSANOTINITIALISED
:
243 errstr
= "Winsock library not initialised";
245 case WSAVERNOTSUPPORTED
:
246 errstr
= "Winsock version not supported";
249 /* getXbyY() errors (already handled in herrmsg):
250 * Authoritative Answer: Host not found */
251 case WSAHOST_NOT_FOUND
:
252 errstr
= "Host not found";
255 /* Non-Authoritative: Host not found, or SERVERFAIL */
257 errstr
= "Host not found, try again";
260 /* Non recoverable errors, FORMERR, REFUSED, NOTIMP */
262 errstr
= "Unrecoverable error in call to nameserver";
265 /* Valid name, no data record of requested type */
267 errstr
= "No data record of requested type";
271 errstr
= "Unknown error";
277 #else /* __MINGW32__ */
281 #include <netinet/in.h>
282 #include <sys/socket.h>
287 #define BT_INVALID_SOCKET -1
288 #define BT_SOCKET_ERROR -1
289 #define BT_SOCKET int
292 int bt_socket_init(int log_level
)
298 int bt_socket_fini(void)
304 int bt_socket_send(int sockfd
, const void *buf
, size_t len
, int flags
)
306 return send(sockfd
, buf
, len
, flags
);
310 int bt_socket_recv(int sockfd
, void *buf
, size_t len
, int flags
)
312 return recv(sockfd
, buf
, len
, flags
);
316 int bt_socket_close(int fd
)
322 bool bt_socket_interrupted(void)
324 return (errno
== EINTR
);
328 const char *bt_socket_errormsg(void)
330 return g_strerror(errno
);
336 * This wrapper is used on platforms that have no way of ignoring SIGPIPE
342 # define MSG_NOSIGNAL SO_NOSIGPIPE
343 # elif defined(__MINGW32__)
344 # define MSG_NOSIGNAL 0
348 #if defined(MSG_NOSIGNAL)
350 ssize_t
bt_socket_send_nosigpipe(int fd
, const void *buffer
, size_t size
)
352 return bt_socket_send(fd
, buffer
, size
, MSG_NOSIGNAL
);
359 ssize_t
bt_socket_send_nosigpipe(int fd
, const void *buffer
, size_t size
)
363 sigset_t sigpipe_set
, pending_set
, old_set
;
364 int sigpipe_was_pending
;
367 * Discard the SIGPIPE from send(), not disturbing any SIGPIPE
368 * that might be already pending. If a bogus SIGPIPE is sent to
369 * the entire process concurrently by a malicious user, it may
370 * be simply discarded.
372 if (sigemptyset(&pending_set
)) {
376 * sigpending returns the mask of signals that are _both_
377 * blocked for the thread _and_ pending for either the thread or
378 * the entire process.
380 if (sigpending(&pending_set
)) {
383 sigpipe_was_pending
= sigismember(&pending_set
, SIGPIPE
);
385 * If sigpipe was pending, it means it was already blocked, so
386 * no need to block it.
388 if (!sigpipe_was_pending
) {
389 if (sigemptyset(&sigpipe_set
)) {
392 if (sigaddset(&sigpipe_set
, SIGPIPE
)) {
395 if (pthread_sigmask(SIG_BLOCK
, &sigpipe_set
, &old_set
)) {
400 /* Send and save errno. */
401 sent
= bt_socket_send(fd
, buffer
, size
, 0);
404 if (sent
== -1 && errno
== EPIPE
&& !sigpipe_was_pending
) {
405 struct timespec timeout
= { 0, 0 };
409 ret
= sigtimedwait(&sigpipe_set
, NULL
,
411 } while (ret
== -1 && errno
== EINTR
);
413 if (!sigpipe_was_pending
) {
414 if (pthread_sigmask(SIG_SETMASK
, &old_set
, NULL
)) {
418 /* Restore send() errno */
426 #endif /* _BABELTRACE_COMPAT_SOCKET_H */
This page took 0.043636 seconds and 5 git commands to generate.