diff --git a/nx/source/runtime/devices/socket.c b/nx/source/runtime/devices/socket.c index f504a799..10e012e8 100644 --- a/nx/source/runtime/devices/socket.c +++ b/nx/source/runtime/devices/socket.c @@ -4,11 +4,7 @@ #include #include #include -//#include #include -#include - -#include #include #include @@ -20,6 +16,7 @@ #include #include +#include #include "runtime/devices/socket.h" #include "services/bsd.h" @@ -87,438 +84,6 @@ static const SocketInitConfig g_defaultSocketInitConfig = { .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) { return &g_defaultSocketInitConfig; } @@ -582,6 +147,87 @@ Result socketGetLastSfdnsresResult(void) { 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. 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; } + +/****************************************** 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) { switch(af) { case AF_INET: @@ -1055,17 +1056,8 @@ in_addr_t inet_addr(const char *cp) { return addr.s_addr; } -long gethostid(void) { - 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; -} +/******************************************** NETDB.H FUNCTIONS AND RELATED ********************************************/ +/***********************************************************************************************************************/ static struct hostent *_socketDeserializeHostent(int *err, const void *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 setnetent(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; +} diff --git a/nx/source/services/bsd.c b/nx/source/services/bsd.c index 460ac3ef..434ac239 100644 --- a/nx/source/services/bsd.c +++ b/nx/source/services/bsd.c @@ -284,7 +284,7 @@ int bsdOpen(const char *pathname, int flags) { IpcCommand c; ipcInitialize(&c); - size_t pathlen = strnlen(pathname, 256); + size_t pathlen = strlen(pathname) + 1; ipcAddSendBuffer(&c, pathname, pathlen, 0); ipcAddSendStatic(&c, pathname, pathlen, 0);