| /* GIO - GLib Input, Output and Streaming Library |
| * |
| * Copyright (C) 2006-2007 Red Hat, Inc. |
| * Copyright (C) 2022 Canonical Ltd. |
| * |
| * SPDX-License-Identifier: LGPL-2.1-or-later |
| * |
| * This library is free software; you can redistribute it and/or |
| * modify it under the terms of the GNU Lesser General Public |
| * License as published by the Free Software Foundation; either |
| * version 2.1 of the License, or (at your option) any later version. |
| * |
| * This library is distributed in the hope that it will be useful, |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| * Lesser General Public License for more details. |
| * |
| * You should have received a copy of the GNU Lesser General |
| * Public License along with this library; if not, see <http://www.gnu.org/licenses/>. |
| * |
| * Author: Alexander Larsson <alexl@redhat.com> |
| * Author: Marco Trevisan <marco.trevisan@canonical.com> |
| */ |
| |
| #include "config.h" |
| #include <errno.h> |
| #include "gioerror.h" |
| |
| #ifdef G_OS_WIN32 |
| #include <winsock2.h> |
| #endif |
| |
| /** |
| * g_io_error_quark: |
| * |
| * Gets the GIO Error Quark. |
| * |
| * Returns: a #GQuark. |
| **/ |
| G_DEFINE_QUARK (g-io-error-quark, g_io_error) |
| |
| /** |
| * g_io_error_from_errno: |
| * @err_no: Error number as defined in errno.h. |
| * |
| * Converts `errno.h` error codes into GIO error codes. |
| * |
| * The fallback value %G_IO_ERROR_FAILED is returned for error codes not |
| * currently handled (but note that future GLib releases may return a more |
| * specific value instead). |
| * |
| * As `errno` is global and may be modified by intermediate function |
| * calls, you should save its value immediately after the call returns, |
| * and use the saved value instead of `errno`: |
| * |
| * |
| * |[<!-- language="C" --> |
| * int saved_errno; |
| * |
| * ret = read (blah); |
| * saved_errno = errno; |
| * |
| * g_io_error_from_errno (saved_errno); |
| * ]| |
| * |
| * Returns: #GIOErrorEnum value for the given `errno.h` error number |
| */ |
| GIOErrorEnum |
| g_io_error_from_errno (gint err_no) |
| { |
| GFileError file_error; |
| GIOErrorEnum io_error; |
| |
| file_error = g_file_error_from_errno (err_no); |
| io_error = g_io_error_from_file_error (file_error); |
| |
| if (io_error != G_IO_ERROR_FAILED) |
| return io_error; |
| |
| switch (err_no) |
| { |
| #ifdef EMLINK |
| case EMLINK: |
| return G_IO_ERROR_TOO_MANY_LINKS; |
| break; |
| #endif |
| |
| #ifdef ENOMSG |
| case ENOMSG: |
| return G_IO_ERROR_INVALID_DATA; |
| break; |
| #endif |
| |
| #ifdef ENODATA |
| case ENODATA: |
| return G_IO_ERROR_INVALID_DATA; |
| break; |
| #endif |
| |
| #ifdef EBADMSG |
| case EBADMSG: |
| return G_IO_ERROR_INVALID_DATA; |
| break; |
| #endif |
| |
| #ifdef ECANCELED |
| case ECANCELED: |
| return G_IO_ERROR_CANCELLED; |
| break; |
| #endif |
| |
| /* ENOTEMPTY == EEXIST on AIX for backward compatibility reasons */ |
| #if defined (ENOTEMPTY) && (!defined (EEXIST) || (ENOTEMPTY != EEXIST)) |
| case ENOTEMPTY: |
| return G_IO_ERROR_NOT_EMPTY; |
| break; |
| #endif |
| |
| #ifdef ENOTSUP |
| case ENOTSUP: |
| return G_IO_ERROR_NOT_SUPPORTED; |
| break; |
| #endif |
| |
| /* EOPNOTSUPP == ENOTSUP on Linux, but POSIX considers them distinct */ |
| #if defined (EOPNOTSUPP) && (!defined (ENOTSUP) || (EOPNOTSUPP != ENOTSUP)) |
| case EOPNOTSUPP: |
| return G_IO_ERROR_NOT_SUPPORTED; |
| break; |
| #endif |
| |
| #ifdef EPROTONOSUPPORT |
| case EPROTONOSUPPORT: |
| return G_IO_ERROR_NOT_SUPPORTED; |
| break; |
| #endif |
| |
| #ifdef ESOCKTNOSUPPORT |
| case ESOCKTNOSUPPORT: |
| return G_IO_ERROR_NOT_SUPPORTED; |
| break; |
| #endif |
| |
| #ifdef EPFNOSUPPORT |
| case EPFNOSUPPORT: |
| return G_IO_ERROR_NOT_SUPPORTED; |
| break; |
| #endif |
| |
| #ifdef EAFNOSUPPORT |
| case EAFNOSUPPORT: |
| return G_IO_ERROR_NOT_SUPPORTED; |
| break; |
| #endif |
| |
| #ifdef ETIMEDOUT |
| case ETIMEDOUT: |
| return G_IO_ERROR_TIMED_OUT; |
| break; |
| #endif |
| |
| #ifdef EBUSY |
| case EBUSY: |
| return G_IO_ERROR_BUSY; |
| break; |
| #endif |
| |
| #ifdef EWOULDBLOCK |
| case EWOULDBLOCK: |
| return G_IO_ERROR_WOULD_BLOCK; |
| break; |
| #endif |
| |
| /* EWOULDBLOCK == EAGAIN on most systems, but POSIX considers them distinct */ |
| #if defined (EAGAIN) && (!defined (EWOULDBLOCK) || (EWOULDBLOCK != EAGAIN)) |
| case EAGAIN: |
| return G_IO_ERROR_WOULD_BLOCK; |
| break; |
| #endif |
| |
| #ifdef EADDRINUSE |
| case EADDRINUSE: |
| return G_IO_ERROR_ADDRESS_IN_USE; |
| break; |
| #endif |
| |
| #ifdef EHOSTUNREACH |
| case EHOSTUNREACH: |
| return G_IO_ERROR_HOST_UNREACHABLE; |
| break; |
| #endif |
| |
| #ifdef ENETUNREACH |
| case ENETUNREACH: |
| return G_IO_ERROR_NETWORK_UNREACHABLE; |
| break; |
| #endif |
| |
| #ifdef ENETDOWN |
| case ENETDOWN: |
| return G_IO_ERROR_NETWORK_UNREACHABLE; |
| break; |
| #endif |
| |
| #ifdef ECONNREFUSED |
| case ECONNREFUSED: |
| return G_IO_ERROR_CONNECTION_REFUSED; |
| break; |
| #endif |
| |
| #ifdef ECONNRESET |
| case ECONNRESET: |
| return G_IO_ERROR_CONNECTION_CLOSED; |
| break; |
| #endif |
| |
| #ifdef ENOTCONN |
| case ENOTCONN: |
| return G_IO_ERROR_NOT_CONNECTED; |
| break; |
| #endif |
| |
| #ifdef EDESTADDRREQ |
| case EDESTADDRREQ: |
| return G_IO_ERROR_DESTINATION_UNSET; |
| break; |
| #endif |
| |
| #ifdef EMSGSIZE |
| case EMSGSIZE: |
| return G_IO_ERROR_MESSAGE_TOO_LARGE; |
| break; |
| #endif |
| |
| #ifdef ENOTSOCK |
| case ENOTSOCK: |
| return G_IO_ERROR_INVALID_ARGUMENT; |
| break; |
| #endif |
| |
| default: |
| return G_IO_ERROR_FAILED; |
| break; |
| } |
| } |
| |
| /** |
| * g_io_error_from_file_error: |
| * @file_error: a #GFileError. |
| * |
| * Converts #GFileError error codes into GIO error codes. |
| * |
| * Returns: #GIOErrorEnum value for the given #GFileError error value. |
| * |
| * Since: 2.74 |
| **/ |
| GIOErrorEnum |
| g_io_error_from_file_error (GFileError file_error) |
| { |
| switch (file_error) |
| { |
| case G_FILE_ERROR_EXIST: |
| return G_IO_ERROR_EXISTS; |
| case G_FILE_ERROR_ISDIR: |
| return G_IO_ERROR_IS_DIRECTORY; |
| case G_FILE_ERROR_ACCES: |
| return G_IO_ERROR_PERMISSION_DENIED; |
| case G_FILE_ERROR_NAMETOOLONG: |
| return G_IO_ERROR_FILENAME_TOO_LONG; |
| case G_FILE_ERROR_NOENT: |
| return G_IO_ERROR_NOT_FOUND; |
| case G_FILE_ERROR_NOTDIR: |
| return G_IO_ERROR_NOT_DIRECTORY; |
| case G_FILE_ERROR_NXIO: |
| return G_IO_ERROR_NOT_REGULAR_FILE; |
| case G_FILE_ERROR_NODEV: |
| return G_IO_ERROR_NO_SUCH_DEVICE; |
| case G_FILE_ERROR_ROFS: |
| return G_IO_ERROR_READ_ONLY; |
| case G_FILE_ERROR_TXTBSY: |
| return G_IO_ERROR_BUSY; |
| case G_FILE_ERROR_LOOP: |
| return G_IO_ERROR_TOO_MANY_LINKS; |
| case G_FILE_ERROR_NOSPC: |
| case G_FILE_ERROR_NOMEM: |
| return G_IO_ERROR_NO_SPACE; |
| case G_FILE_ERROR_MFILE: |
| case G_FILE_ERROR_NFILE: |
| return G_IO_ERROR_TOO_MANY_OPEN_FILES; |
| case G_FILE_ERROR_INVAL: |
| return G_IO_ERROR_INVALID_ARGUMENT; |
| case G_FILE_ERROR_PIPE: |
| return G_IO_ERROR_BROKEN_PIPE; |
| case G_FILE_ERROR_AGAIN: |
| return G_IO_ERROR_WOULD_BLOCK; |
| case G_FILE_ERROR_PERM: |
| return G_IO_ERROR_PERMISSION_DENIED; |
| case G_FILE_ERROR_NOSYS: |
| return G_IO_ERROR_NOT_SUPPORTED; |
| case G_FILE_ERROR_BADF: |
| case G_FILE_ERROR_FAILED: |
| case G_FILE_ERROR_FAULT: |
| case G_FILE_ERROR_INTR: |
| case G_FILE_ERROR_IO: |
| return G_IO_ERROR_FAILED; |
| default: |
| g_return_val_if_reached (G_IO_ERROR_FAILED); |
| } |
| } |
| |
| #ifdef G_OS_WIN32 |
| |
| /** |
| * g_io_error_from_win32_error: |
| * @error_code: Windows error number. |
| * |
| * Converts some common error codes (as returned from GetLastError() |
| * or WSAGetLastError()) into GIO error codes. The fallback value |
| * %G_IO_ERROR_FAILED is returned for error codes not currently |
| * handled (but note that future GLib releases may return a more |
| * specific value instead). |
| * |
| * You can use g_win32_error_message() to get a localized string |
| * corresponding to @error_code. (But note that unlike g_strerror(), |
| * g_win32_error_message() returns a string that must be freed.) |
| * |
| * Returns: #GIOErrorEnum value for the given error number. |
| * |
| * Since: 2.26 |
| **/ |
| GIOErrorEnum |
| g_io_error_from_win32_error (gint error_code) |
| { |
| /* Note: Winsock errors are a subset of Win32 error codes as a |
| * whole. (The fact that the Winsock API makes them look like they |
| * aren't is just because the API predates Win32.) |
| */ |
| |
| switch (error_code) |
| { |
| case WSAEADDRINUSE: |
| return G_IO_ERROR_ADDRESS_IN_USE; |
| |
| case WSAEWOULDBLOCK: |
| return G_IO_ERROR_WOULD_BLOCK; |
| |
| case WSAEACCES: |
| return G_IO_ERROR_PERMISSION_DENIED; |
| |
| case WSA_INVALID_HANDLE: |
| case WSA_INVALID_PARAMETER: |
| case WSAEINVAL: |
| case WSAEBADF: |
| case WSAENOTSOCK: |
| return G_IO_ERROR_INVALID_ARGUMENT; |
| |
| case WSAEPROTONOSUPPORT: |
| return G_IO_ERROR_NOT_SUPPORTED; |
| |
| case WSAECANCELLED: |
| return G_IO_ERROR_CANCELLED; |
| |
| case WSAESOCKTNOSUPPORT: |
| case WSAEOPNOTSUPP: |
| case WSAEPFNOSUPPORT: |
| case WSAEAFNOSUPPORT: |
| return G_IO_ERROR_NOT_SUPPORTED; |
| |
| case WSAECONNRESET: |
| case WSAENETRESET: |
| case WSAESHUTDOWN: |
| return G_IO_ERROR_CONNECTION_CLOSED; |
| |
| case WSAEHOSTUNREACH: |
| return G_IO_ERROR_HOST_UNREACHABLE; |
| |
| case WSAENETUNREACH: |
| return G_IO_ERROR_NETWORK_UNREACHABLE; |
| |
| case WSAECONNREFUSED: |
| return G_IO_ERROR_CONNECTION_REFUSED; |
| |
| case WSAETIMEDOUT: |
| return G_IO_ERROR_TIMED_OUT; |
| |
| case WSAENOTCONN: |
| case ERROR_PIPE_LISTENING: |
| return G_IO_ERROR_NOT_CONNECTED; |
| |
| case WSAEMSGSIZE: |
| return G_IO_ERROR_MESSAGE_TOO_LARGE; |
| |
| default: |
| return G_IO_ERROR_FAILED; |
| } |
| } |
| |
| #endif |