Usermode/libc,libpsocket - Various fixes to psockets and errno
authorJohn Hodge <[email protected]>
Thu, 16 May 2013 05:46:43 +0000 (13:46 +0800)
committerJohn Hodge <[email protected]>
Thu, 16 May 2013 05:46:43 +0000 (13:46 +0800)
12 files changed:
Usermode/Libraries/Makefile.cfg
Usermode/Libraries/libc.so_src/Makefile
Usermode/Libraries/libc.so_src/errno.c [new file with mode: 0644]
Usermode/Libraries/libc.so_src/include_exp/errno.enum.h
Usermode/Libraries/libc.so_src/include_exp/errno.h
Usermode/Libraries/libc.so_src/strtoi.c
Usermode/Libraries/libc.so_src/stub.c
Usermode/Libraries/libposix.so_src/unistd.c
Usermode/Libraries/libpsocket.so_src/getaddrinfo.c
Usermode/Libraries/libpsocket.so_src/include_exp/netdb.h
Usermode/Libraries/libpsocket.so_src/include_exp/netinet/in.h
Usermode/Libraries/libpsocket.so_src/socket.c

index c3cb7b1..8c75e8b 100644 (file)
@@ -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
index 60b86cd..b7cb1d2 100644 (file)
@@ -12,7 +12,7 @@ INCFILES := stdio.h stdlib.h
 \r
 OBJ  = stub.o heap.o stdlib.o env.o stdio.o string.o rand.o\r
 OBJ += perror.o scanf.o signals.o strtoi.o strtof.o\r
-OBJ += printf.o time.o\r
+OBJ += printf.o time.o errno.o\r
 OBJ += arch/$(ARCHDIR).ao\r
 # signals.o\r
 DEPFILES := $(OBJ:%.o=%.d)\r
diff --git a/Usermode/Libraries/libc.so_src/errno.c b/Usermode/Libraries/libc.so_src/errno.c
new file mode 100644 (file)
index 0000000..9877328
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * Acess2 C Library
+ * - By John Hodge (thePowersGang)
+ * 
+ * errno.c
+ * - errno and strerror
+ */
+#include "lib.h"
+#include <errno.h>
+#include <acess/sys.h>
+
+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";
+       }
+}
+
index 1aeb879..de9bd7b 100644 (file)
@@ -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
        
index c7f5b49..213aeba 100644 (file)
@@ -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"
 
index 81af460..758906f 100644 (file)
@@ -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;
index 5f16c05..f723d54 100644 (file)
@@ -94,11 +94,6 @@ int ErrorHandler(int Fault)
        return -1;\r
 }\r
 \r
-EXPORT int *libc_geterrno()\r
-{\r
-       return &_errno;\r
-}\r
-\r
 #if USE_CPUID\r
 /**\r
  * \brief Call the CPUID opcode\r
index 7cfb71a..2d0a7e4 100644 (file)
@@ -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, &ltimeout, 0);
-               return ret;
-       }
-       else
-       {
-               return _SysSelect(nfd, rfd, wfd, efd, NULL, 0);
+               ltimeoutp = &ltimeout;
        }
+       _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;
 }
 
index c26ce32..d4d6ce8 100644 (file)
 #include <net.h>       // Net_ParseAddress
 #include <stdlib.h>    // malloc
 #include <string.h>    // memcpy
+#include <stdlib.h>    // strtol
 #include <acess/sys.h>
 
 // === 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);
index 0968181..d0f12b9 100644 (file)
@@ -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)
index 3a289eb..9323f24 100644 (file)
@@ -8,6 +8,7 @@
 #ifndef _LIBPSOCKET__NETINET__IN_H_
 #define _LIBPSOCKET__NETINET__IN_H_
 
+#include <sys/socket.h>        // sa_family_t
 #include <stdint.h>
 
 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;
index a03a2bd..586176d 100644 (file)
 #include <stdlib.h>    // malloc/free
 #include <string.h>
 #include <netinet/in.h>
+#include <errno.h>
 #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);
 }

UCC git Repository :: git.ucc.asn.au