mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
f267925d45
Winsock APIs (socket, bind, connect, accept, recv, send, ...) report
errors via WSAGetLastError() and do not set errno, so mrb_sys_fail
on Windows was reading a stale or zero errno. Result: every socket
failure raised SystemCallError with errno 0 ("Success") instead of
the appropriate Errno::* class.
Add mrb_hal_socket_set_errno_from_last_error() to the HAL:
- POSIX: no-op (failed calls already set errno)
- Windows: maps WSAGetLastError() to a POSIX errno via wsa_to_errno()
with 32 cases covering the common Winsock error codes; unmapped
codes fall back to EIO. Each case is #ifdef-guarded against older
MSVC CRTs that lack a particular Exxx.
In src/socket.c, route the 22 socket-API failure sites through a new
sock_sys_fail() helper that calls the HAL translator before
mrb_sys_fail. Also fix mrb_hal_socket_set_nonblock() on Windows,
which was returning -1 without setting errno after ioctlsocket
failure.
POSIX behavior unchanged (verified: TCPSocket connect refused ->
Errno::ECONNREFUSED, bind to privileged port -> Errno::EACCES, bad
sockopt -> Errno::EOPNOTSUPP).
Closes #6819, reported by Asmod4n.
Co-authored-by: Claude <noreply@anthropic.com>
94 lines
2.9 KiB
C
94 lines
2.9 KiB
C
/*
|
|
** socket_hal.h - Socket HAL (Hardware Abstraction Layer) interface
|
|
**
|
|
** See Copyright Notice in mruby.h
|
|
**
|
|
** This header defines the platform-independent socket HAL interface.
|
|
** Platform-specific implementations are provided by HAL gems:
|
|
** - hal-posix-socket: POSIX socket implementation (Linux, macOS, BSD, Unix)
|
|
** - hal-win-socket: Windows socket implementation (Windows, MinGW)
|
|
*/
|
|
|
|
#ifndef MRUBY_SOCKET_HAL_H
|
|
#define MRUBY_SOCKET_HAL_H
|
|
|
|
#include <mruby.h>
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
/*
|
|
* Socket HAL Initialization/Finalization
|
|
*/
|
|
|
|
/* Initialize socket subsystem (e.g., WSAStartup on Windows) */
|
|
void mrb_hal_socket_init(mrb_state *mrb);
|
|
|
|
/* Finalize socket subsystem (e.g., WSACleanup on Windows) */
|
|
void mrb_hal_socket_final(mrb_state *mrb);
|
|
|
|
/*
|
|
* Error Handling
|
|
*/
|
|
|
|
/* Translate the most recent socket-API error into a POSIX errno value and
|
|
* store it in errno. On Windows, this reads WSAGetLastError() and maps it;
|
|
* on POSIX, this is a no-op (errno is already set by the failed call).
|
|
* Call this immediately after a socket-API failure, before mrb_sys_fail. */
|
|
void mrb_hal_socket_set_errno_from_last_error(void);
|
|
|
|
/*
|
|
* Socket Control Operations
|
|
*/
|
|
|
|
/* Set non-blocking mode on socket
|
|
* Returns 0 on success, -1 on error (sets errno) */
|
|
int mrb_hal_socket_set_nonblock(mrb_state *mrb, int fd, int nonblock);
|
|
|
|
/*
|
|
* Address Conversion Functions
|
|
*/
|
|
|
|
/* Convert network address to presentation format (string)
|
|
* af: address family (AF_INET, AF_INET6)
|
|
* src: network address in binary form
|
|
* dst: buffer for string result
|
|
* size: size of dst buffer
|
|
* Returns: dst on success, NULL on error */
|
|
const char* mrb_hal_socket_inet_ntop(int af, const void *src, char *dst, size_t size);
|
|
|
|
/* Convert presentation format (string) to network address
|
|
* af: address family (AF_INET, AF_INET6)
|
|
* src: string representation of address
|
|
* dst: buffer for network address result
|
|
* Returns: 1 on success, 0 if src is not valid, -1 on error */
|
|
int mrb_hal_socket_inet_pton(int af, const char *src, void *dst);
|
|
|
|
/*
|
|
* Platform-Specific Socket Features
|
|
*/
|
|
|
|
/* Create Unix domain socket address structure
|
|
* path: Unix socket path
|
|
* Returns: packed sockaddr string, or raises exception if not supported */
|
|
mrb_value mrb_hal_socket_sockaddr_un(mrb_state *mrb, const char *path, size_t pathlen);
|
|
|
|
/* Create a pair of connected sockets
|
|
* domain: address family (e.g., AF_UNIX)
|
|
* type: socket type (e.g., SOCK_STREAM)
|
|
* protocol: protocol (usually 0)
|
|
* sv: array to receive the two socket descriptors
|
|
* Returns: 0 on success, -1 on error (sets errno) */
|
|
int mrb_hal_socket_socketpair(mrb_state *mrb, int domain, int type, int protocol, int sv[2]);
|
|
|
|
/* Get Unix socket path from sockaddr
|
|
* Returns: Unix socket path string, or raises exception if not supported */
|
|
mrb_value mrb_hal_socket_unix_path(mrb_state *mrb, const char *sockaddr, size_t socklen);
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif /* MRUBY_SOCKET_HAL_H */
|