MySQL  8.0.22
Source Code Documentation
task_os.h
Go to the documentation of this file.
1 /* Copyright (c) 2012, 2020, Oracle and/or its affiliates. All rights reserved.
2 
3  This program is free software; you can redistribute it and/or modify
4  it under the terms of the GNU General Public License, version 2.0,
5  as published by the Free Software Foundation.
6 
7  This program is also distributed with certain software (including
8  but not limited to OpenSSL) that is licensed under separate terms,
9  as designated in a particular file or component or in included license
10  documentation. The authors of MySQL hereby grant you an additional
11  permission to link the program and your derivative works with the
12  separately licensed software that they have included with MySQL.
13 
14  This program is distributed in the hope that it will be useful,
15  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  GNU General Public License, version 2.0, for more details.
18 
19  You should have received a copy of the GNU General Public License
20  along with this program; if not, write to the Free Software
21  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
22 
23 #ifndef TASK_OS_H
24 #define TASK_OS_H
25 
26 #include "xcom/result.h"
27 #include "xcom/task_debug.h"
28 
29 #ifdef _WIN32
30 
31 #include <MSWSock.h>
32 #include <Ws2tcpip.h>
33 #include <io.h>
34 #include <winsock2.h>
35 
36 #define DIR_SEP '\\'
37 #define SOCK_EINTR WSAEINTR
38 #define SOCK_EAGAIN WSAEINPROGRESS
39 #define SOCK_EWOULDBLOCK WSAEWOULDBLOCK
40 #define SOCK_EINPROGRESS WSAEINPROGRESS
41 #define SOCK_EALREADY WSAEALREADY
42 #define SOCK_ECONNREFUSED WSAECONNREFUSED
43 #define SOCK_ECONNRESET WSAECONNRESET
44 #define SOCK_ERRNO task_errno
45 #define SOCK_OPT_REUSEADDR SO_EXCLUSIVEADDRUSE
46 #define GET_OS_ERR WSAGetLastError()
47 #define SET_OS_ERR(x) WSASetLastError(x)
48 #define CLOSESOCKET(x) closesocket(x)
49 #define SOCK_SHUT_RDWR SD_BOTH
50 
51 static inline int hard_connect_err(int err) {
52  return err != 0 && from_errno(err) != WSAEINTR &&
53  from_errno(err) != WSAEINPROGRESS &&
55 }
56 
57 static inline int hard_select_err(int err) {
58  return err != 0 && from_errno(err) != WSAEINTR;
59 }
60 
61 #if (_WIN32_WINNT < 0x0600)
62 #error "Need _WIN32_WINNT >= 0x0600"
63 #endif
64 
65 typedef ULONG nfds_t;
66 typedef struct pollfd pollfd;
67 static inline int poll(pollfd *fds, nfds_t nfds, int timeout) {
68  return WSAPoll(fds, nfds, timeout);
69 }
70 
71 static inline int is_socket_error(int x) { return x == SOCKET_ERROR || x < 0; }
72 
73 #else
74 #include <errno.h>
75 #include <netdb.h>
76 #include <netinet/in.h>
77 #include <netinet/tcp.h>
78 #include <sys/socket.h>
79 #include <sys/types.h>
80 #include <unistd.h>
81 
82 #define DIR_SEP '/'
83 
84 /* Solaris and Linux differ here */
85 #ifndef IPPROTO_TCP
86 #define IPPROTO_TCP SOL_TCP
87 #endif
88 
89 #define SOCK_EINTR EINTR
90 #define SOCK_EAGAIN EAGAIN
91 #define SOCK_EWOULDBLOCK EWOULDBLOCK
92 #define SOCK_EINPROGRESS EINPROGRESS
93 #define SOCK_EALREADY EALREADY
94 #define SOCK_ECONNREFUSED ECONNREFUSED
95 #define SOCK_ECONNRESET ECONNRESET
96 #define SOCK_ERRNO task_errno
97 #define SOCK_OPT_REUSEADDR SO_REUSEADDR
98 #define GET_OS_ERR errno
99 #define SET_OS_ERR(x) errno = (x)
100 #define CLOSESOCKET(x) close(x)
101 #define SOCK_SHUT_RDWR (SHUT_RD | SHUT_WR)
102 
103 static inline int hard_connect_err(int err) {
104  return err != 0 && from_errno(err) != EINTR && from_errno(err) != EINPROGRESS;
105 }
106 
107 static inline int hard_select_err(int err) {
108  return from_errno(err) != 0 && from_errno(err) != EINTR;
109 }
110 
111 typedef struct pollfd pollfd;
112 
113 static inline int is_socket_error(int x) { return x < 0; }
114 
115 #endif
116 
117 extern void remove_and_wakeup(int fd);
118 
119 static inline result close_socket(int *sock) {
120  result res = {0, 0};
121  if (*sock != -1) {
122  IFDBG(D_FILEOP, FN; STRLIT("closing socket "); NDBG(*sock, d));
123  do {
124  SET_OS_ERR(0);
125  res.val = CLOSESOCKET(*sock);
126  res.funerr = to_errno(GET_OS_ERR);
127  } while (res.val == -1 && from_errno(res.funerr) == SOCK_EINTR);
128  IFDBG(D_FILEOP, FN; STRLIT("closed socket "); NDBG(*sock, d);
129  NDBG(from_errno(res.funerr), d));
130  remove_and_wakeup(*sock);
131  *sock = -1;
132  }
133  return res;
134 }
135 
136 #if defined(_WIN32)
137 
138 static inline void shutdown_socket(int *sock) {
139  static LPFN_DISCONNECTEX DisconnectEx = NULL;
140  if (DisconnectEx == NULL) {
141  DWORD dwBytesReturned;
142  GUID guidDisconnectEx = WSAID_DISCONNECTEX;
143  WSAIoctl(*sock, SIO_GET_EXTENSION_FUNCTION_POINTER, &guidDisconnectEx,
144  sizeof(GUID), &DisconnectEx, sizeof(DisconnectEx),
145  &dwBytesReturned, NULL, NULL);
146  }
147  if (DisconnectEx != NULL) {
148  DisconnectEx(*sock, (LPOVERLAPPED)NULL, (DWORD)0, (DWORD)0);
149  } else {
150  shutdown(*sock, SOCK_SHUT_RDWR);
151  }
152 }
153 
154 static inline int xcom_getpeername(int sock, struct sockaddr *name,
155  socklen_t *namelen) {
156  int x, retval;
157  x = (int)*namelen;
158  retval = getpeername(sock, name, &x);
159  *namelen = (socklen_t)x;
160  return retval;
161 }
162 
163 #else
164 
165 static inline void shutdown_socket(int *sock) {
166  shutdown(*sock, SOCK_SHUT_RDWR);
167 }
168 
169 static inline int xcom_getpeername(int s, struct sockaddr *name,
170  socklen_t *namelen) {
171  return getpeername(s, name, namelen);
172 }
173 
174 #endif
175 
176 static inline result shut_close_socket(int *sock) {
177  result res = {0, 0};
178  if (*sock >= 0) {
179  shutdown_socket(sock);
180  res = close_socket(sock);
181  *sock = -1;
182  }
183  return res;
184 }
185 
186 #endif
Definition: result.h:29
struct sockaddr sockaddr
Definition: sock_probe_win32.cc:63
#define SOCK_EWOULDBLOCK
Definition: task_os.h:91
static MYSQL * sock
Definition: mysqlcheck.cc:55
#define CLOSESOCKET(x)
Definition: task_os.h:100
#define FN
Definition: gcs_debug.h:307
#define SOCKET_ERROR
Definition: x_platform.h:283
struct pollfd pollfd
Definition: task_os.h:111
#define SET_OS_ERR(x)
Definition: task_os.h:99
static result close_socket(int *sock)
Definition: task_os.h:119
#define SOCK_SHUT_RDWR
Definition: task_os.h:101
#define IFDBG(mask, body)
Definition: gcs_debug.h:278
#define SOCK_EINTR
Definition: task_os.h:89
stdx::expected< size_t, std::error_code > poll(poll_fd *fds, size_t num_fds, std::chrono::milliseconds timeout)
Definition: poll.h:52
Definition: gcs_debug.h:186
static int is_socket_error(int x)
Definition: task_os.h:113
static void shutdown_socket(int *sock)
Definition: task_os.h:165
case opt name
Definition: sslopt-case.h:32
stdx::expected< void, error_type > getpeername(native_handle_type native_handle, struct sockaddr *addr, size_t *addr_len)
Definition: socket.h:417
static Value err()
Create a Value object that represents an error condition.
Definition: json_binary.cc:908
#define GET_OS_ERR
Definition: task_os.h:98
int funerr
Definition: result.h:31
#define NULL
Definition: types.h:54
stdx::expected< void, error_type > shutdown(native_handle_type fd, int how)
Definition: socket.h:607
static int from_errno(int err)
Definition: result.h:41
#define STRLIT(x)
Definition: gcs_debug.h:315
static int to_errno(int err)
Definition: result.h:37
static result shut_close_socket(int *sock)
Definition: task_os.h:176
static int hard_select_err(int err)
Definition: task_os.h:107
static int xcom_getpeername(int s, struct sockaddr *name, socklen_t *namelen)
Definition: task_os.h:169
static int hard_connect_err(int err)
Definition: task_os.h:103
void remove_and_wakeup(int fd)
Definition: task.cc:855
#define NDBG(x, f)
Definition: gcs_debug.h:317
int val
Definition: result.h:30