From 32f4b251f399c50cf48012df98cd8758cc10f960 Mon Sep 17 00:00:00 2001 From: ReenigneArcher <42013603+ReenigneArcher@users.noreply.github.com> Date: Sun, 5 Apr 2026 09:36:08 -0400 Subject: [PATCH] libc: Add POSIX headers & stubs --- lib/net/netinet/in.h | 10 +++ lib/net/netinet/tcp.h | 10 +++ lib/xboxrt/libc_extensions/conio.h | 37 +++++++++++ lib/xboxrt/libc_extensions/dirent.h | 40 ++++++++++++ lib/xboxrt/libc_extensions/errno_ext_.h | 4 ++ lib/xboxrt/libc_extensions/fcntl.h | 41 ++++++++++++ lib/xboxrt/libc_extensions/memory.h | 10 +++ lib/xboxrt/libc_extensions/poll.h | 10 +++ lib/xboxrt/libc_extensions/string_ext_.c | 31 +++++++++ lib/xboxrt/libc_extensions/string_ext_.h | 1 + lib/xboxrt/libc_extensions/sys/ioctl.h | 10 +++ lib/xboxrt/libc_extensions/sys/resource.h | 38 +++++++++++ lib/xboxrt/libc_extensions/sys/select.h | 10 +++ lib/xboxrt/libc_extensions/sys/stat.h | 77 +++++++++++++++++++++++ lib/xboxrt/libc_extensions/sys/time.h | 53 ++++++++++++++++ lib/xboxrt/libc_extensions/sys/types.h | 49 +++++++++++++++ lib/xboxrt/libc_extensions/unistd.h | 50 +++++++++++++++ 17 files changed, 481 insertions(+) create mode 100644 lib/net/netinet/in.h create mode 100644 lib/net/netinet/tcp.h create mode 100644 lib/xboxrt/libc_extensions/conio.h create mode 100644 lib/xboxrt/libc_extensions/dirent.h create mode 100644 lib/xboxrt/libc_extensions/fcntl.h create mode 100644 lib/xboxrt/libc_extensions/memory.h create mode 100644 lib/xboxrt/libc_extensions/poll.h create mode 100644 lib/xboxrt/libc_extensions/sys/ioctl.h create mode 100644 lib/xboxrt/libc_extensions/sys/resource.h create mode 100644 lib/xboxrt/libc_extensions/sys/select.h create mode 100644 lib/xboxrt/libc_extensions/sys/stat.h create mode 100644 lib/xboxrt/libc_extensions/sys/time.h create mode 100644 lib/xboxrt/libc_extensions/sys/types.h diff --git a/lib/net/netinet/in.h b/lib/net/netinet/in.h new file mode 100644 index 000000000..5027baae0 --- /dev/null +++ b/lib/net/netinet/in.h @@ -0,0 +1,10 @@ +// SPDX-License-Identifier: MIT + +#pragma once + +/* + * Provide the BSD netinet/in.h include path expected by Unix-oriented + * third-party libraries while reusing nxdk's lwIP socket compatibility layer. + */ + +#include diff --git a/lib/net/netinet/tcp.h b/lib/net/netinet/tcp.h new file mode 100644 index 000000000..7c2b40752 --- /dev/null +++ b/lib/net/netinet/tcp.h @@ -0,0 +1,10 @@ +// SPDX-License-Identifier: MIT + +#pragma once + +/* + * Provide the BSD netinet/tcp.h include path expected by Unix-oriented + * third-party libraries while reusing nxdk's lwIP socket compatibility layer. + */ + +#include diff --git a/lib/xboxrt/libc_extensions/conio.h b/lib/xboxrt/libc_extensions/conio.h new file mode 100644 index 000000000..8b54edfa6 --- /dev/null +++ b/lib/xboxrt/libc_extensions/conio.h @@ -0,0 +1,37 @@ +// SPDX-License-Identifier: MIT + +#pragma once + +/* + * Provide the tiny conio.h subset that some cross-built utility code expects. + * The Xbox runtime does not provide a console keyboard in these call sites, so + * the helpers intentionally report no pending input. + */ + +#ifdef __cplusplus +extern "C" { +#endif + +static inline int _kbhit(void) +{ + return 0; +} + +static inline int _getch(void) +{ + return -1; +} + +static inline int kbhit(void) +{ + return _kbhit(); +} + +static inline int getch(void) +{ + return _getch(); +} + +#ifdef __cplusplus +} +#endif diff --git a/lib/xboxrt/libc_extensions/dirent.h b/lib/xboxrt/libc_extensions/dirent.h new file mode 100644 index 000000000..2fe4a6957 --- /dev/null +++ b/lib/xboxrt/libc_extensions/dirent.h @@ -0,0 +1,40 @@ +// SPDX-License-Identifier: MIT + +#pragma once + +/* + * Provide a minimal dirent surface for code that is compiled as part of a + * third-party build but does not enumerate Xbox directories at runtime. + */ + +#ifdef __cplusplus +extern "C" { +#endif + +struct dirent { + char d_name[256]; +}; + +typedef struct nxdk_dir_stub DIR; + +static inline DIR *opendir(const char *path) +{ + (void) path; + return 0; +} + +static inline int closedir(DIR *directory) +{ + (void) directory; + return -1; +} + +static inline struct dirent *readdir(DIR *directory) +{ + (void) directory; + return 0; +} + +#ifdef __cplusplus +} +#endif diff --git a/lib/xboxrt/libc_extensions/errno_ext_.h b/lib/xboxrt/libc_extensions/errno_ext_.h index 387d5cde3..c10bfc7da 100644 --- a/lib/xboxrt/libc_extensions/errno_ext_.h +++ b/lib/xboxrt/libc_extensions/errno_ext_.h @@ -8,3 +8,7 @@ #define _PDCLIB_ERRNO_T_DEFINED _PDCLIB_ERRNO_T_DEFINED typedef int errno_t; #endif + +#ifndef EHOSTDOWN +#define EHOSTDOWN EHOSTUNREACH +#endif diff --git a/lib/xboxrt/libc_extensions/fcntl.h b/lib/xboxrt/libc_extensions/fcntl.h new file mode 100644 index 000000000..e8b8ccc31 --- /dev/null +++ b/lib/xboxrt/libc_extensions/fcntl.h @@ -0,0 +1,41 @@ +// SPDX-License-Identifier: MIT + +#pragma once + +/* + * Provide the subset of fcntl.h constants that nxdk consumers currently need. + * + * Some libraries only need this header to exist, while others also depend on + * the open mode constants below. + */ + +#ifndef O_RDONLY +#define O_RDONLY 0x0000 +#endif +#ifndef O_WRONLY +#define O_WRONLY 0x0001 +#endif +#ifndef O_RDWR +#define O_RDWR 0x0002 +#endif +#ifndef O_ACCMODE +#define O_ACCMODE (O_RDONLY | O_WRONLY | O_RDWR) +#endif +#ifndef O_CREAT +#define O_CREAT 0x0100 +#endif +#ifndef O_EXCL +#define O_EXCL 0x0200 +#endif +#ifndef O_TRUNC +#define O_TRUNC 0x0400 +#endif +#ifndef O_APPEND +#define O_APPEND 0x0800 +#endif +#ifndef O_BINARY +#define O_BINARY 0x0000 +#endif +#ifndef O_TEXT +#define O_TEXT 0x0000 +#endif diff --git a/lib/xboxrt/libc_extensions/memory.h b/lib/xboxrt/libc_extensions/memory.h new file mode 100644 index 000000000..05d09fc20 --- /dev/null +++ b/lib/xboxrt/libc_extensions/memory.h @@ -0,0 +1,10 @@ +// SPDX-License-Identifier: MIT + +#pragma once + +/* + * Older third-party sources may still include memory.h for the standard string + * and memory routines. Route that legacy include to string.h. + */ + +#include diff --git a/lib/xboxrt/libc_extensions/poll.h b/lib/xboxrt/libc_extensions/poll.h new file mode 100644 index 000000000..8a6d8c91a --- /dev/null +++ b/lib/xboxrt/libc_extensions/poll.h @@ -0,0 +1,10 @@ +// SPDX-License-Identifier: MIT + +#pragma once + +/* + * Provide the POSIX poll.h include path expected by Unix-oriented third-party + * libraries while reusing nxdk's socket compatibility layer. + */ + +#include diff --git a/lib/xboxrt/libc_extensions/string_ext_.c b/lib/xboxrt/libc_extensions/string_ext_.c index 7ef06ab81..a12b171aa 100644 --- a/lib/xboxrt/libc_extensions/string_ext_.c +++ b/lib/xboxrt/libc_extensions/string_ext_.c @@ -22,6 +22,37 @@ char *strdup (const char *s) return new_s; } +char *strtok_r(char *str, const char *delim, char **saveptr) +{ + char *token; + char *end; + + if (str != NULL) { + *saveptr = str; + } + + if (*saveptr == NULL) { + return NULL; + } + + *saveptr += strspn(*saveptr, delim); + if (**saveptr == '\0') { + *saveptr = NULL; + return NULL; + } + + token = *saveptr; + end = token + strcspn(token, delim); + if (*end == '\0') { + *saveptr = NULL; + } else { + *end = '\0'; + *saveptr = end + 1; + } + + return token; +} + int _strnicmp (const char *s1, const char *s2, size_t n) { assert(s1); diff --git a/lib/xboxrt/libc_extensions/string_ext_.h b/lib/xboxrt/libc_extensions/string_ext_.h index 23e5e0cf2..94d6523fc 100644 --- a/lib/xboxrt/libc_extensions/string_ext_.h +++ b/lib/xboxrt/libc_extensions/string_ext_.h @@ -7,6 +7,7 @@ extern "C" { #endif char *strdup (const char *s); +char *strtok_r(char *str, const char *delim, char **saveptr); static char *_strdup (const char *s) { diff --git a/lib/xboxrt/libc_extensions/sys/ioctl.h b/lib/xboxrt/libc_extensions/sys/ioctl.h new file mode 100644 index 000000000..2483936c3 --- /dev/null +++ b/lib/xboxrt/libc_extensions/sys/ioctl.h @@ -0,0 +1,10 @@ +// SPDX-License-Identifier: MIT + +#pragma once + +/* + * Provide the POSIX sys/ioctl.h include path expected by Unix-oriented + * third-party libraries while reusing nxdk's socket compatibility layer. + */ + +#include diff --git a/lib/xboxrt/libc_extensions/sys/resource.h b/lib/xboxrt/libc_extensions/sys/resource.h new file mode 100644 index 000000000..37c707e28 --- /dev/null +++ b/lib/xboxrt/libc_extensions/sys/resource.h @@ -0,0 +1,38 @@ +// SPDX-License-Identifier: MIT + +#pragma once + +/* + * Provide the small sys/resource.h subset required by libraries that probe for + * process usage statistics during build-time utility code paths. + */ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define RUSAGE_SELF 0 + +struct rusage { + struct timeval ru_utime; + struct timeval ru_stime; +}; + +static inline int getrusage(int who, struct rusage *usage) +{ + (void) who; + if (usage != NULL) { + usage->ru_utime.tv_sec = 0; + usage->ru_utime.tv_usec = 0; + usage->ru_stime.tv_sec = 0; + usage->ru_stime.tv_usec = 0; + } + return -1; +} + +#ifdef __cplusplus +} +#endif diff --git a/lib/xboxrt/libc_extensions/sys/select.h b/lib/xboxrt/libc_extensions/sys/select.h new file mode 100644 index 000000000..49e731422 --- /dev/null +++ b/lib/xboxrt/libc_extensions/sys/select.h @@ -0,0 +1,10 @@ +// SPDX-License-Identifier: MIT + +#pragma once + +/* + * Provide the POSIX sys/select.h include path expected by Unix-oriented + * third-party libraries while reusing nxdk's socket compatibility layer. + */ + +#include diff --git a/lib/xboxrt/libc_extensions/sys/stat.h b/lib/xboxrt/libc_extensions/sys/stat.h new file mode 100644 index 000000000..24774c1c3 --- /dev/null +++ b/lib/xboxrt/libc_extensions/sys/stat.h @@ -0,0 +1,77 @@ +// SPDX-License-Identifier: MIT + +#pragma once + +/* + * Provide the limited sys/stat.h surface currently needed by nxdk consumers. + * + * This keeps the declarations close to the rest of nxdk's libc extension layer + * while the underlying file metadata support remains intentionally small. + */ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef NXDK_DEV_T_DEFINED +#define NXDK_DEV_T_DEFINED +typedef unsigned int dev_t; +#endif + +#ifndef NXDK_INO_T_DEFINED +#define NXDK_INO_T_DEFINED +typedef unsigned int ino_t; +#endif + +#ifndef NXDK_NLINK_T_DEFINED +#define NXDK_NLINK_T_DEFINED +typedef unsigned int nlink_t; +#endif + +#ifndef S_IFMT +#define S_IFMT 0170000 +#endif +#ifndef S_IFDIR +#define S_IFDIR 0040000 +#endif +#ifndef S_IFCHR +#define S_IFCHR 0020000 +#endif +#ifndef S_IFBLK +#define S_IFBLK 0060000 +#endif +#ifndef S_IFREG +#define S_IFREG 0100000 +#endif +#ifndef S_ISDIR +#define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR) +#endif +#ifndef S_ISREG +#define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG) +#endif + +struct stat { + dev_t st_dev; + mode_t st_mode; + ino_t st_ino; + nlink_t st_nlink; + uid_t st_uid; + gid_t st_gid; + dev_t st_rdev; + unsigned int st_size; + time_t st_atime; + time_t st_mtime; + time_t st_ctime; +}; + +int fstat(int fd, struct stat *status); +int stat(const char *path, struct stat *status); +int _fstat(int fd, struct stat *status); +int _stat(const char *path, struct stat *status); + +#ifdef __cplusplus +} +#endif diff --git a/lib/xboxrt/libc_extensions/sys/time.h b/lib/xboxrt/libc_extensions/sys/time.h new file mode 100644 index 000000000..63997e49b --- /dev/null +++ b/lib/xboxrt/libc_extensions/sys/time.h @@ -0,0 +1,53 @@ +// SPDX-License-Identifier: MIT + +#pragma once + +/* + * Provide a standalone POSIX-style sys/time.h for nxdk builds. + * + * lwIP can define timeval from its socket headers, but many third-party + * libraries include sys/time.h directly before they include any socket header. + * Setting LWIP_TIMEVAL_PRIVATE to 0 keeps later lwIP includes from defining a + * second timeval. + */ + +#include + +#ifndef LWIP_TIMEVAL_PRIVATE +#define LWIP_TIMEVAL_PRIVATE 0 +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +struct timezone { + int tz_minuteswest; + int tz_dsttime; +}; + +#ifndef LWIP_HDR_SOCKETS_H +struct timeval { + time_t tv_sec; + long tv_usec; +}; +#endif + +static inline int gettimeofday(struct timeval *timeValue, struct timezone *timeZone) +{ + if (timeValue != NULL) { + timeValue->tv_sec = time(NULL); + timeValue->tv_usec = 0; + } + + if (timeZone != NULL) { + timeZone->tz_minuteswest = 0; + timeZone->tz_dsttime = 0; + } + + return 0; +} + +#ifdef __cplusplus +} +#endif diff --git a/lib/xboxrt/libc_extensions/sys/types.h b/lib/xboxrt/libc_extensions/sys/types.h new file mode 100644 index 000000000..7f6f4104f --- /dev/null +++ b/lib/xboxrt/libc_extensions/sys/types.h @@ -0,0 +1,49 @@ +// SPDX-License-Identifier: MIT + +#pragma once + +/* + * Provide the small POSIX sys/types.h surface that nxdk consumers expect when + * they follow the Unix/BSD socket path instead of the WinSock path. + */ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef NXDK_PID_T_DEFINED +#define NXDK_PID_T_DEFINED +typedef int pid_t; +#endif + +#ifndef NXDK_UID_T_DEFINED +#define NXDK_UID_T_DEFINED +typedef unsigned int uid_t; +#endif + +#ifndef NXDK_GID_T_DEFINED +#define NXDK_GID_T_DEFINED +typedef unsigned int gid_t; +#endif + +#ifndef NXDK_MODE_T_DEFINED +#define NXDK_MODE_T_DEFINED +typedef uint32_t mode_t; +#endif + +#ifndef NXDK_OFF_T_DEFINED +#define NXDK_OFF_T_DEFINED +typedef long off_t; +#endif + +#ifndef NXDK_SSIZE_T_DEFINED +#define NXDK_SSIZE_T_DEFINED +typedef int ssize_t; +#endif + +#ifdef __cplusplus +} +#endif diff --git a/lib/xboxrt/libc_extensions/unistd.h b/lib/xboxrt/libc_extensions/unistd.h index f099d363f..54dc73709 100644 --- a/lib/xboxrt/libc_extensions/unistd.h +++ b/lib/xboxrt/libc_extensions/unistd.h @@ -1,3 +1,53 @@ // SPDX-License-Identifier: MIT // SPDX-FileCopyrightText: 2017 Matt Borgerson + +#pragma once + +/* + * Provide the small POSIX unistd.h surface that nxdk consumers currently need. + * + * The read(), write(), and lseek() stubs exist so cross-built third-party + * utility code can compile even though the shipping Xbox binary does not use + * those file descriptor paths at runtime. + */ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +static inline pid_t getpid(void) +{ + return 1; +} + +static inline ssize_t read(int fd, void *buffer, size_t count) +{ + (void) fd; + (void) buffer; + (void) count; + return -1; +} + +static inline ssize_t write(int fd, const void *buffer, size_t count) +{ + (void) fd; + (void) buffer; + (void) count; + return -1; +} + +static inline off_t lseek(int fd, off_t offset, int whence) +{ + (void) fd; + (void) offset; + (void) whence; + return -1; +} + +#ifdef __cplusplus +} +#endif