// in specific compiler, library, or OS versions, localize all that here
// and in portability.c
-// The tendency of gcc to produce stupid warnings continues with
-// warn_unused_result, which warns about things like ignoring the return code
-// of nice(2) (which is completely useless since -1 is a legitimate return
-// value on success and even the man page tells you to use errno instead).
-
-// This makes it stop.
-
-// Except on Android, where fortify is mandatory.
-#if !defined(__ANDROID__)
-#undef _FORTIFY_SOURCE
-#endif
-
// For musl
#define _ALL_SOURCE
#ifdef __GNUC__
#define noreturn __attribute__((noreturn))
+#define printf_format __attribute__((format(printf, 1, 2)))
#else
#define noreturn
+#define printf_format
#endif
// Always use long file support.
#include <features.h>
+// Types various replacement prototypes need
+#include <sys/types.h>
+
// Various constants old build environments might not have even if kernel does
#ifndef AT_FDCWD
#define AT_REMOVEDIR 0x200
#endif
+#ifndef RLIMIT_RTTIME
+#define RLIMIT_RTTIME 15
+#endif
+
+#ifndef SEEK_DATA
+#define SEEK_DATA 3
+#endif
+
// We don't define GNU_dammit because we're not part of the gnu project, and
// don't want to get any FSF on us. Unfortunately glibc (gnu libc)
// won't give us Linux syscall wrappers without claiming to be part of the
#include <time.h>
char *strptime(const char *buf, const char *format, struct tm *tm);
+// They didn't like posix basename so they defined another function with the
+// same name and if you include libgen.h it #defines basename to something
+// else (where they implemented the real basename), and that define breaks
+// the table entry for the basename command. They didn't make a new function
+// with a different name for their new behavior because gnu.
+//
+// Solution: don't use their broken header, provide an inline to redirect the
+// correct name to the broken name.
+
+char *dirname(char *path);
+char *__xpg_basename(char *path);
+static inline char *basename(char *path) { return __xpg_basename(path); }
+
// uClibc pretends to be glibc and copied a lot of its bugs, but has a few more
#if defined(__UCLIBC__)
#include <unistd.h>
// any flag newer than MS_MOVE, which was added in 2001 (linux 2.5.0.5),
// eleven years earlier.
+#include <sys/mount.h>
+#ifndef MS_MOVE
#define MS_MOVE (1<<13)
+#endif
+#ifndef MS_REC
#define MS_REC (1<<14)
+#endif
+#ifndef MS_SILENT
#define MS_SILENT (1<<15)
+#endif
+#ifndef MS_UNBINDABLE
#define MS_UNBINDABLE (1<<17)
+#endif
+#ifndef MS_PRIVATE
#define MS_PRIVATE (1<<18)
+#endif
+#ifndef MS_SLAVE
#define MS_SLAVE (1<<19)
+#endif
+#ifndef MS_SHARED
#define MS_SHARED (1<<20)
+#endif
+#ifndef MS_RELATIME
+#define MS_RELATIME (1<<21)
+#endif
// When building under obsolete glibc (Ubuntu 8.04-ish), hold its hand a bit.
#elif __GLIBC__ == 2 && __GLIBC_MINOR__ < 10
#ifndef MNT_DETACH
#define MNT_DETACH 2
#endif
-#endif
+#endif // Old glibc
-#endif
+#endif // glibc in general
-#ifdef __MUSL__
-#include <unistd.h>
-// Without this "rm -r dir" fails with "is directory".
-#define faccessat(A, B, C, D) faccessat(A, B, C, 0)
+#if !defined(__GLIBC__)
+// POSIX basename.
+#include <libgen.h>
#endif
// Work out how to do endianness
#endif
#if CFG_TOYBOX_UTMPX
#include <utmpx.h>
-#endif
-#if CFG_TOYBOX_PTY
-#include <pty.h>
#else
-pid_t forkpty(int *amaster, char *name, void *termp, void *winp);
+struct utmpx {int ut_type;};
+#define USER_PROCESS 0
+static inline struct utmpx *getutxent(void) {return 0;}
+static inline void setutxent(void) {;}
+static inline void endutxent(void) {;}
#endif
-
// Some systems don't define O_NOFOLLOW, and it varies by architecture, so...
#include <fcntl.h>
#ifndef O_NOFOLLOW
#define O_NOFOLLOW 0
#endif
+#ifndef O_NOATIME
+#define O_NOATIME 01000000
+#endif
+
#ifndef O_CLOEXEC
#define O_CLOEXEC 02000000
#endif
+#ifndef O_PATH
+#define O_PATH 010000000
+#endif
+
+// Glibc won't give you linux-kernel constants unless you say "no, a BUD lite"
+// even though linux has nothing to do with the FSF and never has.
+#ifndef F_SETPIPE_SZ
+#define F_SETPIPE_SZ 1031
+#endif
+
+#ifndef F_GETPIPE_SZ
+#define F_GETPIPE_SZ 1032
+#endif
+
#if defined(__SIZEOF_DOUBLE__) && defined(__SIZEOF_LONG__) \
&& __SIZEOF_DOUBLE__ <= __SIZEOF_LONG__
typedef double FLOAT;
typedef float FLOAT;
#endif
+#ifndef __uClinux__
+pid_t xfork(void);
+#endif
+
+//#define strncpy(...) @@strncpyisbadmmkay@@
+//#define strncat(...) @@strncatisbadmmkay@@
+
+#ifdef __ANDROID__
+#include <cutils/sched_policy.h>
+#else
+static inline int get_sched_policy(int tid, void *policy) {return 0;}
+static inline char *get_sched_policy_name(int policy) {return "unknown";}
+#endif