diff options
9 files changed, 5 insertions, 7381 deletions
diff --git a/main/musl/0001-updates-from-git.patch b/main/musl/0001-updates-from-git.patch deleted file mode 100644 index 0ed2f7d3e5..0000000000 --- a/main/musl/0001-updates-from-git.patch +++ /dev/null @@ -1,6804 +0,0 @@ -git diff v0.9.14..0311d1dd17ca - -diff --git a/INSTALL b/INSTALL -index ee1fe09..27ed9d7 100644 ---- a/INSTALL -+++ b/INSTALL -@@ -20,7 +20,7 @@ weak aliases, and stand-alone assembly source files. - The system used to build musl does not need to be Linux-based, nor do - the Linux kernel headers need to be available. - --If support for dynamic linking is desired, some further requriements -+If support for dynamic linking is desired, some further requirements - are placed on the compiler and linker. In particular, the linker must - support the -Bsymbolic-functions option. - -@@ -129,7 +129,7 @@ source/build tree. - ==== Option 2: Installing musl as the primary C library ==== - - In this setup, you will need an existing compiler/toolchain. It --shouldnt matter whether it was configured for glibc, uClibc, musl, or -+shouldn't matter whether it was configured for glibc, uClibc, musl, or - something else entirely, but sometimes gcc can be uncooperative, - especially if the system distributor has built gcc with strange - options. It probably makes the most sense to perform the following -diff --git a/Makefile b/Makefile -index 7ac58d4..0ab0bfd 100644 ---- a/Makefile -+++ b/Makefile -@@ -20,6 +20,7 @@ SRCS = $(sort $(wildcard src/*/*.c arch/$(ARCH)/src/*.c)) - OBJS = $(SRCS:.c=.o) - LOBJS = $(OBJS:.o=.lo) - GENH = include/bits/alltypes.h -+GENH_INT = src/internal/version.h - IMPH = src/internal/stdio_impl.h src/internal/pthread_impl.h src/internal/libc.h - - LDFLAGS = -@@ -64,7 +65,7 @@ clean: - rm -f $(LOBJS) - rm -f $(ALL_LIBS) lib/*.[ao] lib/*.so - rm -f $(ALL_TOOLS) -- rm -f $(GENH) -+ rm -f $(GENH) $(GENH_INT) - rm -f include/bits - - distclean: clean -@@ -79,6 +80,11 @@ include/bits/alltypes.h.in: include/bits - include/bits/alltypes.h: include/bits/alltypes.h.in include/alltypes.h.in tools/mkalltypes.sed - sed -f tools/mkalltypes.sed include/bits/alltypes.h.in include/alltypes.h.in > $@ - -+src/internal/version.h: $(wildcard VERSION .git) -+ printf '#define VERSION "%s"\n' "$$(sh tools/version.sh)" > $@ -+ -+src/internal/version.lo: src/internal/version.h -+ - src/ldso/dynlink.lo: arch/$(ARCH)/reloc.h - - crt/crt1.o crt/Scrt1.o: $(wildcard arch/$(ARCH)/crt_arch.h) -diff --git a/VERSION b/VERSION -new file mode 100644 -index 0000000..6d44d22 ---- /dev/null -+++ b/VERSION -@@ -0,0 +1 @@ -+0.9.14 -diff --git a/arch/arm/bits/fcntl.h b/arch/arm/bits/fcntl.h -index 98e91d5..eba10ff 100644 ---- a/arch/arm/bits/fcntl.h -+++ b/arch/arm/bits/fcntl.h -@@ -15,6 +15,7 @@ - #define O_DIRECT 0200000 - #define O_LARGEFILE 0400000 - #define O_NOATIME 01000000 -+#define O_TMPFILE 020040000 - #define O_NDELAY O_NONBLOCK - - #define F_DUPFD 0 -diff --git a/arch/arm/bits/float.h b/arch/arm/bits/float.h -index 89e9eb6..ec46b94 100644 ---- a/arch/arm/bits/float.h -+++ b/arch/arm/bits/float.h -@@ -1,10 +1,10 @@ - #define FLT_ROUNDS 1 - #define FLT_EVAL_METHOD 0 - --#define LDBL_TRUE_MIN 4.9406564584124654e-324 --#define LDBL_MIN 2.2250738585072014e-308 --#define LDBL_MAX 1.7976931348623157e+308 --#define LDBL_EPSILON 2.2204460492503131e-16 -+#define LDBL_TRUE_MIN 4.94065645841246544177e-324L -+#define LDBL_MIN 2.22507385850720138309e-308L -+#define LDBL_MAX 1.79769313486231570815e+308L -+#define LDBL_EPSILON 2.22044604925031308085e-16L - - #define LDBL_MANT_DIG 53 - #define LDBL_MIN_EXP (-1021) -diff --git a/arch/i386/bits/fcntl.h b/arch/i386/bits/fcntl.h -index 4cc0312..0fa8e19 100644 ---- a/arch/i386/bits/fcntl.h -+++ b/arch/i386/bits/fcntl.h -@@ -15,6 +15,7 @@ - #define O_DIRECT 040000 - #define O_LARGEFILE 0100000 - #define O_NOATIME 01000000 -+#define O_TMPFILE 020200000 - #define O_NDELAY O_NONBLOCK - - #define F_DUPFD 0 -diff --git a/arch/i386/bits/syscall.h b/arch/i386/bits/syscall.h -index 800409a..2af242b 100644 ---- a/arch/i386/bits/syscall.h -+++ b/arch/i386/bits/syscall.h -@@ -333,6 +333,11 @@ - #define __NR_inotify_init1 332 - #define __NR_preadv 333 - #define __NR_pwritev 334 -+#define __NR_rt_tgsigqueueinfo 335 -+#define __NR_perf_event_open 336 -+#define __NR_recvmmsg 337 -+#define __NR_fanotify_init 338 -+#define __NR_fanotify_mark 339 - #define __NR_prlimit64 340 - #define __NR_name_to_handle_at 341 - #define __NR_open_by_handle_at 342 -@@ -683,6 +688,11 @@ - #define SYS_inotify_init1 332 - #define SYS_preadv 333 - #define SYS_pwritev 334 -+#define SYS_rt_tgsigqueueinfo 335 -+#define SYS_perf_event_open 336 -+#define SYS_recvmmsg 337 -+#define SYS_fanotify_init 338 -+#define SYS_fanotify_mark 339 - #define SYS_prlimit64 340 - #define SYS_name_to_handle_at 341 - #define SYS_open_by_handle_at 342 -diff --git a/arch/microblaze/bits/fcntl.h b/arch/microblaze/bits/fcntl.h -index 4cc0312..0fa8e19 100644 ---- a/arch/microblaze/bits/fcntl.h -+++ b/arch/microblaze/bits/fcntl.h -@@ -15,6 +15,7 @@ - #define O_DIRECT 040000 - #define O_LARGEFILE 0100000 - #define O_NOATIME 01000000 -+#define O_TMPFILE 020200000 - #define O_NDELAY O_NONBLOCK - - #define F_DUPFD 0 -diff --git a/arch/microblaze/bits/float.h b/arch/microblaze/bits/float.h -index 89e9eb6..ec46b94 100644 ---- a/arch/microblaze/bits/float.h -+++ b/arch/microblaze/bits/float.h -@@ -1,10 +1,10 @@ - #define FLT_ROUNDS 1 - #define FLT_EVAL_METHOD 0 - --#define LDBL_TRUE_MIN 4.9406564584124654e-324 --#define LDBL_MIN 2.2250738585072014e-308 --#define LDBL_MAX 1.7976931348623157e+308 --#define LDBL_EPSILON 2.2204460492503131e-16 -+#define LDBL_TRUE_MIN 4.94065645841246544177e-324L -+#define LDBL_MIN 2.22507385850720138309e-308L -+#define LDBL_MAX 1.79769313486231570815e+308L -+#define LDBL_EPSILON 2.22044604925031308085e-16L - - #define LDBL_MANT_DIG 53 - #define LDBL_MIN_EXP (-1021) -diff --git a/arch/mips/bits/fcntl.h b/arch/mips/bits/fcntl.h -index c51ee7e..5e33f11 100644 ---- a/arch/mips/bits/fcntl.h -+++ b/arch/mips/bits/fcntl.h -@@ -15,6 +15,7 @@ - #define O_DIRECT 0100000 - #define O_LARGEFILE 020000 - #define O_NOATIME 01000000 -+#define O_TMPFILE 020200000 - #define O_NDELAY O_NONBLOCK - - #define F_DUPFD 0 -diff --git a/arch/mips/bits/float.h b/arch/mips/bits/float.h -index 89e9eb6..ec46b94 100644 ---- a/arch/mips/bits/float.h -+++ b/arch/mips/bits/float.h -@@ -1,10 +1,10 @@ - #define FLT_ROUNDS 1 - #define FLT_EVAL_METHOD 0 - --#define LDBL_TRUE_MIN 4.9406564584124654e-324 --#define LDBL_MIN 2.2250738585072014e-308 --#define LDBL_MAX 1.7976931348623157e+308 --#define LDBL_EPSILON 2.2204460492503131e-16 -+#define LDBL_TRUE_MIN 4.94065645841246544177e-324L -+#define LDBL_MIN 2.22507385850720138309e-308L -+#define LDBL_MAX 1.79769313486231570815e+308L -+#define LDBL_EPSILON 2.22044604925031308085e-16L - - #define LDBL_MANT_DIG 53 - #define LDBL_MIN_EXP (-1021) -diff --git a/arch/mips/bits/syscall.h b/arch/mips/bits/syscall.h -index 2726019..574d603 100644 ---- a/arch/mips/bits/syscall.h -+++ b/arch/mips/bits/syscall.h -@@ -318,30 +318,6 @@ - #define __NR_timerfd 4318 - #define __NR_eventfd 4319 - #define __NR_fallocate 4320 --#define __NR_fallocate 4320 --#define __NR_timerfd_create 4321 --#define __NR_timerfd_gettime 4322 --#define __NR_timerfd_settime 4323 --#define __NR_signalfd4 4324 --#define __NR_eventfd2 4325 --#define __NR_epoll_create1 4326 --#define __NR_dup3 4327 --#define __NR_pipe2 4328 --#define __NR_inotify_init1 4329 --#define __NR_preadv 4330 --#define __NR_pwritev 4331 --#define __NR_rt_tgsigqueueinfo 4332 --#define __NR_perf_event_open 4333 --#define __NR_accept4 4334 --#define __NR_recvmmsg 4335 --#define __NR_fanotify_init 4336 --#define __NR_fanotify_mark 4337 --#define __NR_prlimit64 4338 --#define __NR_name_to_handle_at 4339 --#define __NR_open_by_handle_at 4340 --#define __NR_clock_adjtime 4341 --#define __NR_syncfs 4342 --#define __NR_fallocate 4320 - #define __NR_timerfd_create 4321 - #define __NR_timerfd_gettime 4322 - #define __NR_timerfd_settime 4323 -@@ -693,30 +669,6 @@ - #define SYS_timerfd 4318 - #define SYS_eventfd 4319 - #define SYS_fallocate 4320 --#define SYS_fallocate 4320 --#define SYS_timerfd_create 4321 --#define SYS_timerfd_gettime 4322 --#define SYS_timerfd_settime 4323 --#define SYS_signalfd4 4324 --#define SYS_eventfd2 4325 --#define SYS_epoll_create1 4326 --#define SYS_dup3 4327 --#define SYS_pipe2 4328 --#define SYS_inotify_init1 4329 --#define SYS_preadv 4330 --#define SYS_pwritev 4331 --#define SYS_rt_tgsigqueueinfo 4332 --#define SYS_perf_event_open 4333 --#define SYS_accept4 4334 --#define SYS_recvmmsg 4335 --#define SYS_fanotify_init 4336 --#define SYS_fanotify_mark 4337 --#define SYS_prlimit64 4338 --#define SYS_name_to_handle_at 4339 --#define SYS_open_by_handle_at 4340 --#define SYS_clock_adjtime 4341 --#define SYS_syncfs 4342 --#define SYS_fallocate 4320 - #define SYS_timerfd_create 4321 - #define SYS_timerfd_gettime 4322 - #define SYS_timerfd_settime 4323 -diff --git a/arch/powerpc/bits/fcntl.h b/arch/powerpc/bits/fcntl.h -index b57bd57..548e574 100644 ---- a/arch/powerpc/bits/fcntl.h -+++ b/arch/powerpc/bits/fcntl.h -@@ -15,6 +15,7 @@ - #define O_DIRECT 0400000 - #define O_LARGEFILE 0200000 - #define O_NOATIME 01000000 -+#define O_TMPFILE 020040000 - #define O_NDELAY O_NONBLOCK - - #define F_DUPFD 0 -diff --git a/arch/powerpc/bits/float.h b/arch/powerpc/bits/float.h -index 89e9eb6..ec46b94 100644 ---- a/arch/powerpc/bits/float.h -+++ b/arch/powerpc/bits/float.h -@@ -1,10 +1,10 @@ - #define FLT_ROUNDS 1 - #define FLT_EVAL_METHOD 0 - --#define LDBL_TRUE_MIN 4.9406564584124654e-324 --#define LDBL_MIN 2.2250738585072014e-308 --#define LDBL_MAX 1.7976931348623157e+308 --#define LDBL_EPSILON 2.2204460492503131e-16 -+#define LDBL_TRUE_MIN 4.94065645841246544177e-324L -+#define LDBL_MIN 2.22507385850720138309e-308L -+#define LDBL_MAX 1.79769313486231570815e+308L -+#define LDBL_EPSILON 2.22044604925031308085e-16L - - #define LDBL_MANT_DIG 53 - #define LDBL_MIN_EXP (-1021) -diff --git a/arch/powerpc/pthread_arch.h b/arch/powerpc/pthread_arch.h -index cb2a70b..2d1ee43 100644 ---- a/arch/powerpc/pthread_arch.h -+++ b/arch/powerpc/pthread_arch.h -@@ -1,6 +1,11 @@ - static inline struct pthread *__pthread_self() - { -- register char* tp __asm__("r2"); -+#ifdef __clang__ -+ char *tp; -+ __asm__ __volatile__ ("mr %0, 2" : "=r"(tp) : : ); -+#else -+ register char *tp __asm__("r2"); -+#endif - return (pthread_t)(tp - 0x7000 - sizeof(struct pthread)); - } - -diff --git a/arch/x86_64/bits/fcntl.h b/arch/x86_64/bits/fcntl.h -index 0949f31..9977713 100644 ---- a/arch/x86_64/bits/fcntl.h -+++ b/arch/x86_64/bits/fcntl.h -@@ -15,6 +15,7 @@ - #define O_DIRECT 040000 - #define O_LARGEFILE 0 - #define O_NOATIME 01000000 -+#define O_TMPFILE 020200000 - #define O_NDELAY O_NONBLOCK - - #define F_DUPFD 0 -diff --git a/include/arpa/ftp.h b/include/arpa/ftp.h -index 4041aeb..fb0a46f 100644 ---- a/include/arpa/ftp.h -+++ b/include/arpa/ftp.h -@@ -1,5 +1,5 @@ --#ifndef _ARPA_FTP_H_ --#define _ARPA_FTP_H_ -+#ifndef _ARPA_FTP_H -+#define _ARPA_FTP_H - #define PRELIM 1 - #define COMPLETE 2 - #define CONTINUE 3 -diff --git a/include/fcntl.h b/include/fcntl.h -index b9bc269..55a89f9 100644 ---- a/include/fcntl.h -+++ b/include/fcntl.h -@@ -59,8 +59,6 @@ int posix_fallocate(int, off_t, off_t); - #define AT_REMOVEDIR 0x200 - #define AT_SYMLINK_FOLLOW 0x400 - #define AT_EACCESS 0x200 --#define AT_NO_AUTOMOUNT 0x800 --#define AT_EMPTY_PATH 0x1000 - - #define POSIX_FADV_NORMAL 0 - #define POSIX_FADV_RANDOM 1 -@@ -95,6 +93,9 @@ int posix_fallocate(int, off_t, off_t); - #endif - - #if defined(_GNU_SOURCE) || defined(_BSD_SOURCE) -+#define AT_NO_AUTOMOUNT 0x800 -+#define AT_EMPTY_PATH 0x1000 -+ - #define FAPPEND O_APPEND - #define FFSYNC O_FSYNC - #define FASYNC O_ASYNC -diff --git a/include/float.h b/include/float.h -index c7b208a..2b2ad39 100644 ---- a/include/float.h -+++ b/include/float.h -@@ -3,10 +3,10 @@ - - #define FLT_RADIX 2 - --#define FLT_TRUE_MIN 1.40129846e-45F --#define FLT_MIN 1.17549435e-38F --#define FLT_MAX 3.40282347e+38F --#define FLT_EPSILON 1.19209290e-07F -+#define FLT_TRUE_MIN 1.40129846432481707092e-45F -+#define FLT_MIN 1.17549435082228750797e-38F -+#define FLT_MAX 3.40282346638528859812e+38F -+#define FLT_EPSILON 1.1920928955078125e-07F - - #define FLT_MANT_DIG 24 - #define FLT_MIN_EXP (-125) -@@ -16,10 +16,10 @@ - #define FLT_MIN_10_EXP (-37) - #define FLT_MAX_10_EXP 38 - --#define DBL_TRUE_MIN 4.9406564584124654e-324 --#define DBL_MIN 2.2250738585072014e-308 --#define DBL_MAX 1.7976931348623157e+308 --#define DBL_EPSILON 2.2204460492503131e-16 -+#define DBL_TRUE_MIN 4.94065645841246544177e-324 -+#define DBL_MIN 2.22507385850720138309e-308 -+#define DBL_MAX 1.79769313486231570815e+308 -+#define DBL_EPSILON 2.22044604925031308085e-16 - - #define DBL_MANT_DIG 53 - #define DBL_MIN_EXP (-1021) -diff --git a/include/fnmatch.h b/include/fnmatch.h -index 72345b8..f959321 100644 ---- a/include/fnmatch.h -+++ b/include/fnmatch.h -@@ -5,17 +5,12 @@ - extern "C" { - #endif - --#include <features.h> -- - #define FNM_PATHNAME 0x1 - #define FNM_NOESCAPE 0x2 - #define FNM_PERIOD 0x4 -- --#ifdef _GNU_SOURCE - #define FNM_LEADING_DIR 0x8 - #define FNM_CASEFOLD 0x10 - #define FNM_FILE_NAME FNM_PATHNAME --#endif - - #define FNM_NOMATCH 1 - #define FNM_NOSYS (-1) -diff --git a/include/inttypes.h b/include/inttypes.h -index c51769f..61dcb72 100644 ---- a/include/inttypes.h -+++ b/include/inttypes.h -@@ -24,8 +24,10 @@ uintmax_t wcstoumax(const wchar_t *__restrict, wchar_t **__restrict, int); - - #if UINTPTR_MAX == UINT64_MAX - #define __PRI64 "l" -+#define __PRIPTR "l" - #else - #define __PRI64 "ll" -+#define __PRIPTR "" - #endif - - #define PRId8 "d" -@@ -125,12 +127,12 @@ uintmax_t wcstoumax(const wchar_t *__restrict, wchar_t **__restrict, int); - #define PRIxMAX __PRI64 "x" - #define PRIXMAX __PRI64 "X" - --#define PRIdPTR "ld" --#define PRIiPTR "li" --#define PRIoPTR "lo" --#define PRIuPTR "lu" --#define PRIxPTR "lx" --#define PRIXPTR "lX" -+#define PRIdPTR __PRIPTR "d" -+#define PRIiPTR __PRIPTR "i" -+#define PRIoPTR __PRIPTR "o" -+#define PRIuPTR __PRIPTR "u" -+#define PRIxPTR __PRIPTR "x" -+#define PRIXPTR __PRIPTR "X" - - #define SCNd8 "hhd" - #define SCNd16 "hd" -@@ -213,11 +215,11 @@ uintmax_t wcstoumax(const wchar_t *__restrict, wchar_t **__restrict, int); - #define SCNuMAX __PRI64 "u" - #define SCNxMAX __PRI64 "x" - --#define SCNdPTR "ld" --#define SCNiPTR "li" --#define SCNoPTR "lo" --#define SCNuPTR "lu" --#define SCNxPTR "lx" -+#define SCNdPTR __PRIPTR "d" -+#define SCNiPTR __PRIPTR "i" -+#define SCNoPTR __PRIPTR "o" -+#define SCNuPTR __PRIPTR "u" -+#define SCNxPTR __PRIPTR "x" - - #ifdef __cplusplus - } -diff --git a/include/langinfo.h b/include/langinfo.h -index c6349ad..2153c42 100644 ---- a/include/langinfo.h -+++ b/include/langinfo.h -@@ -5,6 +5,7 @@ - extern "C" { - #endif - -+#include <features.h> - #include <nl_types.h> - - #define __NEED_locale_t -@@ -75,8 +76,11 @@ extern "C" { - #define THOUSEP 0x10001 - #define YESEXPR 0x50000 - #define NOEXPR 0x50001 -+ -+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE) - #define YESSTR 0x50002 - #define NOSTR 0x50003 -+#endif - - char *nl_langinfo(nl_item); - char *nl_langinfo_l(nl_item, locale_t); -diff --git a/include/limits.h b/include/limits.h -index a8460cc..f9805a1 100644 ---- a/include/limits.h -+++ b/include/limits.h -@@ -55,7 +55,7 @@ - #define WORD_BIT 32 - #define SSIZE_MAX LONG_MAX - #define TZNAME_MAX 6 --#define TTY_NAME_MAX 20 -+#define TTY_NAME_MAX 32 - #define HOST_NAME_MAX 255 - - /* Implementation choices... */ -@@ -84,12 +84,18 @@ - #define NL_ARGMAX 9 - #define NL_LANGMAX 32 - #define NL_MSGMAX 32767 --#define NL_NMAX (MB_LEN_MAX*4) - #define NL_SETMAX 255 - #define NL_TEXTMAX 2048 - - #endif - -+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE) \ -+ || (defined(_XOPEN_SOURCE) && _XOPEN_SOURCE+0 < 700) -+ -+#define NL_NMAX 16 -+ -+#endif -+ - /* POSIX/SUS requirements follow. These numbers come directly - * from SUS and have nothing to do with the host system. */ - -diff --git a/include/locale.h b/include/locale.h -index 7e80fd9..ce38438 100644 ---- a/include/locale.h -+++ b/include/locale.h -@@ -7,7 +7,11 @@ extern "C" { - - #include <features.h> - -+#ifdef __cplusplus - #define NULL 0L -+#else -+#define NULL ((void*)0) -+#endif - - #define LC_CTYPE 0 - #define LC_NUMERIC 1 -diff --git a/include/math.h b/include/math.h -index c029156..bbee62e 100644 ---- a/include/math.h -+++ b/include/math.h -@@ -16,7 +16,7 @@ extern "C" { - #define INFINITY __builtin_inff() - #else - #define NAN (0.0f/0.0f) --#define INFINITY 1e40f -+#define INFINITY 1e5000f - #endif - - #define HUGE_VALF INFINITY -@@ -91,20 +91,20 @@ int __signbitl(long double); - static __inline int __is##rel(type __x, type __y) \ - { return !isunordered(__x,__y) && __x op __y; } - --__ISREL_DEF(lessf, <, float) --__ISREL_DEF(less, <, double) -+__ISREL_DEF(lessf, <, float_t) -+__ISREL_DEF(less, <, double_t) - __ISREL_DEF(lessl, <, long double) --__ISREL_DEF(lessequalf, <=, float) --__ISREL_DEF(lessequal, <=, double) -+__ISREL_DEF(lessequalf, <=, float_t) -+__ISREL_DEF(lessequal, <=, double_t) - __ISREL_DEF(lessequall, <=, long double) --__ISREL_DEF(lessgreaterf, !=, float) --__ISREL_DEF(lessgreater, !=, double) -+__ISREL_DEF(lessgreaterf, !=, float_t) -+__ISREL_DEF(lessgreater, !=, double_t) - __ISREL_DEF(lessgreaterl, !=, long double) --__ISREL_DEF(greaterf, >, float) --__ISREL_DEF(greater, >, double) -+__ISREL_DEF(greaterf, >, float_t) -+__ISREL_DEF(greater, >, double_t) - __ISREL_DEF(greaterl, >, long double) --__ISREL_DEF(greaterequalf, >=, float) --__ISREL_DEF(greaterequal, >=, double) -+__ISREL_DEF(greaterequalf, >=, float_t) -+__ISREL_DEF(greaterequal, >=, double_t) - __ISREL_DEF(greaterequall, >=, long double) - - #define __tg_pred_2(x, y, p) ( \ -@@ -349,7 +349,7 @@ long double truncl(long double); - - #if defined(_XOPEN_SOURCE) || defined(_BSD_SOURCE) - #undef MAXFLOAT --#define MAXFLOAT 3.40282347e+38F -+#define MAXFLOAT 3.40282346638528859812e+38F - #endif - - #if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE) -@@ -379,7 +379,13 @@ double yn(int, double); - #endif - - #if defined(_GNU_SOURCE) || defined(_BSD_SOURCE) --#define HUGE 3.40282347e+38F -+#define HUGE 3.40282346638528859812e+38F -+ -+double drem(double, double); -+float dremf(float, float); -+ -+int finite(double); -+int finitef(float); - - double scalb(double, double); - float scalbf(float, float); -diff --git a/include/netinet/in.h b/include/netinet/in.h -index 881f670..8be51e8 100644 ---- a/include/netinet/in.h -+++ b/include/netinet/in.h -@@ -206,7 +206,7 @@ uint16_t ntohs(uint16_t); - #define IP_MULTICAST_ALL 49 - #define IP_UNICAST_IF 50 - --#ifdef _GNU_SOURCE -+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE) - #define MCAST_JOIN_GROUP 42 - #define MCAST_BLOCK_SOURCE 43 - #define MCAST_UNBLOCK_SOURCE 44 -@@ -251,6 +251,47 @@ struct ip_mreqn - int imr_ifindex; - }; - -+struct ip_mreq_source { -+ struct in_addr imr_multiaddr; -+ struct in_addr imr_interface; -+ struct in_addr imr_sourceaddr; -+}; -+ -+struct ip_msfilter { -+ struct in_addr imsf_multiaddr; -+ struct in_addr imsf_interface; -+ uint32_t imsf_fmode; -+ uint32_t imsf_numsrc; -+ struct in_addr imsf_slist[1]; -+}; -+#define IP_MSFILTER_SIZE(numsrc) \ -+ (sizeof(struct ip_msfilter) - sizeof(struct in_addr) \ -+ + (numsrc) * sizeof(struct in_addr)) -+ -+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE) -+struct group_req { -+ uint32_t gr_interface; -+ struct sockaddr_storage gr_group; -+}; -+ -+struct group_source_req { -+ uint32_t gsr_interface; -+ struct sockaddr_storage gsr_group; -+ struct sockaddr_storage gsr_source; -+}; -+ -+struct group_filter { -+ uint32_t gf_interface; -+ struct sockaddr_storage gf_group; -+ uint32_t gf_fmode; -+ uint32_t gf_numsrc; -+ struct sockaddr_storage gf_slist[1]; -+}; -+#define GROUP_FILTER_SIZE(numsrc) \ -+ (sizeof(struct group_filter) - sizeof(struct sockaddr_storage) \ -+ + (numsrc) * sizeof(struct sockaddr_storage)) -+#endif -+ - struct in_pktinfo - { - int ipi_ifindex; -diff --git a/include/netinet/tcp.h b/include/netinet/tcp.h -index 8266f21..5212ef7 100644 ---- a/include/netinet/tcp.h -+++ b/include/netinet/tcp.h -@@ -26,6 +26,19 @@ - #define TCP_REPAIR_OPTIONS 22 - #define TCP_FASTOPEN 23 - #define TCP_TIMESTAMP 24 -+#define TCP_NOTSENT_LOWAT 25 -+ -+#define TCP_ESTABLISHED 1 -+#define TCP_SYN_SENT 2 -+#define TCP_SYN_RECV 3 -+#define TCP_FIN_WAIT1 4 -+#define TCP_FIN_WAIT2 5 -+#define TCP_TIME_WAIT 6 -+#define TCP_CLOSE 7 -+#define TCP_CLOSE_WAIT 8 -+#define TCP_LAST_ACK 9 -+#define TCP_LISTEN 10 -+#define TCP_CLOSING 11 - - #if defined(_GNU_SOURCE) || defined(_BSD_SOURCE) - #define SOL_TCP 6 -diff --git a/include/paths.h b/include/paths.h -index 2284870..67de6b3 100644 ---- a/include/paths.h -+++ b/include/paths.h -@@ -21,7 +21,6 @@ - #define _PATH_UTMP "/dev/null/utmp" - #define _PATH_VI "/usr/bin/vi" - #define _PATH_WTMP "/dev/null/wtmp" --#define _PATH_LASTLOG "/var/log/lastlog" - - #define _PATH_DEV "/dev/" - #define _PATH_TMP "/tmp/" -diff --git a/include/resolv.h b/include/resolv.h -index 259e4bc..e12cb3c 100644 ---- a/include/resolv.h -+++ b/include/resolv.h -@@ -125,15 +125,13 @@ struct res_sym { - struct __res_state *__res_state(void); - #define _res (*__res_state()) - --struct rrec; -- - int res_init(void); - int res_query(const char *, int, int, unsigned char *, int); - int res_querydomain(const char *, const char *, int, int, unsigned char *, int); - int res_search(const char *, int, int, unsigned char *, int); --int res_mkquery(int, const char *, int, int, char *, int, struct rrec *, char *, int); --int res_send(const char *, int, char *, int); --int dn_comp(unsigned char *, unsigned char *, int, unsigned char **, unsigned char *, unsigned char **); -+int res_mkquery(int, const char *, int, int, const unsigned char *, int, const unsigned char*, unsigned char *, int); -+int res_send(const unsigned char *, int, unsigned char *, int); -+int dn_comp(const char *, unsigned char *, int, unsigned char **, unsigned char **); - int dn_expand(const unsigned char *, const unsigned char *, const unsigned char *, char *, int); - int dn_skipname(const unsigned char *, const unsigned char *); - -diff --git a/include/search.h b/include/search.h -index ebfe08a..27f6107 100644 ---- a/include/search.h -+++ b/include/search.h -@@ -13,7 +13,7 @@ extern "C" { - typedef enum { FIND, ENTER } ACTION; - typedef enum { preorder, postorder, endorder, leaf } VISIT; - --typedef struct { -+typedef struct entry { - char *key; - void *data; - } ENTRY; -diff --git a/include/signal.h b/include/signal.h -index e65a806..6f10a118 100644 ---- a/include/signal.h -+++ b/include/signal.h -@@ -218,11 +218,8 @@ void (*sigset(int, void (*)(int)))(int); - #define SIGSTKSZ 8192 - #endif - --#if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) --#define NSIG _NSIG --#endif -- - #if defined(_BSD_SOURCE) || defined(_GNU_SOURCE) -+#define NSIG _NSIG - typedef void (*sig_t)(int); - #endif - -diff --git a/include/stddef.h b/include/stddef.h -index 9d52248..0a32919 100644 ---- a/include/stddef.h -+++ b/include/stddef.h -@@ -1,7 +1,11 @@ - #ifndef _STDDEF_H - #define _STDDEF_H - -+#ifdef __cplusplus - #define NULL 0L -+#else -+#define NULL ((void*)0) -+#endif - - #define __NEED_ptrdiff_t - #define __NEED_size_t -diff --git a/include/stdio.h b/include/stdio.h -index cd60bb5..884d2e6 100644 ---- a/include/stdio.h -+++ b/include/stdio.h -@@ -21,7 +21,11 @@ extern "C" { - - #include <bits/alltypes.h> - -+#ifdef __cplusplus - #define NULL 0L -+#else -+#define NULL ((void*)0) -+#endif - - #undef EOF - #define EOF (-1) -diff --git a/include/stdlib.h b/include/stdlib.h -index bca1fb4..1e67b89 100644 ---- a/include/stdlib.h -+++ b/include/stdlib.h -@@ -7,7 +7,11 @@ extern "C" { - - #include <features.h> - -+#ifdef __cplusplus - #define NULL 0L -+#else -+#define NULL ((void*)0) -+#endif - - #define __NEED_size_t - #define __NEED_wchar_t -@@ -139,6 +143,7 @@ int mkstemps (char *, int); - int mkostemps (char *, int, int); - void *valloc (size_t); - void *memalign(size_t, size_t); -+int getloadavg(double *, int); - #define WCOREDUMP(s) ((s) & 0x80) - #define WIFCONTINUED(s) ((s) == 0xffff) - #endif -diff --git a/include/string.h b/include/string.h -index d441233..ff9badb 100644 ---- a/include/string.h -+++ b/include/string.h -@@ -7,7 +7,11 @@ extern "C" { - - #include <features.h> - -+#ifdef __cplusplus - #define NULL 0L -+#else -+#define NULL ((void*)0) -+#endif - - #define __NEED_size_t - #if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \ -diff --git a/include/sys/mtio.h b/include/sys/mtio.h -index dc8e5f5..f16a529 100644 ---- a/include/sys/mtio.h -+++ b/include/sys/mtio.h -@@ -102,7 +102,7 @@ struct mt_tape_info { - {MT_ISEVEREX_FT40A, "Everex FT40A, QIC-40"}, \ - {MT_ISSCSI1, "Generic SCSI-1 tape"}, \ - {MT_ISSCSI2, "Generic SCSI-2 tape"}, \ -- {0, NULL} \ -+ {0, 0} \ - } - - struct mtpos { -diff --git a/include/sys/socket.h b/include/sys/socket.h -index 9fd2025..82edd6f 100644 ---- a/include/sys/socket.h -+++ b/include/sys/socket.h -@@ -19,12 +19,14 @@ extern "C" { - - #include <bits/socket.h> - -+#ifdef _GNU_SOURCE - struct ucred - { - pid_t pid; - uid_t uid; - gid_t gid; - }; -+#endif - - struct linger - { -@@ -33,7 +35,7 @@ struct linger - }; - - #define SHUT_RD 0 --#define SHUT_WD 1 -+#define SHUT_WR 1 - #define SHUT_RDWR 2 - - #ifndef SOCK_STREAM -@@ -225,7 +227,7 @@ struct linger - #define MSG_EOR 0x0080 - #define MSG_WAITALL 0x0100 - #define MSG_FIN 0x0200 --#define MSD_SYN 0x0400 -+#define MSG_SYN 0x0400 - #define MSG_CONFIRM 0x0800 - #define MSG_RST 0x1000 - #define MSG_ERRQUEUE 0x2000 -@@ -290,10 +292,6 @@ int setsockopt (int, int, int, const void *, socklen_t); - - int sockatmark (int); - --#define SHUT_RD 0 --#define SHUT_WR 1 --#define SHUT_RDWR 2 -- - #ifdef __cplusplus - } - #endif -diff --git a/include/sys/time.h b/include/sys/time.h -index 3ce824e..b6787c3 100644 ---- a/include/sys/time.h -+++ b/include/sys/time.h -@@ -43,10 +43,10 @@ int adjtime (const struct timeval *, struct timeval *); - #define timerclear(t) ((t)->tv_sec = (t)->tv_usec = 0) - #define timercmp(s,t,op) ((s)->tv_sec == (t)->tv_sec ? \ - (s)->tv_usec op (t)->tv_usec : (s)->tv_sec op (t)->tv_sec) --#define timeradd(s,t,a) ( (a)->tv_sec = (s)->tv_sec + (t)->tv_sec, \ -+#define timeradd(s,t,a) (void) ( (a)->tv_sec = (s)->tv_sec + (t)->tv_sec, \ - ((a)->tv_usec = (s)->tv_usec + (t)->tv_usec) >= 1000000 && \ - ((a)->tv_usec -= 1000000, (a)->tv_sec++) ) --#define timersub(s,t,a) ( (a)->tv_sec = (s)->tv_sec - (t)->tv_sec, \ -+#define timersub(s,t,a) (void) ( (a)->tv_sec = (s)->tv_sec - (t)->tv_sec, \ - ((a)->tv_usec = (s)->tv_usec - (t)->tv_usec) < 0 && \ - ((a)->tv_usec += 1000000, (a)->tv_sec--) ) - #endif -diff --git a/include/sys/timeb.h b/include/sys/timeb.h -new file mode 100644 -index 0000000..108c1f5 ---- /dev/null -+++ b/include/sys/timeb.h -@@ -0,0 +1,22 @@ -+#ifndef _SYS_TIMEB_H -+#define _SYS_TIMEB_H -+#ifdef __cplusplus -+extern "C" { -+#endif -+ -+#define __NEED_time_t -+ -+#include <bits/alltypes.h> -+ -+struct timeb { -+ time_t time; -+ unsigned short millitm; -+ short timezone, dstflag; -+}; -+ -+int ftime(struct timeb *); -+ -+#ifdef __cplusplus -+} -+#endif -+#endif -diff --git a/include/sys/wait.h b/include/sys/wait.h -index a7ad7cd..c794f5d 100644 ---- a/include/sys/wait.h -+++ b/include/sys/wait.h -@@ -6,8 +6,6 @@ extern "C" { - - #include <features.h> - --#include <signal.h> -- - #define __NEED_pid_t - #define __NEED_id_t - #include <bits/alltypes.h> -@@ -19,9 +17,15 @@ typedef enum { - } idtype_t; - - pid_t wait (int *); --int waitid (idtype_t, id_t, siginfo_t *, int); - pid_t waitpid (pid_t, int *, int ); - -+#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \ -+ || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) \ -+ || defined(_BSD_SOURCE) -+#include <signal.h> -+int waitid (idtype_t, id_t, siginfo_t *, int); -+#endif -+ - #if defined(_GNU_SOURCE) || defined(_BSD_SOURCE) - #include <sys/resource.h> - pid_t wait3 (int *, int, struct rusage *); -diff --git a/include/syslog.h b/include/syslog.h -index a9468d4..f7f545f 100644 ---- a/include/syslog.h -+++ b/include/syslog.h -@@ -82,7 +82,7 @@ typedef struct { - { "emerg", LOG_EMERG }, { "err", LOG_ERR }, { "error", LOG_ERR }, \ - { "info", LOG_INFO }, { "none", INTERNAL_NOPRI }, \ - { "notice", LOG_NOTICE }, { "panic", LOG_EMERG }, \ -- { "warn", LOG_WARNING }, { "warning", LOG_WARNING }, { NULL, -1 } }) -+ { "warn", LOG_WARNING }, { "warning", LOG_WARNING }, { 0, -1 } }) - #define facilitynames ((CODE *)(const struct __CODE []){ \ - { "auth", LOG_AUTH }, { "authpriv", LOG_AUTHPRIV }, \ - { "cron", LOG_CRON }, { "daemon", LOG_DAEMON }, { "ftp", LOG_FTP }, \ -@@ -93,7 +93,7 @@ typedef struct { - { "local0", LOG_LOCAL0 }, { "local1", LOG_LOCAL1 }, \ - { "local2", LOG_LOCAL2 }, { "local3", LOG_LOCAL3 }, \ - { "local4", LOG_LOCAL4 }, { "local5", LOG_LOCAL5 }, \ -- { "local6", LOG_LOCAL6 }, { "local7", LOG_LOCAL7 }, { NULL, -1 } }) -+ { "local6", LOG_LOCAL6 }, { "local7", LOG_LOCAL7 }, { 0, -1 } }) - #endif - #endif - -diff --git a/include/time.h b/include/time.h -index 6b2a069..7057409 100644 ---- a/include/time.h -+++ b/include/time.h -@@ -7,7 +7,12 @@ extern "C" { - - #include <features.h> - -+#ifdef __cplusplus - #define NULL 0L -+#else -+#define NULL ((void*)0) -+#endif -+ - - #define __NEED_size_t - #define __NEED_time_t -@@ -82,8 +87,8 @@ struct itimerspec - #define CLOCK_PROCESS_CPUTIME_ID 2 - #define CLOCK_THREAD_CPUTIME_ID 3 - #define CLOCK_MONOTONIC_RAW 4 --#define CLOCK_REALTIME_COURSE 5 --#define CLOCK_MONOTONIC_COURSE 6 -+#define CLOCK_REALTIME_COARSE 5 -+#define CLOCK_MONOTONIC_COARSE 6 - #define CLOCK_BOOTTIME 7 - #define CLOCK_REALTIME_ALARM 8 - #define CLOCK_BOOTTIME_ALARM 9 -diff --git a/include/unistd.h b/include/unistd.h -index a00a9c4..bf10a6d 100644 ---- a/include/unistd.h -+++ b/include/unistd.h -@@ -15,7 +15,11 @@ extern "C" { - #define SEEK_CUR 1 - #define SEEK_END 2 - -+#ifdef __cplusplus - #define NULL 0L -+#else -+#define NULL ((void*)0) -+#endif - - #define __NEED_size_t - #define __NEED_ssize_t -@@ -31,6 +35,7 @@ extern "C" { - int pipe(int [2]); - int pipe2(int [2], int); - int close(int); -+int posix_close(int, int); - int dup(int); - int dup2(int, int); - int dup3(int, int, int); -@@ -196,6 +201,8 @@ int eaccess(const char *, int); - #define off64_t off_t - #endif - -+#define POSIX_CLOSE_RESTART 0 -+ - #define _XOPEN_VERSION 700 - #define _XOPEN_UNIX 1 - #define _XOPEN_ENH_I18N 1 -diff --git a/include/wchar.h b/include/wchar.h -index fd5aac5..9fd967c 100644 ---- a/include/wchar.h -+++ b/include/wchar.h -@@ -33,7 +33,11 @@ extern "C" { - #define WCHAR_MIN (-1-0x7fffffff+L'\0') - #endif - -+#ifdef __cplusplus - #define NULL 0L -+#else -+#define NULL ((void*)0) -+#endif - - #undef WEOF - #define WEOF 0xffffffffU -diff --git a/src/ctype/__ctype_b_loc.c b/src/ctype/__ctype_b_loc.c -index 6e93dc0..f43795e 100644 ---- a/src/ctype/__ctype_b_loc.c -+++ b/src/ctype/__ctype_b_loc.c -@@ -1,4 +1,3 @@ --#include <ctype.h> - #include <endian.h> - - #if __BYTE_ORDER == __BIG_ENDIAN -diff --git a/src/ctype/__ctype_get_mb_cur_max.c b/src/ctype/__ctype_get_mb_cur_max.c -index 42e4ee7..d235f4d 100644 ---- a/src/ctype/__ctype_get_mb_cur_max.c -+++ b/src/ctype/__ctype_get_mb_cur_max.c -@@ -1,4 +1,4 @@ --#include <stdlib.h> -+#include <stddef.h> - - size_t __ctype_get_mb_cur_max() - { -diff --git a/src/ctype/__ctype_tolower_loc.c b/src/ctype/__ctype_tolower_loc.c -index 62ce69a..efb9910 100644 ---- a/src/ctype/__ctype_tolower_loc.c -+++ b/src/ctype/__ctype_tolower_loc.c -@@ -1,5 +1,4 @@ --#include <ctype.h> --#include <inttypes.h> -+#include <stdint.h> - - static const int32_t table[] = { - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -diff --git a/src/ctype/__ctype_toupper_loc.c b/src/ctype/__ctype_toupper_loc.c -index 1556164..ffaef0e 100644 ---- a/src/ctype/__ctype_toupper_loc.c -+++ b/src/ctype/__ctype_toupper_loc.c -@@ -1,5 +1,4 @@ --#include <ctype.h> --#include <inttypes.h> -+#include <stdint.h> - - static const int32_t table[] = { - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -diff --git a/src/ctype/iswspace.c b/src/ctype/iswspace.c -index 99d517e..b0c0ae1 100644 ---- a/src/ctype/iswspace.c -+++ b/src/ctype/iswspace.c -@@ -14,6 +14,5 @@ int iswspace(wint_t wc) - 0x2006, 0x2008, 0x2009, 0x200a, - 0x2028, 0x2029, 0x205f, 0x3000, 0 - }; -- if (wcschr(spaces, wc)) return 1; -- return 0; -+ return wc && wcschr(spaces, wc); - } -diff --git a/src/dirent/fdopendir.c b/src/dirent/fdopendir.c -index c684a86..c377271 100644 ---- a/src/dirent/fdopendir.c -+++ b/src/dirent/fdopendir.c -@@ -3,8 +3,6 @@ - #include <sys/stat.h> - #include <errno.h> - #include <stdlib.h> --#include <unistd.h> --#include <limits.h> - #include "__dirent.h" - - DIR *fdopendir(int fd) -diff --git a/src/dirent/opendir.c b/src/dirent/opendir.c -index d33d892..5cb84e3 100644 ---- a/src/dirent/opendir.c -+++ b/src/dirent/opendir.c -@@ -1,11 +1,7 @@ - #define _GNU_SOURCE - #include <dirent.h> - #include <fcntl.h> --#include <sys/stat.h> --#include <errno.h> - #include <stdlib.h> --#include <unistd.h> --#include <limits.h> - #include "__dirent.h" - #include "syscall.h" - -diff --git a/src/dirent/readdir.c b/src/dirent/readdir.c -index 2d27d29..98ec029 100644 ---- a/src/dirent/readdir.c -+++ b/src/dirent/readdir.c -@@ -1,11 +1,5 @@ - #include <dirent.h> --#include <fcntl.h> --#include <sys/stat.h> --#include <errno.h> --#include <stdlib.h> --#include <limits.h> - #include "__dirent.h" --#include "syscall.h" - #include "libc.h" - - int __getdents(int, struct dirent *, size_t); -diff --git a/src/dirent/readdir_r.c b/src/dirent/readdir_r.c -index 639d49a..daa6c6e 100644 ---- a/src/dirent/readdir_r.c -+++ b/src/dirent/readdir_r.c -@@ -1,6 +1,5 @@ - #include <dirent.h> - #include <errno.h> --#include <stdlib.h> - #include <string.h> - #include "__dirent.h" - #include "libc.h" -diff --git a/src/dirent/scandir.c b/src/dirent/scandir.c -index a85cfac..3af2b50 100644 ---- a/src/dirent/scandir.c -+++ b/src/dirent/scandir.c -@@ -1,10 +1,10 @@ - #include <dirent.h> - #include <string.h> - #include <stdlib.h> --#include <inttypes.h> -+#include <stdint.h> - #include <errno.h> - #include <stddef.h> --#include <libc.h> -+#include "libc.h" - - int scandir(const char *path, struct dirent ***res, - int (*sel)(const struct dirent *), -diff --git a/src/env/__init_security.c b/src/env/__init_security.c -index 91b9b10..6204c5e 100644 ---- a/src/env/__init_security.c -+++ b/src/env/__init_security.c -@@ -1,4 +1,3 @@ --#include <stddef.h> - #include <elf.h> - #include <poll.h> - #include <fcntl.h> -diff --git a/src/env/__stack_chk_fail.c b/src/env/__stack_chk_fail.c -index 031a1ed..daa1b07 100644 ---- a/src/env/__stack_chk_fail.c -+++ b/src/env/__stack_chk_fail.c -@@ -1,6 +1,5 @@ - #include <string.h> --#include <inttypes.h> --#include <elf.h> -+#include <stdint.h> - #include "pthread_impl.h" - #include "atomic.h" - -diff --git a/src/env/clearenv.c b/src/env/clearenv.c -index a2475ce..62d5095 100644 ---- a/src/env/clearenv.c -+++ b/src/env/clearenv.c -@@ -1,3 +1,4 @@ -+#define _GNU_SOURCE - #include <stdlib.h> - - extern char **__environ; -diff --git a/src/env/putenv.c b/src/env/putenv.c -index d141db1..4042869 100644 ---- a/src/env/putenv.c -+++ b/src/env/putenv.c -@@ -1,7 +1,5 @@ - #include <stdlib.h> - #include <string.h> --#include <errno.h> --#include <stdio.h> - - extern char **__environ; - char **__env_map; -diff --git a/src/env/setenv.c b/src/env/setenv.c -index c2c2544..76e8ee1 100644 ---- a/src/env/setenv.c -+++ b/src/env/setenv.c -@@ -18,14 +18,13 @@ int setenv(const char *var, const char *value, int overwrite) - l1 = strlen(var); - l2 = strlen(value); - s = malloc(l1+l2+2); -- memcpy(s, var, l1); -- s[l1] = '='; -- memcpy(s+l1+1, value, l2); -- s[l1+l2+1] = 0; -- if (__putenv(s, 1)) { -- free(s); -- errno = ENOMEM; -- return -1; -+ if (s) { -+ memcpy(s, var, l1); -+ s[l1] = '='; -+ memcpy(s+l1+1, value, l2); -+ s[l1+l2+1] = 0; -+ if (!__putenv(s, 1)) return 0; - } -- return 0; -+ free(s); -+ return -1; - } -diff --git a/src/env/unsetenv.c b/src/env/unsetenv.c -index 7493d97..3569335 100644 ---- a/src/env/unsetenv.c -+++ b/src/env/unsetenv.c -@@ -1,4 +1,3 @@ --#include <stdio.h> - #include <stdlib.h> - #include <string.h> - #include <errno.h> -diff --git a/src/exit/atexit.c b/src/exit/atexit.c -index c31f3dc..89ff4ff 100644 ---- a/src/exit/atexit.c -+++ b/src/exit/atexit.c -@@ -1,7 +1,5 @@ --#include <stddef.h> - #include <stdlib.h> - #include <stdint.h> --#include <limits.h> - #include "libc.h" - - /* Ensure that at least 32 atexit handlers can be registered without malloc */ -diff --git a/src/exit/exit.c b/src/exit/exit.c -index f259c98..353f50b 100644 ---- a/src/exit/exit.c -+++ b/src/exit/exit.c -@@ -1,6 +1,5 @@ - #include <stdlib.h> --#include <unistd.h> --#include <stdio.h> -+#include <stdint.h> - #include "libc.h" - #include "atomic.h" - #include "syscall.h" -diff --git a/src/fcntl/fcntl.c b/src/fcntl/fcntl.c -index 390ef75..4c34ba0 100644 ---- a/src/fcntl/fcntl.c -+++ b/src/fcntl/fcntl.c -@@ -1,6 +1,5 @@ - #define _GNU_SOURCE - #include <fcntl.h> --#include <unistd.h> - #include <stdarg.h> - #include <errno.h> - #include "syscall.h" -diff --git a/src/fcntl/open.c b/src/fcntl/open.c -index 31d6744..be44208 100644 ---- a/src/fcntl/open.c -+++ b/src/fcntl/open.c -@@ -1,5 +1,4 @@ - #include <fcntl.h> --#include <unistd.h> - #include <stdarg.h> - #include "syscall.h" - #include "libc.h" -diff --git a/src/fcntl/openat.c b/src/fcntl/openat.c -index bdecb8c..634c4bf 100644 ---- a/src/fcntl/openat.c -+++ b/src/fcntl/openat.c -@@ -1,5 +1,4 @@ - #include <fcntl.h> --#include <unistd.h> - #include <stdarg.h> - #include "syscall.h" - #include "libc.h" -diff --git a/src/fenv/i386/fenv.s b/src/fenv/i386/fenv.s -index eaeb6be..f6036d6 100644 ---- a/src/fenv/i386/fenv.s -+++ b/src/fenv/i386/fenv.s -@@ -75,7 +75,7 @@ __fesetround: - 1: addl $__hwcap-1b,(%esp) - pop %edx - testl $0x02000000,(%edx) -- jmp 1f -+ jz 1f - stmxcsr (%esp) - shl $3,%ch - andb $0x9f,1(%esp) -diff --git a/src/internal/syscall_ret.c b/src/internal/syscall_ret.c -index e4a1bdb..d99f4a5 100644 ---- a/src/internal/syscall_ret.c -+++ b/src/internal/syscall_ret.c -@@ -1,5 +1,4 @@ - #include <errno.h> --#include <unistd.h> - - long __syscall_ret(unsigned long r) - { -diff --git a/src/internal/version.c b/src/internal/version.c -new file mode 100644 -index 0000000..16554ba ---- /dev/null -+++ b/src/internal/version.c -@@ -0,0 +1,12 @@ -+#ifdef SHARED -+ -+#include "version.h" -+ -+static const char version[] = VERSION; -+ -+const char *__libc_get_version() -+{ -+ return version; -+} -+ -+#endif -diff --git a/src/ipc/ipc.h b/src/ipc/ipc.h -index 5487582..30ab939 100644 ---- a/src/ipc/ipc.h -+++ b/src/ipc/ipc.h -@@ -1,6 +1,7 @@ - #define IPCOP_semop 1 - #define IPCOP_semget 2 - #define IPCOP_semctl 3 -+#define IPCOP_semtimedop 4 - #define IPCOP_msgsnd 11 - #define IPCOP_msgrcv 12 - #define IPCOP_msgget 13 -diff --git a/src/ipc/semtimedop.c b/src/ipc/semtimedop.c -new file mode 100644 -index 0000000..b0c4cf9 ---- /dev/null -+++ b/src/ipc/semtimedop.c -@@ -0,0 +1,13 @@ -+#define _GNU_SOURCE -+#include <sys/sem.h> -+#include "syscall.h" -+#include "ipc.h" -+ -+int semtimedop(int id, struct sembuf *buf, size_t n, const struct timespec *ts) -+{ -+#ifdef SYS_semtimedop -+ return syscall(SYS_semtimedop, id, buf, n, ts); -+#else -+ return syscall(SYS_ipc, IPCOP_semtimedop, id, n, 0, buf, ts); -+#endif -+} -diff --git a/src/ldso/dlinfo.c b/src/ldso/dlinfo.c -index 4748eaf..63d276d 100644 ---- a/src/ldso/dlinfo.c -+++ b/src/ldso/dlinfo.c -@@ -1,3 +1,4 @@ -+#define _GNU_SOURCE - #include <dlfcn.h> - - int __dlinfo(void *, int, void *); -diff --git a/src/ldso/dynlink.c b/src/ldso/dynlink.c -index a525b3d..27d92f2 100644 ---- a/src/ldso/dynlink.c -+++ b/src/ldso/dynlink.c -@@ -7,12 +7,9 @@ - #include <elf.h> - #include <sys/mman.h> - #include <limits.h> --#include <stdint.h> - #include <fcntl.h> - #include <sys/stat.h> - #include <errno.h> --#include <limits.h> --#include <elf.h> - #include <link.h> - #include <setjmp.h> - #include <pthread.h> -@@ -96,6 +93,8 @@ void __init_ssp(size_t *); - void *__install_initial_tls(void *); - void __init_libc(char **, char *); - -+const char *__libc_get_version(void); -+ - static struct dso *head, *tail, *ldso, *fini_head; - static char *env_path, *sys_path; - static unsigned long long gencnt; -@@ -1043,8 +1042,11 @@ void *__dynlink(int argc, char **argv) - *argv++ = (void *)-1; - if (argv[0] && !strcmp(argv[0], "--")) *argv++ = (void *)-1; - if (!argv[0]) { -- dprintf(2, "musl libc/dynamic program loader\n"); -- dprintf(2, "usage: %s pathname%s\n", ldname, -+ dprintf(2, "musl libc\n" -+ "Version %s\n" -+ "Dynamic Program Loader\n" -+ "Usage: %s [--] pathname%s\n", -+ __libc_get_version(), ldname, - ldd_mode ? "" : " [args]"); - _exit(1); - } -@@ -1354,7 +1356,7 @@ int __dladdr(void *addr, Dl_info *info) - uint32_t *hashval; - buckets = p->ghashtab + 4 + (p->ghashtab[2]*sizeof(size_t)/4); - sym += p->ghashtab[1]; -- for (i = 0; i < p->ghashtab[0]; i++) { -+ for (i = nsym = 0; i < p->ghashtab[0]; i++) { - if (buckets[i] > nsym) - nsym = buckets[i]; - } -diff --git a/src/ldso/microblaze/start.s b/src/ldso/microblaze/start.s -index 5ffbcba..4e0a0e5 100644 ---- a/src/ldso/microblaze/start.s -+++ b/src/ldso/microblaze/start.s -@@ -9,11 +9,12 @@ _start: - addi r7, r7, _GLOBAL_OFFSET_TABLE_+8 - addi r7, r7, _DYNAMIC@GOTOFF - brlid r15, __reloc_self@PLT -- nop -+ addik r1, r1, -16 - -- lwi r5, r1, 0 -+ lwi r5, r1, 16 - brlid r15, __dynlink@PLT -- addi r6, r1, 4 -+ addi r6, r1, 20 -+ addik r1, r1, 16 - - lwi r4, r1, 0 - 1: lwi r5, r1, 4 -diff --git a/src/legacy/euidaccess.c b/src/legacy/euidaccess.c -index 47b464d..7307251 100644 ---- a/src/legacy/euidaccess.c -+++ b/src/legacy/euidaccess.c -@@ -1,3 +1,4 @@ -+#define _GNU_SOURCE - #include <unistd.h> - #include <fcntl.h> - #include "libc.h" -diff --git a/src/legacy/futimes.c b/src/legacy/futimes.c -index f8fd1cd..d81d83a 100644 ---- a/src/legacy/futimes.c -+++ b/src/legacy/futimes.c -@@ -1,6 +1,6 @@ -+#define _GNU_SOURCE - #include <sys/stat.h> - #include <sys/time.h> --#include <fcntl.h> - - int futimes(int fd, const struct timeval tv[2]) - { -diff --git a/src/legacy/getdtablesize.c b/src/legacy/getdtablesize.c -index 623a6af..682da6d 100644 ---- a/src/legacy/getdtablesize.c -+++ b/src/legacy/getdtablesize.c -@@ -1,3 +1,5 @@ -+#define _GNU_SOURCE -+#include <unistd.h> - #include <limits.h> - #include <sys/resource.h> - -diff --git a/src/legacy/getloadavg.c b/src/legacy/getloadavg.c -new file mode 100644 -index 0000000..43a8c9e ---- /dev/null -+++ b/src/legacy/getloadavg.c -@@ -0,0 +1,18 @@ -+#define _GNU_SOURCE -+#include <stdlib.h> -+#include <stdio.h> -+#include <string.h> -+ -+int getloadavg(double *a, int n) -+{ -+ int i; -+ double b[3]; -+ FILE *f = fopen("/proc/loadavg", "rbe"); -+ if (!f) return -1; -+ i = fscanf(f, "%lf %lf %lf", b, b+1, b+2); -+ fclose(f); -+ if (n > i) n = i; -+ if (n < 0) return -1; -+ memcpy(a, b, n * sizeof *a); -+ return n; -+} -diff --git a/src/legacy/getpagesize.c b/src/legacy/getpagesize.c -index a47995c..0fc29ff 100644 ---- a/src/legacy/getpagesize.c -+++ b/src/legacy/getpagesize.c -@@ -1,3 +1,4 @@ -+#define _GNU_SOURCE - #include <unistd.h> - #include "libc.h" - -diff --git a/src/legacy/getpass.c b/src/legacy/getpass.c -index d439a2a..3565d95 100644 ---- a/src/legacy/getpass.c -+++ b/src/legacy/getpass.c -@@ -1,5 +1,5 @@ -+#define _GNU_SOURCE - #include <stdio.h> --#include <string.h> - #include <termios.h> - #include <unistd.h> - #include <fcntl.h> -diff --git a/src/legacy/getusershell.c b/src/legacy/getusershell.c -index f31f404..5fecdec 100644 ---- a/src/legacy/getusershell.c -+++ b/src/legacy/getusershell.c -@@ -1,7 +1,6 @@ - #define _GNU_SOURCE - #include <stdio.h> --#include <string.h> --#include <stdlib.h> -+#include <unistd.h> - - static const char defshells[] = "/bin/sh\n/bin/csh\n"; - -diff --git a/src/legacy/lutimes.c b/src/legacy/lutimes.c -index 13dfe4e..2e5502d 100644 ---- a/src/legacy/lutimes.c -+++ b/src/legacy/lutimes.c -@@ -1,3 +1,4 @@ -+#define _GNU_SOURCE - #include <sys/stat.h> - #include <sys/time.h> - #include <fcntl.h> -diff --git a/src/linux/chroot.c b/src/linux/chroot.c -index 82b4fe7..0e69f14 100644 ---- a/src/linux/chroot.c -+++ b/src/linux/chroot.c -@@ -1,3 +1,4 @@ -+#define _GNU_SOURCE - #include <unistd.h> - #include "syscall.h" - -diff --git a/src/linux/clock_adjtime.c b/src/linux/clock_adjtime.c -index 1fc9bef..056ad6d 100644 ---- a/src/linux/clock_adjtime.c -+++ b/src/linux/clock_adjtime.c -@@ -1,5 +1,3 @@ --#define _GNU_SOURCE --#include <time.h> - #include <sys/timex.h> - #include "syscall.h" - -diff --git a/src/linux/klogctl.c b/src/linux/klogctl.c -index 209ae74..8102ee6 100644 ---- a/src/linux/klogctl.c -+++ b/src/linux/klogctl.c -@@ -1,3 +1,4 @@ -+#include <sys/klog.h> - #include "syscall.h" - - int klogctl (int type, char *buf, int len) -diff --git a/src/linux/personality.c b/src/linux/personality.c -index 06851f5..e00cf79 100644 ---- a/src/linux/personality.c -+++ b/src/linux/personality.c -@@ -1,3 +1,4 @@ -+#include <sys/personality.h> - #include "syscall.h" - #ifdef SYS_personality - int personality(unsigned long persona) -diff --git a/src/linux/prlimit.c b/src/linux/prlimit.c -index 1215248..d1639cc 100644 ---- a/src/linux/prlimit.c -+++ b/src/linux/prlimit.c -@@ -1,4 +1,4 @@ --#include <unistd.h> -+#define _GNU_SOURCE - #include <sys/resource.h> - #include "syscall.h" - #include "libc.h" -@@ -8,4 +8,5 @@ int prlimit(pid_t pid, int resource, const struct rlimit *new_limit, struct rlim - return syscall(SYS_prlimit64, pid, resource, new_limit, old_limit); - } - -+#undef prlimit64 - LFS64(prlimit); -diff --git a/src/linux/sendfile.c b/src/linux/sendfile.c -index 818b19d..d63f419 100644 ---- a/src/linux/sendfile.c -+++ b/src/linux/sendfile.c -@@ -1,4 +1,4 @@ --#include <unistd.h> -+#include <sys/sendfile.h> - #include "syscall.h" - #include "libc.h" - -diff --git a/src/linux/setfsgid.c b/src/linux/setfsgid.c -index a7ed9e9..ad80422 100644 ---- a/src/linux/setfsgid.c -+++ b/src/linux/setfsgid.c -@@ -1,4 +1,4 @@ --#include <unistd.h> -+#include <sys/fsuid.h> - #include "syscall.h" - #include "libc.h" - -diff --git a/src/linux/setfsuid.c b/src/linux/setfsuid.c -index 1509e0a..8635873 100644 ---- a/src/linux/setfsuid.c -+++ b/src/linux/setfsuid.c -@@ -1,4 +1,4 @@ --#include <unistd.h> -+#include <sys/fsuid.h> - #include "syscall.h" - #include "libc.h" - -diff --git a/src/linux/setgroups.c b/src/linux/setgroups.c -index 9758940..1248fdb 100644 ---- a/src/linux/setgroups.c -+++ b/src/linux/setgroups.c -@@ -1,3 +1,4 @@ -+#define _GNU_SOURCE - #include <unistd.h> - #include "syscall.h" - -diff --git a/src/linux/sethostname.c b/src/linux/sethostname.c -index 79a8707..9313b32 100644 ---- a/src/linux/sethostname.c -+++ b/src/linux/sethostname.c -@@ -1,3 +1,4 @@ -+#define _GNU_SOURCE - #include <unistd.h> - #include "syscall.h" - -diff --git a/src/linux/setns.c b/src/linux/setns.c -index 7029b74..0afec81 100644 ---- a/src/linux/setns.c -+++ b/src/linux/setns.c -@@ -1,7 +1,6 @@ - #define _GNU_SOURCE - #include <sched.h> - #include "syscall.h" --#include "libc.h" - - int setns(int fd, int nstype) - { -diff --git a/src/linux/stime.c b/src/linux/stime.c -index 6a7e9e8..29a1ec6 100644 ---- a/src/linux/stime.c -+++ b/src/linux/stime.c -@@ -1,4 +1,5 @@ - #define _GNU_SOURCE -+#include <time.h> - #include <sys/time.h> - - int stime(time_t *t) -diff --git a/src/linux/sysinfo.c b/src/linux/sysinfo.c -index 2dbd0ad..7e64f33 100644 ---- a/src/linux/sysinfo.c -+++ b/src/linux/sysinfo.c -@@ -1,7 +1,6 @@ -+#include <sys/sysinfo.h> - #include "syscall.h" - --struct sysinfo; -- - int sysinfo(struct sysinfo *info) - { - return syscall(SYS_sysinfo, info); -diff --git a/src/linux/wait4.c b/src/linux/wait4.c -index b3ae75e..97f12cc 100644 ---- a/src/linux/wait4.c -+++ b/src/linux/wait4.c -@@ -1,7 +1,6 @@ - #define _GNU_SOURCE - #include <sys/wait.h> - #include <sys/resource.h> --#include <string.h> - #include "syscall.h" - - pid_t wait4(pid_t pid, int *status, int options, struct rusage *usage) -diff --git a/src/locale/intl.c b/src/locale/intl.c -index 964f7da..ad04052 100644 ---- a/src/locale/intl.c -+++ b/src/locale/intl.c -@@ -1,3 +1,4 @@ -+#include <libintl.h> - #include <stdlib.h> - #include <string.h> - #include <strings.h> -diff --git a/src/locale/localeconv.c b/src/locale/localeconv.c -index 494cbcc..cbc75d7 100644 ---- a/src/locale/localeconv.c -+++ b/src/locale/localeconv.c -@@ -1,6 +1,4 @@ - #include <locale.h> --#include <string.h> --#include <stdlib.h> - - static const struct lconv posix_lconv = { - .decimal_point = ".", -diff --git a/src/locale/strcasecmp_l.c b/src/locale/strcasecmp_l.c -index eea2f80..ca80543 100644 ---- a/src/locale/strcasecmp_l.c -+++ b/src/locale/strcasecmp_l.c -@@ -1,5 +1,4 @@ - #include <strings.h> --#include <ctype.h> - - int strcasecmp_l(const char *l, const char *r, locale_t loc) - { -diff --git a/src/locale/strfmon.c b/src/locale/strfmon.c -index f510d9a..e25db97 100644 ---- a/src/locale/strfmon.c -+++ b/src/locale/strfmon.c -@@ -3,7 +3,6 @@ - #include <stdarg.h> - #include <monetary.h> - #include <errno.h> --#include <stdarg.h> - - static ssize_t vstrfmon_l(char *s, size_t n, locale_t loc, const char *fmt, va_list ap) - { -diff --git a/src/malloc/__brk.c b/src/malloc/__brk.c -index 0b561ea..4c9119b 100644 ---- a/src/malloc/__brk.c -+++ b/src/malloc/__brk.c -@@ -3,5 +3,5 @@ - - uintptr_t __brk(uintptr_t newbrk) - { -- return syscall(SYS_brk, newbrk); -+ return __syscall(SYS_brk, newbrk); - } -diff --git a/src/malloc/calloc.c b/src/malloc/calloc.c -index 9d57456..c3dfb47 100644 ---- a/src/malloc/calloc.c -+++ b/src/malloc/calloc.c -@@ -1,6 +1,5 @@ - #include <stdlib.h> - #include <errno.h> --#include <string.h> - - void *calloc(size_t m, size_t n) - { -diff --git a/src/malloc/malloc.c b/src/malloc/malloc.c -index fb65ab5..d6ad904 100644 ---- a/src/malloc/malloc.c -+++ b/src/malloc/malloc.c -@@ -177,6 +177,7 @@ static struct chunk *expand_heap(size_t n) - return w; - fail: - unlock(mal.brk_lock); -+ errno = ENOMEM; - return 0; - } - -diff --git a/src/math/__log1p.h b/src/math/__log1p.h -deleted file mode 100644 -index 5718711..0000000 ---- a/src/math/__log1p.h -+++ /dev/null -@@ -1,94 +0,0 @@ --/* origin: FreeBSD /usr/src/lib/msun/src/k_log.h */ --/* -- * ==================================================== -- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. -- * -- * Developed at SunSoft, a Sun Microsystems, Inc. business. -- * Permission to use, copy, modify, and distribute this -- * software is freely granted, provided that this notice -- * is preserved. -- * ==================================================== -- */ --/* -- * __log1p(f): -- * Return log(1+f) - f for 1+f in ~[sqrt(2)/2, sqrt(2)]. -- * -- * The following describes the overall strategy for computing -- * logarithms in base e. The argument reduction and adding the final -- * term of the polynomial are done by the caller for increased accuracy -- * when different bases are used. -- * -- * Method : -- * 1. Argument Reduction: find k and f such that -- * x = 2^k * (1+f), -- * where sqrt(2)/2 < 1+f < sqrt(2) . -- * -- * 2. Approximation of log(1+f). -- * Let s = f/(2+f) ; based on log(1+f) = log(1+s) - log(1-s) -- * = 2s + 2/3 s**3 + 2/5 s**5 + ....., -- * = 2s + s*R -- * We use a special Reme algorithm on [0,0.1716] to generate -- * a polynomial of degree 14 to approximate R The maximum error -- * of this polynomial approximation is bounded by 2**-58.45. In -- * other words, -- * 2 4 6 8 10 12 14 -- * R(z) ~ Lg1*s +Lg2*s +Lg3*s +Lg4*s +Lg5*s +Lg6*s +Lg7*s -- * (the values of Lg1 to Lg7 are listed in the program) -- * and -- * | 2 14 | -58.45 -- * | Lg1*s +...+Lg7*s - R(z) | <= 2 -- * | | -- * Note that 2s = f - s*f = f - hfsq + s*hfsq, where hfsq = f*f/2. -- * In order to guarantee error in log below 1ulp, we compute log -- * by -- * log(1+f) = f - s*(f - R) (if f is not too large) -- * log(1+f) = f - (hfsq - s*(hfsq+R)). (better accuracy) -- * -- * 3. Finally, log(x) = k*ln2 + log(1+f). -- * = k*ln2_hi+(f-(hfsq-(s*(hfsq+R)+k*ln2_lo))) -- * Here ln2 is split into two floating point number: -- * ln2_hi + ln2_lo, -- * where n*ln2_hi is always exact for |n| < 2000. -- * -- * Special cases: -- * log(x) is NaN with signal if x < 0 (including -INF) ; -- * log(+INF) is +INF; log(0) is -INF with signal; -- * log(NaN) is that NaN with no signal. -- * -- * Accuracy: -- * according to an error analysis, the error is always less than -- * 1 ulp (unit in the last place). -- * -- * Constants: -- * The hexadecimal values are the intended ones for the following -- * constants. The decimal values may be used, provided that the -- * compiler will convert from decimal to binary accurately enough -- * to produce the hexadecimal values shown. -- */ -- --static const double --Lg1 = 6.666666666666735130e-01, /* 3FE55555 55555593 */ --Lg2 = 3.999999999940941908e-01, /* 3FD99999 9997FA04 */ --Lg3 = 2.857142874366239149e-01, /* 3FD24924 94229359 */ --Lg4 = 2.222219843214978396e-01, /* 3FCC71C5 1D8E78AF */ --Lg5 = 1.818357216161805012e-01, /* 3FC74664 96CB03DE */ --Lg6 = 1.531383769920937332e-01, /* 3FC39A09 D078C69F */ --Lg7 = 1.479819860511658591e-01; /* 3FC2F112 DF3E5244 */ -- --/* -- * We always inline __log1p(), since doing so produces a -- * substantial performance improvement (~40% on amd64). -- */ --static inline double __log1p(double f) --{ -- double_t hfsq,s,z,R,w,t1,t2; -- -- s = f/(2.0+f); -- z = s*s; -- w = z*z; -- t1= w*(Lg2+w*(Lg4+w*Lg6)); -- t2= z*(Lg1+w*(Lg3+w*(Lg5+w*Lg7))); -- R = t2+t1; -- hfsq = 0.5*f*f; -- return s*(hfsq+R); --} -diff --git a/src/math/__log1pf.h b/src/math/__log1pf.h -deleted file mode 100644 -index f2fbef2..0000000 ---- a/src/math/__log1pf.h -+++ /dev/null -@@ -1,35 +0,0 @@ --/* origin: FreeBSD /usr/src/lib/msun/src/k_logf.h */ --/* -- * ==================================================== -- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. -- * -- * Developed at SunPro, a Sun Microsystems, Inc. business. -- * Permission to use, copy, modify, and distribute this -- * software is freely granted, provided that this notice -- * is preserved. -- * ==================================================== -- */ --/* -- * See comments in __log1p.h. -- */ -- --/* |(log(1+s)-log(1-s))/s - Lg(s)| < 2**-34.24 (~[-4.95e-11, 4.97e-11]). */ --static const float --Lg1 = 0xaaaaaa.0p-24, /* 0.66666662693 */ --Lg2 = 0xccce13.0p-25, /* 0.40000972152 */ --Lg3 = 0x91e9ee.0p-25, /* 0.28498786688 */ --Lg4 = 0xf89e26.0p-26; /* 0.24279078841 */ -- --static inline float __log1pf(float f) --{ -- float_t hfsq,s,z,R,w,t1,t2; -- -- s = f/(2.0f + f); -- z = s*s; -- w = z*z; -- t1 = w*(Lg2+w*Lg4); -- t2 = z*(Lg1+w*Lg3); -- R = t2+t1; -- hfsq = 0.5f * f * f; -- return s*(hfsq+R); --} -diff --git a/src/math/__rem_pio2.c b/src/math/__rem_pio2.c -index 9305be5..5fafc4a 100644 ---- a/src/math/__rem_pio2.c -+++ b/src/math/__rem_pio2.c -@@ -29,7 +29,6 @@ - * pio2_3t: pi/2 - (pio2_1+pio2_2+pio2_3) - */ - static const double --two24 = 1.67772160000000000000e+07, /* 0x41700000, 0x00000000 */ - invpio2 = 6.36619772367581382433e-01, /* 0x3FE45F30, 0x6DC9C883 */ - pio2_1 = 1.57079632673412561417e+00, /* 0x3FF921FB, 0x54400000 */ - pio2_1t = 6.07710050650619224932e-11, /* 0x3DD0B461, 0x1A626331 */ -@@ -41,18 +40,19 @@ pio2_3t = 8.47842766036889956997e-32; /* 0x397B839A, 0x252049C1 */ - /* caller must handle the case when reduction is not needed: |x| ~<= pi/4 */ - int __rem_pio2(double x, double *y) - { -- double z,w,t,r,fn; -- double tx[3],ty[2]; -- int32_t e0,i,j,nx,n,ix,hx; -- uint32_t low; -+ union {double f; uint64_t i;} u = {x}; -+ double_t z,w,t,r; -+ double tx[3],ty[2],fn; -+ uint32_t ix; -+ int sign, n, ex, ey, i; - -- GET_HIGH_WORD(hx,x); -- ix = hx & 0x7fffffff; -+ sign = u.i>>63; -+ ix = u.i>>32 & 0x7fffffff; - if (ix <= 0x400f6a7a) { /* |x| ~<= 5pi/4 */ - if ((ix & 0xfffff) == 0x921fb) /* |x| ~= pi/2 or 2pi/2 */ - goto medium; /* cancellation -- use medium case */ - if (ix <= 0x4002d97c) { /* |x| ~<= 3pi/4 */ -- if (hx > 0) { -+ if (!sign) { - z = x - pio2_1; /* one round good to 85 bits */ - y[0] = z - pio2_1t; - y[1] = (z-y[0]) - pio2_1t; -@@ -64,7 +64,7 @@ int __rem_pio2(double x, double *y) - return -1; - } - } else { -- if (hx > 0) { -+ if (!sign) { - z = x - 2*pio2_1; - y[0] = z - 2*pio2_1t; - y[1] = (z-y[0]) - 2*pio2_1t; -@@ -81,7 +81,7 @@ int __rem_pio2(double x, double *y) - if (ix <= 0x4015fdbc) { /* |x| ~<= 7pi/4 */ - if (ix == 0x4012d97c) /* |x| ~= 3pi/2 */ - goto medium; -- if (hx > 0) { -+ if (!sign) { - z = x - 3*pio2_1; - y[0] = z - 3*pio2_1t; - y[1] = (z-y[0]) - 3*pio2_1t; -@@ -95,7 +95,7 @@ int __rem_pio2(double x, double *y) - } else { - if (ix == 0x401921fb) /* |x| ~= 4pi/2 */ - goto medium; -- if (hx > 0) { -+ if (!sign) { - z = x - 4*pio2_1; - y[0] = z - 4*pio2_1t; - y[1] = (z-y[0]) - 4*pio2_1t; -@@ -109,32 +109,26 @@ int __rem_pio2(double x, double *y) - } - } - if (ix < 0x413921fb) { /* |x| ~< 2^20*(pi/2), medium size */ -- uint32_t high; - medium: -- /* Use a specialized rint() to get fn. Assume round-to-nearest. */ -+ /* rint(x/(pi/2)), Assume round-to-nearest. */ - fn = x*invpio2 + 0x1.8p52; - fn = fn - 0x1.8p52; --// FIXME --#ifdef HAVE_EFFICIENT_IRINT -- n = irint(fn); --#else - n = (int32_t)fn; --#endif - r = x - fn*pio2_1; - w = fn*pio2_1t; /* 1st round, good to 85 bits */ -- j = ix>>20; - y[0] = r - w; -- GET_HIGH_WORD(high,y[0]); -- i = j - ((high>>20)&0x7ff); -- if (i > 16) { /* 2nd round, good to 118 bits */ -+ u.f = y[0]; -+ ey = u.i>>52 & 0x7ff; -+ ex = ix>>20; -+ if (ex - ey > 16) { /* 2nd round, good to 118 bits */ - t = r; - w = fn*pio2_2; - r = t - w; - w = fn*pio2_2t - ((t-r)-w); - y[0] = r - w; -- GET_HIGH_WORD(high,y[0]); -- i = j - ((high>>20)&0x7ff); -- if (i > 49) { /* 3rd round, good to 151 bits, covers all cases */ -+ u.f = y[0]; -+ ey = u.i>>52 & 0x7ff; -+ if (ex - ey > 49) { /* 3rd round, good to 151 bits, covers all cases */ - t = r; - w = fn*pio2_3; - r = t - w; -@@ -142,7 +136,7 @@ medium: - y[0] = r - w; - } - } -- y[1] = (r-y[0]) - w; -+ y[1] = (r - y[0]) - w; - return n; - } - /* -@@ -152,19 +146,21 @@ medium: - y[0] = y[1] = x - x; - return 0; - } -- /* set z = scalbn(|x|,ilogb(x)-23) */ -- GET_LOW_WORD(low,x); -- e0 = (ix>>20) - 1046; /* e0 = ilogb(z)-23; */ -- INSERT_WORDS(z, ix - ((int32_t)(e0<<20)), low); -- for (i=0; i<2; i++) { -- tx[i] = (double)((int32_t)(z)); -- z = (z-tx[i])*two24; -+ /* set z = scalbn(|x|,-ilogb(x)+23) */ -+ u.f = x; -+ u.i &= (uint64_t)-1>>12; -+ u.i |= (uint64_t)(0x3ff + 23)<<52; -+ z = u.f; -+ for (i=0; i < 2; i++) { -+ tx[i] = (double)(int32_t)z; -+ z = (z-tx[i])*0x1p24; - } -- tx[2] = z; -- nx = 3; -- while (tx[nx-1] == 0.0) nx--; /* skip zero term */ -- n = __rem_pio2_large(tx,ty,e0,nx,1); -- if (hx < 0) { -+ tx[i] = z; -+ /* skip zero terms, first term is non-zero */ -+ while (tx[i] == 0.0) -+ i--; -+ n = __rem_pio2_large(tx,ty,(int)(ix>>20)-(0x3ff+23),i+1,1); -+ if (sign) { - y[0] = -ty[0]; - y[1] = -ty[1]; - return -n; -diff --git a/src/math/__rem_pio2_large.c b/src/math/__rem_pio2_large.c -index bb2dc43..958f28c 100644 ---- a/src/math/__rem_pio2_large.c -+++ b/src/math/__rem_pio2_large.c -@@ -270,10 +270,6 @@ static const double PIo2[] = { - 2.16741683877804819444e-51, /* 0x3569F31D, 0x00000000 */ - }; - --static const double --two24 = 1.67772160000000000000e+07, /* 0x41700000, 0x00000000 */ --twon24 = 5.96046447753906250000e-08; /* 0x3E700000, 0x00000000 */ -- - int __rem_pio2_large(double *x, double *y, int e0, int nx, int prec) - { - int32_t jz,jx,jv,jp,jk,carry,n,iq[20],i,j,k,m,q0,ih; -@@ -304,8 +300,8 @@ int __rem_pio2_large(double *x, double *y, int e0, int nx, int prec) - recompute: - /* distill q[] into iq[] reversingly */ - for (i=0,j=jz,z=q[jz]; j>0; i++,j--) { -- fw = (double)((int32_t)(twon24* z)); -- iq[i] = (int32_t)(z-two24*fw); -+ fw = (double)(int32_t)(0x1p-24*z); -+ iq[i] = (int32_t)(z - 0x1p24*fw); - z = q[j-1]+fw; - } - -@@ -330,7 +326,7 @@ recompute: - if (carry == 0) { - if (j != 0) { - carry = 1; -- iq[i] = 0x1000000- j; -+ iq[i] = 0x1000000 - j; - } - } else - iq[i] = 0xffffff - j; -@@ -378,9 +374,9 @@ recompute: - } - } else { /* break z into 24-bit if necessary */ - z = scalbn(z,-q0); -- if (z >= two24) { -- fw = (double)((int32_t)(twon24*z)); -- iq[jz] = (int32_t)(z-two24*fw); -+ if (z >= 0x1p24) { -+ fw = (double)(int32_t)(0x1p-24*z); -+ iq[jz] = (int32_t)(z - 0x1p24*fw); - jz += 1; - q0 += 24; - iq[jz] = (int32_t)fw; -@@ -392,7 +388,7 @@ recompute: - fw = scalbn(1.0,q0); - for (i=jz; i>=0; i--) { - q[i] = fw*(double)iq[i]; -- fw *= twon24; -+ fw *= 0x1p-24; - } - - /* compute PIo2[0,...,jp]*q[jz,...,0] */ -diff --git a/src/math/__rem_pio2f.c b/src/math/__rem_pio2f.c -index 5bdeb52..838e1fc 100644 ---- a/src/math/__rem_pio2f.c -+++ b/src/math/__rem_pio2f.c -@@ -34,42 +34,32 @@ pio2_1t = 1.58932547735281966916e-08; /* 0x3E5110b4, 0x611A6263 */ - - int __rem_pio2f(float x, double *y) - { -- double w,r,fn; -- double tx[1],ty[1]; -- float z; -- int32_t e0,n,ix,hx; -+ union {float f; uint32_t i;} u = {x}; -+ double tx[1],ty[1],fn; -+ uint32_t ix; -+ int n, sign, e0; - -- GET_FLOAT_WORD(hx, x); -- ix = hx & 0x7fffffff; -+ ix = u.i & 0x7fffffff; - /* 25+53 bit pi is good enough for medium size */ - if (ix < 0x4dc90fdb) { /* |x| ~< 2^28*(pi/2), medium size */ - /* Use a specialized rint() to get fn. Assume round-to-nearest. */ - fn = x*invpio2 + 0x1.8p52; - fn = fn - 0x1.8p52; --// FIXME --#ifdef HAVE_EFFICIENT_IRINT -- n = irint(fn); --#else - n = (int32_t)fn; --#endif -- r = x - fn*pio2_1; -- w = fn*pio2_1t; -- *y = r - w; -+ *y = x - fn*pio2_1 - fn*pio2_1t; - return n; - } -- /* -- * all other (large) arguments -- */ - if(ix>=0x7f800000) { /* x is inf or NaN */ - *y = x-x; - return 0; - } -- /* set z = scalbn(|x|,ilogb(|x|)-23) */ -- e0 = (ix>>23) - 150; /* e0 = ilogb(|x|)-23; */ -- SET_FLOAT_WORD(z, ix - ((int32_t)(e0<<23))); -- tx[0] = z; -+ /* scale x into [2^23, 2^24-1] */ -+ sign = u.i>>31; -+ e0 = (ix>>23) - (0x7f+23); /* e0 = ilogb(|x|)-23, positive */ -+ u.i = ix - (e0<<23); -+ tx[0] = u.f; - n = __rem_pio2_large(tx,ty,e0,1,0); -- if (hx < 0) { -+ if (sign) { - *y = -ty[0]; - return -n; - } -diff --git a/src/math/acosh.c b/src/math/acosh.c -index 4ce9b3d..badbf90 100644 ---- a/src/math/acosh.c -+++ b/src/math/acosh.c -@@ -1,5 +1,10 @@ - #include "libm.h" - -+#if FLT_EVAL_METHOD==2 -+#undef sqrt -+#define sqrt sqrtl -+#endif -+ - /* acosh(x) = log(x + sqrt(x*x-1)) */ - double acosh(double x) - { -diff --git a/src/math/acoshf.c b/src/math/acoshf.c -index 16550f1..8a4ec4d 100644 ---- a/src/math/acoshf.c -+++ b/src/math/acoshf.c -@@ -1,5 +1,13 @@ - #include "libm.h" - -+#if FLT_EVAL_METHOD==2 -+#undef sqrtf -+#define sqrtf sqrtl -+#elif FLT_EVAL_METHOD==1 -+#undef sqrtf -+#define sqrtf sqrt -+#endif -+ - /* acosh(x) = log(x + sqrt(x*x-1)) */ - float acoshf(float x) - { -diff --git a/src/math/erfl.c b/src/math/erfl.c -index 42bb1a1..96b74de 100644 ---- a/src/math/erfl.c -+++ b/src/math/erfl.c -@@ -266,23 +266,12 @@ static long double erfc2(uint32_t ix, long double x) - s * (ra[5] + s * (ra[6] + s * (ra[7] + s * ra[8]))))))); - S = sa[0] + s * (sa[1] + s * (sa[2] + s * (sa[3] + s * (sa[4] + - s * (sa[5] + s * (sa[6] + s * (sa[7] + s * (sa[8] + s)))))))); -- } else { /* 2.857 <= |x| */ -+ } else if (ix < 0x4001d555) { /* 2.857 <= |x| < 6.6666259765625 */ - R = rb[0] + s * (rb[1] + s * (rb[2] + s * (rb[3] + s * (rb[4] + - s * (rb[5] + s * (rb[6] + s * rb[7])))))); - S = sb[0] + s * (sb[1] + s * (sb[2] + s * (sb[3] + s * (sb[4] + - s * (sb[5] + s * (sb[6] + s)))))); -- } -- if (ix < 0x4000b6db) { /* 1.25 <= |x| < 2.85711669921875 ~ 1/.35 */ -- R = ra[0] + s * (ra[1] + s * (ra[2] + s * (ra[3] + s * (ra[4] + -- s * (ra[5] + s * (ra[6] + s * (ra[7] + s * ra[8]))))))); -- S = sa[0] + s * (sa[1] + s * (sa[2] + s * (sa[3] + s * (sa[4] + -- s * (sa[5] + s * (sa[6] + s * (sa[7] + s * (sa[8] + s)))))))); -- } else if (ix < 0x4001d555) { /* 6.6666259765625 > |x| >= 1/.35 ~ 2.857143 */ -- R = rb[0] + s * (rb[1] + s * (rb[2] + s * (rb[3] + s * (rb[4] + -- s * (rb[5] + s * (rb[6] + s * rb[7])))))); -- S = sb[0] + s * (sb[1] + s * (sb[2] + s * (sb[3] + s * (sb[4] + -- s * (sb[5] + s * (sb[6] + s)))))); -- } else { /* 107 > |x| >= 6.666 */ -+ } else { /* 6.666 <= |x| < 107 (erfc only) */ - R = rc[0] + s * (rc[1] + s * (rc[2] + s * (rc[3] + - s * (rc[4] + s * rc[5])))); - S = sc[0] + s * (sc[1] + s * (sc[2] + s * (sc[3] + -diff --git a/src/math/finite.c b/src/math/finite.c -new file mode 100644 -index 0000000..25a0575 ---- /dev/null -+++ b/src/math/finite.c -@@ -0,0 +1,7 @@ -+#define _GNU_SOURCE -+#include <math.h> -+ -+int finite(double x) -+{ -+ return isfinite(x); -+} -diff --git a/src/math/finitef.c b/src/math/finitef.c -new file mode 100644 -index 0000000..2c4c771 ---- /dev/null -+++ b/src/math/finitef.c -@@ -0,0 +1,7 @@ -+#define _GNU_SOURCE -+#include <math.h> -+ -+int finitef(float x) -+{ -+ return isfinite(x); -+} -diff --git a/src/math/fma.c b/src/math/fma.c -index 84868be..02f5c86 100644 ---- a/src/math/fma.c -+++ b/src/math/fma.c -@@ -431,12 +431,24 @@ double fma(double x, double y, double z) - /* - * There is no need to worry about double rounding in directed - * rounding modes. -- * TODO: underflow is not raised properly, example in downward rounding: -+ * But underflow may not be raised properly, example in downward rounding: - * fma(0x1.000000001p-1000, 0x1.000000001p-30, -0x1p-1066) - */ -+ double ret; -+#if defined(FE_INEXACT) && defined(FE_UNDERFLOW) -+ int e = fetestexcept(FE_INEXACT); -+ feclearexcept(FE_INEXACT); -+#endif - fesetround(oround); - adj = r.lo + xy.lo; -- return scalbn(r.hi + adj, spread); -+ ret = scalbn(r.hi + adj, spread); -+#if defined(FE_INEXACT) && defined(FE_UNDERFLOW) -+ if (ilogb(ret) < -1022 && fetestexcept(FE_INEXACT)) -+ feraiseexcept(FE_UNDERFLOW); -+ else if (e) -+ feraiseexcept(FE_INEXACT); -+#endif -+ return ret; - } - - adj = add_adjusted(r.lo, xy.lo); -diff --git a/src/math/fmaf.c b/src/math/fmaf.c -index 745ee39..aa57feb 100644 ---- a/src/math/fmaf.c -+++ b/src/math/fmaf.c -@@ -26,7 +26,8 @@ - */ - - #include <fenv.h> --#include "libm.h" -+#include <math.h> -+#include <stdint.h> - - /* - * Fused multiply-add: Compute x * y + z with a single rounding error. -@@ -39,21 +40,35 @@ float fmaf(float x, float y, float z) - { - #pragma STDC FENV_ACCESS ON - double xy, result; -- uint32_t hr, lr; -+ union {double f; uint64_t i;} u; -+ int e; - - xy = (double)x * y; - result = xy + z; -- EXTRACT_WORDS(hr, lr, result); -+ u.f = result; -+ e = u.i>>52 & 0x7ff; - /* Common case: The double precision result is fine. */ -- if ((lr & 0x1fffffff) != 0x10000000 || /* not a halfway case */ -- (hr & 0x7ff00000) == 0x7ff00000 || /* NaN */ -+ if ((u.i & 0x1fffffff) != 0x10000000 || /* not a halfway case */ -+ e == 0x7ff || /* NaN */ - result - xy == z || /* exact */ - fegetround() != FE_TONEAREST) /* not round-to-nearest */ - { - /* -- TODO: underflow is not raised correctly, example in -- downward rouding: fmaf(0x1p-120f, 0x1p-120f, 0x1p-149f) -+ underflow may not be raised correctly, example: -+ fmaf(0x1p-120f, 0x1p-120f, 0x1p-149f) - */ -+#if defined(FE_INEXACT) && defined(FE_UNDERFLOW) -+ if (e < 0x3ff-126 && e >= 0x3ff-149 && fetestexcept(FE_INEXACT)) { -+ feclearexcept(FE_INEXACT); -+ /* TODO: gcc and clang bug workaround */ -+ volatile float vz = z; -+ result = xy + vz; -+ if (fetestexcept(FE_INEXACT)) -+ feraiseexcept(FE_UNDERFLOW); -+ else -+ feraiseexcept(FE_INEXACT); -+ } -+#endif - z = result; - return z; - } -@@ -68,8 +83,11 @@ float fmaf(float x, float y, float z) - volatile double vxy = xy; /* XXX work around gcc CSE bug */ - double adjusted_result = vxy + z; - fesetround(FE_TONEAREST); -- if (result == adjusted_result) -- SET_LOW_WORD(adjusted_result, lr + 1); -+ if (result == adjusted_result) { -+ u.f = adjusted_result; -+ u.i++; -+ adjusted_result = u.f; -+ } - z = adjusted_result; - return z; - } -diff --git a/src/math/fmal.c b/src/math/fmal.c -index c68db25..4506aac 100644 ---- a/src/math/fmal.c -+++ b/src/math/fmal.c -@@ -264,12 +264,24 @@ long double fmal(long double x, long double y, long double z) - /* - * There is no need to worry about double rounding in directed - * rounding modes. -- * TODO: underflow is not raised correctly, example in downward rounding: -+ * But underflow may not be raised correctly, example in downward rounding: - * fmal(0x1.0000000001p-16000L, 0x1.0000000001p-400L, -0x1p-16440L) - */ -+ long double ret; -+#if defined(FE_INEXACT) && defined(FE_UNDERFLOW) -+ int e = fetestexcept(FE_INEXACT); -+ feclearexcept(FE_INEXACT); -+#endif - fesetround(oround); - adj = r.lo + xy.lo; -- return scalbnl(r.hi + adj, spread); -+ ret = scalbnl(r.hi + adj, spread); -+#if defined(FE_INEXACT) && defined(FE_UNDERFLOW) -+ if (ilogbl(ret) < -16382 && fetestexcept(FE_INEXACT)) -+ feraiseexcept(FE_UNDERFLOW); -+ else if (e) -+ feraiseexcept(FE_INEXACT); -+#endif -+ return ret; - } - - adj = add_adjusted(r.lo, xy.lo); -diff --git a/src/math/j0f.c b/src/math/j0f.c -index 4b0ee3b..45883dc 100644 ---- a/src/math/j0f.c -+++ b/src/math/j0f.c -@@ -13,6 +13,7 @@ - * ==================================================== - */ - -+#define _GNU_SOURCE - #include "libm.h" - - static float pzerof(float), qzerof(float); -diff --git a/src/math/j1f.c b/src/math/j1f.c -index 6abde34..58875af 100644 ---- a/src/math/j1f.c -+++ b/src/math/j1f.c -@@ -13,6 +13,7 @@ - * ==================================================== - */ - -+#define _GNU_SOURCE - #include "libm.h" - - static float ponef(float), qonef(float); -diff --git a/src/math/lgamma_r.c b/src/math/lgamma_r.c -index 82e296f..fff565d 100644 ---- a/src/math/lgamma_r.c -+++ b/src/math/lgamma_r.c -@@ -82,7 +82,6 @@ - #include "libc.h" - - static const double --two52= 4.50359962737049600000e+15, /* 0x43300000, 0x00000000 */ - pi = 3.14159265358979311600e+00, /* 0x400921FB, 0x54442D18 */ - a0 = 7.72156649015328655494e-02, /* 0x3FB3C467, 0xE37DB0C8 */ - a1 = 3.22467033424113591611e-01, /* 0x3FD4A34C, 0xC4A60FAD */ -@@ -147,91 +146,62 @@ w4 = -5.95187557450339963135e-04, /* 0xBF4380CB, 0x8C0FE741 */ - w5 = 8.36339918996282139126e-04, /* 0x3F4B67BA, 0x4CDAD5D1 */ - w6 = -1.63092934096575273989e-03; /* 0xBF5AB89D, 0x0B9E43E4 */ - -+/* sin(pi*x) assuming x > 2^-100, if sin(pi*x)==0 the sign is arbitrary */ - static double sin_pi(double x) - { -- double y,z; -- int n,ix; -+ int n; - -- GET_HIGH_WORD(ix, x); -- ix &= 0x7fffffff; -+ /* spurious inexact if odd int */ -+ x = 2.0*(x*0.5 - floor(x*0.5)); /* x mod 2.0 */ - -- if (ix < 0x3fd00000) -- return __sin(pi*x, 0.0, 0); -+ n = (int)(x*4.0); -+ n = (n+1)/2; -+ x -= n*0.5f; -+ x *= pi; - -- y = -x; /* negative x is assumed */ -- -- /* -- * argument reduction, make sure inexact flag not raised if input -- * is an integer -- */ -- z = floor(y); -- if (z != y) { /* inexact anyway */ -- y *= 0.5; -- y = 2.0*(y - floor(y)); /* y = |x| mod 2.0 */ -- n = (int)(y*4.0); -- } else { -- if (ix >= 0x43400000) { -- y = 0.0; /* y must be even */ -- n = 0; -- } else { -- if (ix < 0x43300000) -- z = y + two52; /* exact */ -- GET_LOW_WORD(n, z); -- n &= 1; -- y = n; -- n <<= 2; -- } -- } - switch (n) { -- case 0: y = __sin(pi*y, 0.0, 0); break; -- case 1: -- case 2: y = __cos(pi*(0.5-y), 0.0); break; -- case 3: -- case 4: y = __sin(pi*(1.0-y), 0.0, 0); break; -- case 5: -- case 6: y = -__cos(pi*(y-1.5), 0.0); break; -- default: y = __sin(pi*(y-2.0), 0.0, 0); break; -+ default: /* case 4: */ -+ case 0: return __sin(x, 0.0, 0); -+ case 1: return __cos(x, 0.0); -+ case 2: return __sin(-x, 0.0, 0); -+ case 3: return -__cos(x, 0.0); - } -- return -y; - } - -- - double __lgamma_r(double x, int *signgamp) - { -- double t,y,z,nadj,p,p1,p2,p3,q,r,w; -- int32_t hx; -- int i,lx,ix; -- -- EXTRACT_WORDS(hx, lx, x); -+ union {double f; uint64_t i;} u = {x}; -+ double_t t,y,z,nadj,p,p1,p2,p3,q,r,w; -+ uint32_t ix; -+ int sign,i; - - /* purge off +-inf, NaN, +-0, tiny and negative arguments */ - *signgamp = 1; -- ix = hx & 0x7fffffff; -+ sign = u.i>>63; -+ ix = u.i>>32 & 0x7fffffff; - if (ix >= 0x7ff00000) - return x*x; -- if ((ix|lx) == 0) -- return 1.0/0.0; -- if (ix < 0x3b900000) { /* |x|<2**-70, return -log(|x|) */ -- if(hx < 0) { -+ if (ix < (0x3ff-70)<<20) { /* |x|<2**-70, return -log(|x|) */ -+ if(sign) { -+ x = -x; - *signgamp = -1; -- return -log(-x); - } - return -log(x); - } -- if (hx < 0) { -- if (ix >= 0x43300000) /* |x|>=2**52, must be -integer */ -- return 1.0/0.0; -+ if (sign) { -+ x = -x; - t = sin_pi(x); - if (t == 0.0) /* -integer */ -- return 1.0/0.0; -- nadj = log(pi/fabs(t*x)); -- if (t < 0.0) -+ return 1.0/(x-x); -+ if (t > 0.0) - *signgamp = -1; -- x = -x; -+ else -+ t = -t; -+ nadj = log(pi/(t*x)); - } - - /* purge off 1 and 2 */ -- if (((ix - 0x3ff00000)|lx) == 0 || ((ix - 0x40000000)|lx) == 0) -+ if ((ix == 0x3ff00000 || ix == 0x40000000) && (uint32_t)u.i == 0) - r = 0; - /* for x < 2.0 */ - else if (ix < 0x40000000) { -@@ -306,7 +276,7 @@ double __lgamma_r(double x, int *signgamp) - r = (x-0.5)*(t-1.0)+w; - } else /* 2**58 <= x <= inf */ - r = x*(log(x)-1.0); -- if (hx < 0) -+ if (sign) - r = nadj - r; - return r; - } -diff --git a/src/math/lgammaf_r.c b/src/math/lgammaf_r.c -index dc65bac..c5b43db 100644 ---- a/src/math/lgammaf_r.c -+++ b/src/math/lgammaf_r.c -@@ -17,7 +17,6 @@ - #include "libc.h" - - static const float --two23= 8.3886080000e+06, /* 0x4b000000 */ - pi = 3.1415927410e+00, /* 0x40490fdb */ - a0 = 7.7215664089e-02, /* 0x3d9e233f */ - a1 = 3.2246702909e-01, /* 0x3ea51a66 */ -@@ -82,87 +81,58 @@ w4 = -5.9518753551e-04, /* 0xba1c065c */ - w5 = 8.3633989561e-04, /* 0x3a5b3dd2 */ - w6 = -1.6309292987e-03; /* 0xbad5c4e8 */ - --static float sin_pif(float x) -+/* sin(pi*x) assuming x > 2^-100, if sin(pi*x)==0 the sign is arbitrary */ -+static float sin_pi(float x) - { -- float y,z; -- int n,ix; -+ double_t y; -+ int n; - -- GET_FLOAT_WORD(ix, x); -- ix &= 0x7fffffff; -+ /* spurious inexact if odd int */ -+ x = 2*(x*0.5f - floorf(x*0.5f)); /* x mod 2.0 */ - -- if(ix < 0x3e800000) -- return __sindf(pi*x); -- -- y = -x; /* negative x is assumed */ -- -- /* -- * argument reduction, make sure inexact flag not raised if input -- * is an integer -- */ -- z = floorf(y); -- if (z != y) { /* inexact anyway */ -- y *= 0.5f; -- y = 2.0f*(y - floorf(y)); /* y = |x| mod 2.0 */ -- n = (int)(y*4.0f); -- } else { -- if (ix >= 0x4b800000) { -- y = 0.0f; /* y must be even */ -- n = 0; -- } else { -- if (ix < 0x4b000000) -- z = y + two23; /* exact */ -- GET_FLOAT_WORD(n, z); -- n &= 1; -- y = n; -- n <<= 2; -- } -- } -+ n = (int)(x*4); -+ n = (n+1)/2; -+ y = x - n*0.5f; -+ y *= 3.14159265358979323846; - switch (n) { -- case 0: y = __sindf(pi*y); break; -- case 1: -- case 2: y = __cosdf(pi*(0.5f - y)); break; -- case 3: -- case 4: y = __sindf(pi*(1.0f - y)); break; -- case 5: -- case 6: y = -__cosdf(pi*(y - 1.5f)); break; -- default: y = __sindf(pi*(y - 2.0f)); break; -+ default: /* case 4: */ -+ case 0: return __sindf(y); -+ case 1: return __cosdf(y); -+ case 2: return __sindf(-y); -+ case 3: return -__cosdf(y); - } -- return -y; - } - -- - float __lgammaf_r(float x, int *signgamp) - { -+ union {float f; uint32_t i;} u = {x}; - float t,y,z,nadj,p,p1,p2,p3,q,r,w; -- int32_t hx; -- int i,ix; -- -- GET_FLOAT_WORD(hx, x); -+ uint32_t ix; -+ int i,sign; - - /* purge off +-inf, NaN, +-0, tiny and negative arguments */ - *signgamp = 1; -- ix = hx & 0x7fffffff; -+ sign = u.i>>31; -+ ix = u.i & 0x7fffffff; - if (ix >= 0x7f800000) - return x*x; -- if (ix == 0) -- return 1.0f/0.0f; - if (ix < 0x35000000) { /* |x| < 2**-21, return -log(|x|) */ -- if (hx < 0) { -+ if (sign) { - *signgamp = -1; -- return -logf(-x); -+ x = -x; - } - return -logf(x); - } -- if (hx < 0) { -- if (ix >= 0x4b000000) /* |x| >= 2**23, must be -integer */ -- return 1.0f/0.0f; -- t = sin_pif(x); -+ if (sign) { -+ x = -x; -+ t = sin_pi(x); - if (t == 0.0f) /* -integer */ -- return 1.0f/0.0f; -- nadj = logf(pi/fabsf(t*x)); -- if (t < 0.0f) -+ return 1.0f/(x-x); -+ if (t > 0.0f) - *signgamp = -1; -- x = -x; -+ else -+ t = -t; -+ nadj = logf(pi/(t*x)); - } - - /* purge off 1 and 2 */ -@@ -241,7 +211,7 @@ float __lgammaf_r(float x, int *signgamp) - r = (x-0.5f)*(t-1.0f)+w; - } else /* 2**58 <= x <= inf */ - r = x*(logf(x)-1.0f); -- if (hx < 0) -+ if (sign) - r = nadj - r; - return r; - } -diff --git a/src/math/lgammal.c b/src/math/lgammal.c -index cc4895e..55ec532 100644 ---- a/src/math/lgammal.c -+++ b/src/math/lgammal.c -@@ -99,7 +99,6 @@ long double __lgammal_r(long double x, int *sg) - #elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384 - static const long double - pi = 3.14159265358979323846264L, --two63 = 9.223372036854775808e18L, - - /* lgam(1+x) = 0.5 x + x a(x)/b(x) - -0.268402099609375 <= x <= 0 -@@ -201,61 +200,27 @@ w5 = 8.412723297322498080632E-4L, - w6 = -1.880801938119376907179E-3L, - w7 = 4.885026142432270781165E-3L; - -+/* sin(pi*x) assuming x > 2^-1000, if sin(pi*x)==0 the sign is arbitrary */ - static long double sin_pi(long double x) - { -- union ldshape u = {x}; -- uint32_t ix = (u.i.se & 0x7fffU)<<16 | u.i.m>>48; -- long double y, z; - int n; - -- if (ix < 0x3ffd8000) /* 0.25 */ -- return sinl(pi * x); -- y = -x; /* x is assume negative */ -+ /* spurious inexact if odd int */ -+ x *= 0.5; -+ x = 2.0*(x - floorl(x)); /* x mod 2.0 */ - -- /* -- * argument reduction, make sure inexact flag not raised if input -- * is an integer -- */ -- z = floorl(y); -- if (z != y) { /* inexact anyway */ -- y *= 0.5; -- y = 2.0*(y - floorl(y));/* y = |x| mod 2.0 */ -- n = (int) (y*4.0); -- } else { -- if (ix >= 0x403f8000) { /* 2^64 */ -- y = 0.0; /* y must be even */ -- n = 0; -- } else { -- if (ix < 0x403e8000) /* 2^63 */ -- z = y + two63; /* exact */ -- u.f = z; -- n = u.i.m & 1; -- y = n; -- n <<= 2; -- } -- } -+ n = (int)(x*4.0); -+ n = (n+1)/2; -+ x -= n*0.5f; -+ x *= pi; - - switch (n) { -- case 0: -- y = sinl(pi * y); -- break; -- case 1: -- case 2: -- y = cosl(pi * (0.5 - y)); -- break; -- case 3: -- case 4: -- y = sinl(pi * (1.0 - y)); -- break; -- case 5: -- case 6: -- y = -cosl(pi * (y - 1.5)); -- break; -- default: -- y = sinl(pi * (y - 2.0)); -- break; -+ default: /* case 4: */ -+ case 0: return __sinl(x, 0.0, 0); -+ case 1: return __cosl(x, 0.0); -+ case 2: return __sinl(-x, 0.0, 0); -+ case 3: return -__cosl(x, 0.0); - } -- return -y; - } - - long double __lgammal_r(long double x, int *sg) { -@@ -267,31 +232,32 @@ long double __lgammal_r(long double x, int *sg) { - - *sg = 1; - -- /* purge off +-inf, NaN, +-0, and negative arguments */ -+ /* purge off +-inf, NaN, +-0, tiny and negative arguments */ - if (ix >= 0x7fff0000) - return x * x; -- if (x == 0) { -- *sg -= 2*sign; -- return 1.0 / fabsl(x); -- } - if (ix < 0x3fc08000) { /* |x|<2**-63, return -log(|x|) */ - if (sign) { - *sg = -1; -- return -logl(-x); -+ x = -x; - } - return -logl(x); - } - if (sign) { -- t = sin_pi (x); -+ x = -x; -+ t = sin_pi(x); - if (t == 0.0) -- return 1.0 / fabsl(t); /* -integer */ -- nadj = logl(pi / fabsl(t * x)); -- if (t < 0.0) -+ return 1.0 / (x-x); /* -integer */ -+ if (t > 0.0) - *sg = -1; -- x = -x; -+ else -+ t = -t; -+ nadj = logl(pi / (t * x)); - } - -- if (ix < 0x40008000) { /* x < 2.0 */ -+ /* purge off 1 and 2 (so the sign is ok with downward rounding) */ -+ if ((ix == 0x3fff8000 || ix == 0x40008000) && u.i.m == 0) { -+ r = 0; -+ } else if (ix < 0x40008000) { /* x < 2.0 */ - if (ix <= 0x3ffee666) { /* 8.99993896484375e-1 */ - /* lgamma(x) = lgamma(x+1) - log(x) */ - r = -logl(x); -@@ -341,12 +307,12 @@ long double __lgammal_r(long double x, int *sg) { - } else if (ix < 0x40028000) { /* 8.0 */ - /* x < 8.0 */ - i = (int)x; -- t = 0.0; - y = x - (double)i; - p = y * (s0 + y * (s1 + y * (s2 + y * (s3 + y * (s4 + y * (s5 + y * s6)))))); - q = r0 + y * (r1 + y * (r2 + y * (r3 + y * (r4 + y * (r5 + y * (r6 + y)))))); - r = 0.5 * y + p / q; -- z = 1.0;/* lgamma(1+s) = log(s) + lgamma(s) */ -+ z = 1.0; -+ /* lgamma(1+s) = log(s) + lgamma(s) */ - switch (i) { - case 7: - z *= (y + 6.0); /* FALLTHRU */ -@@ -376,6 +342,7 @@ long double __lgammal_r(long double x, int *sg) { - } - #endif - -+#if (LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024) || (LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384) - extern int __signgam; - - long double lgammal(long double x) -@@ -384,3 +351,4 @@ long double lgammal(long double x) - } - - weak_alias(__lgammal_r, lgammal_r); -+#endif -diff --git a/src/math/log.c b/src/math/log.c -index 9805120..e61e113 100644 ---- a/src/math/log.c -+++ b/src/math/log.c -@@ -10,7 +10,7 @@ - * ==================================================== - */ - /* log(x) -- * Return the logrithm of x -+ * Return the logarithm of x - * - * Method : - * 1. Argument Reduction: find k and f such that -@@ -60,12 +60,12 @@ - * to produce the hexadecimal values shown. - */ - --#include "libm.h" -+#include <math.h> -+#include <stdint.h> - - static const double - ln2_hi = 6.93147180369123816490e-01, /* 3fe62e42 fee00000 */ - ln2_lo = 1.90821492927058770002e-10, /* 3dea39ef 35793c76 */ --two54 = 1.80143985094819840000e+16, /* 43500000 00000000 */ - Lg1 = 6.666666666666735130e-01, /* 3FE55555 55555593 */ - Lg2 = 3.999999999940941908e-01, /* 3FD99999 9997FA04 */ - Lg3 = 2.857142874366239149e-01, /* 3FD24924 94229359 */ -@@ -76,63 +76,43 @@ Lg7 = 1.479819860511658591e-01; /* 3FC2F112 DF3E5244 */ - - double log(double x) - { -- double hfsq,f,s,z,R,w,t1,t2,dk; -- int32_t k,hx,i,j; -- uint32_t lx; -- -- EXTRACT_WORDS(hx, lx, x); -+ union {double f; uint64_t i;} u = {x}; -+ double_t hfsq,f,s,z,R,w,t1,t2,dk; -+ uint32_t hx; -+ int k; - -+ hx = u.i>>32; - k = 0; -- if (hx < 0x00100000) { /* x < 2**-1022 */ -- if (((hx&0x7fffffff)|lx) == 0) -- return -two54/0.0; /* log(+-0)=-inf */ -- if (hx < 0) -- return (x-x)/0.0; /* log(-#) = NaN */ -- /* subnormal number, scale up x */ -+ if (hx < 0x00100000 || hx>>31) { -+ if (u.i<<1 == 0) -+ return -1/(x*x); /* log(+-0)=-inf */ -+ if (hx>>31) -+ return (x-x)/0.0; /* log(-#) = NaN */ -+ /* subnormal number, scale x up */ - k -= 54; -- x *= two54; -- GET_HIGH_WORD(hx,x); -- } -- if (hx >= 0x7ff00000) -- return x+x; -- k += (hx>>20) - 1023; -- hx &= 0x000fffff; -- i = (hx+0x95f64)&0x100000; -- SET_HIGH_WORD(x, hx|(i^0x3ff00000)); /* normalize x or x/2 */ -- k += i>>20; -+ x *= 0x1p54; -+ u.f = x; -+ hx = u.i>>32; -+ } else if (hx >= 0x7ff00000) { -+ return x; -+ } else if (hx == 0x3ff00000 && u.i<<32 == 0) -+ return 0; -+ -+ /* reduce x into [sqrt(2)/2, sqrt(2)] */ -+ hx += 0x3ff00000 - 0x3fe6a09e; -+ k += (int)(hx>>20) - 0x3ff; -+ hx = (hx&0x000fffff) + 0x3fe6a09e; -+ u.i = (uint64_t)hx<<32 | (u.i&0xffffffff); -+ x = u.f; -+ - f = x - 1.0; -- if ((0x000fffff&(2+hx)) < 3) { /* -2**-20 <= f < 2**-20 */ -- if (f == 0.0) { -- if (k == 0) { -- return 0.0; -- } -- dk = (double)k; -- return dk*ln2_hi + dk*ln2_lo; -- } -- R = f*f*(0.5-0.33333333333333333*f); -- if (k == 0) -- return f - R; -- dk = (double)k; -- return dk*ln2_hi - ((R-dk*ln2_lo)-f); -- } -+ hfsq = 0.5*f*f; - s = f/(2.0+f); -- dk = (double)k; - z = s*s; -- i = hx - 0x6147a; - w = z*z; -- j = 0x6b851 - hx; - t1 = w*(Lg2+w*(Lg4+w*Lg6)); - t2 = z*(Lg1+w*(Lg3+w*(Lg5+w*Lg7))); -- i |= j; - R = t2 + t1; -- if (i > 0) { -- hfsq = 0.5*f*f; -- if (k == 0) -- return f - (hfsq-s*(hfsq+R)); -- return dk*ln2_hi - ((hfsq-(s*(hfsq+R)+dk*ln2_lo))-f); -- } else { -- if (k == 0) -- return f - s*(f-R); -- return dk*ln2_hi - ((s*(f-R)-dk*ln2_lo)-f); -- } -+ dk = k; -+ return s*(hfsq+R) + dk*ln2_lo - hfsq + f + dk*ln2_hi; - } -diff --git a/src/math/log10.c b/src/math/log10.c -index ed65d9b..8102687 100644 ---- a/src/math/log10.c -+++ b/src/math/log10.c -@@ -10,72 +10,91 @@ - * ==================================================== - */ - /* -- * Return the base 10 logarithm of x. See e_log.c and k_log.h for most -- * comments. -+ * Return the base 10 logarithm of x. See log.c for most comments. - * -- * log10(x) = (f - 0.5*f*f + k_log1p(f)) / ln10 + k * log10(2) -- * in not-quite-routine extra precision. -+ * Reduce x to 2^k (1+f) and calculate r = log(1+f) - f + f*f/2 -+ * as in log.c, then combine and scale in extra precision: -+ * log10(x) = (f - f*f/2 + r)/log(10) + k*log10(2) - */ - --#include "libm.h" --#include "__log1p.h" -+#include <math.h> -+#include <stdint.h> - - static const double --two54 = 1.80143985094819840000e+16, /* 0x43500000, 0x00000000 */ - ivln10hi = 4.34294481878168880939e-01, /* 0x3fdbcb7b, 0x15200000 */ - ivln10lo = 2.50829467116452752298e-11, /* 0x3dbb9438, 0xca9aadd5 */ - log10_2hi = 3.01029995663611771306e-01, /* 0x3FD34413, 0x509F6000 */ --log10_2lo = 3.69423907715893078616e-13; /* 0x3D59FEF3, 0x11F12B36 */ -+log10_2lo = 3.69423907715893078616e-13, /* 0x3D59FEF3, 0x11F12B36 */ -+Lg1 = 6.666666666666735130e-01, /* 3FE55555 55555593 */ -+Lg2 = 3.999999999940941908e-01, /* 3FD99999 9997FA04 */ -+Lg3 = 2.857142874366239149e-01, /* 3FD24924 94229359 */ -+Lg4 = 2.222219843214978396e-01, /* 3FCC71C5 1D8E78AF */ -+Lg5 = 1.818357216161805012e-01, /* 3FC74664 96CB03DE */ -+Lg6 = 1.531383769920937332e-01, /* 3FC39A09 D078C69F */ -+Lg7 = 1.479819860511658591e-01; /* 3FC2F112 DF3E5244 */ - - double log10(double x) - { -- double f,hfsq,hi,lo,r,val_hi,val_lo,w,y,y2; -- int32_t i,k,hx; -- uint32_t lx; -- -- EXTRACT_WORDS(hx, lx, x); -+ union {double f; uint64_t i;} u = {x}; -+ double_t hfsq,f,s,z,R,w,t1,t2,dk,y,hi,lo,val_hi,val_lo; -+ uint32_t hx; -+ int k; - -+ hx = u.i>>32; - k = 0; -- if (hx < 0x00100000) { /* x < 2**-1022 */ -- if (((hx&0x7fffffff)|lx) == 0) -- return -two54/0.0; /* log(+-0)=-inf */ -- if (hx<0) -- return (x-x)/0.0; /* log(-#) = NaN */ -- /* subnormal number, scale up x */ -+ if (hx < 0x00100000 || hx>>31) { -+ if (u.i<<1 == 0) -+ return -1/(x*x); /* log(+-0)=-inf */ -+ if (hx>>31) -+ return (x-x)/0.0; /* log(-#) = NaN */ -+ /* subnormal number, scale x up */ - k -= 54; -- x *= two54; -- GET_HIGH_WORD(hx, x); -- } -- if (hx >= 0x7ff00000) -- return x+x; -- if (hx == 0x3ff00000 && lx == 0) -- return 0.0; /* log(1) = +0 */ -- k += (hx>>20) - 1023; -- hx &= 0x000fffff; -- i = (hx+0x95f64)&0x100000; -- SET_HIGH_WORD(x, hx|(i^0x3ff00000)); /* normalize x or x/2 */ -- k += i>>20; -- y = (double)k; -+ x *= 0x1p54; -+ u.f = x; -+ hx = u.i>>32; -+ } else if (hx >= 0x7ff00000) { -+ return x; -+ } else if (hx == 0x3ff00000 && u.i<<32 == 0) -+ return 0; -+ -+ /* reduce x into [sqrt(2)/2, sqrt(2)] */ -+ hx += 0x3ff00000 - 0x3fe6a09e; -+ k += (int)(hx>>20) - 0x3ff; -+ hx = (hx&0x000fffff) + 0x3fe6a09e; -+ u.i = (uint64_t)hx<<32 | (u.i&0xffffffff); -+ x = u.f; -+ - f = x - 1.0; - hfsq = 0.5*f*f; -- r = __log1p(f); -+ s = f/(2.0+f); -+ z = s*s; -+ w = z*z; -+ t1 = w*(Lg2+w*(Lg4+w*Lg6)); -+ t2 = z*(Lg1+w*(Lg3+w*(Lg5+w*Lg7))); -+ R = t2 + t1; - - /* See log2.c for details. */ -+ /* hi+lo = f - hfsq + s*(hfsq+R) ~ log(1+f) */ - hi = f - hfsq; -- SET_LOW_WORD(hi, 0); -- lo = (f - hi) - hfsq + r; -+ u.f = hi; -+ u.i &= (uint64_t)-1<<32; -+ hi = u.f; -+ lo = f - hi - hfsq + s*(hfsq+R); -+ -+ /* val_hi+val_lo ~ log10(1+f) + k*log10(2) */ - val_hi = hi*ivln10hi; -- y2 = y*log10_2hi; -- val_lo = y*log10_2lo + (lo+hi)*ivln10lo + lo*ivln10hi; -+ dk = k; -+ y = dk*log10_2hi; -+ val_lo = dk*log10_2lo + (lo+hi)*ivln10lo + lo*ivln10hi; - - /* -- * Extra precision in for adding y*log10_2hi is not strictly needed -+ * Extra precision in for adding y is not strictly needed - * since there is no very large cancellation near x = sqrt(2) or - * x = 1/sqrt(2), but we do it anyway since it costs little on CPUs - * with some parallelism and it reduces the error for many args. - */ -- w = y2 + val_hi; -- val_lo += (y2 - w) + val_hi; -+ w = y + val_hi; -+ val_lo += (y - w) + val_hi; - val_hi = w; - - return val_lo + val_hi; -diff --git a/src/math/log10f.c b/src/math/log10f.c -index e10749b..9ca2f01 100644 ---- a/src/math/log10f.c -+++ b/src/math/log10f.c -@@ -13,57 +13,65 @@ - * See comments in log10.c. - */ - --#include "libm.h" --#include "__log1pf.h" -+#include <math.h> -+#include <stdint.h> - - static const float --two25 = 3.3554432000e+07, /* 0x4c000000 */ - ivln10hi = 4.3432617188e-01, /* 0x3ede6000 */ - ivln10lo = -3.1689971365e-05, /* 0xb804ead9 */ - log10_2hi = 3.0102920532e-01, /* 0x3e9a2080 */ --log10_2lo = 7.9034151668e-07; /* 0x355427db */ -+log10_2lo = 7.9034151668e-07, /* 0x355427db */ -+/* |(log(1+s)-log(1-s))/s - Lg(s)| < 2**-34.24 (~[-4.95e-11, 4.97e-11]). */ -+Lg1 = 0xaaaaaa.0p-24, /* 0.66666662693 */ -+Lg2 = 0xccce13.0p-25, /* 0.40000972152 */ -+Lg3 = 0x91e9ee.0p-25, /* 0.28498786688 */ -+Lg4 = 0xf89e26.0p-26; /* 0.24279078841 */ - - float log10f(float x) - { -- float f,hfsq,hi,lo,r,y; -- int32_t i,k,hx; -- -- GET_FLOAT_WORD(hx, x); -+ union {float f; uint32_t i;} u = {x}; -+ float_t hfsq,f,s,z,R,w,t1,t2,dk,hi,lo; -+ uint32_t ix; -+ int k; - -+ ix = u.i; - k = 0; -- if (hx < 0x00800000) { /* x < 2**-126 */ -- if ((hx&0x7fffffff) == 0) -- return -two25/0.0f; /* log(+-0)=-inf */ -- if (hx < 0) -- return (x-x)/0.0f; /* log(-#) = NaN */ -+ if (ix < 0x00800000 || ix>>31) { /* x < 2**-126 */ -+ if (ix<<1 == 0) -+ return -1/(x*x); /* log(+-0)=-inf */ -+ if (ix>>31) -+ return (x-x)/0.0f; /* log(-#) = NaN */ - /* subnormal number, scale up x */ - k -= 25; -- x *= two25; -- GET_FLOAT_WORD(hx, x); -- } -- if (hx >= 0x7f800000) -- return x+x; -- if (hx == 0x3f800000) -- return 0.0f; /* log(1) = +0 */ -- k += (hx>>23) - 127; -- hx &= 0x007fffff; -- i = (hx+(0x4afb0d))&0x800000; -- SET_FLOAT_WORD(x, hx|(i^0x3f800000)); /* normalize x or x/2 */ -- k += i>>23; -- y = (float)k; -+ x *= 0x1p25f; -+ u.f = x; -+ ix = u.i; -+ } else if (ix >= 0x7f800000) { -+ return x; -+ } else if (ix == 0x3f800000) -+ return 0; -+ -+ /* reduce x into [sqrt(2)/2, sqrt(2)] */ -+ ix += 0x3f800000 - 0x3f3504f3; -+ k += (int)(ix>>23) - 0x7f; -+ ix = (ix&0x007fffff) + 0x3f3504f3; -+ u.i = ix; -+ x = u.f; -+ - f = x - 1.0f; -- hfsq = 0.5f * f * f; -- r = __log1pf(f); -+ s = f/(2.0f + f); -+ z = s*s; -+ w = z*z; -+ t1= w*(Lg2+w*Lg4); -+ t2= z*(Lg1+w*Lg3); -+ R = t2 + t1; -+ hfsq = 0.5f*f*f; - --// FIXME --// /* See log2f.c and log2.c for details. */ --// if (sizeof(float_t) > sizeof(float)) --// return (r - hfsq + f) * ((float_t)ivln10lo + ivln10hi) + --// y * ((float_t)log10_2lo + log10_2hi); - hi = f - hfsq; -- GET_FLOAT_WORD(hx, hi); -- SET_FLOAT_WORD(hi, hx&0xfffff000); -- lo = (f - hi) - hfsq + r; -- return y*log10_2lo + (lo+hi)*ivln10lo + lo*ivln10hi + -- hi*ivln10hi + y*log10_2hi; -+ u.f = hi; -+ u.i &= 0xfffff000; -+ hi = u.f; -+ lo = f - hi - hfsq + s*(hfsq+R); -+ dk = k; -+ return dk*log10_2lo + (lo+hi)*ivln10lo + lo*ivln10hi + hi*ivln10hi + dk*log10_2hi; - } -diff --git a/src/math/log10l.c b/src/math/log10l.c -index f0eeeaf..c7aacf9 100644 ---- a/src/math/log10l.c -+++ b/src/math/log10l.c -@@ -117,16 +117,15 @@ static const long double S[4] = { - - long double log10l(long double x) - { -- long double y; -- volatile long double z; -+ long double y, z; - int e; - - if (isnan(x)) - return x; - if(x <= 0.0) { - if(x == 0.0) -- return -1.0 / (x - x); -- return (x - x) / (x - x); -+ return -1.0 / (x*x); -+ return (x - x) / 0.0; - } - if (x == INFINITY) - return INFINITY; -diff --git a/src/math/log1p.c b/src/math/log1p.c -index a71ac42..0097134 100644 ---- a/src/math/log1p.c -+++ b/src/math/log1p.c -@@ -10,6 +10,7 @@ - * ==================================================== - */ - /* double log1p(double x) -+ * Return the natural logarithm of 1+x. - * - * Method : - * 1. Argument Reduction: find k and f such that -@@ -23,31 +24,9 @@ - * and add back the correction term c/u. - * (Note: when x > 2**53, one can simply return log(x)) - * -- * 2. Approximation of log1p(f). -- * Let s = f/(2+f) ; based on log(1+f) = log(1+s) - log(1-s) -- * = 2s + 2/3 s**3 + 2/5 s**5 + ....., -- * = 2s + s*R -- * We use a special Reme algorithm on [0,0.1716] to generate -- * a polynomial of degree 14 to approximate R The maximum error -- * of this polynomial approximation is bounded by 2**-58.45. In -- * other words, -- * 2 4 6 8 10 12 14 -- * R(z) ~ Lp1*s +Lp2*s +Lp3*s +Lp4*s +Lp5*s +Lp6*s +Lp7*s -- * (the values of Lp1 to Lp7 are listed in the program) -- * and -- * | 2 14 | -58.45 -- * | Lp1*s +...+Lp7*s - R(z) | <= 2 -- * | | -- * Note that 2s = f - s*f = f - hfsq + s*hfsq, where hfsq = f*f/2. -- * In order to guarantee error in log below 1ulp, we compute log -- * by -- * log1p(f) = f - (hfsq - s*(hfsq+R)). -+ * 2. Approximation of log(1+f): See log.c - * -- * 3. Finally, log1p(x) = k*ln2 + log1p(f). -- * = k*ln2_hi+(f-(hfsq-(s*(hfsq+R)+k*ln2_lo))) -- * Here ln2 is split into two floating point number: -- * ln2_hi + ln2_lo, -- * where n*ln2_hi is always exact for |n| < 2000. -+ * 3. Finally, log1p(x) = k*ln2 + log(1+f) + c/u. See log.c - * - * Special cases: - * log1p(x) is NaN with signal if x < -1 (including -INF) ; -@@ -79,94 +58,65 @@ - static const double - ln2_hi = 6.93147180369123816490e-01, /* 3fe62e42 fee00000 */ - ln2_lo = 1.90821492927058770002e-10, /* 3dea39ef 35793c76 */ --two54 = 1.80143985094819840000e+16, /* 43500000 00000000 */ --Lp1 = 6.666666666666735130e-01, /* 3FE55555 55555593 */ --Lp2 = 3.999999999940941908e-01, /* 3FD99999 9997FA04 */ --Lp3 = 2.857142874366239149e-01, /* 3FD24924 94229359 */ --Lp4 = 2.222219843214978396e-01, /* 3FCC71C5 1D8E78AF */ --Lp5 = 1.818357216161805012e-01, /* 3FC74664 96CB03DE */ --Lp6 = 1.531383769920937332e-01, /* 3FC39A09 D078C69F */ --Lp7 = 1.479819860511658591e-01; /* 3FC2F112 DF3E5244 */ -+Lg1 = 6.666666666666735130e-01, /* 3FE55555 55555593 */ -+Lg2 = 3.999999999940941908e-01, /* 3FD99999 9997FA04 */ -+Lg3 = 2.857142874366239149e-01, /* 3FD24924 94229359 */ -+Lg4 = 2.222219843214978396e-01, /* 3FCC71C5 1D8E78AF */ -+Lg5 = 1.818357216161805012e-01, /* 3FC74664 96CB03DE */ -+Lg6 = 1.531383769920937332e-01, /* 3FC39A09 D078C69F */ -+Lg7 = 1.479819860511658591e-01; /* 3FC2F112 DF3E5244 */ - - double log1p(double x) - { -- double hfsq,f,c,s,z,R,u; -- int32_t k,hx,hu,ax; -- -- GET_HIGH_WORD(hx, x); -- ax = hx & 0x7fffffff; -+ union {double f; uint64_t i;} u = {x}; -+ double_t hfsq,f,c,s,z,R,w,t1,t2,dk; -+ uint32_t hx,hu; -+ int k; - -+ hx = u.i>>32; - k = 1; -- if (hx < 0x3FDA827A) { /* 1+x < sqrt(2)+ */ -- if (ax >= 0x3ff00000) { /* x <= -1.0 */ -- if (x == -1.0) -- return -two54/0.0; /* log1p(-1)=+inf */ -- return (x-x)/(x-x); /* log1p(x<-1)=NaN */ -+ if (hx < 0x3fda827a || hx>>31) { /* 1+x < sqrt(2)+ */ -+ if (hx >= 0xbff00000) { /* x <= -1.0 */ -+ if (x == -1) -+ return x/0.0; /* log1p(-1) = -inf */ -+ return (x-x)/0.0; /* log1p(x<-1) = NaN */ - } -- if (ax < 0x3e200000) { /* |x| < 2**-29 */ -- /* if 0x1p-1022 <= |x| < 0x1p-54, avoid raising underflow */ -- if (ax < 0x3c900000 && ax >= 0x00100000) -- return x; --#if FLT_EVAL_METHOD != 0 -- FORCE_EVAL((float)x); --#endif -- return x - x*x*0.5; -+ if (hx<<1 < 0x3ca00000<<1) { /* |x| < 2**-53 */ -+ /* underflow if subnormal */ -+ if ((hx&0x7ff00000) == 0) -+ FORCE_EVAL((float)x); -+ return x; - } -- if (hx > 0 || hx <= (int32_t)0xbfd2bec4) { /* sqrt(2)/2- <= 1+x < sqrt(2)+ */ -+ if (hx <= 0xbfd2bec4) { /* sqrt(2)/2- <= 1+x < sqrt(2)+ */ - k = 0; -+ c = 0; - f = x; -- hu = 1; - } -- } -- if (hx >= 0x7ff00000) -- return x+x; -- if (k != 0) { -- if (hx < 0x43400000) { -- u = 1 + x; -- GET_HIGH_WORD(hu, u); -- k = (hu>>20) - 1023; -- c = k > 0 ? 1.0-(u-x) : x-(u-1.0); /* correction term */ -- c /= u; -- } else { -- u = x; -- GET_HIGH_WORD(hu,u); -- k = (hu>>20) - 1023; -+ } else if (hx >= 0x7ff00000) -+ return x; -+ if (k) { -+ u.f = 1 + x; -+ hu = u.i>>32; -+ hu += 0x3ff00000 - 0x3fe6a09e; -+ k = (int)(hu>>20) - 0x3ff; -+ /* correction term ~ log(1+x)-log(u), avoid underflow in c/u */ -+ if (k < 54) { -+ c = k >= 2 ? 1-(u.f-x) : x-(u.f-1); -+ c /= u.f; -+ } else - c = 0; -- } -- hu &= 0x000fffff; -- /* -- * The approximation to sqrt(2) used in thresholds is not -- * critical. However, the ones used above must give less -- * strict bounds than the one here so that the k==0 case is -- * never reached from here, since here we have committed to -- * using the correction term but don't use it if k==0. -- */ -- if (hu < 0x6a09e) { /* u ~< sqrt(2) */ -- SET_HIGH_WORD(u, hu|0x3ff00000); /* normalize u */ -- } else { -- k += 1; -- SET_HIGH_WORD(u, hu|0x3fe00000); /* normalize u/2 */ -- hu = (0x00100000-hu)>>2; -- } -- f = u - 1.0; -+ /* reduce u into [sqrt(2)/2, sqrt(2)] */ -+ hu = (hu&0x000fffff) + 0x3fe6a09e; -+ u.i = (uint64_t)hu<<32 | (u.i&0xffffffff); -+ f = u.f - 1; - } - hfsq = 0.5*f*f; -- if (hu == 0) { /* |f| < 2**-20 */ -- if (f == 0.0) { -- if(k == 0) -- return 0.0; -- c += k*ln2_lo; -- return k*ln2_hi + c; -- } -- R = hfsq*(1.0 - 0.66666666666666666*f); -- if (k == 0) -- return f - R; -- return k*ln2_hi - ((R-(k*ln2_lo+c))-f); -- } - s = f/(2.0+f); - z = s*s; -- R = z*(Lp1+z*(Lp2+z*(Lp3+z*(Lp4+z*(Lp5+z*(Lp6+z*Lp7)))))); -- if (k == 0) -- return f - (hfsq-s*(hfsq+R)); -- return k*ln2_hi - ((hfsq-(s*(hfsq+R)+(k*ln2_lo+c)))-f); -+ w = z*z; -+ t1 = w*(Lg2+w*(Lg4+w*Lg6)); -+ t2 = z*(Lg1+w*(Lg3+w*(Lg5+w*Lg7))); -+ R = t2 + t1; -+ dk = k; -+ return s*(hfsq+R) + (dk*ln2_lo+c) - hfsq + f + dk*ln2_hi; - } -diff --git a/src/math/log1pf.c b/src/math/log1pf.c -index e6940d2..23985c3 100644 ---- a/src/math/log1pf.c -+++ b/src/math/log1pf.c -@@ -1,8 +1,5 @@ - /* origin: FreeBSD /usr/src/lib/msun/src/s_log1pf.c */ - /* -- * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. -- */ --/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * -@@ -18,95 +15,63 @@ - static const float - ln2_hi = 6.9313812256e-01, /* 0x3f317180 */ - ln2_lo = 9.0580006145e-06, /* 0x3717f7d1 */ --two25 = 3.355443200e+07, /* 0x4c000000 */ --Lp1 = 6.6666668653e-01, /* 3F2AAAAB */ --Lp2 = 4.0000000596e-01, /* 3ECCCCCD */ --Lp3 = 2.8571429849e-01, /* 3E924925 */ --Lp4 = 2.2222198546e-01, /* 3E638E29 */ --Lp5 = 1.8183572590e-01, /* 3E3A3325 */ --Lp6 = 1.5313838422e-01, /* 3E1CD04F */ --Lp7 = 1.4798198640e-01; /* 3E178897 */ -+/* |(log(1+s)-log(1-s))/s - Lg(s)| < 2**-34.24 (~[-4.95e-11, 4.97e-11]). */ -+Lg1 = 0xaaaaaa.0p-24, /* 0.66666662693 */ -+Lg2 = 0xccce13.0p-25, /* 0.40000972152 */ -+Lg3 = 0x91e9ee.0p-25, /* 0.28498786688 */ -+Lg4 = 0xf89e26.0p-26; /* 0.24279078841 */ - - float log1pf(float x) - { -- float hfsq,f,c,s,z,R,u; -- int32_t k,hx,hu,ax; -- -- GET_FLOAT_WORD(hx, x); -- ax = hx & 0x7fffffff; -+ union {float f; uint32_t i;} u = {x}; -+ float_t hfsq,f,c,s,z,R,w,t1,t2,dk; -+ uint32_t ix,iu; -+ int k; - -+ ix = u.i; - k = 1; -- if (hx < 0x3ed413d0) { /* 1+x < sqrt(2)+ */ -- if (ax >= 0x3f800000) { /* x <= -1.0 */ -- if (x == -1.0f) -- return -two25/0.0f; /* log1p(-1)=+inf */ -- return (x-x)/(x-x); /* log1p(x<-1)=NaN */ -+ if (ix < 0x3ed413d0 || ix>>31) { /* 1+x < sqrt(2)+ */ -+ if (ix >= 0xbf800000) { /* x <= -1.0 */ -+ if (x == -1) -+ return x/0.0f; /* log1p(-1)=+inf */ -+ return (x-x)/0.0f; /* log1p(x<-1)=NaN */ - } -- if (ax < 0x38000000) { /* |x| < 2**-15 */ -- /* if 0x1p-126 <= |x| < 0x1p-24, avoid raising underflow */ -- if (ax < 0x33800000 && ax >= 0x00800000) -- return x; --#if FLT_EVAL_METHOD != 0 -- FORCE_EVAL(x*x); --#endif -- return x - x*x*0.5f; -+ if (ix<<1 < 0x33800000<<1) { /* |x| < 2**-24 */ -+ /* underflow if subnormal */ -+ if ((ix&0x7f800000) == 0) -+ FORCE_EVAL(x*x); -+ return x; - } -- if (hx > 0 || hx <= (int32_t)0xbe95f619) { /* sqrt(2)/2- <= 1+x < sqrt(2)+ */ -+ if (ix <= 0xbe95f619) { /* sqrt(2)/2- <= 1+x < sqrt(2)+ */ - k = 0; -+ c = 0; - f = x; -- hu = 1; - } -- } -- if (hx >= 0x7f800000) -- return x+x; -- if (k != 0) { -- if (hx < 0x5a000000) { -- u = 1 + x; -- GET_FLOAT_WORD(hu, u); -- k = (hu>>23) - 127; -- /* correction term */ -- c = k > 0 ? 1.0f-(u-x) : x-(u-1.0f); -- c /= u; -- } else { -- u = x; -- GET_FLOAT_WORD(hu,u); -- k = (hu>>23) - 127; -+ } else if (ix >= 0x7f800000) -+ return x; -+ if (k) { -+ u.f = 1 + x; -+ iu = u.i; -+ iu += 0x3f800000 - 0x3f3504f3; -+ k = (int)(iu>>23) - 0x7f; -+ /* correction term ~ log(1+x)-log(u), avoid underflow in c/u */ -+ if (k < 25) { -+ c = k >= 2 ? 1-(u.f-x) : x-(u.f-1); -+ c /= u.f; -+ } else - c = 0; -- } -- hu &= 0x007fffff; -- /* -- * The approximation to sqrt(2) used in thresholds is not -- * critical. However, the ones used above must give less -- * strict bounds than the one here so that the k==0 case is -- * never reached from here, since here we have committed to -- * using the correction term but don't use it if k==0. -- */ -- if (hu < 0x3504f4) { /* u < sqrt(2) */ -- SET_FLOAT_WORD(u, hu|0x3f800000); /* normalize u */ -- } else { -- k += 1; -- SET_FLOAT_WORD(u, hu|0x3f000000); /* normalize u/2 */ -- hu = (0x00800000-hu)>>2; -- } -- f = u - 1.0f; -- } -- hfsq = 0.5f * f * f; -- if (hu == 0) { /* |f| < 2**-20 */ -- if (f == 0.0f) { -- if (k == 0) -- return 0.0f; -- c += k*ln2_lo; -- return k*ln2_hi+c; -- } -- R = hfsq*(1.0f - 0.66666666666666666f * f); -- if (k == 0) -- return f - R; -- return k*ln2_hi - ((R-(k*ln2_lo+c))-f); -+ /* reduce u into [sqrt(2)/2, sqrt(2)] */ -+ iu = (iu&0x007fffff) + 0x3f3504f3; -+ u.i = iu; -+ f = u.f - 1; - } - s = f/(2.0f + f); - z = s*s; -- R = z*(Lp1+z*(Lp2+z*(Lp3+z*(Lp4+z*(Lp5+z*(Lp6+z*Lp7)))))); -- if (k == 0) -- return f - (hfsq-s*(hfsq+R)); -- return k*ln2_hi - ((hfsq-(s*(hfsq+R)+(k*ln2_lo+c)))-f); -+ w = z*z; -+ t1= w*(Lg2+w*Lg4); -+ t2= z*(Lg1+w*Lg3); -+ R = t2 + t1; -+ hfsq = 0.5f*f*f; -+ dk = k; -+ return s*(hfsq+R) + (dk*ln2_lo+c) - hfsq + f + dk*ln2_hi; - } -diff --git a/src/math/log1pl.c b/src/math/log1pl.c -index edb48df..37da46d 100644 ---- a/src/math/log1pl.c -+++ b/src/math/log1pl.c -@@ -118,7 +118,7 @@ long double log1pl(long double xm1) - /* Test for domain errors. */ - if (x <= 0.0) { - if (x == 0.0) -- return -1/x; /* -inf with divbyzero */ -+ return -1/(x*x); /* -inf with divbyzero */ - return 0/0.0f; /* nan with invalid */ - } - -diff --git a/src/math/log2.c b/src/math/log2.c -index 1974215..0aafad4 100644 ---- a/src/math/log2.c -+++ b/src/math/log2.c -@@ -10,55 +10,66 @@ - * ==================================================== - */ - /* -- * Return the base 2 logarithm of x. See log.c and __log1p.h for most -- * comments. -+ * Return the base 2 logarithm of x. See log.c for most comments. - * -- * This reduces x to {k, 1+f} exactly as in e_log.c, then calls the kernel, -- * then does the combining and scaling steps -- * log2(x) = (f - 0.5*f*f + k_log1p(f)) / ln2 + k -- * in not-quite-routine extra precision. -+ * Reduce x to 2^k (1+f) and calculate r = log(1+f) - f + f*f/2 -+ * as in log.c, then combine and scale in extra precision: -+ * log2(x) = (f - f*f/2 + r)/log(2) + k - */ - --#include "libm.h" --#include "__log1p.h" -+#include <math.h> -+#include <stdint.h> - - static const double --two54 = 1.80143985094819840000e+16, /* 0x43500000, 0x00000000 */ - ivln2hi = 1.44269504072144627571e+00, /* 0x3ff71547, 0x65200000 */ --ivln2lo = 1.67517131648865118353e-10; /* 0x3de705fc, 0x2eefa200 */ -+ivln2lo = 1.67517131648865118353e-10, /* 0x3de705fc, 0x2eefa200 */ -+Lg1 = 6.666666666666735130e-01, /* 3FE55555 55555593 */ -+Lg2 = 3.999999999940941908e-01, /* 3FD99999 9997FA04 */ -+Lg3 = 2.857142874366239149e-01, /* 3FD24924 94229359 */ -+Lg4 = 2.222219843214978396e-01, /* 3FCC71C5 1D8E78AF */ -+Lg5 = 1.818357216161805012e-01, /* 3FC74664 96CB03DE */ -+Lg6 = 1.531383769920937332e-01, /* 3FC39A09 D078C69F */ -+Lg7 = 1.479819860511658591e-01; /* 3FC2F112 DF3E5244 */ - - double log2(double x) - { -- double f,hfsq,hi,lo,r,val_hi,val_lo,w,y; -- int32_t i,k,hx; -- uint32_t lx; -- -- EXTRACT_WORDS(hx, lx, x); -+ union {double f; uint64_t i;} u = {x}; -+ double_t hfsq,f,s,z,R,w,t1,t2,y,hi,lo,val_hi,val_lo; -+ uint32_t hx; -+ int k; - -+ hx = u.i>>32; - k = 0; -- if (hx < 0x00100000) { /* x < 2**-1022 */ -- if (((hx&0x7fffffff)|lx) == 0) -- return -two54/0.0; /* log(+-0)=-inf */ -- if (hx < 0) -- return (x-x)/0.0; /* log(-#) = NaN */ -- /* subnormal number, scale up x */ -+ if (hx < 0x00100000 || hx>>31) { -+ if (u.i<<1 == 0) -+ return -1/(x*x); /* log(+-0)=-inf */ -+ if (hx>>31) -+ return (x-x)/0.0; /* log(-#) = NaN */ -+ /* subnormal number, scale x up */ - k -= 54; -- x *= two54; -- GET_HIGH_WORD(hx, x); -- } -- if (hx >= 0x7ff00000) -- return x+x; -- if (hx == 0x3ff00000 && lx == 0) -- return 0.0; /* log(1) = +0 */ -- k += (hx>>20) - 1023; -- hx &= 0x000fffff; -- i = (hx+0x95f64) & 0x100000; -- SET_HIGH_WORD(x, hx|(i^0x3ff00000)); /* normalize x or x/2 */ -- k += i>>20; -- y = (double)k; -+ x *= 0x1p54; -+ u.f = x; -+ hx = u.i>>32; -+ } else if (hx >= 0x7ff00000) { -+ return x; -+ } else if (hx == 0x3ff00000 && u.i<<32 == 0) -+ return 0; -+ -+ /* reduce x into [sqrt(2)/2, sqrt(2)] */ -+ hx += 0x3ff00000 - 0x3fe6a09e; -+ k += (int)(hx>>20) - 0x3ff; -+ hx = (hx&0x000fffff) + 0x3fe6a09e; -+ u.i = (uint64_t)hx<<32 | (u.i&0xffffffff); -+ x = u.f; -+ - f = x - 1.0; - hfsq = 0.5*f*f; -- r = __log1p(f); -+ s = f/(2.0+f); -+ z = s*s; -+ w = z*z; -+ t1 = w*(Lg2+w*(Lg4+w*Lg6)); -+ t2 = z*(Lg1+w*(Lg3+w*(Lg5+w*Lg7))); -+ R = t2 + t1; - - /* - * f-hfsq must (for args near 1) be evaluated in extra precision -@@ -90,13 +101,19 @@ double log2(double x) - * The multi-precision calculations for the multiplications are - * routine. - */ -+ -+ /* hi+lo = f - hfsq + s*(hfsq+R) ~ log(1+f) */ - hi = f - hfsq; -- SET_LOW_WORD(hi, 0); -- lo = (f - hi) - hfsq + r; -+ u.f = hi; -+ u.i &= (uint64_t)-1<<32; -+ hi = u.f; -+ lo = f - hi - hfsq + s*(hfsq+R); -+ - val_hi = hi*ivln2hi; - val_lo = (lo+hi)*ivln2lo + lo*ivln2hi; - - /* spadd(val_hi, val_lo, y), except for not using double_t: */ -+ y = k; - w = y + val_hi; - val_lo += (y - w) + val_hi; - val_hi = w; -diff --git a/src/math/log2f.c b/src/math/log2f.c -index e0d6a9e..b3e305f 100644 ---- a/src/math/log2f.c -+++ b/src/math/log2f.c -@@ -13,67 +13,62 @@ - * See comments in log2.c. - */ - --#include "libm.h" --#include "__log1pf.h" -+#include <math.h> -+#include <stdint.h> - - static const float --two25 = 3.3554432000e+07, /* 0x4c000000 */ - ivln2hi = 1.4428710938e+00, /* 0x3fb8b000 */ --ivln2lo = -1.7605285393e-04; /* 0xb9389ad4 */ -+ivln2lo = -1.7605285393e-04, /* 0xb9389ad4 */ -+/* |(log(1+s)-log(1-s))/s - Lg(s)| < 2**-34.24 (~[-4.95e-11, 4.97e-11]). */ -+Lg1 = 0xaaaaaa.0p-24, /* 0.66666662693 */ -+Lg2 = 0xccce13.0p-25, /* 0.40000972152 */ -+Lg3 = 0x91e9ee.0p-25, /* 0.28498786688 */ -+Lg4 = 0xf89e26.0p-26; /* 0.24279078841 */ - - float log2f(float x) - { -- float f,hfsq,hi,lo,r,y; -- int32_t i,k,hx; -- -- GET_FLOAT_WORD(hx, x); -+ union {float f; uint32_t i;} u = {x}; -+ float_t hfsq,f,s,z,R,w,t1,t2,hi,lo; -+ uint32_t ix; -+ int k; - -+ ix = u.i; - k = 0; -- if (hx < 0x00800000) { /* x < 2**-126 */ -- if ((hx&0x7fffffff) == 0) -- return -two25/0.0f; /* log(+-0)=-inf */ -- if (hx < 0) -- return (x-x)/0.0f; /* log(-#) = NaN */ -+ if (ix < 0x00800000 || ix>>31) { /* x < 2**-126 */ -+ if (ix<<1 == 0) -+ return -1/(x*x); /* log(+-0)=-inf */ -+ if (ix>>31) -+ return (x-x)/0.0f; /* log(-#) = NaN */ - /* subnormal number, scale up x */ - k -= 25; -- x *= two25; -- GET_FLOAT_WORD(hx, x); -- } -- if (hx >= 0x7f800000) -- return x+x; -- if (hx == 0x3f800000) -- return 0.0f; /* log(1) = +0 */ -- k += (hx>>23) - 127; -- hx &= 0x007fffff; -- i = (hx+(0x4afb0d))&0x800000; -- SET_FLOAT_WORD(x, hx|(i^0x3f800000)); /* normalize x or x/2 */ -- k += i>>23; -- y = (float)k; -- f = x - 1.0f; -- hfsq = 0.5f * f * f; -- r = __log1pf(f); -+ x *= 0x1p25f; -+ u.f = x; -+ ix = u.i; -+ } else if (ix >= 0x7f800000) { -+ return x; -+ } else if (ix == 0x3f800000) -+ return 0; - -- /* -- * We no longer need to avoid falling into the multi-precision -- * calculations due to compiler bugs breaking Dekker's theorem. -- * Keep avoiding this as an optimization. See log2.c for more -- * details (some details are here only because the optimization -- * is not yet available in double precision). -- * -- * Another compiler bug turned up. With gcc on i386, -- * (ivln2lo + ivln2hi) would be evaluated in float precision -- * despite runtime evaluations using double precision. So we -- * must cast one of its terms to float_t. This makes the whole -- * expression have type float_t, so return is forced to waste -- * time clobbering its extra precision. -- */ --// FIXME --// if (sizeof(float_t) > sizeof(float)) --// return (r - hfsq + f) * ((float_t)ivln2lo + ivln2hi) + y; -+ /* reduce x into [sqrt(2)/2, sqrt(2)] */ -+ ix += 0x3f800000 - 0x3f3504f3; -+ k += (int)(ix>>23) - 0x7f; -+ ix = (ix&0x007fffff) + 0x3f3504f3; -+ u.i = ix; -+ x = u.f; -+ -+ f = x - 1.0f; -+ s = f/(2.0f + f); -+ z = s*s; -+ w = z*z; -+ t1= w*(Lg2+w*Lg4); -+ t2= z*(Lg1+w*Lg3); -+ R = t2 + t1; -+ hfsq = 0.5f*f*f; - - hi = f - hfsq; -- GET_FLOAT_WORD(hx,hi); -- SET_FLOAT_WORD(hi,hx&0xfffff000); -- lo = (f - hi) - hfsq + r; -- return (lo+hi)*ivln2lo + lo*ivln2hi + hi*ivln2hi + y; -+ u.f = hi; -+ u.i &= 0xfffff000; -+ hi = u.f; -+ lo = f - hi - hfsq + s*(hfsq+R); -+ return (lo+hi)*ivln2lo + lo*ivln2hi + hi*ivln2hi + k; - } -diff --git a/src/math/log2l.c b/src/math/log2l.c -index 345b395..d00531d 100644 ---- a/src/math/log2l.c -+++ b/src/math/log2l.c -@@ -117,7 +117,7 @@ long double log2l(long double x) - return x; - if (x <= 0.0) { - if (x == 0.0) -- return -1/(x+0); /* -inf with divbyzero */ -+ return -1/(x*x); /* -inf with divbyzero */ - return 0/0.0f; /* nan with invalid */ - } - -diff --git a/src/math/logf.c b/src/math/logf.c -index c7f7dbe..52230a1 100644 ---- a/src/math/logf.c -+++ b/src/math/logf.c -@@ -13,12 +13,12 @@ - * ==================================================== - */ - --#include "libm.h" -+#include <math.h> -+#include <stdint.h> - - static const float - ln2_hi = 6.9313812256e-01, /* 0x3f317180 */ - ln2_lo = 9.0580006145e-06, /* 0x3717f7d1 */ --two25 = 3.355443200e+07, /* 0x4c000000 */ - /* |(log(1+s)-log(1-s))/s - Lg(s)| < 2**-34.24 (~[-4.95e-11, 4.97e-11]). */ - Lg1 = 0xaaaaaa.0p-24, /* 0.66666662693 */ - Lg2 = 0xccce13.0p-25, /* 0.40000972152 */ -@@ -27,61 +27,43 @@ Lg4 = 0xf89e26.0p-26; /* 0.24279078841 */ - - float logf(float x) - { -- float hfsq,f,s,z,R,w,t1,t2,dk; -- int32_t k,ix,i,j; -- -- GET_FLOAT_WORD(ix, x); -+ union {float f; uint32_t i;} u = {x}; -+ float_t hfsq,f,s,z,R,w,t1,t2,dk; -+ uint32_t ix; -+ int k; - -+ ix = u.i; - k = 0; -- if (ix < 0x00800000) { /* x < 2**-126 */ -- if ((ix & 0x7fffffff) == 0) -- return -two25/0.0f; /* log(+-0)=-inf */ -- if (ix < 0) -- return (x-x)/0.0f; /* log(-#) = NaN */ -+ if (ix < 0x00800000 || ix>>31) { /* x < 2**-126 */ -+ if (ix<<1 == 0) -+ return -1/(x*x); /* log(+-0)=-inf */ -+ if (ix>>31) -+ return (x-x)/0.0f; /* log(-#) = NaN */ - /* subnormal number, scale up x */ - k -= 25; -- x *= two25; -- GET_FLOAT_WORD(ix, x); -- } -- if (ix >= 0x7f800000) -- return x+x; -- k += (ix>>23) - 127; -- ix &= 0x007fffff; -- i = (ix + (0x95f64<<3)) & 0x800000; -- SET_FLOAT_WORD(x, ix|(i^0x3f800000)); /* normalize x or x/2 */ -- k += i>>23; -+ x *= 0x1p25f; -+ u.f = x; -+ ix = u.i; -+ } else if (ix >= 0x7f800000) { -+ return x; -+ } else if (ix == 0x3f800000) -+ return 0; -+ -+ /* reduce x into [sqrt(2)/2, sqrt(2)] */ -+ ix += 0x3f800000 - 0x3f3504f3; -+ k += (int)(ix>>23) - 0x7f; -+ ix = (ix&0x007fffff) + 0x3f3504f3; -+ u.i = ix; -+ x = u.f; -+ - f = x - 1.0f; -- if ((0x007fffff & (0x8000 + ix)) < 0xc000) { /* -2**-9 <= f < 2**-9 */ -- if (f == 0.0f) { -- if (k == 0) -- return 0.0f; -- dk = (float)k; -- return dk*ln2_hi + dk*ln2_lo; -- } -- R = f*f*(0.5f - 0.33333333333333333f*f); -- if (k == 0) -- return f-R; -- dk = (float)k; -- return dk*ln2_hi - ((R-dk*ln2_lo)-f); -- } - s = f/(2.0f + f); -- dk = (float)k; - z = s*s; -- i = ix-(0x6147a<<3); - w = z*z; -- j = (0x6b851<<3)-ix; - t1= w*(Lg2+w*Lg4); - t2= z*(Lg1+w*Lg3); -- i |= j; - R = t2 + t1; -- if (i > 0) { -- hfsq = 0.5f * f * f; -- if (k == 0) -- return f - (hfsq-s*(hfsq+R)); -- return dk*ln2_hi - ((hfsq-(s*(hfsq+R)+dk*ln2_lo))-f); -- } else { -- if (k == 0) -- return f - s*(f-R); -- return dk*ln2_hi - ((s*(f-R)-dk*ln2_lo)-f); -- } -+ hfsq = 0.5f*f*f; -+ dk = k; -+ return s*(hfsq+R) + dk*ln2_lo - hfsq + f + dk*ln2_hi; - } -diff --git a/src/math/logl.c b/src/math/logl.c -index ef2b551..03c5188 100644 ---- a/src/math/logl.c -+++ b/src/math/logl.c -@@ -35,9 +35,9 @@ - * - * log(1+x) = x - 0.5 x**2 + x**3 P(x)/Q(x). - * -- * Otherwise, setting z = 2(x-1)/x+1), -+ * Otherwise, setting z = 2(x-1)/(x+1), - * -- * log(x) = z + z**3 P(z)/Q(z). -+ * log(x) = log(1+z/2) - log(1-z/2) = z + z**3 P(z)/Q(z). - * - * - * ACCURACY: -@@ -116,7 +116,7 @@ long double logl(long double x) - return x; - if (x <= 0.0) { - if (x == 0.0) -- return -1/(x+0); /* -inf with divbyzero */ -+ return -1/(x*x); /* -inf with divbyzero */ - return 0/0.0f; /* nan with invalid */ - } - -@@ -127,7 +127,7 @@ long double logl(long double x) - x = frexpl(x, &e); - - /* logarithm using log(x) = z + z**3 P(z)/Q(z), -- * where z = 2(x-1)/x+1) -+ * where z = 2(x-1)/(x+1) - */ - if (e > 2 || e < -2) { - if (x < SQRTH) { /* 2(2x-1)/(2x+1) */ -diff --git a/src/math/modfl.c b/src/math/modfl.c -index fc85bb5..f736bba 100644 ---- a/src/math/modfl.c -+++ b/src/math/modfl.c -@@ -14,7 +14,6 @@ long double modfl(long double x, long double *iptr) - long double modfl(long double x, long double *iptr) - { - union ldshape u = {x}; -- uint64_t mask; - int e = (u.i.se & 0x7fff) - 0x3fff; - int s = u.i.se >> 15; - long double absx; -diff --git a/src/math/remainder.c b/src/math/remainder.c -index ed5c477..6cd089c 100644 ---- a/src/math/remainder.c -+++ b/src/math/remainder.c -@@ -1,7 +1,10 @@ - #include <math.h> -+#include "libc.h" - - double remainder(double x, double y) - { - int q; - return remquo(x, y, &q); - } -+ -+weak_alias(remainder, drem); -diff --git a/src/math/remainderf.c b/src/math/remainderf.c -index b418bbf..420d3bf 100644 ---- a/src/math/remainderf.c -+++ b/src/math/remainderf.c -@@ -1,7 +1,10 @@ - #include <math.h> -+#include "libc.h" - - float remainderf(float x, float y) - { - int q; - return remquof(x, y, &q); - } -+ -+weak_alias(remainderf, dremf); -diff --git a/src/math/scalb.c b/src/math/scalb.c -index a54bdf2..efe69e6 100644 ---- a/src/math/scalb.c -+++ b/src/math/scalb.c -@@ -15,6 +15,7 @@ - * should use scalbn() instead. - */ - -+#define _GNU_SOURCE - #include <math.h> - - double scalb(double x, double fn) -diff --git a/src/math/scalbf.c b/src/math/scalbf.c -index 9436497..f44ed5b 100644 ---- a/src/math/scalbf.c -+++ b/src/math/scalbf.c -@@ -13,6 +13,7 @@ - * ==================================================== - */ - -+#define _GNU_SOURCE - #include <math.h> - - float scalbf(float x, float fn) -diff --git a/src/math/sincos.c b/src/math/sincos.c -index 49f8a09..35b2d92 100644 ---- a/src/math/sincos.c -+++ b/src/math/sincos.c -@@ -10,6 +10,7 @@ - * ==================================================== - */ - -+#define _GNU_SOURCE - #include "libm.h" - - void sincos(double x, double *sin, double *cos) -diff --git a/src/math/sincosf.c b/src/math/sincosf.c -index 1b50f01..f8ca723 100644 ---- a/src/math/sincosf.c -+++ b/src/math/sincosf.c -@@ -14,6 +14,7 @@ - * ==================================================== - */ - -+#define _GNU_SOURCE - #include "libm.h" - - /* Small multiples of pi/2 rounded to double precision. */ -diff --git a/src/math/tgamma.c b/src/math/tgamma.c -index f91af73..28f6e0f 100644 ---- a/src/math/tgamma.c -+++ b/src/math/tgamma.c -@@ -26,7 +26,7 @@ most ideas and constants are from boost and python - - static const double pi = 3.141592653589793238462643383279502884; - --/* sin(pi x) with x > 0 && isnormal(x) assumption */ -+/* sin(pi x) with x > 0x1p-100, if sin(pi*x)==0 the sign is arbitrary */ - static double sinpi(double x) - { - int n; -@@ -49,8 +49,7 @@ static double sinpi(double x) - case 1: - return __cos(x, 0); - case 2: -- /* sin(0-x) and -sin(x) have different sign at 0 */ -- return __sin(0-x, 0, 0); -+ return __sin(-x, 0, 0); - case 3: - return -__cos(x, 0); - } -@@ -108,35 +107,33 @@ static double S(double x) - - double tgamma(double x) - { -- double absx, y, dy, z, r; -+ union {double f; uint64_t i;} u = {x}; -+ double absx, y; -+ double_t dy, z, r; -+ uint32_t ix = u.i>>32 & 0x7fffffff; -+ int sign = u.i>>63; - - /* special cases */ -- if (!isfinite(x)) -+ if (ix >= 0x7ff00000) - /* tgamma(nan)=nan, tgamma(inf)=inf, tgamma(-inf)=nan with invalid */ - return x + INFINITY; -+ if (ix < (0x3ff-54)<<20) -+ /* |x| < 2^-54: tgamma(x) ~ 1/x, +-0 raises div-by-zero */ -+ return 1/x; - - /* integer arguments */ - /* raise inexact when non-integer */ - if (x == floor(x)) { -- if (x == 0) -- /* tgamma(+-0)=+-inf with divide-by-zero */ -- return 1/x; -- if (x < 0) -+ if (sign) - return 0/0.0; - if (x <= sizeof fact/sizeof *fact) - return fact[(int)x - 1]; - } - -- absx = fabs(x); -- -- /* x ~ 0: tgamma(x) ~ 1/x */ -- if (absx < 0x1p-54) -- return 1/x; -- - /* x >= 172: tgamma(x)=inf with overflow */ - /* x =< -184: tgamma(x)=+-0 with underflow */ -- if (absx >= 184) { -- if (x < 0) { -+ if (ix >= 0x40670000) { /* |x| >= 184 */ -+ if (sign) { - FORCE_EVAL((float)(0x1p-126/x)); - if (floor(x) * 0.5 == floor(x * 0.5)) - return 0; -@@ -146,6 +143,8 @@ double tgamma(double x) - return x; - } - -+ absx = sign ? -x : x; -+ - /* handle the error of x + g - 0.5 */ - y = absx + gmhalf; - if (absx > gmhalf) { -@@ -160,20 +159,21 @@ double tgamma(double x) - r = S(absx) * exp(-y); - if (x < 0) { - /* reflection formula for negative x */ -+ /* sinpi(absx) is not 0, integers are already handled */ - r = -pi / (sinpi(absx) * absx * r); - dy = -dy; - z = -z; - } - r += dy * (gmhalf+0.5) * r / y; - z = pow(y, 0.5*z); -- r = r * z * z; -- return r; -+ y = r * z * z; -+ return y; - } - - #if 0 - double __lgamma_r(double x, int *sign) - { -- double r, absx, z, zz, w; -+ double r, absx; - - *sign = 1; - -diff --git a/src/misc/get_current_dir_name.c b/src/misc/get_current_dir_name.c -index e0f463b..782cddc 100644 ---- a/src/misc/get_current_dir_name.c -+++ b/src/misc/get_current_dir_name.c -@@ -1,3 +1,4 @@ -+#define _GNU_SOURCE - #include <stdlib.h> - #include <string.h> - #include <limits.h> -@@ -6,11 +7,9 @@ - - char *get_current_dir_name(void) { - struct stat a, b; -- char buf[PATH_MAX]; - char *res = getenv("PWD"); - if (res && *res && !stat(res, &a) && !stat(".", &b) - && (a.st_dev == b.st_dev) && (a.st_ino == b.st_ino)) - return strdup(res); -- if(!getcwd(buf, sizeof(buf))) return NULL; -- return strdup(buf); -+ return getcwd(0, 0); - } -diff --git a/src/misc/getgrouplist.c b/src/misc/getgrouplist.c -index 63557af..c9a8f09 100644 ---- a/src/misc/getgrouplist.c -+++ b/src/misc/getgrouplist.c -@@ -1,3 +1,4 @@ -+#define _GNU_SOURCE - #include <grp.h> - #include <string.h> - #include <limits.h> -diff --git a/src/misc/getrusage.c b/src/misc/getrusage.c -index a5cbd75..0aaf0ac 100644 ---- a/src/misc/getrusage.c -+++ b/src/misc/getrusage.c -@@ -1,5 +1,4 @@ - #include <sys/resource.h> --#include <string.h> - #include "syscall.h" - - int getrusage(int who, struct rusage *ru) -diff --git a/src/misc/initgroups.c b/src/misc/initgroups.c -index 545d185..922a958 100644 ---- a/src/misc/initgroups.c -+++ b/src/misc/initgroups.c -@@ -1,11 +1,7 @@ --#include <sys/types.h> --#include <unistd.h> -+#define _GNU_SOURCE - #include <grp.h> - #include <limits.h> - --int getgrouplist(const char *, gid_t, gid_t *, int *); --int setgroups(size_t, const gid_t *); -- - int initgroups(const char *user, gid_t gid) - { - gid_t groups[NGROUPS_MAX]; -diff --git a/src/misc/nftw.c b/src/misc/nftw.c -index 63d6aff..b2e84bc 100644 ---- a/src/misc/nftw.c -+++ b/src/misc/nftw.c -@@ -2,8 +2,6 @@ - #include <dirent.h> - #include <sys/stat.h> - #include <errno.h> --#include <stdlib.h> --#include <fcntl.h> - #include <unistd.h> - #include <string.h> - #include <limits.h> -diff --git a/src/misc/syslog.c b/src/misc/syslog.c -index ba9cc62..1cd61ce 100644 ---- a/src/misc/syslog.c -+++ b/src/misc/syslog.c -@@ -1,7 +1,6 @@ - #include <stdarg.h> - #include <sys/socket.h> - #include <stdio.h> --#include <fcntl.h> - #include <unistd.h> - #include <syslog.h> - #include <time.h> -diff --git a/src/misc/uname.c b/src/misc/uname.c -index 46db90d..55ea342 100644 ---- a/src/misc/uname.c -+++ b/src/misc/uname.c -@@ -1,5 +1,4 @@ - #include <sys/utsname.h> --#include <string.h> - #include "syscall.h" - - int uname(struct utsname *uts) -diff --git a/src/misc/wordexp.c b/src/misc/wordexp.c -index 617706e..a5f1b65 100644 ---- a/src/misc/wordexp.c -+++ b/src/misc/wordexp.c -@@ -7,7 +7,21 @@ - #include <stdlib.h> - #include <sys/wait.h> - #include <signal.h> --#include <pthread.h> -+#include <errno.h> -+#include <fcntl.h> -+#include "pthread_impl.h" -+ -+static void reap(pid_t pid) -+{ -+ int status; -+ for (;;) { -+ if (waitpid(pid, &status, 0) < 0) { -+ if (errno != EINTR) return; -+ } else { -+ if (WIFEXITED(status)) return; -+ } -+ } -+} - - static char *getword(FILE *f) - { -@@ -22,12 +36,13 @@ static int do_wordexp(const char *s, wordexp_t *we, int flags) - size_t np=0; - char *w, **tmp; - char *redir = (flags & WRDE_SHOWERR) ? "" : "2>/dev/null"; -- int err = 0, status; -+ int err = 0; - FILE *f; - size_t wc = 0; - char **wv = 0; - int p[2]; - pid_t pid; -+ sigset_t set; - - if (flags & WRDE_REUSE) wordfree(we); - -@@ -80,25 +95,26 @@ static int do_wordexp(const char *s, wordexp_t *we, int flags) - i = wc; - if (flags & WRDE_DOOFFS) { - if (we->we_offs > SIZE_MAX/sizeof(void *)/4) -- return WRDE_NOSPACE; -+ goto nospace; - i += we->we_offs; - } else { - we->we_offs = 0; - } - -- if (pipe(p) < 0) return WRDE_NOSPACE; -+ if (pipe2(p, O_CLOEXEC) < 0) goto nospace; -+ __block_all_sigs(&set); - pid = fork(); -+ __restore_sigs(&set); - if (pid < 0) { - close(p[0]); - close(p[1]); -- return WRDE_NOSPACE; -+ goto nospace; - } - if (!pid) { -- dup2(p[1], 1); -- close(p[0]); -- close(p[1]); -+ if (p[1] == 1) fcntl(1, F_SETFD, 0); -+ else dup2(p[1], 1); - execl("/bin/sh", "sh", "-c", -- "eval \"printf %s\\\\\\\\0 $1 $2\"", -+ "eval \"printf %s\\\\\\\\0 x $1 $2\"", - "sh", s, redir, (char *)0); - _exit(1); - } -@@ -108,12 +124,19 @@ static int do_wordexp(const char *s, wordexp_t *we, int flags) - if (!f) { - close(p[0]); - kill(pid, SIGKILL); -- waitpid(pid, &status, 0); -- return WRDE_NOSPACE; -+ reap(pid); -+ goto nospace; - } - - l = wv ? i+1 : 0; - -+ free(getword(f)); -+ if (feof(f)) { -+ fclose(f); -+ reap(pid); -+ return WRDE_SYNTAX; -+ } -+ - while ((w = getword(f))) { - if (i+1 >= l) { - l += l/2+10; -@@ -127,24 +150,26 @@ static int do_wordexp(const char *s, wordexp_t *we, int flags) - if (!feof(f)) err = WRDE_NOSPACE; - - fclose(f); -- waitpid(pid, &status, 0); -- if (WEXITSTATUS(status)) { -- if (!(flags & WRDE_APPEND)) { -- free(wv); -- return WRDE_SYNTAX; -- } else if (wv==we->we_wordv) { -- return WRDE_SYNTAX; -- } -- } -+ reap(pid); -+ -+ if (!wv) wv = calloc(i+1, sizeof *wv); - - we->we_wordv = wv; - we->we_wordc = i; - -- for (i=we->we_offs; i; i--) -- we->we_wordv[i-1] = 0; -- -- if (flags & WRDE_DOOFFS) we->we_wordc -= we->we_offs; -+ if (flags & WRDE_DOOFFS) { -+ if (wv) for (i=we->we_offs; i; i--) -+ we->we_wordv[i-1] = 0; -+ we->we_wordc -= we->we_offs; -+ } - return err; -+ -+nospace: -+ if (!(flags & WRDE_APPEND)) { -+ we->we_wordc = 0; -+ we->we_wordv = 0; -+ } -+ return WRDE_NOSPACE; - } - - int wordexp(const char *restrict s, wordexp_t *restrict we, int flags) -diff --git a/src/mman/msync.c b/src/mman/msync.c -index eaf35d3..bb20475 100644 ---- a/src/mman/msync.c -+++ b/src/mman/msync.c -@@ -1,4 +1,3 @@ --#include <unistd.h> - #include <sys/mman.h> - #include "syscall.h" - -diff --git a/src/mman/munmap.c b/src/mman/munmap.c -index 91aefd4..8488d75 100644 ---- a/src/mman/munmap.c -+++ b/src/mman/munmap.c -@@ -1,4 +1,3 @@ --#include <unistd.h> - #include <sys/mman.h> - #include "syscall.h" - #include "libc.h" -diff --git a/src/multibyte/internal.c b/src/multibyte/internal.c -index ab22806..1813b26 100644 ---- a/src/multibyte/internal.c -+++ b/src/multibyte/internal.c -@@ -4,8 +4,6 @@ - * unnecessary. - */ - --#include <inttypes.h> -- - #include "internal.h" - - #define C(x) ( x<2 ? -1 : ( R(0x80,0xc0) | x ) ) -diff --git a/src/multibyte/internal.h b/src/multibyte/internal.h -index 25ba240..82f5a07 100644 ---- a/src/multibyte/internal.h -+++ b/src/multibyte/internal.h -@@ -6,6 +6,7 @@ - - #define bittab __fsmu8 - -+#include <stdint.h> - #include "libc.h" - - extern const uint32_t bittab[] ATTR_LIBC_VISIBILITY; -diff --git a/src/multibyte/mblen.c b/src/multibyte/mblen.c -index 26d3564..96b47b1 100644 ---- a/src/multibyte/mblen.c -+++ b/src/multibyte/mblen.c -@@ -5,11 +5,6 @@ - */ - - #include <stdlib.h> --#include <inttypes.h> --#include <wchar.h> --#include <errno.h> -- --#include "internal.h" - - int mblen(const char *s, size_t n) - { -diff --git a/src/multibyte/mbrlen.c b/src/multibyte/mbrlen.c -index c9714ef..3a5a743 100644 ---- a/src/multibyte/mbrlen.c -+++ b/src/multibyte/mbrlen.c -@@ -4,12 +4,7 @@ - * unnecessary. - */ - --#include <stdlib.h> --#include <inttypes.h> - #include <wchar.h> --#include <errno.h> -- --#include "internal.h" - - size_t mbrlen(const char *restrict s, size_t n, mbstate_t *restrict st) - { -diff --git a/src/multibyte/mbrtowc.c b/src/multibyte/mbrtowc.c -index db80366..35e834e 100644 ---- a/src/multibyte/mbrtowc.c -+++ b/src/multibyte/mbrtowc.c -@@ -4,11 +4,8 @@ - * unnecessary. - */ - --#include <stdlib.h> --#include <inttypes.h> - #include <wchar.h> - #include <errno.h> -- - #include "internal.h" - - size_t mbrtowc(wchar_t *restrict wc, const char *restrict src, size_t n, mbstate_t *restrict st) -diff --git a/src/multibyte/mbsinit.c b/src/multibyte/mbsinit.c -index c0e7e49..e001d84 100644 ---- a/src/multibyte/mbsinit.c -+++ b/src/multibyte/mbsinit.c -@@ -4,12 +4,7 @@ - * unnecessary. - */ - --#include <stdlib.h> --#include <inttypes.h> - #include <wchar.h> --#include <errno.h> -- --#include "internal.h" - - int mbsinit(const mbstate_t *st) - { -diff --git a/src/multibyte/mbsnrtowcs.c b/src/multibyte/mbsnrtowcs.c -index 33457f9..68b9960 100644 ---- a/src/multibyte/mbsnrtowcs.c -+++ b/src/multibyte/mbsnrtowcs.c -@@ -4,13 +4,7 @@ - * unnecessary. - */ - --#include <stdlib.h> --#include <inttypes.h> - #include <wchar.h> --#include <errno.h> --#include <stdio.h> -- --#include "internal.h" - - size_t mbsnrtowcs(wchar_t *restrict wcs, const char **restrict src, size_t n, size_t wn, mbstate_t *restrict st) - { -diff --git a/src/multibyte/mbsrtowcs.c b/src/multibyte/mbsrtowcs.c -index b9bbc33..3c1343a 100644 ---- a/src/multibyte/mbsrtowcs.c -+++ b/src/multibyte/mbsrtowcs.c -@@ -4,11 +4,9 @@ - * unnecessary. - */ - --#include <stdlib.h> --#include <inttypes.h> -+#include <stdint.h> - #include <wchar.h> - #include <errno.h> -- - #include "internal.h" - - size_t mbsrtowcs(wchar_t *restrict ws, const char **restrict src, size_t wn, mbstate_t *restrict st) -@@ -59,7 +57,7 @@ resume0: - return wn0; - } - if (*s-1u < 0x7f && (uintptr_t)s%4 == 0) { -- while (wn>=4 && !(( *(uint32_t*)s | *(uint32_t*)s-0x01010101) & 0x80808080)) { -+ while (wn>=5 && !(( *(uint32_t*)s | *(uint32_t*)s-0x01010101) & 0x80808080)) { - *ws++ = *s++; - *ws++ = *s++; - *ws++ = *s++; -diff --git a/src/multibyte/mbtowc.c b/src/multibyte/mbtowc.c -index ec9e54a..6710637 100644 ---- a/src/multibyte/mbtowc.c -+++ b/src/multibyte/mbtowc.c -@@ -4,13 +4,10 @@ - * unnecessary. - */ - --#include <stdlib.h> --#include <inttypes.h> - #include <wchar.h> - #include <errno.h> -- - #include "internal.h" --#include <stdio.h> -+ - int mbtowc(wchar_t *restrict wc, const char *restrict src, size_t n) - { - unsigned c; -diff --git a/src/multibyte/wcrtomb.c b/src/multibyte/wcrtomb.c -index 250649f..59f733d 100644 ---- a/src/multibyte/wcrtomb.c -+++ b/src/multibyte/wcrtomb.c -@@ -4,13 +4,9 @@ - * unnecessary. - */ - --#include <stdlib.h> --#include <inttypes.h> - #include <wchar.h> - #include <errno.h> - --#include "internal.h" -- - size_t wcrtomb(char *restrict s, wchar_t wc, mbstate_t *restrict st) - { - if (!s) return 1; -diff --git a/src/multibyte/wcsnrtombs.c b/src/multibyte/wcsnrtombs.c -index a2e308b..7eb05d4 100644 ---- a/src/multibyte/wcsnrtombs.c -+++ b/src/multibyte/wcsnrtombs.c -@@ -4,12 +4,7 @@ - * unnecessary. - */ - --#include <stdlib.h> --#include <inttypes.h> - #include <wchar.h> --#include <errno.h> -- --#include "internal.h" - - size_t wcsnrtombs(char *restrict dst, const wchar_t **restrict wcs, size_t wn, size_t n, mbstate_t *restrict st) - { -diff --git a/src/multibyte/wcsrtombs.c b/src/multibyte/wcsrtombs.c -index d48a65e..5cf8f3e 100644 ---- a/src/multibyte/wcsrtombs.c -+++ b/src/multibyte/wcsrtombs.c -@@ -4,12 +4,7 @@ - * unnecessary. - */ - --#include <stdlib.h> --#include <inttypes.h> - #include <wchar.h> --#include <errno.h> -- --#include "internal.h" - - size_t wcsrtombs(char *restrict s, const wchar_t **restrict ws, size_t n, mbstate_t *restrict st) - { -diff --git a/src/multibyte/wctomb.c b/src/multibyte/wctomb.c -index 6910ef3..de7ed84 100644 ---- a/src/multibyte/wctomb.c -+++ b/src/multibyte/wctomb.c -@@ -5,11 +5,7 @@ - */ - - #include <stdlib.h> --#include <inttypes.h> - #include <wchar.h> --#include <errno.h> -- --#include "internal.h" - - int wctomb(char *s, wchar_t wc) - { -diff --git a/src/network/__dns.c b/src/network/__dns.c -index 8f3c637..97d8031 100644 ---- a/src/network/__dns.c -+++ b/src/network/__dns.c -@@ -11,6 +11,7 @@ - #include <ctype.h> - #include <unistd.h> - #include <pthread.h> -+#include <errno.h> - #include "__dns.h" - #include "stdio_impl.h" - -@@ -35,9 +36,9 @@ int __dns_doqueries(unsigned char *dest, const char *name, int *rr, int rrcnt) - struct sockaddr_in sin; - struct sockaddr_in6 sin6; - } sa = {0}, ns[3] = {{0}}; -- socklen_t sl; -+ socklen_t sl = sizeof sa.sin; - int nns = 0; -- int family = AF_UNSPEC; -+ int family = AF_INET; - unsigned char q[280] = "", *r = dest; - int ql; - int rlen; -@@ -75,10 +76,12 @@ int __dns_doqueries(unsigned char *dest, const char *name, int *rr, int rrcnt) - for (s=line+11; isspace(*s); s++); - for (z=s; *z && !isspace(*z); z++); - *z=0; -- if (__ipparse(ns+nns, family, s) < 0) continue; -+ if (__ipparse(ns+nns, AF_UNSPEC, s) < 0) continue; - ns[nns].sin.sin_port = htons(53); -- family = ns[nns++].sin.sin_family; -- sl = family==AF_INET6 ? sizeof sa.sin6 : sizeof sa.sin; -+ if (ns[nns++].sin.sin_family == AF_INET6) { -+ family = AF_INET6; -+ sl = sizeof sa.sin6; -+ } - } - if (f) __fclose_ca(f); - if (!nns) { -@@ -93,6 +96,29 @@ int __dns_doqueries(unsigned char *dest, const char *name, int *rr, int rrcnt) - sa.sin.sin_family = family; - fd = socket(family, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0); - -+ /* Handle case where system lacks IPv6 support */ -+ if (fd < 0 && errno == EAFNOSUPPORT) { -+ if (family != AF_INET6) return EAI_SYSTEM; -+ fd = socket(AF_INET, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0); -+ family = AF_INET; -+ } -+ if (fd < 0) return EAI_SYSTEM; -+ -+ /* Convert any IPv4 addresses in a mixed environment to v4-mapped */ -+ if (family == AF_INET6) { -+ setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &(int){0}, sizeof 0); -+ for (i=0; i<nns; i++) { -+ if (ns[i].sin.sin_family != AF_INET) continue; -+ memcpy(ns[i].sin6.sin6_addr.s6_addr+12, -+ &ns[i].sin.sin_addr, 4); -+ memcpy(ns[i].sin6.sin6_addr.s6_addr, -+ "\0\0\0\0\0\0\0\0\0\0\xff\xff", 12); -+ ns[i].sin6.sin6_family = AF_INET6; -+ ns[i].sin6.sin6_flowinfo = 0; -+ ns[i].sin6.sin6_scope_id = 0; -+ } -+ } -+ - pthread_cleanup_push(cleanup, (void *)(intptr_t)fd); - pthread_setcancelstate(cs, 0); - -diff --git a/src/network/__ipparse.c b/src/network/__ipparse.c -index b0647aa..79f3b8c 100644 ---- a/src/network/__ipparse.c -+++ b/src/network/__ipparse.c -@@ -1,27 +1,30 @@ --#include <string.h> - #include <stdlib.h> -+#include <ctype.h> - #include <sys/socket.h> - #include <netinet/in.h> - #include <arpa/inet.h> - #include "__dns.h" --#include <stdio.h> - - int __ipparse(void *dest, int family, const char *s0) - { - const char *s = s0; - unsigned char *d = dest; - unsigned long a[16] = { 0 }; -- const char *z; -+ char *z; - int i; - - if (family == AF_INET6) goto not_v4; - - for (i=0; i<4; i++) { -- a[i] = strtoul(s, (char **)&z, 0); -- if (z==s || (*z && *z != '.')) goto not_v4; -+ a[i] = strtoul(s, &z, 0); -+ if (z==s || (*z && *z != '.') || !isdigit(*s)) { -+ if (family == AF_INET) return -1; -+ goto not_v4; -+ } - if (!*z) break; - s=z+1; - } -+ if (i==4) return -1; - switch (i) { - case 0: - a[1] = a[0] & 0xffffff; -@@ -35,7 +38,10 @@ int __ipparse(void *dest, int family, const char *s0) - } - ((struct sockaddr_in *)d)->sin_family = AF_INET; - d = (void *)&((struct sockaddr_in *)d)->sin_addr; -- for (i=0; i<4; i++) d[i] = a[i]; -+ for (i=0; i<4; i++) { -+ if (a[i] > 255) return -1; -+ d[i] = a[i]; -+ } - return 0; - - not_v4: -diff --git a/src/network/dn_comp.c b/src/network/dn_comp.c -new file mode 100644 -index 0000000..4f4452a ---- /dev/null -+++ b/src/network/dn_comp.c -@@ -0,0 +1,9 @@ -+#include <resolv.h> -+#include "libc.h" -+ -+int __dn_comp(const char *src, unsigned char *dst, int space, unsigned char **dnptrs, unsigned char **lastdnptr) -+{ -+ return -1; -+} -+ -+weak_alias(__dn_comp, dn_comp); -diff --git a/src/network/dn_expand.c b/src/network/dn_expand.c -index 4e02e3d..96adf37 100644 ---- a/src/network/dn_expand.c -+++ b/src/network/dn_expand.c -@@ -10,7 +10,7 @@ int __dn_expand(const unsigned char *base, const unsigned char *end, const unsig - for (;;) { - if (*p & 0xc0) { - if (p+1==end) return -1; -- j = (p[0]&1) | p[1]; -+ j = ((p[0] & 0x3f) << 8) | p[1]; - if (len < 0) len = p+2-src; - if (j >= end-base) return -1; - p = base+j; -diff --git a/src/network/getaddrinfo.c b/src/network/getaddrinfo.c -index 4c1fe27..5d45be7 100644 ---- a/src/network/getaddrinfo.c -+++ b/src/network/getaddrinfo.c -@@ -31,9 +31,6 @@ static int have_af(int family) - } - #endif - --#include <stdlib.h> --#include <netdb.h> -- - union sa { - struct sockaddr_in sin; - struct sockaddr_in6 sin6; -@@ -65,6 +62,9 @@ int getaddrinfo(const char *restrict host, const char *restrict serv, const stru - int result; - int cnt; - -+ if (family != AF_INET && family != AF_INET6 && family != AF_UNSPEC) -+ return EAI_FAMILY; -+ - if (host && strlen(host)>255) return EAI_NONAME; - if (serv && strlen(serv)>32) return EAI_SERVICE; - -diff --git a/src/network/gethostbyaddr.c b/src/network/gethostbyaddr.c -index c9b6388..598e224 100644 ---- a/src/network/gethostbyaddr.c -+++ b/src/network/gethostbyaddr.c -@@ -1,8 +1,6 @@ - #define _GNU_SOURCE - - #include <netdb.h> --#include <string.h> --#include <netinet/in.h> - #include <errno.h> - #include <stdlib.h> - -diff --git a/src/network/gethostbyname2.c b/src/network/gethostbyname2.c -index c9f90da..dc9d662 100644 ---- a/src/network/gethostbyname2.c -+++ b/src/network/gethostbyname2.c -@@ -2,8 +2,6 @@ - - #include <sys/socket.h> - #include <netdb.h> --#include <string.h> --#include <netinet/in.h> - #include <errno.h> - #include <stdlib.h> - -diff --git a/src/network/gethostbyname2_r.c b/src/network/gethostbyname2_r.c -index 0dc6dc0..27eb080 100644 ---- a/src/network/gethostbyname2_r.c -+++ b/src/network/gethostbyname2_r.c -@@ -5,7 +5,7 @@ - #include <string.h> - #include <netinet/in.h> - #include <errno.h> --#include <inttypes.h> -+#include <stdint.h> - - int gethostbyname2_r(const char *name, int af, - struct hostent *h, char *buf, size_t buflen, -diff --git a/src/network/getifaddrs.c b/src/network/getifaddrs.c -index a14ac1b..5a94cc7 100644 ---- a/src/network/getifaddrs.c -+++ b/src/network/getifaddrs.c -@@ -11,6 +11,7 @@ - #include <arpa/inet.h> /* inet_pton */ - #include <unistd.h> - #include <sys/ioctl.h> -+#include <sys/socket.h> - - typedef union { - struct sockaddr_in6 v6; -@@ -66,7 +67,7 @@ static void ipv6netmask(unsigned prefix_length, struct sockaddr_in6 *sa) - - static void dealwithipv6(stor **list, stor** head) - { -- FILE* f = fopen("/proc/net/if_inet6", "r"); -+ FILE* f = fopen("/proc/net/if_inet6", "rbe"); - /* 00000000000000000000000000000001 01 80 10 80 lo - A B C D E F - all numbers in hex -diff --git a/src/network/getnameinfo.c b/src/network/getnameinfo.c -index 3d115c7..33f89a3 100644 ---- a/src/network/getnameinfo.c -+++ b/src/network/getnameinfo.c -@@ -1,6 +1,5 @@ - #include <netdb.h> - #include <limits.h> --#include <stdlib.h> - #include <string.h> - #include <stdio.h> - #include <sys/socket.h> -diff --git a/src/network/if_nameindex.c b/src/network/if_nameindex.c -index ad0a766..53b80b2 100644 ---- a/src/network/if_nameindex.c -+++ b/src/network/if_nameindex.c -@@ -6,8 +6,6 @@ - #include <errno.h> - #include "syscall.h" - --#include <stdio.h> -- - static void *do_nameindex(int s, size_t n) - { - size_t i, len, k; -diff --git a/src/network/inet_addr.c b/src/network/inet_addr.c -new file mode 100644 -index 0000000..ea0a8f7 ---- /dev/null -+++ b/src/network/inet_addr.c -@@ -0,0 +1,11 @@ -+#include <sys/socket.h> -+#include <netinet/in.h> -+#include <arpa/inet.h> -+#include "__dns.h" -+ -+in_addr_t inet_addr(const char *p) -+{ -+ struct sockaddr_in sin; -+ if (__ipparse(&sin, AF_INET, p) < 0) return -1; -+ return sin.sin_addr.s_addr; -+} -diff --git a/src/network/inet_legacy.c b/src/network/inet_legacy.c -index e802557..0a0ad6f 100644 ---- a/src/network/inet_legacy.c -+++ b/src/network/inet_legacy.c -@@ -1,16 +1,8 @@ - #include <sys/socket.h> - #include <netinet/in.h> - #include <arpa/inet.h> --#include <stdio.h> - #include "__dns.h" - --in_addr_t inet_addr(const char *p) --{ -- struct sockaddr_in sin; -- if (__ipparse(&sin, AF_INET, p)) return -1; -- return sin.sin_addr.s_addr; --} -- - in_addr_t inet_network(const char *p) - { - return ntohl(inet_addr(p)); -@@ -18,15 +10,10 @@ in_addr_t inet_network(const char *p) - - int inet_aton(const char *cp, struct in_addr *inp) - { -- return inet_pton(AF_INET, cp, (void *)inp) > 0; --} -- --char *inet_ntoa(struct in_addr in) --{ -- static char buf[16]; -- unsigned char *a = (void *)∈ -- snprintf(buf, sizeof buf, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]); -- return buf; -+ struct sockaddr_in sin; -+ if (__ipparse(&sin, AF_INET, cp) < 0) return 0; -+ *inp = sin.sin_addr; -+ return 1; - } - - struct in_addr inet_makeaddr(int net, int host) -diff --git a/src/network/inet_ntoa.c b/src/network/inet_ntoa.c -new file mode 100644 -index 0000000..71411e0 ---- /dev/null -+++ b/src/network/inet_ntoa.c -@@ -0,0 +1,10 @@ -+#include <arpa/inet.h> -+#include <stdio.h> -+ -+char *inet_ntoa(struct in_addr in) -+{ -+ static char buf[16]; -+ unsigned char *a = (void *)∈ -+ snprintf(buf, sizeof buf, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]); -+ return buf; -+} -diff --git a/src/network/inet_ntop.c b/src/network/inet_ntop.c -index ca33343..14f9f4c 100644 ---- a/src/network/inet_ntop.c -+++ b/src/network/inet_ntop.c -@@ -1,7 +1,5 @@ - #include <sys/socket.h> --#include <netinet/in.h> - #include <arpa/inet.h> --#include <netdb.h> - #include <errno.h> - #include <stdio.h> - #include <string.h> -diff --git a/src/network/inet_pton.c b/src/network/inet_pton.c -index 5c4850a..4496b47 100644 ---- a/src/network/inet_pton.c -+++ b/src/network/inet_pton.c -@@ -1,7 +1,5 @@ - #include <sys/socket.h> --#include <netdb.h> - #include <arpa/inet.h> --#include <stdlib.h> - #include <ctype.h> - #include <errno.h> - #include <string.h> -@@ -18,52 +16,46 @@ int inet_pton(int af, const char *restrict s, void *restrict a0) - { - uint16_t ip[8]; - unsigned char *a = a0; -- const char *z; -- unsigned long x; - int i, j, v, d, brk=-1, need_v4=0; - -- /* Reimplement this because inet_pton cannot accept special v4 forms */ - if (af==AF_INET) { -- for (i=0; i<4 && *s; i++) { -- a[i] = x = strtoul(s, (char **)&z, 10); -- if (!isdigit(*s) || z==s || (*z && *z != '.') || x>255) -- return 0; -- s=z+1; -+ for (i=0; i<4; i++) { -+ for (v=j=0; j<3 && isdigit(s[j]); j++) -+ v = 10*v + s[j]-'0'; -+ if (j==0 || (j>1 && s[0]=='0') || v>255) return 0; -+ a[i] = v; -+ if (s[j]==0 && i==3) return 1; -+ if (s[j]!='.') return 0; -+ s += j+1; - } -- return 1; -+ return 0; - } else if (af!=AF_INET6) { - errno = EAFNOSUPPORT; - return -1; - } - -- if (s[0]==':' && s[1]==':') s++; -+ if (*s==':' && *++s!=':') return 0; - -- for (i=0; ; i++, s+=j+1) { -+ for (i=0; ; i++) { - if (s[0]==':' && brk<0) { - brk=i; -- j=0; - ip[i]=0; -- if (!s[1]) break; -+ if (!*++s) break; - continue; - } -- if (hexval(s[0])<0) return -1; -- while (s[0]=='0' && s[1]=='0') s++; -- for (v=j=0; j<5 && (d=hexval(s[j]))>=0; j++) -+ for (v=j=0; j<4 && (d=hexval(s[j]))>=0; j++) - v=16*v+d; -- if (v > 65535) return -1; -+ if (j==0) return 0; - ip[i] = v; -- if (!s[j]) { -- if (brk<0 && i!=7) return -1; -- break; -- } -- if (i<7) { -- if (s[j]==':') continue; -- if (s[j]!='.') return -1; -+ if (!s[j] && (brk>=0 || i==7)) break; -+ if (i==7) return 0; -+ if (s[j]!=':') { -+ if (s[j]!='.' || (i<6 && brk<0)) return 0; - need_v4=1; - i++; - break; - } -- return -1; -+ s += j+1; - } - if (brk>=0) { - memmove(ip+brk+7-i, ip+brk, 2*(i+1-brk)); -@@ -73,6 +65,6 @@ int inet_pton(int af, const char *restrict s, void *restrict a0) - *a++ = ip[j]>>8; - *a++ = ip[j]; - } -- if (need_v4 &&inet_pton(AF_INET, (void *)s, a-4) <= 0) return -1; -+ if (need_v4 && inet_pton(AF_INET, (void *)s, a-4) <= 0) return 0; - return 1; - } -diff --git a/src/network/proto.c b/src/network/proto.c -index 8c25c53..031003a 100644 ---- a/src/network/proto.c -+++ b/src/network/proto.c -@@ -1,5 +1,4 @@ - #include <netdb.h> --#include <stdio.h> - #include <string.h> - - /* do we really need all these?? */ -diff --git a/src/network/recv.c b/src/network/recv.c -index d04a54a..5970048 100644 ---- a/src/network/recv.c -+++ b/src/network/recv.c -@@ -1,6 +1,4 @@ - #include <sys/socket.h> --#include "syscall.h" --#include "libc.h" - - ssize_t recv(int fd, void *buf, size_t len, int flags) - { -diff --git a/src/network/res_query.c b/src/network/res_query.c -index c3ad109..3847da3 100644 ---- a/src/network/res_query.c -+++ b/src/network/res_query.c -@@ -1,4 +1,5 @@ - #define _GNU_SOURCE -+#include <resolv.h> - #include <netdb.h> - #include "__dns.h" - #include "libc.h" -diff --git a/src/network/send.c b/src/network/send.c -index b6ec310..9f10497 100644 ---- a/src/network/send.c -+++ b/src/network/send.c -@@ -1,6 +1,4 @@ - #include <sys/socket.h> --#include "syscall.h" --#include "libc.h" - - ssize_t send(int fd, const void *buf, size_t len, int flags) - { -diff --git a/src/network/serv.c b/src/network/serv.c -index 5ade6ad..41424e8 100644 ---- a/src/network/serv.c -+++ b/src/network/serv.c -@@ -1,6 +1,4 @@ - #include <netdb.h> --#include <stdio.h> --#include <string.h> - - void endservent(void) - { -diff --git a/src/passwd/fgetgrent.c b/src/passwd/fgetgrent.c -index 2f18d92..d8d1c77 100644 ---- a/src/passwd/fgetgrent.c -+++ b/src/passwd/fgetgrent.c -@@ -1,3 +1,4 @@ -+#define _GNU_SOURCE - #include "pwf.h" - - struct group *fgetgrent(FILE *f) -diff --git a/src/passwd/fgetpwent.c b/src/passwd/fgetpwent.c -index e95fdb2..eb47b2a 100644 ---- a/src/passwd/fgetpwent.c -+++ b/src/passwd/fgetpwent.c -@@ -1,3 +1,4 @@ -+#define _GNU_SOURCE - #include "pwf.h" - - struct passwd *fgetpwent(FILE *f) -diff --git a/src/passwd/fgetspent.c b/src/passwd/fgetspent.c -index a9a3c97..47473bd 100644 ---- a/src/passwd/fgetspent.c -+++ b/src/passwd/fgetspent.c -@@ -1,11 +1,15 @@ - #include "pwf.h" -+#include <pthread.h> - - struct spwd *fgetspent(FILE *f) - { -- return 0; --} -- --int putspent(const struct spwd *sp, FILE *f) --{ -- return -1; -+ static char *line; -+ static struct spwd sp; -+ size_t size = 0; -+ struct spwd *res = 0; -+ int cs; -+ pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs); -+ if (getline(&line, &size, f) >= 0 && __parsespent(line, &sp) >= 0) res = &sp; -+ pthread_setcancelstate(cs, 0); -+ return res; - } -diff --git a/src/passwd/getgr_r.c b/src/passwd/getgr_r.c -index 234c901..3fe2e2b 100644 ---- a/src/passwd/getgr_r.c -+++ b/src/passwd/getgr_r.c -@@ -26,14 +26,14 @@ static int getgr_r(const char *name, gid_t gid, struct group *gr, char *buf, siz - while (__getgrent_a(f, gr, &line, &len, &mem, &nmem)) { - if (name && !strcmp(name, gr->gr_name) - || !name && gr->gr_gid == gid) { -- if (size < len + nmem*sizeof(char *) + 32) { -+ if (size < len + (nmem+1)*sizeof(char *) + 32) { - rv = ERANGE; - break; - } - *res = gr; - buf += (16-(uintptr_t)buf)%16; - gr->gr_mem = (void *)buf; -- buf += nmem*sizeof(char *); -+ buf += (nmem+1)*sizeof(char *); - memcpy(buf, line, len); - FIX(name); - FIX(passwd); -diff --git a/src/passwd/getspnam_r.c b/src/passwd/getspnam_r.c -index f4d7b35..15f8c87 100644 ---- a/src/passwd/getspnam_r.c -+++ b/src/passwd/getspnam_r.c -@@ -12,9 +12,45 @@ - * file. It also avoids any allocation to prevent memory-exhaustion - * attacks via huge TCB shadow files. */ - --static long xatol(const char *s) -+static long xatol(char **s) - { -- return isdigit(*s) ? atol(s) : -1; -+ long x; -+ if (**s == ':' || **s == '\n') return -1; -+ for (x=0; **s-'0'<10U; ++*s) x=10*x+(**s-'0'); -+ return x; -+} -+ -+int __parsespent(char *s, struct spwd *sp) -+{ -+ sp->sp_namp = s; -+ if (!(s = strchr(s, ':'))) return -1; -+ *s = 0; -+ -+ sp->sp_pwdp = ++s; -+ if (!(s = strchr(s, ':'))) return -1; -+ *s = 0; -+ -+ s++; sp->sp_lstchg = xatol(&s); -+ if (*s != ':') return -1; -+ -+ s++; sp->sp_min = xatol(&s); -+ if (*s != ':') return -1; -+ -+ s++; sp->sp_max = xatol(&s); -+ if (*s != ':') return -1; -+ -+ s++; sp->sp_warn = xatol(&s); -+ if (*s != ':') return -1; -+ -+ s++; sp->sp_inact = xatol(&s); -+ if (*s != ':') return -1; -+ -+ s++; sp->sp_expire = xatol(&s); -+ if (*s != ':') return -1; -+ -+ s++; sp->sp_flag = xatol(&s); -+ if (*s != '\n') return -1; -+ return 0; - } - - static void cleanup(void *p) -@@ -29,7 +65,6 @@ int getspnam_r(const char *name, struct spwd *sp, char *buf, size_t size, struct - int rv = 0; - int fd; - size_t k, l = strlen(name); -- char *s; - int skip = 0; - int cs; - -@@ -71,34 +106,8 @@ int getspnam_r(const char *name, struct spwd *sp, char *buf, size_t size, struct - rv = ERANGE; - break; - } -- buf[k-1] = 0; -- -- s = buf; -- sp->sp_namp = s; -- if (!(s = strchr(s, ':'))) continue; -- -- *s++ = 0; sp->sp_pwdp = s; -- if (!(s = strchr(s, ':'))) continue; -- -- *s++ = 0; sp->sp_lstchg = xatol(s); -- if (!(s = strchr(s, ':'))) continue; -- -- *s++ = 0; sp->sp_min = xatol(s); -- if (!(s = strchr(s, ':'))) continue; -- -- *s++ = 0; sp->sp_max = xatol(s); -- if (!(s = strchr(s, ':'))) continue; -- -- *s++ = 0; sp->sp_warn = xatol(s); -- if (!(s = strchr(s, ':'))) continue; -- -- *s++ = 0; sp->sp_inact = xatol(s); -- if (!(s = strchr(s, ':'))) continue; -- -- *s++ = 0; sp->sp_expire = xatol(s); -- if (!(s = strchr(s, ':'))) continue; - -- *s++ = 0; sp->sp_flag = xatol(s); -+ if (__parsespent(buf, sp) < 0) continue; - *res = sp; - break; - } -diff --git a/src/passwd/putgrent.c b/src/passwd/putgrent.c -index d7847b1..a0b320f 100644 ---- a/src/passwd/putgrent.c -+++ b/src/passwd/putgrent.c -@@ -1,3 +1,4 @@ -+#define _GNU_SOURCE - #include <grp.h> - #include <stdio.h> - -@@ -6,9 +7,11 @@ int putgrent(const struct group *gr, FILE *f) - int r; - size_t i; - flockfile(f); -- r = fprintf(f, "%s:%s:%d:", gr->gr_name, gr->gr_passwd, gr->gr_gid); -+ if ((r = fprintf(f, "%s:%s:%d:", gr->gr_name, gr->gr_passwd, gr->gr_gid))<0) goto done; - if (gr->gr_mem) for (i=0; gr->gr_mem[i]; i++) -- if (fprintf(f, "%s%s", i?",":"", gr->gr_mem[i])<0) r = -1; -+ if ((r = fprintf(f, "%s%s", i?",":"", gr->gr_mem[i]))<0) goto done; -+ r = fputc('\n', f); -+done: - funlockfile(f); - return r<0 ? -1 : 0; - } -diff --git a/src/passwd/putpwent.c b/src/passwd/putpwent.c -index 80fbf38..3a02e57 100644 ---- a/src/passwd/putpwent.c -+++ b/src/passwd/putpwent.c -@@ -1,3 +1,4 @@ -+#define _GNU_SOURCE - #include <pwd.h> - #include <stdio.h> - -diff --git a/src/passwd/putspent.c b/src/passwd/putspent.c -new file mode 100644 -index 0000000..55c41bb ---- /dev/null -+++ b/src/passwd/putspent.c -@@ -0,0 +1,13 @@ -+#include <shadow.h> -+#include <stdio.h> -+ -+#define NUM(n) ((n) == -1 ? 0 : -1), ((n) == -1 ? 0 : (n)) -+#define STR(s) ((s) ? (s) : "") -+ -+int putspent(const struct spwd *sp, FILE *f) -+{ -+ return fprintf(f, "%s:%s:%.*ld:%.*ld:%.*ld:%.*ld:%.*ld:%.*ld:%.*lu\n", -+ STR(sp->sp_namp), STR(sp->sp_pwdp), NUM(sp->sp_lstchg), -+ NUM(sp->sp_min), NUM(sp->sp_max), NUM(sp->sp_warn), -+ NUM(sp->sp_inact), NUM(sp->sp_expire), NUM(sp->sp_flag)) < 0 ? -1 : 0; -+} -diff --git a/src/passwd/pwf.h b/src/passwd/pwf.h -index 0a76ef8..2d813ad 100644 ---- a/src/passwd/pwf.h -+++ b/src/passwd/pwf.h -@@ -9,5 +9,5 @@ - #include "libc.h" - - struct passwd *__getpwent_a(FILE *f, struct passwd *pw, char **line, size_t *size); --struct spwd *__getspent_a(FILE *f, struct spwd *sp, char **line, size_t *size); - struct group *__getgrent_a(FILE *f, struct group *gr, char **line, size_t *size, char ***mem, size_t *nmem); -+int __parsespent(char *s, struct spwd *sp); -diff --git a/src/prng/__rand48_step.c b/src/prng/__rand48_step.c -index 105f810..ccaffc3 100644 ---- a/src/prng/__rand48_step.c -+++ b/src/prng/__rand48_step.c -@@ -1,4 +1,3 @@ --#include <stdlib.h> - #include <stdint.h> - - uint64_t __rand48_step(unsigned short *xi, unsigned short *lc) -diff --git a/src/process/execl.c b/src/process/execl.c -index 327d78b..5ee5c81 100644 ---- a/src/process/execl.c -+++ b/src/process/execl.c -@@ -16,6 +16,7 @@ int execl(const char *path, const char *argv0, ...) - for (i=1; i<argc; i++) - argv[i] = va_arg(ap, char *); - argv[i] = NULL; -+ va_end(ap); - return execv(path, argv); - } - } -diff --git a/src/process/execle.c b/src/process/execle.c -index 6490836..37ca503 100644 ---- a/src/process/execle.c -+++ b/src/process/execle.c -@@ -14,10 +14,10 @@ int execle(const char *path, const char *argv0, ...) - char **envp; - va_start(ap, argv0); - argv[0] = (char *)argv0; -- for (i=1; i<argc; i++) -+ for (i=1; i<=argc; i++) - argv[i] = va_arg(ap, char *); -- argv[i] = NULL; - envp = va_arg(ap, char **); -+ va_end(ap); - return execve(path, argv, envp); - } - } -diff --git a/src/process/execlp.c b/src/process/execlp.c -index c7b3f51..5eed886 100644 ---- a/src/process/execlp.c -+++ b/src/process/execlp.c -@@ -16,6 +16,7 @@ int execlp(const char *file, const char *argv0, ...) - for (i=1; i<argc; i++) - argv[i] = va_arg(ap, char *); - argv[i] = NULL; -+ va_end(ap); - return execvp(file, argv); - } - } -diff --git a/src/process/fexecve.c b/src/process/fexecve.c -index 8ab02a7..6507b42 100644 ---- a/src/process/fexecve.c -+++ b/src/process/fexecve.c -@@ -1,5 +1,4 @@ - #include <unistd.h> --#include <stdio.h> - #include <errno.h> - - void __procfdname(char *, unsigned); -diff --git a/src/process/system.c b/src/process/system.c -index f5b7b49..8cbdda0 100644 ---- a/src/process/system.c -+++ b/src/process/system.c -@@ -1,5 +1,5 @@ - #include <unistd.h> --#include <fcntl.h> -+#include <stdlib.h> - #include <signal.h> - #include <sys/wait.h> - #include <spawn.h> -diff --git a/src/process/vfork.c b/src/process/vfork.c -index 16d07ea..fc4adb4 100644 ---- a/src/process/vfork.c -+++ b/src/process/vfork.c -@@ -1,3 +1,4 @@ -+#define _GNU_SOURCE - #include <unistd.h> - #include "syscall.h" - #include "libc.h" -diff --git a/src/regex/fnmatch.c b/src/regex/fnmatch.c -index ffd3ea0..4df10a3 100644 ---- a/src/regex/fnmatch.c -+++ b/src/regex/fnmatch.c -@@ -19,7 +19,7 @@ - #include <wchar.h> - #include <wctype.h> - --#define END -1 -+#define END 0 - #define UNMATCHABLE -2 - #define BRACKET -3 - #define QUESTION -4 -@@ -53,7 +53,7 @@ static int pat_next(const char *pat, size_t m, size_t *step, int flags) - return END; - } - *step = 1; -- if (pat[0]=='\\' && !(flags & FNM_NOESCAPE)) { -+ if (pat[0]=='\\' && pat[1] && !(flags & FNM_NOESCAPE)) { - *step = 2; - pat++; - esc = 1; -@@ -288,12 +288,19 @@ int fnmatch(const char *pat, const char *str, int flags) - if (flags & FNM_PATHNAME) for (;;) { - for (s=str; *s && *s!='/'; s++); - for (p=pat; (c=pat_next(p, -1, &inc, flags))!=END && c!='/'; p+=inc); -- if (*s && *p!=*s) return FNM_NOMATCH; -+ if (c!=*s && (!*s || !(flags & FNM_LEADING_DIR))) -+ return FNM_NOMATCH; - if (fnmatch_internal(pat, p-pat, str, s-str, flags)) - return FNM_NOMATCH; -- if (!*s && c==END) return 0; -+ if (!c) return 0; - str = s+1; -- pat = p+1; -+ pat = p+inc; -+ } else if (flags & FNM_LEADING_DIR) { -+ for (s=str; *s; s++) { -+ if (*s != '/') continue; -+ if (!fnmatch_internal(pat, -1, str, s-str, flags)) -+ return 0; -+ } - } - return fnmatch_internal(pat, -1, str, -1, flags); - } -diff --git a/src/regex/glob.c b/src/regex/glob.c -index 6c07e6b..6affee0 100644 ---- a/src/regex/glob.c -+++ b/src/regex/glob.c -@@ -7,8 +7,6 @@ - #include <stdlib.h> - #include <errno.h> - #include <stddef.h> --#include <unistd.h> --#include <stdio.h> - #include "libc.h" - - struct match -diff --git a/src/regex/regcomp.c b/src/regex/regcomp.c -index 5cedfd5..d907627 100644 ---- a/src/regex/regcomp.c -+++ b/src/regex/regcomp.c -@@ -30,7 +30,6 @@ - */ - - #include <string.h> --#include <errno.h> - #include <stdlib.h> - #include <regex.h> - #include <limits.h> -@@ -516,7 +515,7 @@ tre_new_item(tre_mem_t mem, int min, int max, int *i, int *max_i, - if (*max_i > 1024) - return REG_ESPACE; - *max_i *= 2; -- new_items = xrealloc(array, sizeof(*items) * *max_i); -+ new_items = xrealloc(array, sizeof(*array) * *max_i); - if (new_items == NULL) - return REG_ESPACE; - *items = array = new_items; -@@ -765,7 +764,7 @@ tre_parse_bracket(tre_parse_ctx_t *ctx, tre_ast_node_t **result) - if (num_neg_classes > 0) - { - l->neg_classes = tre_mem_alloc(ctx->mem, -- (sizeof(l->neg_classes) -+ (sizeof(*l->neg_classes) - * (num_neg_classes + 1))); - if (l->neg_classes == NULL) - { -@@ -805,7 +804,7 @@ tre_parse_bracket(tre_parse_ctx_t *ctx, tre_ast_node_t **result) - if (num_neg_classes > 0) - { - l->neg_classes = tre_mem_alloc(ctx->mem, -- (sizeof(l->neg_classes) -+ (sizeof(*l->neg_classes) - * (num_neg_classes + 1))); - if (l->neg_classes == NULL) - { -@@ -3167,7 +3166,7 @@ regcomp(regex_t *restrict preg, const char *restrict regex, int cflags) - sizeof(*tag_directions) * (tnfa->num_tags + 1)); - } - tnfa->minimal_tags = xcalloc((unsigned)tnfa->num_tags * 2 + 1, -- sizeof(tnfa->minimal_tags)); -+ sizeof(*tnfa->minimal_tags)); - if (tnfa->minimal_tags == NULL) - ERROR_EXIT(REG_ESPACE); - -diff --git a/src/search/hsearch.c b/src/search/hsearch.c -index be856b2..6fe5ced 100644 ---- a/src/search/hsearch.c -+++ b/src/search/hsearch.c -@@ -14,14 +14,14 @@ with the posix api items cannot be iterated and length cannot be queried - #define MINSIZE 8 - #define MAXSIZE ((size_t)-1/2 + 1) - --struct entry { -+struct elem { - ENTRY item; - size_t hash; - }; - - static size_t mask; - static size_t used; --static struct entry *tab; -+static struct elem *tab; - - static size_t keyhash(char *k) - { -@@ -37,9 +37,9 @@ static int resize(size_t nel) - { - size_t newsize; - size_t i, j; -- struct entry *e, *newe; -- struct entry *oldtab = tab; -- struct entry *oldend = tab + mask + 1; -+ struct elem *e, *newe; -+ struct elem *oldtab = tab; -+ struct elem *oldend = tab + mask + 1; - - if (nel > MAXSIZE) - nel = MAXSIZE; -@@ -81,10 +81,10 @@ void hdestroy(void) - used = 0; - } - --static struct entry *lookup(char *key, size_t hash) -+static struct elem *lookup(char *key, size_t hash) - { - size_t i, j; -- struct entry *e; -+ struct elem *e; - - for (i=hash,j=1; ; i+=j++) { - e = tab + (i & mask); -@@ -98,7 +98,7 @@ static struct entry *lookup(char *key, size_t hash) - ENTRY *hsearch(ENTRY item, ACTION action) - { - size_t hash = keyhash(item.key); -- struct entry *e = lookup(item.key, hash); -+ struct elem *e = lookup(item.key, hash); - - if (e->item.key) - return &e->item; -diff --git a/src/signal/raise.c b/src/signal/raise.c -index 6fa43be..35063c5 100644 ---- a/src/signal/raise.c -+++ b/src/signal/raise.c -@@ -1,5 +1,4 @@ - #include <signal.h> --#include <errno.h> - #include <stdint.h> - #include "syscall.h" - #include "pthread_impl.h" -diff --git a/src/signal/sigaction.c b/src/signal/sigaction.c -index 5499bd1..f7ff4a6 100644 ---- a/src/signal/sigaction.c -+++ b/src/signal/sigaction.c -@@ -1,4 +1,3 @@ --#include <stdlib.h> - #include <signal.h> - #include <errno.h> - #include <string.h> -diff --git a/src/signal/sigfillset.c b/src/signal/sigfillset.c -index 4d0a807..16e7b4f 100644 ---- a/src/signal/sigfillset.c -+++ b/src/signal/sigfillset.c -@@ -1,5 +1,4 @@ - #include <signal.h> --#include <string.h> - #include <limits.h> - - int sigfillset(sigset_t *set) -diff --git a/src/signal/sighold.c b/src/signal/sighold.c -index 5b0f6b1..cfa2306 100644 ---- a/src/signal/sighold.c -+++ b/src/signal/sighold.c -@@ -1,5 +1,4 @@ - #include <signal.h> --#include <stdlib.h> - - int sighold(int sig) - { -@@ -7,5 +6,5 @@ int sighold(int sig) - - sigemptyset(&mask); - if (sigaddset(&mask, sig) < 0) return -1; -- return sigprocmask(SIG_BLOCK, &mask, NULL); -+ return sigprocmask(SIG_BLOCK, &mask, 0); - } -diff --git a/src/signal/sigignore.c b/src/signal/sigignore.c -index 98dff61..5ba05e1 100644 ---- a/src/signal/sigignore.c -+++ b/src/signal/sigignore.c -@@ -1,5 +1,4 @@ - #include <signal.h> --#include <stdlib.h> - - int sigignore(int sig) - { -@@ -8,5 +7,5 @@ int sigignore(int sig) - sigemptyset(&sa.sa_mask); - sa.sa_handler = SIG_IGN; - sa.sa_flags = 0; -- return sigaction(sig, &sa, NULL); -+ return sigaction(sig, &sa, 0); - } -diff --git a/src/signal/siginterrupt.c b/src/signal/siginterrupt.c -index 60b3405..7006340 100644 ---- a/src/signal/siginterrupt.c -+++ b/src/signal/siginterrupt.c -@@ -1,13 +1,12 @@ --#include <stdlib.h> - #include <signal.h> - - int siginterrupt(int sig, int flag) - { - struct sigaction sa; - -- sigaction(sig, NULL, &sa); -+ sigaction(sig, 0, &sa); - if (flag) sa.sa_flags &= ~SA_RESTART; - else sa.sa_flags |= SA_RESTART; - -- return sigaction(sig, &sa, NULL); -+ return sigaction(sig, &sa, 0); - } -diff --git a/src/signal/sigismember.c b/src/signal/sigismember.c -index dd1a8db..ab87d62 100644 ---- a/src/signal/sigismember.c -+++ b/src/signal/sigismember.c -@@ -1,5 +1,4 @@ - #include <signal.h> --#include <errno.h> - - int sigismember(const sigset_t *set, int sig) - { -diff --git a/src/signal/siglongjmp.c b/src/signal/siglongjmp.c -index 2974ff7..b644ceb 100644 ---- a/src/signal/siglongjmp.c -+++ b/src/signal/siglongjmp.c -@@ -1,6 +1,5 @@ - #include <setjmp.h> - #include <signal.h> --#include <stdlib.h> - #include "syscall.h" - #include "pthread_impl.h" - -diff --git a/src/signal/signal.c b/src/signal/signal.c -index 9d2f23a..c0f063e 100644 ---- a/src/signal/signal.c -+++ b/src/signal/signal.c -@@ -1,5 +1,4 @@ - #include <signal.h> --#include <stddef.h> - #include "syscall.h" - #include "libc.h" - -diff --git a/src/signal/sigpause.c b/src/signal/sigpause.c -index 6c0f05d..363d2fe 100644 ---- a/src/signal/sigpause.c -+++ b/src/signal/sigpause.c -@@ -1,5 +1,4 @@ - #include <signal.h> --#include <stdlib.h> - - int sigpause(int sig) - { -diff --git a/src/signal/sigqueue.c b/src/signal/sigqueue.c -index eb4d184..b75f0c5 100644 ---- a/src/signal/sigqueue.c -+++ b/src/signal/sigqueue.c -@@ -1,7 +1,6 @@ - #include <signal.h> - #include <string.h> - #include <unistd.h> --#include <stdint.h> - #include "syscall.h" - #include "pthread_impl.h" - -diff --git a/src/signal/sigrelse.c b/src/signal/sigrelse.c -index b0b3024..b4c5a00 100644 ---- a/src/signal/sigrelse.c -+++ b/src/signal/sigrelse.c -@@ -1,5 +1,4 @@ - #include <signal.h> --#include <stdlib.h> - - int sigrelse(int sig) - { -@@ -7,5 +6,5 @@ int sigrelse(int sig) - - sigemptyset(&mask); - if (sigaddset(&mask, sig) < 0) return -1; -- return sigprocmask(SIG_UNBLOCK, &mask, NULL); -+ return sigprocmask(SIG_UNBLOCK, &mask, 0); - } -diff --git a/src/signal/sigset.c b/src/signal/sigset.c -index 1b6b38f..0d7b456 100644 ---- a/src/signal/sigset.c -+++ b/src/signal/sigset.c -@@ -1,5 +1,4 @@ - #include <signal.h> --#include <stdlib.h> - - void (*sigset(int sig, void (*handler)(int)))(int) - { -@@ -11,7 +10,7 @@ void (*sigset(int sig, void (*handler)(int)))(int) - return SIG_ERR; - - if (handler == SIG_HOLD) { -- if (sigaction(sig, NULL, &sa_old) < 0) -+ if (sigaction(sig, 0, &sa_old) < 0) - return SIG_ERR; - if (sigprocmask(SIG_BLOCK, &mask, &mask) < 0) - return SIG_ERR; -diff --git a/src/signal/sigsetjmp.c b/src/signal/sigsetjmp.c -index 6a5f6f1..cb2257f 100644 ---- a/src/signal/sigsetjmp.c -+++ b/src/signal/sigsetjmp.c -@@ -1,6 +1,5 @@ - #include <setjmp.h> - #include <signal.h> --#include <stdlib.h> - - /* !!! This function will not work unless the compiler performs - * tail call optimization. Machine-specific asm versions should -diff --git a/src/signal/sigwait.c b/src/signal/sigwait.c -index 48a855b..c8822ee 100644 ---- a/src/signal/sigwait.c -+++ b/src/signal/sigwait.c -@@ -1,10 +1,9 @@ - #include <signal.h> --#include <stddef.h> - - int sigwait(const sigset_t *restrict mask, int *restrict sig) - { - siginfo_t si; -- if (sigtimedwait(mask, &si, NULL) < 0) -+ if (sigtimedwait(mask, &si, 0) < 0) - return -1; - *sig = si.si_signo; - return 0; -diff --git a/src/signal/sigwaitinfo.c b/src/signal/sigwaitinfo.c -index c7b164d..bb51f8b 100644 ---- a/src/signal/sigwaitinfo.c -+++ b/src/signal/sigwaitinfo.c -@@ -1,7 +1,6 @@ - #include <signal.h> --#include <stddef.h> - - int sigwaitinfo(const sigset_t *restrict mask, siginfo_t *restrict si) - { -- return sigtimedwait(mask, si, NULL); -+ return sigtimedwait(mask, si, 0); - } -diff --git a/src/stat/fchmodat.c b/src/stat/fchmodat.c -index aeb50bc..12e7ff0 100644 ---- a/src/stat/fchmodat.c -+++ b/src/stat/fchmodat.c -@@ -1,7 +1,6 @@ - #include <sys/stat.h> - #include <fcntl.h> - #include <errno.h> --#include <stdio.h> - #include "syscall.h" - - void __procfdname(char *, unsigned); -diff --git a/src/stat/futimesat.c b/src/stat/futimesat.c -index 0cc1854..dbefc84 100644 ---- a/src/stat/futimesat.c -+++ b/src/stat/futimesat.c -@@ -1,3 +1,4 @@ -+#define _GNU_SOURCE - #include <sys/time.h> - #include "syscall.h" - -diff --git a/src/stat/lchmod.c b/src/stat/lchmod.c -index c35f586..f324ba7 100644 ---- a/src/stat/lchmod.c -+++ b/src/stat/lchmod.c -@@ -1,3 +1,4 @@ -+#define _GNU_SOURCE - #include <sys/stat.h> - #include <fcntl.h> - -diff --git a/src/stdio/fgetln.c b/src/stdio/fgetln.c -index a2e4bd3..afe12b5 100644 ---- a/src/stdio/fgetln.c -+++ b/src/stdio/fgetln.c -@@ -1,3 +1,4 @@ -+#define _GNU_SOURCE - #include "stdio_impl.h" - #include <string.h> - -diff --git a/src/stdio/fwide.c b/src/stdio/fwide.c -index 4848068..fdf8e4b 100644 ---- a/src/stdio/fwide.c -+++ b/src/stdio/fwide.c -@@ -1,3 +1,4 @@ -+#include <wchar.h> - #include "stdio_impl.h" - - #define SH (8*sizeof(int)-1) -diff --git a/src/stdio/swprintf.c b/src/stdio/swprintf.c -index cbf83d2..f75eb11 100644 ---- a/src/stdio/swprintf.c -+++ b/src/stdio/swprintf.c -@@ -1,4 +1,3 @@ --#include <stdio.h> - #include <stdarg.h> - #include <wchar.h> - -diff --git a/src/stdio/swscanf.c b/src/stdio/swscanf.c -index c798609..d893fba 100644 ---- a/src/stdio/swscanf.c -+++ b/src/stdio/swscanf.c -@@ -1,4 +1,3 @@ --#include <stdio.h> - #include <stdarg.h> - #include <wchar.h> - #include "libc.h" -diff --git a/src/stdio/vfprintf.c b/src/stdio/vfprintf.c -index a2b287b..b5948bd 100644 ---- a/src/stdio/vfprintf.c -+++ b/src/stdio/vfprintf.c -@@ -530,7 +530,6 @@ static int printf_core(FILE *f, const char *fmt, va_list *ap, union arg *nl_arg, - /* Check validity of argument type (nl/normal) */ - if (st==NOARG) { - if (argpos>=0) return -1; -- else if (!f) continue; - } else { - if (argpos>=0) nl_type[argpos]=st, arg=nl_arg[argpos]; - else if (f) pop_arg(&arg, st, ap); -@@ -660,8 +659,12 @@ int vfprintf(FILE *restrict f, const char *restrict fmt, va_list ap) - unsigned char internal_buf[80], *saved_buf = 0; - int ret; - -+ /* the copy allows passing va_list* even if va_list is an array */ - va_copy(ap2, ap); -- if (printf_core(0, fmt, &ap2, nl_arg, nl_type) < 0) return -1; -+ if (printf_core(0, fmt, &ap2, nl_arg, nl_type) < 0) { -+ va_end(ap2); -+ return -1; -+ } - - FLOCK(f); - if (!f->buf_size) { -diff --git a/src/stdio/vfscanf.c b/src/stdio/vfscanf.c -index c0e607f..0091a8d 100644 ---- a/src/stdio/vfscanf.c -+++ b/src/stdio/vfscanf.c -@@ -5,10 +5,7 @@ - #include <wctype.h> - #include <limits.h> - #include <string.h> --#include <errno.h> --#include <math.h> --#include <float.h> --#include <inttypes.h> -+#include <stdint.h> - - #include "stdio_impl.h" - #include "shgetc.h" -diff --git a/src/stdio/vfwprintf.c b/src/stdio/vfwprintf.c -index eb07931..984ff7b 100644 ---- a/src/stdio/vfwprintf.c -+++ b/src/stdio/vfwprintf.c -@@ -167,7 +167,7 @@ static const char sizeprefix['y'-'a'] = { - - static int wprintf_core(FILE *f, const wchar_t *fmt, va_list *ap, union arg *nl_arg, int *nl_type) - { -- wchar_t *a, *z, *s=(wchar_t *)fmt, *s0; -+ wchar_t *a, *z, *s=(wchar_t *)fmt; - unsigned l10n=0, litpct, fl; - int w, p; - union arg arg; -@@ -242,7 +242,6 @@ static int wprintf_core(FILE *f, const wchar_t *fmt, va_list *ap, union arg *nl_ - } else p = -1; - - /* Format specifier state machine */ -- s0=s; - st=0; - do { - if (OOB(*s)) return -1; -@@ -254,7 +253,6 @@ static int wprintf_core(FILE *f, const wchar_t *fmt, va_list *ap, union arg *nl_ - /* Check validity of argument type (nl/normal) */ - if (st==NOARG) { - if (argpos>=0) return -1; -- else if (!f) continue; - } else { - if (argpos>=0) nl_type[argpos]=st, arg=nl_arg[argpos]; - else if (f) pop_arg(&arg, st, ap); -@@ -288,8 +286,7 @@ static int wprintf_core(FILE *f, const wchar_t *fmt, va_list *ap, union arg *nl_ - case 'S': - a = arg.p; - z = wmemchr(a, 0, p); -- if (!z) z=a+p; -- else p=z-a; -+ if (z) p=z-a; - if (w<p) w=p; - if (!(fl&LEFT_ADJ)) fprintf(f, "%.*s", w-p, ""); - out(f, a, p); -@@ -350,8 +347,12 @@ int vfwprintf(FILE *restrict f, const wchar_t *restrict fmt, va_list ap) - union arg nl_arg[NL_ARGMAX]; - int ret; - -+ /* the copy allows passing va_list* even if va_list is an array */ - va_copy(ap2, ap); -- if (wprintf_core(0, fmt, &ap2, nl_arg, nl_type) < 0) return -1; -+ if (wprintf_core(0, fmt, &ap2, nl_arg, nl_type) < 0) { -+ va_end(ap2); -+ return -1; -+ } - - FLOCK(f); - ret = wprintf_core(f, fmt, &ap2, nl_arg, nl_type); -diff --git a/src/stdio/vfwscanf.c b/src/stdio/vfwscanf.c -index 75f04d7..f8f4b70 100644 ---- a/src/stdio/vfwscanf.c -+++ b/src/stdio/vfwscanf.c -@@ -6,9 +6,6 @@ - #include <wctype.h> - #include <limits.h> - #include <string.h> --#include <errno.h> --#include <math.h> --#include <float.h> - - #include "stdio_impl.h" - #include "shgetc.h" -diff --git a/src/stdlib/ecvt.c b/src/stdlib/ecvt.c -index 79c3de6..797b664 100644 ---- a/src/stdlib/ecvt.c -+++ b/src/stdlib/ecvt.c -@@ -1,3 +1,4 @@ -+#define _GNU_SOURCE - #include <stdlib.h> - #include <stdio.h> - -diff --git a/src/stdlib/gcvt.c b/src/stdlib/gcvt.c -index 6c075e2..f29bc30 100644 ---- a/src/stdlib/gcvt.c -+++ b/src/stdlib/gcvt.c -@@ -1,3 +1,4 @@ -+#define _GNU_SOURCE - #include <stdlib.h> - #include <stdio.h> - -diff --git a/src/stdlib/wcstod.c b/src/stdlib/wcstod.c -index 83f308d..26fe9af 100644 ---- a/src/stdlib/wcstod.c -+++ b/src/stdlib/wcstod.c -@@ -1,6 +1,7 @@ - #include "shgetc.h" - #include "floatscan.h" - #include "stdio_impl.h" -+#include <wchar.h> - #include <wctype.h> - - /* This read function heavily cheats. It knows: -diff --git a/src/string/bcmp.c b/src/string/bcmp.c -index 5d6a388..87c6007 100644 ---- a/src/string/bcmp.c -+++ b/src/string/bcmp.c -@@ -1,3 +1,4 @@ -+#define _BSD_SOURCE - #include <string.h> - #include <strings.h> - -diff --git a/src/string/bcopy.c b/src/string/bcopy.c -index e76272f..a07129f 100644 ---- a/src/string/bcopy.c -+++ b/src/string/bcopy.c -@@ -1,3 +1,4 @@ -+#define _BSD_SOURCE - #include <string.h> - #include <strings.h> - -diff --git a/src/string/bzero.c b/src/string/bzero.c -index 0f98b4a..ba536b0 100644 ---- a/src/string/bzero.c -+++ b/src/string/bzero.c -@@ -1,3 +1,4 @@ -+#define _BSD_SOURCE - #include <string.h> - #include <strings.h> - -diff --git a/src/string/index.c b/src/string/index.c -index dd61125..252948f 100644 ---- a/src/string/index.c -+++ b/src/string/index.c -@@ -1,3 +1,4 @@ -+#define _BSD_SOURCE - #include <string.h> - #include <strings.h> - -diff --git a/src/string/memccpy.c b/src/string/memccpy.c -index b85009c..7c233d5 100644 ---- a/src/string/memccpy.c -+++ b/src/string/memccpy.c -@@ -1,5 +1,4 @@ - #include <string.h> --#include <stdlib.h> - #include <stdint.h> - #include <limits.h> - -diff --git a/src/string/memchr.c b/src/string/memchr.c -index a0472f7..4daff7b 100644 ---- a/src/string/memchr.c -+++ b/src/string/memchr.c -@@ -1,5 +1,4 @@ - #include <string.h> --#include <stdlib.h> - #include <stdint.h> - #include <limits.h> - -diff --git a/src/string/memmem.c b/src/string/memmem.c -index 861fef2..5211d75 100644 ---- a/src/string/memmem.c -+++ b/src/string/memmem.c -@@ -1,6 +1,5 @@ - #define _GNU_SOURCE - #include <string.h> --#include <stdlib.h> - #include <stdint.h> - - static char *twobyte_memmem(const unsigned char *h, size_t k, const unsigned char *n) -diff --git a/src/string/mempcpy.c b/src/string/mempcpy.c -index c23ca69..a297985 100644 ---- a/src/string/mempcpy.c -+++ b/src/string/mempcpy.c -@@ -1,3 +1,4 @@ -+#define _GNU_SOURCE - #include <string.h> - - void *mempcpy(void *dest, const void *src, size_t n) -diff --git a/src/string/rindex.c b/src/string/rindex.c -index 17df2bf..693c750 100644 ---- a/src/string/rindex.c -+++ b/src/string/rindex.c -@@ -1,3 +1,4 @@ -+#define _BSD_SOURCE - #include <string.h> - #include <strings.h> - -diff --git a/src/string/stpcpy.c b/src/string/stpcpy.c -index feb9eb8..06623c4 100644 ---- a/src/string/stpcpy.c -+++ b/src/string/stpcpy.c -@@ -1,5 +1,4 @@ - #include <string.h> --#include <stdlib.h> - #include <stdint.h> - #include <limits.h> - #include "libc.h" -diff --git a/src/string/stpncpy.c b/src/string/stpncpy.c -index 0a2c2a9..1f57a4d 100644 ---- a/src/string/stpncpy.c -+++ b/src/string/stpncpy.c -@@ -1,5 +1,4 @@ - #include <string.h> --#include <stdlib.h> - #include <stdint.h> - #include <limits.h> - #include "libc.h" -diff --git a/src/string/strchrnul.c b/src/string/strchrnul.c -index ceae4d4..05700ad 100644 ---- a/src/string/strchrnul.c -+++ b/src/string/strchrnul.c -@@ -1,5 +1,4 @@ - #include <string.h> --#include <stdlib.h> - #include <stdint.h> - #include <limits.h> - #include "libc.h" -diff --git a/src/string/strcmp.c b/src/string/strcmp.c -index 91eb740..808bd83 100644 ---- a/src/string/strcmp.c -+++ b/src/string/strcmp.c -@@ -2,6 +2,6 @@ - - int strcmp(const char *l, const char *r) - { -- for (; *l==*r && *l && *r; l++, r++); -+ for (; *l==*r && *l; l++, r++); - return *(unsigned char *)l - *(unsigned char *)r; - } -diff --git a/src/string/strlcpy.c b/src/string/strlcpy.c -index 4d3ff92..193d724 100644 ---- a/src/string/strlcpy.c -+++ b/src/string/strlcpy.c -@@ -1,5 +1,5 @@ -+#define _BSD_SOURCE - #include <string.h> --#include <stdlib.h> - #include <stdint.h> - #include <limits.h> - #include "libc.h" -diff --git a/src/string/strlen.c b/src/string/strlen.c -index d6f8631..929ddcb 100644 ---- a/src/string/strlen.c -+++ b/src/string/strlen.c -@@ -1,5 +1,4 @@ - #include <string.h> --#include <stdlib.h> - #include <stdint.h> - #include <limits.h> - -diff --git a/src/string/strstr.c b/src/string/strstr.c -index 0649174..915c0a2 100644 ---- a/src/string/strstr.c -+++ b/src/string/strstr.c -@@ -1,5 +1,4 @@ - #include <string.h> --#include <stdlib.h> - #include <stdint.h> - - static char *twobyte_strstr(const unsigned char *h, const unsigned char *n) -diff --git a/src/string/strverscmp.c b/src/string/strverscmp.c -index 94d2e15..6f37cc6 100644 ---- a/src/string/strverscmp.c -+++ b/src/string/strverscmp.c -@@ -1,7 +1,6 @@ - #define _GNU_SOURCE - #include <ctype.h> - #include <string.h> --#include <sys/types.h> - - int strverscmp(const char *l, const char *r) - { -diff --git a/src/string/wcsstr.c b/src/string/wcsstr.c -index 037d096..3e28e28 100644 ---- a/src/string/wcsstr.c -+++ b/src/string/wcsstr.c -@@ -1,7 +1,4 @@ - #include <wchar.h> --#include <string.h> --#include <stdlib.h> --#include <stdint.h> - - #define MAX(a,b) ((a)>(b)?(a):(b)) - #define MIN(a,b) ((a)<(b)?(a):(b)) -diff --git a/src/string/wmemchr.c b/src/string/wmemchr.c -index 37d6962..2bc2c27 100644 ---- a/src/string/wmemchr.c -+++ b/src/string/wmemchr.c -@@ -1,4 +1,3 @@ --#include <string.h> - #include <wchar.h> - - wchar_t *wmemchr(const wchar_t *s, wchar_t c, size_t n) -diff --git a/src/string/wmemcmp.c b/src/string/wmemcmp.c -index 6788a38..2a19326 100644 ---- a/src/string/wmemcmp.c -+++ b/src/string/wmemcmp.c -@@ -1,4 +1,3 @@ --#include <string.h> - #include <wchar.h> - - int wmemcmp(const wchar_t *l, const wchar_t *r, size_t n) -diff --git a/src/string/wmemcpy.c b/src/string/wmemcpy.c -index 55a8e1d..52e6e6e 100644 ---- a/src/string/wmemcpy.c -+++ b/src/string/wmemcpy.c -@@ -1,4 +1,3 @@ --#include <string.h> - #include <wchar.h> - - wchar_t *wmemcpy(wchar_t *restrict d, const wchar_t *restrict s, size_t n) -diff --git a/src/string/wmemmove.c b/src/string/wmemmove.c -index cde4fee..e406f3d 100644 ---- a/src/string/wmemmove.c -+++ b/src/string/wmemmove.c -@@ -1,4 +1,3 @@ --#include <string.h> - #include <wchar.h> - - wchar_t *wmemmove(wchar_t *d, const wchar_t *s, size_t n) -diff --git a/src/string/wmemset.c b/src/string/wmemset.c -index 1a2a861..07a037a 100644 ---- a/src/string/wmemset.c -+++ b/src/string/wmemset.c -@@ -1,4 +1,3 @@ --#include <string.h> - #include <wchar.h> - - wchar_t *wmemset(wchar_t *d, wchar_t c, size_t n) -diff --git a/src/temp/__randname.c b/src/temp/__randname.c -index 38c99d3..464b83d 100644 ---- a/src/temp/__randname.c -+++ b/src/temp/__randname.c -@@ -1,4 +1,3 @@ --#include <string.h> - #include <time.h> - #include <stdint.h> - -diff --git a/src/temp/mkdtemp.c b/src/temp/mkdtemp.c -index 195e9cb..6c2c16e 100644 ---- a/src/temp/mkdtemp.c -+++ b/src/temp/mkdtemp.c -@@ -1,12 +1,7 @@ - #include <string.h> --#include <stdio.h> - #include <stdlib.h> --#include <fcntl.h> --#include <unistd.h> --#include <limits.h> - #include <errno.h> - #include <sys/stat.h> --#include "libc.h" - - char *__randname(char *); - -diff --git a/src/temp/mktemp.c b/src/temp/mktemp.c -index 67130e1..4ab0df2 100644 ---- a/src/temp/mktemp.c -+++ b/src/temp/mktemp.c -@@ -1,6 +1,6 @@ -+#define _GNU_SOURCE - #include <string.h> --#include <fcntl.h> --#include <unistd.h> -+#include <stdlib.h> - #include <errno.h> - #include <sys/stat.h> - -diff --git a/src/termios/tcgetattr.c b/src/termios/tcgetattr.c -index d9ce786..545a0bf 100644 ---- a/src/termios/tcgetattr.c -+++ b/src/termios/tcgetattr.c -@@ -1,6 +1,5 @@ - #include <termios.h> - #include <sys/ioctl.h> --#include <string.h> - - int tcgetattr(int fd, struct termios *tio) - { -diff --git a/src/termios/tcsetattr.c b/src/termios/tcsetattr.c -index e9a168f..94df18f 100644 ---- a/src/termios/tcsetattr.c -+++ b/src/termios/tcsetattr.c -@@ -1,6 +1,5 @@ - #include <termios.h> - #include <sys/ioctl.h> --#include <string.h> - #include <errno.h> - - int tcsetattr(int fd, int act, const struct termios *tio) -diff --git a/src/thread/pthread_attr_init.c b/src/thread/pthread_attr_init.c -index 6693488..969e0a3 100644 ---- a/src/thread/pthread_attr_init.c -+++ b/src/thread/pthread_attr_init.c -@@ -1,5 +1,4 @@ - #include "pthread_impl.h" --#include <string.h> - - int pthread_attr_init(pthread_attr_t *a) - { -diff --git a/src/thread/pthread_key_create.c b/src/thread/pthread_key_create.c -index e51cb02..c29935c 100644 ---- a/src/thread/pthread_key_create.c -+++ b/src/thread/pthread_key_create.c -@@ -17,7 +17,7 @@ int pthread_key_create(pthread_key_t *k, void (*dtor)(void *)) - __pthread_self_init(); - if (!dtor) dtor = nodtor; - do { -- if (!a_cas_p(keys+j, 0, dtor)) { -+ if (!a_cas_p(keys+j, 0, (void *)dtor)) { - *k = j; - return 0; - } -diff --git a/src/thread/pthread_sigmask.c b/src/thread/pthread_sigmask.c -index b274bd0..88c333f 100644 ---- a/src/thread/pthread_sigmask.c -+++ b/src/thread/pthread_sigmask.c -@@ -1,6 +1,5 @@ - #include <signal.h> - #include <errno.h> --#include <pthread.h> - #include "syscall.h" - - int pthread_sigmask(int how, const sigset_t *restrict set, sigset_t *restrict old) -diff --git a/src/thread/synccall.c b/src/thread/synccall.c -index 4127a41..a21578d 100644 ---- a/src/thread/synccall.c -+++ b/src/thread/synccall.c -@@ -1,6 +1,5 @@ - #include "pthread_impl.h" - #include <semaphore.h> --#include <string.h> - - static struct chain { - struct chain *next; -diff --git a/src/time/__map_file.c b/src/time/__map_file.c -index b322f09..84ae839 100644 ---- a/src/time/__map_file.c -+++ b/src/time/__map_file.c -@@ -9,7 +9,7 @@ const char unsigned *__map_file(const char *pathname, size_t *size) - { - struct stat st; - const unsigned char *map = MAP_FAILED; -- int flags = O_RDONLY|O_LARGEFILE|O_CLOEXEC|O_NOFOLLOW|O_NONBLOCK; -+ int flags = O_RDONLY|O_LARGEFILE|O_CLOEXEC|O_NONBLOCK; - int fd = __syscall(SYS_open, pathname, flags); - if (fd < 0) return 0; - if (!__syscall(SYS_fstat, fd, &st)) -diff --git a/src/time/__tz.c b/src/time/__tz.c -index 81676d3..9d56a61 100644 ---- a/src/time/__tz.c -+++ b/src/time/__tz.c -@@ -138,7 +138,7 @@ static void do_tzset() - * free so as not to pull it into static programs. Growth - * strategy makes it so free would have minimal benefit anyway. */ - i = strlen(s); -- if (i > PATH_MAX+1) s = "", i = 0; -+ if (i > PATH_MAX+1) s = __gmt, i = 3; - if (i >= old_tz_size) { - old_tz_size *= 2; - if (i >= old_tz_size) old_tz_size = i+1; -@@ -162,7 +162,7 @@ static void do_tzset() - break; - memcpy(pathname, s, l+1); - pathname[l] = 0; -- for (try=search; !map && *try; try+=l) { -+ for (try=search; !map && *try; try+=l+1) { - l = strlen(try); - memcpy(pathname-l, try, l); - map = __map_file(pathname-l, &map_size); -@@ -176,8 +176,8 @@ static void do_tzset() - if (map) { - int scale = 2; - if (sizeof(time_t) > 4 && map[4]=='2') { -- size_t skip = zi_dotprod(zi, VEC(1,1,8,5,6,1), 6); -- trans = zi+skip+44+20; -+ size_t skip = zi_dotprod(zi+20, VEC(1,1,8,5,6,1), 6); -+ trans = zi+skip+44+44; - scale++; - } else { - trans = zi+44; -diff --git a/src/time/ftime.c b/src/time/ftime.c -new file mode 100644 -index 0000000..a1734d0 ---- /dev/null -+++ b/src/time/ftime.c -@@ -0,0 +1,12 @@ -+#include <sys/timeb.h> -+#include <time.h> -+ -+int ftime(struct timeb *tp) -+{ -+ struct timespec ts; -+ clock_gettime(CLOCK_REALTIME, &ts); -+ tp->time = ts.tv_sec; -+ tp->millitm = ts.tv_nsec / 1000000; -+ tp->timezone = tp->dstflag = 0; -+ return 0; -+} -diff --git a/src/time/mktime.c b/src/time/mktime.c -index ef1fb42..0ab4780 100644 ---- a/src/time/mktime.c -+++ b/src/time/mktime.c -@@ -1,7 +1,5 @@ - #include "time_impl.h" - #include <errno.h> --#include <stdlib.h> --#include <string.h> - - time_t mktime(struct tm *tm) - { -diff --git a/src/time/nanosleep.c b/src/time/nanosleep.c -index c8878b1..a2ff483 100644 ---- a/src/time/nanosleep.c -+++ b/src/time/nanosleep.c -@@ -1,4 +1,3 @@ --#include <unistd.h> - #include <time.h> - #include "syscall.h" - #include "libc.h" -diff --git a/src/time/strftime.c b/src/time/strftime.c -index dac6403..bc15013 100644 ---- a/src/time/strftime.c -+++ b/src/time/strftime.c -@@ -216,7 +216,7 @@ size_t __strftime_l(char *restrict s, size_t n, const char *restrict f, const st - const char *t; - int plus; - unsigned long width; -- for (l=0; l+1<n; f++) { -+ for (l=0; l<n; f++) { - if (!*f) { - s[l] = 0; - return l; -@@ -230,14 +230,13 @@ size_t __strftime_l(char *restrict s, size_t n, const char *restrict f, const st - width = strtoul(f, &p, 10); - if (*p == 'C' || *p == 'F' || *p == 'G' || *p == 'Y') { - if (!width && p!=f) width = 1; -- if (width >= n-l) return 0; - } else { - width = 0; - } - f = p; - if (*f == 'E' || *f == 'O') f++; - t = __strftime_fmt_1(&buf, &k, *f, tm, loc); -- if (!t) return 0; -+ if (!t) break; - if (width) { - for (; *t=='+' || *t=='-' || (*t=='0'&&t[1]); t++, k--); - width--; -@@ -247,14 +246,17 @@ size_t __strftime_l(char *restrict s, size_t n, const char *restrict f, const st - s[l++] = '-'; - else - width++; -- if (width >= n-l) return 0; -- for (; width > k; width--) -+ for (; width > k && l < n; width--) - s[l++] = '0'; - } -- if (k >= n-l) return 0; -+ if (k > n-l) k = n-l; - memcpy(s+l, t, k); - l += k; - } -+ if (n) { -+ if (l==n) l=n-1; -+ s[l] = 0; -+ } - return 0; - } - -diff --git a/src/time/strptime.c b/src/time/strptime.c -index 0f66e6c..d1d141e 100644 ---- a/src/time/strptime.c -+++ b/src/time/strptime.c -@@ -1,4 +1,3 @@ --#include <stdio.h> - #include <stdlib.h> - #include <langinfo.h> - #include <time.h> -diff --git a/src/time/time.c b/src/time/time.c -index 2275485..4b95e75 100644 ---- a/src/time/time.c -+++ b/src/time/time.c -@@ -1,5 +1,4 @@ - #include <time.h> --#include <sys/time.h> - #include "syscall.h" - - int __clock_gettime(clockid_t, struct timespec *); -diff --git a/src/time/wcsftime.c b/src/time/wcsftime.c -index 72af913..8d2a2eb 100644 ---- a/src/time/wcsftime.c -+++ b/src/time/wcsftime.c -@@ -1,6 +1,5 @@ - #include <wchar.h> - #include <time.h> --#include <string.h> - #include <locale.h> - #include "libc.h" - -@@ -16,7 +15,7 @@ size_t __wcsftime_l(wchar_t *restrict s, size_t n, const wchar_t *restrict f, co - const wchar_t *t; - int plus; - unsigned long width; -- for (l=0; l+1<n; f++) { -+ for (l=0; l<n; f++) { - if (!*f) { - s[l] = 0; - return l; -@@ -30,14 +29,13 @@ size_t __wcsftime_l(wchar_t *restrict s, size_t n, const wchar_t *restrict f, co - width = wcstoul(f, &p, 10); - if (*p == 'C' || *p == 'F' || *p == 'G' || *p == 'Y') { - if (!width && p!=f) width = 1; -- if (width >= n-l) return 0; - } else { - width = 0; - } - f = p; - if (*f == 'E' || *f == 'O') f++; - t_mb = __strftime_fmt_1(&buf, &k, *f, tm, loc); -- if (!t_mb) return 0; -+ if (!t_mb) break; - k = mbstowcs(wbuf, t_mb, sizeof wbuf / sizeof *wbuf); - if (k == (size_t)-1) return 0; - t = wbuf; -@@ -50,14 +48,17 @@ size_t __wcsftime_l(wchar_t *restrict s, size_t n, const wchar_t *restrict f, co - s[l++] = '-'; - else - width++; -- if (width >= n-l) return 0; -- for (; width > k; width--) -+ for (; width > k && l < n; width--) - s[l++] = '0'; - } -- if (k >= n-l) return 0; -+ if (k >= n-l) k = n-l; - wmemcpy(s+l, t, k); - l += k; - } -+ if (n) { -+ if (l==n) l=n-1; -+ s[l] = 0; -+ } - return 0; - } - -diff --git a/src/unistd/ctermid.c b/src/unistd/ctermid.c -index ffa9b75..7768405 100644 ---- a/src/unistd/ctermid.c -+++ b/src/unistd/ctermid.c -@@ -1,6 +1,4 @@ - #include <stdio.h> --#include <stdlib.h> --#include <string.h> - #include <fcntl.h> - #include <unistd.h> - #include <limits.h> -diff --git a/src/unistd/faccessat.c b/src/unistd/faccessat.c -index 5b2c5e3..3347895 100644 ---- a/src/unistd/faccessat.c -+++ b/src/unistd/faccessat.c -@@ -1,5 +1,7 @@ - #include <unistd.h> - #include <fcntl.h> -+#include <errno.h> -+#include <sys/wait.h> - #include "syscall.h" - #include "pthread_impl.h" - -@@ -7,19 +9,26 @@ struct ctx { - int fd; - const char *filename; - int amode; -- int p; -+}; -+ -+static const int errors[] = { -+ 0, -EACCES, -ELOOP, -ENAMETOOLONG, -ENOENT, -ENOTDIR, -+ -EROFS, -EBADF, -EINVAL, -ETXTBSY, -+ -EFAULT, -EIO, -ENOMEM, -+ -EBUSY - }; - - static int checker(void *p) - { - struct ctx *c = p; - int ret; -- if (__syscall(SYS_setgid, __syscall(SYS_getegid)) -- || __syscall(SYS_setuid, __syscall(SYS_geteuid))) -+ int i; -+ if (__syscall(SYS_setregid, __syscall(SYS_getegid), -1) -+ || __syscall(SYS_setreuid, __syscall(SYS_geteuid), -1)) - __syscall(SYS_exit, 1); - ret = __syscall(SYS_faccessat, c->fd, c->filename, c->amode, 0); -- __syscall(SYS_write, c->p, &ret, sizeof ret); -- return 0; -+ for (i=0; i < sizeof errors/sizeof *errors - 1 && ret!=errors[i]; i++); -+ return i; - } - - int faccessat(int fd, const char *filename, int amode, int flag) -@@ -32,19 +41,21 @@ int faccessat(int fd, const char *filename, int amode, int flag) - - char stack[1024]; - sigset_t set; -- int ret, p[2]; -- -- if (pipe(p)) return __syscall_ret(-EBUSY); -- struct ctx c = { .fd = fd, .filename = filename, .amode = amode, .p = p[1] }; -+ pid_t pid; -+ int ret = -EBUSY; -+ struct ctx c = { .fd = fd, .filename = filename, .amode = amode }; - - __block_all_sigs(&set); - -- ret = __clone(checker, stack+sizeof stack, 0, &c); -- __syscall(SYS_close, p[1]); -- -- if (ret<0 || __syscall(SYS_read, p[0], &ret, sizeof ret) != sizeof(ret)) -- ret = -EBUSY; -- __syscall(SYS_close, p[0]); -+ pid = __clone(checker, stack+sizeof stack, 0, &c); -+ if (pid > 0) { -+ int status; -+ do { -+ __syscall(SYS_wait4, pid, &status, __WCLONE, 0); -+ } while (!WIFEXITED(status) && !WIFSIGNALED(status)); -+ if (WIFEXITED(status)) -+ ret = errors[WEXITSTATUS(status)]; -+ } - - __restore_sigs(&set); - -diff --git a/src/unistd/getcwd.c b/src/unistd/getcwd.c -index 2e540cd..a7b925d 100644 ---- a/src/unistd/getcwd.c -+++ b/src/unistd/getcwd.c -@@ -7,7 +7,13 @@ - char *getcwd(char *buf, size_t size) - { - char tmp[PATH_MAX]; -- if (!buf) buf = tmp, size = PATH_MAX; -+ if (!buf) { -+ buf = tmp; -+ size = PATH_MAX; -+ } else if (!size) { -+ errno = EINVAL; -+ return 0; -+ } - if (syscall(SYS_getcwd, buf, size) < 0) return 0; - return buf == tmp ? strdup(buf) : buf; - } -diff --git a/src/unistd/gethostname.c b/src/unistd/gethostname.c -index a406c4e..f984b7d 100644 ---- a/src/unistd/gethostname.c -+++ b/src/unistd/gethostname.c -@@ -1,6 +1,5 @@ - #include <unistd.h> - #include <sys/utsname.h> --#include <string.h> - - int gethostname(char *name, size_t len) - { -diff --git a/src/unistd/getlogin_r.c b/src/unistd/getlogin_r.c -index 37ce0d4..53866c6 100644 ---- a/src/unistd/getlogin_r.c -+++ b/src/unistd/getlogin_r.c -@@ -1,5 +1,4 @@ - #include <unistd.h> --#include <stdlib.h> - #include <string.h> - #include <errno.h> - -diff --git a/src/unistd/posix_close.c b/src/unistd/posix_close.c -new file mode 100644 -index 0000000..90f51a8 ---- /dev/null -+++ b/src/unistd/posix_close.c -@@ -0,0 +1,6 @@ -+#include <unistd.h> -+ -+int posix_close(int fd, int flags) -+{ -+ return close(fd); -+} -diff --git a/src/unistd/ttyname_r.c b/src/unistd/ttyname_r.c -index a2ce351..8bac7b2 100644 ---- a/src/unistd/ttyname_r.c -+++ b/src/unistd/ttyname_r.c -@@ -1,7 +1,5 @@ - #include <unistd.h> - #include <errno.h> --#include <stdio.h> --#include <string.h> - - void __procfdname(char *, unsigned); - -diff --git a/src/unistd/usleep.c b/src/unistd/usleep.c -index ce1c814..6c96652 100644 ---- a/src/unistd/usleep.c -+++ b/src/unistd/usleep.c -@@ -1,3 +1,4 @@ -+#define _GNU_SOURCE - #include <unistd.h> - #include <time.h> - -diff --git a/tools/install.sh b/tools/install.sh -index 7dcea33..4e5a8b9 100755 ---- a/tools/install.sh -+++ b/tools/install.sh -@@ -53,7 +53,7 @@ else - cat < "$1" > "$tmp" - fi - --mv "$tmp" "$2" -+mv -f "$tmp" "$2" - test -d "$2" && { - rm -f "$2/$tmp" - printf "%s: %s is a directory\n" "$0" "$dst" 1>&2 -diff --git a/tools/version.sh b/tools/version.sh -new file mode 100644 -index 0000000..f1cc594 ---- /dev/null -+++ b/tools/version.sh -@@ -0,0 +1,12 @@ -+#!/bin/sh -+ -+if test -d .git ; then -+if type git >/dev/null 2>&1 ; then -+git describe --tags --match 'v[0-9]*' 2>/dev/null \ -+| sed -e 's/^v//' -e 's/-/-git-/' -+else -+sed 's/$/-git/' < VERSION -+fi -+else -+cat VERSION -+fi - diff --git a/main/musl/0002-fix-hangs-in-localtime-for-near-overflowing-time_t.patch b/main/musl/0002-fix-hangs-in-localtime-for-near-overflowing-time_t.patch deleted file mode 100644 index a9f2e8e991..0000000000 --- a/main/musl/0002-fix-hangs-in-localtime-for-near-overflowing-time_t.patch +++ /dev/null @@ -1,25 +0,0 @@ -From f89e29829029c5003450f7b58bd00fe5d1049d09 Mon Sep 17 00:00:00 2001 -From: Rich Felker <dalias@aerifal.cx> -Date: Thu, 19 Dec 2013 10:05:13 +0000 -Subject: fix hangs in localtime for near-overflowing time_t values on 64-bit archs - ---- -diff --git a/src/time/localtime_r.c b/src/time/localtime_r.c -index c52678f..1d43d9f 100644 ---- a/src/time/localtime_r.c -+++ b/src/time/localtime_r.c -@@ -4,6 +4,12 @@ - - struct tm *__localtime_r(const time_t *restrict t, struct tm *restrict tm) - { -+ /* Reject time_t values whose year would overflow int because -+ * __secs_to_zone cannot safely handle them. */ -+ if (*t < INT_MIN * 31622400LL || *t > INT_MAX * 31622400LL) { -+ errno = EOVERFLOW; -+ return 0; -+ } - __secs_to_zone(*t, 0, &tm->tm_isdst, &tm->__tm_gmtoff, 0, &tm->__tm_zone); - if (__secs_to_tm((long long)*t - tm->__tm_gmtoff, tm) < 0) { - errno = EOVERFLOW; --- -cgit v0.9.0.3-65-g4555 diff --git a/main/musl/0003-fix-failure-of-fchmod-fstat-fchdir-and-fchown-to-pro.patch b/main/musl/0003-fix-failure-of-fchmod-fstat-fchdir-and-fchown-to-pro.patch deleted file mode 100644 index f62d5ac6c4..0000000000 --- a/main/musl/0003-fix-failure-of-fchmod-fstat-fchdir-and-fchown-to-pro.patch +++ /dev/null @@ -1,116 +0,0 @@ -From 65ea604c74f3fecbc61a266a22fdf527764995b6 Mon Sep 17 00:00:00 2001 -From: Rich Felker <dalias@aerifal.cx> -Date: Thu, 19 Dec 2013 14:24:55 -0500 -Subject: [PATCH 1/1] fix failure of fchmod, fstat, fchdir, and fchown to - produce EBADF - -the workaround/fallback code for supporting O_PATH file descriptors -when the kernel lacks support for performing these operations on them -caused EBADF to get replaced by ENOENT (due to missing entry in -/proc/self/fd). this is unlikely to affect real-world code (calls that -might yield EBADF are generally unsafe, especially in library code) -but it was breaking some test cases. - -the fix I've applied is something of a tradeoff: it adds one syscall -to these operations on kernels where the workaround is needed. the -alternative would be to catch ENOENT from the /proc lookup and -translate it to EBADF, but I want to avoid doing that in the interest -of not touching/depending on /proc at all in these functions as long -as the kernel correctly supports the operations. this is following the -general principle of isolating hacks to code paths that are taken on -broken systems, and keeping the code for correct systems completely -hack-free. ---- - src/stat/fchmod.c | 4 +++- - src/stat/fstat.c | 4 +++- - src/unistd/fchdir.c | 4 +++- - src/unistd/fchown.c | 4 +++- - 4 files changed, 12 insertions(+), 4 deletions(-) - -diff --git a/src/stat/fchmod.c b/src/stat/fchmod.c -index 1b943d4..6d28141 100644 ---- a/src/stat/fchmod.c -+++ b/src/stat/fchmod.c -@@ -1,5 +1,6 @@ - #include <sys/stat.h> - #include <errno.h> -+#include <fcntl.h> - #include "syscall.h" - - void __procfdname(char *, unsigned); -@@ -7,7 +8,8 @@ void __procfdname(char *, unsigned); - int fchmod(int fd, mode_t mode) - { - int ret = __syscall(SYS_fchmod, fd, mode); -- if (ret != -EBADF || fd < 0) return __syscall_ret(ret); -+ if (ret != -EBADF || __syscall(SYS_fcntl, fd, F_GETFD) < 0) -+ return __syscall_ret(ret); - - char buf[15+3*sizeof(int)]; - __procfdname(buf, fd); -diff --git a/src/stat/fstat.c b/src/stat/fstat.c -index 29b4243..b561176 100644 ---- a/src/stat/fstat.c -+++ b/src/stat/fstat.c -@@ -1,5 +1,6 @@ - #include <sys/stat.h> - #include <errno.h> -+#include <fcntl.h> - #include "syscall.h" - #include "libc.h" - -@@ -8,7 +9,8 @@ void __procfdname(char *, unsigned); - int fstat(int fd, struct stat *st) - { - int ret = __syscall(SYS_fstat, fd, st); -- if (ret != -EBADF || fd < 0) return __syscall_ret(ret); -+ if (ret != -EBADF || __syscall(SYS_fcntl, fd, F_GETFD) < 0) -+ return __syscall_ret(ret); - - char buf[15+3*sizeof(int)]; - __procfdname(buf, fd); -diff --git a/src/unistd/fchdir.c b/src/unistd/fchdir.c -index 9fbc815..72c3915 100644 ---- a/src/unistd/fchdir.c -+++ b/src/unistd/fchdir.c -@@ -1,5 +1,6 @@ - #include <unistd.h> - #include <errno.h> -+#include <fcntl.h> - #include "syscall.h" - - void __procfdname(char *, unsigned); -@@ -7,7 +8,8 @@ void __procfdname(char *, unsigned); - int fchdir(int fd) - { - int ret = __syscall(SYS_fchdir, fd); -- if (ret != -EBADF || fd < 0) return __syscall_ret(ret); -+ if (ret != -EBADF || __syscall(SYS_fcntl, fd, F_GETFD) < 0) -+ return __syscall_ret(ret); - - char buf[15+3*sizeof(int)]; - __procfdname(buf, fd); -diff --git a/src/unistd/fchown.c b/src/unistd/fchown.c -index e1c3198..36633b0 100644 ---- a/src/unistd/fchown.c -+++ b/src/unistd/fchown.c -@@ -1,5 +1,6 @@ - #include <unistd.h> - #include <errno.h> -+#include <fcntl.h> - #include "syscall.h" - - void __procfdname(char *, unsigned); -@@ -7,7 +8,8 @@ void __procfdname(char *, unsigned); - int fchown(int fd, uid_t uid, gid_t gid) - { - int ret = __syscall(SYS_fchown, fd, uid, gid); -- if (ret != -EBADF || fd < 0) return __syscall_ret(ret); -+ if (ret != -EBADF || __syscall(SYS_fcntl, fd, F_GETFD) < 0) -+ return __syscall_ret(ret); - - char buf[15+3*sizeof(int)]; - __procfdname(buf, fd); --- -1.8.5.1 - diff --git a/main/musl/1002-add-sys-quota.h-and-quotactl-syscall-wrapper.patch b/main/musl/1002-add-sys-quota.h-and-quotactl-syscall-wrapper.patch deleted file mode 100644 index 218382ac5c..0000000000 --- a/main/musl/1002-add-sys-quota.h-and-quotactl-syscall-wrapper.patch +++ /dev/null @@ -1,138 +0,0 @@ -From 03dbf5d8e44e2e3bca6a55bec189d1682442b0cd Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Timo=20Ter=C3=A4s?= <timo.teras@iki.fi> -Date: Wed, 18 Dec 2013 08:41:22 +0200 -Subject: [PATCH] add sys/quota.h and quotactl syscall wrapper - ---- - include/sys/quota.h | 104 +++++++++++++++++++++++++++++++++++++++++++++++++++ - src/linux/quotactl.c | 7 ++++ - 2 files changed, 111 insertions(+) - create mode 100644 include/sys/quota.h - create mode 100644 src/linux/quotactl.c - -diff --git a/include/sys/quota.h b/include/sys/quota.h -new file mode 100644 -index 0000000..7bcad02 ---- /dev/null -+++ b/include/sys/quota.h -@@ -0,0 +1,104 @@ -+#ifndef _SYS_SYSCTL_H -+#define _SYS_SYSCTL_H -+ -+#ifdef __cplusplus -+extern "C" { -+#endif -+ -+#include <stdint.h> -+ -+#define _LINUX_QUOTA_VERSION 2 -+ -+#define dbtob(num) ((num) << 10) -+#define btodb(num) ((num) >> 10) -+#define fs_to_dq_blocks(num, blksize) (((num) * (blksize)) / BLOCK_SIZE) -+ -+#define MAX_IQ_TIME 604800 -+#define MAX_DQ_TIME 604800 -+ -+#define MAXQUOTAS 2 -+#define USRQUOTA 0 -+#define GRPQUOTA 1 -+ -+#define INITQFNAMES { "user", "group", "undefined" }; -+ -+#define QUOTAFILENAME "quota" -+#define QUOTAGROUP "staff" -+ -+#define NR_DQHASH 43 -+#define NR_DQUOTS 256 -+ -+#define SUBCMDMASK 0x00ff -+#define SUBCMDSHIFT 8 -+#define QCMD(cmd, type) (((cmd) << SUBCMDSHIFT) | ((type) & SUBCMDMASK)) -+ -+#define Q_SYNC 0x800001 -+#define Q_QUOTAON 0x800002 -+#define Q_QUOTAOFF 0x800003 -+#define Q_GETFMT 0x800004 -+#define Q_GETINFO 0x800005 -+#define Q_SETINFO 0x800006 -+#define Q_GETQUOTA 0x800007 -+#define Q_SETQUOTA 0x800008 -+ -+#define QFMT_VFS_OLD 1 -+#define QFMT_VFS_V0 2 -+#define QFMT_OCFS2 3 -+#define QFMT_VFS_V1 4 -+ -+#define QIF_BLIMITS 1 -+#define QIF_SPACE 2 -+#define QIF_ILIMITS 4 -+#define QIF_INODES 8 -+#define QIF_BTIME 16 -+#define QIF_ITIME 32 -+#define QIF_LIMITS (QIF_BLIMITS | QIF_ILIMITS) -+#define QIF_USAGE (QIF_SPACE | QIF_INODES) -+#define QIF_TIMES (QIF_BTIME | QIF_ITIME) -+#define QIF_ALL (QIF_LIMITS | QIF_USAGE | QIF_TIMES) -+ -+struct dqblk -+{ -+ uint64_t dqb_bhardlimit; -+ uint64_t dqb_bsoftlimit; -+ uint64_t dqb_curspace; -+ uint64_t dqb_ihardlimit; -+ uint64_t dqb_isoftlimit; -+ uint64_t dqb_curinodes; -+ uint64_t dqb_btime; -+ uint64_t dqb_itime; -+ uint32_t dqb_valid; -+}; -+ -+#define dq_bhardlimit dq_dqb.dqb_bhardlimit -+#define dq_bsoftlimit dq_dqb.dqb_bsoftlimit -+#define dq_curspace dq_dqb.dqb_curspace -+#define dq_valid dq_dqb.dqb_valid -+#define dq_ihardlimit dq_dqb.dqb_ihardlimit -+#define dq_isoftlimit dq_dqb.dqb_isoftlimit -+#define dq_curinodes dq_dqb.dqb_curinodes -+#define dq_btime dq_dqb.dqb_btime -+#define dq_itime dq_dqb.dqb_itime -+ -+#define dqoff(UID) ((loff_t)((UID) * sizeof (struct dqblk))) -+ -+#define IIF_BGRACE 1 -+#define IIF_IGRACE 2 -+#define IIF_FLAGS 4 -+#define IIF_ALL (IIF_BGRACE | IIF_IGRACE | IIF_FLAGS) -+ -+struct dqinfo -+{ -+ uint64_t dqi_bgrace; -+ uint64_t dqi_igrace; -+ uint32_t dqi_flags; -+ uint32_t dqi_valid; -+}; -+ -+int quotactl(int, const char *, int, char *); -+ -+#ifdef __cplusplus -+} -+#endif -+ -+#endif -diff --git a/src/linux/quotactl.c b/src/linux/quotactl.c -new file mode 100644 -index 0000000..344eb0d ---- /dev/null -+++ b/src/linux/quotactl.c -@@ -0,0 +1,7 @@ -+#include <sys/quota.h> -+#include "syscall.h" -+ -+int quotactl(int cmd, const char *special, int id, char *addr) -+{ -+ return syscall(SYS_quotactl, cmd, special, id, addr); -+} --- -1.8.5.1 - diff --git a/main/musl/1003-add-netinet-igmp.h-and-multicast-groups-to-netinet-i.patch b/main/musl/1003-add-netinet-igmp.h-and-multicast-groups-to-netinet-i.patch deleted file mode 100644 index ca8bfdaf93..0000000000 --- a/main/musl/1003-add-netinet-igmp.h-and-multicast-groups-to-netinet-i.patch +++ /dev/null @@ -1,88 +0,0 @@ -From e136625c8e0dc757dd1bd335bfca6e753e06d185 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Timo=20Ter=C3=A4s?= <timo.teras@iki.fi> -Date: Wed, 18 Dec 2013 08:47:01 +0200 -Subject: [PATCH] add netinet/igmp.h and multicast groups to netinet/in.h - ---- - include/netinet/igmp.h | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++ - include/netinet/in.h | 5 +++++ - 2 files changed, 57 insertions(+) - create mode 100644 include/netinet/igmp.h - -diff --git a/include/netinet/igmp.h b/include/netinet/igmp.h -new file mode 100644 -index 0000000..822a6c7 ---- /dev/null -+++ b/include/netinet/igmp.h -@@ -0,0 +1,52 @@ -+#ifndef _NETINET_IGMP_H -+#define _NETINET_IGMP_H 1 -+ -+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE) -+ -+#include <sys/types.h> -+#include <netinet/in.h> -+ -+struct igmp { -+ u_int8_t igmp_type; /* IGMP type */ -+ u_int8_t igmp_code; /* routing code */ -+ u_int16_t igmp_cksum; /* checksum */ -+ struct in_addr igmp_group; /* group address */ -+}; -+ -+#define IGMP_MINLEN 8 -+ -+#define IGMP_MEMBERSHIP_QUERY 0x11 /* membership query */ -+#define IGMP_V1_MEMBERSHIP_REPORT 0x12 /* Ver. 1 membership report */ -+#define IGMP_V2_MEMBERSHIP_REPORT 0x16 /* Ver. 2 membership report */ -+#define IGMP_V2_LEAVE_GROUP 0x17 /* Leave-group message */ -+ -+#define IGMP_DVMRP 0x13 /* DVMRP routing message */ -+#define IGMP_PIM 0x14 /* PIM routing message */ -+#define IGMP_TRACE 0x15 -+ -+#define IGMP_MTRACE_RESP 0x1e /* traceroute resp.(to sender)*/ -+#define IGMP_MTRACE 0x1f /* mcast traceroute messages */ -+ -+#define IGMP_MAX_HOST_REPORT_DELAY 10 /* max delay for response to */ -+ /* query (in seconds) according */ -+ /* to RFC1112 */ -+#define IGMP_TIMER_SCALE 10 /* denotes that the igmp code field */ -+ /* specifies time in 10th of seconds*/ -+ -+#define IGMP_DELAYING_MEMBER 1 -+#define IGMP_IDLE_MEMBER 2 -+#define IGMP_LAZY_MEMBER 3 -+#define IGMP_SLEEPING_MEMBER 4 -+#define IGMP_AWAKENING_MEMBER 5 -+ -+#define IGMP_v1_ROUTER 1 -+#define IGMP_v2_ROUTER 2 -+ -+#define IGMP_HOST_MEMBERSHIP_QUERY IGMP_MEMBERSHIP_QUERY -+#define IGMP_HOST_MEMBERSHIP_REPORT IGMP_V1_MEMBERSHIP_REPORT -+#define IGMP_HOST_NEW_MEMBERSHIP_REPORT IGMP_V2_MEMBERSHIP_REPORT -+#define IGMP_HOST_LEAVE_MESSAGE IGMP_V2_LEAVE_GROUP -+ -+#endif -+ -+#endif -diff --git a/include/netinet/in.h b/include/netinet/in.h -index 8be51e8..db96144 100644 ---- a/include/netinet/in.h -+++ b/include/netinet/in.h -@@ -53,6 +53,11 @@ struct ipv6_mreq - #define INADDR_NONE ((in_addr_t) 0xffffffff) - #define INADDR_LOOPBACK ((in_addr_t) 0x7f000001) - -+#define INADDR_UNSPEC_GROUP ((in_addr_t) 0xe0000000) -+#define INADDR_ALLHOSTS_GROUP ((in_addr_t) 0xe0000001) -+#define INADDR_ALLRTRS_GROUP ((in_addr_t) 0xe0000002) -+#define INADDR_MAX_LOCAL_GROUP ((in_addr_t) 0xe00000ff) -+ - #define IN6ADDR_ANY_INIT { { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } } } - #define IN6ADDR_LOOPBACK_INIT { { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 } } } - --- -1.8.5.1 - diff --git a/main/musl/1004-define-and-implement-herror.patch b/main/musl/1004-define-and-implement-herror.patch deleted file mode 100644 index 0935dff6c8..0000000000 --- a/main/musl/1004-define-and-implement-herror.patch +++ /dev/null @@ -1,55 +0,0 @@ -From 2a21ef4263d853616df24cc8e4c00f5a2c2980e9 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Timo=20Ter=C3=A4s?= <timo.teras@iki.fi> -Date: Wed, 18 Dec 2013 13:24:06 +0200 -Subject: [PATCH] define and implement herror - ---- - include/netdb.h | 1 + - src/network/herror.c | 23 +++++++++++++++++++++++ - 2 files changed, 24 insertions(+) - create mode 100644 src/network/herror.c - -diff --git a/include/netdb.h b/include/netdb.h -index 8a7013a..2dd799b 100644 ---- a/include/netdb.h -+++ b/include/netdb.h -@@ -134,6 +134,7 @@ int *__h_errno_location(void); - #endif - - #if defined(_GNU_SOURCE) || defined(_BSD_SOURCE) -+void herror(const char *); - const char *hstrerror(int); - int gethostbyname_r(const char *, struct hostent *, char *, size_t, struct hostent **, int *); - int gethostbyname2_r(const char *, int, struct hostent *, char *, size_t, struct hostent **, int *); -diff --git a/src/network/herror.c b/src/network/herror.c -new file mode 100644 -index 0000000..25117a3 ---- /dev/null -+++ b/src/network/herror.c -@@ -0,0 +1,23 @@ -+#define _GNU_SOURCE -+#include <stdio.h> -+#include <string.h> -+#include <netdb.h> -+#include "stdio_impl.h" -+ -+void herror(const char *msg) -+{ -+ FILE *f = stderr; -+ const char *errstr = hstrerror(h_errno); -+ -+ FLOCK(f); -+ -+ if (msg && *msg) { -+ fwrite(msg, strlen(msg), 1, f); -+ fputc(':', f); -+ fputc(' ', f); -+ } -+ fwrite(errstr, strlen(errstr), 1, f); -+ fputc('\n', f); -+ -+ FUNLOCK(f); -+} --- -1.8.5.1 - diff --git a/main/musl/1005-add-TCP_INFO-and-TCP_MD5SIG-socket-option-related-st.patch b/main/musl/1005-add-TCP_INFO-and-TCP_MD5SIG-socket-option-related-st.patch deleted file mode 100644 index 7af697cdc3..0000000000 --- a/main/musl/1005-add-TCP_INFO-and-TCP_MD5SIG-socket-option-related-st.patch +++ /dev/null @@ -1,81 +0,0 @@ -From 38c01bb8b97d911d3eb5d1ab48ad40c0857f78cb Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Timo=20Ter=C3=A4s?= <timo.teras@iki.fi> -Date: Wed, 18 Dec 2013 13:53:11 +0200 -Subject: [PATCH] add TCP_INFO and TCP_MD5SIG socket option related structures - ---- - include/netinet/tcp.h | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 58 insertions(+) - -diff --git a/include/netinet/tcp.h b/include/netinet/tcp.h -index 5212ef7..5639b89 100644 ---- a/include/netinet/tcp.h -+++ b/include/netinet/tcp.h -@@ -79,6 +79,64 @@ struct tcphdr - u_int16_t check; - u_int16_t urg_ptr; - }; -+ -+#define TCPI_OPT_TIMESTAMPS 1 -+#define TCPI_OPT_SACK 2 -+#define TCPI_OPT_WSCALE 4 -+#define TCPI_OPT_ECN 8 -+ -+#define TCP_CA_Open 0 -+#define TCP_CA_Disorder 1 -+#define TCP_CA_CWR 2 -+#define TCP_CA_Recovery 3 -+#define TCP_CA_Loss 4 -+ -+struct tcp_info -+{ -+ u_int8_t tcpi_state; -+ u_int8_t tcpi_ca_state; -+ u_int8_t tcpi_retransmits; -+ u_int8_t tcpi_probes; -+ u_int8_t tcpi_backoff; -+ u_int8_t tcpi_options; -+ u_int8_t tcpi_snd_wscale : 4, tcpi_rcv_wscale : 4; -+ u_int32_t tcpi_rto; -+ u_int32_t tcpi_ato; -+ u_int32_t tcpi_snd_mss; -+ u_int32_t tcpi_rcv_mss; -+ u_int32_t tcpi_unacked; -+ u_int32_t tcpi_sacked; -+ u_int32_t tcpi_lost; -+ u_int32_t tcpi_retrans; -+ u_int32_t tcpi_fackets; -+ u_int32_t tcpi_last_data_sent; -+ u_int32_t tcpi_last_ack_sent; -+ u_int32_t tcpi_last_data_recv; -+ u_int32_t tcpi_last_ack_recv; -+ u_int32_t tcpi_pmtu; -+ u_int32_t tcpi_rcv_ssthresh; -+ u_int32_t tcpi_rtt; -+ u_int32_t tcpi_rttvar; -+ u_int32_t tcpi_snd_ssthresh; -+ u_int32_t tcpi_snd_cwnd; -+ u_int32_t tcpi_advmss; -+ u_int32_t tcpi_reordering; -+ u_int32_t tcpi_rcv_rtt; -+ u_int32_t tcpi_rcv_space; -+ u_int32_t tcpi_total_retrans; -+}; -+ -+#define TCP_MD5SIG_MAXKEYLEN 80 -+ -+struct tcp_md5sig -+{ -+ struct sockaddr_storage tcpm_addr; -+ u_int16_t __tcpm_pad1; -+ u_int16_t tcpm_keylen; -+ u_int32_t __tcpm_pad2; -+ u_int8_t tcpm_key[TCP_MD5SIG_MAXKEYLEN]; -+}; -+ - #endif - - #endif --- -1.8.5.1 - diff --git a/main/musl/1006-fix-struct-signalfd_siginfo.patch b/main/musl/1006-fix-struct-signalfd_siginfo.patch deleted file mode 100644 index f8c1634bfb..0000000000 --- a/main/musl/1006-fix-struct-signalfd_siginfo.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 5979593566fd4b22ab076f2a699b238006dc0c67 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Timo=20Ter=C3=A4s?= <timo.teras@iki.fi> -Date: Wed, 25 Dec 2013 13:33:46 +0200 -Subject: [PATCH] fix struct signalfd_siginfo - -ssi_ptr is really 64-bit in kernel, so fix that. assuming sizeof(void*) -for it also caused incorrect padding for 32-bits, as the following -64-bits are aligned to 64-bits (and the padding was not taken into -account), so fix the padding as well. add addr_lsb field while there. ---- - include/sys/signalfd.h | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) - -diff --git a/include/sys/signalfd.h b/include/sys/signalfd.h -index 4f3d399..55431b9 100644 ---- a/include/sys/signalfd.h -+++ b/include/sys/signalfd.h -@@ -30,11 +30,12 @@ struct signalfd_siginfo { - uint32_t ssi_trapno; - int32_t ssi_status; - int32_t ssi_int; -- uintptr_t ssi_ptr; -+ uint64_t ssi_ptr; - uint64_t ssi_utime; - uint64_t ssi_stime; - uint64_t ssi_addr; -- uint8_t pad[128-12*4-sizeof(void *)-3*8]; -+ uint16_t ssi_addr_lsb; -+ uint8_t pad[128-12*4-4*8-2]; - }; - - #ifdef __cplusplus --- -1.8.5.1 - diff --git a/main/musl/APKBUILD b/main/musl/APKBUILD index cf5e0b23b9..0742d1f590 100644 --- a/main/musl/APKBUILD +++ b/main/musl/APKBUILD @@ -1,8 +1,8 @@ # Contributor: William Pitcock <nenolod@dereferenced.org> # Maintainer: Timo Teräs <timo.teras@iki.fi> pkgname=musl -pkgver=0.9.14 -pkgrel=12 +pkgver=0.9.15 +pkgrel=0 pkgdesc="the musl c library (libc) implementation" url="http://www.musl-libc.org/" arch="all" @@ -14,17 +14,7 @@ install="" subpackages="$pkgname-dev $pkgname-utils" [ "${CTARGET#*musl}" = "$CTARGET" ] && subpackages="$subpackages musl-gcc:crosstool" source="http://www.musl-libc.org/releases/musl-$pkgver.tar.gz - 0001-updates-from-git.patch - 0002-fix-hangs-in-localtime-for-near-overflowing-time_t.patch - 0003-fix-failure-of-fchmod-fstat-fchdir-and-fchown-to-pro.patch - 1001-add-basic-dns-record-parsing-functions.patch - 1002-add-sys-quota.h-and-quotactl-syscall-wrapper.patch - 1003-add-netinet-igmp.h-and-multicast-groups-to-netinet-i.patch - 1004-define-and-implement-herror.patch - 1005-add-TCP_INFO-and-TCP_MD5SIG-socket-option-related-st.patch - 1006-fix-struct-signalfd_siginfo.patch - 2001-workaround-gcc-pr58245.patch getopt_long.c @@ -116,46 +106,22 @@ crosstool() { find "$pkgdir" -type d -delete 2>/dev/null } -md5sums="bfb685695aa942e64c63170589e575b2 musl-0.9.14.tar.gz -de075c4b6ff2bf406f437d100f06c6bd 0001-updates-from-git.patch -6cb4691d52d1567346e648567df283de 0002-fix-hangs-in-localtime-for-near-overflowing-time_t.patch -1190ec4f2310129c5363dd4eae29a72c 0003-fix-failure-of-fchmod-fstat-fchdir-and-fchown-to-pro.patch +md5sums="06f590a38c85722ee9343db2416425f4 musl-0.9.15.tar.gz a3810683ef61ac27e2f6ec9801280c81 1001-add-basic-dns-record-parsing-functions.patch -06a67be89404258c321c08348cb547ce 1002-add-sys-quota.h-and-quotactl-syscall-wrapper.patch -bb7b6eb67c1749943f378c88acc48e5c 1003-add-netinet-igmp.h-and-multicast-groups-to-netinet-i.patch -fcf15ee683ea241ad26330c28934fa27 1004-define-and-implement-herror.patch -e46d5241827593673a3d8f1a6b8bacdc 1005-add-TCP_INFO-and-TCP_MD5SIG-socket-option-related-st.patch -facf88b880202a3665de40524b2c89ea 1006-fix-struct-signalfd_siginfo.patch 7a09c5cd7b3e9532e6902f54a5e928bb 2001-workaround-gcc-pr58245.patch 61c6c1e84ed1df82abbe6d75e90cf21c getopt_long.c 0df687757221bbb0fc1aa67f1bd646f9 __stack_chk_fail_local.c ef81489a6258501cf45db58dfc6d5211 getent 33e4fd94e2560e008e2c3b431d0e3419 ldconfig" -sha256sums="982e9de1287cf95f9aa526adba008660d8885bfccc41faf5c613ea47f1922872 musl-0.9.14.tar.gz -d8e303e61f2cc220ce2b7ffd992d37406b87dd2a4062f61f5de3e0df144227b0 0001-updates-from-git.patch -3efe2d67f6e1601dd1c946f79e142dc1c4aeb8f1d3256bf48dec2057a506d5fe 0002-fix-hangs-in-localtime-for-near-overflowing-time_t.patch -027720d36cbca364690f5eaae5dcf7efef74b8eae784e8a048fd46a4f2732329 0003-fix-failure-of-fchmod-fstat-fchdir-and-fchown-to-pro.patch +sha256sums="4a7baab8f295511196dee48d33b8b82a159a81233facb89433707c792033cbe7 musl-0.9.15.tar.gz 758390768b1bc4159d56908ca332b9640cd0552ed3b4b2b8d4a6d499c54c11a1 1001-add-basic-dns-record-parsing-functions.patch -4ef5ae263b55c0c691c5fb212bcdaa2050091e6acfa2a6dffc597db9743b8c53 1002-add-sys-quota.h-and-quotactl-syscall-wrapper.patch -f57dee5a9309055b298056e4d4107c67e3b0d5f164ab277ffcb353fb1688a2d2 1003-add-netinet-igmp.h-and-multicast-groups-to-netinet-i.patch -995d3e6a7013f220cf3fdeae7ebfd84a1dc2517ebf53e712ab10c8b379e8ac9e 1004-define-and-implement-herror.patch -2fb0f1b6f7f0092f5f8f144cede321ad375379e93805440af538d2be846d0c24 1005-add-TCP_INFO-and-TCP_MD5SIG-socket-option-related-st.patch -1f6b55e003c395f56c7ba23c4eb7de39943b01754f5ee9b3b2289ab4337bca02 1006-fix-struct-signalfd_siginfo.patch 45d6efda7450809e4e68f6e951431dcadf6cb7f0260930d50a9f1a8667aca49f 2001-workaround-gcc-pr58245.patch d9b644ec20bc33e81a7c52b9fcf7973d835923a69faf50f03db45534b811bd96 getopt_long.c 299a7d75a09de3e2e11e7fb4acc3182e4a14e868093d2f30938fce9bfcff13da __stack_chk_fail_local.c d6996273f5aaaed429058257e4646b243d9e3a4d8609522f802762453f5be4cb getent 306c6ca7407560340797866e077e053627ad409277d1b9da58106fce4cf717cb ldconfig" -sha512sums="e5c3f7b1549dc2f9cbd3359cc413f761d5967607c23705f651c33d0ae93f00582193a41fe1f87158467d58d8eba2d7c09e0fe2f2b2c02c1dda78eee1a4cecff6 musl-0.9.14.tar.gz -1f93d537e707c60f53823419477fd9165e0aa8b6b28c6b95b80222c943b572029dcdaec2c1bb34e20e5c8c73c6869b89f5bea5b99f401db64d0a4c00abc4b092 0001-updates-from-git.patch -0ffe19fad7a8c572cd9f8a5bb7dec02fe9ac9555a09f74008fa7d7741e76a969e087670f132038c2a238b523b8c636bbc82e1f29db6b77b195d7b3b8efd90137 0002-fix-hangs-in-localtime-for-near-overflowing-time_t.patch -7c50c54c2fea33ff2a217eaf145bfc38524afcc7ca43d50463c89741b4d966bb77c6ca53ccc1752b08b6d92b2a53996b730a222d355d68bcd8df8b66b5ed8e32 0003-fix-failure-of-fchmod-fstat-fchdir-and-fchown-to-pro.patch +sha512sums="2c5f3e742cf29fd76db8079b6012b1b359eda635593995ea8add008abc9744f0ca504e915f7828692aeafc3bddc66e0716492182cd5696e2fa24d9a2289601b8 musl-0.9.15.tar.gz dad965258daf69371b844f76bfe5a914b0eca0ca76f3fc340b8fd7acf598b5f87bbe6d68b1f43ed0293ee0ed3bfd85d5173ccc169aa6265646248d5b8a906708 1001-add-basic-dns-record-parsing-functions.patch -c64a8c5fa7f0ad095e9281cf23eeed70f476adadb044eb8ac8e038153fd19accf601d82cf89dc289c933b7cbfce3e59ba6c03fa5f7a3a63038905453b5b152a1 1002-add-sys-quota.h-and-quotactl-syscall-wrapper.patch -a8bb390658552b766c1d92cf261bc77bd2369cd185d9803f2ba0265713de16f812dfe916a4d1b428bf5073848741800d856571009042e7514098344d31751f45 1003-add-netinet-igmp.h-and-multicast-groups-to-netinet-i.patch -c510abb133aedc25a421837ee9e8e02d22d512fab2534d7ac612c2df1df28484d4a7e9ccef0ceec85ba2fb27ecea916d242dfbfff13159d22c4da4757a06e4f5 1004-define-and-implement-herror.patch -a6bd33dcd80a525b9aacb5947ed294fd67148b83c02b139dcb8af39aaff0a27964aa6a640b07331d0f433df22ca3f177d7422b61917d42307cefddf7352002e5 1005-add-TCP_INFO-and-TCP_MD5SIG-socket-option-related-st.patch -bde8bf601451034e73f8502832794c1f04a4d16b5cd0839ca7d547be4ce178185aa45d81f5bc051470e4caae9e349d0bc287ed752bd692442d1bd90a8540da13 1006-fix-struct-signalfd_siginfo.patch 69ad3fc851b44f33dd7c98b83fd0adbd149b37263d17b989f4d7338ee0703dfe8994f4299744e2509492300227d652de6f21b6cdba9b633fcefd3d9f7ca0cf20 2001-workaround-gcc-pr58245.patch 140f3f20d30bd95ebce8c41b8cc7f616c6cbedf4ea06c729c21014e74f6043796825cc40ebc5180620ea38173afdba23f09ebf6d8b11fa05440b14d23764fca9 getopt_long.c 062bb49fa54839010acd4af113e20f7263dde1c8a2ca359b5fb2661ef9ed9d84a0f7c3bc10c25dcfa10bb3c5a4874588dff636ac43d5dbb3d748d75400756d0b __stack_chk_fail_local.c |