wutsocket: implement missing functions

This commit is contained in:
GaryOderNichts 2021-02-09 17:22:24 +01:00 committed by fincs
parent efc1bd47ff
commit f1e9cbd58a
11 changed files with 446 additions and 0 deletions

129
include/netdb.h Normal file
View File

@ -0,0 +1,129 @@
#pragma once
#include <stdint.h>
#include <sys/socket.h>
extern int h_errno;
struct hostent
{
char *h_name;
char **h_aliases;
int h_addrtype;
int h_length;
char **h_addr_list;
#define h_addr h_addr_list[0]
};
struct servent
{
char *s_name;
char **s_aliases;
int s_port;
char *s_proto;
};
struct addrinfo
{
int ai_flags;
int ai_family;
int ai_socktype;
int ai_protocol;
socklen_t ai_addrlen;
char *ai_canonname;
struct sockaddr *ai_addr;
struct addrinfo *ai_next;
};
#define NETDB_INTERNAL -1
#define NETDB_SUCCESS 0
#define HOST_NOT_FOUND 1
#define TRY_AGAIN 2
#define NO_RECOVERY 3
#define NO_DATA 4
#define NO_ADDRESS NO_DATA
#define EAI_ADDRFAMILY 1
#define EAI_AGAIN 2
#define EAI_BADFLAGS 3
#define EAI_FAIL 4
#define EAI_FAMILY 5
#define EAI_MEMORY 6
#define EAI_NODATA 7
#define EAI_NONAME 8
#define EAI_SERVICE 9
#define EAI_SOCKTYPE 10
#define EAI_SYSTEM 11
#define EAI_BADHINTS 12
#define EAI_PROTOCOL 13
#define EAI_OVERFLOW 14
#define EAI_MAX 15
#define NI_MAXHOST 1025
#define NI_MAXSERV 32
// nsysnet only implements NI_NOFQDN, NI_NUMERICHOST and NI_NUMERICSERV
#define NI_NOFQDN 0x0001
#define NI_NUMERICHOST 0x0002
#define NI_NAMEREQD 0x0004
#define NI_NUMERICSERV 0x0008
#define NI_DGRAM 0x0010
#define NI_NUMERICSCOPE 0x0020
// nsysnet only implements AI_PASSIVE, AI_CANONNAME and AI_NUMERICHOST
#define AI_PASSIVE 0x0001
#define AI_CANONNAME 0x0002
#define AI_NUMERICHOST 0x0004
#define AI_V4MAPPED 0x0008
#define AI_ALL 0x0010
#define AI_ADDRCONFIG 0x0020
#ifdef __cplusplus
extern "C" {
#endif
struct hostent *
gethostbyname(const char *name);
struct hostent *
gethostbyaddr(const void *addr,
socklen_t len,
int type);
struct hostent *
gethostent(void);
struct servent *
getservbyname(const char *name,
const char *proto);
struct servent *
getservbyport(int port,
const char *proto);
struct servent *
getservent(void);
int
getaddrinfo(const char *node,
const char *service,
const struct addrinfo *hints,
struct addrinfo **res);
void
freeaddrinfo(struct addrinfo *res);
int
getnameinfo(const struct sockaddr *addr,
socklen_t addrlen,
char *host,
socklen_t hostlen,
char *serv,
socklen_t servlen,
int flags);
const char *
gai_strerror(int ecode);
#ifdef __cplusplus
}
#endif

57
include/nsysnet/_netdb.h Normal file
View File

@ -0,0 +1,57 @@
#pragma once
#include <wut.h>
#include <netdb.h>
/**
* \defgroup nsysnet_netdb Netdb
* \ingroup nsysnet
* @{
*/
#ifdef __cplusplus
extern "C" {
#endif
struct hostent *
RPLWRAP(gethostbyaddr)(const void *addr,
size_t len,
int type);
struct hostent *
RPLWRAP(gethostbyname)(const char *name);
int
RPLWRAP(getaddrinfo)(const char *node,
const char *service,
const struct addrinfo *hints,
struct addrinfo **res);
void
RPLWRAP(freeaddrinfo)(struct addrinfo *res);
int
RPLWRAP(getnameinfo)(const struct sockaddr *addr,
socklen_t addrlen,
char *host,
socklen_t hostlen,
char *serv,
socklen_t servlen,
int flags);
void
RPLWRAP(clear_resolver_cache)(void);
int
RPLWRAP(set_resolver_allocator)(void* (*alloc)(uint32_t),
void (*free)(void*));
int *
RPLWRAP(get_h_errno)(void);
const char *
RPLWRAP(gai_strerror)(int ecode);
#ifdef __cplusplus
}
#endif
/** @} */

21
include/sys/filio.h Normal file
View File

@ -0,0 +1,21 @@
#pragma once
#include <sys/ioccom.h>
/* Generic file-descriptor ioctl's. */
#define FIOCLEX _IO('f', 1) /* set close on exec on fd */
#define FIONCLEX _IO('f', 2) /* remove close on exec */
#define FIONREAD _IOR('f', 127, int) /* get # bytes to read */
#define FIONWRITE _IOR('f', 119, int) /* get # bytes (yet) to write */
#define FIONBIO _IOW('f', 126, int) /* set/clear non-blocking i/o */
#define FIOASYNC _IOW('f', 125, int) /* set/clear async i/o */
#define FIOSETOWN _IOW('f', 124, int) /* set owner */
#define FIOGETOWN _IOR('f', 123, int) /* get owner */
#define FIODTYPE _IOR('f', 122, int) /* get d_flags type part */
#define FIOGETLBA _IOR('f', 121, int) /* get start blk # */
struct fiodgname_arg {
int len;
void *buf;
};
#define FIODGNAME _IOW('f', 120, struct fiodgname_arg) /* get dev. name */
#define FIONSPACE _IOR('f', 118, int) /* get space in send queue */

40
include/sys/ioccom.h Normal file
View File

@ -0,0 +1,40 @@
#pragma once
/*
* Ioctl's have the command encoded in the lower word, and the size of
* any in or out parameters in the upper word. The high 3 bits of the
* upper word are used to encode the in/out status of the parameter.
*/
#define IOCPARM_SHIFT 13 /* number of bits for ioctl size */
#define IOCPARM_MASK ((1 << IOCPARM_SHIFT) - 1) /* parameter length mask */
#define IOCPARM_LEN(x) (((x) >> 16) & IOCPARM_MASK)
#define IOCBASECMD(x) ((x) & ~(IOCPARM_MASK << 16))
#define IOCGROUP(x) (((x) >> 8) & 0xff)
#define IOCPARM_MAX (1 << IOCPARM_SHIFT) /* max size of ioctl */
#define IOC_VOID 0x20000000 /* no parameters */
#define IOC_OUT 0x40000000 /* copy out parameters */
#define IOC_IN 0x80000000 /* copy in parameters */
#define IOC_INOUT (IOC_IN|IOC_OUT)
#define IOC_DIRMASK (IOC_VOID|IOC_OUT|IOC_IN)
#define _IOC(inout,group,num,len) ((int) \
((inout) | (((len) & IOCPARM_MASK) << 16) | ((group) << 8) | (num)))
#define _IO(g,n) _IOC(IOC_VOID, (g), (n), 0)
#define _IOWINT(g,n) _IOC(IOC_VOID, (g), (n), sizeof(int))
#define _IOR(g,n,t) _IOC(IOC_OUT, (g), (n), sizeof(t))
#define _IOW(g,n,t) _IOC(IOC_IN, (g), (n), sizeof(t))
/* this should be _IORW, but stdio got there first */
#define _IOWR(g,n,t) _IOC(IOC_INOUT, (g), (n), sizeof(t))
#ifdef __cplusplus
extern "C" {
#endif
int ioctl(int fd,
int request,
...);
#ifdef __cplusplus
}
#endif

5
include/sys/ioctl.h Normal file
View File

@ -0,0 +1,5 @@
#pragma once
#include <sys/ioccom.h>
#include <sys/filio.h>

View File

@ -26,6 +26,7 @@
* SOL_SOCKET options * SOL_SOCKET options
*/ */
#define SO_REUSEADDR 0x0004 // reuse address #define SO_REUSEADDR 0x0004 // reuse address
#define SO_KEEPALIVE 0x0008 // keep connections alive
#define SO_BROADCAST 0x0020 // broadcast #define SO_BROADCAST 0x0020 // broadcast
#define SO_LINGER 0x0080 // linger (no effect?) #define SO_LINGER 0x0080 // linger (no effect?)
#define SO_OOBINLINE 0x0100 // out-of-band data inline (no effect?) #define SO_OOBINLINE 0x0100 // out-of-band data inline (no effect?)
@ -37,6 +38,8 @@
#define SO_RCVLOWAT 0x1004 // receive low-water mark #define SO_RCVLOWAT 0x1004 // receive low-water mark
#define SO_TYPE 0x1008 // get socket type #define SO_TYPE 0x1008 // get socket type
#define SO_ERROR 0x1009 // get socket error #define SO_ERROR 0x1009 // get socket error
#define SO_RXDATA 0x1011 // get count of bytes in sb_rcv
#define SO_TXDATA 0x1012 // get count of bytes in sb_snd
#define SO_NBIO 0x1014 // set socket to NON-blocking mode #define SO_NBIO 0x1014 // set socket to NON-blocking mode
#define SO_BIO 0x1015 // set socket to blocking mode #define SO_BIO 0x1015 // set socket to blocking mode
#define SO_NONBLOCK 0x1016 // set/get blocking mode via optval param #define SO_NONBLOCK 0x1016 // set/get blocking mode via optval param

View File

@ -0,0 +1,53 @@
#include "wut_socket.h"
#include <nsysnet/_netdb.h>
#include <netdb.h>
int
getaddrinfo(const char *node,
const char *service,
const struct addrinfo *hints,
struct addrinfo **res)
{
int rc;
if (!node && !service) {
return EAI_NONAME;
}
if (!res) {
errno = EINVAL;
return EAI_SYSTEM;
}
rc = RPLWRAP(getaddrinfo)(node, service, hints, res);
return rc;
}
void
freeaddrinfo(struct addrinfo *res)
{
RPLWRAP(freeaddrinfo)(res);
}
int
getnameinfo(const struct sockaddr *addr,
socklen_t addrlen,
char *host,
socklen_t hostlen,
char *serv,
socklen_t servlen,
int flags)
{
int rc;
rc = RPLWRAP(getnameinfo)(addr, addrlen, host, hostlen, serv, servlen, flags);
return rc;
}
const char *
gai_strerror(int ecode)
{
return RPLWRAP(gai_strerror)(ecode);
}

View File

@ -0,0 +1,40 @@
#include "wut_socket.h"
#include <netdb.h>
#include <nsysnet/_netdb.h>
struct hostent *
gethostbyaddr(const void *addr,
socklen_t len,
int type)
{
if (!addr || !len) {
h_errno = HOST_NOT_FOUND;
return NULL;
}
if (type != AF_INET) {
h_errno = HOST_NOT_FOUND;
return NULL;
}
struct hostent *ent = RPLWRAP(gethostbyaddr)(addr, len, type);
h_errno = *RPLWRAP(get_h_errno)();
return ent;
}
struct hostent *
gethostbyname(const char *name)
{
if (!name) {
h_errno = HOST_NOT_FOUND;
return NULL;
}
struct hostent *ent = RPLWRAP(gethostbyname)(name);
h_errno = *RPLWRAP(get_h_errno)();
return ent;
}

View File

@ -0,0 +1,60 @@
#include "wut_socket.h"
#include <sys/ioctl.h>
int
ioctl(int fd,
int request,
...)
{
void *data;
va_list args;
int sockfd;
int rc;
va_start(args, request);
data = (request & IOC_INOUT) ? va_arg(args, void *) : NULL;
va_end(args);
if(data == NULL && (request & IOC_INOUT) && IOCPARM_LEN(request) != 0) {
errno = EFAULT;
return -1;
}
sockfd = __wut_get_nsysnet_fd(fd);
if (sockfd == -1) {
return -1;
}
switch(request) {
case FIONBIO: {
int flags = fcntl(fd, F_GETFL, 0);
if(flags == -1) {
return -1;
}
flags = *(int *)data != 0 ? (flags | O_NONBLOCK) : (flags & ~O_NONBLOCK);
return fcntl(fd, F_SETFL, flags);
}
case FIONREAD: {
socklen_t optlen = sizeof(int32_t);
rc = RPLWRAP(getsockopt)(sockfd,
SOL_SOCKET,
SO_RXDATA,
data,
&optlen);
return __wut_get_nsysnet_result(NULL, rc);
}
case FIONWRITE: {
socklen_t optlen = sizeof(int32_t);
rc = RPLWRAP(getsockopt)(sockfd,
SOL_SOCKET,
SO_TXDATA,
data,
&optlen);
return __wut_get_nsysnet_result(NULL, rc);
}
default:
break;
}
return -1;
}

View File

@ -0,0 +1,36 @@
#include "wut_socket.h"
#include <netdb.h>
struct servent *
getservbyname(const char *name,
const char *proto)
{
h_errno = NO_RECOVERY;
errno = ENOSYS;
return NULL;
}
struct servent *
getservbyport(int port,
const char *proto)
{
h_errno = NO_RECOVERY;
errno = ENOSYS;
return NULL;
}
struct servent *
getservent(void)
{
h_errno = NO_RECOVERY;
errno = ENOSYS;
return NULL;
}
struct hostent *
gethostent(void)
{
h_errno = NO_RECOVERY;
errno = ENOSYS;
return NULL;
}

View File

@ -2,6 +2,8 @@
#define NSYSNET_UNKNOWN_ERROR_OFFSET 10000 #define NSYSNET_UNKNOWN_ERROR_OFFSET 10000
int h_errno;
static BOOL static BOOL
__wut_socket_initialised = FALSE; __wut_socket_initialised = FALSE;