1 /* GIO - GLib Input, Output and Streaming Library
2 *
3 * Copyright (C) 2006-2007 Red Hat, Inc.
4 * Copyright (C) 2022 Canonical Ltd.
5 *
6 * SPDX-License-Identifier: LGPL-2.1-or-later
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General
19 * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
20 *
21 * Author: Alexander Larsson <alexl@redhat.com>
22 * Author: Marco Trevisan <marco.trevisan@canonical.com>
23 */
24
25 #include "config.h"
26 #include <errno.h>
27 #include "gioerror.h"
28
29 #ifdef G_OS_WIN32
30 #include <winsock2.h>
31 #endif
32
33 /**
34 * g_io_error_quark:
35 *
36 * Gets the GIO Error Quark.
37 *
38 * Returns: a #GQuark.
39 **/
40 G_DEFINE_QUARK (g-io-error-quark, g_io_error)
41
42 /**
43 * g_io_error_from_errno:
44 * @err_no: Error number as defined in errno.h.
45 *
46 * Converts `errno.h` error codes into GIO error codes.
47 *
48 * The fallback value %G_IO_ERROR_FAILED is returned for error codes not
49 * currently handled (but note that future GLib releases may return a more
50 * specific value instead).
51 *
52 * As `errno` is global and may be modified by intermediate function
53 * calls, you should save its value immediately after the call returns,
54 * and use the saved value instead of `errno`:
55 *
56 *
57 * |[<!-- language="C" -->
58 * int saved_errno;
59 *
60 * ret = read (blah);
61 * saved_errno = errno;
62 *
63 * g_io_error_from_errno (saved_errno);
64 * ]|
65 *
66 * Returns: #GIOErrorEnum value for the given `errno.h` error number
67 */
68 GIOErrorEnum
69 g_io_error_from_errno (gint err_no)
70 {
71 GFileError file_error;
72 GIOErrorEnum io_error;
73
74 file_error = g_file_error_from_errno (err_no);
75 io_error = g_io_error_from_file_error (file_error);
76
77 if (io_error != G_IO_ERROR_FAILED)
78 return io_error;
79
80 switch (err_no)
81 {
82 #ifdef EMLINK
83 case EMLINK:
84 return G_IO_ERROR_TOO_MANY_LINKS;
85 break;
86 #endif
87
88 #ifdef ENOMSG
89 case ENOMSG:
90 return G_IO_ERROR_INVALID_DATA;
91 break;
92 #endif
93
94 #ifdef ENODATA
95 case ENODATA:
96 return G_IO_ERROR_INVALID_DATA;
97 break;
98 #endif
99
100 #ifdef EBADMSG
101 case EBADMSG:
102 return G_IO_ERROR_INVALID_DATA;
103 break;
104 #endif
105
106 #ifdef ECANCELED
107 case ECANCELED:
108 return G_IO_ERROR_CANCELLED;
109 break;
110 #endif
111
112 /* ENOTEMPTY == EEXIST on AIX for backward compatibility reasons */
113 #if defined (ENOTEMPTY) && (!defined (EEXIST) || (ENOTEMPTY != EEXIST))
114 case ENOTEMPTY:
115 return G_IO_ERROR_NOT_EMPTY;
116 break;
117 #endif
118
119 #ifdef ENOTSUP
120 case ENOTSUP:
121 return G_IO_ERROR_NOT_SUPPORTED;
122 break;
123 #endif
124
125 /* EOPNOTSUPP == ENOTSUP on Linux, but POSIX considers them distinct */
126 #if defined (EOPNOTSUPP) && (!defined (ENOTSUP) || (EOPNOTSUPP != ENOTSUP))
127 case EOPNOTSUPP:
128 return G_IO_ERROR_NOT_SUPPORTED;
129 break;
130 #endif
131
132 #ifdef EPROTONOSUPPORT
133 case EPROTONOSUPPORT:
134 return G_IO_ERROR_NOT_SUPPORTED;
135 break;
136 #endif
137
138 #ifdef ESOCKTNOSUPPORT
139 case ESOCKTNOSUPPORT:
140 return G_IO_ERROR_NOT_SUPPORTED;
141 break;
142 #endif
143
144 #ifdef EPFNOSUPPORT
145 case EPFNOSUPPORT:
146 return G_IO_ERROR_NOT_SUPPORTED;
147 break;
148 #endif
149
150 #ifdef EAFNOSUPPORT
151 case EAFNOSUPPORT:
152 return G_IO_ERROR_NOT_SUPPORTED;
153 break;
154 #endif
155
156 #ifdef ETIMEDOUT
157 case ETIMEDOUT:
158 return G_IO_ERROR_TIMED_OUT;
159 break;
160 #endif
161
162 #ifdef EBUSY
163 case EBUSY:
164 return G_IO_ERROR_BUSY;
165 break;
166 #endif
167
168 #ifdef EWOULDBLOCK
169 case EWOULDBLOCK:
170 return G_IO_ERROR_WOULD_BLOCK;
171 break;
172 #endif
173
174 /* EWOULDBLOCK == EAGAIN on most systems, but POSIX considers them distinct */
175 #if defined (EAGAIN) && (!defined (EWOULDBLOCK) || (EWOULDBLOCK != EAGAIN))
176 case EAGAIN:
177 return G_IO_ERROR_WOULD_BLOCK;
178 break;
179 #endif
180
181 #ifdef EADDRINUSE
182 case EADDRINUSE:
183 return G_IO_ERROR_ADDRESS_IN_USE;
184 break;
185 #endif
186
187 #ifdef EHOSTUNREACH
188 case EHOSTUNREACH:
189 return G_IO_ERROR_HOST_UNREACHABLE;
190 break;
191 #endif
192
193 #ifdef ENETUNREACH
194 case ENETUNREACH:
195 return G_IO_ERROR_NETWORK_UNREACHABLE;
196 break;
197 #endif
198
199 #ifdef ENETDOWN
200 case ENETDOWN:
201 return G_IO_ERROR_NETWORK_UNREACHABLE;
202 break;
203 #endif
204
205 #ifdef ECONNREFUSED
206 case ECONNREFUSED:
207 return G_IO_ERROR_CONNECTION_REFUSED;
208 break;
209 #endif
210
211 #ifdef ECONNRESET
212 case ECONNRESET:
213 return G_IO_ERROR_CONNECTION_CLOSED;
214 break;
215 #endif
216
217 #ifdef ENOTCONN
218 case ENOTCONN:
219 return G_IO_ERROR_NOT_CONNECTED;
220 break;
221 #endif
222
223 #ifdef EDESTADDRREQ
224 case EDESTADDRREQ:
225 return G_IO_ERROR_DESTINATION_UNSET;
226 break;
227 #endif
228
229 #ifdef EMSGSIZE
230 case EMSGSIZE:
231 return G_IO_ERROR_MESSAGE_TOO_LARGE;
232 break;
233 #endif
234
235 #ifdef ENOTSOCK
236 case ENOTSOCK:
237 return G_IO_ERROR_INVALID_ARGUMENT;
238 break;
239 #endif
240
241 default:
242 return G_IO_ERROR_FAILED;
243 break;
244 }
245 }
246
247 /**
248 * g_io_error_from_file_error:
249 * @file_error: a #GFileError.
250 *
251 * Converts #GFileError error codes into GIO error codes.
252 *
253 * Returns: #GIOErrorEnum value for the given #GFileError error value.
254 *
255 * Since: 2.74
256 **/
257 GIOErrorEnum
258 g_io_error_from_file_error (GFileError file_error)
259 {
260 switch (file_error)
261 {
262 case G_FILE_ERROR_EXIST:
263 return G_IO_ERROR_EXISTS;
264 case G_FILE_ERROR_ISDIR:
265 return G_IO_ERROR_IS_DIRECTORY;
266 case G_FILE_ERROR_ACCES:
267 return G_IO_ERROR_PERMISSION_DENIED;
268 case G_FILE_ERROR_NAMETOOLONG:
269 return G_IO_ERROR_FILENAME_TOO_LONG;
270 case G_FILE_ERROR_NOENT:
271 return G_IO_ERROR_NOT_FOUND;
272 case G_FILE_ERROR_NOTDIR:
273 return G_IO_ERROR_NOT_DIRECTORY;
274 case G_FILE_ERROR_NXIO:
275 return G_IO_ERROR_NOT_REGULAR_FILE;
276 case G_FILE_ERROR_NODEV:
277 return G_IO_ERROR_NO_SUCH_DEVICE;
278 case G_FILE_ERROR_ROFS:
279 return G_IO_ERROR_READ_ONLY;
280 case G_FILE_ERROR_TXTBSY:
281 return G_IO_ERROR_BUSY;
282 case G_FILE_ERROR_LOOP:
283 return G_IO_ERROR_TOO_MANY_LINKS;
284 case G_FILE_ERROR_NOSPC:
285 case G_FILE_ERROR_NOMEM:
286 return G_IO_ERROR_NO_SPACE;
287 case G_FILE_ERROR_MFILE:
288 case G_FILE_ERROR_NFILE:
289 return G_IO_ERROR_TOO_MANY_OPEN_FILES;
290 case G_FILE_ERROR_INVAL:
291 return G_IO_ERROR_INVALID_ARGUMENT;
292 case G_FILE_ERROR_PIPE:
293 return G_IO_ERROR_BROKEN_PIPE;
294 case G_FILE_ERROR_AGAIN:
295 return G_IO_ERROR_WOULD_BLOCK;
296 case G_FILE_ERROR_PERM:
297 return G_IO_ERROR_PERMISSION_DENIED;
298 case G_FILE_ERROR_NOSYS:
299 return G_IO_ERROR_NOT_SUPPORTED;
300 case G_FILE_ERROR_BADF:
301 case G_FILE_ERROR_FAILED:
302 case G_FILE_ERROR_FAULT:
303 case G_FILE_ERROR_INTR:
304 case G_FILE_ERROR_IO:
305 return G_IO_ERROR_FAILED;
306 default:
307 g_return_val_if_reached (G_IO_ERROR_FAILED);
308 }
309 }
310
311 #ifdef G_OS_WIN32
312
313 /**
314 * g_io_error_from_win32_error:
315 * @error_code: Windows error number.
316 *
317 * Converts some common error codes (as returned from GetLastError()
318 * or WSAGetLastError()) into GIO error codes. The fallback value
319 * %G_IO_ERROR_FAILED is returned for error codes not currently
320 * handled (but note that future GLib releases may return a more
321 * specific value instead).
322 *
323 * You can use g_win32_error_message() to get a localized string
324 * corresponding to @error_code. (But note that unlike g_strerror(),
325 * g_win32_error_message() returns a string that must be freed.)
326 *
327 * Returns: #GIOErrorEnum value for the given error number.
328 *
329 * Since: 2.26
330 **/
331 GIOErrorEnum
332 g_io_error_from_win32_error (gint error_code)
333 {
334 /* Note: Winsock errors are a subset of Win32 error codes as a
335 * whole. (The fact that the Winsock API makes them look like they
336 * aren't is just because the API predates Win32.)
337 */
338
339 switch (error_code)
340 {
341 case WSAEADDRINUSE:
342 return G_IO_ERROR_ADDRESS_IN_USE;
343
344 case WSAEWOULDBLOCK:
345 return G_IO_ERROR_WOULD_BLOCK;
346
347 case WSAEACCES:
348 return G_IO_ERROR_PERMISSION_DENIED;
349
350 case WSA_INVALID_HANDLE:
351 case WSA_INVALID_PARAMETER:
352 case WSAEINVAL:
353 case WSAEBADF:
354 case WSAENOTSOCK:
355 return G_IO_ERROR_INVALID_ARGUMENT;
356
357 case WSAEPROTONOSUPPORT:
358 return G_IO_ERROR_NOT_SUPPORTED;
359
360 case WSAECANCELLED:
361 return G_IO_ERROR_CANCELLED;
362
363 case WSAESOCKTNOSUPPORT:
364 case WSAEOPNOTSUPP:
365 case WSAEPFNOSUPPORT:
366 case WSAEAFNOSUPPORT:
367 return G_IO_ERROR_NOT_SUPPORTED;
368
369 case WSAECONNRESET:
370 case WSAENETRESET:
371 case WSAESHUTDOWN:
372 return G_IO_ERROR_CONNECTION_CLOSED;
373
374 case WSAEHOSTUNREACH:
375 return G_IO_ERROR_HOST_UNREACHABLE;
376
377 case WSAENETUNREACH:
378 return G_IO_ERROR_NETWORK_UNREACHABLE;
379
380 case WSAECONNREFUSED:
381 return G_IO_ERROR_CONNECTION_REFUSED;
382
383 case WSAETIMEDOUT:
384 return G_IO_ERROR_TIMED_OUT;
385
386 case WSAENOTCONN:
387 case ERROR_PIPE_LISTENING:
388 return G_IO_ERROR_NOT_CONNECTED;
389
390 case WSAEMSGSIZE:
391 return G_IO_ERROR_MESSAGE_TOO_LARGE;
392
393 default:
394 return G_IO_ERROR_FAILED;
395 }
396 }
397
398 #endif