Move socket.c definitions around, fix bugs

This commit is contained in:
TuxSH 2018-02-07 13:32:45 +01:00
parent 339bdad422
commit 35176d9d7d
2 changed files with 455 additions and 448 deletions

View File

@ -4,11 +4,7 @@
#include <ctype.h> #include <ctype.h>
#include <string.h> #include <string.h>
#include <malloc.h> #include <malloc.h>
//#include <sys/dirent.h>
#include <sys/iosupport.h> #include <sys/iosupport.h>
#include <sys/param.h>
#include <unistd.h>
#include <sys/select.h> #include <sys/select.h>
#include <poll.h> #include <poll.h>
@ -20,6 +16,7 @@
#include <arpa/inet.h> #include <arpa/inet.h>
#include <netdb.h> #include <netdb.h>
#include <unistd.h>
#include "runtime/devices/socket.h" #include "runtime/devices/socket.h"
#include "services/bsd.h" #include "services/bsd.h"
@ -87,438 +84,6 @@ static const SocketInitConfig g_defaultSocketInitConfig = {
.dns_timeout = 0, .dns_timeout = 0,
}; };
static int _socketParseBsdResult(struct _reent *r, int ret) {
int errno_;
if(ret != -1)
return ret; // Nothing to do
else {
if(g_bsdErrno == -1) {
// We're using -1 to signal Switch error codes.
// Note: all of the bsd:u/s handlers return 0.
switch(g_bsdResult) {
case 0xD201:
errno_ = ENFILE;
case 0xD401:
errno_ = EFAULT;
break;
case 0x10601:
errno_ = EBUSY;
break;
default:
errno_ = EPIPE;
break;
}
}
else
errno_ = g_bsdErrno; // Nintendo actually used the Linux errno definitions for their FreeBSD build :)
}
if(r == NULL)
errno = errno_;
else
r->_errno = errno_;
return -1;
}
static int _socketGetFd(int fd) {
__handle *handle = __get_handle(fd);
if(handle == NULL) {
errno = EBADF;
return -1;
}
if(strcmp(devoptab_list[handle->device]->name, "soc") != 0) {
errno = ENOTSOCK;
return -1;
}
return *(int *)handle->fileStruct;
}
static int _socketOpen(struct _reent *r, void *fdptr, const char *path, int flags, int mode) {
(void)mode;
int ret = _socketParseBsdResult(r, bsdOpen(path, flags));
if(ret == -1)
return ret;
*(int *)fdptr = ret;
return 0;
}
static int _socketClose(struct _reent *r, void *fdptr) {
int fd = *(int *)fdptr;
return _socketParseBsdResult(r, bsdClose(fd));
}
static ssize_t _socketWrite(struct _reent *r, void *fdptr, const char *buf, size_t count) {
int fd = *(int *)fdptr;
ssize_t ret = bsdWrite(fd, buf, count);
_socketParseBsdResult(r, (int)ret);
return ret;
}
static ssize_t _socketRead(struct _reent *r, void *fdptr, char *buf, size_t count) {
int fd = *(int *)fdptr;
ssize_t ret = bsdRead(fd, buf, count);
_socketParseBsdResult(r, (int)ret);
return ret;
}
// Adapted from ctrulib
static int _socketInetAtonDetail(int *outBase, size_t *outNumBytes, const char *cp, struct in_addr *inp) {
int base;
u32 val;
int c;
char bytes[4];
size_t num_bytes = 0;
c = *cp;
for(;;) {
if(!isdigit(c)) return 0;
val = 0;
base = 10;
if(c == '0') {
c = *++cp;
if(c == 'x' || c == 'X') {
base = 16;
c = *++cp;
}
else base = 8;
}
for(;;) {
if(isdigit(c)) {
if(base == 8 && c >= '8') return 0;
val *= base;
val += c - '0';
c = *++cp;
}
else if(base == 16 && isxdigit(c)) {
val *= base;
val += c + 10 - (islower(c) ? 'a' : 'A');
c = *++cp;
}
else break;
}
if(c == '.') {
if(num_bytes > 3) return 0;
if(val > 0xFF) return 0;
bytes[num_bytes++] = val;
c = *++cp;
}
else break;
}
if(c != 0) {
*outNumBytes = num_bytes;
*outBase = base;
return 0;
}
switch(num_bytes) {
case 0:
break;
case 1:
if(val > 0xFFFFFF) return 0;
val |= bytes[0] << 24;
break;
case 2:
if(val > 0xFFFF) return 0;
val |= bytes[0] << 24;
val |= bytes[1] << 16;
break;
case 3:
if(val > 0xFF) return 0;
val |= bytes[0] << 24;
val |= bytes[1] << 16;
val |= bytes[2] << 8;
break;
}
if(inp)
inp->s_addr = htonl(val);
*outNumBytes = num_bytes;
*outBase = base;
return 1;
}
// Adapted from ctrulib
static const char *inet_ntop4(const void *src, char *dst, socklen_t size) {
const u8 *ip = src;
char *p;
size_t i;
unsigned int n;
if(size < INET_ADDRSTRLEN) {
errno = ENOSPC;
return NULL;
}
for(p = dst, i = 0; i < 4; ++i) {
if(i > 0) *p++ = '.';
n = ip[i];
if(n >= 100) {
*p++ = n/100 + '0';
n %= 100;
}
if(n >= 10 || ip[i] >= 100) {
*p++ = n/10 + '0';
n %= 10;
}
*p++ = n + '0';
}
*p = 0;
return dst;
}
static int inet_pton4(const char *src, void *dst) {
int base;
size_t numBytes;
int ret = _socketInetAtonDetail(&base, &numBytes, src, (struct in_addr *)dst);
return (ret == 1 && base == 10 && numBytes == 4) ? 1 : 0;
}
// ==============================================================
/* Copyright (c) 1996 by Internet Software Consortium.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
* CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
* SOFTWARE.
*/
#define INADDRSZ 4
#define IN6ADDRSZ 16
#define INT16SZ 2
/* const char *
* inet_ntop6(src, dst, size)
* convert IPv6 binary address into presentation (printable) format
* author:
* Paul Vixie, 1996.
*/
static const char *
inet_ntop6(src, dst, size)
const u_char *src;
char *dst;
size_t size;
{
/*
* Note that int32_t and int16_t need only be "at least" large enough
* to contain a value of the specified size. On some systems, like
* Crays, there is no such thing as an integer variable with 16 bits.
* Keep this in mind if you think this function should have been coded
* to use pointer overlays. All the world's not a VAX.
*/
char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"], *tp;
struct { int base, len; } best = {0}, cur = {0};
u_int words[IN6ADDRSZ / INT16SZ];
int i;
/*
* Preprocess:
* Copy the input (bytewise) array into a wordwise array.
* Find the longest run of 0x00's in src[] for :: shorthanding.
*/
memset(words, 0, sizeof words);
for (i = 0; i < IN6ADDRSZ; i++)
words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3));
best.base = -1;
cur.base = -1;
for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++) {
if (words[i] == 0) {
if (cur.base == -1)
cur.base = i, cur.len = 1;
else
cur.len++;
} else {
if (cur.base != -1) {
if (best.base == -1 || cur.len > best.len)
best = cur;
cur.base = -1;
}
}
}
if (cur.base != -1) {
if (best.base == -1 || cur.len > best.len)
best = cur;
}
if (best.base != -1 && best.len < 2)
best.base = -1;
/*
* Format the result.
*/
tp = tmp;
for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++) {
/* Are we inside the best run of 0x00's? */
if (best.base != -1 && i >= best.base &&
i < (best.base + best.len)) {
if (i == best.base)
*tp++ = ':';
continue;
}
/* Are we following an initial run of 0x00s or any real hex? */
if (i != 0)
*tp++ = ':';
/* Is this address an encapsulated IPv4? */
if (i == 6 && best.base == 0 &&
(best.len == 6 || (best.len == 5 && words[5] == 0xffff))) {
if (!inet_ntop4(src+12, tp, sizeof tmp - (tp - tmp)))
return (NULL);
tp += strlen(tp);
break;
}
//TuxSH:
//sprintf(tp, "%x", words[i]);
{
char *e = tp + 7;
memset(e, '0', 4);
u_int word = words[i];
while(word > 0) {
static const char digits[] = "0123456789abcdef";
*e-- = digits[word & 0xF];
word >>= 4;
}
}
tp += strlen(tp);
}
/* Was it a trailing run of 0x00's? */
if (best.base != -1 && (best.base + best.len) == (IN6ADDRSZ / INT16SZ))
*tp++ = ':';
*tp++ = '\0';
/*
* Check for overflow, copy, and we're done.
*/
if ((tp - tmp) > size) {
errno = ENOSPC;
return (NULL);
}
strcpy(dst, tmp);
return (dst);
}
/* int
* inet_pton6(src, dst)
* convert presentation level address to network order binary form.
* return:
* 1 if `src' is a valid [RFC1884 2.2] address, else 0.
* notice:
* (1) does not touch `dst' unless it's returning 1.
* (2) :: in a full address is silently ignored.
* credit:
* inspired by Mark Andrews.
* author:
* Paul Vixie, 1996.
*/
static int
inet_pton6(src, dst)
const char *src;
u_char *dst;
{
static const char xdigits_l[] = "0123456789abcdef",
xdigits_u[] = "0123456789ABCDEF";
u_char tmp[IN6ADDRSZ], *tp, *endp, *colonp;
const char *xdigits, *curtok;
int ch, saw_xdigit;
u_int val;
memset((tp = tmp), 0, IN6ADDRSZ);
endp = tp + IN6ADDRSZ;
colonp = NULL;
/* Leading :: requires some special handling. */
if (*src == ':')
if (*++src != ':')
return (0);
curtok = src;
saw_xdigit = 0;
val = 0;
while ((ch = *src++) != '\0') {
const char *pch;
if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL)
pch = strchr((xdigits = xdigits_u), ch);
if (pch != NULL) {
val <<= 4;
val |= (pch - xdigits);
if (val > 0xffff)
return (0);
saw_xdigit = 1;
continue;
}
if (ch == ':') {
curtok = src;
if (!saw_xdigit) {
if (colonp)
return (0);
colonp = tp;
continue;
}
if (tp + INT16SZ > endp)
return (0);
*tp++ = (u_char) (val >> 8) & 0xff;
*tp++ = (u_char) val & 0xff;
saw_xdigit = 0;
val = 0;
continue;
}
if (ch == '.' && ((tp + INADDRSZ) <= endp) &&
inet_pton4(curtok, tp) > 0) {
tp += INADDRSZ;
saw_xdigit = 0;
break; /* '\0' was seen by inet_pton4(). */
}
return (0);
}
if (saw_xdigit) {
if (tp + INT16SZ > endp)
return (0);
*tp++ = (u_char) (val >> 8) & 0xff;
*tp++ = (u_char) val & 0xff;
}
if (colonp != NULL) {
/*
* Since some memmove()'s erroneously fail to handle
* overlapping regions, we'll do the shift by hand.
*/
const int n = tp - colonp;
int i;
for (i = 1; i <= n; i++) {
endp[- i] = colonp[n - i];
colonp[n - i] = 0;
}
tp = endp;
}
if (tp != endp)
return (0);
/* bcopy(tmp, dst, IN6ADDRSZ); */
memcpy(dst, tmp, IN6ADDRSZ);
return (1);
}
// ==============================================================
const SocketInitConfig *socketGetDefaultInitConfig(void) { const SocketInitConfig *socketGetDefaultInitConfig(void) {
return &g_defaultSocketInitConfig; return &g_defaultSocketInitConfig;
} }
@ -582,6 +147,87 @@ Result socketGetLastSfdnsresResult(void) {
return g_sfdnsresResult; return g_sfdnsresResult;
} }
/********************************************* BSD:U FUNCTIONS AND RELATED *********************************************/
/***********************************************************************************************************************/
static int _socketGetFd(int fd) {
__handle *handle = __get_handle(fd);
if(handle == NULL) {
errno = EBADF;
return -1;
}
if(strcmp(devoptab_list[handle->device]->name, "soc") != 0) {
errno = ENOTSOCK;
return -1;
}
return *(int *)handle->fileStruct;
}
static int _socketParseBsdResult(struct _reent *r, int ret) {
int errno_;
if(ret != -1)
return ret; // Nothing to do
else {
if(g_bsdErrno == -1) {
// We're using -1 to signal Switch error codes.
// Note: all of the bsd:u/s handlers return 0.
switch(g_bsdResult) {
case 0xD201:
errno_ = ENFILE;
case 0xD401:
errno_ = EFAULT;
break;
case 0x10601:
errno_ = EBUSY;
break;
default:
errno_ = EPIPE;
break;
}
}
else
errno_ = g_bsdErrno; // Nintendo actually used the Linux errno definitions for their FreeBSD build :)
}
if(r == NULL)
errno = errno_;
else
r->_errno = errno_;
return -1;
}
static int _socketOpen(struct _reent *r, void *fdptr, const char *path, int flags, int mode) {
(void)mode;
int ret = _socketParseBsdResult(r, bsdOpen(path, flags));
if(ret == -1)
return ret;
*(int *)fdptr = ret;
return 0;
}
static int _socketClose(struct _reent *r, void *fdptr) {
int fd = *(int *)fdptr;
return _socketParseBsdResult(r, bsdClose(fd));
}
static ssize_t _socketWrite(struct _reent *r, void *fdptr, const char *buf, size_t count) {
int fd = *(int *)fdptr;
ssize_t ret = bsdWrite(fd, buf, count);
_socketParseBsdResult(r, (int)ret);
return ret;
}
static ssize_t _socketRead(struct _reent *r, void *fdptr, char *buf, size_t count) {
int fd = *(int *)fdptr;
ssize_t ret = bsdRead(fd, buf, count);
_socketParseBsdResult(r, (int)ret);
return ret;
}
/* /*
It is way too complicated and inefficient to use devoptab with bsdSelect. It is way too complicated and inefficient to use devoptab with bsdSelect.
We're therefore implementing select with poll. We're therefore implementing select with poll.
@ -1013,6 +659,361 @@ int recvmmsg(int sockfd, struct mmsghdr *msgvec, unsigned int vlen, int flags, s
return -1; return -1;
} }
/****************************************** ARPA/INET.H FUNCTIONS AND RELATED ******************************************/
/***********************************************************************************************************************/
// Adapted from ctrulib
static int _socketInetAtonDetail(int *outBase, size_t *outNumBytes, const char *cp, struct in_addr *inp) {
int base;
u32 val;
int c;
char bytes[4];
size_t num_bytes = 0;
c = *cp;
for(;;) {
if(!isdigit(c)) return 0;
val = 0;
base = 10;
if(c == '0') {
c = *++cp;
if(c == 'x' || c == 'X') {
base = 16;
c = *++cp;
}
else base = 8;
}
for(;;) {
if(isdigit(c)) {
if(base == 8 && c >= '8') return 0;
val *= base;
val += c - '0';
c = *++cp;
}
else if(base == 16 && isxdigit(c)) {
val *= base;
val += c + 10 - (islower(c) ? 'a' : 'A');
c = *++cp;
}
else break;
}
if(c == '.') {
if(num_bytes > 3) return 0;
if(val > 0xFF) return 0;
bytes[num_bytes++] = val;
c = *++cp;
}
else break;
}
if(c != 0) {
*outNumBytes = num_bytes;
*outBase = base;
return 0;
}
switch(num_bytes) {
case 0:
break;
case 1:
if(val > 0xFFFFFF) return 0;
val |= bytes[0] << 24;
break;
case 2:
if(val > 0xFFFF) return 0;
val |= bytes[0] << 24;
val |= bytes[1] << 16;
break;
case 3:
if(val > 0xFF) return 0;
val |= bytes[0] << 24;
val |= bytes[1] << 16;
val |= bytes[2] << 8;
break;
}
if(inp)
inp->s_addr = htonl(val);
*outNumBytes = num_bytes;
*outBase = base;
return 1;
}
// Adapted from ctrulib
static const char *inet_ntop4(const void *src, char *dst, socklen_t size) {
const u8 *ip = src;
char *p;
size_t i;
unsigned int n;
if(size < INET_ADDRSTRLEN) {
errno = ENOSPC;
return NULL;
}
for(p = dst, i = 0; i < 4; ++i) {
if(i > 0) *p++ = '.';
n = ip[i];
if(n >= 100) {
*p++ = n/100 + '0';
n %= 100;
}
if(n >= 10 || ip[i] >= 100) {
*p++ = n/10 + '0';
n %= 10;
}
*p++ = n + '0';
}
*p = 0;
return dst;
}
static int inet_pton4(const char *src, void *dst) {
int base;
size_t numBytes;
int ret = _socketInetAtonDetail(&base, &numBytes, src, (struct in_addr *)dst);
return (ret == 1 && base == 10 && numBytes == 4) ? 1 : 0;
}
/* Copyright (c) 1996 by Internet Software Consortium.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
* CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
* SOFTWARE.
*/
#define INADDRSZ 4
#define IN6ADDRSZ 16
#define INT16SZ 2
/* const char *
* inet_ntop6(src, dst, size)
* convert IPv6 binary address into presentation (printable) format
* author:
* Paul Vixie, 1996.
*/
static const char *
inet_ntop6(src, dst, size)
const u_char *src;
char *dst;
size_t size;
{
/*
* Note that int32_t and int16_t need only be "at least" large enough
* to contain a value of the specified size. On some systems, like
* Crays, there is no such thing as an integer variable with 16 bits.
* Keep this in mind if you think this function should have been coded
* to use pointer overlays. All the world's not a VAX.
*/
char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"], *tp;
struct { int base, len; } best = {0}, cur = {0};
u_int words[IN6ADDRSZ / INT16SZ];
int i;
/*
* Preprocess:
* Copy the input (bytewise) array into a wordwise array.
* Find the longest run of 0x00's in src[] for :: shorthanding.
*/
memset(words, 0, sizeof words);
for (i = 0; i < IN6ADDRSZ; i++)
words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3));
best.base = -1;
cur.base = -1;
for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++) {
if (words[i] == 0) {
if (cur.base == -1)
cur.base = i, cur.len = 1;
else
cur.len++;
} else {
if (cur.base != -1) {
if (best.base == -1 || cur.len > best.len)
best = cur;
cur.base = -1;
}
}
}
if (cur.base != -1) {
if (best.base == -1 || cur.len > best.len)
best = cur;
}
if (best.base != -1 && best.len < 2)
best.base = -1;
/*
* Format the result.
*/
tp = tmp;
for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++) {
/* Are we inside the best run of 0x00's? */
if (best.base != -1 && i >= best.base &&
i < (best.base + best.len)) {
if (i == best.base)
*tp++ = ':';
continue;
}
/* Are we following an initial run of 0x00s or any real hex? */
if (i != 0)
*tp++ = ':';
/* Is this address an encapsulated IPv4? */
if (i == 6 && best.base == 0 &&
(best.len == 6 || (best.len == 5 && words[5] == 0xffff))) {
if (!inet_ntop4(src+12, tp, sizeof tmp - (tp - tmp)))
return (NULL);
tp += strlen(tp);
break;
}
//TuxSH:
//sprintf(tp, "%x", words[i]);
{
char *e = tp + 7;
memset(e, '0', 4);
u_int word = words[i];
while(word > 0) {
static const char digits[] = "0123456789abcdef";
*e-- = digits[word & 0xF];
word >>= 4;
}
}
tp += strlen(tp);
}
/* Was it a trailing run of 0x00's? */
if (best.base != -1 && (best.base + best.len) == (IN6ADDRSZ / INT16SZ))
*tp++ = ':';
*tp++ = '\0';
/*
* Check for overflow, copy, and we're done.
*/
if ((tp - tmp) > size) {
errno = ENOSPC;
return (NULL);
}
strcpy(dst, tmp);
return (dst);
}
/* int
* inet_pton6(src, dst)
* convert presentation level address to network order binary form.
* return:
* 1 if `src' is a valid [RFC1884 2.2] address, else 0.
* notice:
* (1) does not touch `dst' unless it's returning 1.
* (2) :: in a full address is silently ignored.
* credit:
* inspired by Mark Andrews.
* author:
* Paul Vixie, 1996.
*/
static int
inet_pton6(src, dst)
const char *src;
u_char *dst;
{
static const char xdigits_l[] = "0123456789abcdef",
xdigits_u[] = "0123456789ABCDEF";
u_char tmp[IN6ADDRSZ], *tp, *endp, *colonp;
const char *xdigits, *curtok;
int ch, saw_xdigit;
u_int val;
memset((tp = tmp), 0, IN6ADDRSZ);
endp = tp + IN6ADDRSZ;
colonp = NULL;
/* Leading :: requires some special handling. */
if (*src == ':')
if (*++src != ':')
return (0);
curtok = src;
saw_xdigit = 0;
val = 0;
while ((ch = *src++) != '\0') {
const char *pch;
if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL)
pch = strchr((xdigits = xdigits_u), ch);
if (pch != NULL) {
val <<= 4;
val |= (pch - xdigits);
if (val > 0xffff)
return (0);
saw_xdigit = 1;
continue;
}
if (ch == ':') {
curtok = src;
if (!saw_xdigit) {
if (colonp)
return (0);
colonp = tp;
continue;
}
if (tp + INT16SZ > endp)
return (0);
*tp++ = (u_char) (val >> 8) & 0xff;
*tp++ = (u_char) val & 0xff;
saw_xdigit = 0;
val = 0;
continue;
}
if (ch == '.' && ((tp + INADDRSZ) <= endp) &&
inet_pton4(curtok, tp) > 0) {
tp += INADDRSZ;
saw_xdigit = 0;
break; /* '\0' was seen by inet_pton4(). */
}
return (0);
}
if (saw_xdigit) {
if (tp + INT16SZ > endp)
return (0);
*tp++ = (u_char) (val >> 8) & 0xff;
*tp++ = (u_char) val & 0xff;
}
if (colonp != NULL) {
/*
* Since some memmove()'s erroneously fail to handle
* overlapping regions, we'll do the shift by hand.
*/
const int n = tp - colonp;
int i;
for (i = 1; i <= n; i++) {
endp[- i] = colonp[n - i];
colonp[n - i] = 0;
}
tp = endp;
}
if (tp != endp)
return (0);
/* bcopy(tmp, dst, IN6ADDRSZ); */
memcpy(dst, tmp, IN6ADDRSZ);
return (1);
}
const char *inet_ntop(int af, const void *src, char *dst, socklen_t size) { const char *inet_ntop(int af, const void *src, char *dst, socklen_t size) {
switch(af) { switch(af) {
case AF_INET: case AF_INET:
@ -1055,17 +1056,8 @@ in_addr_t inet_addr(const char *cp) {
return addr.s_addr; return addr.s_addr;
} }
long gethostid(void) { /******************************************** NETDB.H FUNCTIONS AND RELATED ********************************************/
return INADDR_LOOPBACK; //FIXME /***********************************************************************************************************************/
}
int gethostname(char *name, size_t namelen)
{
//FIXME
long hostid = gethostid();
const char *hostname = inet_ntop(AF_INET, &hostid, name, namelen);
return hostname == NULL ? -1 : 0;
}
static struct hostent *_socketDeserializeHostent(int *err, const void *out_he_serialized) { static struct hostent *_socketDeserializeHostent(int *err, const void *out_he_serialized) {
const char *buf = (const char *)out_he_serialized; const char *buf = (const char *)out_he_serialized;
@ -1522,3 +1514,18 @@ struct servent *getservent(void) { return NULL; }
void sethostent(int a) { (void)a;} void sethostent(int a) { (void)a;}
void setnetent(int a) { (void)a;} void setnetent(int a) { (void)a;}
void setprotoent(int a) { (void)a; } void setprotoent(int a) { (void)a; }
/******************************************** UNISTD.H FUNCTIONS AND RELATED ********************************************/
/************************************************************************************************************************/
long gethostid(void) {
return INADDR_LOOPBACK; //FIXME
}
int gethostname(char *name, size_t namelen) {
// The Switch doesn't have a proper name, so let's use its IP
struct in_addr in;
in.s_addr = gethostid();
const char *hostname = inet_ntop(AF_INET, &in, name, namelen);
return hostname == NULL ? -1 : 0;
}

View File

@ -284,7 +284,7 @@ int bsdOpen(const char *pathname, int flags) {
IpcCommand c; IpcCommand c;
ipcInitialize(&c); ipcInitialize(&c);
size_t pathlen = strnlen(pathname, 256); size_t pathlen = strlen(pathname) + 1;
ipcAddSendBuffer(&c, pathname, pathlen, 0); ipcAddSendBuffer(&c, pathname, pathlen, 0);
ipcAddSendStatic(&c, pathname, pathlen, 0); ipcAddSendStatic(&c, pathname, pathlen, 0);