From 8cf9dc88c488ba959a211f1ec653a366d16e1531 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Thu, 16 May 2013 13:46:43 +0800 Subject: [PATCH] Usermode/libc,libpsocket - Various fixes to psockets and errno --- Usermode/Libraries/Makefile.cfg | 2 +- Usermode/Libraries/libc.so_src/Makefile | 2 +- Usermode/Libraries/libc.so_src/errno.c | 30 +++ .../libc.so_src/include_exp/errno.enum.h | 4 +- .../Libraries/libc.so_src/include_exp/errno.h | 9 +- Usermode/Libraries/libc.so_src/strtoi.c | 2 +- Usermode/Libraries/libc.so_src/stub.c | 5 - Usermode/Libraries/libposix.so_src/unistd.c | 26 +-- .../Libraries/libpsocket.so_src/getaddrinfo.c | 44 ++++- .../libpsocket.so_src/include_exp/netdb.h | 1 + .../include_exp/netinet/in.h | 5 +- Usermode/Libraries/libpsocket.so_src/socket.c | 172 +++++++++++++----- 12 files changed, 230 insertions(+), 72 deletions(-) create mode 100644 Usermode/Libraries/libc.so_src/errno.c diff --git a/Usermode/Libraries/Makefile.cfg b/Usermode/Libraries/Makefile.cfg index c3cb7b14..8c75e8bc 100644 --- a/Usermode/Libraries/Makefile.cfg +++ b/Usermode/Libraries/Makefile.cfg @@ -21,7 +21,7 @@ LDFLAGS := -I/Acess/Libs/ld-acess.so -lld-acess `$(CC) -print-libgcc-file-name` endif CPPFLAGS += -I$(ACESSDIR)/Usermode/include/ -DARCHDIR=$(ARCHDIR) -DARCHDIR_is_$(ARCHDIR)=1 CPPFLAGS += $(addprefix -I,$(wildcard $(ACESSUSERDIR)Libraries/*/include_exp/)) -CFLAGS += -Wall -g +CFLAGS += -Wall -g -std=gnu99 LDFLAGS += -g -nostdlib -shared -eSoMain -x --no-undefined -L$(OUTPUTDIR)Libs/ # vim: ft=make diff --git a/Usermode/Libraries/libc.so_src/Makefile b/Usermode/Libraries/libc.so_src/Makefile index 60b86cd2..b7cb1d22 100644 --- a/Usermode/Libraries/libc.so_src/Makefile +++ b/Usermode/Libraries/libc.so_src/Makefile @@ -12,7 +12,7 @@ INCFILES := stdio.h stdlib.h OBJ = stub.o heap.o stdlib.o env.o stdio.o string.o rand.o OBJ += perror.o scanf.o signals.o strtoi.o strtof.o -OBJ += printf.o time.o +OBJ += printf.o time.o errno.o OBJ += arch/$(ARCHDIR).ao # signals.o DEPFILES := $(OBJ:%.o=%.d) diff --git a/Usermode/Libraries/libc.so_src/errno.c b/Usermode/Libraries/libc.so_src/errno.c new file mode 100644 index 00000000..98773282 --- /dev/null +++ b/Usermode/Libraries/libc.so_src/errno.c @@ -0,0 +1,30 @@ +/* + * Acess2 C Library + * - By John Hodge (thePowersGang) + * + * errno.c + * - errno and strerror + */ +#include "lib.h" +#include +#include + +EXPORT int *libc_geterrno() +{ + return &_errno; +} + +EXPORT const char *strerror(int errnum) +{ + switch(errnum) + { + case ENOSYS: return "Invalid instruction/syscall"; + case ENOENT: return "No such file or directory"; + case EINVAL: return "Bad arguments"; + case EPERM: return "Permissions error"; + default: + _SysDebug("strerror: errnum=%i unk", errnum); + return "unknown error"; + } +} + diff --git a/Usermode/Libraries/libc.so_src/include_exp/errno.enum.h b/Usermode/Libraries/libc.so_src/include_exp/errno.enum.h index 1aeb879b..de9bd7b5 100644 --- a/Usermode/Libraries/libc.so_src/include_exp/errno.enum.h +++ b/Usermode/Libraries/libc.so_src/include_exp/errno.enum.h @@ -9,7 +9,7 @@ enum { EBUSY, // Resource is busy ERANGE, // Value out of range ENOTFOUND, // Item not found - EREADONLY, // Read only + EREADONLY, // Read only (duplicate with EROFS?) ENOTIMPL, // Not implemented ENOENT, // No entry? EEXIST, // Already exists @@ -17,10 +17,12 @@ enum { ENOTDIR, // Not a directory EIO, // IO Error EINTR, // Operation interrupted (signal) + EWOULDBLOCK, // Operation would have blocked ENODEV, // ??? EADDRNOTAVAIL, // ? EINPROGRESS, // ? EROFS, + EPERM, // Permissions error EAGAIN, // Try again diff --git a/Usermode/Libraries/libc.so_src/include_exp/errno.h b/Usermode/Libraries/libc.so_src/include_exp/errno.h index c7f5b491..213aeba2 100644 --- a/Usermode/Libraries/libc.so_src/include_exp/errno.h +++ b/Usermode/Libraries/libc.so_src/include_exp/errno.h @@ -1,3 +1,10 @@ +/** + * Acess2 C Library + * - By John Hodge (thePowersGang) + * + * errno.h + * - Error values and related functions + */ #ifndef _ERRNO_H_ #define _ERRNO_H_ @@ -6,7 +13,7 @@ extern int *libc_geterrno(); #define errno (*libc_geterrno()) -#define strerror(_x) "Unimplemented" +extern const char *strerr(int errnum); #include "errno.enum.h" diff --git a/Usermode/Libraries/libc.so_src/strtoi.c b/Usermode/Libraries/libc.so_src/strtoi.c index 81af4601..758906fd 100644 --- a/Usermode/Libraries/libc.so_src/strtoi.c +++ b/Usermode/Libraries/libc.so_src/strtoi.c @@ -143,7 +143,7 @@ long atol(const char *str) return tmp; } -long atoll(const char *str) +long long atoll(const char *str) { long long tmp = strtoll(str, NULL, 0); return tmp; diff --git a/Usermode/Libraries/libc.so_src/stub.c b/Usermode/Libraries/libc.so_src/stub.c index 5f16c05e..f723d544 100644 --- a/Usermode/Libraries/libc.so_src/stub.c +++ b/Usermode/Libraries/libc.so_src/stub.c @@ -94,11 +94,6 @@ int ErrorHandler(int Fault) return -1; } -EXPORT int *libc_geterrno() -{ - return &_errno; -} - #if USE_CPUID /** * \brief Call the CPUID opcode diff --git a/Usermode/Libraries/libposix.so_src/unistd.c b/Usermode/Libraries/libposix.so_src/unistd.c index 7cfb71ab..2d0a7e4a 100644 --- a/Usermode/Libraries/libposix.so_src/unistd.c +++ b/Usermode/Libraries/libposix.so_src/unistd.c @@ -42,7 +42,9 @@ int open(const char *path, int openmode, ...) if( openmode & O_NONBLOCK ) openflags |= OPENFLAG_NONBLOCK; - return _SysOpen(path, openflags, create_mode); + int ret = _SysOpen(path, openflags, create_mode); + _SysDebug("open('%s', 0%o, 0%o) = %i", path, openmode, create_mode, ret); + return ret; } int creat(const char *path, mode_t mode) @@ -94,14 +96,16 @@ int dup(int oldfd) { _SysDebug("libposix: dup() does not share offsets/flags"); // NOTE: Acess's CopyFD doesn't cause offset sharing - // TODO: Check that -1 does cause a new allocation - return _SysCopyFD(oldfd, -1); + int ret = _SysCopyFD(oldfd, -1); + _SysDebug("dup(%i) = %i", oldfd, ret); + return ret; } int dup2(int oldfd, int newfd) { _SysDebug("libposix: dup2() does not share offsets/flags"); // NOTE: Acess's CopyFD doesn't cause offset sharing + _SysDebug("dup2(%i,%i)", oldfd, newfd); return _SysCopyFD(oldfd, newfd); } @@ -139,18 +143,17 @@ int kill(pid_t pid, int signal) int select(int nfd, fd_set *rfd, fd_set *wfd, fd_set *efd, struct timeval *timeout) { - + long long int ltimeout = 0, *ltimeoutp = NULL; if( timeout ) { - long long int ltimeout = 0; ltimeout = timeout->tv_sec*1000 + timeout->tv_usec / 1000; - int ret = _SysSelect(nfd, rfd, wfd, efd, <imeout, 0); - return ret; - } - else - { - return _SysSelect(nfd, rfd, wfd, efd, NULL, 0); + ltimeoutp = <imeout; } + _SysDebug("select(%i,{0x%x},{0x%x},{0x%x},%lli)", + nfd, (rfd?rfd->flags[0]:0), (wfd?wfd->flags[0]:0), (efd?efd->flags[0]:0), + (ltimeoutp ? *ltimeoutp : -1) + ); + return _SysSelect(nfd, rfd, wfd, efd, ltimeoutp, 0); } int pipe(int pipefd[2]) @@ -158,6 +161,7 @@ int pipe(int pipefd[2]) pipefd[0] = _SysOpen("/Devices/fifo/anon", OPENFLAG_READ|OPENFLAG_WRITE); pipefd[1] = _SysCopyFD(pipefd[0], -1); _SysFDFlags(pipefd[1], OPENFLAG_READ|OPENFLAG_WRITE, OPENFLAG_WRITE); + _SysDebug("pipe({%i,%i})", pipefd[0], pipefd[1]); return 0; } diff --git a/Usermode/Libraries/libpsocket.so_src/getaddrinfo.c b/Usermode/Libraries/libpsocket.so_src/getaddrinfo.c index c26ce321..d4d6ce8d 100644 --- a/Usermode/Libraries/libpsocket.so_src/getaddrinfo.c +++ b/Usermode/Libraries/libpsocket.so_src/getaddrinfo.c @@ -10,14 +10,20 @@ #include // Net_ParseAddress #include // malloc #include // memcpy +#include // strtol #include // === CODE === int getaddrinfo(const char *node, const char *service, const struct addrinfo *hints, struct addrinfo **res) { - static const struct addrinfo defhints = {.ai_flags = AI_V4MAPPED | AI_ADDRCONFIG}; + static const struct addrinfo defhints = { + .ai_family = AF_UNSPEC, + .ai_flags = AI_V4MAPPED | AI_ADDRCONFIG + }; struct addrinfo *ret = NULL; + _SysDebug("getaddrinfo('%s','%s',%p,%p)", node, service, hints, res); + // Error checks if( !node && !service ) return EAI_NONAME; @@ -66,6 +72,7 @@ int getaddrinfo(const char *node, const char *service, const struct addrinfo *hi // - No luck with above, and hints->ai_flags doesn't have AI_NUMERICHOST set if( !ret && !(hints->ai_flags & AI_NUMERICHOST) ) { + _SysDebug("getaddrinfo: TODO DNS Lookups"); // TODO: DNS Lookups // ? /Acess/Conf/Nameservers // ? /Acess/Conf/Hosts @@ -78,14 +85,37 @@ int getaddrinfo(const char *node, const char *service, const struct addrinfo *hi } } - int default_socktype = 0; - int default_protocol = 0; + int default_socktype = hints->ai_socktype; + int default_protocol = hints->ai_protocol; int default_port = 0; + #if 0 + if( default_protocol == 0 ) + { + switch(default_socktype) + { + case SOCK_DGRAM: + default_protocol = + } + } + #endif + // Convert `node` into types if( service ) { - // TODO: Read something like /Acess/Conf/services + char *end; + + default_port = strtol(service, &end, 0); + if( *end != '\0' && !(hints->ai_flags & AI_NUMERICSERV) ) + { + // TODO: Read something like /Acess/Conf/services + _SysDebug("getaddrinfo: TODO Service translation"); + } + + if( *end != '\0' ) + { + return EAI_NONAME; + } } struct addrinfo *ai; @@ -106,10 +136,16 @@ int getaddrinfo(const char *node, const char *service, const struct addrinfo *hi case AF_INET: if( in->sin_port == 0 ) in->sin_port = default_port; + _SysDebug("%p: IPv4 [%s]:%i %i,%i", + ai, Net_PrintAddress(4, &in->sin_addr), + in->sin_port, ai->ai_socktype, ai->ai_protocol); break; case AF_INET6: if( in6->sin6_port == 0 ) in6->sin6_port = default_port; + _SysDebug("%p: IPv6 [%s]:%i %i,%i", + ai, Net_PrintAddress(6, &in6->sin6_addr), + in6->sin6_port, ai->ai_socktype, ai->ai_protocol); break; default: _SysDebug("getaddrinfo: Unknown address family %i (setting port)", ai->ai_family); diff --git a/Usermode/Libraries/libpsocket.so_src/include_exp/netdb.h b/Usermode/Libraries/libpsocket.so_src/include_exp/netdb.h index 09681812..d0f12b93 100644 --- a/Usermode/Libraries/libpsocket.so_src/include_exp/netdb.h +++ b/Usermode/Libraries/libpsocket.so_src/include_exp/netdb.h @@ -7,6 +7,7 @@ #define AI_V4MAPPED 0x002 #define AI_ADDRCONFIG 0x004 #define AI_NUMERICHOST 0x008 +#define AI_NUMERICSERV 0x010 #define NI_NAMEREQD (1<<0) #define NI_DGRAM (1<<1) diff --git a/Usermode/Libraries/libpsocket.so_src/include_exp/netinet/in.h b/Usermode/Libraries/libpsocket.so_src/include_exp/netinet/in.h index 3a289ebf..9323f246 100644 --- a/Usermode/Libraries/libpsocket.so_src/include_exp/netinet/in.h +++ b/Usermode/Libraries/libpsocket.so_src/include_exp/netinet/in.h @@ -8,6 +8,7 @@ #ifndef _LIBPSOCKET__NETINET__IN_H_ #define _LIBPSOCKET__NETINET__IN_H_ +#include // sa_family_t #include typedef uint32_t in_addr_t; @@ -19,7 +20,7 @@ struct in_addr struct sockaddr_in { - uint16_t sin_family; + sa_family_t sin_family; uint16_t sin_port; struct in_addr sin_addr; }; @@ -42,7 +43,7 @@ struct in6_addr struct sockaddr_in6 { - uint16_t sin6_family; + sa_family_t sin6_family; uint16_t sin6_port; uint32_t sin6_flowinfo; struct in6_addr sin6_addr; diff --git a/Usermode/Libraries/libpsocket.so_src/socket.c b/Usermode/Libraries/libpsocket.so_src/socket.c index a03a2bd7..586176dc 100644 --- a/Usermode/Libraries/libpsocket.so_src/socket.c +++ b/Usermode/Libraries/libpsocket.so_src/socket.c @@ -10,10 +10,16 @@ #include // malloc/free #include #include +#include #include "common.h" #define MAXFD 32 +#define IOCTL_TCPC_PORT 5 +#define IOCTL_TCPC_HOST 6 +#define IOCTL_TCPC_CONNECT 7 +#define IOCTL_TCPS_PORT 5 + typedef struct s_sockinfo { int fd; @@ -24,6 +30,9 @@ typedef struct s_sockinfo struct sockaddr *remote; } t_sockinfo; +// === PROTOTYPES === +void _CommitClient(int sockfd); + struct s_sockinfo gSockInfo[MAXFD]; static int giNumPreinit = 0; @@ -49,12 +58,23 @@ int socket(int domain, int type, int protocol) { t_sockinfo *si = NULL; - if( domain < 0 || domain > AF_INET6 ) return -1; - if( type < 0 || type > SOCK_RDM ) return -1; + if( domain < 0 || domain > AF_INET6 ) { + _SysDebug("socket: Domain %i invalid", domain); + errno = EINVAL; + return -1; + } + if( type < 0 || type > SOCK_RDM ) { + _SysDebug("socket: Type %i invalid", type); + errno = EINVAL; + return -1; + } // Allocate an info struct si = _GetInfo(0); - if( !si ) return -1; + if( !si ) { + errno = ENOMEM; + return -1; + } int fd = _SysOpen("/Devices/null", OPENFLAG_RDWR); if( fd == -1 ) return -1; @@ -66,7 +86,8 @@ int socket(int domain, int type, int protocol) si->protocol = protocol; si->local = NULL; si->remote = NULL; - + + _SysDebug("socket(%i,%i,%i) = %i", domain, type, protocol, fd); return fd; } @@ -86,20 +107,106 @@ int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen) return 0; } -int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen) +size_t _getAddrData(const struct sockaddr *addr, const void **dataptr, int *port) { - t_sockinfo *si = _GetInfo(sockfd);; - if( !si ) return -1; + size_t addrLen = 0; + const struct sockaddr_in *in4 = (void*)addr; + const struct sockaddr_in6 *in6 = (void*)addr; + switch( addr->sa_family ) + { + case AF_INET: + *dataptr = &in4->sin_addr; + addrLen = 4; + *port = in4->sin_port; + break; + case AF_INET6: + *dataptr = &in6->sin6_addr; + addrLen = 16; + *port = in6->sin6_port; + break; + default: + _SysDebug("libpsocket _getAddrData: Unkown sa_family %i", addr->sa_family); + return 0; + } + return addrLen; +} - if( si->remote ) { - // Oops? +int _OpenIf(int DestFD, const struct sockaddr *addr, const char *file, int *port) +{ + const uint8_t *addrBuffer = NULL; + size_t addrLen = 0; + + addrLen = _getAddrData(addr, (const void **)&addrBuffer, port); + if( addrLen == 0 ) { + errno = EINVAL; + return -1; + } + + char hexAddr[addrLen*2+1]; + int bNonZero = 0; + for( int i = 0; i < addrLen; i ++ ) { + hexAddr[i*2+0] = "0123456789ABCDEF"[addrBuffer[i] >> 4]; + hexAddr[i*2+1] = "0123456789ABCDEF"[addrBuffer[i] & 15]; + if(addrBuffer[i]) bNonZero = 1; + } + hexAddr[addrLen*2] = 0; + + char *path; + if( bNonZero ) + path = mkstr("/Devices/ip/routes/@%i:%s/%s", addr->sa_family, hexAddr, file); + else + path = mkstr("/Devices/ip/*%i/%s", addr->sa_family, file); + + int ret = _SysReopen(DestFD, path, OPENFLAG_RDWR); + _SysDebug("libpsocket: _SysReopen(%i, '%s') = %i", DestFD, path, ret); + free(path); + // TODO: Error-check? + return ret; +} + +int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen) +{ + t_sockinfo *si = _GetInfo(sockfd); + if( !si || si->remote ) { + _SysDebug("connect: FD %i already connected", sockfd); + errno = EALREADY; return -1; } si->remote = malloc( addrlen ); memcpy(si->remote, addr, addrlen); - return 0; + int ret = 0; + if( si->type == SOCK_STREAM ) + { + int lport = 0; + const struct sockaddr *bindaddr = (si->local ? si->local : addr); + ret = _OpenIf(sockfd, bindaddr, "tcpc", &lport); + if(ret == -1) + return ret; + + if( si->local ) { + //_SysIOCtl(sockfd, IOCTL_TCPC_LPORT, &lport); + _SysDebug("connect: TODO - Bind to local port"); + } + + int port; + const void *addrdata; + _getAddrData(addr, &addrdata, &port); + + _SysIOCtl(sockfd, IOCTL_TCPC_PORT, &port); + _SysIOCtl(sockfd, IOCTL_TCPC_HOST, (void*)addrdata); + ret = _SysIOCtl(sockfd, IOCTL_TCPC_CONNECT, NULL); + _SysDebug("connect: :%i = %i", port, ret); + } + else + { + _SysDebug("connect: TODO - non-TCP clients (%i)", si->type); + } + + _CommitClient(sockfd); + + return ret; } int listen(int sockfd, int backlog) @@ -129,51 +236,26 @@ void _CommitServer(int sockfd) t_sockinfo *si = _GetInfo(sockfd); if( !si ) return ; - const char *file; - - file = "tcps"; - if( !si->local ) { // Um... oops? return ; } - uint8_t *addrBuffer = NULL; - size_t addrLen = 0; - switch( si->local->sa_family ) - { - case AF_INET: - addrBuffer = (void*)&((struct sockaddr_in*)si->local)->sin_addr; - addrLen = 4; - break; - case AF_INET6: - addrBuffer = (void*)&((struct sockaddr_in6*)si->local)->sin6_addr; - addrLen = 16; - break; - default: + if( si->type != SOCK_STREAM ) { + _SysDebug("TODO: Non-tcp servers"); return ; } - - char hexAddr[addrLen*2+1]; - int bNonZero = 0, i; - for( i = 0; i < addrLen; i ++ ) { - hexAddr[i*2+0] = "0123456789ABCDEF"[addrBuffer[i] >> 4]; - hexAddr[i*2+1] = "0123456789ABCDEF"[addrBuffer[i] & 15]; - if(addrBuffer[i]) bNonZero = 1; - } - - char *path; - if( bNonZero ) - path = mkstr("/Devices/ip/routes/@%i:%s/%s", si->local->sa_family, file); - else - path = mkstr("/Devices/ip/*%i/%s", si->local->sa_family, file); - _SysReopen(si->fd, path, OPENFLAG_RDWR); - // TODO: Error-check + // Bind to the local address + int port; + int ret = _OpenIf(sockfd, si->local, "tcps", &port); + if( ret == -1 ) { + return ; + } - free(path); - + // Bind to port // TODO: Set up socket + _SysIOCtl(sockfd, IOCTL_TCPS_PORT, &port); _ClearInfo(si); } -- 2.20.1