From 3bccc2ef8c582e52e49b5e93651276cc5c651aee Mon Sep 17 00:00:00 2001 From: Alexander Date: Sat, 16 Dec 2023 14:59:44 +0100 Subject: [PATCH 1/2] sysdeps/managarm: handle more errors in sys_socket --- sysdeps/managarm/generic/file.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/sysdeps/managarm/generic/file.cpp b/sysdeps/managarm/generic/file.cpp index 35c9ef295c..bd5cd45935 100644 --- a/sysdeps/managarm/generic/file.cpp +++ b/sysdeps/managarm/generic/file.cpp @@ -769,8 +769,15 @@ int sys_socket(int domain, int type_and_flags, int proto, int *fd) { managarm::posix::SvrResponse resp(getSysdepsAllocator()); resp.ParseFromArray(recvResp.data(), recvResp.length()); - if(resp.error() == managarm::posix::Errors::ILLEGAL_ARGUMENTS) { + if(resp.error() == managarm::posix::Errors::ADDRESS_FAMILY_NOT_SUPPORTED) { return EAFNOSUPPORT; + } else if(resp.error() == managarm::posix::Errors::NOT_SUPPORTED + || resp.error() == managarm::posix::Errors::ILLEGAL_ARGUMENTS) { + return EINVAL; + } else if(resp.error() == managarm::posix::Errors::PROTOCOL_NOT_SUPPORTED) { + return EPROTONOSUPPORT; + } else if(resp.error() == managarm::posix::Errors::INTERNAL_ERROR) { + return EIEIO; } else { __ensure(resp.error() == managarm::posix::Errors::SUCCESS); *fd = resp.fd(); From 9a1e701fa9367fb9bd882fdb673f4e84ae14b832 Mon Sep 17 00:00:00 2001 From: Alexander Date: Fri, 22 Dec 2023 16:45:12 +0100 Subject: [PATCH 2/2] [WIP] sysdeps/managarm: move posix, fs error to c error conversion out This should reduce code size a bit, along with generally cleaning up code. --- sysdeps/managarm/generic/drm.cpp | 80 +++++++++------------ sysdeps/managarm/generic/ensure.cpp | 1 - sysdeps/managarm/generic/errors.cpp | 85 +++++++++++++++++++++++ sysdeps/managarm/generic/socket.cpp | 9 ++- sysdeps/managarm/include/mlibc/errors.hpp | 32 +++++++++ sysdeps/managarm/meson.build | 1 + 6 files changed, 157 insertions(+), 51 deletions(-) create mode 100644 sysdeps/managarm/generic/errors.cpp create mode 100644 sysdeps/managarm/include/mlibc/errors.hpp diff --git a/sysdeps/managarm/generic/drm.cpp b/sysdeps/managarm/generic/drm.cpp index 61b34fe2e1..7b0b603d6d 100644 --- a/sysdeps/managarm/generic/drm.cpp +++ b/sysdeps/managarm/generic/drm.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include @@ -35,7 +36,7 @@ int ioctl_drm(int fd, unsigned long request, void *arg, int *result, HelHandle h managarm::fs::GenericIoctlReply resp(getSysdepsAllocator()); resp.ParseFromArray(recv_resp.data(), recv_resp.length()); - __ensure(resp.error() == managarm::fs::Errors::SUCCESS); + FS_SUCCESS_OR_RETURN_ERROR(resp.error()); param->version_major = resp.drm_version_major(); param->version_minor = resp.drm_version_minor(); @@ -80,15 +81,11 @@ int ioctl_drm(int fd, unsigned long request, void *arg, int *result, HelHandle h managarm::fs::GenericIoctlReply resp(getSysdepsAllocator()); resp.ParseFromArray(recv_resp.data(), recv_resp.length()); - if(resp.error() == managarm::fs::Errors::ILLEGAL_ARGUMENT) { - return EINVAL; - }else{ - __ensure(resp.error() == managarm::fs::Errors::SUCCESS); + FS_SUCCESS_OR_RETURN_ERROR(resp.error());; - param->value = resp.drm_value(); - *result = resp.result(); - return 0; - } + param->value = resp.drm_value(); + *result = resp.result(); + return 0; } case DRM_IOCTL_SET_CLIENT_CAP: { auto param = reinterpret_cast(arg); @@ -113,15 +110,11 @@ int ioctl_drm(int fd, unsigned long request, void *arg, int *result, HelHandle h managarm::fs::GenericIoctlReply resp(getSysdepsAllocator()); resp.ParseFromArray(recv_resp.data(), recv_resp.length()); - if(resp.error() == managarm::fs::Errors::ILLEGAL_ARGUMENT) { - return EINVAL; - }else{ - __ensure(resp.error() == managarm::fs::Errors::SUCCESS); + FS_SUCCESS_OR_RETURN_ERROR(resp.error()); - param->value = resp.drm_value(); - *result = resp.result(); - return 0; - } + param->value = resp.drm_value(); + *result = resp.result(); + return 0; } case DRM_IOCTL_GET_MAGIC: { auto param = reinterpret_cast(arg); @@ -174,7 +167,7 @@ int ioctl_drm(int fd, unsigned long request, void *arg, int *result, HelHandle h managarm::fs::GenericIoctlReply resp(getSysdepsAllocator()); resp.ParseFromArray(recv_resp.data(), recv_resp.length()); - __ensure(resp.error() == managarm::fs::Errors::SUCCESS); + FS_SUCCESS_OR_RETURN_ERROR(resp.error()); for(size_t i = 0; i < resp.drm_fb_ids_size(); i++) { if(i >= param->count_fbs) @@ -245,7 +238,7 @@ int ioctl_drm(int fd, unsigned long request, void *arg, int *result, HelHandle h managarm::fs::GenericIoctlReply resp(getSysdepsAllocator()); resp.ParseFromArray(recv_resp.data(), recv_resp.length()); - __ensure(resp.error() == managarm::fs::Errors::SUCCESS); + FS_SUCCESS_OR_RETURN_ERROR(resp.error()); for(size_t i = 0; i < resp.drm_encoders_size(); i++) { if(i >= param->count_encoders) @@ -429,7 +422,7 @@ int ioctl_drm(int fd, unsigned long request, void *arg, int *result, HelHandle h managarm::fs::GenericIoctlReply resp(getSysdepsAllocator()); resp.ParseFromArray(recv_resp.data(), recv_resp.length()); - __ensure(resp.error() == managarm::fs::Errors::SUCCESS); + FS_SUCCESS_OR_RETURN_ERROR(resp.error()); param->crtc_id = resp.drm_crtc_id(); param->fb_id = resp.drm_fb_id(); @@ -473,7 +466,7 @@ int ioctl_drm(int fd, unsigned long request, void *arg, int *result, HelHandle h managarm::fs::GenericIoctlReply resp(getSysdepsAllocator()); resp.ParseFromArray(recv_resp.data(), recv_resp.length()); - __ensure(resp.error() == managarm::fs::Errors::SUCCESS); + FS_SUCCESS_OR_RETURN_ERROR(resp.error()); // FIXME: send this via a helix_ng buffer for(size_t i = 0; i < resp.drm_plane_res_size(); i++) { @@ -511,7 +504,7 @@ int ioctl_drm(int fd, unsigned long request, void *arg, int *result, HelHandle h managarm::fs::GenericIoctlReply resp(getSysdepsAllocator()); resp.ParseFromArray(recv_resp.data(), recv_resp.length()); - __ensure(resp.error() == managarm::fs::Errors::SUCCESS); + FS_SUCCESS_OR_RETURN_ERROR(resp.error()); param->encoder_type = resp.drm_encoder_type(); param->crtc_id = resp.drm_crtc_id(); @@ -546,7 +539,7 @@ int ioctl_drm(int fd, unsigned long request, void *arg, int *result, HelHandle h managarm::fs::GenericIoctlReply resp(getSysdepsAllocator()); resp.ParseFromArray(recv_resp.data(), recv_resp.length()); - __ensure(resp.error() == managarm::fs::Errors::SUCCESS); + FS_SUCCESS_OR_RETURN_ERROR(resp.error()); param->handle = resp.drm_handle(); param->pitch = resp.drm_pitch(); @@ -582,7 +575,7 @@ int ioctl_drm(int fd, unsigned long request, void *arg, int *result, HelHandle h managarm::fs::GenericIoctlReply resp(getSysdepsAllocator()); resp.ParseFromArray(recv_resp.data(), recv_resp.length()); - __ensure(resp.error() == managarm::fs::Errors::SUCCESS); + FS_SUCCESS_OR_RETURN_ERROR(resp.error()); param->fb_id = resp.drm_fb_id(); @@ -610,7 +603,7 @@ int ioctl_drm(int fd, unsigned long request, void *arg, int *result, HelHandle h managarm::fs::GenericIoctlReply resp(getSysdepsAllocator()); resp.ParseFromArray(recv_resp.data(), recv_resp.length()); - __ensure(resp.error() == managarm::fs::Errors::SUCCESS); + FS_SUCCESS_OR_RETURN_ERROR(resp.error()); param->width = resp.drm_width(); param->height = resp.drm_height(); @@ -659,7 +652,7 @@ int ioctl_drm(int fd, unsigned long request, void *arg, int *result, HelHandle h managarm::fs::GenericIoctlReply resp(getSysdepsAllocator()); resp.ParseFromArray(recv_resp.data(), recv_resp.length()); - __ensure(resp.error() == managarm::fs::Errors::SUCCESS); + FS_SUCCESS_OR_RETURN_ERROR(resp.error()); param->fb_id = resp.drm_fb_id(); @@ -688,7 +681,7 @@ int ioctl_drm(int fd, unsigned long request, void *arg, int *result, HelHandle h managarm::fs::GenericIoctlReply resp(getSysdepsAllocator()); resp.ParseFromArray(recv_resp.data(), recv_resp.length()); - __ensure(resp.error() == managarm::fs::Errors::SUCCESS); + FS_SUCCESS_OR_RETURN_ERROR(resp.error()); *result = resp.result(); return 0; @@ -715,7 +708,7 @@ int ioctl_drm(int fd, unsigned long request, void *arg, int *result, HelHandle h managarm::fs::GenericIoctlReply resp(getSysdepsAllocator()); resp.ParseFromArray(recv_resp.data(), recv_resp.length()); - __ensure(resp.error() == managarm::fs::Errors::SUCCESS); + FS_SUCCESS_OR_RETURN_ERROR(resp.error()); param->offset = resp.drm_offset(); @@ -746,7 +739,7 @@ int ioctl_drm(int fd, unsigned long request, void *arg, int *result, HelHandle h managarm::fs::GenericIoctlReply resp(getSysdepsAllocator()); resp.ParseFromArray(recv_resp.data(), recv_resp.length()); - __ensure(resp.error() == managarm::fs::Errors::SUCCESS); + FS_SUCCESS_OR_RETURN_ERROR(resp.error()); param->fb_id = resp.drm_fb_id(); param->x = resp.drm_x(); @@ -790,7 +783,7 @@ int ioctl_drm(int fd, unsigned long request, void *arg, int *result, HelHandle h managarm::fs::GenericIoctlReply resp(getSysdepsAllocator()); resp.ParseFromArray(recv_resp.data(), recv_resp.length()); - __ensure(resp.error() == managarm::fs::Errors::SUCCESS); + FS_SUCCESS_OR_RETURN_ERROR(resp.error()); *result = resp.result(); return 0; @@ -819,7 +812,7 @@ int ioctl_drm(int fd, unsigned long request, void *arg, int *result, HelHandle h managarm::fs::GenericIoctlReply resp(getSysdepsAllocator()); resp.ParseFromArray(recv_resp.data(), recv_resp.length()); - __ensure(resp.error() == managarm::fs::Errors::SUCCESS); + FS_SUCCESS_OR_RETURN_ERROR(resp.error()); auto props = reinterpret_cast(param->props_ptr); auto prop_vals = reinterpret_cast(param->prop_values_ptr); @@ -862,7 +855,7 @@ int ioctl_drm(int fd, unsigned long request, void *arg, int *result, HelHandle h managarm::fs::GenericIoctlReply resp(getSysdepsAllocator()); resp.ParseFromArray(recv_resp.data(), recv_resp.length()); - __ensure(resp.error() == managarm::fs::Errors::SUCCESS); + FS_SUCCESS_OR_RETURN_ERROR(resp.error()); *result = resp.result(); return 0; @@ -901,13 +894,10 @@ int ioctl_drm(int fd, unsigned long request, void *arg, int *result, HelHandle h managarm::fs::GenericIoctlReply resp(getSysdepsAllocator()); resp.ParseFromArray(recv_resp.data(), recv_resp.length()); - if(resp.error() == managarm::fs::Errors::ILLEGAL_ARGUMENT) { - return EINVAL; - }else{ - __ensure(resp.error() == managarm::fs::Errors::SUCCESS); - *result = resp.result(); - return 0; - } + FS_SUCCESS_OR_RETURN_ERROR(resp.error()); + + *result = resp.result(); + return 0; } case DRM_IOCTL_MODE_CURSOR: { auto param = reinterpret_cast(arg); @@ -1003,7 +993,7 @@ int ioctl_drm(int fd, unsigned long request, void *arg, int *result, HelHandle h managarm::fs::GenericIoctlReply resp(getSysdepsAllocator()); resp.ParseFromArray(recv_resp.data(), recv_resp.length()); - __ensure(resp.error() == managarm::fs::Errors::SUCCESS); + FS_SUCCESS_OR_RETURN_ERROR(resp.error()); param->blob_id = resp.drm_blob_id(); @@ -1031,7 +1021,7 @@ int ioctl_drm(int fd, unsigned long request, void *arg, int *result, HelHandle h managarm::fs::GenericIoctlReply resp(getSysdepsAllocator()); resp.ParseFromArray(recv_resp.data(), recv_resp.length()); - __ensure(resp.error() == managarm::fs::Errors::SUCCESS); + FS_SUCCESS_OR_RETURN_ERROR(resp.error()); *result = resp.result(); return 0; @@ -1131,7 +1121,7 @@ int ioctl_drm(int fd, unsigned long request, void *arg, int *result, HelHandle h managarm::fs::GenericIoctlReply resp(getSysdepsAllocator()); resp.ParseFromArray(recv_resp.data(), recv_resp.length()); - __ensure(resp.error() == managarm::fs::Errors::SUCCESS); + FS_SUCCESS_OR_RETURN_ERROR(resp.error()); param->fd = resp.drm_prime_fd(); *result = resp.result(); @@ -1160,11 +1150,7 @@ int ioctl_drm(int fd, unsigned long request, void *arg, int *result, HelHandle h managarm::fs::GenericIoctlReply resp(getSysdepsAllocator()); resp.ParseFromArray(recv_resp.data(), recv_resp.length()); - if(resp.error() == managarm::fs::Errors::FILE_NOT_FOUND) { - return EBADF; - } else { - __ensure(resp.error() == managarm::fs::Errors::SUCCESS); - } + FS_SUCCESS_OR_RETURN_ERROR(resp.error()); param->handle = resp.drm_prime_handle(); *result = resp.result(); diff --git a/sysdeps/managarm/generic/ensure.cpp b/sysdeps/managarm/generic/ensure.cpp index ab0d84fdb2..5a87833b16 100644 --- a/sysdeps/managarm/generic/ensure.cpp +++ b/sysdeps/managarm/generic/ensure.cpp @@ -1,4 +1,3 @@ - #include #include #include diff --git a/sysdeps/managarm/generic/errors.cpp b/sysdeps/managarm/generic/errors.cpp new file mode 100644 index 0000000000..fcafc18fc3 --- /dev/null +++ b/sysdeps/managarm/generic/errors.cpp @@ -0,0 +1,85 @@ +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include + +#include +#include + +int posixErrorToError(managarm::posix::Errors posixError) { + using enum managarm::posix::Errors; + + switch(posixError) { + case SUCCESS: return 0; + case DEAD_FORK: mlibc::panicLogger() << "mlibc: posix error DEAD_FORK must be handled manually" << frg::endlog; __builtin_unreachable(); + case ILLEGAL_REQUEST: mlibc::panicLogger() << "mlibc: posix error ILLEGAL_REQUEST must be handled manually" << frg::endlog; __builtin_unreachable(); + case ILLEGAL_ARGUMENTS: return EINVAL; + case FILE_NOT_FOUND: return ENOENT; + case ACCESS_DENIED: return EPERM; + case ALREADY_EXISTS: return EEXIST; + case NO_SUCH_FD: return EBADFD; + case END_OF_FILE: mlibc::panicLogger() << "mlibc: posix error END_OF_FILE must be handled manually" << frg::endlog; __builtin_unreachable(); + case BAD_FD: return EBADFD; + case WOULD_BLOCK: return EWOULDBLOCK; + case BROKEN_PIPE: return EPIPE; + case NOT_SUPPORTED: return ENOTSUP; + case RESOURCE_IN_USE: return EBUSY; + case ILLEGAL_OPERATION_TARGET: return EINVAL; + case NOT_A_DIRECTORY: return ENOTDIR; + case NO_BACKING_DEVICE: return ENXIO; + + // TODO: the name of this posix error implies that it might return other errors, since "ESRCH" is "No such process" + // Maybe we should rename this? + case NO_SUCH_RESOURCE: return ESRCH; + case INSUFFICIENT_PERMISSION: return EPERM; + case IS_DIRECTORY: return EISDIR; + case NOT_A_TTY: return ENOTTY; + case PROTOCOL_NOT_SUPPORTED: return EPROTONOSUPPORT; + case ADDRESS_FAMILY_NOT_SUPPORTED: return EAFNOSUPPORT; + case NO_MEMORY: return ENOMEM; + case INTERNAL_ERROR: return EIEIO; + default: mlibc::panicLogger() << "mlibc: invalid posix error: " << (int)posixError << frg::endlog; __builtin_unreachable(); + } +} + +int fsErrorToError(managarm::fs::Errors fsError) { + using enum managarm::fs::Errors; + + switch(fsError) { + case SUCCESS: return 0; + case FILE_NOT_FOUND: return ENOENT; + case END_OF_FILE: mlibc::panicLogger() << "mlibc: posix error END_OF_FILE must be handled manually" << frg::endlog; __builtin_unreachable(); + case ILLEGAL_ARGUMENT: return EINVAL; + case WOULD_BLOCK: return EWOULDBLOCK; + case SEEK_ON_PIPE: return ESPIPE; + case BROKEN_PIPE: return EPIPE; + case ACCESS_DENIED: return EPERM; + case AF_NOT_SUPPORTED: return EAFNOSUPPORT; + case DESTINATION_ADDRESS_REQUIRED: return EDESTADDRREQ; + case NETWORK_UNREACHABLE: return ENETUNREACH; + case MESSAGE_TOO_LARGE: return EMSGSIZE; + case HOST_UNREACHABLE: return EHOSTUNREACH; + case INSUFFICIENT_PERMISSIONS: return EPERM; + case ADDRESS_IN_USE: return EADDRINUSE; + case ADDRESS_NOT_AVAILABLE: return EADDRNOTAVAIL; + case NOT_CONNECTED: return ENOTCONN; + case ALREADY_EXISTS: return EEXIST; + case ILLEGAL_OPERATION_TARGET: return EINVAL; + case NOT_DIRECTORY: return ENOTDIR; + case NO_SPACE_LEFT: return ENOSPC; + case NOT_A_TERMINAL: return ENOTTY; + case NO_BACKING_DEVICE: return ENXIO; + case IS_DIRECTORY: return EISDIR; + case NOT_A_SOCKET: return ENOTSOCK; + default: mlibc::panicLogger() << "mlibc: invalid fs error: " << (int)posixError << frg::endlog; __builtin_unreachable(); + } +} diff --git a/sysdeps/managarm/generic/socket.cpp b/sysdeps/managarm/generic/socket.cpp index 86a9373b4b..51781b8f87 100644 --- a/sysdeps/managarm/generic/socket.cpp +++ b/sysdeps/managarm/generic/socket.cpp @@ -191,7 +191,7 @@ int sys_sockname(int fd, struct sockaddr *addr_ptr, socklen_t max_addr_length, managarm::fs::SvrResponse resp(getSysdepsAllocator()); resp.ParseFromArray(recv_resp.data(), recv_resp.length()); - if(resp.error() == managarm::fs::Errors::ILLEGAL_OPERATION_TARGET) { + if(resp.error() == managarm::fs::Errors::NOT_A_SOCKET) { return ENOTSOCK; } __ensure(resp.error() == managarm::fs::Errors::SUCCESS); @@ -234,7 +234,7 @@ int sys_peername(int fd, struct sockaddr *addr_ptr, socklen_t max_addr_length, managarm::fs::SvrResponse resp(getSysdepsAllocator()); resp.ParseFromArray(recvResp.data(), recvResp.length()); - if(resp.error() == managarm::fs::Errors::ILLEGAL_OPERATION_TARGET) { + if(resp.error() == managarm::fs::Errors::NOT_A_SOCKET) { return ENOTSOCK; }else if(resp.error() == managarm::fs::Errors::NOT_CONNECTED) { return ENOTCONN; @@ -364,11 +364,14 @@ int sys_setsockopt(int fd, int layer, int number, }else if(layer == IPPROTO_TCP && number == TCP_KEEPIDLE) { mlibc::infoLogger() << "\e[31mmlibc: setsockopt() call with IPPROTO_TCP and TCP_KEEPIDLE is unimplemented\e[39m" << frg::endlog; return 0; + }else if(layer == SOL_NETLINK && number == NETLINK_BROADCAST_ERROR) { + mlibc::infoLogger() << "\e[31mmlibc: setsockopt() call with SOL_NETLINK and NETLINK_BROADCAST_ERROR is unimplemented\e[39m" << frg::endlog; + return 0; }else if(layer == SOL_NETLINK && number == NETLINK_EXT_ACK) { mlibc::infoLogger() << "\e[31mmlibc: setsockopt() call with SOL_NETLINK and NETLINK_EXT_ACK is unimplemented\e[39m" << frg::endlog; return 0; }else if(layer == SOL_NETLINK && number == NETLINK_GET_STRICT_CHK) { - mlibc::infoLogger() << "\e[31mmlibc: setsockopt() call with SOL_NETLINK and NETLINK_EXT_ACK is unimplemented\e[39m" << frg::endlog; + mlibc::infoLogger() << "\e[31mmlibc: setsockopt() call with SOL_NETLINK and NETLINK_GET_STRICT_CHK is unimplemented\e[39m" << frg::endlog; return 0; }else if(layer == IPPROTO_TCP && number == TCP_KEEPINTVL) { mlibc::infoLogger() << "\e[31mmlibc: setsockopt() call with IPPROTO_TCP and TCP_KEEPINTVL is unimplemented\e[39m" << frg::endlog; diff --git a/sysdeps/managarm/include/mlibc/errors.hpp b/sysdeps/managarm/include/mlibc/errors.hpp new file mode 100644 index 0000000000..3b93205027 --- /dev/null +++ b/sysdeps/managarm/include/mlibc/errors.hpp @@ -0,0 +1,32 @@ +#ifndef MLIBC_ERRORS +#define MLIBC_ERRORS + +#include + +#include +#include + +constexpr bool logErrors = false; + +int posixErrorToError(managarm::posix::Errors posixError); +int fsErrorToError(managarm::fs::Errors posixError); + +#define POSIX_SUCCESS_OR_RETURN_ERROR(error) \ +if(int __error = posixErrorToError(error) != 0) { \ + if(logErrors) { \ + mlibc::infoLogger() << "mlibc: posix returned error " << (int)error << " (c error " << __error << ")\n" \ + " In file " __FILE__ " on line " HEL_STRINGIFY(__LINE__) "\n"; \ + } \ + return __error; \ +} + +#define FS_SUCCESS_OR_RETURN_ERROR(error) \ +if(int __error = fsErrorToError(error) != 0) { \ + if(logErrors) { \ + mlibc::infoLogger() << "mlibc: fs protocol returned error " << (int)error << " (c error " << __error << ")\n" \ + " In file " __FILE__ " on line " HEL_STRINGIFY(__LINE__) "\n"; \ + } \ + return __error; \ +} + +#endif diff --git a/sysdeps/managarm/meson.build b/sysdeps/managarm/meson.build index 34da8d77c5..584b244d31 100644 --- a/sysdeps/managarm/meson.build +++ b/sysdeps/managarm/meson.build @@ -35,6 +35,7 @@ libc_sources += files( 'generic/drm.cpp', 'generic/ensure.cpp', 'generic/entry.cpp', + 'generic/errors.cpp', 'generic/file.cpp', 'generic/fork-exec.cpp', 'generic/ioctl.cpp',