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
31 #define BT_INVALID_SOCKET INVALID_SOCKET
32 #define BT_SOCKET_ERROR SOCKET_ERROR
33 #define BT_SOCKET SOCKET
36 int bt_socket_init(int log_level
)
42 /* Request winsock 2.2 support */
43 verreq
= MAKEWORD(2, 2);
45 ret
= WSAStartup(verreq
, &wsa
);
47 #ifdef BT_LOG_WRITE_CUR_LVL
48 BT_LOG_WRITE_CUR_LVL(BT_LOG_ERROR
, log_level
, BT_LOG_TAG
,
49 "Winsock init failed with error: %d", ret
);
54 if (LOBYTE(wsa
.wVersion
) != 2 || HIBYTE(wsa
.wVersion
) != 2) {
55 #ifdef BT_LOG_WRITE_CUR_LVL
56 BT_LOG_WRITE_CUR_LVL(BT_LOG_ERROR
, log_level
, BT_LOG_TAG
,
57 "Could not init winsock 2.2 support");
68 int bt_socket_fini(void)
74 int bt_socket_send(int sockfd
, const void *buf
, size_t len
, int flags
)
76 return send(sockfd
, buf
, len
, flags
);
80 int bt_socket_recv(int sockfd
, void *buf
, size_t len
, int flags
)
82 return recv(sockfd
, buf
, len
, flags
);
86 int bt_socket_close(int fd
)
88 return closesocket(fd
);
92 bool bt_socket_interrupted(void)
94 /* There is no equivalent to EINTR in winsock 2.2 */
99 const char *bt_socket_errormsg(void)
102 int error
= WSAGetLastError();
106 errstr
= "Call interrupted";
112 errstr
= "Bad access";
115 errstr
= "Bad argument";
118 errstr
= "Invalid arguments";
121 errstr
= "Out of file descriptors";
124 errstr
= "Call would block";
128 errstr
= "Blocking call in progress";
131 errstr
= "Descriptor is not a socket";
133 case WSAEDESTADDRREQ
:
134 errstr
= "Need destination address";
137 errstr
= "Bad message size";
140 errstr
= "Bad protocol";
143 errstr
= "Protocol option is unsupported";
145 case WSAEPROTONOSUPPORT
:
146 errstr
= "Protocol is unsupported";
148 case WSAESOCKTNOSUPPORT
:
149 errstr
= "Socket is unsupported";
152 errstr
= "Operation not supported";
154 case WSAEAFNOSUPPORT
:
155 errstr
= "Address family not supported";
157 case WSAEPFNOSUPPORT
:
158 errstr
= "Protocol family not supported";
161 errstr
= "Address already in use";
163 case WSAEADDRNOTAVAIL
:
164 errstr
= "Address not available";
167 errstr
= "Network down";
170 errstr
= "Network unreachable";
173 errstr
= "Network has been reset";
175 case WSAECONNABORTED
:
176 errstr
= "Connection was aborted";
179 errstr
= "Connection was reset";
182 errstr
= "No buffer space";
185 errstr
= "Socket is already connected";
188 errstr
= "Socket is not connected";
191 errstr
= "Socket has been shut down";
193 case WSAETOOMANYREFS
:
194 errstr
= "Too many references";
197 errstr
= "Timed out";
199 case WSAECONNREFUSED
:
200 errstr
= "Connection refused";
205 case WSAENAMETOOLONG
:
206 errstr
= "Name too long";
209 errstr
= "Host down";
211 case WSAEHOSTUNREACH
:
212 errstr
= "Host unreachable";
215 errstr
= "Not empty";
218 errstr
= "Process limit reached";
221 errstr
= "Too many users";
224 errstr
= "Bad quota";
227 errstr
= "Something is stale";
230 errstr
= "Remote error";
233 errstr
= "Disconnected";
236 /* Extended Winsock errors */
238 errstr
= "Winsock library is not ready";
240 case WSANOTINITIALISED
:
241 errstr
= "Winsock library not initialised";
243 case WSAVERNOTSUPPORTED
:
244 errstr
= "Winsock version not supported";
247 /* getXbyY() errors (already handled in herrmsg):
248 * Authoritative Answer: Host not found */
249 case WSAHOST_NOT_FOUND
:
250 errstr
= "Host not found";
253 /* Non-Authoritative: Host not found, or SERVERFAIL */
255 errstr
= "Host not found, try again";
258 /* Non recoverable errors, FORMERR, REFUSED, NOTIMP */
260 errstr
= "Unrecoverable error in call to nameserver";
263 /* Valid name, no data record of requested type */
265 errstr
= "No data record of requested type";
269 errstr
= "Unknown error";
275 #else /* __MINGW32__ */
278 #include <sys/socket.h>
279 #include <netinet/in.h>
282 #define BT_INVALID_SOCKET -1
283 #define BT_SOCKET_ERROR -1
284 #define BT_SOCKET int
287 int bt_socket_init(int log_level
)
293 int bt_socket_fini(void)
299 int bt_socket_send(int sockfd
, const void *buf
, size_t len
, int flags
)
301 return send(sockfd
, buf
, len
, flags
);
305 int bt_socket_recv(int sockfd
, void *buf
, size_t len
, int flags
)
307 return recv(sockfd
, buf
, len
, flags
);
311 int bt_socket_close(int fd
)
317 bool bt_socket_interrupted(void)
319 return (errno
== EINTR
);
323 const char *bt_socket_errormsg(void)
325 return g_strerror(errno
);
331 * This wrapper is used on platforms that have no way of ignoring SIGPIPE
337 # define MSG_NOSIGNAL SO_NOSIGPIPE
338 # elif defined(__MINGW32__)
339 # define MSG_NOSIGNAL 0
343 #if defined(MSG_NOSIGNAL)
345 ssize_t
bt_socket_send_nosigpipe(int fd
, const void *buffer
, size_t size
)
347 return bt_socket_send(fd
, buffer
, size
, MSG_NOSIGNAL
);
354 ssize_t
bt_socket_send_nosigpipe(int fd
, const void *buffer
, size_t size
)
358 sigset_t sigpipe_set
, pending_set
, old_set
;
359 int sigpipe_was_pending
;
362 * Discard the SIGPIPE from send(), not disturbing any SIGPIPE
363 * that might be already pending. If a bogus SIGPIPE is sent to
364 * the entire process concurrently by a malicious user, it may
365 * be simply discarded.
367 if (sigemptyset(&pending_set
)) {
371 * sigpending returns the mask of signals that are _both_
372 * blocked for the thread _and_ pending for either the thread or
373 * the entire process.
375 if (sigpending(&pending_set
)) {
378 sigpipe_was_pending
= sigismember(&pending_set
, SIGPIPE
);
380 * If sigpipe was pending, it means it was already blocked, so
381 * no need to block it.
383 if (!sigpipe_was_pending
) {
384 if (sigemptyset(&sigpipe_set
)) {
387 if (sigaddset(&sigpipe_set
, SIGPIPE
)) {
390 if (pthread_sigmask(SIG_BLOCK
, &sigpipe_set
, &old_set
)) {
395 /* Send and save errno. */
396 sent
= bt_socket_send(fd
, buffer
, size
, 0);
399 if (sent
== -1 && errno
== EPIPE
&& !sigpipe_was_pending
) {
400 struct timespec timeout
= { 0, 0 };
404 ret
= sigtimedwait(&sigpipe_set
, NULL
,
406 } while (ret
== -1 && errno
== EINTR
);
408 if (!sigpipe_was_pending
) {
409 if (pthread_sigmask(SIG_SETMASK
, &old_set
, NULL
)) {
413 /* Restore send() errno */
421 #endif /* _BABELTRACE_COMPAT_SOCKET_H */
This page took 0.036946 seconds and 4 git commands to generate.