From c377cffe13ce580eb2a96740852d75258c7eb672 Mon Sep 17 00:00:00 2001 From: rw-r-r-0644 Date: Sun, 7 Mar 2021 13:09:12 +0100 Subject: [PATCH] Network socket changes (#136) --- Makefile | 1 + cafe/nsysnet.def | 18 +- include/arpa/inet.h | 48 ++++ include/curl/curlbuild.h | 2 +- include/netinet/in.h | 31 +++ include/netinet/tcp.h | 8 + include/nn/ac/ac_c.h | 20 ++ include/nsysnet/_socket.h | 158 ++++++++++++ include/nsysnet/nssl.h | 81 +++++- include/nsysnet/socket.h | 242 ++---------------- include/poll.h | 31 +++ include/sys/select.h | 5 + include/sys/socket.h | 155 +++++++++++ libraries/libwhb/include/whb/libmanager.h | 4 +- libraries/libwhb/src/libmanager.c | 24 -- libraries/libwhb/src/log_udp.c | 6 +- libraries/wutcrt/wut_crt.c | 4 + libraries/wutsocket/NSSLCreateConnection.c | 31 +++ libraries/wutsocket/accept.c | 32 +++ libraries/wutsocket/bind.c | 16 ++ libraries/wutsocket/connect.c | 15 ++ libraries/wutsocket/fcntl.c | 48 ++++ libraries/wutsocket/getpeername.c | 16 ++ libraries/wutsocket/getsockname.c | 16 ++ libraries/wutsocket/getsockopt.c | 18 ++ libraries/wutsocket/inet_addr.c | 11 + libraries/wutsocket/inet_ntop.c | 14 + libraries/wutsocket/inet_pton.c | 13 + libraries/wutsocket/listen.c | 15 ++ libraries/wutsocket/poll.c | 87 +++++++ libraries/wutsocket/recv.c | 17 ++ libraries/wutsocket/recvfrom.c | 19 ++ libraries/wutsocket/select.c | 103 ++++++++ libraries/wutsocket/send.c | 17 ++ libraries/wutsocket/sendto.c | 19 ++ libraries/wutsocket/setsockopt.c | 18 ++ libraries/wutsocket/shutdown.c | 15 ++ libraries/wutsocket/sockatmark.c | 18 ++ libraries/wutsocket/socket.c | 29 +++ libraries/wutsocket/wut_socket.c | 80 ++++++ libraries/wutsocket/wut_socket.h | 20 ++ libraries/wutsocket/wut_socket_close.c | 11 + libraries/wutsocket/wut_socket_common.c | 107 ++++++++ libraries/wutsocket/wut_socket_open.c | 13 + libraries/wutsocket/wut_socket_read.c | 13 + libraries/wutsocket/wut_socket_write.c | 13 + .../test_compile_headers_list.h | 2 +- 47 files changed, 1420 insertions(+), 264 deletions(-) create mode 100644 include/arpa/inet.h create mode 100644 include/netinet/in.h create mode 100644 include/netinet/tcp.h create mode 100644 include/nsysnet/_socket.h create mode 100644 include/poll.h create mode 100644 include/sys/select.h create mode 100644 include/sys/socket.h create mode 100644 libraries/wutsocket/NSSLCreateConnection.c create mode 100644 libraries/wutsocket/accept.c create mode 100644 libraries/wutsocket/bind.c create mode 100644 libraries/wutsocket/connect.c create mode 100644 libraries/wutsocket/fcntl.c create mode 100644 libraries/wutsocket/getpeername.c create mode 100644 libraries/wutsocket/getsockname.c create mode 100644 libraries/wutsocket/getsockopt.c create mode 100644 libraries/wutsocket/inet_addr.c create mode 100644 libraries/wutsocket/inet_ntop.c create mode 100644 libraries/wutsocket/inet_pton.c create mode 100644 libraries/wutsocket/listen.c create mode 100644 libraries/wutsocket/poll.c create mode 100644 libraries/wutsocket/recv.c create mode 100644 libraries/wutsocket/recvfrom.c create mode 100644 libraries/wutsocket/select.c create mode 100644 libraries/wutsocket/send.c create mode 100644 libraries/wutsocket/sendto.c create mode 100644 libraries/wutsocket/setsockopt.c create mode 100644 libraries/wutsocket/shutdown.c create mode 100644 libraries/wutsocket/sockatmark.c create mode 100644 libraries/wutsocket/socket.c create mode 100644 libraries/wutsocket/wut_socket.c create mode 100644 libraries/wutsocket/wut_socket.h create mode 100644 libraries/wutsocket/wut_socket_close.c create mode 100644 libraries/wutsocket/wut_socket_common.c create mode 100644 libraries/wutsocket/wut_socket_open.c create mode 100644 libraries/wutsocket/wut_socket_read.c create mode 100644 libraries/wutsocket/wut_socket_write.c diff --git a/Makefile b/Makefile index b4747e4..440f5f5 100644 --- a/Makefile +++ b/Makefile @@ -23,6 +23,7 @@ SOURCES := cafe \ libraries/wutstdc++ \ libraries/wutmalloc \ libraries/wutdevoptab \ + libraries/wutsocket \ libraries/libwhb/src \ libraries/libgfd/src \ libraries/nn_swkbd diff --git a/cafe/nsysnet.def b/cafe/nsysnet.def index ead94a5..8d6e8e7 100644 --- a/cafe/nsysnet.def +++ b/cafe/nsysnet.def @@ -4,7 +4,6 @@ NSSLAddServerPKI NSSLAddServerPKIExternal NSSLAddServerPKIGroups -NSSLCreateConnection NSSLCreateContext NSSLDestroyConnection NSSLDestroyContext @@ -71,6 +70,16 @@ WDUdsUninitParent WDWpsStart WDWpsStartAsync WDWpsStop +htonl +htons +inet_aton +inet_ntoa +inet_ntoa_r +ntohl +ntohs + +:TEXT_WRAP +NSSLCreateConnection accept bind clear_resolver_cache @@ -92,11 +101,6 @@ getpeername getsocklibopt getsockname getsockopt -htonl -htons -inet_aton -inet_ntoa -inet_ntoa_r inet_ntop inet_pton listen @@ -147,8 +151,6 @@ netconf_set_wifi_cfg netconf_setopt netconf_write_aoss_config netconf_write_compat_profile_id -ntohl -ntohs recv recvfrom recvfrom_ex diff --git a/include/arpa/inet.h b/include/arpa/inet.h new file mode 100644 index 0000000..db03747 --- /dev/null +++ b/include/arpa/inet.h @@ -0,0 +1,48 @@ +#pragma once +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +uint32_t +htonl(uint32_t hostlong); + +uint16_t +htons(uint16_t hostshort); + +uint32_t +ntohl(uint32_t netlong); + +uint16_t +ntohs(uint16_t netshort); + +in_addr_t +inet_addr(const char *cp); + +int +inet_aton(const char *cp, + struct in_addr *inp); + +char * +inet_ntoa(struct in_addr in); + +char * +inet_ntoa_r(struct in_addr in, + char *buf); + +const char * +inet_ntop(int af, + const void *src, + char *dst, + socklen_t size); + +int +inet_pton(int af, + const char *src, + void *dst); + +#ifdef __cplusplus +} +#endif diff --git a/include/curl/curlbuild.h b/include/curl/curlbuild.h index b5ad6bc..09d84c3 100644 --- a/include/curl/curlbuild.h +++ b/include/curl/curlbuild.h @@ -53,7 +53,7 @@ * */ -#include +#include /* ================================================================ */ /* DEFINITION OF THESE SYMBOLS SHALL NOT TAKE PLACE ANYWHERE ELSE */ diff --git a/include/netinet/in.h b/include/netinet/in.h new file mode 100644 index 0000000..3d13392 --- /dev/null +++ b/include/netinet/in.h @@ -0,0 +1,31 @@ +#pragma once +#include +#include + +#define INADDR_ANY 0x00000000 +#define INADDR_LOOPBACK 0x7F000001 +#define INADDR_BROADCAST 0xFFFFFFFF +#define INADDR_NONE 0xFFFFFFFF + +#define INET_ADDRSTRLEN 16 + +#define IPPROTO_IP 0 +#define IPPROTO_TCP 6 +#define IPPROTO_UDP 17 + +#define IP_TOS 3 +#define IP_TTL 4 + +typedef uint16_t in_port_t; +typedef uint32_t in_addr_t; + +struct in_addr { + in_addr_t s_addr; +}; + +struct sockaddr_in { + sa_family_t sin_family; + in_port_t sin_port; + struct in_addr sin_addr; + unsigned char sin_zero[8]; +}; diff --git a/include/netinet/tcp.h b/include/netinet/tcp.h new file mode 100644 index 0000000..05b446a --- /dev/null +++ b/include/netinet/tcp.h @@ -0,0 +1,8 @@ +#pragma once + +#define SOL_TCP 6 + +#define TCP_ACKDELAYTIME 0x2001 +#define TCP_NOACKDELAY 0x2002 +#define TCP_MAXSEG 0x2003 +#define TCP_NODELAY 0x2004 diff --git a/include/nn/ac/ac_c.h b/include/nn/ac/ac_c.h index d2a5361..1093b3f 100644 --- a/include/nn/ac/ac_c.h +++ b/include/nn/ac/ac_c.h @@ -43,6 +43,26 @@ ACInitialize(); void ACFinalize(); +/** + * Connects to a network, using the default configuration + * + * \return + * A \link nn_result Result\endlink - see \link NNResult_IsSuccess \endlink + * and \link NNResult_IsFailure \endlink. + */ +NNResult +ACConnect(); + +/** + * Checks whether the console is currently connected to a network. + * + * \return + * A \link nn_result Result\endlink - see \link NNResult_IsSuccess \endlink + * and \link NNResult_IsFailure \endlink. + */ +NNResult +ACIsApplicationConnected(BOOL *connected); + /** * Gets the default connection configuration id. This is the default as marked * in System Settings. diff --git a/include/nsysnet/_socket.h b/include/nsysnet/_socket.h new file mode 100644 index 0000000..f8848f2 --- /dev/null +++ b/include/nsysnet/_socket.h @@ -0,0 +1,158 @@ +#pragma once +#include +#include +#include +#include +#include +#include +#include +#include + +/** + * \defgroup nsysnet_socket Socket + * \ingroup nsysnet + * @{ + */ +#ifdef __cplusplus +extern "C" { +#endif + +/* + * fd_set for select() + */ +#define NSYSNET_FD_SETSIZE 32 + +#define NSYSNET_FD_SET(n, p) ((p)->fds_bits |= (1L << (n))) +#define NSYSNET_FD_CLR(n, p) ((p)->fds_bits &= ~(1L << (n))) +#define NSYSNET_FD_ISSET(n, p) ((p)->fds_bits & (1L << (n))) +#define NSYSNET_FD_ZERO(p) ((p)->fds_bits = 0L) + +typedef uint32_t nsysnet_fd_mask; +typedef struct nsysnet_fd_set nsysnet_fd_set; + +struct nsysnet_fd_set +{ + nsysnet_fd_mask fds_bits; +}; + +struct nsysnet_timeval +{ + long tv_sec; + long tv_usec; +}; + +void +RPLWRAP(socket_lib_init)(); + +void +RPLWRAP(socket_lib_finish)(); + +int +RPLWRAP(accept)(int sockfd, + struct sockaddr *addr, + socklen_t *addrlen); + +int +RPLWRAP(bind)(int sockfd, + const struct sockaddr *addr, + socklen_t addrlen); + +int +RPLWRAP(socketclose)(int sockfd); + +int +RPLWRAP(connect)(int sockfd, + const struct sockaddr *addr, + socklen_t addrlen); + +int +RPLWRAP(getpeername)(int sockfd, + struct sockaddr *addr, + socklen_t *addrlen); + +int +RPLWRAP(getsockname)(int sockfd, + struct sockaddr *addr, + socklen_t *addrlen); + +int +RPLWRAP(getsockopt)(int sockfd, + int level, + int optname, + void *optval, + socklen_t *optlen); + +int +RPLWRAP(listen)(int sockfd, + int backlog); + +int +RPLWRAP(recv)(int sockfd, + void *buf, + size_t len, + int flags); + +int +RPLWRAP(recvfrom)(int sockfd, + void *buf, + size_t len, + int flags, + struct sockaddr *src_addr, + socklen_t *addrlen); + +int +RPLWRAP(send)(int sockfd, + const void *buf, + size_t len, + int flags); + +int +RPLWRAP(sendto)(int sockfd, + const void *buf, + size_t len, + int flags, + const struct sockaddr *dest_addr, + socklen_t addrlen); + +int +RPLWRAP(setsockopt)(int sockfd, + int level, + int optname, + const void *optval, + socklen_t optlen); + +int +RPLWRAP(shutdown)(int sockfd, + int how); + +int +RPLWRAP(socket)(int domain, + int type, + int protocol); + +int +RPLWRAP(select)(int nfds, + nsysnet_fd_set *readfds, + nsysnet_fd_set *writefds, + nsysnet_fd_set *exceptfds, + struct nsysnet_timeval *timeout); + +const char * +RPLWRAP(inet_ntop)(int af, + const void *src, + char *dst, + socklen_t size); + +int +RPLWRAP(inet_pton)(int af, + const char *src, + void *dst); + +int +RPLWRAP(socketlasterr)(); + +#ifdef __cplusplus +} +#endif + +/** @} */ diff --git a/include/nsysnet/nssl.h b/include/nsysnet/nssl.h index b2e32ee..ebc6eaa 100644 --- a/include/nsysnet/nssl.h +++ b/include/nsysnet/nssl.h @@ -24,11 +24,71 @@ extern "C" { #endif +//! An NSSL library return code. +typedef int32_t NSSLError; //! A handle to a NSSL context created with NSSLCreateContext(). typedef int32_t NSSLContextHandle; //! A handle to a NSSL connection created with NSSLCreateConnection(). typedef int32_t NSSLConnectionHandle; +/** + * List of errors returned by the NSSL library. + */ +typedef enum NSSLErrors +{ + NSSL_ERROR_OK = 0x0, + NSSL_ERROR_GENERIC = -0x1, + NSSL_ERROR_INVALID_NSSL_CONTEXT = -0x280001, + NSSL_ERROR_INVALID_CERT_ID = -0x280002, + NSSL_ERROR_CERT_LIMIT = -0x280003, + NSSL_ERROR_INVALID_NSSL_CONNECTION = -0x280004, + NSSL_ERROR_INVALID_CERT = -0x280005, + NSSL_ERROR_ZERO_RETURN = -0x280006, + NSSL_ERROR_WANT_READ = -0x280007, + NSSL_ERROR_WANT_WRITE = -0x280008, + NSSL_ERROR_IO_ERROR = -0x280009, + NSSL_ERROR_NSSL_LIB_ERROR = -0x28000a, + NSSL_ERROR_UNKNOWN = -0x28000b, + NSSL_ERROR_OUT_OF_MEMORY = -0x28000c, + NSSL_ERROR_INVALID_STATE = -0x28000d, + NSSL_ERROR_HANDSHAKE_ERROR = -0x28000e, + NSSL_ERROR_NO_CERT = -0x28000f, + NSSL_ERROR_INVALID_FD = -0x280010, + NSSL_ERROR_LIB_NOT_READY = -0x280011, + NSSL_ERROR_IPC_ERROR = -0x280012, + NSSL_ERROR_RESOURCE_LIMIT = -0x280013, + NSSL_ERROR_INVALID_HANDLE = -0x280014, + NSSL_ERROR_INVALID_CERT_TYPE = -0x280015, + NSSL_ERROR_INVALID_KEY_TYPE = -0x280016, + NSSL_ERROR_INVALID_SIZE = -0x280017, + NSSL_ERROR_NO_PEER_CERT = -0x280018, + NSSL_ERROR_INSUFFICIENT_SIZE = -0x280019, + NSSL_ERROR_NO_CIPHER = -0x28001a, + NSSL_ERROR_INVALID_ARG = -0x28001b, + NSSL_ERROR_INVALID_NSSL_SESSION = -0x28001c, + NSSL_ERROR_NO_SESSION = -0x28001d, + NSSL_ERROR_SSL_SHUTDOWN_ERROR = -0x28001e, + NSSL_ERROR_CERT_SIZE_LIMIT = -0x28001f, + NSSL_ERROR_CERT_NO_ACCESS = -0x280020, + NSSL_ERROR_INVALID_CERT_ID2 = -0x280021, + NSSL_ERROR_CERT_READ_ERROR = -0x280022, + NSSL_ERROR_CERT_STORE_INIT_FAILURE = -0x280023, + NSSL_ERROR_INVALID_CERT_ENCODING = -0x280024, + NSSL_ERROR_CERT_STORE_ERROR = -0x280025, + NSSL_ERROR_PRIVATE_KEY_READ_ERROR = -0x280026, + NSSL_ERROR_INVALID_PRIVATE_KEY = -0x280027, + NSSL_ERROR_NOT_READY = -0x280028, + NSSL_ERROR_ENCRYPTION_ERROR = -0x280029, + NSSL_ERROR_NO_CERT_STORE = -0x28002a, + NSSL_ERROR_PRIVATE_KEY_SIZE_LIMIT = -0x28002b, + NSSL_ERROR_PROCESS_MAX_EXT_CERTS = -0x28002c, + NSSL_ERROR_PROCESS_MAX_CONTEXTS = -0x28002d, + NSSL_ERROR_PROCESS_MAX_CONNECTIONS = -0x28002e, + NSSL_ERROR_CERT_NOT_EXPORTABLE = -0x28002f, + NSSL_ERROR_INVALID_CERT_SIZE = -0x280030, + NSSL_ERROR_INVALID_KEY_SIZE = -0x280031, +} NSSLErrors; + /** * The IDs of a system CA. These certificates are built-in to the system and can * be added to a NSSL context with NSSLAddServerPKI(). @@ -191,7 +251,7 @@ typedef enum NSSLServerCertId * \sa * - NSSLFinish() */ -int32_t +NSSLError NSSLInit(); /** @@ -200,7 +260,7 @@ NSSLInit(); * \returns * 0 on success, or -1 on error. */ -int32_t +NSSLError NSSLFinish(); /** @@ -212,7 +272,7 @@ NSSLFinish(); * * \returns * A #NSSLContextHandle representing the newly created context, or a negative - * value on error. + * value among NSSLErrors on error. * * \sa * - NSSLDestroyContext() @@ -229,7 +289,7 @@ NSSLCreateContext(int32_t unk); * \returns * 0 on success, or a negative value if an error occurred. */ -int32_t +NSSLError NSSLDestroyContext(NSSLContextHandle context); /** @@ -258,7 +318,7 @@ NSSLDestroyContext(NSSLContextHandle context); * x509 in binary DER. What's a working value for unk? 0? * \endif */ -int32_t +NSSLError NSSLAddServerPKIExternal(NSSLContextHandle context, const void *cert, int32_t length, @@ -279,7 +339,7 @@ NSSLAddServerPKIExternal(NSSLContextHandle context, * \sa * - NSSLAddServerPKIExternal() */ -int32_t +NSSLError NSSLAddServerPKI(NSSLContextHandle context, NSSLServerCertId pki); @@ -305,7 +365,8 @@ NSSLAddServerPKI(NSSLContextHandle context, * If opening a new underlying socket, whether to open it in blocking mode. * * \returns - * A #NSSLConnectionHandle representing the current connection. + * A #NSSLConnectionHandle representing the current connection, or a negative + * value among NSSLErrors on error. * * \sa * - NSSLRead() @@ -333,7 +394,7 @@ NSSLCreateConnection(NSSLContextHandle context, * \returns * 0 on success or a negative error value. */ -int32_t +NSSLError NSSLDestroyConnection(NSSLConnectionHandle connection); /** @@ -358,7 +419,7 @@ NSSLDestroyConnection(NSSLConnectionHandle connection); * \sa * - NSSLWrite() */ -int32_t +NSSLError NSSLRead(NSSLConnectionHandle connection, const void *buffer, int32_t length, @@ -386,7 +447,7 @@ NSSLRead(NSSLConnectionHandle connection, * \sa * - NSSLRead() */ -int32_t +NSSLError NSSLWrite(NSSLConnectionHandle connection, const void *buffer, int32_t length, diff --git a/include/nsysnet/socket.h b/include/nsysnet/socket.h index b0f7877..182185c 100644 --- a/include/nsysnet/socket.h +++ b/include/nsysnet/socket.h @@ -1,238 +1,50 @@ #pragma once #include #include - -#define FD_SETSIZE 32 #include #include -#include +#include +#include +#include +#include +#include + +#warning "nsysnet/socket.h is deprecated; please use standard socket headers instead." -/** - * \defgroup nsysnet_socket Socket - * \ingroup nsysnet - * @{ - */ #ifdef __cplusplus extern "C" { #endif -#define SOL_SOCKET -1 +#define NSN_EAGAIN EAGAIN +#define NSN_EWOULDBLOCK EWOULDBLOCK -#define INADDR_ANY 0 -#define INADDR_BROADCAST 0xFFFFFFFF - -#define PF_UNSPEC 0 -#define PF_INET 2 -#define PF_INET6 23 - -#define AF_UNSPEC PF_UNSPEC -#define AF_INET PF_INET -#define AF_INET6 PF_INET6 - -#define SOCK_STREAM 1 -#define SOCK_DGRAM 2 - -#define MSG_OOB 0x0001 -#define MSG_PEEK 0x0002 -#define MSG_DONTROUTE 0x0004 -#define MSG_DONTWAIT 0x0020 - -#define SHUT_RD 0 -#define SHUT_WR 1 -#define SHUT_RDWR 2 - -#define IPPROTO_IP 0 -#define IPPROTO_TCP 6 -#define IPPROTO_UDP 17 - -/* - * SOL_SOCKET options - */ -#define SO_REUSEADDR 0x0004 // reuse address -#define SO_BROADCAST 0x0020 // broadcast -#define SO_LINGER 0x0080 // linger (no effect?) -#define SO_OOBINLINE 0x0100 // out-of-band data inline (no effect?) -#define SO_TCPSACK 0x0200 // set tcp selective acknowledgment -#define SO_WINSCALE 0x0400 // set tcp window scaling -#define SO_SNDBUF 0x1001 // send buffer size -#define SO_RCVBUF 0x1002 // receive buffer size -#define SO_SNDLOWAT 0x1003 // send low-water mark (no effect?) -#define SO_RCVLOWAT 0x1004 // receive low-water mark -#define SO_TYPE 0x1008 // get socket type -#define SO_ERROR 0x1009 // get socket error -#define SO_NBIO 0x1014 // set socket to NON-blocking mode -#define SO_BIO 0x1015 // set socket to blocking mode -#define SO_NONBLOCK 0x1016 // set/get blocking mode via optval param - -/* - * Errors returned by nsysnet socket functions - * WARNING: these do not match with sys/errno.h (where EAGAIN is 11 for example). - */ -#define NSN_EAGAIN 6 -#define NSN_EWOULDBLOCK 6 - -typedef uint32_t socklen_t; -typedef uint16_t sa_family_t; - -struct sockaddr +__attribute__ ((deprecated)) +static inline void +socket_lib_init() { - sa_family_t sa_family; - char sa_data[]; -}; +} -struct sockaddr_storage +__attribute__ ((deprecated)) +static inline void +socket_lib_finish() { - sa_family_t ss_family; - char ss_padding[14]; -}; +} -struct linger +__attribute__ ((deprecated)) +static inline int +socketclose(int sockfd) { - int l_onoff; - int l_linger; -}; + return close(sockfd); +} -struct in_addr +__attribute__ ((deprecated)) +static inline int +socketlasterr() { - unsigned int s_addr; -}; - -struct sockaddr_in -{ - unsigned short sin_family; - unsigned short sin_port; - struct in_addr sin_addr; - char sin_zero[8]; -}; - -void -socket_lib_init(); - -void -socket_lib_finish(); - -int -accept(int sockfd, - struct sockaddr *addr, - socklen_t *addrlen); - -int -bind(int sockfd, - const struct sockaddr *addr, - socklen_t addrlen); - -int -socketclose(int sockfd); - -int -connect(int sockfd, - const struct sockaddr *addr, - socklen_t addrlen); - -int -getpeername(int sockfd, - struct sockaddr *addr, - socklen_t *addrlen); - -int -getsockname(int sockfd, - struct sockaddr *addr, - socklen_t *addrlen); - -int -getsockopt(int sockfd, - int level, - int optname, - void *optval, - socklen_t *optlen); - -int -listen(int sockfd, - int backlog); - -int -recv(int sockfd, - void *buf, - size_t len, - int flags); - -int -recvfrom(int sockfd, - void *buf, - size_t len, - int flags, - struct sockaddr *src_addr, - socklen_t *addrlen); - -int -send(int sockfd, - const void *buf, - size_t len, - int flags); - -int -sendto(int sockfd, - const void *buf, - size_t len, - int flags, - const struct sockaddr *dest_addr, - socklen_t addrlen); - -int -setsockopt(int sockfd, - int level, - int optname, - const void *optval, - socklen_t optlen); - -int -shutdown(int sockfd, - int how); - -int -socket(int domain, - int type, - int protocol); - -int -select(int nfds, - fd_set *readfds, - fd_set *writefds, - fd_set *exceptfds, - struct timeval *timeout); - -const char * -inet_ntoa(struct in_addr in); - -char * -inet_ntoa_r(struct in_addr in, char *buf); - -const char * -inet_ntop(int af, const void *src, char *dst, socklen_t size); - -int -inet_pton(int af, const char *src, void *dst); - -int -inet_aton(const char *cp, struct in_addr *inp); - -int -socketlasterr(); - -uint32_t -htonl(uint32_t val); - -uint16_t -htons(uint16_t val); - -uint32_t -ntohl(uint32_t val); - -uint16_t -ntohs(uint16_t val); + return errno; +} #ifdef __cplusplus } #endif -/** @} */ diff --git a/include/poll.h b/include/poll.h new file mode 100644 index 0000000..f601fc4 --- /dev/null +++ b/include/poll.h @@ -0,0 +1,31 @@ +#pragma once + +#define POLLIN 0x01 +#define POLLPRI 0x02 +#define POLLOUT 0x04 +#define POLLERR 0x08 +#define POLLHUP 0x10 +#define POLLNVAL 0x20 + +typedef unsigned long nfds_t; + +struct pollfd +{ + int fd; + int events; + int revents; +}; + +#ifdef __cplusplus +extern "C" { +#endif + +int +poll(struct pollfd *fds, + nfds_t nfds, + int timeout); + +#ifdef __cplusplus +} +#endif + diff --git a/include/sys/select.h b/include/sys/select.h new file mode 100644 index 0000000..e5751c5 --- /dev/null +++ b/include/sys/select.h @@ -0,0 +1,5 @@ +#pragma once + +#define FD_SETSIZE 32 + +#include_next diff --git a/include/sys/socket.h b/include/sys/socket.h new file mode 100644 index 0000000..95fbab9 --- /dev/null +++ b/include/sys/socket.h @@ -0,0 +1,155 @@ +#pragma once +#include +#include + +#define SOL_SOCKET -1 + +#define PF_UNSPEC 0 +#define PF_INET 2 + +#define AF_UNSPEC PF_UNSPEC +#define AF_INET PF_INET + +#define SOCK_STREAM 1 +#define SOCK_DGRAM 2 + +#define MSG_OOB 0x0001 +#define MSG_PEEK 0x0002 +#define MSG_DONTROUTE 0x0004 +#define MSG_DONTWAIT 0x0020 + +#define SHUT_RD 0 +#define SHUT_WR 1 +#define SHUT_RDWR 2 + +/* + * SOL_SOCKET options + */ +#define SO_REUSEADDR 0x0004 // reuse address +#define SO_BROADCAST 0x0020 // broadcast +#define SO_LINGER 0x0080 // linger (no effect?) +#define SO_OOBINLINE 0x0100 // out-of-band data inline (no effect?) +#define SO_TCPSACK 0x0200 // set tcp selective acknowledgment +#define SO_WINSCALE 0x0400 // set tcp window scaling +#define SO_SNDBUF 0x1001 // send buffer size +#define SO_RCVBUF 0x1002 // receive buffer size +#define SO_SNDLOWAT 0x1003 // send low-water mark (no effect?) +#define SO_RCVLOWAT 0x1004 // receive low-water mark +#define SO_TYPE 0x1008 // get socket type +#define SO_ERROR 0x1009 // get socket error +#define SO_NBIO 0x1014 // set socket to NON-blocking mode +#define SO_BIO 0x1015 // set socket to blocking mode +#define SO_NONBLOCK 0x1016 // set/get blocking mode via optval param + +typedef uint32_t socklen_t; +typedef uint16_t sa_family_t; + +struct sockaddr +{ + sa_family_t sa_family; + char sa_data[]; +}; + +struct sockaddr_storage +{ + sa_family_t ss_family; + char ss_padding[14]; +}; + +struct linger +{ + int l_onoff; + int l_linger; +}; + +#ifdef __cplusplus +extern "C" { +#endif + +int +accept(int sockfd, + struct sockaddr *addr, + socklen_t *addrlen); + +int +bind(int sockfd, + const struct sockaddr *addr, + socklen_t addrlen); + +int +connect(int sockfd, + const struct sockaddr *addr, + socklen_t addrlen); + +int +getpeername(int sockfd, + struct sockaddr *addr, + socklen_t *addrlen); + +int +getsockname(int sockfd, + struct sockaddr *addr, + socklen_t *addrlen); + +int +getsockopt(int sockfd, + int level, + int optname, + void *optval, + socklen_t *optlen); + +int +listen(int sockfd, + int backlog); + +ssize_t +recv(int sockfd, + void *buf, + size_t len, + int flags); + +ssize_t +recvfrom(int sockfd, + void *buf, + size_t len, + int flags, + struct sockaddr *src_addr, + socklen_t *addrlen); + +ssize_t +send(int sockfd, + const void *buf, + size_t len, + int flags); + +ssize_t +sendto(int sockfd, + const void *buf, + size_t len, + int flags, + const struct sockaddr *dest_addr, + socklen_t addrlen); + +int +setsockopt(int sockfd, + int level, + int optname, + const void *optval, + socklen_t optlen); + +int +shutdown(int sockfd, + int how); + +int +socket(int domain, + int type, + int protocol); + +int +sockatmark(int sockfd); + +#ifdef __cplusplus +} +#endif + diff --git a/libraries/libwhb/include/whb/libmanager.h b/libraries/libwhb/include/whb/libmanager.h index d088997..42a179a 100644 --- a/libraries/libwhb/include/whb/libmanager.h +++ b/libraries/libwhb/include/whb/libmanager.h @@ -14,10 +14,10 @@ extern "C" { * Socket Library (nsysnet.rpl) */ -void +__attribute__ ((deprecated)) void WHBInitializeSocketLibrary(); -void +__attribute__ ((deprecated)) void WHBDeinitializeSocketLibrary(); #ifdef __cplusplus diff --git a/libraries/libwhb/src/libmanager.c b/libraries/libwhb/src/libmanager.c index 3701b00..c3fac99 100644 --- a/libraries/libwhb/src/libmanager.c +++ b/libraries/libwhb/src/libmanager.c @@ -1,33 +1,9 @@ -#include - -/** - * Socket Library (nsysnet.rpl) - */ - -static BOOL -isSocketInitialized = FALSE; - -static unsigned int -numberOfSocketClients = 0; - void WHBInitializeSocketLibrary() { - if(!isSocketInitialized) { - isSocketInitialized = TRUE; - socket_lib_init(); - } - numberOfSocketClients++; } void WHBDeinitializeSocketLibrary() { - if(numberOfSocketClients > 0) { - numberOfSocketClients--; - } - if(isSocketInitialized && numberOfSocketClients == 0) { - isSocketInitialized = FALSE; - socket_lib_finish(); - } } diff --git a/libraries/libwhb/src/log_udp.c b/libraries/libwhb/src/log_udp.c index e875ba8..4027d9b 100644 --- a/libraries/libwhb/src/log_udp.c +++ b/libraries/libwhb/src/log_udp.c @@ -1,6 +1,8 @@ #include #include -#include +#include +#include +#include #include #include #include @@ -29,7 +31,6 @@ BOOL WHBLogUdpInit() { int broadcastEnable = 1; - WHBInitializeSocketLibrary(); sSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); if (sSocket < 0) { @@ -53,6 +54,5 @@ WHBLogUdpDeinit() return FALSE; } - WHBDeinitializeSocketLibrary(); return WHBRemoveLogHandler(udpLogHandler); } diff --git a/libraries/wutcrt/wut_crt.c b/libraries/wutcrt/wut_crt.c index 82931af..3da4244 100644 --- a/libraries/wutcrt/wut_crt.c +++ b/libraries/wutcrt/wut_crt.c @@ -2,11 +2,13 @@ void __init_wut_malloc(); void __init_wut_newlib(); extern void __init_wut_stdcpp(); void __init_wut_devoptab(); +void __init_wut_socket(); void __fini_wut_malloc(); void __fini_wut_newlib(); extern void __fini_wut_stdcpp(); void __fini_wut_devoptab(); +void __fini_wut_socket(); void __attribute__((weak)) __init_wut() @@ -17,11 +19,13 @@ __init_wut() __init_wut_stdcpp(); //} __init_wut_devoptab(); + __init_wut_socket(); } void __attribute__((weak)) __fini_wut() { + __fini_wut_socket(); __fini_wut_devoptab(); //if (__fini_wut_stdcpp) { __fini_wut_stdcpp(); diff --git a/libraries/wutsocket/NSSLCreateConnection.c b/libraries/wutsocket/NSSLCreateConnection.c new file mode 100644 index 0000000..69441bb --- /dev/null +++ b/libraries/wutsocket/NSSLCreateConnection.c @@ -0,0 +1,31 @@ +#include "wut_socket.h" +#include + +NSSLConnectionHandle +RPLWRAP(NSSLCreateConnection)(NSSLContextHandle context, + const char *host, + int32_t hostLength, + int32_t options, + int32_t socket, + int32_t block); + +NSSLConnectionHandle +NSSLCreateConnection(NSSLContextHandle context, + const char *host, + int32_t hostLength, + int32_t options, + int32_t socket, + int32_t block) +{ + socket = __wut_get_nsysnet_fd(socket); + if (socket == -1) { + return NSSL_ERROR_INVALID_FD; + } + + return RPLWRAP(NSSLCreateConnection)(context, + host, + hostLength, + options, + socket, + block); +} diff --git a/libraries/wutsocket/accept.c b/libraries/wutsocket/accept.c new file mode 100644 index 0000000..8339ce8 --- /dev/null +++ b/libraries/wutsocket/accept.c @@ -0,0 +1,32 @@ +#include "wut_socket.h" + +int +accept(int sockfd, + struct sockaddr *address, + socklen_t *addrlen) +{ + int rc, fd, dev; + + fd = __wut_get_nsysnet_fd(sockfd); + if (fd == -1) { + return -1; + } + + dev = __get_handle(sockfd)->device; + sockfd = fd; + + fd = __alloc_handle(dev); + if (fd == -1) { + return -1; + } + + rc = RPLWRAP(accept)(sockfd, address, addrlen); + if (rc == -1) { + __release_handle(fd); + return __wut_get_nsysnet_result(NULL, rc); + } + + *(int *)__get_handle(fd)->fileStruct = rc; + return fd; +} + diff --git a/libraries/wutsocket/bind.c b/libraries/wutsocket/bind.c new file mode 100644 index 0000000..57b139e --- /dev/null +++ b/libraries/wutsocket/bind.c @@ -0,0 +1,16 @@ +#include "wut_socket.h" + +int +bind(int sockfd, + const struct sockaddr *addr, + socklen_t addrlen) +{ + int rc; + sockfd = __wut_get_nsysnet_fd(sockfd); + if (sockfd == -1) { + return -1; + } + rc = RPLWRAP(bind)(sockfd, addr, addrlen); + return __wut_get_nsysnet_result(NULL, rc); +} + diff --git a/libraries/wutsocket/connect.c b/libraries/wutsocket/connect.c new file mode 100644 index 0000000..6f83f8e --- /dev/null +++ b/libraries/wutsocket/connect.c @@ -0,0 +1,15 @@ +#include "wut_socket.h" + +int connect(int sockfd, + const struct sockaddr *addr, + socklen_t addrlen) +{ + int rc; + sockfd = __wut_get_nsysnet_fd(sockfd); + if (sockfd == -1) { + return -1; + } + rc = RPLWRAP(connect)(sockfd, addr, addrlen); + return __wut_get_nsysnet_result(NULL, rc); +} + diff --git a/libraries/wutsocket/fcntl.c b/libraries/wutsocket/fcntl.c new file mode 100644 index 0000000..804b349 --- /dev/null +++ b/libraries/wutsocket/fcntl.c @@ -0,0 +1,48 @@ +#include "wut_socket.h" + +int +fcntl(int fd, + int cmd, ...) +{ + va_list args; + int sockfd, rc, flags, nonblock; + socklen_t nonblock_len = sizeof(nonblock); + + if (cmd != F_GETFL && cmd != F_SETFL) { + errno = EOPNOTSUPP; + return -1; + } + + sockfd = __wut_get_nsysnet_fd(fd); + if (sockfd == -1) { + return -1; + } + + /* F_SETFL */ + if (cmd == F_SETFL) { + va_start(args, cmd); + flags = va_arg(args, int); + va_end(args); + + nonblock = !!(flags & O_NONBLOCK); + rc = RPLWRAP(setsockopt)(sockfd, + SOL_SOCKET, + SO_NONBLOCK, + &nonblock, + nonblock_len); + return __wut_get_nsysnet_result(NULL, rc); + } + + /* F_GETFL */ + rc = RPLWRAP(getsockopt)(sockfd, + SOL_SOCKET, + SO_NONBLOCK, + &nonblock, + &nonblock_len); + if (rc == -1) { + return __wut_get_nsysnet_result(NULL, rc); + } + flags = (nonblock) ? O_NONBLOCK : 0; + return flags; +} + diff --git a/libraries/wutsocket/getpeername.c b/libraries/wutsocket/getpeername.c new file mode 100644 index 0000000..f5b0e36 --- /dev/null +++ b/libraries/wutsocket/getpeername.c @@ -0,0 +1,16 @@ +#include "wut_socket.h" + +int +getpeername(int sockfd, + struct sockaddr *addr, + socklen_t *addrlen) +{ + int rc; + sockfd = __wut_get_nsysnet_fd(sockfd); + if (sockfd == -1) { + return -1; + } + rc = RPLWRAP(getpeername)(sockfd, addr, addrlen); + return __wut_get_nsysnet_result(NULL, rc); +} + diff --git a/libraries/wutsocket/getsockname.c b/libraries/wutsocket/getsockname.c new file mode 100644 index 0000000..e9cc3bf --- /dev/null +++ b/libraries/wutsocket/getsockname.c @@ -0,0 +1,16 @@ +#include "wut_socket.h" + +int +getsockname(int sockfd, + struct sockaddr *addr, + socklen_t *addrlen) +{ + int rc; + sockfd = __wut_get_nsysnet_fd(sockfd); + if (sockfd == -1) { + return -1; + } + rc = RPLWRAP(getsockname)(sockfd, addr, addrlen); + return __wut_get_nsysnet_result(NULL, rc); +} + diff --git a/libraries/wutsocket/getsockopt.c b/libraries/wutsocket/getsockopt.c new file mode 100644 index 0000000..13f8c51 --- /dev/null +++ b/libraries/wutsocket/getsockopt.c @@ -0,0 +1,18 @@ +#include "wut_socket.h" + +int +getsockopt(int sockfd, + int level, + int optname, + void *optval, + socklen_t *optlen) +{ + int rc; + sockfd = __wut_get_nsysnet_fd(sockfd); + if (sockfd == -1) { + return -1; + } + rc = RPLWRAP(getsockopt)(sockfd, level, optname, optval, optlen); + return __wut_get_nsysnet_result(NULL, rc); +} + diff --git a/libraries/wutsocket/inet_addr.c b/libraries/wutsocket/inet_addr.c new file mode 100644 index 0000000..53dc7c1 --- /dev/null +++ b/libraries/wutsocket/inet_addr.c @@ -0,0 +1,11 @@ +#include "wut_socket.h" + +in_addr_t +inet_addr(const char *cp) +{ + struct in_addr addr = { + .s_addr = INADDR_NONE, + }; + inet_aton(cp, &addr); + return addr.s_addr; +} diff --git a/libraries/wutsocket/inet_ntop.c b/libraries/wutsocket/inet_ntop.c new file mode 100644 index 0000000..b932a8e --- /dev/null +++ b/libraries/wutsocket/inet_ntop.c @@ -0,0 +1,14 @@ +#include "wut_socket.h" + +const char * +inet_ntop(int af, + const void *src, + char *dst, + socklen_t size) +{ + const char *rc = RPLWRAP(inet_ntop)(af, src, dst, size); + if (!rc) { + errno = EAFNOSUPPORT; + } + return rc; +} diff --git a/libraries/wutsocket/inet_pton.c b/libraries/wutsocket/inet_pton.c new file mode 100644 index 0000000..9aa0e49 --- /dev/null +++ b/libraries/wutsocket/inet_pton.c @@ -0,0 +1,13 @@ +#include "wut_socket.h" + +int +inet_pton(int af, + const char *src, + void *dst) +{ + int rc = RPLWRAP(inet_pton)(af, src, dst); + if (rc < 0) { + errno = EAFNOSUPPORT; + } + return rc; +} diff --git a/libraries/wutsocket/listen.c b/libraries/wutsocket/listen.c new file mode 100644 index 0000000..61562b2 --- /dev/null +++ b/libraries/wutsocket/listen.c @@ -0,0 +1,15 @@ +#include "wut_socket.h" + +int +listen(int sockfd, + int backlog) +{ + int rc; + sockfd = __wut_get_nsysnet_fd(sockfd); + if (sockfd == -1) { + return -1; + } + rc = RPLWRAP(listen)(sockfd, backlog); + return __wut_get_nsysnet_result(NULL, rc); +} + diff --git a/libraries/wutsocket/poll.c b/libraries/wutsocket/poll.c new file mode 100644 index 0000000..27c2672 --- /dev/null +++ b/libraries/wutsocket/poll.c @@ -0,0 +1,87 @@ +#include "wut_socket.h" + +int +poll(struct pollfd *fds, + nfds_t nfds, + int timeout) +{ + int cnv_nfds = 0, rc, i; + nsysnet_fd_set cnv_rd, cnv_wr, cnv_ex; + struct nsysnet_timeval cnv_timeout; + + if (!fds) { + errno = EINVAL; + return -1; + } + + NSYSNET_FD_ZERO(&cnv_rd); + NSYSNET_FD_ZERO(&cnv_wr); + NSYSNET_FD_ZERO(&cnv_ex); + + for (i = 0; i < nfds; i++) { + int cnv_fd; + + if (fds[i].fd < 0) { + continue; + } + + cnv_fd = __wut_get_nsysnet_fd(fds[i].fd); + if (cnv_fd == -1) { + return -1; + } + + if ((cnv_fd + 1) > cnv_nfds) { + cnv_nfds = cnv_fd + 1; + } + + if (fds[i].events & POLLIN) { + NSYSNET_FD_SET(cnv_fd, &cnv_rd); + } + if (fds[i].events & POLLOUT) { + NSYSNET_FD_SET(cnv_fd, &cnv_wr); + } + if (fds[i].events & POLLPRI) { + NSYSNET_FD_SET(cnv_fd, &cnv_ex); + } + } + + if (timeout >= 0) { + cnv_timeout.tv_sec = timeout / 1000; + cnv_timeout.tv_usec = (timeout % 1000) * 1000; + } + + rc = RPLWRAP(select)(cnv_nfds, &cnv_rd, &cnv_wr, &cnv_ex, + (timeout >= 0) ? &cnv_timeout : NULL); + + rc = __wut_get_nsysnet_result(NULL, rc); + if (rc == -1) { + return rc; + } + + for (i = 0; i < nfds; i++) { + int cnv_fd; + + fds[i].revents = 0; + + if (fds[i].fd < 0) { + continue; + } + + cnv_fd = __wut_get_nsysnet_fd(fds[i].fd); + if (cnv_fd == -1) { + continue; + } + + if (NSYSNET_FD_ISSET(cnv_fd, &cnv_rd)) { + fds[i].revents |= POLLIN; + } + if (NSYSNET_FD_ISSET(cnv_fd, &cnv_wr)) { + fds[i].revents |= POLLOUT; + } + if (NSYSNET_FD_ISSET(cnv_fd, &cnv_ex)) { + fds[i].revents |= POLLPRI; + } + } + + return rc; +} diff --git a/libraries/wutsocket/recv.c b/libraries/wutsocket/recv.c new file mode 100644 index 0000000..2475bdd --- /dev/null +++ b/libraries/wutsocket/recv.c @@ -0,0 +1,17 @@ +#include "wut_socket.h" + +ssize_t +recv(int sockfd, + void *buf, + size_t len, + int flags) +{ + int rc; + sockfd = __wut_get_nsysnet_fd(sockfd); + if (sockfd == -1) { + return -1; + } + rc = RPLWRAP(recv)(sockfd, buf, len, flags); + return (ssize_t)__wut_get_nsysnet_result(NULL, rc); +} + diff --git a/libraries/wutsocket/recvfrom.c b/libraries/wutsocket/recvfrom.c new file mode 100644 index 0000000..54039d0 --- /dev/null +++ b/libraries/wutsocket/recvfrom.c @@ -0,0 +1,19 @@ +#include "wut_socket.h" + +ssize_t +recvfrom(int sockfd, + void *buf, + size_t len, + int flags, + struct sockaddr *src_addr, + socklen_t *addrlen) +{ + int rc; + sockfd = __wut_get_nsysnet_fd(sockfd); + if (sockfd == -1) { + return -1; + } + rc = RPLWRAP(recvfrom)(sockfd, buf, len, flags, src_addr, addrlen); + return (ssize_t)__wut_get_nsysnet_result(NULL, rc); +} + diff --git a/libraries/wutsocket/select.c b/libraries/wutsocket/select.c new file mode 100644 index 0000000..4190f99 --- /dev/null +++ b/libraries/wutsocket/select.c @@ -0,0 +1,103 @@ +#include "wut_socket.h" + +int +select(int nfds, + fd_set *readfds, + fd_set *writefds, + fd_set *exceptfds, + struct timeval *timeout) +{ + int cnv_nfds = 0, rc, i; + nsysnet_fd_set cnv_rd, cnv_wr, cnv_ex; + struct nsysnet_timeval cnv_timeout; + + if (nfds > FD_SETSIZE) { + errno = EINVAL; + return -1; + } + + NSYSNET_FD_ZERO(&cnv_rd); + NSYSNET_FD_ZERO(&cnv_wr); + NSYSNET_FD_ZERO(&cnv_ex); + + for (i = 0; i < nfds; i++) { + int rd_fd, wr_fd, ex_fd, cnv_fd; + + rd_fd = readfds && FD_ISSET(i, readfds); + wr_fd = writefds && FD_ISSET(i, writefds); + ex_fd = exceptfds && FD_ISSET(i, exceptfds); + + if (!rd_fd && !wr_fd && !ex_fd) { + continue; + } + + cnv_fd = __wut_get_nsysnet_fd(i); + if (cnv_fd == -1) { + return -1; + } + + if ((cnv_fd + 1) > cnv_nfds) { + cnv_nfds = cnv_fd + 1; + } + + if (rd_fd) { + NSYSNET_FD_SET(cnv_fd, &cnv_rd); + } + if (wr_fd) { + NSYSNET_FD_SET(cnv_fd, &cnv_wr); + } + if (ex_fd) { + NSYSNET_FD_SET(cnv_fd, &cnv_ex); + } + } + + if (timeout) { + cnv_timeout.tv_sec = timeout->tv_sec; + cnv_timeout.tv_usec = timeout->tv_usec; + } + + rc = RPLWRAP(select)(cnv_nfds, + readfds ? &cnv_rd : NULL, + writefds ? &cnv_wr : NULL, + exceptfds ? &cnv_ex : NULL, + timeout ? &cnv_timeout : NULL); + + rc = __wut_get_nsysnet_result(NULL, rc); + if (rc == -1) { + return rc; + } + + rc = 0; + + if (readfds) { + FD_ZERO(readfds); + } + if (writefds) { + FD_ZERO(writefds); + } + if (exceptfds) { + FD_ZERO(exceptfds); + } + + for (i = 0; i < nfds; i++) { + int cnv_fd = __wut_get_nsysnet_fd(i); + if (cnv_fd == -1) { + continue; + } + + if (NSYSNET_FD_ISSET(cnv_fd, &cnv_rd)) { + FD_SET(i, readfds); + rc++; + } + if (NSYSNET_FD_ISSET(cnv_fd, &cnv_wr)) { + FD_SET(i, writefds); + rc++; + } + if (NSYSNET_FD_ISSET(cnv_fd, &cnv_ex)) { + FD_SET(i, exceptfds); + rc++; + } + } + + return rc; +} diff --git a/libraries/wutsocket/send.c b/libraries/wutsocket/send.c new file mode 100644 index 0000000..729a88b --- /dev/null +++ b/libraries/wutsocket/send.c @@ -0,0 +1,17 @@ +#include "wut_socket.h" + +ssize_t +send(int sockfd, + const void* buf, + size_t len, + int flags) +{ + int rc; + sockfd = __wut_get_nsysnet_fd(sockfd); + if (sockfd == -1) { + return -1; + } + rc = RPLWRAP(send)(sockfd, buf, len, flags); + return (ssize_t)__wut_get_nsysnet_result(NULL, rc); +} + diff --git a/libraries/wutsocket/sendto.c b/libraries/wutsocket/sendto.c new file mode 100644 index 0000000..7208c36 --- /dev/null +++ b/libraries/wutsocket/sendto.c @@ -0,0 +1,19 @@ +#include "wut_socket.h" + +ssize_t +sendto(int sockfd, + const void *buf, + size_t len, + int flags, + const struct sockaddr *dest_addr, + socklen_t addrlen) +{ + int rc; + sockfd = __wut_get_nsysnet_fd(sockfd); + if (sockfd == -1) { + return -1; + } + rc = RPLWRAP(sendto)(sockfd, buf, len, flags, dest_addr, addrlen); + return (ssize_t)__wut_get_nsysnet_result(NULL, rc); +} + diff --git a/libraries/wutsocket/setsockopt.c b/libraries/wutsocket/setsockopt.c new file mode 100644 index 0000000..20c4dc3 --- /dev/null +++ b/libraries/wutsocket/setsockopt.c @@ -0,0 +1,18 @@ +#include "wut_socket.h" + +int +setsockopt(int sockfd, + int level, + int optname, + const void *optval, + socklen_t optlen) +{ + int rc; + sockfd = __wut_get_nsysnet_fd(sockfd); + if (sockfd == -1) { + return -1; + } + rc = RPLWRAP(setsockopt)(sockfd, level, optname, optval, optlen); + return __wut_get_nsysnet_result(NULL, rc); +} + diff --git a/libraries/wutsocket/shutdown.c b/libraries/wutsocket/shutdown.c new file mode 100644 index 0000000..38c1228 --- /dev/null +++ b/libraries/wutsocket/shutdown.c @@ -0,0 +1,15 @@ +#include "wut_socket.h" + +int +shutdown(int sockfd, + int how) +{ + int rc; + sockfd = __wut_get_nsysnet_fd(sockfd); + if (sockfd == -1) { + return -1; + } + rc = RPLWRAP(shutdown)(sockfd, how); + return __wut_get_nsysnet_result(NULL, rc); +} + diff --git a/libraries/wutsocket/sockatmark.c b/libraries/wutsocket/sockatmark.c new file mode 100644 index 0000000..fa062d5 --- /dev/null +++ b/libraries/wutsocket/sockatmark.c @@ -0,0 +1,18 @@ +#include "wut_socket.h" + +int sockatmark(int sockfd) +{ + char buf[1]; + int rc; + + sockfd = __wut_get_nsysnet_fd(sockfd); + + rc = RPLWRAP(recv)(sockfd, buf, sizeof(buf), MSG_OOB | MSG_PEEK | MSG_DONTWAIT); + if (rc > 0) { + return 1; + } + + rc = __wut_get_nsysnet_result(NULL, rc); + + return (errno == EWOULDBLOCK) ? 0 : rc; +} diff --git a/libraries/wutsocket/socket.c b/libraries/wutsocket/socket.c new file mode 100644 index 0000000..8f16e39 --- /dev/null +++ b/libraries/wutsocket/socket.c @@ -0,0 +1,29 @@ +#include "wut_socket.h" + +int +socket(int domain, + int type, + int protocol) +{ + int rc, fd, dev; + + dev = FindDevice("sock:"); + if (dev == -1) { + return -1; + } + + fd = __alloc_handle(dev); + if (fd == -1) { + return -1; + } + + rc = RPLWRAP(socket)(domain, type, protocol); + if (rc == -1) { + __release_handle(fd); + return __wut_get_nsysnet_result(NULL, rc); + } + + *(int *)__get_handle(fd)->fileStruct = rc; + return fd; +} + diff --git a/libraries/wutsocket/wut_socket.c b/libraries/wutsocket/wut_socket.c new file mode 100644 index 0000000..336e0e5 --- /dev/null +++ b/libraries/wutsocket/wut_socket.c @@ -0,0 +1,80 @@ +#include "wut_socket.h" + +static devoptab_t +__wut_socket_devoptab = +{ + .name = "sock", + .structSize = sizeof(int), + .open_r = __wut_socket_open, + .close_r = __wut_socket_close, + .write_r = __wut_socket_write, + .read_r = __wut_socket_read, + .seek_r = NULL, + .fstat_r = NULL, + .stat_r = NULL, + .link_r = NULL, + .unlink_r = NULL, + .chdir_r = NULL, + .rename_r = NULL, + .mkdir_r = NULL, + .dirStateSize = 0, + .diropen_r = NULL, + .dirreset_r = NULL, + .dirnext_r = NULL, + .dirclose_r = NULL, + .statvfs_r = NULL, + .ftruncate_r = NULL, + .fsync_r = NULL, + .deviceData = 0, + .chmod_r = NULL, + .fchmod_r = NULL, + .rmdir_r = NULL, +}; + +static BOOL +__wut_socket_initialised = FALSE; + +void +__init_wut_socket() +{ + BOOL connected = FALSE; + int dev; + + if (__wut_socket_initialised) { + return; + } + + ACInitialize(); + ACConnect(); + + ACIsApplicationConnected(&connected); + if (!connected) { + ACFinalize(); + return; + } + + RPLWRAP(socket_lib_init)(); + + dev = AddDevice(&__wut_socket_devoptab); + if (dev == -1) { + RPLWRAP(socket_lib_finish)(); + ACFinalize(); + return; + } + + __wut_socket_initialised = TRUE; +} + +void +__fini_wut_socket() +{ + if (!__wut_socket_initialised) { + return; + } + + RPLWRAP(socket_lib_finish)(); + ACFinalize(); + + __wut_socket_initialised = FALSE; +} + diff --git a/libraries/wutsocket/wut_socket.h b/libraries/wutsocket/wut_socket.h new file mode 100644 index 0000000..bf47bb5 --- /dev/null +++ b/libraries/wutsocket/wut_socket.h @@ -0,0 +1,20 @@ +#pragma once +#include +#include +#include +#include +#include +#include +#include +#include +#define __LINUX_ERRNO_EXTENSIONS__ +#include + +int __wut_get_nsysnet_fd(int fd); +int __wut_get_nsysnet_result(struct _reent *r, int rc); + +int __wut_socket_open(struct _reent *r, void *fileStruct, const char *path, int flags, int mode); +int __wut_socket_close(struct _reent *r, void *fd); +ssize_t __wut_socket_write(struct _reent *r, void *fd, const char *ptr, size_t len); +ssize_t __wut_socket_read(struct _reent *r, void *fd, char *ptr, size_t len); + diff --git a/libraries/wutsocket/wut_socket_close.c b/libraries/wutsocket/wut_socket_close.c new file mode 100644 index 0000000..7826771 --- /dev/null +++ b/libraries/wutsocket/wut_socket_close.c @@ -0,0 +1,11 @@ +#include "wut_socket.h" + +int +__wut_socket_close(struct _reent *r, + void *fd) +{ + int sockfd = *(int *)fd; + int rc = RPLWRAP(socketclose)(sockfd); + return __wut_get_nsysnet_result(r, rc); +} + diff --git a/libraries/wutsocket/wut_socket_common.c b/libraries/wutsocket/wut_socket_common.c new file mode 100644 index 0000000..366f7ab --- /dev/null +++ b/libraries/wutsocket/wut_socket_common.c @@ -0,0 +1,107 @@ +#include "wut_socket.h" + +#define NSYSNET_UNKNOWN_ERROR_OFFSET 10000 + +static unsigned char +__wut_nsysnet_error_code_map[] = +{ + 0, // 0 + ENOBUFS, + ETIMEDOUT, + EISCONN, + EOPNOTSUPP, + ECONNABORTED, // 5 + EWOULDBLOCK, + ECONNREFUSED, + ECONNRESET, + ENOTCONN, + EALREADY, // 10 + EINVAL, + EMSGSIZE, + EPIPE, + EDESTADDRREQ, + ESHUTDOWN, // 15 + ENOPROTOOPT, + EBUSY, + ENOMEM, + EADDRNOTAVAIL, + EADDRINUSE, // 20 + EAFNOSUPPORT, + EINPROGRESS, + EIO, + ENOTSOCK, + EINVAL, // 25 + EINVAL, + EIO, + ETOOMANYREFS, + EFAULT, + ENETUNREACH, // 30 + EPROTONOSUPPORT, + EPROTOTYPE, + EINVAL, + EINVAL, + EINVAL, // 35 + EINVAL, + EINVAL, + EINVAL, + EINVAL, + EINVAL, // 40 + EINVAL, + ENODEV, + EBUSY, + EBUSY, + EINVAL, // 45 + EINVAL, + EINVAL, + ENOMEM, + EBADFD, + ECANCELED, // 50 + EMFILE, +}; + +int +__wut_get_nsysnet_fd(int fd) +{ + __handle *handle = __get_handle(fd); + if (handle == NULL) { + errno = EBADF; + return -1; + } + if (strcmp(devoptab_list[handle->device]->name, "sock") != 0) { + errno = ENOTSOCK; + return -1; + } + return *(int *)handle->fileStruct; +} + +int +__wut_get_nsysnet_result(struct _reent *r, + int rc) +{ + int sockerror, error; + + if (rc >= 0) { + return rc; + } + + sockerror = RPLWRAP(socketlasterr)(); + + if (sockerror < 0) { + return -1; + } + + if (sockerror < sizeof(__wut_nsysnet_error_code_map)) { + error = __wut_nsysnet_error_code_map[sockerror]; + } else { + error = NSYSNET_UNKNOWN_ERROR_OFFSET + sockerror; + } + + if (r) { + r->_errno = error; + } else { + errno = error; + } + + return -1; +} + diff --git a/libraries/wutsocket/wut_socket_open.c b/libraries/wutsocket/wut_socket_open.c new file mode 100644 index 0000000..0fdb6ad --- /dev/null +++ b/libraries/wutsocket/wut_socket_open.c @@ -0,0 +1,13 @@ +#include "wut_socket.h" + +int +__wut_socket_open(struct _reent *r, + void *fileStruct, + const char *path, + int flags, + int mode) +{ + r->_errno = ENOSYS; + return -1; +} + diff --git a/libraries/wutsocket/wut_socket_read.c b/libraries/wutsocket/wut_socket_read.c new file mode 100644 index 0000000..a10e259 --- /dev/null +++ b/libraries/wutsocket/wut_socket_read.c @@ -0,0 +1,13 @@ +#include "wut_socket.h" + +ssize_t +__wut_socket_read(struct _reent *r, + void *fd, + char *ptr, + size_t len) +{ + int sockfd = *(int *)fd; + int rc = RPLWRAP(recv)(sockfd, ptr, len, 0); + return (ssize_t)__wut_get_nsysnet_result(r, rc); +} + diff --git a/libraries/wutsocket/wut_socket_write.c b/libraries/wutsocket/wut_socket_write.c new file mode 100644 index 0000000..b19438b --- /dev/null +++ b/libraries/wutsocket/wut_socket_write.c @@ -0,0 +1,13 @@ +#include "wut_socket.h" + +ssize_t +__wut_socket_write(struct _reent *r, + void *fd, + const char *ptr, + size_t len) +{ + int sockfd = *(int *)fd; + int rc = RPLWRAP(send)(sockfd, ptr, len, 0); + return (ssize_t)__wut_get_nsysnet_result(r, rc); +} + diff --git a/tests/test_compile_headers_common/test_compile_headers_list.h b/tests/test_compile_headers_common/test_compile_headers_list.h index bdf3948..61391db 100644 --- a/tests/test_compile_headers_common/test_compile_headers_list.h +++ b/tests/test_compile_headers_common/test_compile_headers_list.h @@ -94,7 +94,7 @@ #include #include #include -#include +#include #include #include #include