From a094c5bafa02ac778c42ac3d85cd167fa44d88c9 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Mon, 26 Nov 2018 17:25:47 +0100 Subject: [PATCH 001/475] Cygwin: spinlock: remove useless get_ll call LARGE_INTEGER has QuadPart anyway, no reason to compute the 64 bit value from HighPart and LowPart. Signed-off-by: Corinna Vinschen --- winsup/cygwin/spinlock.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/winsup/cygwin/spinlock.h b/winsup/cygwin/spinlock.h index f244355be..d8ded1274 100644 --- a/winsup/cygwin/spinlock.h +++ b/winsup/cygwin/spinlock.h @@ -30,7 +30,7 @@ class spinlock { LARGE_INTEGER t; if (NtQuerySystemTime (&t) == STATUS_SUCCESS) - return get_ll (t); + return t.QuadPart; return 0LL; } public: From 65091f0f35b29d5a043630fd877f0314a0779fb6 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Mon, 26 Nov 2018 17:24:35 +0100 Subject: [PATCH 002/475] Cygwin: timers: Simplify hires_ms and hires_ns Drop hires_base and move inited into hires_ns. Signed-off-by: Corinna Vinschen --- winsup/cygwin/hires.h | 11 ++--------- winsup/cygwin/times.cc | 2 -- 2 files changed, 2 insertions(+), 11 deletions(-) diff --git a/winsup/cygwin/hires.h b/winsup/cygwin/hires.h index 04ee6066a..d07bf394d 100644 --- a/winsup/cygwin/hires.h +++ b/winsup/cygwin/hires.h @@ -38,16 +38,9 @@ details. */ /* # of millisecs per second. */ #define MSPERSEC (1000L) -class hires_base +class hires_ns { - protected: int inited; - public: - void reset() {inited = false;} -}; - -class hires_ns : public hires_base -{ LARGE_INTEGER primed_pc; double freq; void prime (); @@ -57,7 +50,7 @@ class hires_ns : public hires_base LONGLONG resolution(); }; -class hires_ms : public hires_base +class hires_ms { public: LONGLONG nsecs (); diff --git a/winsup/cygwin/times.cc b/winsup/cygwin/times.cc index 11fb8f257..e89051407 100644 --- a/winsup/cygwin/times.cc +++ b/winsup/cygwin/times.cc @@ -120,8 +120,6 @@ settimeofday (const struct timeval *tv, const struct timezone *tz) st.wMilliseconds = tv->tv_usec / (USPERSEC / MSPERSEC); res = -!SetSystemTime (&st); - gtod.reset (); - if (res) set_errno (EPERM); } From 161d0fd27bdedcf5ff9ea2a56596a3b1ce368d74 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Mon, 26 Nov 2018 17:38:15 +0100 Subject: [PATCH 003/475] Cygwin: timers: drop error handling for Windows perf timer functions Per MSDN, the perf timer functions always succeed on Windows XP or later. Signed-off-by: Corinna Vinschen --- winsup/cygwin/times.cc | 37 +++++++------------------------------ 1 file changed, 7 insertions(+), 30 deletions(-) diff --git a/winsup/cygwin/times.cc b/winsup/cygwin/times.cc index e89051407..1ead18efc 100644 --- a/winsup/cygwin/times.cc +++ b/winsup/cygwin/times.cc @@ -466,21 +466,14 @@ void hires_ns::prime () { LARGE_INTEGER ifreq; - if (!QueryPerformanceFrequency (&ifreq)) - { - inited = -1; - return; - } + + /* On XP or later the perf counter functions will always succeed. */ + QueryPerformanceFrequency (&ifreq); int priority = GetThreadPriority (GetCurrentThread ()); SetThreadPriority (GetCurrentThread (), THREAD_PRIORITY_TIME_CRITICAL); - if (!QueryPerformanceCounter (&primed_pc)) - { - SetThreadPriority (GetCurrentThread (), priority); - inited = -1; - return; - } + QueryPerformanceCounter (&primed_pc); freq = (double) ((double) NSPERSEC / (double) ifreq.QuadPart); inited = true; @@ -490,21 +483,11 @@ hires_ns::prime () LONGLONG hires_ns::nsecs (bool monotonic) { + LARGE_INTEGER now; + if (!inited) prime (); - if (inited < 0) - { - set_errno (ENOSYS); - return (LONGLONG) -1; - } - - LARGE_INTEGER now; - if (!QueryPerformanceCounter (&now)) - { - set_errno (ENOSYS); - return -1; - } - + QueryPerformanceCounter (&now); // FIXME: Use round() here? now.QuadPart = (LONGLONG) (freq * (double) (now.QuadPart - (monotonic ? 0LL : primed_pc.QuadPart))); @@ -646,12 +629,6 @@ hires_ns::resolution () { if (!inited) prime (); - if (inited < 0) - { - set_errno (ENOSYS); - return (LONGLONG) -1; - } - return (freq <= 1.0) ? 1LL : (LONGLONG) freq; } From 5eaa64f9d86cae422016c3b08476b1cea556628e Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Mon, 26 Nov 2018 17:47:53 +0100 Subject: [PATCH 004/475] Cygwin: timers: use spinlock to prime hires_ns thread-safe The current method to make hires_ns priming thread-safe isn't thread-safe. Rather than hoping that running the thread in TIME_CRITICAL priority is doing the right thing, use a spinlock. Signed-off-by: Corinna Vinschen --- winsup/cygwin/hires.h | 2 +- winsup/cygwin/times.cc | 26 ++++++++++++-------------- 2 files changed, 13 insertions(+), 15 deletions(-) diff --git a/winsup/cygwin/hires.h b/winsup/cygwin/hires.h index d07bf394d..10aed7baf 100644 --- a/winsup/cygwin/hires.h +++ b/winsup/cygwin/hires.h @@ -40,7 +40,7 @@ details. */ class hires_ns { - int inited; + LONG inited; LARGE_INTEGER primed_pc; double freq; void prime (); diff --git a/winsup/cygwin/times.cc b/winsup/cygwin/times.cc index 1ead18efc..4e405b2df 100644 --- a/winsup/cygwin/times.cc +++ b/winsup/cygwin/times.cc @@ -24,6 +24,7 @@ details. */ #include "thread.h" #include "cygtls.h" #include "ntdll.h" +#include "spinlock.h" hires_ms NO_COPY gtod; @@ -465,19 +466,16 @@ ftime (struct timeb *tp) void hires_ns::prime () { - LARGE_INTEGER ifreq; + spinlock hspin (inited, 1); + if (!hspin) + { + LARGE_INTEGER ifreq; - /* On XP or later the perf counter functions will always succeed. */ - QueryPerformanceFrequency (&ifreq); - - int priority = GetThreadPriority (GetCurrentThread ()); - - SetThreadPriority (GetCurrentThread (), THREAD_PRIORITY_TIME_CRITICAL); - QueryPerformanceCounter (&primed_pc); - - freq = (double) ((double) NSPERSEC / (double) ifreq.QuadPart); - inited = true; - SetThreadPriority (GetCurrentThread (), priority); + /* On XP or later the perf counter functions will always succeed. */ + QueryPerformanceFrequency (&ifreq); + freq = (double) ((double) NSPERSEC / (double) ifreq.QuadPart); + QueryPerformanceCounter (&primed_pc); + } } LONGLONG @@ -485,7 +483,7 @@ hires_ns::nsecs (bool monotonic) { LARGE_INTEGER now; - if (!inited) + if (inited <= 0) prime (); QueryPerformanceCounter (&now); // FIXME: Use round() here? @@ -627,7 +625,7 @@ static ULONG minperiod; // FIXME: Maintain period after a fork. LONGLONG hires_ns::resolution () { - if (!inited) + if (inited <= 0) prime (); return (freq <= 1.0) ? 1LL : (LONGLONG) freq; } From 0b868df147d613b6f277161eff4ac2834aa24ee7 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Wed, 28 Nov 2018 23:49:59 +0100 Subject: [PATCH 005/475] Cygwin: pthread_cond_timedwait: make sure to wait until abstime finishes --- winsup/cygwin/thread.cc | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/winsup/cygwin/thread.cc b/winsup/cygwin/thread.cc index 0bddaf345..c47a597be 100644 --- a/winsup/cygwin/thread.cc +++ b/winsup/cygwin/thread.cc @@ -2945,25 +2945,33 @@ extern "C" int pthread_cond_timedwait (pthread_cond_t *cond, pthread_mutex_t *mutex, const struct timespec *abstime) { + int err = 0; LARGE_INTEGER timeout; pthread_testcancel (); __try { - int err = __pthread_cond_wait_init (cond, mutex); + err = __pthread_cond_wait_init (cond, mutex); if (err) - return err; + __leave; - err = pthread_convert_abstime ((*cond)->clock_id, abstime, &timeout); - if (err) - return err; + do + { + err = pthread_convert_abstime ((*cond)->clock_id, abstime, &timeout); + if (err) + __leave; - return (*cond)->wait (*mutex, &timeout); + err = (*cond)->wait (*mutex, &timeout); + } + while (err == ETIMEDOUT); + } + __except (NO_ERROR) + { + return EINVAL; } - __except (NO_ERROR) {} __endtry - return EINVAL; + return err; } extern "C" int From 6df301076af0f8b6dd0b12eb7c3ea15a4f835267 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Tue, 27 Nov 2018 13:59:37 +0100 Subject: [PATCH 006/475] Cygwin: timers: clock_setres: make no-op clock_setres is a questionable function only existing on QNX. Disable the function, just return success for CLOCK_REALTIME to maintain backward compatibility. Signed-off-by: Corinna Vinschen --- winsup/cygwin/times.cc | 38 ++------------------------------------ 1 file changed, 2 insertions(+), 36 deletions(-) diff --git a/winsup/cygwin/times.cc b/winsup/cygwin/times.cc index 4e405b2df..c557e8273 100644 --- a/winsup/cygwin/times.cc +++ b/winsup/cygwin/times.cc @@ -688,47 +688,13 @@ clock_getres (clockid_t clk_id, struct timespec *tp) extern "C" int clock_setres (clockid_t clk_id, struct timespec *tp) { - static NO_COPY bool period_set; - int status; - + /* Don't use this function. It only exists in QNX. Just return + success on CLOCK_REALTIME for backward compat. */ if (clk_id != CLOCK_REALTIME) { set_errno (EINVAL); return -1; } - - /* Convert to 100ns to match OS resolution. The OS uses ULONG values - to express resolution in 100ns units, so the coarsest timer resolution - is < 430 secs. Actually the coarsest timer resolution is only slightly - beyond 15ms, but this might change in future OS versions, so we play nice - here. */ - ULONGLONG period = tp->tv_sec * NS100PERSEC - + (tp->tv_nsec + (NSPERSEC/NS100PERSEC) - 1) - / (NSPERSEC/NS100PERSEC); - - /* clock_setres is non-POSIX/non-Linux. On QNX, the function always - rounds the incoming value to the nearest supported value. */ - ULONG coarsest, finest, actual; - if (NT_SUCCESS (NtQueryTimerResolution (&coarsest, &finest, &actual))) - { - if (period > coarsest) - period = coarsest; - else if (finest > period) - period = finest; - } - - if (period_set - && NT_SUCCESS (NtSetTimerResolution (minperiod, FALSE, &actual))) - period_set = false; - - status = NtSetTimerResolution (period, TRUE, &actual); - if (!NT_SUCCESS (status)) - { - __seterrno_from_nt_status (status); - return -1; - } - minperiod = period; - period_set = true; return 0; } From f4d6ef2d417e0fc10a159ab64827f837c9a3be84 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Wed, 28 Nov 2018 22:49:30 +0100 Subject: [PATCH 007/475] time.h: Introduce Linux-specific CLOCK id values - Add CLOCK_REALTIME_COARSE, CLOCK_MONOTONIC_RAW, CLOCK_MONOTONIC_COARSE and CLOCK_BOOTTIME - Guard new values with __GNU_VISIBLE - Add CLOCK_REALTIME_COARSE as (clockid_t) 0 for simplicity (It allows to have all values < 8 and so be used as array index into an array of clocks) - Fix macro bracketing Signed-off-by: Corinna Vinschen --- newlib/libc/include/time.h | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/newlib/libc/include/time.h b/newlib/libc/include/time.h index a2efcc15e..bd35d0e02 100644 --- a/newlib/libc/include/time.h +++ b/newlib/libc/include/time.h @@ -251,7 +251,11 @@ extern "C" { /* Manifest Constants, P1003.1b-1993, p. 262 */ -#define CLOCK_REALTIME (clockid_t)1 +#if __GNU_VISIBLE +#define CLOCK_REALTIME_COARSE ((clockid_t) 0) +#endif + +#define CLOCK_REALTIME ((clockid_t) 1) /* Flag indicating time is "absolute" with respect to the clock associated with a time. */ @@ -266,7 +270,7 @@ extern "C" { the identifier of the CPU_time clock associated with the PROCESS making the function call. */ -#define CLOCK_PROCESS_CPUTIME_ID (clockid_t)2 +#define CLOCK_PROCESS_CPUTIME_ID ((clockid_t) 2) #endif @@ -276,7 +280,7 @@ extern "C" { the identifier of the CPU_time clock associated with the THREAD making the function call. */ -#define CLOCK_THREAD_CPUTIME_ID (clockid_t)3 +#define CLOCK_THREAD_CPUTIME_ID ((clockid_t) 3) #endif @@ -286,7 +290,17 @@ extern "C" { * as a clock whose value cannot be set via clock_settime() and which * cannot have backward clock jumps. */ -#define CLOCK_MONOTONIC (clockid_t)4 +#define CLOCK_MONOTONIC ((clockid_t) 4) + +#if __GNU_VISIBLE + +#define CLOCK_MONOTONIC_RAW ((clockid_t) 5) + +#define CLOCK_MONOTONIC_COARSE ((clockid_t) 6) + +#define CLOCK_BOOTTIME ((clockid_t) 7) + +#endif #endif From c05df02725c5986d029eeec63beb467bdd6286ef Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Tue, 27 Nov 2018 13:47:02 +0100 Subject: [PATCH 008/475] Cygwin: implement extensible clock interface - Drop hires_[nm]s clocks, rename hires.h to clock.h. - Implement clk_t class as an extensible clock class in new file clock.cc. - Introduce get_clock(clock_id) returning a pointer to the clk_t instance for clock_id. Provide the following methods along the lines of the former hires classes: void clk_t::nsecs (struct timespec *); ULONGLONG clk_t::nsecs (); LONGLONG clk_t::usecs (); LONGLONG clk_t::msecs (); void clk_t::resolution (struct timespec *); - Add CLOCK_REALTIME_COARSE, CLOCK_MONOTONIC_RAW, CLOCK_MONOTONIC_COARSE and CLOCK_BOOTTIME clocks. - Allow clock_nanosleep, pthread_condattr_setclock and timer_create to use all new clocks (both clocks should be usable with a small tweak, though). - Bump DLL major version to 2.12. Signed-off-by: Corinna Vinschen --- winsup/cygwin/Makefile.in | 1 + winsup/cygwin/aio.cc | 5 +- winsup/cygwin/autoload.cc | 8 + winsup/cygwin/clock.cc | 286 +++++++++++++++++++++++++ winsup/cygwin/clock.h | 149 +++++++++++++ winsup/cygwin/cygheap.h | 2 +- winsup/cygwin/fhandler_socket_unix.cc | 6 +- winsup/cygwin/hires.h | 64 ------ winsup/cygwin/include/cygwin/version.h | 10 +- winsup/cygwin/ntdll.h | 3 +- winsup/cygwin/sched.cc | 2 +- winsup/cygwin/select.cc | 4 +- winsup/cygwin/signal.cc | 23 +- winsup/cygwin/strace.cc | 10 +- winsup/cygwin/sysconf.cc | 2 +- winsup/cygwin/thread.cc | 12 +- winsup/cygwin/timer.cc | 13 +- winsup/cygwin/times.cc | 222 +++---------------- winsup/cygwin/wincap.cc | 12 ++ winsup/cygwin/wincap.h | 4 + 20 files changed, 541 insertions(+), 297 deletions(-) create mode 100644 winsup/cygwin/clock.cc create mode 100644 winsup/cygwin/clock.h delete mode 100644 winsup/cygwin/hires.h diff --git a/winsup/cygwin/Makefile.in b/winsup/cygwin/Makefile.in index a232836e1..fb0195fc2 100644 --- a/winsup/cygwin/Makefile.in +++ b/winsup/cygwin/Makefile.in @@ -254,6 +254,7 @@ DLL_OFILES:= \ autoload.o \ base64.o \ bsdlib.o \ + clock.o \ ctype.o \ cxx.o \ cygheap.o \ diff --git a/winsup/cygwin/aio.cc b/winsup/cygwin/aio.cc index 7d5d98299..b245bdd02 100644 --- a/winsup/cygwin/aio.cc +++ b/winsup/cygwin/aio.cc @@ -7,7 +7,6 @@ Cygwin license. Please consult the file "CYGWIN_LICENSE" for details. */ #include "winsup.h" -#include "hires.h" #include "path.h" #include "fhandler.h" #include "dtable.h" @@ -803,12 +802,12 @@ retry: return -1; } - time0 = ntod.nsecs (); + time0 = get_clock (CLOCK_MONOTONIC)->nsecs (); /* Note wait below is abortable even w/ empty sigmask and infinite timeout */ res = sigtimedwait (&sigmask, &si, timeout ? &to : NULL); if (res == -1) return -1; /* Return with errno set by failed sigtimedwait() */ - time1 = ntod.nsecs (); + time1 = get_clock (CLOCK_MONOTONIC)->nsecs (); /* Adjust timeout to account for time just waited */ time1 -= time0; diff --git a/winsup/cygwin/autoload.cc b/winsup/cygwin/autoload.cc index 4fac3e39c..5a0e400aa 100644 --- a/winsup/cygwin/autoload.cc +++ b/winsup/cygwin/autoload.cc @@ -586,6 +586,14 @@ LoadDLLfunc (GetSystemTimePreciseAsFileTime, 4, kernel32) LoadDLLfuncEx (PrefetchVirtualMemory, 16, kernel32, 1) LoadDLLfunc (SetThreadGroupAffinity, 12, kernel32) +/* MSDN claims these are exported by kernel32.dll, but only + QueryUnbiasedInterruptTime actually is. The others are only + available via KernelBase.dll. */ +LoadDLLfunc (QueryInterruptTime, 4, KernelBase) +LoadDLLfunc (QueryInterruptTimePrecise, 4, KernelBase) +LoadDLLfunc (QueryUnbiasedInterruptTime, 4, KernelBase) +LoadDLLfunc (QueryUnbiasedInterruptTimePrecise, 4, KernelBase) + /* ldap functions are cdecl! */ #pragma push_macro ("mangle") #undef mangle diff --git a/winsup/cygwin/clock.cc b/winsup/cygwin/clock.cc new file mode 100644 index 000000000..99d0a281b --- /dev/null +++ b/winsup/cygwin/clock.cc @@ -0,0 +1,286 @@ +#include "winsup.h" +#include +#include "pinfo.h" +#include "clock.h" +#include "miscfuncs.h" +#include "spinlock.h" + +static LONGLONG +system_qpc_resolution () +{ + LARGE_INTEGER qpf; + + QueryPerformanceFrequency (&qpf); + return qpf.QuadPart; +} + +static LONGLONG +system_tickcount_resolution () +{ + ULONG coarsest = 0, finest, actual; + + if (!coarsest) + { + /* The actual resolution of the OS timer is a system-wide setting which + can be changed any time, by any process. The only fixed value we + can rely on is the coarsest value. */ + NtQueryTimerResolution (&coarsest, &finest, &actual); + } + return NS100PERSEC / coarsest; +} + +void +clk_t::init () +{ + spinlock spin (inited, 1); + if (!spin) + ticks_per_sec = system_tickcount_resolution (); +} + +void +clk_realtime_t::init () +{ + spinlock spin (inited, 1); + if (!spin) + ticks_per_sec = wincap.has_precise_system_time () + ? system_qpc_resolution () + : system_tickcount_resolution (); +} + +void +clk_monotonic_t::init () +{ + spinlock spin (inited, 1); + if (!spin) + ticks_per_sec = system_qpc_resolution (); +} + +int +clk_realtime_coarse_t::now (clockid_t clockid, struct timespec *ts) +{ + LARGE_INTEGER now; + + GetSystemTimeAsFileTime ((LPFILETIME) &now); + /* Add conversion factor for UNIX vs. Windows base time */ + now.QuadPart -= FACTOR; + ts->tv_sec = now.QuadPart / NS100PERSEC; + ts->tv_nsec = (now.QuadPart % NS100PERSEC) * (NSPERSEC/NS100PERSEC); + return 0; +} + +int +clk_realtime_t::now (clockid_t clockid, struct timespec *ts) +{ + LARGE_INTEGER now; + + wincap.has_precise_system_time () + ? GetSystemTimePreciseAsFileTime ((LPFILETIME) &now) + : GetSystemTimeAsFileTime ((LPFILETIME) &now); + /* Add conversion factor for UNIX vs. Windows base time */ + now.QuadPart -= FACTOR; + ts->tv_sec = now.QuadPart / NS100PERSEC; + ts->tv_nsec = (now.QuadPart % NS100PERSEC) * (NSPERSEC/NS100PERSEC); + return 0; +} + +int +clk_process_t::now (clockid_t clockid, struct timespec *ts) +{ + pid_t pid = CLOCKID_TO_PID (clockid); + HANDLE hProcess; + KERNEL_USER_TIMES kut; + int64_t x; + + if (pid == 0) + pid = myself->pid; + + pinfo p (pid); + if (!p || !p->exists ()) + { + set_errno (EINVAL); + return -1; + } + + hProcess = OpenProcess (PROCESS_QUERY_LIMITED_INFORMATION, 0, + p->dwProcessId); + NtQueryInformationProcess (hProcess, ProcessTimes, + &kut, sizeof kut, NULL); + + x = kut.KernelTime.QuadPart + kut.UserTime.QuadPart; + ts->tv_sec = x / NS100PERSEC; + ts->tv_nsec = (x % NS100PERSEC) * (NSPERSEC/NS100PERSEC); + CloseHandle (hProcess); + return 0; +} + +int +clk_thread_t::now (clockid_t clockid, struct timespec *ts) +{ + long thr_id = CLOCKID_TO_THREADID (clockid); + HANDLE hThread; + KERNEL_USER_TIMES kut; + int64_t x; + + if (thr_id == 0) + thr_id = pthread::self ()->getsequence_np (); + + hThread = OpenThread (THREAD_QUERY_LIMITED_INFORMATION, 0, thr_id); + if (!hThread) + { + set_errno (EINVAL); + return -1; + } + + NtQueryInformationThread (hThread, ThreadTimes, + &kut, sizeof kut, NULL); + + x = kut.KernelTime.QuadPart + kut.UserTime.QuadPart; + ts->tv_sec = x / NS100PERSEC; + ts->tv_nsec = (x % NS100PERSEC) * (NSPERSEC/NS100PERSEC); + CloseHandle (hThread); + return 0; +} + +extern "C" void WINAPI QueryUnbiasedInterruptTimePrecise (PULONGLONG); +extern "C" void WINAPI QueryInterruptTimePrecise (PULONGLONG); + +int +clk_monotonic_t::now (clockid_t clockid, struct timespec *ts) +{ + if (wincap.has_precise_interrupt_time ()) + { + /* Suspend time not taken into account, as on Linux */ + ULONGLONG now; + + QueryUnbiasedInterruptTimePrecise (&now); + ts->tv_sec = now / NS100PERSEC; + now %= NS100PERSEC; + ts->tv_nsec = now * (NSPERSEC/NS100PERSEC); + } + else + { + /* https://stackoverflow.com/questions/24330496. Skip rounding since + its almost always wrong when working with timestamps */ + UINT64 bias; + LARGE_INTEGER now; + struct timespec bts; + + if (inited <= 0) + init (); + do + { + bias = SharedUserData.InterruptTimeBias; + QueryPerformanceCounter(&now); + } + while (bias != SharedUserData.InterruptTimeBias); + /* Convert perf counter to timespec */ + ts->tv_sec = now.QuadPart / ticks_per_sec; + now.QuadPart %= ticks_per_sec; + ts->tv_nsec = (now.QuadPart * NSPERSEC) / ticks_per_sec; + /* Convert bias to timespec */ + bts.tv_sec = bias / NS100PERSEC; + bias %= NS100PERSEC; + bts.tv_nsec = bias * (NSPERSEC/NS100PERSEC); + /* Subtract bias from perf */ + ts_diff (bts, *ts); + } + return 0; +} + +int +clk_monotonic_coarse_t::now (clockid_t clockid, struct timespec *ts) +{ + if (wincap.has_unbiased_interrupt_time ()) + { + /* Suspend time not taken into account, as on Linux */ + ULONGLONG now; + + QueryUnbiasedInterruptTime (&now); + ts->tv_sec = now / NS100PERSEC; + now %= NS100PERSEC; + ts->tv_nsec = now * (NSPERSEC/NS100PERSEC); + } + else + { + /* Vista-only: GetTickCount64 is biased but it's coarse and + monotonic. */ + LONGLONG now; + + if (inited <= 0) + init (); + now = GetTickCount64 (); + ts->tv_sec = now / ticks_per_sec; + now %= ticks_per_sec; + ts->tv_nsec = (now * NSPERSEC) / ticks_per_sec; + } + return 0; +} + +int +clk_boottime_t::now (clockid_t clockid, struct timespec *ts) +{ + /* Suspend time taken into account, as on Linux */ + if (wincap.has_precise_interrupt_time ()) + { + ULONGLONG now; + + QueryInterruptTimePrecise (&now); + ts->tv_sec = now / NS100PERSEC; + now %= NS100PERSEC; + ts->tv_nsec = now * (NSPERSEC/NS100PERSEC); + } + else + { + LARGE_INTEGER now; + + if (inited <= 0) + init (); + QueryPerformanceCounter (&now); + ts->tv_sec = now.QuadPart / ticks_per_sec; + now.QuadPart %= ticks_per_sec; + ts->tv_nsec = (now.QuadPart * NSPERSEC) / ticks_per_sec; + } + return 0; +} + +void +clk_t::resolution (struct timespec *ts) +{ + if (inited <= 0) + init (); + ts->tv_sec = 0; + ts->tv_nsec = NSPERSEC / ticks_per_sec; +} + +static clk_realtime_coarse_t clk_realtime_coarse; +static clk_realtime_t clk_realtime; +static clk_process_t clk_process; +static clk_thread_t clk_thread; +static clk_monotonic_t clk_monotonic; +static clk_monotonic_t clk_monotonic_raw; /* same as clk_monotonic */ +static clk_monotonic_coarse_t clk_monotonic_coarse; +static clk_boottime_t clk_boottime; + +clk_t *cyg_clock[MAX_CLOCKS] = +{ + &clk_realtime_coarse, + &clk_realtime, + &clk_process, + &clk_thread, + &clk_monotonic, + &clk_monotonic_raw, + &clk_monotonic_coarse, + &clk_boottime, +}; + +clk_t * +get_clock (clockid_t clk_id) +{ + extern clk_t *cyg_clock[MAX_CLOCKS]; + clockid_t clockid = CLOCKID (clk_id); + if (clk_id >= MAX_CLOCKS + && clockid != CLOCK_PROCESS_CPUTIME_ID + && clockid != CLOCK_THREAD_CPUTIME_ID) + return NULL; + return cyg_clock[clockid]; +} diff --git a/winsup/cygwin/clock.h b/winsup/cygwin/clock.h new file mode 100644 index 000000000..3c5bd5fbd --- /dev/null +++ b/winsup/cygwin/clock.h @@ -0,0 +1,149 @@ +/* clock.h: Definitions for clock calculations + +This file is part of Cygwin. + +This software is a copyrighted work licensed under the terms of the +Cygwin license. Please consult the file "CYGWIN_LICENSE" for +details. */ + +#ifndef __CLOCK_H__ +#define __CLOCK_H__ + +#include + +/* Must be a power of 2. */ +#define MAX_CLOCKS (8) + +/* Conversions for per-process and per-thread clocks */ +#define CLOCKID(cid) \ + ((cid) % MAX_CLOCKS) +#define PID_TO_CLOCKID(pid) \ + ((pid) * MAX_CLOCKS + CLOCK_PROCESS_CPUTIME_ID) +#define CLOCKID_TO_PID(cid) \ + (((cid) - CLOCK_PROCESS_CPUTIME_ID) / MAX_CLOCKS) +#define CLOCKID_IS_PROCESS(cid) \ + (CLOCKID(cid) == CLOCK_PROCESS_CPUTIME_ID) +#define THREADID_TO_CLOCKID(tid) \ + ((tid) * MAX_CLOCKS + CLOCK_THREAD_CPUTIME_ID) +#define CLOCKID_TO_THREADID(cid) \ + (((cid) - CLOCK_THREAD_CPUTIME_ID) / MAX_CLOCKS) +#define CLOCKID_IS_THREAD(cid) \ + (CLOCKID(cid) == CLOCK_THREAD_CPUTIME_ID) + +/* Largest delay in ms for sleep and alarm calls. + Allow actual delay to exceed requested delay by 10 s. + Express as multiple of 1000 (i.e. seconds) + max resolution + The tv_sec argument in timeval structures cannot exceed + CLOCK_DELAY_MAX / 1000 - 1, so that adding fractional part + and rounding won't exceed CLOCK_DELAY_MAX */ +#define CLOCK_DELAY_MAX ((((UINT_MAX - 10000) / 1000) * 1000) + 10) + +/* 100ns difference between Windows and UNIX timebase. */ +#define FACTOR (0x19db1ded53e8000LL) +/* # of nanosecs per second. */ +#define NSPERSEC (1000000000LL) +/* # of 100ns intervals per second. */ +#define NS100PERSEC (10000000LL) +/* # of microsecs per second. */ +#define USPERSEC (1000000LL) +/* # of millisecs per second. */ +#define MSPERSEC (1000L) + +class clk_t +{ + protected: + LONG inited; + LONGLONG ticks_per_sec; + virtual void init (); + virtual int now (clockid_t, struct timespec *) = 0; + + public: + int nsecs (clockid_t _id, struct timespec *ts) + { + return now (_id, ts); + } + void resolution (struct timespec *); + + /* shortcuts for non-process/thread clocks */ + void nsecs (struct timespec *ts) { nsecs (0, ts); } + ULONGLONG nsecs () + { + struct timespec ts; + nsecs (&ts); + return (ULONGLONG) ts.tv_sec * NSPERSEC + ts.tv_nsec; + } + LONGLONG n100secs () + { + struct timespec ts; + nsecs (&ts); + return ts.tv_sec * NS100PERSEC + ts.tv_nsec / (NSPERSEC/NS100PERSEC); + } + LONGLONG usecs () + { + struct timespec ts; + nsecs (&ts); + return ts.tv_sec * USPERSEC + ts.tv_nsec / (NSPERSEC/USPERSEC); + } + LONGLONG msecs () + { + struct timespec ts; + nsecs (&ts); + return ts.tv_sec * MSPERSEC + ts.tv_nsec / (NSPERSEC/MSPERSEC); + } +}; + +class clk_realtime_coarse_t : public clk_t +{ + virtual int now (clockid_t, struct timespec *); +}; + +class clk_realtime_t : public clk_t +{ + virtual void init (); + virtual int now (clockid_t, struct timespec *); +}; + +class clk_process_t : public clk_t +{ + virtual int now (clockid_t, struct timespec *); +}; + +class clk_thread_t : public clk_t +{ + virtual int now (clockid_t, struct timespec *); +}; + +class clk_monotonic_t : public clk_t +{ + protected: + virtual void init (); + private: + virtual int now (clockid_t, struct timespec *); +}; + +class clk_monotonic_coarse_t : public clk_t +{ + virtual int now (clockid_t, struct timespec *); +}; + +class clk_boottime_t : public clk_monotonic_t +{ + virtual int now (clockid_t, struct timespec *); +}; + +clk_t *get_clock (clockid_t clk_id); + +/* Compute interval between two timespec timestamps: ts1 = ts1 - ts0. */ +static inline void +ts_diff (const struct timespec &ts0, struct timespec &ts1) +{ + ts1.tv_nsec -= ts0.tv_nsec; + if (ts1.tv_nsec < 0) + { + ts1.tv_nsec += NSPERSEC; + --ts1.tv_sec; + } + ts1.tv_sec -= ts0.tv_sec; +} + +#endif /*__CLOCK_H__*/ diff --git a/winsup/cygwin/cygheap.h b/winsup/cygwin/cygheap.h index abbf9ec07..d8a2e79a4 100644 --- a/winsup/cygwin/cygheap.h +++ b/winsup/cygwin/cygheap.h @@ -6,7 +6,7 @@ This software is a copyrighted work licensed under the terms of the Cygwin license. Please consult the file "CYGWIN_LICENSE" for details. */ -#include "hires.h" +#include "clock.h" #include "cygheap_malloc.h" #include "pwdgrp.h" diff --git a/winsup/cygwin/fhandler_socket_unix.cc b/winsup/cygwin/fhandler_socket_unix.cc index da83eccee..e71d2a722 100644 --- a/winsup/cygwin/fhandler_socket_unix.cc +++ b/winsup/cygwin/fhandler_socket_unix.cc @@ -24,7 +24,6 @@ #include "fhandler.h" #include "dtable.h" #include "cygheap.h" -#include "hires.h" #include "shared_info.h" #include "ntdll.h" #include "miscfuncs.h" @@ -1269,7 +1268,7 @@ fhandler_socket_unix::wait_pipe_thread (PUNICODE_STRING pipe_name) pwbuf->NameLength = pipe_name->Length; pwbuf->TimeoutSpecified = TRUE; memcpy (pwbuf->Name, pipe_name->Buffer, pipe_name->Length); - stamp = ntod.nsecs (); + stamp = get_clock (CLOCK_MONOTONIC)->n100secs (); do { status = NtFsControlFile (npfsh, evt, NULL, NULL, &io, FSCTL_PIPE_WAIT, @@ -1298,7 +1297,8 @@ fhandler_socket_unix::wait_pipe_thread (PUNICODE_STRING pipe_name) /* Another concurrent connect grabbed the pipe instance under our nose. Fix the timeout value and go waiting again, unless the timeout has passed. */ - pwbuf->Timeout.QuadPart -= (stamp - ntod.nsecs ()) / 100LL; + pwbuf->Timeout.QuadPart -= + stamp - get_clock (CLOCK_MONOTONIC)->n100secs (); if (pwbuf->Timeout.QuadPart >= 0) { status = STATUS_IO_TIMEOUT; diff --git a/winsup/cygwin/hires.h b/winsup/cygwin/hires.h deleted file mode 100644 index 10aed7baf..000000000 --- a/winsup/cygwin/hires.h +++ /dev/null @@ -1,64 +0,0 @@ -/* hires.h: Definitions for hires clock calculations - -This file is part of Cygwin. - -This software is a copyrighted work licensed under the terms of the -Cygwin license. Please consult the file "CYGWIN_LICENSE" for -details. */ - -#ifndef __HIRES_H__ -#define __HIRES_H__ - -#include - -/* Conversions for per-process and per-thread clocks */ -#define PID_TO_CLOCKID(pid) (pid * 8 + CLOCK_PROCESS_CPUTIME_ID) -#define CLOCKID_TO_PID(cid) ((cid - CLOCK_PROCESS_CPUTIME_ID) / 8) -#define CLOCKID_IS_PROCESS(cid) ((cid % 8) == CLOCK_PROCESS_CPUTIME_ID) -#define THREADID_TO_CLOCKID(tid) (tid * 8 + CLOCK_THREAD_CPUTIME_ID) -#define CLOCKID_TO_THREADID(cid) ((cid - CLOCK_THREAD_CPUTIME_ID) / 8) -#define CLOCKID_IS_THREAD(cid) ((cid % 8) == CLOCK_THREAD_CPUTIME_ID) - -/* Largest delay in ms for sleep and alarm calls. - Allow actual delay to exceed requested delay by 10 s. - Express as multiple of 1000 (i.e. seconds) + max resolution - The tv_sec argument in timeval structures cannot exceed - HIRES_DELAY_MAX / 1000 - 1, so that adding fractional part - and rounding won't exceed HIRES_DELAY_MAX */ -#define HIRES_DELAY_MAX ((((UINT_MAX - 10000) / 1000) * 1000) + 10) - -/* 100ns difference between Windows and UNIX timebase. */ -#define FACTOR (0x19db1ded53e8000LL) -/* # of nanosecs per second. */ -#define NSPERSEC (1000000000LL) -/* # of 100ns intervals per second. */ -#define NS100PERSEC (10000000LL) -/* # of microsecs per second. */ -#define USPERSEC (1000000LL) -/* # of millisecs per second. */ -#define MSPERSEC (1000L) - -class hires_ns -{ - LONG inited; - LARGE_INTEGER primed_pc; - double freq; - void prime (); - public: - LONGLONG nsecs (bool monotonic = false); - LONGLONG usecs () {return nsecs () / 1000LL;} - LONGLONG resolution(); -}; - -class hires_ms -{ - public: - LONGLONG nsecs (); - LONGLONG usecs () {return nsecs () / 10LL;} - LONGLONG msecs () {return nsecs () / 10000LL;} - UINT resolution (); -}; - -extern hires_ms gtod; -extern hires_ns ntod; -#endif /*__HIRES_H__*/ diff --git a/winsup/cygwin/include/cygwin/version.h b/winsup/cygwin/include/cygwin/version.h index 56b626963..bb1fa9746 100644 --- a/winsup/cygwin/include/cygwin/version.h +++ b/winsup/cygwin/include/cygwin/version.h @@ -10,8 +10,8 @@ details. */ the Cygwin shared library". This version is used to track important changes to the DLL and is mainly informative in nature. */ -#define CYGWIN_VERSION_DLL_MAJOR 2011 -#define CYGWIN_VERSION_DLL_MINOR 3 +#define CYGWIN_VERSION_DLL_MAJOR 2012 +#define CYGWIN_VERSION_DLL_MINOR 0 /* Major numbers before CYGWIN_VERSION_DLL_EPOCH are incompatible. */ @@ -498,13 +498,15 @@ details. */ 327: Export pthread_tryjoin_np, pthread_timedjoin_np. 328: Export aio_cancel, aio_error, aio_fsync, aio_read, aio_return, aio_suspend, aio_write, lio_listio. - 329: Export sched_getcpu.. + 329: Export sched_getcpu. + 330: Add CLOCK_REALTIME_COARSE, CLOCK_MONOTONIC_RAW, CLOCK_MONOTONIC_COARSE, + CLOCK_BOOTTIME. Note that we forgot to bump the api for ualarm, strtoll, strtoull, sigaltstack, sethostname. */ #define CYGWIN_VERSION_API_MAJOR 0 -#define CYGWIN_VERSION_API_MINOR 329 +#define CYGWIN_VERSION_API_MINOR 330 /* There is also a compatibity version number associated with the shared memory regions. It is incremented when incompatible changes are made to the shared diff --git a/winsup/cygwin/ntdll.h b/winsup/cygwin/ntdll.h index d64de1b9a..8d60ae732 100644 --- a/winsup/cygwin/ntdll.h +++ b/winsup/cygwin/ntdll.h @@ -793,7 +793,8 @@ typedef struct _KUSER_SHARED_DATA KSYSTEM_TIME InterruptTime; BYTE Reserved2[0x2c8]; ULONG DismountCount; - /* A lot more follows... */ + BYTE Reserved3[0xd0]; + UINT64 InterruptTimeBias; } KUSER_SHARED_DATA, *PKUSER_SHARED_DATA; /* Checked on 64 bit. */ diff --git a/winsup/cygwin/sched.cc b/winsup/cygwin/sched.cc index 702d038b0..10168e641 100644 --- a/winsup/cygwin/sched.cc +++ b/winsup/cygwin/sched.cc @@ -12,7 +12,7 @@ #include "miscfuncs.h" #include "cygerrno.h" #include "pinfo.h" -#include "hires.h" +#include "clock.h" /* for getpid */ #include #include diff --git a/winsup/cygwin/select.cc b/winsup/cygwin/select.cc index a580ac658..0d82a5914 100644 --- a/winsup/cygwin/select.cc +++ b/winsup/cygwin/select.cc @@ -159,7 +159,7 @@ select (int maxfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, int ret = 0; /* Record the current time for later use. */ - LONGLONG start_time = gtod.usecs (); + LONGLONG start_time = get_clock (CLOCK_REALTIME)->usecs (); select_stuff sel; sel.return_on_signal = 0; @@ -210,7 +210,7 @@ select (int maxfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, if (us != -1LL && wait_state == select_stuff::select_set_zero) { select_printf ("recalculating us"); - LONGLONG now = gtod.usecs (); + LONGLONG now = get_clock (CLOCK_REALTIME)->usecs (); if (now >= (start_time + us)) { select_printf ("timed out after verification"); diff --git a/winsup/cygwin/signal.cc b/winsup/cygwin/signal.cc index de3e88697..9e6fdc61a 100644 --- a/winsup/cygwin/signal.cc +++ b/winsup/cygwin/signal.cc @@ -76,16 +76,9 @@ clock_nanosleep (clockid_t clk_id, int flags, const struct timespec *rqtp, /* support for CPU-time clocks is optional */ if (CLOCKID_IS_PROCESS (clk_id) || CLOCKID_IS_THREAD (clk_id)) return ENOTSUP; - - switch (clk_id) - { - case CLOCK_REALTIME: - case CLOCK_MONOTONIC: - break; - default: - /* unknown or illegal clock ID */ - return EINVAL; - } + /* All other valid clocks are valid */ + if (clk_id >= MAX_CLOCKS) + return EINVAL; LARGE_INTEGER timeout; @@ -103,14 +96,18 @@ clock_nanosleep (clockid_t clk_id, int flags, const struct timespec *rqtp, || (tp.tv_sec == rqtp->tv_sec && tp.tv_nsec > rqtp->tv_nsec)) return 0; - if (clk_id == CLOCK_REALTIME) - timeout.QuadPart += FACTOR; - else + switch (clk_id) { + case CLOCK_REALTIME_COARSE: + case CLOCK_REALTIME: + timeout.QuadPart += FACTOR; + break; + default: /* other clocks need to be handled with a relative timeout */ timeout.QuadPart -= tp.tv_sec * NS100PERSEC + tp.tv_nsec / (NSPERSEC/NS100PERSEC); timeout.QuadPart *= -1LL; + break; } } else /* !abstime */ diff --git a/winsup/cygwin/strace.cc b/winsup/cygwin/strace.cc index b95b436aa..21c2d6d4a 100644 --- a/winsup/cygwin/strace.cc +++ b/winsup/cygwin/strace.cc @@ -82,8 +82,14 @@ strace::dll_info () int strace::microseconds () { - static hires_ns now NO_COPY; - return (int) now.usecs (); + /* Need a local clock instance because this function is called before + the global constructors of the inferior process have been called. */ + static clk_monotonic_t clock_monotonic; + static LONGLONG process_start NO_COPY; + + if (!process_start) + process_start = clock_monotonic.usecs (); + return (int) (clock_monotonic.usecs () - process_start); } static int __stdcall diff --git a/winsup/cygwin/sysconf.cc b/winsup/cygwin/sysconf.cc index 753febca4..216e5142f 100644 --- a/winsup/cygwin/sysconf.cc +++ b/winsup/cygwin/sysconf.cc @@ -19,7 +19,7 @@ details. */ #include "ntdll.h" #include "tls_pbuf.h" #include "cpuid.h" -#include "hires.h" +#include "clock.h" static long get_open_max (int in) diff --git a/winsup/cygwin/thread.cc b/winsup/cygwin/thread.cc index c47a597be..f0f7b0a5f 100644 --- a/winsup/cygwin/thread.cc +++ b/winsup/cygwin/thread.cc @@ -2566,6 +2566,7 @@ pthread_convert_abstime (clockid_t clock_id, const struct timespec *abstime, / (NSPERSEC/NS100PERSEC); switch (clock_id) { + case CLOCK_REALTIME_COARSE: case CLOCK_REALTIME: timeout->QuadPart += FACTOR; break; @@ -3035,14 +3036,9 @@ pthread_condattr_setclock (pthread_condattr_t *attr, clockid_t clock_id) { if (!pthread_condattr::is_good_object (attr)) return EINVAL; - switch (clock_id) - { - case CLOCK_REALTIME: - case CLOCK_MONOTONIC: - break; - default: - return EINVAL; - } + if (CLOCKID_IS_PROCESS (clock_id) || CLOCKID_IS_THREAD (clock_id) + || clock_id >= MAX_CLOCKS) + return EINVAL; (*attr)->clock_id = clock_id; return 0; } diff --git a/winsup/cygwin/timer.cc b/winsup/cygwin/timer.cc index 9d3d7dc94..e1d78eb49 100644 --- a/winsup/cygwin/timer.cc +++ b/winsup/cygwin/timer.cc @@ -127,7 +127,7 @@ timer_thread (VOID *x) LONG sleep_ms; /* Account for delays in starting thread and sending the signal */ - now = gtod.usecs (); + now = get_clock (tt->clock_id)->usecs (); sleep_us = sleepto_us - now; if (sleep_us > 0) { @@ -232,7 +232,8 @@ timer_tracker::settime (int in_flags, const itimerspec *value, itimerspec *ovalu if (timespec_bad (value->it_value) || timespec_bad (value->it_interval)) __leave; - long long now = in_flags & TIMER_ABSTIME ? 0 : gtod.usecs (); + long long now = in_flags & TIMER_ABSTIME ? + 0 : get_clock (clock_id)->usecs (); lock_timer_tracker here; cancel (); @@ -272,7 +273,7 @@ timer_tracker::gettime (itimerspec *ovalue) else { ovalue->it_interval = it_interval; - long long now = gtod.usecs (); + long long now = get_clock (clock_id)->usecs (); long long left_us = sleepto_us - now; if (left_us < 0) left_us = 0; @@ -317,7 +318,7 @@ timer_create (clockid_t clock_id, struct sigevent *__restrict evp, return -1; } - if (clock_id != CLOCK_REALTIME) + if (clock_id >= MAX_CLOCKS) { set_errno (EINVAL); return -1; @@ -466,8 +467,8 @@ alarm (unsigned int seconds) struct itimerspec newt = {}, oldt; /* alarm cannot fail, but only needs not be correct for arguments < 64k. Truncate */ - if (seconds > (HIRES_DELAY_MAX / 1000 - 1)) - seconds = (HIRES_DELAY_MAX / 1000 - 1); + if (seconds > (CLOCK_DELAY_MAX / 1000 - 1)) + seconds = (CLOCK_DELAY_MAX / 1000 - 1); newt.it_value.tv_sec = seconds; timer_settime ((timer_t) &ttstart, 0, &newt, &oldt); int ret = oldt.it_value.tv_sec + (oldt.it_value.tv_nsec > 0); diff --git a/winsup/cygwin/times.cc b/winsup/cygwin/times.cc index c557e8273..8908d44f1 100644 --- a/winsup/cygwin/times.cc +++ b/winsup/cygwin/times.cc @@ -26,10 +26,6 @@ details. */ #include "ntdll.h" #include "spinlock.h" -hires_ms NO_COPY gtod; - -hires_ns NO_COPY ntod; - static inline void __attribute__ ((always_inline)) get_system_time (PLARGE_INTEGER systime) { @@ -171,10 +167,7 @@ gettimeofday (struct timeval *__restrict tv, void *__restrict tzvp) { struct timezone *tz = (struct timezone *) tzvp; static bool tzflag; - LONGLONG now = gtod.usecs (); - - if (now == (LONGLONG) -1) - return -1; + LONGLONG now = get_clock (CLOCK_REALTIME)->usecs (); tv->tv_sec = now / USPERSEC; tv->tv_usec = now % USPERSEC; @@ -462,135 +455,23 @@ ftime (struct timeb *tp) return 0; } -#define stupid_printf if (cygwin_finished_initializing) debug_printf -void -hires_ns::prime () -{ - spinlock hspin (inited, 1); - if (!hspin) - { - LARGE_INTEGER ifreq; - - /* On XP or later the perf counter functions will always succeed. */ - QueryPerformanceFrequency (&ifreq); - freq = (double) ((double) NSPERSEC / (double) ifreq.QuadPart); - QueryPerformanceCounter (&primed_pc); - } -} - -LONGLONG -hires_ns::nsecs (bool monotonic) -{ - LARGE_INTEGER now; - - if (inited <= 0) - prime (); - QueryPerformanceCounter (&now); - // FIXME: Use round() here? - now.QuadPart = (LONGLONG) (freq * (double) - (now.QuadPart - (monotonic ? 0LL : primed_pc.QuadPart))); - return now.QuadPart; -} - -LONGLONG -hires_ms::nsecs () -{ - LARGE_INTEGER systime; - get_system_time (&systime); - /* Add conversion factor for UNIX vs. Windows base time */ - return systime.QuadPart - FACTOR; -} - extern "C" int clock_gettime (clockid_t clk_id, struct timespec *tp) { - if (CLOCKID_IS_PROCESS (clk_id)) + clk_t *clock = get_clock (clk_id); + + if (!clock) { - pid_t pid = CLOCKID_TO_PID (clk_id); - HANDLE hProcess; - KERNEL_USER_TIMES kut; - int64_t x; - - if (pid == 0) - pid = getpid (); - - pinfo p (pid); - if (!p || !p->exists ()) - { - set_errno (EINVAL); - return -1; - } - - hProcess = OpenProcess (PROCESS_QUERY_LIMITED_INFORMATION, 0, - p->dwProcessId); - NtQueryInformationProcess (hProcess, ProcessTimes, - &kut, sizeof kut, NULL); - - x = kut.KernelTime.QuadPart + kut.UserTime.QuadPart; - tp->tv_sec = x / NS100PERSEC; - tp->tv_nsec = (x % NS100PERSEC) * (NSPERSEC/NS100PERSEC); - - CloseHandle (hProcess); - return 0; + set_errno (EINVAL); + return -1; } - - if (CLOCKID_IS_THREAD (clk_id)) + __try { - long thr_id = CLOCKID_TO_THREADID (clk_id); - HANDLE hThread; - KERNEL_USER_TIMES kut; - int64_t x; - - if (thr_id == 0) - thr_id = pthread::self ()->getsequence_np (); - - hThread = OpenThread (THREAD_QUERY_LIMITED_INFORMATION, 0, thr_id); - if (!hThread) - { - set_errno (EINVAL); - return -1; - } - - NtQueryInformationThread (hThread, ThreadTimes, - &kut, sizeof kut, NULL); - - x = kut.KernelTime.QuadPart + kut.UserTime.QuadPart; - tp->tv_sec = x / NS100PERSEC; - tp->tv_nsec = (x % NS100PERSEC) * (NSPERSEC/NS100PERSEC); - - CloseHandle (hThread); - return 0; + return clock->nsecs (clk_id, tp); } - - switch (clk_id) - { - case CLOCK_REALTIME: - { - LONGLONG now = gtod.nsecs (); - if (now == (LONGLONG) -1) - return -1; - tp->tv_sec = now / NS100PERSEC; - tp->tv_nsec = (now % NS100PERSEC) * (NSPERSEC / NS100PERSEC); - break; - } - - case CLOCK_MONOTONIC: - { - LONGLONG now = ntod.nsecs (true); - if (now == (LONGLONG) -1) - return -1; - - tp->tv_sec = now / NSPERSEC; - tp->tv_nsec = (now % NSPERSEC); - break; - } - - default: - set_errno (EINVAL); - return -1; - } - - return 0; + __except (EFAULT) {} + __endtry + return -1; } extern "C" int @@ -608,80 +489,45 @@ clock_settime (clockid_t clk_id, const struct timespec *tp) return -1; } - if (clk_id != CLOCK_REALTIME) + if (clk_id != CLOCK_REALTIME_COARSE && clk_id != CLOCK_REALTIME) { set_errno (EINVAL); return -1; } - tv.tv_sec = tp->tv_sec; - tv.tv_usec = tp->tv_nsec / 1000; + __try + { + tv.tv_sec = tp->tv_sec; + tv.tv_usec = tp->tv_nsec / 1000; + } + __except (EFAULT) + { + return -1; + } + __endtry return settimeofday (&tv, NULL); } -static ULONG minperiod; // FIXME: Maintain period after a fork. - -LONGLONG -hires_ns::resolution () -{ - if (inited <= 0) - prime (); - return (freq <= 1.0) ? 1LL : (LONGLONG) freq; -} - -UINT -hires_ms::resolution () -{ - if (!minperiod) - { - ULONG coarsest, finest, actual; - - NtQueryTimerResolution (&coarsest, &finest, &actual); - /* The actual resolution of the OS timer is a system-wide setting which - can be changed any time, by any process. The only fixed value we - can rely on is the coarsest value. */ - minperiod = coarsest; - } - return minperiod; -} - extern "C" int clock_getres (clockid_t clk_id, struct timespec *tp) { - if (CLOCKID_IS_PROCESS (clk_id) || CLOCKID_IS_THREAD (clk_id)) + clk_t *clock = get_clock (clk_id); + + if (!clock) { - ULONG coarsest, finest, actual; - - NtQueryTimerResolution (&coarsest, &finest, &actual); - tp->tv_sec = coarsest / NS100PERSEC; - tp->tv_nsec = (coarsest % NS100PERSEC) * (NSPERSEC/NS100PERSEC); - return 0; + set_errno (EINVAL); + return -1; } - - switch (clk_id) + __try { - case CLOCK_REALTIME: - { - DWORD period = gtod.resolution (); - tp->tv_sec = period / NS100PERSEC; - tp->tv_nsec = (period % NS100PERSEC) * (NSPERSEC/NS100PERSEC); - break; - } - - case CLOCK_MONOTONIC: - { - LONGLONG period = ntod.resolution (); - tp->tv_sec = period / NSPERSEC; - tp->tv_nsec = period % NSPERSEC; - break; - } - - default: - set_errno (EINVAL); - return -1; + clock->resolution (tp); } - + __except (EFAULT) + { + return -1; + } + __endtry return 0; } diff --git a/winsup/cygwin/wincap.cc b/winsup/cygwin/wincap.cc index 0d20d37db..d5d8ef63c 100644 --- a/winsup/cygwin/wincap.cc +++ b/winsup/cygwin/wincap.cc @@ -32,6 +32,8 @@ wincaps wincap_vista __attribute__((section (".cygwin_dll_common"), shared)) = { has_new_pebteb_region:false, has_broken_whoami:true, has_unprivileged_createsymlink:false, + has_unbiased_interrupt_time:false, + has_precise_interrupt_time:false, }, }; @@ -50,6 +52,8 @@ wincaps wincap_7 __attribute__((section (".cygwin_dll_common"), shared)) = { has_new_pebteb_region:false, has_broken_whoami:true, has_unprivileged_createsymlink:false, + has_unbiased_interrupt_time:true, + has_precise_interrupt_time:false, }, }; @@ -68,6 +72,8 @@ wincaps wincap_8 __attribute__((section (".cygwin_dll_common"), shared)) = { has_new_pebteb_region:false, has_broken_whoami:false, has_unprivileged_createsymlink:false, + has_unbiased_interrupt_time:true, + has_precise_interrupt_time:false, }, }; @@ -86,6 +92,8 @@ wincaps wincap_10 __attribute__((section (".cygwin_dll_common"), shared)) = { has_new_pebteb_region:false, has_broken_whoami:false, has_unprivileged_createsymlink:false, + has_unbiased_interrupt_time:true, + has_precise_interrupt_time:true, }, }; @@ -104,6 +112,8 @@ wincaps wincap_10_1511 __attribute__((section (".cygwin_dll_common"), shared)) = has_new_pebteb_region:true, has_broken_whoami:false, has_unprivileged_createsymlink:false, + has_unbiased_interrupt_time:true, + has_precise_interrupt_time:true, }, }; @@ -122,6 +132,8 @@ wincaps wincap_10_1703 __attribute__((section (".cygwin_dll_common"), shared)) = has_new_pebteb_region:true, has_broken_whoami:false, has_unprivileged_createsymlink:true, + has_unbiased_interrupt_time:true, + has_precise_interrupt_time:true, }, }; diff --git a/winsup/cygwin/wincap.h b/winsup/cygwin/wincap.h index 9dc000056..cc1c6ba99 100644 --- a/winsup/cygwin/wincap.h +++ b/winsup/cygwin/wincap.h @@ -27,6 +27,8 @@ struct wincaps unsigned has_new_pebteb_region : 1; unsigned has_broken_whoami : 1; unsigned has_unprivileged_createsymlink : 1; + unsigned has_unbiased_interrupt_time : 1; + unsigned has_precise_interrupt_time : 1; }; }; @@ -74,6 +76,8 @@ public: bool IMPLEMENT (has_new_pebteb_region) bool IMPLEMENT (has_broken_whoami) bool IMPLEMENT (has_unprivileged_createsymlink) + bool IMPLEMENT (has_unbiased_interrupt_time) + bool IMPLEMENT (has_precise_interrupt_time) #undef IMPLEMENT }; From 3cbb70f8907ab58ce192b36e2e6f5a93b6d6105a Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Thu, 29 Nov 2018 11:12:05 +0100 Subject: [PATCH 009/475] Cygwin: document latest changes Signed-off-by: Corinna Vinschen --- winsup/cygwin/release/2.12.0 | 24 ++++++++++++++++++++++++ winsup/doc/new-features.xml | 22 ++++++++++++++++++++++ 2 files changed, 46 insertions(+) create mode 100644 winsup/cygwin/release/2.12.0 diff --git a/winsup/cygwin/release/2.12.0 b/winsup/cygwin/release/2.12.0 new file mode 100644 index 000000000..4e97f2a42 --- /dev/null +++ b/winsup/cygwin/release/2.12.0 @@ -0,0 +1,24 @@ +What's new: +----------- + +- Support for CLOCK_REALTIME_COARSE, CLOCK_MONOTONIC_COARSE, + CLOCK_MONOTONIC_RAW, CLOCK_BOOTTIME clocks. + + +What changed: +------------- + +- clock_nanosleep, pthread_condattr_setclock and timer_create now support + all clocks, except CLOCK_PROCESS_CPUTIME_ID and CLOCK_THREAD_CPUTIME_ID. + +- clock_setres is a no-op now. + + +Bug Fixes +--------- + +- Fix a thread race when initializing CLOCK_MONOTONIC. + Addresses: https://cygwin.com/ml/cygwin/2018-11/msg00017.html + +- Fix early timeout from pthread_cond_timedwait. + Addresses: https://cygwin.com/ml/cygwin/2018-11/msg00171.html diff --git a/winsup/doc/new-features.xml b/winsup/doc/new-features.xml index e7dfca5ba..e3786e545 100644 --- a/winsup/doc/new-features.xml +++ b/winsup/doc/new-features.xml @@ -4,6 +4,28 @@ What's new and what changed in Cygwin +What's new and what changed in 2.12 + + + + +Support for CLOCK_REALTIME_COARSE, CLOCK_MONOTONIC_COARSE, +CLOCK_MONOTONIC_RAW, CLOCK_BOOTTIME clocks. + + + +clock_nanosleep, pthread_condattr_setclock and timer_create now support +all clocks, except CLOCK_PROCESS_CPUTIME_ID and CLOCK_THREAD_CPUTIME_ID. + + + +clock_setres is a no-op now. + + + + + + What's new and what changed in 2.11 From 09870c6e958cf32fd62676e742c1c70d378a90a1 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Thu, 29 Nov 2018 11:22:42 +0100 Subject: [PATCH 010/475] stdio.h: Expose cuserid with __GNU_VISIBLE Signed-off-by: Corinna Vinschen --- newlib/libc/include/stdio.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/newlib/libc/include/stdio.h b/newlib/libc/include/stdio.h index f8d60766a..164d95bca 100644 --- a/newlib/libc/include/stdio.h +++ b/newlib/libc/include/stdio.h @@ -180,7 +180,7 @@ typedef _fpos64_t fpos64_t; #if __POSIX_VISIBLE char * ctermid (char *); #endif -#if __XSI_VISIBLE && __XSI_VISIBLE < 600 +#if __GNU_VISIBLE || (__XSI_VISIBLE && __XSI_VISIBLE < 600) char * cuserid (char *); #endif FILE * tmpfile (void); From 43e8fddfa654365f96ffa87825a99ccc63cfa0db Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Thu, 29 Nov 2018 12:56:18 +0100 Subject: [PATCH 011/475] Cygwin: clocks: use either tickcount or tick period Use whatever native unit the system provides for the resolution of a timer to avoid rounding problems Signed-off-by: Corinna Vinschen --- winsup/cygwin/clock.cc | 37 ++++++++++++++++++++++--------------- winsup/cygwin/clock.h | 4 ++++ 2 files changed, 26 insertions(+), 15 deletions(-) diff --git a/winsup/cygwin/clock.cc b/winsup/cygwin/clock.cc index 99d0a281b..0c8390a49 100644 --- a/winsup/cygwin/clock.cc +++ b/winsup/cygwin/clock.cc @@ -6,16 +6,17 @@ #include "spinlock.h" static LONGLONG -system_qpc_resolution () +system_qpc_tickspersec () { LARGE_INTEGER qpf; + /* ticks per sec */ QueryPerformanceFrequency (&qpf); return qpf.QuadPart; } static LONGLONG -system_tickcount_resolution () +system_tickcount_period () { ULONG coarsest = 0, finest, actual; @@ -26,7 +27,7 @@ system_tickcount_resolution () can rely on is the coarsest value. */ NtQueryTimerResolution (&coarsest, &finest, &actual); } - return NS100PERSEC / coarsest; + return coarsest; } void @@ -34,7 +35,7 @@ clk_t::init () { spinlock spin (inited, 1); if (!spin) - ticks_per_sec = system_tickcount_resolution (); + period = system_tickcount_period (); } void @@ -42,9 +43,12 @@ clk_realtime_t::init () { spinlock spin (inited, 1); if (!spin) - ticks_per_sec = wincap.has_precise_system_time () - ? system_qpc_resolution () - : system_tickcount_resolution (); + { + if (wincap.has_precise_system_time ()) + ticks_per_sec = system_qpc_tickspersec (); + else + period = system_tickcount_period (); + } } void @@ -52,7 +56,7 @@ clk_monotonic_t::init () { spinlock spin (inited, 1); if (!spin) - ticks_per_sec = system_qpc_resolution (); + ticks_per_sec = system_qpc_tickspersec (); } int @@ -202,16 +206,16 @@ clk_monotonic_coarse_t::now (clockid_t clockid, struct timespec *ts) } else { - /* Vista-only: GetTickCount64 is biased but it's coarse and - monotonic. */ - LONGLONG now; + /* Vista-only: GetTickCount64 is biased but it's coarse and monotonic. */ + ULONGLONG now; if (inited <= 0) init (); now = GetTickCount64 (); - ts->tv_sec = now / ticks_per_sec; - now %= ticks_per_sec; - ts->tv_nsec = (now * NSPERSEC) / ticks_per_sec; + now *= period; /* Normalize to 100ns period */ + ts->tv_sec = now / NS100PERSEC; + now %= NS100PERSEC; + ts->tv_nsec = now * (NSPERSEC/NS100PERSEC); } return 0; } @@ -249,7 +253,10 @@ clk_t::resolution (struct timespec *ts) if (inited <= 0) init (); ts->tv_sec = 0; - ts->tv_nsec = NSPERSEC / ticks_per_sec; + if (ticks_per_sec) + ts->tv_nsec = NSPERSEC / ticks_per_sec; + else + ts->tv_nsec = period * (NSPERSEC/NS100PERSEC); } static clk_realtime_coarse_t clk_realtime_coarse; diff --git a/winsup/cygwin/clock.h b/winsup/cygwin/clock.h index 3c5bd5fbd..075aaed1d 100644 --- a/winsup/cygwin/clock.h +++ b/winsup/cygwin/clock.h @@ -53,7 +53,11 @@ class clk_t { protected: LONG inited; + /* Some values are returned as ticks/s, some as 100ns period of a + single tick. Store the original value and use a computation method + making the most sense for the value given, to avoid rounding issues. */ LONGLONG ticks_per_sec; + LONGLONG period; virtual void init (); virtual int now (clockid_t, struct timespec *) = 0; From 166914ea8c86b5e569a5fef226e602a4d279897b Mon Sep 17 00:00:00 2001 From: Mark Geisert Date: Fri, 30 Nov 2018 22:14:00 -0800 Subject: [PATCH 012/475] fix version typo --- winsup/doc/new-features.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/winsup/doc/new-features.xml b/winsup/doc/new-features.xml index e3786e545..7cc449764 100644 --- a/winsup/doc/new-features.xml +++ b/winsup/doc/new-features.xml @@ -4,7 +4,7 @@ What's new and what changed in Cygwin -What's new and what changed in 2.12 +What's new and what changed in 2.12 From 2b72887ac834b0f0f675baff1af90771c7e36c87 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Fri, 30 Nov 2018 22:39:57 +0100 Subject: [PATCH 013/475] Cygwin: clocks: fix a hang on pre-Windows 10 machines when calling clocks too early in DLL init, the vtables are not correctly set up for some reason. Calls to init() from now() fail because the init pointer in the vtable is NULL. Real life example is mintty which runs into a minor problem at startup, triggering a system_printf call. Strace is another problem, it's called the first time prior to any class initialization. Workaround is to make sure that no virtual methods are called in an early stage. Make init() non-virtual and convert resolution() to a virtual method instead. Add a special non-virtual clk_monotonic_t::strace_usecs. While at it: - Inline internal-only methods. - Drop the `inited' member. Convert period/ticks_per_sec toa union. Initialize period/ticks_per_sec via InterlockeExchange64. - Fix GetTickCount64 usage. No, it's not returning ticks but milliseconds since boot (unbiased). - Fix comment indentation. Signed-off-by: Corinna Vinschen --- winsup/cygwin/clock.cc | 73 ++++++++++++++++++++++------------------- winsup/cygwin/clock.h | 40 +++++++++++++++------- winsup/cygwin/strace.cc | 8 ++--- 3 files changed, 71 insertions(+), 50 deletions(-) diff --git a/winsup/cygwin/clock.cc b/winsup/cygwin/clock.cc index 0c8390a49..18d628884 100644 --- a/winsup/cygwin/clock.cc +++ b/winsup/cygwin/clock.cc @@ -5,7 +5,7 @@ #include "miscfuncs.h" #include "spinlock.h" -static LONGLONG +static inline LONGLONG system_qpc_tickspersec () { LARGE_INTEGER qpf; @@ -15,7 +15,7 @@ system_qpc_tickspersec () return qpf.QuadPart; } -static LONGLONG +static inline LONGLONG system_tickcount_period () { ULONG coarsest = 0, finest, actual; @@ -23,40 +23,37 @@ system_tickcount_period () if (!coarsest) { /* The actual resolution of the OS timer is a system-wide setting which - can be changed any time, by any process. The only fixed value we - can rely on is the coarsest value. */ + can be changed any time, by any process. The only fixed value we + can rely on is the coarsest value. */ NtQueryTimerResolution (&coarsest, &finest, &actual); } return coarsest; } -void +void inline clk_t::init () { - spinlock spin (inited, 1); - if (!spin) - period = system_tickcount_period (); + if (!period) + InterlockedExchange64 (&period, system_tickcount_period ()); } -void +void inline clk_realtime_t::init () { - spinlock spin (inited, 1); - if (!spin) + if (wincap.has_precise_system_time ()) { - if (wincap.has_precise_system_time ()) - ticks_per_sec = system_qpc_tickspersec (); - else - period = system_tickcount_period (); + if (!ticks_per_sec) + InterlockedExchange64 (&ticks_per_sec, system_qpc_tickspersec ()); } + else if (!period) + InterlockedExchange64 (&period, system_tickcount_period ()); } -void +void inline clk_monotonic_t::init () { - spinlock spin (inited, 1); - if (!spin) - ticks_per_sec = system_qpc_tickspersec (); + if (!ticks_per_sec) + InterlockedExchange64 (&ticks_per_sec, system_qpc_tickspersec ()); } int @@ -169,8 +166,7 @@ clk_monotonic_t::now (clockid_t clockid, struct timespec *ts) LARGE_INTEGER now; struct timespec bts; - if (inited <= 0) - init (); + init (); do { bias = SharedUserData.InterruptTimeBias; @@ -209,13 +205,10 @@ clk_monotonic_coarse_t::now (clockid_t clockid, struct timespec *ts) /* Vista-only: GetTickCount64 is biased but it's coarse and monotonic. */ ULONGLONG now; - if (inited <= 0) - init (); - now = GetTickCount64 (); - now *= period; /* Normalize to 100ns period */ - ts->tv_sec = now / NS100PERSEC; - now %= NS100PERSEC; - ts->tv_nsec = now * (NSPERSEC/NS100PERSEC); + now = GetTickCount64 (); /* Returns ms since boot */ + ts->tv_sec = now / MSPERSEC; + now %= MSPERSEC; + ts->tv_nsec = now * (NSPERSEC/MSPERSEC); } return 0; } @@ -237,8 +230,7 @@ clk_boottime_t::now (clockid_t clockid, struct timespec *ts) { LARGE_INTEGER now; - if (inited <= 0) - init (); + init (); QueryPerformanceCounter (&now); ts->tv_sec = now.QuadPart / ticks_per_sec; now.QuadPart %= ticks_per_sec; @@ -250,15 +242,30 @@ clk_boottime_t::now (clockid_t clockid, struct timespec *ts) void clk_t::resolution (struct timespec *ts) { - if (inited <= 0) - init (); + init (); ts->tv_sec = 0; - if (ticks_per_sec) + ts->tv_nsec = period * (NSPERSEC/NS100PERSEC); +} + +void +clk_realtime_t::resolution (struct timespec *ts) +{ + init (); + ts->tv_sec = 0; + if (wincap.has_precise_system_time ()) ts->tv_nsec = NSPERSEC / ticks_per_sec; else ts->tv_nsec = period * (NSPERSEC/NS100PERSEC); } +void +clk_monotonic_t::resolution (struct timespec *ts) +{ + init (); + ts->tv_sec = 0; + ts->tv_nsec = NSPERSEC / ticks_per_sec; +} + static clk_realtime_coarse_t clk_realtime_coarse; static clk_realtime_t clk_realtime; static clk_process_t clk_process; diff --git a/winsup/cygwin/clock.h b/winsup/cygwin/clock.h index 075aaed1d..c05bf477c 100644 --- a/winsup/cygwin/clock.h +++ b/winsup/cygwin/clock.h @@ -52,13 +52,15 @@ details. */ class clk_t { protected: - LONG inited; /* Some values are returned as ticks/s, some as 100ns period of a single tick. Store the original value and use a computation method making the most sense for the value given, to avoid rounding issues. */ - LONGLONG ticks_per_sec; - LONGLONG period; - virtual void init (); + union + { + LONGLONG ticks_per_sec; + LONGLONG period; + }; + void init (); virtual int now (clockid_t, struct timespec *) = 0; public: @@ -66,32 +68,35 @@ class clk_t { return now (_id, ts); } - void resolution (struct timespec *); + virtual void resolution (struct timespec *); /* shortcuts for non-process/thread clocks */ - void nsecs (struct timespec *ts) { nsecs (0, ts); } + void nsecs (struct timespec *ts) + { + now (0, ts); + } ULONGLONG nsecs () { struct timespec ts; - nsecs (&ts); + now (0, &ts); return (ULONGLONG) ts.tv_sec * NSPERSEC + ts.tv_nsec; } LONGLONG n100secs () { struct timespec ts; - nsecs (&ts); + now (0, &ts); return ts.tv_sec * NS100PERSEC + ts.tv_nsec / (NSPERSEC/NS100PERSEC); } LONGLONG usecs () { struct timespec ts; - nsecs (&ts); + now (0, &ts); return ts.tv_sec * USPERSEC + ts.tv_nsec / (NSPERSEC/USPERSEC); } LONGLONG msecs () { struct timespec ts; - nsecs (&ts); + now (0, &ts); return ts.tv_sec * MSPERSEC + ts.tv_nsec / (NSPERSEC/MSPERSEC); } }; @@ -103,8 +108,10 @@ class clk_realtime_coarse_t : public clk_t class clk_realtime_t : public clk_t { - virtual void init (); + void init (); virtual int now (clockid_t, struct timespec *); + public: + virtual void resolution (struct timespec *); }; class clk_process_t : public clk_t @@ -120,9 +127,18 @@ class clk_thread_t : public clk_t class clk_monotonic_t : public clk_t { protected: - virtual void init (); + void init (); private: virtual int now (clockid_t, struct timespec *); + public: + virtual void resolution (struct timespec *); + /* Under strace 1st call is so early that vtable is NULL. */ + LONGLONG strace_usecs () + { + struct timespec ts; + clk_monotonic_t::now (0, &ts); + return ts.tv_sec * USPERSEC + ts.tv_nsec / (NSPERSEC/USPERSEC); + } }; class clk_monotonic_coarse_t : public clk_t diff --git a/winsup/cygwin/strace.cc b/winsup/cygwin/strace.cc index 21c2d6d4a..35f8a59ae 100644 --- a/winsup/cygwin/strace.cc +++ b/winsup/cygwin/strace.cc @@ -82,14 +82,12 @@ strace::dll_info () int strace::microseconds () { - /* Need a local clock instance because this function is called before - the global constructors of the inferior process have been called. */ - static clk_monotonic_t clock_monotonic; static LONGLONG process_start NO_COPY; + clk_monotonic_t *clk = (clk_monotonic_t *) get_clock (CLOCK_MONOTONIC); if (!process_start) - process_start = clock_monotonic.usecs (); - return (int) (clock_monotonic.usecs () - process_start); + process_start = clk->strace_usecs (); + return (int) (clk->strace_usecs () - process_start); } static int __stdcall From 5b4de1c915e7f8db19bfe3907d1a301406a3ded7 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Sat, 1 Dec 2018 16:50:40 +0100 Subject: [PATCH 014/475] Cygwin: mkvers: fix a bug in sed statement While reformatting the script, backticks `` were replaced with brackets $(). This in turn invalidated the \\( ... \\) expressions in the sed script because backslash resolution in $() works differently from backslash resolution in ``. Only a single backslash is valid now. While at it, fix up the uname(2) date representation when building a snapshot. Signed-off-by: Corinna Vinschen --- winsup/cygwin/mkvers.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/winsup/cygwin/mkvers.sh b/winsup/cygwin/mkvers.sh index 5aecb141b..6309c84b1 100755 --- a/winsup/cygwin/mkvers.sh +++ b/winsup/cygwin/mkvers.sh @@ -140,7 +140,8 @@ done | tee /tmp/mkvers.$$ 1>&9 trap "rm -f /tmp/mkvers.$$" 0 1 2 15 if [ -n "$snapshotdate" ]; then - usedate="$(echo $snapshotdate | sed 's/-\\(..:..[^-]*\\).*$/ \1SNP/')" + usedate="$(echo $snapshotdate \ + | sed -e 's/\(....\)\(..\)\(..\)-\(..:..\).*$/\1-\2-\3 \4SNP/')" else usedate="$builddate" fi From 8f4149ea9395e4dbd4b9df5e05668bd487ab42eb Mon Sep 17 00:00:00 2001 From: imp Date: Tue, 28 Feb 2017 23:42:47 +0000 Subject: [PATCH 015/475] Renumber copyright clause 4 Renumber cluase 4 to 3, per what everybody else did when BSD granted them permission to remove clause 3. My insistance on keeping the same numbering for legal reasons is too pedantic, so give up on that point. Submitted by: Jan Schaumann Pull Request: https://github.com/freebsd/freebsd/pull/96 --- newlib/libc/include/sys/time.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/newlib/libc/include/sys/time.h b/newlib/libc/include/sys/time.h index ce2e667f7..2cf543d0b 100644 --- a/newlib/libc/include/sys/time.h +++ b/newlib/libc/include/sys/time.h @@ -14,7 +14,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * From 3c3c17500c568785bc19beeae137456f501228f6 Mon Sep 17 00:00:00 2001 From: ian Date: Sat, 29 Jul 2017 17:00:23 +0000 Subject: [PATCH 016/475] Add inline functions to convert between sbintime_t and decimal time units. Use them in some existing code that is vulnerable to roundoff errors. The existing constant SBT_1NS is a honeypot, luring unsuspecting folks into writing code such as long_timeout_ns*SBT_1NS to generate the argument for a sleep call. The actual value of 1ns in sbt units is ~4.3, leading to a large roundoff error giving a shorter sleep than expected when multiplying by the trucated value of 4 in SBT_1NS. (The evil honeypot aspect becomes clear after you waste a whole day figuring out why your sleeps return early.) --- newlib/libc/include/sys/time.h | 59 ++++++++++++++++++++++++++++++---- 1 file changed, 52 insertions(+), 7 deletions(-) diff --git a/newlib/libc/include/sys/time.h b/newlib/libc/include/sys/time.h index 2cf543d0b..f263a5352 100644 --- a/newlib/libc/include/sys/time.h +++ b/newlib/libc/include/sys/time.h @@ -138,7 +138,7 @@ bintime_shift(struct bintime *_bt, int _exp) #define SBT_1M (SBT_1S * 60) #define SBT_1MS (SBT_1S / 1000) #define SBT_1US (SBT_1S / 1000000) -#define SBT_1NS (SBT_1S / 1000000000) +#define SBT_1NS (SBT_1S / 1000000000) /* beware rounding, see nstosbt() */ #define SBT_MAX 0x7fffffffffffffffLL static __inline int @@ -165,6 +165,53 @@ sbttobt(sbintime_t _sbt) return (_bt); } +/* + * Decimal<->sbt conversions. Multiplying or dividing by SBT_1NS results in + * large roundoff errors which sbttons() and nstosbt() avoid. Millisecond and + * microsecond functions are also provided for completeness. + */ +static __inline int64_t +sbttons(sbintime_t _sbt) +{ + + return ((1000000000 * _sbt) >> 32); +} + +static __inline sbintime_t +nstosbt(int64_t _ns) +{ + + return ((_ns * (((uint64_t)1 << 63) / 500000000) >> 32)); +} + +static __inline int64_t +sbttous(sbintime_t _sbt) +{ + + return ((1000000 * _sbt) >> 32); +} + +static __inline sbintime_t +ustosbt(int64_t _us) +{ + + return ((_us * (((uint64_t)1 << 63) / 500000) >> 32)); +} + +static __inline int64_t +sbttoms(sbintime_t _sbt) +{ + + return ((1000 * _sbt) >> 32); +} + +static __inline sbintime_t +mstosbt(int64_t _ms) +{ + + return ((_ms * (((uint64_t)1 << 63) / 500) >> 32)); +} + /*- * Background information: * @@ -220,7 +267,7 @@ sbttots(sbintime_t _sbt) struct timespec _ts; _ts.tv_sec = _sbt >> 32; - _ts.tv_nsec = ((uint64_t)1000000000 * (uint32_t)_sbt) >> 32; + _ts.tv_nsec = sbttons((uint32_t)_sbt); return (_ts); } @@ -228,8 +275,7 @@ static __inline sbintime_t tstosbt(struct timespec _ts) { - return (((sbintime_t)_ts.tv_sec << 32) + - (_ts.tv_nsec * (((uint64_t)1 << 63) / 500000000) >> 32)); + return (((sbintime_t)_ts.tv_sec << 32) + nstosbt(_ts.tv_nsec)); } static __inline struct timeval @@ -238,7 +284,7 @@ sbttotv(sbintime_t _sbt) struct timeval _tv; _tv.tv_sec = _sbt >> 32; - _tv.tv_usec = ((uint64_t)1000000 * (uint32_t)_sbt) >> 32; + _tv.tv_usec = sbttous((uint32_t)_sbt); return (_tv); } @@ -246,8 +292,7 @@ static __inline sbintime_t tvtosbt(struct timeval _tv) { - return (((sbintime_t)_tv.tv_sec << 32) + - (_tv.tv_usec * (((uint64_t)1 << 63) / 500000) >> 32)); + return (((sbintime_t)_tv.tv_sec << 32) + ustosbt(_tv.tv_usec)); } #endif /* __BSD_VISIBLE */ From 3266b2dd5e7036149413b96d558053b99df95c48 Mon Sep 17 00:00:00 2001 From: pfg Date: Mon, 20 Nov 2017 19:43:44 +0000 Subject: [PATCH 017/475] sys: further adoption of SPDX licensing ID tags. Mainly focus on files that use BSD 3-Clause license. The Software Package Data Exchange (SPDX) group provides a specification to make it easier for automated tools to detect and summarize well known opensource licenses. We are gradually adopting the specification, noting that the tags are considered only advisory and do not, in any way, superceed or replace the license texts. Special thanks to Wind River for providing access to "The Duke of Highlander" tool: an older (2014) run over FreeBSD tree was useful as a starting point. --- newlib/libc/include/sys/time.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/newlib/libc/include/sys/time.h b/newlib/libc/include/sys/time.h index f263a5352..0dfdbfea4 100644 --- a/newlib/libc/include/sys/time.h +++ b/newlib/libc/include/sys/time.h @@ -3,6 +3,8 @@ Public domain; no rights reserved. */ /*- + * SPDX-License-Identifier: BSD-3-Clause + * * Copyright (c) 1982, 1986, 1993 * The Regents of the University of California. All rights reserved. * From 68b1d72e1d966064e15ad40faf8dfd2d99438ca3 Mon Sep 17 00:00:00 2001 From: ian Date: Sat, 3 Mar 2018 22:28:20 +0000 Subject: [PATCH 018/475] Correct a misplaced closing paren. Does not affect the result, but does clarify (at least for me) that the multiplication happens before the shift. --- newlib/libc/include/sys/time.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/newlib/libc/include/sys/time.h b/newlib/libc/include/sys/time.h index 0dfdbfea4..e5023ae64 100644 --- a/newlib/libc/include/sys/time.h +++ b/newlib/libc/include/sys/time.h @@ -183,7 +183,7 @@ static __inline sbintime_t nstosbt(int64_t _ns) { - return ((_ns * (((uint64_t)1 << 63) / 500000000) >> 32)); + return ((_ns * (((uint64_t)1 << 63) / 500000000)) >> 32); } static __inline int64_t @@ -197,7 +197,7 @@ static __inline sbintime_t ustosbt(int64_t _us) { - return ((_us * (((uint64_t)1 << 63) / 500000) >> 32)); + return ((_us * (((uint64_t)1 << 63) / 500000)) >> 32); } static __inline int64_t @@ -211,7 +211,7 @@ static __inline sbintime_t mstosbt(int64_t _ms) { - return ((_ms * (((uint64_t)1 << 63) / 500) >> 32)); + return ((_ms * (((uint64_t)1 << 63) / 500)) >> 32); } /*- From 7bf8fc0987838fc435e251183410ed16bfb36c95 Mon Sep 17 00:00:00 2001 From: imp Date: Thu, 15 Nov 2018 16:02:13 +0000 Subject: [PATCH 019/475] When converting ns,us,ms to sbt, return the ceil() of the result rather than the floor(). Returning the floor means that sbttoX(Xtosbt(y)) != y for almost all values of y. In practice, this results in a difference of at most 1 in the lsb of the sbintime_t. This difference is meaningless for all current users of these functions, but is important for the newly introduced sysctl conversion routines which implicitly rely on the transformation being idempotent. Sponsored by: Netflix, Inc --- newlib/libc/include/sys/time.h | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/newlib/libc/include/sys/time.h b/newlib/libc/include/sys/time.h index e5023ae64..5182dc14e 100644 --- a/newlib/libc/include/sys/time.h +++ b/newlib/libc/include/sys/time.h @@ -171,6 +171,10 @@ sbttobt(sbintime_t _sbt) * Decimal<->sbt conversions. Multiplying or dividing by SBT_1NS results in * large roundoff errors which sbttons() and nstosbt() avoid. Millisecond and * microsecond functions are also provided for completeness. + * + * These functions return the smallest sbt larger or equal to the number of + * seconds requested so that sbttoX(Xtosbt(y)) == y. The 1 << 32 - 1 term added + * transforms the >> 32 from floor() to ceil(). */ static __inline int64_t sbttons(sbintime_t _sbt) @@ -183,7 +187,7 @@ static __inline sbintime_t nstosbt(int64_t _ns) { - return ((_ns * (((uint64_t)1 << 63) / 500000000)) >> 32); + return ((_ns * (((uint64_t)1 << 63) / 500000000) + (1ull << 32) - 1) >> 32); } static __inline int64_t @@ -197,7 +201,7 @@ static __inline sbintime_t ustosbt(int64_t _us) { - return ((_us * (((uint64_t)1 << 63) / 500000)) >> 32); + return ((_us * (((uint64_t)1 << 63) / 500000) + (1ull << 32) - 1) >> 32); } static __inline int64_t @@ -211,7 +215,7 @@ static __inline sbintime_t mstosbt(int64_t _ms) { - return ((_ms * (((uint64_t)1 << 63) / 500)) >> 32); + return ((_ms * (((uint64_t)1 << 63) / 500) + (1ull << 32) - 1) >> 32); } /*- From be517bd298641a4148f7b17dfc4528332154b459 Mon Sep 17 00:00:00 2001 From: imp Date: Tue, 20 Nov 2018 07:11:23 +0000 Subject: [PATCH 020/475] Ensure that all values of ns, us and ms work for {n,u,m}stosbt Integer overflows and wrong constants limited the accuracy of these functions and created situatiosn where sbttoXs(Xstosbt(Y)) != Y. This was especailly true in the ns case where we had millions of values that were wrong. Instead, used fixed constants because there's no way to say ceil(X) for integer math. Document what these crazy constants are. Also, use a shift one fewer left to avoid integer overflow causing incorrect results, and adjust the equasion accordingly. Document this. Allow times >= 1s to be well defined for these conversion functions (at least the Xstosbt). There's too many users in the tree that they work for >= 1s. This fixes a failure on boot to program firmware on the mlx4 NIC. There was a msleep(1000) in the code. Prior to my recent rounding changes, msleep(1000) worked, but msleep(1001) did not because the old code rounded to just below 2^64 and the new code rounds to just above it (overflowing, causing the msleep(1000) to really sleep 1ms). A test program to test all cases will be committed shortly. The test exaustively tries every value (thanks to bde for the test). Sponsored by: Netflix, Inc Differential Revision: https://reviews.freebsd.org/D18051 --- newlib/libc/include/sys/time.h | 59 ++++++++++++++++++++++++++++++---- 1 file changed, 52 insertions(+), 7 deletions(-) diff --git a/newlib/libc/include/sys/time.h b/newlib/libc/include/sys/time.h index 5182dc14e..081e0cf65 100644 --- a/newlib/libc/include/sys/time.h +++ b/newlib/libc/include/sys/time.h @@ -33,7 +33,7 @@ * SUCH DAMAGE. * * @(#)time.h 8.5 (Berkeley) 5/4/95 - * $FreeBSD$ + * $FreeBSD: head/sys/sys/time.h 340664 2018-11-20 07:11:23Z imp $ */ #ifndef _SYS_TIME_H_ @@ -172,9 +172,24 @@ sbttobt(sbintime_t _sbt) * large roundoff errors which sbttons() and nstosbt() avoid. Millisecond and * microsecond functions are also provided for completeness. * - * These functions return the smallest sbt larger or equal to the number of - * seconds requested so that sbttoX(Xtosbt(y)) == y. The 1 << 32 - 1 term added - * transforms the >> 32 from floor() to ceil(). + * These functions return the smallest sbt larger or equal to the + * number of seconds requested so that sbttoX(Xtosbt(y)) == y. Unlike + * top of second computations below, which require that we tick at the + * top of second, these need to be rounded up so we do whatever for at + * least as long as requested. + * + * The naive computation we'd do is this + * ((unit * 2^64 / SIFACTOR) + 2^32-1) >> 32 + * However, that overflows. Instead, we compute + * ((unit * 2^63 / SIFACTOR) + 2^31-1) >> 32 + * and use pre-computed constants that are the ceil of the 2^63 / SIFACTOR + * term to ensure we are using exactly the right constant. We use the lesser + * evil of ull rather than a uint64_t cast to ensure we have well defined + * right shift semantics. With these changes, we get all the ns, us and ms + * conversions back and forth right. + * Note: This file is used for both kernel and userland includes, so we can't + * rely on KASSERT being defined, nor can we pollute the namespace by including + * assert.h. */ static __inline int64_t sbttons(sbintime_t _sbt) @@ -186,8 +201,18 @@ sbttons(sbintime_t _sbt) static __inline sbintime_t nstosbt(int64_t _ns) { + sbintime_t sb = 0; - return ((_ns * (((uint64_t)1 << 63) / 500000000) + (1ull << 32) - 1) >> 32); +#ifdef KASSERT + KASSERT(_ns >= 0, ("Negative values illegal for nstosbt: %jd", _ns)); +#endif + if (_ns >= SBT_1S) { + sb = (_ns / 1000000000) * SBT_1S; + _ns = _ns % 1000000000; + } + /* 9223372037 = ceil(2^63 / 1000000000) */ + sb += ((_ns * 9223372037ull) + 0x7fffffff) >> 31; + return (sb); } static __inline int64_t @@ -200,8 +225,18 @@ sbttous(sbintime_t _sbt) static __inline sbintime_t ustosbt(int64_t _us) { + sbintime_t sb = 0; - return ((_us * (((uint64_t)1 << 63) / 500000) + (1ull << 32) - 1) >> 32); +#ifdef KASSERT + KASSERT(_us >= 0, ("Negative values illegal for ustosbt: %jd", _us)); +#endif + if (_us >= SBT_1S) { + sb = (_us / 1000000) * SBT_1S; + _us = _us % 1000000; + } + /* 9223372036855 = ceil(2^63 / 1000000) */ + sb += ((_us * 9223372036855ull) + 0x7fffffff) >> 31; + return (sb); } static __inline int64_t @@ -214,8 +249,18 @@ sbttoms(sbintime_t _sbt) static __inline sbintime_t mstosbt(int64_t _ms) { + sbintime_t sb = 0; - return ((_ms * (((uint64_t)1 << 63) / 500) + (1ull << 32) - 1) >> 32); +#ifdef KASSERT + KASSERT(_ms >= 0, ("Negative values illegal for mstosbt: %jd", _ms)); +#endif + if (_ms >= SBT_1S) { + sb = (_ms / 1000) * SBT_1S; + _ms = _ms % 1000; + } + /* 9223372036854776 = ceil(2^63 / 1000) */ + sb += ((_ms * 9223372036854776ull) + 0x7fffffff) >> 31; + return (sb); } /*- From 55db4a8e3ae0aef3a3530a82515d8ba5d2ea121c Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Tue, 4 Dec 2018 07:34:25 +0100 Subject: [PATCH 021/475] sys/time.h: Remove KASSERT The KASSERT is only used by the FreeBSD kernel. Signed-off-by: Sebastian Huber --- newlib/libc/include/sys/time.h | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/newlib/libc/include/sys/time.h b/newlib/libc/include/sys/time.h index 081e0cf65..c760adfbd 100644 --- a/newlib/libc/include/sys/time.h +++ b/newlib/libc/include/sys/time.h @@ -187,9 +187,6 @@ sbttobt(sbintime_t _sbt) * evil of ull rather than a uint64_t cast to ensure we have well defined * right shift semantics. With these changes, we get all the ns, us and ms * conversions back and forth right. - * Note: This file is used for both kernel and userland includes, so we can't - * rely on KASSERT being defined, nor can we pollute the namespace by including - * assert.h. */ static __inline int64_t sbttons(sbintime_t _sbt) @@ -203,9 +200,6 @@ nstosbt(int64_t _ns) { sbintime_t sb = 0; -#ifdef KASSERT - KASSERT(_ns >= 0, ("Negative values illegal for nstosbt: %jd", _ns)); -#endif if (_ns >= SBT_1S) { sb = (_ns / 1000000000) * SBT_1S; _ns = _ns % 1000000000; @@ -227,9 +221,6 @@ ustosbt(int64_t _us) { sbintime_t sb = 0; -#ifdef KASSERT - KASSERT(_us >= 0, ("Negative values illegal for ustosbt: %jd", _us)); -#endif if (_us >= SBT_1S) { sb = (_us / 1000000) * SBT_1S; _us = _us % 1000000; @@ -251,9 +242,6 @@ mstosbt(int64_t _ms) { sbintime_t sb = 0; -#ifdef KASSERT - KASSERT(_ms >= 0, ("Negative values illegal for mstosbt: %jd", _ms)); -#endif if (_ms >= SBT_1S) { sb = (_ms / 1000) * SBT_1S; _ms = _ms % 1000; From df6915f029ac9acd2b479ea898388cbd7dda4974 Mon Sep 17 00:00:00 2001 From: Szabolcs Nagy Date: Mon, 10 Dec 2018 14:40:01 +0000 Subject: [PATCH 022/475] Fix powf overflow handling in non-nearest rounding mode The threshold value at which powf overflows depends on the rounding mode and the current check did not take this into account. So when the result was rounded away from zero it could become infinity without setting errno to ERANGE. Example: pow(0x1.7ac7cp+5, 23) is 0x1.fffffep+127 + 0.1633ulp If the result goes above 0x1.fffffep+127 + 0.5ulp then errno is set, which is fine in nearest rounding mode, but powf(0x1.7ac7cp+5, 23) is inf in upward rounding mode powf(-0x1.7ac7cp+5, 23) is -inf in downward rounding mode and the previous implementation did not set errno in these cases. The fix tries to avoid affecting the common code path or calling a function that may introduce a stack frame, so float arithmetics is used to check the rounding mode and the threshold is selected accordingly. --- newlib/libm/common/sf_pow.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/newlib/libm/common/sf_pow.c b/newlib/libm/common/sf_pow.c index f7b22b612..2946c611b 100644 --- a/newlib/libm/common/sf_pow.c +++ b/newlib/libm/common/sf_pow.c @@ -220,7 +220,17 @@ powf (float x, float y) { /* |y*log(x)| >= 126. */ if (ylogx > 0x1.fffffffd1d571p+6 * POWF_SCALE) + /* |x^y| > 0x1.ffffffp127. */ return __math_oflowf (sign_bias); + if (WANT_ROUNDING && WANT_ERRNO + && ylogx > 0x1.fffffffa3aae2p+6 * POWF_SCALE) + /* |x^y| > 0x1.fffffep127, check if we round away from 0. */ + if ((!sign_bias + && eval_as_float (1.0f + opt_barrier_float (0x1p-25f)) != 1.0f) + || (sign_bias + && eval_as_float (-1.0f - opt_barrier_float (0x1p-25f)) + != -1.0f)) + return __math_oflowf (sign_bias); if (ylogx <= -150.0 * POWF_SCALE) return __math_uflowf (sign_bias); #if WANT_ERRNO_UFLOW From b3692aed5e48b6107afba6aab21d03191dc80117 Mon Sep 17 00:00:00 2001 From: Jon Beniston Date: Tue, 11 Dec 2018 21:03:03 +0000 Subject: [PATCH 023/475] nano-vfprintf_float.c: Fix check if negative for nans. --- newlib/libc/stdio/nano-vfprintf_float.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/newlib/libc/stdio/nano-vfprintf_float.c b/newlib/libc/stdio/nano-vfprintf_float.c index 071a09edc..524f67a31 100644 --- a/newlib/libc/stdio/nano-vfprintf_float.c +++ b/newlib/libc/stdio/nano-vfprintf_float.c @@ -39,6 +39,7 @@ #include #include #include +#include #include #include #include @@ -213,7 +214,7 @@ _printf_float (struct _reent *data, } if (isnan (_fpvalue)) { - if (_fpvalue < 0) + if (signbit (_fpvalue)) pdata->l_buf[0] = '-'; if (code <= 'G') /* 'A', 'E', 'F', or 'G'. */ cp = "NAN"; From a091d5da63f6711fe046e2a0f63d917e3b5254d4 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Wed, 19 Dec 2018 21:10:37 +0100 Subject: [PATCH 024/475] Cygwin: fix heap allocation on WOW64 and /3GB enabled 32 bit machines The check for the TEB being allocated beyond the first 2GB area is not valid anymore. At least on W10 WOW64, the TEB is allocated in the lower 2GB even in large-address aware executables. Use VirtualQuery instead. It fails for invalid addresses so that's a simple enough test. Signed-off-by: Corinna Vinschen --- winsup/cygwin/heap.cc | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/winsup/cygwin/heap.cc b/winsup/cygwin/heap.cc index 18145d21c..e18cd5508 100644 --- a/winsup/cygwin/heap.cc +++ b/winsup/cygwin/heap.cc @@ -44,22 +44,28 @@ eval_start_address () starting at 0x20000000. This should work right from the start in 99% of the cases. */ uintptr_t start_address = 0x20000000L; - if ((uintptr_t) NtCurrentTeb () >= 0xbf000000L) + MEMORY_BASIC_INFORMATION mbi; + + if (VirtualQuery ((void *) 0xbf000000L, &mbi, sizeof mbi)) { /* However, if we're running on a /3GB enabled 32 bit system or on a 64 bit system, and the executable is large address aware, then we know that we have spare 1 Gig (32 bit) or even 2 Gigs (64 bit) virtual address space. This memory region is practically unused - by Windows, only PEB and TEBs are allocated top-down here. We use - the current TEB address as very simple test that this is a large - address aware executable. - The above test for an address beyond 0xbf000000 is supposed to - make sure that we really have 3GB on a 32 bit system. Windows - supports smaller large address regions, but then it's not that - interesting for us to use it for the heap. - If the region is big enough, the heap gets allocated at its - start. What we get are 0.999 or 1.999 Gigs of free contiguous - memory for heap, thread stacks, and shared memory regions. */ + by Windows, only PEB and TEBs are allocated top-down here. + + We used to use the current TEB address as very simple test that + this is a large address aware executable, but that fails on W10 + WOW64 because the main TEB is apparently commited in the lower + 2 Gigs these days. + + The above test for address 0xbf000000 is supposed to make sure + that we really have 3GB on a 32 bit system. Windows supports + smaller large address regions, but then it's not that interesting + for us to use it for the heap. If the region is big enough, the + heap gets allocated at its start. What we get are 0.999 or 1.999 + Gigs of free contiguous memory for heap, thread stacks, and shared + memory regions. */ start_address = 0x80000000L; } #endif From 44756a36abd7157937d2ef9e862300fb3282d655 Mon Sep 17 00:00:00 2001 From: markj Date: Mon, 26 Nov 2018 13:42:18 +0000 Subject: [PATCH 025/475] Plug routing sysctl leaks. Various structures exported by sysctl_rtsock() contain padding fields which were not being zeroed. Reported by: Thomas Barabosch, Fraunhofer FKIE Reviewed by: ae MFC after: 3 days Security: kernel memory disclosure Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D18333 --- newlib/libc/sys/rtems/include/net/if.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/newlib/libc/sys/rtems/include/net/if.h b/newlib/libc/sys/rtems/include/net/if.h index 54bb9094d..a9b875cf1 100644 --- a/newlib/libc/sys/rtems/include/net/if.h +++ b/newlib/libc/sys/rtems/include/net/if.h @@ -29,7 +29,7 @@ * SUCH DAMAGE. * * @(#)if.h 8.1 (Berkeley) 6/10/93 - * $FreeBSD: head/sys/net/if.h 333502 2018-05-11 20:08:28Z mmacy $ + * $FreeBSD: head/sys/net/if.h 340968 2018-11-26 13:42:18Z markj $ */ #ifndef _NET_IF_H_ @@ -271,6 +271,7 @@ struct if_msghdr { int ifm_addrs; /* like rtm_addrs */ int ifm_flags; /* value of if_flags */ u_short ifm_index; /* index for associated ifp */ + u_short _ifm_spare1; struct if_data ifm_data;/* statistics and other data about if */ }; @@ -296,6 +297,7 @@ struct if_msghdrl { u_short _ifm_spare1; /* spare space to grow if_index, see if_var.h */ u_short ifm_len; /* length of if_msghdrl incl. if_data */ u_short ifm_data_off; /* offset of if_data from beginning */ + int _ifm_spare2; struct if_data ifm_data;/* statistics and other data about if */ }; @@ -311,6 +313,7 @@ struct ifa_msghdr { int ifam_addrs; /* like rtm_addrs */ int ifam_flags; /* value of ifa_flags */ u_short ifam_index; /* index for associated ifp */ + u_short _ifam_spare1; int ifam_metric; /* value of ifa_ifp->if_metric */ }; @@ -352,6 +355,7 @@ struct ifma_msghdr { int ifmam_addrs; /* like rtm_addrs */ int ifmam_flags; /* value of ifa_flags */ u_short ifmam_index; /* index for associated ifp */ + u_short _ifmam_spare1; }; /* From dc6e94551f09d3a983afd571478d63a09d6f66fa Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Thu, 20 Dec 2018 10:55:28 +0100 Subject: [PATCH 026/475] RTEMS: Use __uint64_t for __ino_t FreeBSD uses a 64-bit ino_t since 2017-05-23. We need this for the pipe() support in libbsd. Signed-off-by: Sebastian Huber --- newlib/libc/sys/rtems/include/machine/_types.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/newlib/libc/sys/rtems/include/machine/_types.h b/newlib/libc/sys/rtems/include/machine/_types.h index c61d6575d..8e2d9a3ef 100644 --- a/newlib/libc/sys/rtems/include/machine/_types.h +++ b/newlib/libc/sys/rtems/include/machine/_types.h @@ -18,7 +18,7 @@ typedef __int64_t _off_t; typedef _off_t _fpos_t; #define __machine_fpos_t_defined -typedef unsigned long __ino_t; +typedef __uint64_t __ino_t; #define __machine_ino_t_defined typedef __uint32_t __mode_t; From 29cfc892a50a6fe2ffff585c1861e255c2196513 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Sun, 23 Dec 2018 00:17:34 +0100 Subject: [PATCH 027/475] Cygwin: ntdll.h: Update _FILE_INFORMATION_CLASS - Add missing members added in later OS versions - Rearrange accompanying FILE_foo_INFORMATION structs ordered by info class - Add promising FILE_foo_INFORMATION structs of later Windows 10 releases plus accompanying enums - Drop "Checked on 64 bit" comments since that's self-evident these days Signed-off-by: Corinna Vinschen --- winsup/cygwin/ntdll.h | 657 ++++++++++++++++++++++-------------------- 1 file changed, 348 insertions(+), 309 deletions(-) diff --git a/winsup/cygwin/ntdll.h b/winsup/cygwin/ntdll.h index 8d60ae732..872cb3170 100644 --- a/winsup/cygwin/ntdll.h +++ b/winsup/cygwin/ntdll.h @@ -173,60 +173,85 @@ extern GUID __cygwin_socket_guid; typedef enum _FILE_INFORMATION_CLASS { - FileDirectoryInformation = 1, - FileFullDirectoryInformation, // 2 - FileBothDirectoryInformation, // 3 - FileBasicInformation, // 4 wdm - FileStandardInformation, // 5 wdm - FileInternalInformation, // 6 - FileEaInformation, // 7 - FileAccessInformation, // 8 - FileNameInformation, // 9 - FileRenameInformation, // 10 - FileLinkInformation, // 11 - FileNamesInformation, // 12 - FileDispositionInformation, // 13 - FilePositionInformation, // 14 wdm - FileFullEaInformation, // 15 - FileModeInformation, // 16 - FileAlignmentInformation, // 17 - FileAllInformation, // 18 - FileAllocationInformation, // 19 - FileEndOfFileInformation, // 20 wdm - FileAlternateNameInformation, // 21 - FileStreamInformation, // 22 - FilePipeInformation, // 23 - FilePipeLocalInformation, // 24 - FilePipeRemoteInformation, // 25 - FileMailslotQueryInformation, // 26 - FileMailslotSetInformation, // 27 - FileCompressionInformation, // 28 - FileObjectIdInformation, // 29 - FileCompletionInformation, // 30 - FileMoveClusterInformation, // 31 - FileQuotaInformation, // 32 - FileReparsePointInformation, // 33 - FileNetworkOpenInformation, // 34 - FileAttributeTagInformation, // 35 - FileTrackingInformation, // 36 - FileIdBothDirectoryInformation, // 37 - FileIdFullDirectoryInformation, // 38 - FileValidDataLengthInformation, // 39 - FileShortNameInformation, // 40 + FileDirectoryInformation = 1, // 1 + FileFullDirectoryInformation, // 2 + FileBothDirectoryInformation, // 3 + FileBasicInformation, // 4 + FileStandardInformation, // 5 + FileInternalInformation, // 6 + FileEaInformation, // 7 + FileAccessInformation, // 8 + FileNameInformation, // 9 + FileRenameInformation, // 10 + FileLinkInformation, // 11 + FileNamesInformation, // 12 + FileDispositionInformation, // 13 + FilePositionInformation, // 14 + FileFullEaInformation, // 15 + FileModeInformation, // 16 + FileAlignmentInformation, // 17 + FileAllInformation, // 18 + FileAllocationInformation, // 19 + FileEndOfFileInformation, // 20 + FileAlternateNameInformation, // 21 + FileStreamInformation, // 22 + FilePipeInformation, // 23 + FilePipeLocalInformation, // 24 + FilePipeRemoteInformation, // 25 + FileMailslotQueryInformation, // 26 + FileMailslotSetInformation, // 27 + FileCompressionInformation, // 28 + FileObjectIdInformation, // 29 + FileCompletionInformation, // 30 + FileMoveClusterInformation, // 31 + FileQuotaInformation, // 32 + FileReparsePointInformation, // 33 + FileNetworkOpenInformation, // 34 + FileAttributeTagInformation, // 35 + FileTrackingInformation, // 36 + FileIdBothDirectoryInformation, // 37 + FileIdFullDirectoryInformation, // 38 + FileValidDataLengthInformation, // 39 + FileShortNameInformation, // 40 + FileIoCompletionNotificationInformation, // 41 + FileIoStatusBlockRangeInformation, // 42 + FileIoPriorityHintInformation, // 43 + FileSfioReserveInformation, // 44 + FileSfioVolumeInformation, // 45 + FileHardLinkInformation, // 46 + FileProcessIdsUsingFileInformation, // 47 + FileNormalizedNameInformation, // 48 + FileNetworkPhysicalNameInformation, // 49 + FileIdGlobalTxDirectoryInformation, // 50 + FileIsRemoteDeviceInformation, // 51 + FileUnusedInformation, // 52 + FileNumaNodeInformation, // 53 + FileStandardLinkInformation, // 54 + FileRemoteProtocolInformation, // 55 + FileRenameInformationBypassAccessCheck, // 56 + FileLinkInformationBypassAccessCheck, // 57 + FileVolumeNameInformation, // 58 + FileIdInformation, // 59 + FileIdExtdDirectoryInformation, // 60 + FileReplaceCompletionInformation, // 61 + FileHardLinkFullIdInformation, // 62 + FileIdExtdBothDirectoryInformation, // 63 + FileDispositionInformationEx, // 64 + FileRenameInformationEx, // 65 + FileRenameInformationExBypassAccessCheck, // 66 + FileDesiredStorageClassInformation, // 67 + FileStatInformation, // 68 + FileMemoryPartitionInformation, // 69 + FileStatLxInformation, // 70 + FileCaseSensitiveInformation, // 71 + FileLinkInformationEx, // 72 + FileLinkInformationExBypassAccessCheck, // 73 + FileStorageReserveIdInformation, // 74 + FileCaseSensitiveInformationForceAccessCheck, // 75 FileMaximumInformation } FILE_INFORMATION_CLASS, *PFILE_INFORMATION_CLASS; -/* Checked on 64 bit. */ -typedef struct _FILE_NAMES_INFORMATION -{ - ULONG NextEntryOffset; - ULONG FileIndex; - ULONG FileNameLength; - WCHAR FileName[1]; -} FILE_NAMES_INFORMATION, *PFILE_NAMES_INFORMATION; - -/* Checked on 64 bit. */ -typedef struct _FILE_DIRECTORY_INFORMATION +typedef struct _FILE_DIRECTORY_INFORMATION // 1 { ULONG NextEntryOffset; ULONG FileIndex; @@ -241,8 +266,7 @@ typedef struct _FILE_DIRECTORY_INFORMATION WCHAR FileName[1]; } FILE_DIRECTORY_INFORMATION, *PFILE_DIRECTORY_INFORMATION; -/* Checked on 64 bit. */ -typedef struct _FILE_BOTH_DIR_INFORMATION +typedef struct _FILE_BOTH_DIR_INFORMATION // 3 { ULONG NextEntryOffset; ULONG FileIndex; @@ -260,8 +284,156 @@ typedef struct _FILE_BOTH_DIR_INFORMATION WCHAR FileName[1]; } FILE_BOTH_DIR_INFORMATION, *PFILE_BOTH_DIR_INFORMATION; -/* Checked on 64 bit. */ -typedef struct _FILE_ID_BOTH_DIR_INFORMATION +typedef struct _FILE_BASIC_INFORMATION // 4 +{ + LARGE_INTEGER CreationTime; + LARGE_INTEGER LastAccessTime; + LARGE_INTEGER LastWriteTime; + LARGE_INTEGER ChangeTime; + ULONG FileAttributes; +} FILE_BASIC_INFORMATION, *PFILE_BASIC_INFORMATION; + +typedef struct _FILE_STANDARD_INFORMATION // 5 +{ + LARGE_INTEGER AllocationSize; + LARGE_INTEGER EndOfFile; + ULONG NumberOfLinks; + BOOLEAN DeletePending; + BOOLEAN Directory; +} FILE_STANDARD_INFORMATION, *PFILE_STANDARD_INFORMATION; + +typedef struct _FILE_INTERNAL_INFORMATION // 6 +{ + LARGE_INTEGER IndexNumber; +} FILE_INTERNAL_INFORMATION, *PFILE_INTERNAL_INFORMATION; + +typedef struct _FILE_EA_INFORMATION // 7 +{ + ULONG EaSize; +} FILE_EA_INFORMATION, *PFILE_EA_INFORMATION; + +typedef struct _FILE_ACCESS_INFORMATION // 8 +{ + ACCESS_MASK AccessFlags; +} FILE_ACCESS_INFORMATION, *PFILE_ACCESS_INFORMATION; + +typedef struct _FILE_NAME_INFORMATION // 9, 21, 40 +{ + ULONG FileNameLength; + WCHAR FileName[1]; +} FILE_NAME_INFORMATION, *PFILE_NAME_INFORMATION; + +typedef struct _FILE_RENAME_INFORMATION // 10, 56, 65, 66 +{ + union + { + BOOLEAN ReplaceIfExists; // FileRenameInformation + ULONG Flags; // FileRenameInformationEx + }; + HANDLE RootDirectory; + ULONG FileNameLength; + WCHAR FileName[1]; +} FILE_RENAME_INFORMATION, *PFILE_RENAME_INFORMATION; + +typedef struct _FILE_LINK_INFORMATION // 11, 57, 72, 73 +{ + union + { + BOOLEAN ReplaceIfExists; // FileLinkInformation + ULONG Flags; // FileLinkInformationEx + }; + HANDLE RootDirectory; + ULONG FileNameLength; + WCHAR FileName[1]; +} FILE_LINK_INFORMATION, *PFILE_LINK_INFORMATION; + +typedef struct _FILE_NAMES_INFORMATION // 12 +{ + ULONG NextEntryOffset; + ULONG FileIndex; + ULONG FileNameLength; + WCHAR FileName[1]; +} FILE_NAMES_INFORMATION, *PFILE_NAMES_INFORMATION; + +typedef struct _FILE_DISPOSITION_INFORMATION // 13 +{ + BOOLEAN DeleteFile; +} FILE_DISPOSITION_INFORMATION, *PFILE_DISPOSITION_INFORMATION; + +typedef struct _FILE_POSITION_INFORMATION // 14 +{ + LARGE_INTEGER CurrentByteOffset; +} FILE_POSITION_INFORMATION, *PFILE_POSITION_INFORMATION; + +typedef struct _FILE_MODE_INFORMATION // 16 +{ + ULONG Mode; +} FILE_MODE_INFORMATION, *PFILE_MODE_INFORMATION; + +typedef struct _FILE_ALIGNMENT_INFORMATION // 17 +{ + ULONG AlignmentRequirement; +} FILE_ALIGNMENT_INFORMATION; + +typedef struct _FILE_ALL_INFORMATION { // 18 + FILE_BASIC_INFORMATION BasicInformation; + FILE_STANDARD_INFORMATION StandardInformation; + FILE_INTERNAL_INFORMATION InternalInformation; + FILE_EA_INFORMATION EaInformation; + FILE_ACCESS_INFORMATION AccessInformation; + FILE_POSITION_INFORMATION PositionInformation; + FILE_MODE_INFORMATION ModeInformation; + FILE_ALIGNMENT_INFORMATION AlignmentInformation; + FILE_NAME_INFORMATION NameInformation; +} FILE_ALL_INFORMATION, *PFILE_ALL_INFORMATION; + +typedef struct _FILE_END_OF_FILE_INFORMATION // 20 +{ + LARGE_INTEGER EndOfFile; +} FILE_END_OF_FILE_INFORMATION, *PFILE_END_OF_FILE_INFORMATION; + +typedef struct _FILE_PIPE_INFORMATION // 23 +{ + ULONG ReadMode; + ULONG CompletionMode; +} FILE_PIPE_INFORMATION, *PFILE_PIPE_INFORMATION; + +typedef struct _FILE_PIPE_LOCAL_INFORMATION // 24 +{ + ULONG NamedPipeType; + ULONG NamedPipeConfiguration; + ULONG MaximumInstances; + ULONG CurrentInstances; + ULONG InboundQuota; + ULONG ReadDataAvailable; + ULONG OutboundQuota; + ULONG WriteQuotaAvailable; + ULONG NamedPipeState; + ULONG NamedPipeEnd; +} FILE_PIPE_LOCAL_INFORMATION, *PFILE_PIPE_LOCAL_INFORMATION; + +typedef struct _FILE_COMPRESSION_INFORMATION // 28 +{ + LARGE_INTEGER CompressedFileSize; + USHORT CompressionFormat; + UCHAR CompressionUnitShift; + UCHAR ChunkShift; + UCHAR ClusterShift; + UCHAR Reserved[3]; +} FILE_COMPRESSION_INFORMATION, *PFILE_COMPRESSION_INFORMATION; + +typedef struct _FILE_NETWORK_OPEN_INFORMATION // 34 +{ + LARGE_INTEGER CreationTime; + LARGE_INTEGER LastAccessTime; + LARGE_INTEGER LastWriteTime; + LARGE_INTEGER ChangeTime; + LARGE_INTEGER AllocationSize; + LARGE_INTEGER EndOfFile; + ULONG FileAttributes; +} FILE_NETWORK_OPEN_INFORMATION, *PFILE_NETWORK_OPEN_INFORMATION; + +typedef struct _FILE_ID_BOTH_DIR_INFORMATION // 37 { ULONG NextEntryOffset; ULONG FileIndex; @@ -280,6 +452,127 @@ typedef struct _FILE_ID_BOTH_DIR_INFORMATION WCHAR FileName[1]; } FILE_ID_BOTH_DIR_INFORMATION, *PFILE_ID_BOTH_DIR_INFORMATION; +typedef struct _FILE_PROCESS_IDS_USING_FILE_INFORMATION // 47 +{ + ULONG NumberOfProcessIdsInList; + ULONG_PTR ProcessIdList[1]; +} FILE_PROCESS_IDS_USING_FILE_INFORMATION, + *PFILE_PROCESS_IDS_USING_FILE_INFORMATION; + +typedef struct _FILE_DISPOSITION_INFORMATION_EX // 64 +{ + ULONG Flags; +} FILE_DISPOSITION_INFORMATION_EX, *PFILE_DISPOSITION_INFORMATION_EX; + +typedef struct _FILE_STAT_INFORMATION // 68 +{ + LARGE_INTEGER FileId; + LARGE_INTEGER CreationTime; + LARGE_INTEGER LastAccessTime; + LARGE_INTEGER LastWriteTime; + LARGE_INTEGER ChangeTime; + LARGE_INTEGER AllocationSize; + LARGE_INTEGER EndOfFile; + ULONG FileAttributes; + ULONG ReparseTag; + ULONG NumberOfLinks; + ACCESS_MASK EffectiveAccess; +} FILE_STAT_INFORMATION, *PFILE_STAT_INFORMATION; + +typedef struct _FILE_CASE_SENSITIVE_INFORMATION // 71 +{ + ULONG Flags; +} FILE_CASE_SENSITIVE_INFORMATION, *PFILE_CASE_SENSITIVE_INFORMATION; + +enum { + FILE_LINK_REPLACE_IF_EXISTS = 0x01, + FILE_LINK_POSIX_SEMANTICS = 0x02, + FILE_LINK_SUPPRESS_STORAGE_RESERVE_INHERITANCE = 0x08, + FILE_LINK_NO_INCREASE_AVAILABLE_SPACE = 0x10, + FILE_LINK_NO_DECREASE_AVAILABLE_SPACE = 0x20, + FILE_LINK_PRESERVE_AVAILABLE_SPACE = 0x30, + FILE_LINK_IGNORE_READONLY_ATTRIBUTE = 0x40 +}; + +enum { + FILE_DISPOSITION_DO_NOT_DELETE = 0x00, + FILE_DISPOSITION_DELETE = 0x01, + FILE_DISPOSITION_POSIX_SEMANTICS = 0x02, + FILE_DISPOSITION_FORCE_IMAGE_SECTION_CHECK = 0x04, + FILE_DISPOSITION_ON_CLOSE = 0x08 +}; + +enum +{ + FILE_RENAME_REPLACE_IF_EXISTS = 0x01, + FILE_RENAME_POSIX_SEMANTICS = 0x02, + FILE_RENAME_SUPPRESS_PIN_STATE_INHERITANCE = 0x04, + FILE_RENAME_SUPPRESS_STORAGE_RESERVE_INHERITANCE = 0x08, + FILE_RENAME_NO_INCREASE_AVAILABLE_SPACE = 0x10, + FILE_RENAME_NO_DECREASE_AVAILABLE_SPACE = 0x20, + FILE_RENAME_PRESERVE_AVAILABLE_SPACE = 0x30, + FILE_RENAME_IGNORE_READONLY_ATTRIBUTE = 0x40 +}; + +enum +{ + FILE_CS_FLAG_CASE_SENSITIVE_DIR = 0x01 +}; + +enum +{ + FILE_PIPE_QUEUE_OPERATION = 0, + FILE_PIPE_COMPLETE_OPERATION = 1 +}; + +enum +{ + FILE_PIPE_BYTE_STREAM_MODE = 0, + FILE_PIPE_MESSAGE_MODE = 1 +}; + +enum +{ + FILE_PIPE_DISCONNECTED_STATE = 1, + FILE_PIPE_LISTENING_STATE = 2, + FILE_PIPE_CONNECTED_STATE = 3, + FILE_PIPE_CLOSING_STATE = 4 +}; + +enum +{ + FILE_PIPE_INBOUND = 0, + FILE_PIPE_OUTBOUND = 1, + FILE_PIPE_FULL_DUPLEX = 2 +}; + +enum +{ + FILE_PIPE_CLIENT_END = 0, + FILE_PIPE_SERVER_END = 1 +}; + +enum +{ + FILE_PIPE_BYTE_STREAM_TYPE = 0, + FILE_PIPE_MESSAGE_TYPE = 1 +}; + +typedef struct _FILE_PIPE_PEEK_BUFFER { + ULONG NamedPipeState; + ULONG ReadDataAvailable; + ULONG NumberOfMessages; + ULONG MessageLength; + CHAR Data[1]; +} FILE_PIPE_PEEK_BUFFER, *PFILE_PIPE_PEEK_BUFFER; + +typedef struct _FILE_PIPE_WAIT_FOR_BUFFER { + LARGE_INTEGER Timeout; + ULONG NameLength; + BOOLEAN TimeoutSpecified; + WCHAR Name[1]; +} FILE_PIPE_WAIT_FOR_BUFFER, *PFILE_PIPE_WAIT_FOR_BUFFER; + typedef enum _SYSTEM_INFORMATION_CLASS { SystemBasicInformation = 0, @@ -292,7 +585,6 @@ typedef enum _SYSTEM_INFORMATION_CLASS /* There are a lot more of these... */ } SYSTEM_INFORMATION_CLASS; -/* Checked on 64 bit. */ typedef struct _SYSTEM_BASIC_INFORMATION { ULONG Unknown; @@ -308,7 +600,6 @@ typedef struct _SYSTEM_BASIC_INFORMATION UCHAR NumberProcessors; } SYSTEM_BASIC_INFORMATION, *PSYSTEM_BASIC_INFORMATION; -/* Checked on 64 bit. */ typedef struct _SYSTEM_PAGEFILE_INFORMATION { ULONG NextEntryOffset; @@ -318,7 +609,6 @@ typedef struct _SYSTEM_PAGEFILE_INFORMATION UNICODE_STRING FileName; } SYSTEM_PAGEFILE_INFORMATION, *PSYSTEM_PAGEFILE_INFORMATION; -/* Checked on 64 bit. */ typedef struct _SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION { LARGE_INTEGER IdleTime; @@ -331,7 +621,6 @@ typedef struct _SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION typedef LONG KPRIORITY; -/* Checked on 64 bit. */ typedef struct _VM_COUNTERS { SIZE_T PeakVirtualSize; @@ -347,7 +636,6 @@ typedef struct _VM_COUNTERS SIZE_T PeakPagefileUsage; } VM_COUNTERS, *PVM_COUNTERS; -/* Checked on 64 bit. */ typedef struct _CLIENT_ID { HANDLE UniqueProcess; @@ -398,7 +686,6 @@ typedef enum MaximumWaitReason } KWAIT_REASON; -/* Checked on 64 bit. */ typedef struct _SYSTEM_THREADS { LARGE_INTEGER KernelTime; @@ -415,7 +702,6 @@ typedef struct _SYSTEM_THREADS DWORD Reserved; } SYSTEM_THREADS, *PSYSTEM_THREADS; -/* Checked on 64 bit. */ typedef struct _SYSTEM_PROCESS_INFORMATION { ULONG NextEntryOffset; @@ -437,7 +723,6 @@ typedef struct _SYSTEM_PROCESS_INFORMATION SYSTEM_THREADS Threads[1]; } SYSTEM_PROCESS_INFORMATION, *PSYSTEM_PROCESS_INFORMATION; -/* Checked on 64 bit. */ typedef struct _IO_STATUS_BLOCK { union { @@ -447,7 +732,6 @@ typedef struct _IO_STATUS_BLOCK ULONG_PTR Information; } IO_STATUS_BLOCK, *PIO_STATUS_BLOCK; -/* Checked on 64 bit. */ typedef struct _SYSTEM_PERFORMANCE_INFORMATION { LARGE_INTEGER IdleTime; @@ -525,7 +809,6 @@ typedef struct _SYSTEM_PERFORMANCE_INFORMATION ULONG SystemCalls; } SYSTEM_PERFORMANCE_INFORMATION, *PSYSTEM_PERFORMANCE_INFORMATION; -/* Checked on 64 bit. */ typedef struct _SYSTEM_TIMEOFDAY_INFORMATION { LARGE_INTEGER BootTime; @@ -547,7 +830,6 @@ typedef enum _PROCESSINFOCLASS ProcessDebugFlags = 31 } PROCESSINFOCLASS; -/* Checked on 64 bit. */ typedef struct _DEBUG_BUFFER { HANDLE SectionHandle; @@ -568,7 +850,6 @@ typedef struct _DEBUG_BUFFER PVOID Reserved[8]; } DEBUG_BUFFER, *PDEBUG_BUFFER; -/* Checked on 64 bit. */ typedef struct _DEBUG_HEAP_INFORMATION { ULONG_PTR Base; @@ -584,14 +865,12 @@ typedef struct _DEBUG_HEAP_INFORMATION PVOID Blocks; } DEBUG_HEAP_INFORMATION, *PDEBUG_HEAP_INFORMATION; -/* Checked on 64 bit. */ typedef struct _DEBUG_HEAP_ARRAY { ULONG Count; DEBUG_HEAP_INFORMATION Heaps[1]; } DEBUG_HEAP_ARRAY, *PDEBUG_HEAP_ARRAY; -/* Checked on 64 bit. */ typedef struct _DEBUG_HEAP_BLOCK { ULONG_PTR Size; @@ -600,7 +879,6 @@ typedef struct _DEBUG_HEAP_BLOCK ULONG_PTR Address; } DEBUG_HEAP_BLOCK, *PDEBUG_HEAP_BLOCK; -/* Checked on 64 bit. */ typedef struct _DEBUG_MODULE_INFORMATION { ULONG_PTR Reserved[2]; @@ -614,14 +892,12 @@ typedef struct _DEBUG_MODULE_INFORMATION CHAR ImageName[256]; } DEBUG_MODULE_INFORMATION, *PDEBUG_MODULE_INFORMATION; -/* Checked on 64 bit. */ typedef struct _DEBUG_MODULE_ARRAY { ULONG Count; DEBUG_MODULE_INFORMATION Modules[1]; } DEBUG_MODULE_ARRAY, *PDEBUG_MODULE_ARRAY; -/* Checked on 64 bit. */ typedef struct _KERNEL_USER_TIMES { LARGE_INTEGER CreateTime; @@ -630,7 +906,6 @@ typedef struct _KERNEL_USER_TIMES LARGE_INTEGER UserTime; } KERNEL_USER_TIMES, *PKERNEL_USER_TIMES; -/* Checked on 64 bit. */ typedef struct _LDR_DATA_TABLE_ENTRY { /* Heads up! The pointers within the LIST_ENTRYs don't point to the @@ -651,7 +926,6 @@ typedef struct _LDR_DATA_TABLE_ENTRY including WOW64. */ } LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY; -/* Checked on 64 bit. */ typedef struct _PEB_LDR_DATA { ULONG Length; @@ -666,7 +940,6 @@ typedef struct _PEB_LDR_DATA PVOID EntryInProgress; } PEB_LDR_DATA, *PPEB_LDR_DATA; -/* Checked on 64 bit. */ typedef struct _RTL_USER_PROCESS_PARAMETERS { ULONG AllocationSize; @@ -699,7 +972,6 @@ typedef struct _RTL_USER_PROCESS_PARAMETERS UNICODE_STRING RuntimeInfo; } RTL_USER_PROCESS_PARAMETERS, *PRTL_USER_PROCESS_PARAMETERS; -/* Checked on 64 bit. */ typedef struct _PEB { BYTE Reserved1[2]; @@ -719,7 +991,6 @@ typedef struct _PEB /* A lot more follows... */ } PEB, *PPEB; -/* Checked on 64 bit. */ typedef struct _GDI_TEB_BATCH { ULONG Offset; @@ -727,7 +998,6 @@ typedef struct _GDI_TEB_BATCH ULONG Buffer[0x136]; } GDI_TEB_BATCH, *PGDI_TEB_BATCH; -/* Checked on 64 bit. */ typedef struct _TEB { NT_TIB Tib; @@ -778,7 +1048,6 @@ typedef struct _TEB /* A lot more follows... */ } TEB, *PTEB; -/* Checked on 64 bit. */ typedef struct _KSYSTEM_TIME { ULONG LowPart; @@ -786,7 +1055,6 @@ typedef struct _KSYSTEM_TIME LONG High2Time; } KSYSTEM_TIME, *PKSYSTEM_TIME; -/* Checked on 64 bit. */ typedef struct _KUSER_SHARED_DATA { BYTE Reserved1[0x08]; @@ -797,7 +1065,6 @@ typedef struct _KUSER_SHARED_DATA UINT64 InterruptTimeBias; } KUSER_SHARED_DATA, *PKUSER_SHARED_DATA; -/* Checked on 64 bit. */ typedef struct _PROCESS_BASIC_INFORMATION { NTSTATUS ExitStatus; @@ -808,7 +1075,6 @@ typedef struct _PROCESS_BASIC_INFORMATION ULONG_PTR InheritedFromUniqueProcessId; } PROCESS_BASIC_INFORMATION, *PPROCESS_BASIC_INFORMATION; -/* Checked on 64 bit. */ typedef struct _PROCESS_SESSION_INFORMATION { ULONG SessionId; @@ -822,234 +1088,23 @@ typedef enum _MEMORY_INFORMATION_CLASS MemoryBasicVlmInformation } MEMORY_INFORMATION_CLASS; -/* Checked on 64 bit. */ typedef struct _MEMORY_WORKING_SET_LIST { ULONG NumberOfPages; ULONG_PTR WorkingSetList[1]; } MEMORY_WORKING_SET_LIST, *PMEMORY_WORKING_SET_LIST; -/* Checked on 64 bit. */ typedef struct _MEMORY_SECTION_NAME { UNICODE_STRING SectionFileName; } MEMORY_SECTION_NAME, *PMEMORY_SECTION_NAME; -/* Checked on 64 bit. */ -typedef struct _FILE_BASIC_INFORMATION -{ - LARGE_INTEGER CreationTime; - LARGE_INTEGER LastAccessTime; - LARGE_INTEGER LastWriteTime; - LARGE_INTEGER ChangeTime; - ULONG FileAttributes; -} FILE_BASIC_INFORMATION, *PFILE_BASIC_INFORMATION; - -/* Checked on 64 bit. */ -typedef struct _FILE_STANDARD_INFORMATION -{ - LARGE_INTEGER AllocationSize; - LARGE_INTEGER EndOfFile; - ULONG NumberOfLinks; - BOOLEAN DeletePending; - BOOLEAN Directory; -} FILE_STANDARD_INFORMATION, *PFILE_STANDARD_INFORMATION; - -/* Checked on 64 bit. */ -typedef struct _FILE_NETWORK_OPEN_INFORMATION -{ - LARGE_INTEGER CreationTime; - LARGE_INTEGER LastAccessTime; - LARGE_INTEGER LastWriteTime; - LARGE_INTEGER ChangeTime; - LARGE_INTEGER AllocationSize; - LARGE_INTEGER EndOfFile; - ULONG FileAttributes; -} FILE_NETWORK_OPEN_INFORMATION, *PFILE_NETWORK_OPEN_INFORMATION; - -/* Checked on 64 bit. */ -typedef struct _FILE_INTERNAL_INFORMATION -{ - LARGE_INTEGER IndexNumber; -} FILE_INTERNAL_INFORMATION, *PFILE_INTERNAL_INFORMATION; - -/* Checked on 64 bit. */ -typedef struct _FILE_EA_INFORMATION -{ - ULONG EaSize; -} FILE_EA_INFORMATION, *PFILE_EA_INFORMATION; - -/* Checked on 64 bit. */ -typedef struct _FILE_ACCESS_INFORMATION -{ - ACCESS_MASK AccessFlags; -} FILE_ACCESS_INFORMATION, *PFILE_ACCESS_INFORMATION; - -/* Checked on 64 bit. */ -typedef struct _FILE_DISPOSITION_INFORMATION -{ - BOOLEAN DeleteFile; -} FILE_DISPOSITION_INFORMATION, *PFILE_DISPOSITION_INFORMATION; - -/* Checked on 64 bit. */ -typedef struct _FILE_POSITION_INFORMATION -{ - LARGE_INTEGER CurrentByteOffset; -} FILE_POSITION_INFORMATION, *PFILE_POSITION_INFORMATION; - -/* Checked on 64 bit. */ -typedef struct _FILE_END_OF_FILE_INFORMATION -{ - LARGE_INTEGER EndOfFile; -} FILE_END_OF_FILE_INFORMATION, *PFILE_END_OF_FILE_INFORMATION; - -/* Checked on 64 bit. */ -typedef struct _FILE_MODE_INFORMATION -{ - ULONG Mode; -} FILE_MODE_INFORMATION, *PFILE_MODE_INFORMATION; - -/* Checked on 64 bit. */ -typedef struct _FILE_ALIGNMENT_INFORMATION -{ - ULONG AlignmentRequirement; -} FILE_ALIGNMENT_INFORMATION; - -/* Checked on 64 bit. */ -typedef struct _FILE_NAME_INFORMATION -{ - ULONG FileNameLength; - WCHAR FileName[1]; -} FILE_NAME_INFORMATION, *PFILE_NAME_INFORMATION; - -/* Checked on 64 bit. */ -typedef struct _FILE_LINK_INFORMATION -{ - BOOLEAN ReplaceIfExists; - HANDLE RootDirectory; - ULONG FileNameLength; - WCHAR FileName[1]; -} FILE_LINK_INFORMATION, *PFILE_LINK_INFORMATION; - -/* Checked on 64 bit. */ -typedef struct _FILE_RENAME_INFORMATION -{ - BOOLEAN ReplaceIfExists; - HANDLE RootDirectory; - ULONG FileNameLength; - WCHAR FileName[1]; -} FILE_RENAME_INFORMATION, *PFILE_RENAME_INFORMATION; - -/* Checked on 64 bit. */ -typedef struct _FILE_ALL_INFORMATION { - FILE_BASIC_INFORMATION BasicInformation; - FILE_STANDARD_INFORMATION StandardInformation; - FILE_INTERNAL_INFORMATION InternalInformation; - FILE_EA_INFORMATION EaInformation; - FILE_ACCESS_INFORMATION AccessInformation; - FILE_POSITION_INFORMATION PositionInformation; - FILE_MODE_INFORMATION ModeInformation; - FILE_ALIGNMENT_INFORMATION AlignmentInformation; - FILE_NAME_INFORMATION NameInformation; -} FILE_ALL_INFORMATION, *PFILE_ALL_INFORMATION; - -enum -{ - FILE_PIPE_QUEUE_OPERATION = 0, - FILE_PIPE_COMPLETE_OPERATION = 1 -}; - -enum -{ - FILE_PIPE_BYTE_STREAM_MODE = 0, - FILE_PIPE_MESSAGE_MODE = 1 -}; - -enum -{ - FILE_PIPE_DISCONNECTED_STATE = 1, - FILE_PIPE_LISTENING_STATE = 2, - FILE_PIPE_CONNECTED_STATE = 3, - FILE_PIPE_CLOSING_STATE = 4 -}; - -enum -{ - FILE_PIPE_INBOUND = 0, - FILE_PIPE_OUTBOUND = 1, - FILE_PIPE_FULL_DUPLEX = 2 -}; - -enum -{ - FILE_PIPE_CLIENT_END = 0, - FILE_PIPE_SERVER_END = 1 -}; - -enum -{ - FILE_PIPE_BYTE_STREAM_TYPE = 0, - FILE_PIPE_MESSAGE_TYPE = 1 -}; - -/* Checked on 64 bit. */ -typedef struct _FILE_PIPE_INFORMATION -{ - ULONG ReadMode; - ULONG CompletionMode; -} FILE_PIPE_INFORMATION, *PFILE_PIPE_INFORMATION; - -/* Checked on 64 bit. */ -typedef struct _FILE_PIPE_LOCAL_INFORMATION -{ - ULONG NamedPipeType; - ULONG NamedPipeConfiguration; - ULONG MaximumInstances; - ULONG CurrentInstances; - ULONG InboundQuota; - ULONG ReadDataAvailable; - ULONG OutboundQuota; - ULONG WriteQuotaAvailable; - ULONG NamedPipeState; - ULONG NamedPipeEnd; -} FILE_PIPE_LOCAL_INFORMATION, *PFILE_PIPE_LOCAL_INFORMATION; - -/* Checked on 64 bit. */ -typedef struct _FILE_PIPE_PEEK_BUFFER { - ULONG NamedPipeState; - ULONG ReadDataAvailable; - ULONG NumberOfMessages; - ULONG MessageLength; - CHAR Data[1]; -} FILE_PIPE_PEEK_BUFFER, *PFILE_PIPE_PEEK_BUFFER; - -/* Checked on 64 bit. */ -typedef struct _FILE_PIPE_WAIT_FOR_BUFFER { - LARGE_INTEGER Timeout; - ULONG NameLength; - BOOLEAN TimeoutSpecified; - WCHAR Name[1]; -} FILE_PIPE_WAIT_FOR_BUFFER, *PFILE_PIPE_WAIT_FOR_BUFFER; - -/* Checked on 64 bit. */ -typedef struct _FILE_COMPRESSION_INFORMATION -{ - LARGE_INTEGER CompressedFileSize; - USHORT CompressionFormat; - UCHAR CompressionUnitShift; - UCHAR ChunkShift; - UCHAR ClusterShift; - UCHAR Reserved[3]; -} FILE_COMPRESSION_INFORMATION, *PFILE_COMPRESSION_INFORMATION; - -/* Checked on 64 bit. */ typedef struct _FILE_FS_DEVICE_INFORMATION { ULONG DeviceType; ULONG Characteristics; } FILE_FS_DEVICE_INFORMATION, *PFILE_FS_DEVICE_INFORMATION; -/* Checked on 64 bit. */ typedef struct _FILE_FS_ATTRIBUTE_INFORMATION { ULONG FileSystemAttributes; @@ -1058,7 +1113,6 @@ typedef struct _FILE_FS_ATTRIBUTE_INFORMATION WCHAR FileSystemName[1]; } FILE_FS_ATTRIBUTE_INFORMATION, *PFILE_FS_ATTRIBUTE_INFORMATION; -/* Checked on 64 bit. */ #pragma pack(push,4) typedef struct _FILE_FS_VOLUME_INFORMATION { @@ -1071,7 +1125,6 @@ typedef struct _FILE_FS_VOLUME_INFORMATION } FILE_FS_VOLUME_INFORMATION, *PFILE_FS_VOLUME_INFORMATION; #pragma pack(pop) -/* Checked on 64 bit. */ typedef struct _FILE_FS_SIZE_INFORMATION { LARGE_INTEGER TotalAllocationUnits; @@ -1080,7 +1133,6 @@ typedef struct _FILE_FS_SIZE_INFORMATION ULONG BytesPerSector; } FILE_FS_SIZE_INFORMATION, *PFILE_FS_SIZE_INFORMATION; -/* Checked on 64 bit. */ typedef struct _FILE_FS_CONTROL_INFORMATION { LARGE_INTEGER FreeSpaceStartFiltering; LARGE_INTEGER FreeSpaceThreshold; @@ -1090,7 +1142,6 @@ typedef struct _FILE_FS_CONTROL_INFORMATION { ULONG FileSystemControlFlags; } FILE_FS_CONTROL_INFORMATION, *PFILE_FS_CONTROL_INFORMATION; -/* Checked on 64 bit. */ typedef struct _FILE_FS_FULL_SIZE_INFORMATION { LARGE_INTEGER TotalAllocationUnits; @@ -1100,7 +1151,6 @@ typedef struct _FILE_FS_FULL_SIZE_INFORMATION ULONG BytesPerSector; } FILE_FS_FULL_SIZE_INFORMATION, *PFILE_FS_FULL_SIZE_INFORMATION; -/* Checked on 64 bit. */ typedef struct _FILE_FS_OBJECTID_INFORMATION { UCHAR ObjectId[16]; @@ -1128,7 +1178,6 @@ typedef enum _OBJECT_INFORMATION_CLASS // and many more } OBJECT_INFORMATION_CLASS; -/* Checked on 64 bit. */ typedef struct _OBJECT_BASIC_INFORMATION { ULONG Attributes; @@ -1144,27 +1193,23 @@ typedef struct _OBJECT_BASIC_INFORMATION LARGE_INTEGER CreateTime; } OBJECT_BASIC_INFORMATION, *POBJECT_BASIC_INFORMATION; -/* Checked on 64 bit. */ typedef struct _OBJECT_NAME_INFORMATION { UNICODE_STRING Name; } OBJECT_NAME_INFORMATION; -/* Checked on 64 bit. */ typedef struct _DIRECTORY_BASIC_INFORMATION { UNICODE_STRING ObjectName; UNICODE_STRING ObjectTypeName; } DIRECTORY_BASIC_INFORMATION, *PDIRECTORY_BASIC_INFORMATION; -/* Checked on 64 bit. */ typedef struct _FILE_GET_QUOTA_INFORMATION { ULONG NextEntryOffset; ULONG SidLength; SID Sid; } FILE_GET_QUOTA_INFORMATION, *PFILE_GET_QUOTA_INFORMATION; -/* Checked on 64 bit. */ typedef struct _FILE_QUOTA_INFORMATION { ULONG NextEntryOffset; ULONG SidLength; @@ -1175,7 +1220,6 @@ typedef struct _FILE_QUOTA_INFORMATION { SID Sid; } FILE_QUOTA_INFORMATION, *PFILE_QUOTA_INFORMATION; -/* Checked on 64 bit. */ typedef struct _FILE_GET_EA_INFORMATION { ULONG NextEntryOffset; @@ -1183,7 +1227,6 @@ typedef struct _FILE_GET_EA_INFORMATION CHAR EaName[1]; } FILE_GET_EA_INFORMATION, *PFILE_GET_EA_INFORMATION; -/* Checked on 64 bit. */ typedef struct _FILE_FULL_EA_INFORMATION { ULONG NextEntryOffset; @@ -1193,7 +1236,6 @@ typedef struct _FILE_FULL_EA_INFORMATION CHAR EaName[1]; } FILE_FULL_EA_INFORMATION, *PFILE_FULL_EA_INFORMATION; -/* Checked on 64 bit. */ typedef struct _FILE_MAILSLOT_SET_INFORMATION { LARGE_INTEGER ReadTimeout; @@ -1201,7 +1243,6 @@ typedef struct _FILE_MAILSLOT_SET_INFORMATION typedef VOID NTAPI (*PIO_APC_ROUTINE)(PVOID, PIO_STATUS_BLOCK, ULONG); -/* Checked on 64 bit. */ typedef struct _EVENT_BASIC_INFORMATION { EVENT_TYPE EventType; @@ -1213,7 +1254,6 @@ typedef enum _EVENT_INFORMATION_CLASS EventBasicInformation = 0 } EVENT_INFORMATION_CLASS, *PEVENT_INFORMATION_CLASS; -/* Checked on 64 bit. */ typedef struct _SEMAPHORE_BASIC_INFORMATION { LONG CurrentCount; @@ -1233,7 +1273,6 @@ typedef enum _THREADINFOCLASS ThreadQuerySetWin32StartAddress = 9 } THREADINFOCLASS, *PTHREADINFOCLASS; -/* Checked on 64 bit. */ typedef struct _THREAD_BASIC_INFORMATION { NTSTATUS ExitStatus; From 092a768885fceb0962c8654b176d1046e2af081d Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Sun, 23 Dec 2018 00:21:21 +0100 Subject: [PATCH 028/475] Cygwin: wincap: add wincap_10_1709, add has_posix_file_info item Various new file info class members adding important POSIX semantics have been added with W10 1709. We may want to utilize them, so add a matching wincaps. Rearrange checking the W10 build number to prefer the latest builds over the older builds. Rename wincap_10 to wincap_10_1507 for enhanced clarity. Signed-off-by: Corinna Vinschen --- winsup/cygwin/wincap.cc | 42 +++++++++++++++++++++++++++++++++++------ winsup/cygwin/wincap.h | 2 ++ 2 files changed, 38 insertions(+), 6 deletions(-) diff --git a/winsup/cygwin/wincap.cc b/winsup/cygwin/wincap.cc index d5d8ef63c..4ba9aa51d 100644 --- a/winsup/cygwin/wincap.cc +++ b/winsup/cygwin/wincap.cc @@ -8,6 +8,7 @@ Cygwin license. Please consult the file "CYGWIN_LICENSE" for details. */ #include "winsup.h" +#include "miscfuncs.h" #include "security.h" #include "ntdll.h" @@ -34,6 +35,7 @@ wincaps wincap_vista __attribute__((section (".cygwin_dll_common"), shared)) = { has_unprivileged_createsymlink:false, has_unbiased_interrupt_time:false, has_precise_interrupt_time:false, + has_posix_file_info:false, }, }; @@ -54,6 +56,7 @@ wincaps wincap_7 __attribute__((section (".cygwin_dll_common"), shared)) = { has_unprivileged_createsymlink:false, has_unbiased_interrupt_time:true, has_precise_interrupt_time:false, + has_posix_file_info:false, }, }; @@ -74,10 +77,11 @@ wincaps wincap_8 __attribute__((section (".cygwin_dll_common"), shared)) = { has_unprivileged_createsymlink:false, has_unbiased_interrupt_time:true, has_precise_interrupt_time:false, + has_posix_file_info:false, }, }; -wincaps wincap_10 __attribute__((section (".cygwin_dll_common"), shared)) = { +wincaps wincap_10_1507 __attribute__((section (".cygwin_dll_common"), shared)) = { def_guard_pages:2, { is_server:false, @@ -94,6 +98,7 @@ wincaps wincap_10 __attribute__((section (".cygwin_dll_common"), shared)) = { has_unprivileged_createsymlink:false, has_unbiased_interrupt_time:true, has_precise_interrupt_time:true, + has_posix_file_info:false, }, }; @@ -114,6 +119,7 @@ wincaps wincap_10_1511 __attribute__((section (".cygwin_dll_common"), shared)) = has_unprivileged_createsymlink:false, has_unbiased_interrupt_time:true, has_precise_interrupt_time:true, + has_posix_file_info:false, }, }; @@ -134,6 +140,28 @@ wincaps wincap_10_1703 __attribute__((section (".cygwin_dll_common"), shared)) = has_unprivileged_createsymlink:true, has_unbiased_interrupt_time:true, has_precise_interrupt_time:true, + has_posix_file_info:false, + }, +}; + +wincaps wincap_10_1709 __attribute__((section (".cygwin_dll_common"), shared)) = { + def_guard_pages:2, + { + is_server:false, + needs_count_in_si_lpres2:false, + has_gaa_largeaddress_bug:false, + has_broken_alloc_console:true, + has_console_logon_sid:true, + has_precise_system_time:true, + has_microsoft_accounts:true, + has_processor_groups:true, + has_broken_prefetchvm:false, + has_new_pebteb_region:true, + has_broken_whoami:false, + has_unprivileged_createsymlink:true, + has_unbiased_interrupt_time:true, + has_precise_interrupt_time:true, + has_posix_file_info:true, }, }; @@ -171,18 +199,20 @@ wincapc::init () caps = &wincap_8; break; default: - caps = &wincap_10; + caps = &wincap_10_1507; break; } break; case 10: default: - if (version.dwBuildNumber < 10586) - caps = &wincap_10; - else if (version.dwBuildNumber < 15063) + if (likely (version.dwBuildNumber >= 16299)) + caps = &wincap_10_1709; + else if (version.dwBuildNumber >= 15063) + caps = &wincap_10_1703; + else if (version.dwBuildNumber >= 10586) caps = &wincap_10_1511; else - caps = &wincap_10_1703; + caps = & wincap_10_1507; } ((wincaps *)caps)->is_server = (version.wProductType != VER_NT_WORKSTATION); diff --git a/winsup/cygwin/wincap.h b/winsup/cygwin/wincap.h index cc1c6ba99..649246299 100644 --- a/winsup/cygwin/wincap.h +++ b/winsup/cygwin/wincap.h @@ -29,6 +29,7 @@ struct wincaps unsigned has_unprivileged_createsymlink : 1; unsigned has_unbiased_interrupt_time : 1; unsigned has_precise_interrupt_time : 1; + unsigned has_posix_file_info : 1; }; }; @@ -78,6 +79,7 @@ public: bool IMPLEMENT (has_unprivileged_createsymlink) bool IMPLEMENT (has_unbiased_interrupt_time) bool IMPLEMENT (has_precise_interrupt_time) + bool IMPLEMENT (has_posix_file_info) #undef IMPLEMENT }; From 0c25ca40ce7897e3951a91986b6381ebe6ea7d23 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Sun, 23 Dec 2018 17:53:55 +0100 Subject: [PATCH 029/475] Cygwin: support exFAT and fix remote FAT/FAT32 recognition Newer FAT32 and exFAT add FILE_SUPPORTS_ENCRYPTION to their flags which wasn't handled by Cygwin yet. Signed-off-by: Corinna Vinschen --- winsup/cygwin/globals.cc | 1 + winsup/cygwin/mount.cc | 8 +++++++- winsup/cygwin/mount.h | 2 ++ winsup/cygwin/path.h | 2 ++ 4 files changed, 12 insertions(+), 1 deletion(-) diff --git a/winsup/cygwin/globals.cc b/winsup/cygwin/globals.cc index 7c84eb637..ebe8b569f 100644 --- a/winsup/cygwin/globals.cc +++ b/winsup/cygwin/globals.cc @@ -130,6 +130,7 @@ const int __collate_load_error = 0; extern UNICODE_STRING _RDATA ro_u_mtx = _ROU (L"mtx"); extern UNICODE_STRING _RDATA ro_u_csc = _ROU (L"CSC-CACHE"); extern UNICODE_STRING _RDATA ro_u_fat = _ROU (L"FAT"); + extern UNICODE_STRING _RDATA ro_u_exfat = _ROU (L"exFAT"); extern UNICODE_STRING _RDATA ro_u_mvfs = _ROU (L"MVFS"); extern UNICODE_STRING _RDATA ro_u_nfs = _ROU (L"NFS"); extern UNICODE_STRING _RDATA ro_u_ntfs = _ROU (L"NTFS"); diff --git a/winsup/cygwin/mount.cc b/winsup/cygwin/mount.cc index c11ae5ace..9fd98541d 100644 --- a/winsup/cygwin/mount.cc +++ b/winsup/cygwin/mount.cc @@ -343,9 +343,11 @@ fs_info::update (PUNICODE_STRING upath, HANDLE in_vol) #define FS_IS_WINDOWS_NTFS TEST_GVI(flags () & MINIMAL_WIN_NTFS_FLAGS, \ MINIMAL_WIN_NTFS_FLAGS) /* These are the exact flags of a real Windows FAT/FAT32 filesystem. + Newer FAT32/exFAT support FILE_SUPPORTS_ENCRYPTION as well. Anything else is a filesystem faking to be FAT. */ #define WIN_FAT_FLAGS (FILE_CASE_PRESERVED_NAMES | FILE_UNICODE_ON_DISK) -#define FS_IS_WINDOWS_FAT TEST_GVI(flags (), WIN_FAT_FLAGS) +#define FAT_IGNORE (FILE_SUPPORTS_ENCRYPTION) +#define FS_IS_WINDOWS_FAT TEST_GVI(flags () & ~FAT_IGNORE, WIN_FAT_FLAGS) if ((flags () & FILE_SUPPORTS_OBJECT_IDS) && NT_SUCCESS (NtQueryVolumeInformationFile (vol, &io, &ffoi, @@ -379,6 +381,8 @@ fs_info::update (PUNICODE_STRING upath, HANDLE in_vol) is_cifs (!FS_IS_WINDOWS_FAT); /* Then check remote filesystems honest about their name. */ if (!got_fs () + /* Microsoft exFAT */ + && !is_exfat (RtlEqualUnicodeString (&fsname, &ro_u_exfat, FALSE)) /* Microsoft NFS needs distinct access methods for metadata. */ && !is_nfs (RtlEqualUnicodeString (&fsname, &ro_u_nfs, FALSE)) /* MVFS == Rational ClearCase remote filesystem. Has a couple of @@ -430,6 +434,7 @@ fs_info::update (PUNICODE_STRING upath, HANDLE in_vol) if (!got_fs () && !is_ntfs (RtlEqualUnicodeString (&fsname, &ro_u_ntfs, FALSE)) && !is_fat (RtlEqualUnicodePathPrefix (&fsname, &ro_u_fat, TRUE)) + && !is_exfat (RtlEqualUnicodeString (&fsname, &ro_u_exfat, FALSE)) && !is_refs (RtlEqualUnicodeString (&fsname, &ro_u_refs, FALSE)) && !is_csc_cache (RtlEqualUnicodeString (&fsname, &ro_u_csc, FALSE)) && is_cdrom (ffdi.DeviceType == FILE_DEVICE_CD_ROM)) @@ -1553,6 +1558,7 @@ mount_info::del_item (const char *path, unsigned flags) fs_names_t fs_names[] = { { "none", false }, { "vfat", true }, + { "exfat", true }, { "ntfs", true }, { "refs", true }, { "smbfs", false }, diff --git a/winsup/cygwin/mount.h b/winsup/cygwin/mount.h index 0b392ca85..86e1b19c1 100644 --- a/winsup/cygwin/mount.h +++ b/winsup/cygwin/mount.h @@ -31,6 +31,7 @@ enum fs_info_type { none = 0, fat, + exfat, ntfs, refs, samba, @@ -100,6 +101,7 @@ class fs_info IMPLEMENT_STATUS_FLAG (bool, has_buggy_basic_info) IMPLEMENT_STATUS_FLAG (bool, has_dos_filenames_only) IMPLEMENT_FS_FLAG (fat) + IMPLEMENT_FS_FLAG (exfat) IMPLEMENT_FS_FLAG (ntfs) IMPLEMENT_FS_FLAG (refs) IMPLEMENT_FS_FLAG (samba) diff --git a/winsup/cygwin/path.h b/winsup/cygwin/path.h index 69954d8a5..309247d5f 100644 --- a/winsup/cygwin/path.h +++ b/winsup/cygwin/path.h @@ -369,6 +369,8 @@ class path_conv DWORD fs_name_len () const {return fs.name_len ();} bool fs_got_fs () const { return fs.got_fs (); } bool fs_is_fat () const {return fs.is_fat ();} + bool fs_is_exfat () const {return fs.is_exfat ();} + bool fs_is_any_fat () const {return fs.is_fat () || fs.is_exfat ();} bool fs_is_ntfs () const {return fs.is_ntfs ();} bool fs_is_refs () const {return fs.is_refs ();} bool fs_is_samba () const {return fs.is_samba ();} From a7f392686b5b2091e8f555ff2a2d63443e1fcb1c Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Sun, 23 Dec 2018 21:36:42 +0100 Subject: [PATCH 030/475] Cygwin: utilize FILE_DISPOSITION_POSIX_SEMANTICS - short-circuit most code in unlink_nt since it's not necessary anymore if FILE_DISPOSITION_POSIX_SEMANTICS is supported. - Immediately remove O_TMPFILE from filesystem after creation. Disable code for now because we have to implement /proc/self/fd opening by handle first, lest linkat fails. Signed-off-by: Corinna Vinschen --- winsup/cygwin/syscalls.cc | 79 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 76 insertions(+), 3 deletions(-) diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc index 6d1085539..c1a3ed418 100644 --- a/winsup/cygwin/syscalls.cc +++ b/winsup/cygwin/syscalls.cc @@ -658,23 +658,64 @@ unlink_nt (path_conv &pc) HANDLE fh, fh_ro = NULL; OBJECT_ATTRIBUTES attr; IO_STATUS_BLOCK io; + ACCESS_MASK access = DELETE; + ULONG flags = FILE_OPEN_FOR_BACKUP_INTENT; HANDLE old_trans = NULL, trans = NULL; ULONG num_links = 1; FILE_DISPOSITION_INFORMATION disp = { TRUE }; int reopened = 0; - bin_status bin_stat = dont_move; syscall_printf ("Trying to delete %S, isdir = %d", pc.get_nt_native_path (), pc.isdir ()); - ACCESS_MASK access = DELETE; - ULONG flags = FILE_OPEN_FOR_BACKUP_INTENT; + /* Add the reparse point flag to known reparse points, otherwise we remove the target, not the reparse point. */ if (pc.is_known_reparse_point ()) flags |= FILE_OPEN_REPARSE_POINT; pc.get_object_attr (attr, sec_none_nih); + + /* First check if we can use POSIX unlink semantics: W10 1709++, local NTFS. + With POSIX unlink semantics the entire job gets MUCH easier and faster. + Just try to do it and if it fails, it fails. */ + if (wincap.has_posix_file_info () && !pc.isremote () && pc.fs_is_ntfs ()) + { + FILE_DISPOSITION_INFORMATION_EX fdie; + + if (pc.file_attributes () & FILE_ATTRIBUTE_READONLY) + access |= FILE_WRITE_ATTRIBUTES; + status = NtOpenFile (&fh, access, &attr, &io, FILE_SHARE_VALID_FLAGS, + flags); + if (!NT_SUCCESS (status)) + goto out; + /* Why didn't the devs add a FILE_DELETE_IGNORE_READONLY_ATTRIBUTE + flag just like they did with FILE_LINK_IGNORE_READONLY_ATTRIBUTE + and FILE_LINK_IGNORE_READONLY_ATTRIBUTE??? + + POSIX unlink semantics are nice, but they still fail if the file + has the R/O attribute set. Removing the file is very much a safe + bet afterwards, so, no transaction. */ + if (pc.file_attributes () & FILE_ATTRIBUTE_READONLY) + { + status = NtSetAttributesFile (fh, pc.file_attributes () + & ~FILE_ATTRIBUTE_READONLY); + if (!NT_SUCCESS (status)) + { + NtClose (fh); + goto out; + } + } + fdie.Flags = FILE_DISPOSITION_DELETE | FILE_DISPOSITION_POSIX_SEMANTICS; + status = NtSetInformationFile (fh, &io, &fdie, sizeof fdie, + FileDispositionInformationEx); + /* Restore R/O attribute in case we have multiple hardlinks. */ + if (pc.file_attributes () & FILE_ATTRIBUTE_READONLY) + NtSetAttributesFile (fh, pc.file_attributes ()); + NtClose (fh); + goto out; + } + /* If the R/O attribute is set, we have to open the file with FILE_WRITE_ATTRIBUTES to be able to remove this flags before trying to delete it. We do this separately because there are filesystems @@ -1426,7 +1467,39 @@ open (const char *unix_path, int flags, ...) if ((fh->is_fs_special () && fh->device_access_denied (flags)) || !fh->open_with_arch (flags, mode & 07777)) __leave; /* errno already set */ +#if 0 + /* W10 1709 POSIX unlink semantics: + TODO: Works nicely for O_TEMPFILE but using linkat requires that + we first fix /proc/self/fd handling to allow opening by handle + rather than by symlinked filename only. */ + if ((flags & O_TMPFILE) && wincap.has_posix_file_info () + && fh->pc.fs_is_ntfs ()) + { + HANDLE del_h; + OBJECT_ATTRIBUTES attr; + NTSTATUS status; + IO_STATUS_BLOCK io; + FILE_DISPOSITION_INFORMATION_EX fdie; + + status = NtOpenFile (&del_h, DELETE, + fh->pc.init_reopen_attr (attr, fh->get_handle ()), &io, + FILE_SHARE_VALID_FLAGS, FILE_OPEN_FOR_BACKUP_INTENT); + if (!NT_SUCCESS (status)) + debug_printf ("reopening tmpfile handle failed, status %y", status); + else + { + fdie.Flags = FILE_DISPOSITION_DELETE + | FILE_DISPOSITION_POSIX_SEMANTICS; + status = NtSetInformationFile (del_h, &io, &fdie, sizeof fdie, + FileDispositionInformationEx); + if (!NT_SUCCESS (status)) + debug_printf ("Setting POSIX delete disposition on tmpfile " + "failed, status = %y", status); + NtClose (del_h); + } + } +#endif fd = fh; if (fd <= 2) set_std_handle (fd); From 866901441b57b4505d8a78aad0caf53bc246ec6e Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Tue, 25 Dec 2018 01:06:34 +0100 Subject: [PATCH 031/475] Cygwin: cygheap: convert installation paths to UNICODE_STRINGS Signed-off-by: Corinna Vinschen --- winsup/cygwin/cygheap.cc | 28 +++++++++++++++------------- winsup/cygwin/cygheap.h | 7 ++++--- winsup/cygwin/environ.cc | 5 +++-- winsup/cygwin/mount.cc | 2 +- winsup/cygwin/uinfo.cc | 13 +++++++------ 5 files changed, 30 insertions(+), 25 deletions(-) diff --git a/winsup/cygwin/cygheap.cc b/winsup/cygwin/cygheap.cc index 87a5eb964..0e9741c7c 100644 --- a/winsup/cygwin/cygheap.cc +++ b/winsup/cygwin/cygheap.cc @@ -139,11 +139,11 @@ init_cygheap::init_installation_root () { ptrdiff_t len = 0; - if (!GetModuleFileNameW (cygwin_hmodule, installation_root, PATH_MAX)) + if (!GetModuleFileNameW (cygwin_hmodule, installation_root_buf, PATH_MAX)) api_fatal ("Can't initialize Cygwin installation root dir.\n" "GetModuleFileNameW(%p, %p, %u), %E", - cygwin_hmodule, installation_root, PATH_MAX); - PWCHAR p = installation_root; + cygwin_hmodule, installation_root_buf, PATH_MAX); + PWCHAR p = installation_root_buf; if (wcsncasecmp (p, L"\\\\", 2)) /* Normal drive letter path */ { len = 4; @@ -170,18 +170,18 @@ init_cygheap::init_installation_root () p = wcschr (p + 1, L'\\'); /* Skip share name */ } } - installation_root[1] = L'?'; + installation_root_buf[1] = L'?'; RtlInitEmptyUnicodeString (&installation_key, installation_key_buf, sizeof installation_key_buf); - RtlInt64ToHexUnicodeString (hash_path_name (0, installation_root), + RtlInt64ToHexUnicodeString (hash_path_name (0, installation_root_buf), &installation_key, FALSE); /* Strip off last path component ("\\cygwin1.dll") */ - PWCHAR w = wcsrchr (installation_root, L'\\'); + PWCHAR w = wcsrchr (installation_root_buf, L'\\'); if (w) { *w = L'\0'; - w = wcsrchr (installation_root, L'\\'); + w = wcsrchr (installation_root_buf, L'\\'); } if (!w) api_fatal ("Can't initialize Cygwin installation root dir.\n" @@ -190,15 +190,14 @@ init_cygheap::init_installation_root () /* Copy result into installation_dir before stripping off "bin" dir and revert to Win32 path. This path is added to the Windows environment in build_env. See there for a description. */ - installation_dir_len = wcpncpy (installation_dir, installation_root + len, - PATH_MAX) - - installation_dir; + wcpncpy (installation_dir_buf, installation_root_buf + len, PATH_MAX); + if (len == 4) /* Local path */ ; else if (len == 6) /* UNC path */ - installation_dir[0] = L'\\'; + installation_dir_buf[0] = L'\\'; else /* Long, prefixed path */ - installation_dir[1] = L'\\'; + installation_dir_buf[1] = L'\\'; /* If w < p, the Cygwin DLL resides in the root dir of a drive or network path. In that case, if we strip off yet another backslash, the path @@ -208,12 +207,15 @@ init_cygheap::init_installation_root () if (w > p) *w = L'\0'; + RtlInitUnicodeString (&installation_root, installation_root_buf); + RtlInitUnicodeString (&installation_dir, installation_dir_buf); + for (int i = 1; i >= 0; --i) { reg_key r (i, KEY_WRITE, _WIDE (CYGWIN_INFO_INSTALLATIONS_NAME), NULL); if (NT_SUCCESS (r.set_string (installation_key_buf, - installation_root))) + installation_root_buf))) break; } } diff --git a/winsup/cygwin/cygheap.h b/winsup/cygwin/cygheap.h index d8a2e79a4..be088b224 100644 --- a/winsup/cygwin/cygheap.h +++ b/winsup/cygwin/cygheap.h @@ -557,9 +557,10 @@ struct init_cygheap: public mini_cygheap _cmalloc_entry *chain; unsigned bucket_val[NBUCKETS]; char *buckets[NBUCKETS]; - WCHAR installation_root[PATH_MAX]; - WCHAR installation_dir[PATH_MAX]; - size_t installation_dir_len; + UNICODE_STRING installation_root; + WCHAR installation_root_buf[PATH_MAX]; + UNICODE_STRING installation_dir; + WCHAR installation_dir_buf[PATH_MAX]; UNICODE_STRING installation_key; WCHAR installation_key_buf[18]; cygheap_root root; diff --git a/winsup/cygwin/environ.cc b/winsup/cygwin/environ.cc index 67ead1dde..495c340a4 100644 --- a/winsup/cygwin/environ.cc +++ b/winsup/cygwin/environ.cc @@ -1282,10 +1282,11 @@ build_env (const char * const *envp, PWCHAR &envblock, int &envc, during execve. */ if (!saw_PATH) { - new_tl += cygheap->installation_dir_len + 5; + new_tl += cygheap->installation_dir.Length / sizeof (WCHAR) + 5; if (new_tl > tl) tl = raise_envblock (new_tl, envblock, s); - s = wcpcpy (wcpcpy (s, L"PATH="), cygheap->installation_dir) + 1; + s = wcpcpy (wcpcpy (s, L"PATH="), + cygheap->installation_dir.Buffer) + 1; } *s = L'\0'; /* Two null bytes at the end */ assert ((s - envblock) <= tl); /* Detect if we somehow ran over end diff --git a/winsup/cygwin/mount.cc b/winsup/cygwin/mount.cc index 9fd98541d..1844dd8d0 100644 --- a/winsup/cygwin/mount.cc +++ b/winsup/cygwin/mount.cc @@ -492,7 +492,7 @@ mount_info::init (bool user_init) PWCHAR pathend; WCHAR path[PATH_MAX]; - pathend = wcpcpy (path, cygheap->installation_root); + pathend = wcpcpy (path, cygheap->installation_root.Buffer); if (!user_init) create_root_entry (path); diff --git a/winsup/cygwin/uinfo.cc b/winsup/cygwin/uinfo.cc index c2f4803ce..8dcf731de 100644 --- a/winsup/cygwin/uinfo.cc +++ b/winsup/cygwin/uinfo.cc @@ -1305,11 +1305,11 @@ cygheap_pwdgrp::_nss_init () char *buf = tp.c_get (); PCWSTR rel_path = L"\\etc\\nsswitch.conf"; - path.Length = (wcslen (cygheap->installation_root) + wcslen (rel_path)) - * sizeof (WCHAR); + path.Length = cygheap->installation_root.Length + + wcslen (rel_path) * sizeof (WCHAR); path.MaximumLength = path.Length + sizeof (WCHAR); path.Buffer = (PWCHAR) alloca (path.MaximumLength); - wcpcpy (wcpcpy (path.Buffer, cygheap->installation_root), rel_path); + wcpcpy (wcpcpy (path.Buffer, cygheap->installation_root.Buffer), rel_path); InitializeObjectAttributes (&attr, &path, OBJ_CASE_INSENSITIVE, NULL, NULL); if (rl.init (&attr, buf, NT_MAX_PATH)) @@ -1665,11 +1665,12 @@ pwdgrp::check_file () if (!path.Buffer) { PCWSTR rel_path = is_group () ? L"\\etc\\group" : L"\\etc\\passwd"; - path.Length = (wcslen (cygheap->installation_root) + wcslen (rel_path)) - * sizeof (WCHAR); + path.Length = cygheap->installation_root.Length + + wcslen (rel_path) * sizeof (WCHAR); path.MaximumLength = path.Length + sizeof (WCHAR); path.Buffer = (PWCHAR) cmalloc_abort (HEAP_BUF, path.MaximumLength); - wcpcpy (wcpcpy (path.Buffer, cygheap->installation_root), rel_path); + wcpcpy (wcpcpy (path.Buffer, cygheap->installation_root.Buffer), + rel_path); InitializeObjectAttributes (&attr, &path, OBJ_CASE_INSENSITIVE, NULL, NULL); } From 92edcf929ae862a97bb0b8d0494c84b4e1b748b9 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Tue, 25 Dec 2018 01:07:39 +0100 Subject: [PATCH 032/475] Cygwin: wincap: add wincap_10_1803, add has_case_sensitive_dirs item - Allow to disable the flag by calling disable_case_sensitive_dirs. Signed-off-by: Corinna Vinschen --- winsup/cygwin/wincap.cc | 33 ++++++++++++++++++++++++++++++++- winsup/cygwin/wincap.h | 6 ++++++ 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/winsup/cygwin/wincap.cc b/winsup/cygwin/wincap.cc index 4ba9aa51d..d9aea8ac4 100644 --- a/winsup/cygwin/wincap.cc +++ b/winsup/cygwin/wincap.cc @@ -36,6 +36,7 @@ wincaps wincap_vista __attribute__((section (".cygwin_dll_common"), shared)) = { has_unbiased_interrupt_time:false, has_precise_interrupt_time:false, has_posix_file_info:false, + has_case_sensitive_dirs:false, }, }; @@ -57,6 +58,7 @@ wincaps wincap_7 __attribute__((section (".cygwin_dll_common"), shared)) = { has_unbiased_interrupt_time:true, has_precise_interrupt_time:false, has_posix_file_info:false, + has_case_sensitive_dirs:false, }, }; @@ -78,6 +80,7 @@ wincaps wincap_8 __attribute__((section (".cygwin_dll_common"), shared)) = { has_unbiased_interrupt_time:true, has_precise_interrupt_time:false, has_posix_file_info:false, + has_case_sensitive_dirs:false, }, }; @@ -99,6 +102,7 @@ wincaps wincap_10_1507 __attribute__((section (".cygwin_dll_common"), shared)) has_unbiased_interrupt_time:true, has_precise_interrupt_time:true, has_posix_file_info:false, + has_case_sensitive_dirs:false, }, }; @@ -120,6 +124,7 @@ wincaps wincap_10_1511 __attribute__((section (".cygwin_dll_common"), shared)) = has_unbiased_interrupt_time:true, has_precise_interrupt_time:true, has_posix_file_info:false, + has_case_sensitive_dirs:false, }, }; @@ -141,6 +146,7 @@ wincaps wincap_10_1703 __attribute__((section (".cygwin_dll_common"), shared)) = has_unbiased_interrupt_time:true, has_precise_interrupt_time:true, has_posix_file_info:false, + has_case_sensitive_dirs:false, }, }; @@ -162,6 +168,29 @@ wincaps wincap_10_1709 __attribute__((section (".cygwin_dll_common"), shared)) = has_unbiased_interrupt_time:true, has_precise_interrupt_time:true, has_posix_file_info:true, + has_case_sensitive_dirs:false, + }, +}; + +wincaps wincap_10_1803 __attribute__((section (".cygwin_dll_common"), shared)) = { + def_guard_pages:2, + { + is_server:false, + needs_count_in_si_lpres2:false, + has_gaa_largeaddress_bug:false, + has_broken_alloc_console:true, + has_console_logon_sid:true, + has_precise_system_time:true, + has_microsoft_accounts:true, + has_processor_groups:true, + has_broken_prefetchvm:false, + has_new_pebteb_region:true, + has_broken_whoami:false, + has_unprivileged_createsymlink:true, + has_unbiased_interrupt_time:true, + has_precise_interrupt_time:true, + has_posix_file_info:true, + has_case_sensitive_dirs:true, }, }; @@ -205,7 +234,9 @@ wincapc::init () break; case 10: default: - if (likely (version.dwBuildNumber >= 16299)) + if (likely (version.dwBuildNumber >= 17134)) + caps = &wincap_10_1803; + else if (version.dwBuildNumber >= 16299) caps = &wincap_10_1709; else if (version.dwBuildNumber >= 15063) caps = &wincap_10_1703; diff --git a/winsup/cygwin/wincap.h b/winsup/cygwin/wincap.h index 649246299..967ddbdfe 100644 --- a/winsup/cygwin/wincap.h +++ b/winsup/cygwin/wincap.h @@ -30,6 +30,7 @@ struct wincaps unsigned has_unbiased_interrupt_time : 1; unsigned has_precise_interrupt_time : 1; unsigned has_posix_file_info : 1; + unsigned has_case_sensitive_dirs : 1; }; }; @@ -80,7 +81,12 @@ public: bool IMPLEMENT (has_unbiased_interrupt_time) bool IMPLEMENT (has_precise_interrupt_time) bool IMPLEMENT (has_posix_file_info) + bool IMPLEMENT (has_case_sensitive_dirs) + void disable_case_sensitive_dirs () + { + ((wincaps *)caps)->has_case_sensitive_dirs = false; + } #undef IMPLEMENT }; From 4021509ba28e7ce6cec63ed15bc904805b566bbc Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Tue, 25 Dec 2018 01:09:12 +0100 Subject: [PATCH 033/475] Cygwin: mkdir: create case-sensitive dirs On Windows 10 1803 and later, create dirs under the Cygwin installation dir as case sensitive, if WSL is installed. Signed-off-by: Corinna Vinschen --- winsup/cygwin/fhandler_disk_file.cc | 34 +++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/winsup/cygwin/fhandler_disk_file.cc b/winsup/cygwin/fhandler_disk_file.cc index b58b8442a..a8b7af44b 100644 --- a/winsup/cygwin/fhandler_disk_file.cc +++ b/winsup/cygwin/fhandler_disk_file.cc @@ -1760,6 +1760,10 @@ fhandler_disk_file::mkdir (mode_t mode) I don't know what setting that is or how to recognize such a share, so for now we don't request WRITE_DAC on remote drives. */ access |= READ_CONTROL | WRITE_DAC; + /* Setting case sensitivity requires FILE_WRITE_ATTRIBUTES. */ + if (wincap.has_case_sensitive_dirs () + && !pc.isremote () && pc.fs_is_ntfs ()) + access |= FILE_WRITE_ATTRIBUTES; status = NtCreateFile (&dir, access, pc.get_object_attr (attr, sa), &io, NULL, FILE_ATTRIBUTE_DIRECTORY, FILE_SHARE_VALID_FLAGS, FILE_CREATE, @@ -1773,6 +1777,36 @@ fhandler_disk_file::mkdir (mode_t mode) pc.file_attributes (FILE_ATTRIBUTE_DIRECTORY); if (has_acls ()) set_created_file_access (dir, pc, mode & 07777); + /* Starting with Windows 10 1803, try to create all dirs below the + installation root as case-sensitive. If STATUS_NOT_SUPPORTED + is returned, WSL isn't installed (unfortunately a requirement + for this functionality. */ + if (wincap.has_case_sensitive_dirs () + && !pc.isremote () && pc.fs_is_ntfs ()) + { + PUNICODE_STRING new_dir = pc.get_nt_native_path (); + PUNICODE_STRING root_dir = &cygheap->installation_root; + + if (RtlEqualUnicodePathPrefix (new_dir, root_dir, TRUE) + && new_dir->Buffer[root_dir->Length / sizeof (WCHAR)] == L'\\') + { + FILE_CASE_SENSITIVE_INFORMATION fcsi; + + fcsi.Flags = FILE_CS_FLAG_CASE_SENSITIVE_DIR; + status = NtSetInformationFile (dir, &io, &fcsi, sizeof fcsi, + FileCaseSensitiveInformation); + if (!NT_SUCCESS (status)) + { + debug_printf ("Setting dir case sensitivity, status %y", + status); + if (status == STATUS_NOT_SUPPORTED) + { + debug_printf ("Dir case sensitivity requires WSL"); + wincap.disable_case_sensitive_dirs (); + } + } + } + } NtClose (dir); res = 0; } From af4a65a26d703cf150cd6d75336c19543aa014d8 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Tue, 25 Dec 2018 23:38:52 +0100 Subject: [PATCH 034/475] Cygwin: Add FS_IOC_GETFLAGS and FS_IOC_SETFLAGS ioctls Signed-off-by: Corinna Vinschen --- winsup/cygwin/autoload.cc | 2 + winsup/cygwin/fhandler.h | 3 + winsup/cygwin/fhandler_disk_file.cc | 247 ++++++++++++++++++++++++++++ winsup/cygwin/include/cygwin/fs.h | 27 +++ 4 files changed, 279 insertions(+) diff --git a/winsup/cygwin/autoload.cc b/winsup/cygwin/autoload.cc index 5a0e400aa..7978287cb 100644 --- a/winsup/cygwin/autoload.cc +++ b/winsup/cygwin/autoload.cc @@ -534,6 +534,8 @@ LoadDLLprime (ws2_32, _wsock_init, 0) LoadDLLfunc (CheckTokenMembership, 12, advapi32) LoadDLLfunc (CreateProcessAsUserW, 44, advapi32) LoadDLLfunc (DeregisterEventSource, 4, advapi32) +LoadDLLfunc (DecryptFileW, 8, advapi32) +LoadDLLfunc (EncryptFileW, 4, advapi32) LoadDLLfunc (LogonUserW, 24, advapi32) LoadDLLfunc (LookupAccountNameW, 28, advapi32) LoadDLLfunc (LookupAccountSidW, 28, advapi32) diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h index 9e63867ab..07e8a1834 100644 --- a/winsup/cygwin/fhandler.h +++ b/winsup/cygwin/fhandler.h @@ -1437,6 +1437,8 @@ class fhandler_disk_file: public fhandler_base int __reg3 readdir_helper (DIR *, dirent *, DWORD, DWORD, PUNICODE_STRING fname); int prw_open (bool, void *); + uint64_t fs_ioc_getflags (); + int fs_ioc_setflags (uint64_t); public: fhandler_disk_file (); @@ -1462,6 +1464,7 @@ class fhandler_disk_file: public fhandler_base int __reg2 link (const char *); int __reg2 utimens (const struct timespec *); int __reg2 fstatvfs (struct statvfs *buf); + int ioctl (unsigned int cmd, void *buf); HANDLE mmap (caddr_t *addr, size_t len, int prot, int flags, off_t off); int munmap (HANDLE h, caddr_t addr, size_t len); diff --git a/winsup/cygwin/fhandler_disk_file.cc b/winsup/cygwin/fhandler_disk_file.cc index a8b7af44b..e0a196fae 100644 --- a/winsup/cygwin/fhandler_disk_file.cc +++ b/winsup/cygwin/fhandler_disk_file.cc @@ -25,6 +25,7 @@ details. */ #include "devices.h" #include "ldap.h" #include +#include #define _COMPILING_NEWLIB #include @@ -2437,6 +2438,252 @@ fhandler_disk_file::closedir (DIR *dir) return res; } +uint64_t +fhandler_disk_file::fs_ioc_getflags () +{ + NTSTATUS status; + IO_STATUS_BLOCK io; + FILE_BASIC_INFORMATION fbi; + FILE_CASE_SENSITIVE_INFORMATION fcsi; + uint64_t flags = 0; + + status = NtQueryInformationFile (get_handle (), &io, &fbi, sizeof fbi, + FileBasicInformation); + if (NT_SUCCESS (status)) + { + flags = (uint64_t) fbi.FileAttributes & FS_FL_USER_VISIBLE; + pc.file_attributes (fbi.FileAttributes); + } + else + flags = (uint64_t) pc.file_attributes () & FS_FL_USER_VISIBLE; + if (pc.isdir () && wincap.has_case_sensitive_dirs () + && !pc.isremote () && pc.fs_is_ntfs ()) + { + fcsi.Flags = 0; + status = NtQueryInformationFile (get_handle (), &io, + &fcsi, sizeof fcsi, + FileCaseSensitiveInformation); + if (NT_SUCCESS (status) + && (fcsi.Flags & FILE_CS_FLAG_CASE_SENSITIVE_DIR)) + flags |= FS_CASESENS_FL; + } + return flags; +} + +/* Settable DOS attributes */ +#define FS_FL_SETATTRIBS (FS_READONLY_FL \ + | FS_HIDDEN_FL \ + | FS_SYSTEM_FL \ + | FS_ARCHIVE_FL \ + | FS_TEMP_FL \ + | FS_NOTINDEXED_FL) + +int +fhandler_disk_file::fs_ioc_setflags (uint64_t flags) +{ + int ret = -1; + uint64_t old_flags; + HANDLE fh; + NTSTATUS status; + OBJECT_ATTRIBUTES attr; + IO_STATUS_BLOCK io; + FILE_BASIC_INFORMATION fbi; + FILE_SET_SPARSE_BUFFER fssb; + USHORT comp; + FILE_CASE_SENSITIVE_INFORMATION fcsi; + + if ((get_access () & (GENERIC_WRITE | FILE_WRITE_ATTRIBUTES)) != 0) + fh = get_handle (); + else + { + status = NtOpenFile (&fh, FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES, + pc.init_reopen_attr (attr, get_handle ()), &io, + FILE_SHARE_VALID_FLAGS, + FILE_OPEN_FOR_BACKUP_INTENT); + if (!NT_SUCCESS (status)) + { + fh = get_handle (); + __seterrno_from_nt_status (status); + goto out; + } + } + old_flags = fs_ioc_getflags (); + if ((old_flags & FS_FL_SETATTRIBS) != (flags & FS_FL_SETATTRIBS)) + { + fbi.CreationTime.QuadPart + = fbi.LastAccessTime.QuadPart + = fbi.LastWriteTime.QuadPart + = fbi.ChangeTime.QuadPart = 0LL; + fbi.FileAttributes = (ULONG) old_flags; + fbi.FileAttributes &= ~FS_FL_SETATTRIBS; + fbi.FileAttributes |= (flags & FS_FL_SETATTRIBS); + if (fbi.FileAttributes == 0) + fbi.FileAttributes = FILE_ATTRIBUTE_NORMAL; + status = NtSetInformationFile (fh, &io, &fbi, sizeof fbi, + FileBasicInformation); + if (!NT_SUCCESS (status)) + { + __seterrno_from_nt_status (status); + goto out; + } + } + if (!pc.isdir() && (flags & FS_SPARSE_FL) != (old_flags & FS_SPARSE_FL)) + { + fssb.SetSparse = (flags & FS_SPARSE_FL) ? TRUE : FALSE; + status = NtFsControlFile (fh, NULL, NULL, NULL, &io, + FSCTL_SET_SPARSE, &fssb, sizeof fssb, NULL, 0); + if (!NT_SUCCESS (status)) + { + __seterrno_from_nt_status (status); + goto out; + } + } + if (pc.isdir () && (flags & FS_CASESENS_FL) != (old_flags & FS_CASESENS_FL)) + { + if (wincap.has_case_sensitive_dirs () + && !pc.isremote () && pc.fs_is_ntfs ()) + { + fcsi.Flags = (flags & FS_CASESENS_FL) + ? FILE_CS_FLAG_CASE_SENSITIVE_DIR : 0; + status = NtSetInformationFile (fh, &io, &fcsi, sizeof fcsi, + FileCaseSensitiveInformation); + if (!NT_SUCCESS (status)) + { + /* Special case: The directory contains files which only + differ in case. NtSetInformationFile refuses to change + back to case insensitivity and returns status 0xc00004b3. + There's no STATUS_xyz macro assigned to that value yet, + nor does it map to a useful Win32 error value. */ + if (status == (NTSTATUS) 0xc00004b3) + set_errno (EINVAL); /* Does that make sense? */ + else + __seterrno_from_nt_status (status); + goto out; + } + } + else + { + set_errno (ENOTSUP); + goto out; + } + } + if ((flags & FS_COMPRESSED_FL) != (old_flags & FS_COMPRESSED_FL)) + { + if (fh != get_handle ()) + NtClose (fh); + fh = NULL; + if ((get_access () & (GENERIC_WRITE | GENERIC_READ)) + != (GENERIC_WRITE | GENERIC_READ)) + { + status = NtOpenFile (&fh, GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE, + pc.init_reopen_attr (attr, get_handle ()), &io, + FILE_SHARE_VALID_FLAGS, + FILE_SYNCHRONOUS_IO_NONALERT + | FILE_OPEN_FOR_BACKUP_INTENT); + if (!NT_SUCCESS (status)) + { + fh = get_handle (); + __seterrno_from_nt_status (status); + goto out; + } + } + comp = (flags & FS_COMPRESSED_FL) + ? COMPRESSION_FORMAT_DEFAULT : COMPRESSION_FORMAT_NONE; + status = NtFsControlFile (fh, NULL, NULL, NULL, &io, + FSCTL_SET_COMPRESSION, &comp, sizeof comp, + NULL, 0); + if (!NT_SUCCESS (status)) + { + __seterrno_from_nt_status (status); + goto out; + } + } + if (!pc.isdir() && (flags & FS_ENCRYPT_FL) != (old_flags & FS_ENCRYPT_FL)) + { + tmp_pathbuf tp; + PWCHAR path = tp.w_get (); + BOOL cret; + + /* EncryptFileW/DecryptFileW needs exclusive access. */ + if (fh != get_handle ()) + NtClose (fh); + NtClose (get_handle ()); + set_io_handle (NULL); + + pc.get_wide_win32_path (path); + cret = (flags & FS_ENCRYPT_FL) + ? EncryptFileW (path) : DecryptFileW (path, 0); + status = NtOpenFile (&fh, get_access (), + pc.get_object_attr (attr, sec_none_nih), &io, + FILE_SHARE_VALID_FLAGS, + FILE_SYNCHRONOUS_IO_NONALERT + | FILE_OPEN_FOR_BACKUP_INTENT); + if (!NT_SUCCESS (status)) + { + __seterrno_from_nt_status (status); + return -1; + } + set_io_handle (fh); + if (!cret) + { + __seterrno (); + goto out; + } + } + ret = 0; +out: + status = NtQueryInformationFile (fh, &io, &fbi, sizeof fbi, + FileBasicInformation); + if (NT_SUCCESS (status)) + pc.file_attributes (fbi.FileAttributes); + if (fh != get_handle ()) + NtClose (fh); + return ret; +} + +int +fhandler_disk_file::ioctl (unsigned int cmd, void *p) +{ + int ret = -1; + uint64_t flags = 0; + + switch (cmd) + { + case FS_IOC_GETFLAGS: + __try + { + uint64_t *fp = (uint64_t *) p; + *fp = fs_ioc_getflags (); + ret = 0; + } + __except (EFAULT) {} + __endtry + break; + case FS_IOC_SETFLAGS: + __try + { + flags = *(__uint64_t *) p; + } + __except (EFAULT) + { + break; + } + __endtry + if (flags & ~FS_FL_USER_MODIFIABLE) + { + set_errno (EINVAL); + break; + } + ret = fs_ioc_setflags (flags); + break; + default: + ret = fhandler_base::ioctl (cmd, p); + break; + } + syscall_printf ("%d = ioctl_file(%x, %p)", ret, cmd, p); + return ret; +} + fhandler_cygdrive::fhandler_cygdrive () : fhandler_disk_file () { diff --git a/winsup/cygwin/include/cygwin/fs.h b/winsup/cygwin/include/cygwin/fs.h index 48b0cca45..9b4baf302 100644 --- a/winsup/cygwin/include/cygwin/fs.h +++ b/winsup/cygwin/include/cygwin/fs.h @@ -10,6 +10,8 @@ details. */ #ifndef _CYGWIN_FS_H_ #define _CYGWIN_FS_H_ +#include + #define BLKRRPART 0x0000125f #define BLKGETSIZE 0x00001260 #define BLKSSZGET 0x00001268 @@ -19,6 +21,31 @@ details. */ #define BLKPBSZGET 0x0000127b #define BLKGETSIZE64 0x00041268 +/* Get/Set file attributes */ +#define FS_IOC_GETFLAGS _IOR('f', 1, __uint64_t) +#define FS_IOC_SETFLAGS _IOW('f', 2, __uint64_t) + +/* Inode flags (FS_IOC_GETFLAGS / FS_IOC_SETFLAGS) + + This is loosely following the Linux inode flags. Basically it's just + a convenient way to handle certain aspects of files on Windows which + are not covered by POSIX calls, mostly connected to DOS attributes. */ +#define FS_READONLY_FL 0x000000001ULL /* DOS R/O */ +#define FS_HIDDEN_FL 0x000000002ULL /* DOS Hidden */ +#define FS_SYSTEM_FL 0x000000004ULL /* DOS System */ +#define FS_ARCHIVE_FL 0x000000020ULL /* DOS Archive */ +#define FS_TEMP_FL 0x000000100ULL /* DOS Temporary */ +#define FS_SPARSE_FL 0x000000200ULL /* Sparse file */ +#define FS_REPARSE_FL 0x000000400ULL /* Reparse point */ +#define FS_COMPRESSED_FL 0x000000800ULL /* Compressed file */ +#define FS_OFFLINE_FL 0x000001000ULL /* DOS Offline */ +#define FS_NOTINDEXED_FL 0x000002000ULL /* DOS Not context indexed */ +#define FS_ENCRYPT_FL 0x000004000ULL /* Encrypted file */ +#define FS_CASESENS_FL 0x100000000ULL /* Case sensitive dir */ + +#define FS_FL_USER_VISIBLE 0x100007f27ULL /* User visible flags */ +#define FS_FL_USER_MODIFIABLE 0x100006b27ULL /* User modifiable flags */ + /* Flags for renameat2, from /usr/include/linux/fs.h. For now we support only RENAME_NOREPLACE. */ #define RENAME_NOREPLACE (1 << 0) From 0d4b39d37b966eccc27ff383f6453797f576859d Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Tue, 25 Dec 2018 23:39:11 +0100 Subject: [PATCH 035/475] Cygwin: Add lsattr and chattr tools Signed-off-by: Corinna Vinschen --- winsup/utils/Makefile.in | 2 +- winsup/utils/chattr.c | 362 +++++++++++++++++++++++++++++++++++++++ winsup/utils/lsattr.c | 289 +++++++++++++++++++++++++++++++ 3 files changed, 652 insertions(+), 1 deletion(-) create mode 100644 winsup/utils/chattr.c create mode 100644 winsup/utils/lsattr.c diff --git a/winsup/utils/Makefile.in b/winsup/utils/Makefile.in index be525d07f..b64f457e7 100644 --- a/winsup/utils/Makefile.in +++ b/winsup/utils/Makefile.in @@ -54,7 +54,7 @@ MINGW_CXX := @MINGW_CXX@ # List all binaries to be linked in Cygwin mode. Each binary on this list # must have a corresponding .o of the same name. -CYGWIN_BINS := ${addsuffix .exe,cygpath gencat getconf getfacl ldd locale kill minidumper mkgroup \ +CYGWIN_BINS := ${addsuffix .exe,chattr cygpath gencat getconf getfacl ldd locale lsattr kill minidumper mkgroup \ mkpasswd mount passwd pldd ps regtool setfacl setmetamode ssp tzset umount} # List all binaries to be linked in MinGW mode. Each binary on this list diff --git a/winsup/utils/chattr.c b/winsup/utils/chattr.c new file mode 100644 index 000000000..c21d4b7a5 --- /dev/null +++ b/winsup/utils/chattr.c @@ -0,0 +1,362 @@ +/* chattr.c + + Written by Corinna Vinschen + +This file is part of Cygwin. + +This software is a copyrighted work licensed under the terms of the +Cygwin license. Please consult the file "CYGWIN_LICENSE" for +details. */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +int Ropt, Vopt, fopt; +uint64_t add, del, set; + +struct option longopts[] = { + { "recursive", no_argument, NULL, 'R' }, + { "verbose", no_argument, NULL, 'V' }, + { "force", no_argument, NULL, 'f' }, + { "help", no_argument, NULL, 'h' }, + { "version", no_argument, NULL, 'v' }, + { NULL, no_argument, NULL, 0} +}; + +const char *opts = "+RVfhv"; + +struct +{ + uint64_t flagval; + char chr; + const char *str; +} supp_flag[] = { + { FS_READONLY_FL, 'r', "Readonly" }, + { FS_HIDDEN_FL, 'h', "Hidden" }, + { FS_SYSTEM_FL, 's', "System" }, + { FS_ARCHIVE_FL, 'a', "Archive" }, + { FS_TEMP_FL, 't', "Temporary" }, + { FS_SPARSE_FL, 'S', "Sparse" }, + { FS_REPARSE_FL, 'r', NULL }, + { FS_COMPRESSED_FL, 'c', "Compressed" }, + { FS_OFFLINE_FL, 'o', NULL }, + { FS_NOTINDEXED_FL, 'n', "Notindexed" }, + { FS_ENCRYPT_FL, 'e', "Encrypted" }, + { FS_CASESENS_FL, 'C', "Casesensitive" }, + { 0, '\0', NULL }, +}; +const char *supp_list = "rhsatSrconeC"; + +void +print_flags (uint64_t flags) +{ + int i; + + for (i = 0; supp_flag[i].flagval; ++i) + fputc ((flags & supp_flag[i].flagval) ? supp_flag[i].chr : '-', stdout); +} + +int +get_flags (const char *opt) +{ + const char *p = opt, *sl; + uint64_t *mode; + ptrdiff_t idx; + + switch (*p) + { + case '+': + mode = &add; + break; + case '-': + mode = &del; + break; + case '=': + mode = &set; + break; + default: + return 1; + } + while (*++p) + { + sl = strchr (supp_list, *p); + if (!sl) + return 1; + idx = sl - supp_list; + if (!supp_flag[idx].str) + return 1; + *mode |= supp_flag[idx].flagval; + } + return 0; +} + +int +sanity_check () +{ + int ret = -1; + if (!set && !add && !del) + fprintf (stderr, "%s: Must use at least one of =, + or -\n", + program_invocation_short_name); + else if (set && (add | del)) + fprintf (stderr, "%s: = is incompatible with + and -\n", + program_invocation_short_name); + else if ((add & del) != 0) + fprintf (stderr, "%s: Can't both set and unset same flag.\n", + program_invocation_short_name); + else + ret = 0; + return ret; +} + +int +chattr (const char *path) +{ + int fd; + uint64_t flags, newflags; + + fd = open (path, O_RDONLY); + if (fd < 0) + { + fprintf (stderr, "%s: %s while trying to open %s\n", + program_invocation_short_name, strerror (errno), path); + return 1; + } + if (ioctl (fd, FS_IOC_GETFLAGS, &flags)) + { + close (fd); + fprintf (stderr, "%s: %s while trying to fetch flags from %s\n", + program_invocation_short_name, strerror (errno), path); + return 1; + } + if (set) + newflags = set; + else + { + newflags = flags; + newflags |= add; + newflags &= ~del; + } + if (newflags != flags) + { + if (Vopt) + { + printf ("Flags of %s set as ", path); + print_flags (newflags); + fputc ('\n', stdout); + } + if (ioctl (fd, FS_IOC_SETFLAGS, &newflags)) + { + close (fd); + fprintf (stderr, "%s: %s while trying to set flags on %s\n", + program_invocation_short_name, strerror (errno), path); + return 1; + } + } + close (fd); + return 0; +} + +int +chattr_dir (const char *path) +{ + DIR *dir; + struct dirent *de; + char *subpath = (char *) malloc (strlen (path) + 1 + NAME_MAX + 1); + char *comp; + + dir = opendir (path); + if (!dir) + { + free (subpath); + return 1; + } + comp = stpcpy (subpath, path); + if (comp[-1] != '/') + *comp++ = '/'; + while ((de = readdir (dir))) + { + struct stat st; + + if (strcmp (de->d_name, ".") == 0 || strcmp (de->d_name, "..") == 0) + continue; + + stpcpy (comp, de->d_name); + if (lstat (subpath, &st) != 0) + fprintf (stderr, "%s: %s while trying to stat %s\n", + program_invocation_short_name, strerror (errno), + subpath); + else + { + if (S_ISREG (st.st_mode) || S_ISDIR (st.st_mode)) + chattr (subpath); + if (S_ISDIR (st.st_mode) && Ropt) + chattr_dir (subpath); + } + } + free (subpath); + return 0; +} + +static void +print_version () +{ + printf ("%s (cygwin) %d.%d.%d\n" + "Get POSIX ACL information\n" + "Copyright (C) 2018 - %s Cygwin Authors\n" + "This is free software; see the source for copying conditions. " + "There is NO\n" + "warranty; not even for MERCHANTABILITY or FITNESS FOR A " + "PARTICULAR PURPOSE.\n", + program_invocation_short_name, + CYGWIN_VERSION_DLL_MAJOR / 1000, + CYGWIN_VERSION_DLL_MAJOR % 1000, + CYGWIN_VERSION_DLL_MINOR, + strrchr (__DATE__, ' ') + 1); +} + +static void +usage (FILE *stream) +{ + fprintf (stream, "Usage: %s [-RVfhv] [+-=mode]... [file]...\n", + program_invocation_short_name); + if (stream == stderr) + fprintf (stream, "Try '%s --help' for more information\n", + program_invocation_short_name); + if (stream == stdout) + fprintf (stream, "\n" + "Change file attributes\n" + "\n" + " -R, --recursive recursively list attributes of directories and their \n" + " contents\n" + " -V, --verbose Be verbose during operation\n" + " -f, --force suppress error messages\n" + " -h, --help this help text\n" + " -v, --version display the program version\n" + "\n" + "The format of 'mode' is {+-=}[acCehnrsSt]\n" + "\n" + "The operator '+' causes the selected attributes to be added to the\n" + "existing attributes of the files; '-' causes them to be removed; and\n" + "'=' causes them to be the only attributes that the files have.\n" + "\n" + "Supported attributes:\n" + "\n" + " 'r', 'Readonly': file is read-only\n" + " 'h', 'Hidden': file or directory is hidden\n" + " 's', 'System': file or directory that the operating system uses\n" + " 'a', 'Archive': file or directory has the archive marker set\n" + " 't', 'Temporary': file is being used for temporary storage\n" + " 'S', 'Sparse': file is sparse\n" + " 'c', 'Compressed': file or directory is compressed\n" + " 'n', 'Notindexed': file or directory is not to be indexed by the\n" + " content indexing service\n" + " 'e', 'Encrypted': file is encrypted\n" + " 'C', 'Casesensitive': directory is handled case sensitive\n" + " (Windows 10 1803 or later, local NTFS only,\n" + " WSL must be installed)\n"); +} + +int +main (int argc, char **argv) +{ + int c, ret = 0; + int lastoptind = 0; + char *opt; + + opterr = 0; + while ((c = getopt_long (argc, argv, opts, longopts, NULL)) != EOF) + { + switch (c) + { + case 'R': + Ropt = 1; + lastoptind = optind; + break; + case 'V': + Vopt = 1; + lastoptind = optind; + break; + case 'f': + fopt = 1; + lastoptind = optind; + break; + case 'v': + print_version (); + return 0; + break; + default: + if (optind > lastoptind) + { + --optind; + goto next; + } + /*FALLTHRU*/ + case 'h': + usage (c == 'h' ? stdout : stderr); + return 1; + } + } +next: + while (optind < argc) + { + if (strcmp (argv[optind], "--") == 0) + { + ++optind; + break; + } + opt = strchr ("+-=", argv[optind][0]); + if (!opt) + break; + if (argv[optind][1] == '\0' || get_flags (argv[optind])) + { + usage (stderr); + return 1; + } + ++optind; + } + if (sanity_check ()) + return 1; + if (optind > argc - 1) + { + chattr ("."); + if (Ropt) + chattr_dir ("."); + } + else for (; optind < argc; ++optind) + { + struct stat st; + + if (lstat (argv[optind], &st) != 0) + { + fprintf (stderr, "%s: %s while trying to stat %s\n", + program_invocation_short_name, strerror (errno), + argv[optind]); + ret = 1; + } + else if (!S_ISREG (st.st_mode) && !S_ISDIR (st.st_mode)) + { + fprintf (stderr, "%s: %s on %s\n", + program_invocation_short_name, strerror (ENOTSUP), + argv[optind]); + ret = 1; + } + else + { + if (chattr (argv[optind])) + ret = 1; + if (S_ISDIR (st.st_mode) && chattr_dir (argv[optind])) + ret = 1; + } + } + return ret; +} diff --git a/winsup/utils/lsattr.c b/winsup/utils/lsattr.c new file mode 100644 index 000000000..ee72043f0 --- /dev/null +++ b/winsup/utils/lsattr.c @@ -0,0 +1,289 @@ +/* lsattr.c + + Written by Corinna Vinschen + +This file is part of Cygwin. + +This software is a copyrighted work licensed under the terms of the +Cygwin license. Please consult the file "CYGWIN_LICENSE" for +details. */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +int Ropt, aopt, dopt, lopt, nopt; + +struct option longopts[] = { + { "recursive", no_argument, NULL, 'R' }, + { "version", no_argument, NULL, 'V' }, + { "all", no_argument, NULL, 'a' }, + { "directory", no_argument, NULL, 'd' }, + { "help", no_argument, NULL, 'h' }, + { "long", no_argument, NULL, 'l' }, + { "no-headers", no_argument, NULL, 'n' }, + { NULL, no_argument, NULL, 0} +}; + +const char *opts = "+RVadhln"; + +struct +{ + uint64_t flagval; + char chr; + const char *str; +} supp_flag[] = { + { FS_READONLY_FL, 'r', "Readonly" }, + { FS_HIDDEN_FL, 'h', "Hidden" }, + { FS_SYSTEM_FL, 's', "System" }, + { FS_ARCHIVE_FL, 'a', "Archive" }, + { FS_TEMP_FL, 't', "Temporary" }, + { FS_SPARSE_FL, 'S', "Sparse" }, + { FS_REPARSE_FL, 'r', "Reparse" }, + { FS_COMPRESSED_FL, 'c', "Compressed" }, + { FS_OFFLINE_FL, 'o', "Offline" }, + { FS_NOTINDEXED_FL, 'n', "Notindexed" }, + { FS_ENCRYPT_FL, 'e', "Encrypted" }, + { FS_CASESENS_FL, 'C', "Casesensitive" }, + { 0, '\0', NULL }, +}; + +void +print_long (const char *path, uint64_t flags) +{ + int i; + int first = 1; + + printf("%-28s ", path); + for (i = 0; supp_flag[i].flagval; ++i) + if (flags & supp_flag[i].flagval) + { + if (!first) + fputs (", ", stdout); + first = 0; + fputs (supp_flag[i].str, stdout); + } + if (first) + fputs ("---", stdout); + fputc ('\n', stdout); +} + +void +print_short (const char *path, uint64_t flags) +{ + int i; + + for (i = 0; supp_flag[i].flagval; ++i) + fputc ((flags & supp_flag[i].flagval) ? supp_flag[i].chr : '-', stdout); + printf(" %s\n", path); +} + +int +lsattr (const char *path) +{ + int fd; + uint64_t flags; + + fd = open (path, O_RDONLY); + if (fd < 0) + { + fprintf (stderr, "%s: %s while trying to open %s\n", + program_invocation_short_name, strerror (errno), + path); + return 1; + } + if (ioctl (fd, FS_IOC_GETFLAGS, &flags)) + { + close (fd); + fprintf (stderr, "%s: %s while trying to fetch flags from %s\n", + program_invocation_short_name, strerror (errno), + path); + return 1; + } + close (fd); + if (lopt) + print_long (path, flags); + else + print_short (path, flags); + return 0; +} + +int +lsattr_dir (const char *path) +{ + DIR *dir; + struct dirent *de; + char *subpath = (char *) malloc (strlen (path) + 1 + NAME_MAX + 1); + char *comp; + + dir = opendir (path); + if (!dir) + { + free (subpath); + return 1; + } + comp = stpcpy (subpath, path); + if (comp[-1] != '/') + *comp++ = '/'; + while ((de = readdir (dir))) + { + struct stat st; + + stpcpy (comp, de->d_name); + if (lstat (subpath, &st) != 0) + fprintf (stderr, "%s: %s while trying to stat %s\n", + program_invocation_short_name, strerror (errno), + subpath); + else if (de->d_name[0] != '.' || aopt) + { + if (S_ISREG (st.st_mode) || S_ISDIR (st.st_mode)) + lsattr (subpath); + if (S_ISDIR (st.st_mode) && Ropt + && strcmp (de->d_name, ".") != 0 + && strcmp (de->d_name, "..") != 0) + { + if (!nopt) + printf ("\n%s:\n", path); + lsattr_dir (subpath); + if (!nopt) + fputc ('\n', stdout); + } + } + } + free (subpath); + return 0; +} + +static void +print_version () +{ + printf ("%s (cygwin) %d.%d.%d\n" + "Get POSIX ACL information\n" + "Copyright (C) 2018 - %s Cygwin Authors\n" + "This is free software; see the source for copying conditions. " + "There is NO\n" + "warranty; not even for MERCHANTABILITY or FITNESS FOR A " + "PARTICULAR PURPOSE.\n", + program_invocation_short_name, + CYGWIN_VERSION_DLL_MAJOR / 1000, + CYGWIN_VERSION_DLL_MAJOR % 1000, + CYGWIN_VERSION_DLL_MINOR, + strrchr (__DATE__, ' ') + 1); +} + +static void +usage (FILE *stream) +{ + fprintf (stream, "Usage: %s [-RVadhln] [file]...\n", + program_invocation_short_name); + if (stream == stderr) + fprintf (stream, "Try '%s --help' for more information\n", + program_invocation_short_name); + if (stream == stdout) + fprintf (stream, "\n" + "List file attributes\n" + "\n" + " -R, --recursive recursively list attributes of directories and their \n" + " contents\n" + " -V, --version display the program version\n" + " -a, --all list all files in directories, including files that\n" + " start with '.'\n" + " -d, --directory list directories like other files, rather than listing\n" + " their contents.\n" + " -l, --long print options using long names instead of single\n" + " character abbreviations\n" + " -n, --no-headers don't print directory headers when recursing\n" + " -h, --help this help text\n" + "\n" + "Supported attributes:\n" + "\n" + " 'r', 'Readonly': file is read-only, directory is system-marked\n" + " 'h', 'Hidden': file or directory is hidden\n" + " 's', 'System': file or directory that the operating system uses\n" + " 'a', 'Archive': file or directory has the archive marker set\n" + " 't', 'Temporary': file is being used for temporary storage\n" + " 'S', 'Sparse': file is sparse\n" + " 'r', 'Reparse': file or directory that has a reparse point\n" + " 'c', 'Compressed': file or directory is compressed\n" + " 'o', 'Offline': the data of a file is moved to offline storage\n" + " 'n', 'Notindexed': file or directory is not to be indexed by the\n" + " content indexing service\n" + " 'e', 'Encrypted': file is encrypted\n" + " 'C', 'Casesensitive': directory is handled case sensitive\n" + " (Windows 10 1803 or later, local NTFS only,\n" + " WSL must be installed)\n"); +} + +int +main (int argc, char **argv) +{ + int c, ret = 0; + + opterr = 0; + while ((c = getopt_long (argc, argv, opts, longopts, NULL)) != EOF) + { + switch (c) + { + case 'R': + Ropt = 1; + break; + case 'V': + print_version (); + return 0; + case 'a': + aopt = 1; + break; + case 'd': + dopt = 1; + break; + case 'l': + lopt = 1; + break; + case 'n': + nopt = 1; + break; + case 'h': + default: + usage (c == 'h' ? stdout : stderr); + return 1; + } + } + if (optind > argc - 1) + lsattr_dir ("."); + else for (; optind < argc; ++optind) + { + struct stat st; + + if (lstat (argv[optind], &st) != 0) + { + fprintf (stderr, "%s: %s while trying to stat %s\n", + program_invocation_short_name, strerror (errno), + argv[optind]); + ret = 1; + } + else if (!S_ISREG (st.st_mode) && !S_ISDIR (st.st_mode)) + { + fprintf (stderr, "%s: %s on %s\n", + program_invocation_short_name, strerror (ENOTSUP), + argv[optind]); + ret = 1; + } + else if (S_ISDIR (st.st_mode) && !dopt) + { + if (lsattr_dir (argv[optind])) + ret = 1; + } + else if (lsattr (argv[optind])) + ret = 1; + } + return ret; +} From 66cd1cbaf81bf3d87067ebf721d843ffe719badf Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Wed, 26 Dec 2018 11:22:06 +0100 Subject: [PATCH 036/475] Cygwin: Add documentation for chattr and lsattr Signed-off-by: Corinna Vinschen --- winsup/doc/utils.xml | 129 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 129 insertions(+) diff --git a/winsup/doc/utils.xml b/winsup/doc/utils.xml index 182134379..17b564da4 100644 --- a/winsup/doc/utils.xml +++ b/winsup/doc/utils.xml @@ -13,6 +13,70 @@ identically. All of the Cygwin command-line utilities support the --help and --version options. + + + chattr + 1 + Cygwin Utilities + + + + chattr + Change file attributes + + + + +chattr [-RVfhv] [+-=mode]... [file]... + + + + + Options + + -R, --recursive recursively list attributes of directories and their + contents + -V, --verbose Be verbose during operation + -f, --force suppress error messages + -h, --help this help text + -v, --version display the program version + + + + + Description + The chattr program allows to change file + attributes, namely DOS attributes, as well as making files sparse, + encrypt or compress them on FS level, or setting directories' + case sensitivity. + + + The format of 'mode' is {+-=}[acCehnrsSt] + + The operator '+' causes the selected attributes to be added to the + existing attributes of the files; '-' causes them to be removed; and + '=' causes them to be the only attributes that the files have. + + Supported attributes: + + + 'r', 'Readonly': file is read-only + 'h', 'Hidden': file or directory is hidden + 's', 'System': file or directory that the operating system uses + 'a', 'Archive': file or directory has the archive marker set + 't', 'Temporary': file is being used for temporary storage + 'S', 'Sparse': file is sparse + 'c', 'Compressed': file or directory is compressed + 'n', 'Notindexed': file or directory is not to be indexed by the + content indexing service + 'e', 'Encrypted': file is encrypted + 'C', 'Casesensitive': directory is handled case sensitive + (Windows 10 1803 or later, local NTFS only, + WSL must be installed) + + + + cygcheck @@ -951,6 +1015,71 @@ bash$ locale noexpr + + + lsattr + 1 + Cygwin Utilities + + + + lsattr + List file attributes + + + + +lsattr [-RVadhln] [file]... + + + + + Options + + -R, --recursive recursively list attributes of directories and their + contents + -V, --version display the program version + -a, --all list all files in directories, including files that + start with '.' + -d, --directory list directories like other files, rather than listing + their contents. + -l, --long print options using long names instead of single + character abbreviations + -n, --no-headers don't print directory headers when recursing + -h, --help this help text + + + + + Description + The lsattr program allows to list file + attributes, namely DOS attributes, file sparseness, FS level + encryption and compression state, as well as directories' + case sensitivity setting. + + + Supported attributes: + + + 'r', 'Readonly': file is read-only, directory is system-marked + 'h', 'Hidden': file or directory is hidden + 's', 'System': file or directory that the operating system uses + 'a', 'Archive': file or directory has the archive marker set + 't', 'Temporary': file is being used for temporary storage + 'S', 'Sparse': file is sparse + 'r', 'Reparse': file or directory that has a reparse point + 'c', 'Compressed': file or directory is compressed + 'o', 'Offline': the data of a file is moved to offline storage + 'n', 'Notindexed': file or directory is not to be indexed by the + content indexing service + 'e', 'Encrypted': file is encrypted + 'C', 'Casesensitive': directory is handled case sensitive + (Windows 10 1803 or later, local NTFS only, + WSL must be installed) + + + + minidumper From 4cd209e921ceab5cf5a5cc5abc3ff62ecc462d33 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Wed, 26 Dec 2018 11:36:22 +0100 Subject: [PATCH 037/475] Cygwin: Add Christmas hacking release notes Signed-off-by: Corinna Vinschen --- winsup/cygwin/release/2.12.0 | 22 ++++++++++++++++++++++ winsup/doc/new-features.xml | 30 ++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+) diff --git a/winsup/cygwin/release/2.12.0 b/winsup/cygwin/release/2.12.0 index 4e97f2a42..65868adb7 100644 --- a/winsup/cygwin/release/2.12.0 +++ b/winsup/cygwin/release/2.12.0 @@ -4,6 +4,22 @@ What's new: - Support for CLOCK_REALTIME_COARSE, CLOCK_MONOTONIC_COARSE, CLOCK_MONOTONIC_RAW, CLOCK_BOOTTIME clocks. +- Support for case sensitive directories. mkdir(2) automatically + creates directories within the Cygwin installation dir as case + sensitive now. + + This feature requires Windows 10 1803 or later and WSL installed! + +- New file ioctls's FS_IOC_GETFLAGS and FS_IOC_SETFLAGS. The actual + inode flags are Cygwin-specific. This allows to set or reset + DOS attributes, file sparseness, FS level encryption and compression, + as well as directory case sensitivity programatically. + +- New tools chattr(1) and lsattr(1) to utilize setting and viewing the + aforementioned new ioctl's on the command line. + +- Support for exFAT. + What changed: ------------- @@ -13,6 +29,10 @@ What changed: - clock_setres is a no-op now. +- Use the new POSIX unlink semantics on NTFS starting with Windows 10 1709. + Deleting an in-use file now actually removes the file, rather than moving + it to the recycler bin. + Bug Fixes --------- @@ -22,3 +42,5 @@ Bug Fixes - Fix early timeout from pthread_cond_timedwait. Addresses: https://cygwin.com/ml/cygwin/2018-11/msg00171.html + +- Fix a bug in recognizing remote FAT/FAT32/exFAT correctly. diff --git a/winsup/doc/new-features.xml b/winsup/doc/new-features.xml index 7cc449764..4750c0e9a 100644 --- a/winsup/doc/new-features.xml +++ b/winsup/doc/new-features.xml @@ -13,6 +13,30 @@ Support for CLOCK_REALTIME_COARSE, CLOCK_MONOTONIC_COARSE, CLOCK_MONOTONIC_RAW, CLOCK_BOOTTIME clocks. + +Support for case sensitive directories. mkdir(2) automatically creates +directories within the Cygwin installation dir as case sensitive +now. + +This feature requires Windows 10 1803 or later and WSL installed! + + + +New file ioctls's FS_IOC_GETFLAGS and FS_IOC_SETFLAGS. The actual inode +flags are Cygwin-specific. This allows to set or reset DOS attributes, +file sparseness, FS level encryption and compression, as well as +directory case sensitivity programatically. + + + +New tools chattr(1) and lsattr(1) to utilize setting and viewing the +aforementioned new ioctl's on the command line. + + + +Support for exFAT. + + clock_nanosleep, pthread_condattr_setclock and timer_create now support all clocks, except CLOCK_PROCESS_CPUTIME_ID and CLOCK_THREAD_CPUTIME_ID. @@ -22,6 +46,12 @@ all clocks, except CLOCK_PROCESS_CPUTIME_ID and CLOCK_THREAD_CPUTIME_ID. clock_setres is a no-op now. + +Use the new POSIX unlink semantics on NTFS starting with Windows 10 +1709. Deleting an in-use file now actually removes the file, rather +than moving it to the recycler bin. + + From 7148fbc49688986b3648ba6ce3f2afd527d8baa0 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Wed, 26 Dec 2018 21:22:40 +0100 Subject: [PATCH 038/475] Cygwin: Change /proc/$PID/fd/ symlink target for deleted files - As on Linux, print the file name with an attached " (deleted)" Signed-off-by: Corinna Vinschen --- winsup/cygwin/fhandler.cc | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/winsup/cygwin/fhandler.cc b/winsup/cygwin/fhandler.cc index 22dbdb05d..f7e34c746 100644 --- a/winsup/cygwin/fhandler.cc +++ b/winsup/cygwin/fhandler.cc @@ -137,11 +137,23 @@ fhandler_base::set_name (path_conv &in_pc) char *fhandler_base::get_proc_fd_name (char *buf) { + IO_STATUS_BLOCK io; + FILE_STANDARD_INFORMATION fsi; + /* If the file had been opened with O_TMPFILE | O_EXCL, don't expose the filename. linkat is supposed to return ENOENT in this - case. See man 2 open on Linux. */ - if ((get_flags () & (O_TMPFILE | O_EXCL)) == (O_TMPFILE | O_EXCL)) - return strcpy (buf, ""); + case. FIXME: As soon as we open by handle from /proc//fd, + the O_EXCL test has to be moved to open. */ + if ((get_flags () & (O_TMPFILE | O_EXCL)) == (O_TMPFILE | O_EXCL) + || (get_device () == FH_FS + && NT_SUCCESS (NtQueryInformationFile (get_handle (), &io, + &fsi, sizeof fsi, + FileStandardInformation)) + && fsi.DeletePending)) + { + stpcpy (stpcpy (buf, get_name ()), " (deleted)"); + return buf; + } if (get_name ()) return strcpy (buf, get_name ()); if (dev ().name ()) From 07e0a9584f9a5b2668c767ede0482a5fba498731 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Wed, 26 Dec 2018 21:51:13 +0100 Subject: [PATCH 039/475] Cygwin: open(2): Change comment in disabled O_TMPFILE POSIX unlink code - Turns out, the definition of POSIX unlink semantics is half-hearted so far: It's not possible to link an open file HANDLE if it has been deleted with POSIX semantics, nor is it possible to remove the delete disposition. This breaks linkat on an O_TMPFILE. Tested with W10 1809. Signed-off-by: Corinna Vinschen --- winsup/cygwin/syscalls.cc | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc index c1a3ed418..0d4809037 100644 --- a/winsup/cygwin/syscalls.cc +++ b/winsup/cygwin/syscalls.cc @@ -1468,13 +1468,20 @@ open (const char *unix_path, int flags, ...) || !fh->open_with_arch (flags, mode & 07777)) __leave; /* errno already set */ #if 0 - /* W10 1709 POSIX unlink semantics: + /* Don't use W10 1709 POSIX unlink semantics here. - TODO: Works nicely for O_TEMPFILE but using linkat requires that - we first fix /proc/self/fd handling to allow opening by handle - rather than by symlinked filename only. */ + Including W10 1809, NtSetInformationFile(FileLinkInformation) on a + HANDLE to a file unlinked with POSIX semantics fails with + STATUS_ACCESS_DENIED. Trying to remove the delete disposition on + the file prior to calling link fails with STATUS_FILE_DELETED. + This breaks + + fd = open(O_TMPFILE); + linkat("/proc/self/fd/); + + semantics. */ if ((flags & O_TMPFILE) && wincap.has_posix_file_info () - && fh->pc.fs_is_ntfs ()) + && !fh->pc.isremote () && fh->pc.fs_is_ntfs ()) { HANDLE del_h; OBJECT_ATTRIBUTES attr; From 572687310059534b2da9428ca19df992509c8a5d Mon Sep 17 00:00:00 2001 From: Jeff Johnston Date: Mon, 31 Dec 2018 23:40:11 -0500 Subject: [PATCH 040/475] Bump release to 3.1.0 for yearly snapshot --- newlib/NEWS | 14 ++++++ newlib/acinclude.m4 | 2 +- newlib/configure | 24 ++++----- newlib/doc/configure | 36 +++++++++----- newlib/iconvdata/configure | 40 +++++++++------ newlib/libc/configure | 20 ++++---- newlib/libc/machine/a29k/configure | 20 ++++---- newlib/libc/machine/aarch64/configure | 20 ++++---- newlib/libc/machine/arc/configure | 20 ++++---- newlib/libc/machine/arm/configure | 20 ++++---- newlib/libc/machine/bfin/configure | 20 ++++---- newlib/libc/machine/configure | 20 ++++---- newlib/libc/machine/cr16/configure | 20 ++++---- newlib/libc/machine/cris/configure | 20 ++++---- newlib/libc/machine/crx/configure | 20 ++++---- newlib/libc/machine/d10v/configure | 20 ++++---- newlib/libc/machine/d30v/configure | 20 ++++---- newlib/libc/machine/epiphany/configure | 20 ++++---- newlib/libc/machine/fr30/configure | 20 ++++---- newlib/libc/machine/frv/configure | 20 ++++---- newlib/libc/machine/ft32/configure | 20 ++++---- newlib/libc/machine/h8300/configure | 20 ++++---- newlib/libc/machine/h8500/configure | 20 ++++---- newlib/libc/machine/hppa/configure | 20 ++++---- newlib/libc/machine/i386/configure | 20 ++++---- newlib/libc/machine/i960/configure | 20 ++++---- newlib/libc/machine/iq2000/configure | 20 ++++---- newlib/libc/machine/lm32/configure | 20 ++++---- newlib/libc/machine/m32c/configure | 20 ++++---- newlib/libc/machine/m32r/configure | 20 ++++---- newlib/libc/machine/m68hc11/configure | 20 ++++---- newlib/libc/machine/m68k/configure | 20 ++++---- newlib/libc/machine/m88k/configure | 20 ++++---- newlib/libc/machine/mep/configure | 20 ++++---- newlib/libc/machine/microblaze/configure | 20 ++++---- newlib/libc/machine/mips/configure | 20 ++++---- newlib/libc/machine/mn10200/configure | 20 ++++---- newlib/libc/machine/mn10300/configure | 20 ++++---- newlib/libc/machine/moxie/configure | 20 ++++---- newlib/libc/machine/msp430/configure | 20 ++++---- newlib/libc/machine/mt/configure | 20 ++++---- newlib/libc/machine/nds32/configure | 20 ++++---- newlib/libc/machine/necv70/configure | 20 ++++---- newlib/libc/machine/nios2/configure | 20 ++++---- newlib/libc/machine/nvptx/configure | 20 ++++---- newlib/libc/machine/or1k/configure | 20 ++++---- newlib/libc/machine/powerpc/configure | 20 ++++---- newlib/libc/machine/riscv/configure | 20 ++++---- newlib/libc/machine/rl78/configure | 20 ++++---- newlib/libc/machine/rx/configure | 20 ++++---- newlib/libc/machine/sh/configure | 20 ++++---- newlib/libc/machine/sparc/configure | 20 ++++---- newlib/libc/machine/spu/configure | 20 ++++---- newlib/libc/machine/tic4x/configure | 20 ++++---- newlib/libc/machine/tic6x/configure | 20 ++++---- newlib/libc/machine/tic80/configure | 20 ++++---- newlib/libc/machine/v850/configure | 20 ++++---- newlib/libc/machine/visium/configure | 20 ++++---- newlib/libc/machine/w65/configure | 20 ++++---- newlib/libc/machine/x86_64/configure | 20 ++++---- newlib/libc/machine/xc16x/configure | 20 ++++---- newlib/libc/machine/xscale/configure | 20 ++++---- newlib/libc/machine/xstormy16/configure | 20 ++++---- newlib/libc/machine/z8k/configure | 20 ++++---- newlib/libc/stdlib/Makefile.in | 49 ++++++++++--------- newlib/libc/sys/a29khif/configure | 20 ++++---- newlib/libc/sys/arm/configure | 20 ++++---- newlib/libc/sys/configure | 20 ++++---- newlib/libc/sys/d10v/configure | 20 ++++---- newlib/libc/sys/decstation/configure | 20 ++++---- newlib/libc/sys/epiphany/configure | 20 ++++---- newlib/libc/sys/h8300hms/configure | 20 ++++---- newlib/libc/sys/h8500hms/configure | 20 ++++---- newlib/libc/sys/linux/configure | 20 ++++---- newlib/libc/sys/linux/linuxthreads/configure | 20 ++++---- .../sys/linux/linuxthreads/machine/configure | 20 ++++---- .../linux/linuxthreads/machine/i386/configure | 20 ++++---- newlib/libc/sys/linux/machine/configure | 20 ++++---- newlib/libc/sys/linux/machine/i386/configure | 40 +++++++++------ newlib/libc/sys/m88kbug/configure | 20 ++++---- newlib/libc/sys/mmixware/configure | 20 ++++---- newlib/libc/sys/netware/configure | 20 ++++---- newlib/libc/sys/or1k/configure | 20 ++++---- newlib/libc/sys/phoenix/configure | 20 ++++---- newlib/libc/sys/rdos/configure | 20 ++++---- newlib/libc/sys/rtems/configure | 20 ++++---- newlib/libc/sys/sh/configure | 20 ++++---- newlib/libc/sys/sparc64/configure | 20 ++++---- newlib/libc/sys/sun4/configure | 20 ++++---- newlib/libc/sys/sysmec/configure | 20 ++++---- newlib/libc/sys/sysnec810/configure | 20 ++++---- newlib/libc/sys/sysnecv850/configure | 20 ++++---- newlib/libc/sys/sysvi386/configure | 20 ++++---- newlib/libc/sys/sysvnecv70/configure | 20 ++++---- newlib/libc/sys/tic80/configure | 20 ++++---- newlib/libc/sys/tirtos/configure | 20 ++++---- newlib/libc/sys/w65/configure | 20 ++++---- newlib/libc/sys/z8ksim/configure | 20 ++++---- newlib/libm/configure | 20 ++++---- newlib/libm/machine/aarch64/configure | 20 ++++---- newlib/libm/machine/arm/configure | 20 ++++---- newlib/libm/machine/configure | 38 +++++++++----- newlib/libm/machine/i386/configure | 20 ++++---- newlib/libm/machine/nds32/configure | 20 ++++---- newlib/libm/machine/riscv/configure | 20 ++++---- newlib/libm/machine/spu/configure | 20 ++++---- 106 files changed, 1135 insertions(+), 1068 deletions(-) diff --git a/newlib/NEWS b/newlib/NEWS index 57b36ea89..90169cd9c 100644 --- a/newlib/NEWS +++ b/newlib/NEWS @@ -1,3 +1,17 @@ +*** Major changes in newlib version 3.1.0: + +- global stdio streams support added for reent small +- _CLOCKID_T made system configurable +- generated Unicode 10.0 width data, case conversion data, + character category data +- Unicode table generation scripts fixed/enhanced +- performance enhancements for qsort, strstr +- nvptx port added +- sinf/cosf/sincosf/exp/exp2/log/log2/pow rewritten for performance and accuracy +- various gcc warnings fixed +- various standard improvements + + *** Major changes in newlib version 3.0.0: - K&R support removed in code and docs diff --git a/newlib/acinclude.m4 b/newlib/acinclude.m4 index 19dfe0864..ed5944648 100644 --- a/newlib/acinclude.m4 +++ b/newlib/acinclude.m4 @@ -2,7 +2,7 @@ dnl This provides configure definitions used by all the newlib dnl configure.in files. AC_DEFUN([DEF_NEWLIB_MAJOR_VERSION],m4_define([NEWLIB_MAJOR_VERSION],[3])) -AC_DEFUN([DEF_NEWLIB_MINOR_VERSION],m4_define([NEWLIB_MINOR_VERSION],[0])) +AC_DEFUN([DEF_NEWLIB_MINOR_VERSION],m4_define([NEWLIB_MINOR_VERSION],[1])) AC_DEFUN([DEF_NEWLIB_PATCHLEVEL_VERSION],m4_define([NEWLIB_PATCHLEVEL_VERSION],[0])) AC_DEFUN([DEF_NEWLIB_VERSION],m4_define([NEWLIB_VERSION],[NEWLIB_MAJOR_VERSION.NEWLIB_MINOR_VERSION.NEWLIB_PATCHLEVEL_VERSION])) diff --git a/newlib/configure b/newlib/configure index 192a0b37a..6eef23c40 100755 --- a/newlib/configure +++ b/newlib/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for newlib 3.0.0. +# Generated by GNU Autoconf 2.68 for newlib 3.1.0. # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -567,8 +567,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='newlib' PACKAGE_TARNAME='newlib' -PACKAGE_VERSION='3.0.0' -PACKAGE_STRING='newlib 3.0.0' +PACKAGE_VERSION='3.1.0' +PACKAGE_STRING='newlib 3.1.0' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1379,7 +1379,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures newlib 3.0.0 to adapt to many kinds of systems. +\`configure' configures newlib 3.1.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1449,7 +1449,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of newlib 3.0.0:";; + short | recursive ) echo "Configuration of newlib 3.1.0:";; esac cat <<\_ACEOF @@ -1584,7 +1584,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -newlib configure 3.0.0 +newlib configure 3.1.0 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -1862,7 +1862,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by newlib $as_me 3.0.0, which was +It was created by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -3222,7 +3222,7 @@ fi # Define the identity of the package. PACKAGE='newlib' - VERSION='3.0.0' + VERSION='3.1.0' # Some tools Automake needs. @@ -12424,13 +12424,13 @@ _ACEOF fi -$as_echo "#define _NEWLIB_VERSION \"3.0.0\"" >>confdefs.h +$as_echo "#define _NEWLIB_VERSION \"3.1.0\"" >>confdefs.h $as_echo "#define __NEWLIB__ 3" >>confdefs.h -$as_echo "#define __NEWLIB_MINOR__ 0" >>confdefs.h +$as_echo "#define __NEWLIB_MINOR__ 1" >>confdefs.h $as_echo "#define __NEWLIB_PATCHLEVEL__ 0" >>confdefs.h @@ -13363,7 +13363,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by newlib $as_me 3.0.0, which was +This file was extended by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -13429,7 +13429,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -newlib config.status 3.0.0 +newlib config.status 3.1.0 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" diff --git a/newlib/doc/configure b/newlib/doc/configure index f288e6a5c..dbd706d7e 100755 --- a/newlib/doc/configure +++ b/newlib/doc/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for newlib 3.0.0. +# Generated by GNU Autoconf 2.68 for newlib 3.1.0. # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -556,8 +556,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='newlib' PACKAGE_TARNAME='newlib' -PACKAGE_VERSION='3.0.0' -PACKAGE_STRING='newlib 3.0.0' +PACKAGE_VERSION='3.1.0' +PACKAGE_STRING='newlib 3.1.0' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -691,6 +691,7 @@ enable_newlib_iconv enable_newlib_elix_level enable_newlib_io_float enable_newlib_supplied_syscalls +enable_newlib_fno_builtin enable_dependency_tracking enable_maintainer_mode ' @@ -1241,7 +1242,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures newlib 3.0.0 to adapt to many kinds of systems. +\`configure' configures newlib 3.1.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1311,7 +1312,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of newlib 3.0.0:";; + short | recursive ) echo "Configuration of newlib 3.1.0:";; esac cat <<\_ACEOF @@ -1327,6 +1328,7 @@ Optional Features: --enable-newlib-elix-level supply desired elix library level (1-4) --disable-newlib-io-float disable printf/scanf family float support --disable-newlib-supplied-syscalls disable newlib from supplying syscalls + --disable-newlib-fno-builtin disable -fno-builtin flag to allow compiler to use builtin library functions --disable-dependency-tracking speeds up one-time build --enable-dependency-tracking do not reject slow dependency extractors --enable-maintainer-mode enable make rules and dependencies not useful @@ -1402,7 +1404,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -newlib configure 3.0.0 +newlib configure 3.1.0 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -1457,7 +1459,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by newlib $as_me 3.0.0, which was +It was created by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -2491,6 +2493,18 @@ else fi +# Check whether --enable-newlib-fno-builtin was given. +if test "${enable_newlib_fno_builtin+set}" = set; then : + enableval=$enable_newlib_fno_builtin; case "${enableval}" in + yes) newlib_fno_builtin=yes ;; + no) newlib_fno_builtin=no ;; + *) as_fn_error $? "bad value ${enableval} for newlib-fno-builtin option" "$LINENO" 5 ;; + esac +else + newlib_fno_builtin= +fi + + test -z "${with_target_subdir}" && with_target_subdir=. @@ -2529,7 +2543,7 @@ fi # Define the identity of the package. PACKAGE='newlib' - VERSION='3.0.0' + VERSION='3.1.0' # Some tools Automake needs. @@ -3337,8 +3351,6 @@ fi . ${newlib_basedir}/configure.host -newlib_cflags="${newlib_cflags} -fno-builtin" - NEWLIB_CFLAGS=${newlib_cflags} @@ -4051,7 +4063,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by newlib $as_me 3.0.0, which was +This file was extended by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -4108,7 +4120,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -newlib config.status 3.0.0 +newlib config.status 3.1.0 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" diff --git a/newlib/iconvdata/configure b/newlib/iconvdata/configure index b5db63cd7..cfac61373 100755 --- a/newlib/iconvdata/configure +++ b/newlib/iconvdata/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for newlib 3.0.0. +# Generated by GNU Autoconf 2.68 for newlib 3.1.0. # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -567,8 +567,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='newlib' PACKAGE_TARNAME='newlib' -PACKAGE_VERSION='3.0.0' -PACKAGE_STRING='newlib 3.0.0' +PACKAGE_VERSION='3.1.0' +PACKAGE_STRING='newlib 3.1.0' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -760,6 +760,7 @@ enable_newlib_iconv enable_newlib_elix_level enable_newlib_io_float enable_newlib_supplied_syscalls +enable_newlib_fno_builtin enable_dependency_tracking enable_maintainer_mode enable_shared @@ -1322,7 +1323,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures newlib 3.0.0 to adapt to many kinds of systems. +\`configure' configures newlib 3.1.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1392,7 +1393,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of newlib 3.0.0:";; + short | recursive ) echo "Configuration of newlib 3.1.0:";; esac cat <<\_ACEOF @@ -1408,6 +1409,7 @@ Optional Features: --enable-newlib-elix-level supply desired elix library level (1-4) --disable-newlib-io-float disable printf/scanf family float support --disable-newlib-supplied-syscalls disable newlib from supplying syscalls + --disable-newlib-fno-builtin disable -fno-builtin flag to allow compiler to use builtin library functions --disable-dependency-tracking speeds up one-time build --enable-dependency-tracking do not reject slow dependency extractors --enable-maintainer-mode enable make rules and dependencies not useful @@ -1503,7 +1505,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -newlib configure 3.0.0 +newlib configure 3.1.0 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -1781,7 +1783,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by newlib $as_me 3.0.0, which was +It was created by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -2815,6 +2817,18 @@ else fi +# Check whether --enable-newlib-fno-builtin was given. +if test "${enable_newlib_fno_builtin+set}" = set; then : + enableval=$enable_newlib_fno_builtin; case "${enableval}" in + yes) newlib_fno_builtin=yes ;; + no) newlib_fno_builtin=no ;; + *) as_fn_error $? "bad value ${enableval} for newlib-fno-builtin option" "$LINENO" 5 ;; + esac +else + newlib_fno_builtin= +fi + + test -z "${with_target_subdir}" && with_target_subdir=. @@ -2853,7 +2867,7 @@ fi # Define the identity of the package. PACKAGE='newlib' - VERSION='3.0.0' + VERSION='3.1.0' # Some tools Automake needs. @@ -3661,8 +3675,6 @@ fi . ${newlib_basedir}/configure.host -newlib_cflags="${newlib_cflags} -fno-builtin" - NEWLIB_CFLAGS=${newlib_cflags} @@ -11431,7 +11443,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 11434 "configure" +#line 11446 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -11537,7 +11549,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 11540 "configure" +#line 11552 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -12384,7 +12396,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by newlib $as_me 3.0.0, which was +This file was extended by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -12441,7 +12453,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -newlib config.status 3.0.0 +newlib config.status 3.1.0 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" diff --git a/newlib/libc/configure b/newlib/libc/configure index add8f679c..0dc213e86 100755 --- a/newlib/libc/configure +++ b/newlib/libc/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for newlib 3.0.0. +# Generated by GNU Autoconf 2.68 for newlib 3.1.0. # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -567,8 +567,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='newlib' PACKAGE_TARNAME='newlib' -PACKAGE_VERSION='3.0.0' -PACKAGE_STRING='newlib 3.0.0' +PACKAGE_VERSION='3.1.0' +PACKAGE_STRING='newlib 3.1.0' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1371,7 +1371,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures newlib 3.0.0 to adapt to many kinds of systems. +\`configure' configures newlib 3.1.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1441,7 +1441,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of newlib 3.0.0:";; + short | recursive ) echo "Configuration of newlib 3.1.0:";; esac cat <<\_ACEOF @@ -1557,7 +1557,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -newlib configure 3.0.0 +newlib configure 3.1.0 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -1835,7 +1835,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by newlib $as_me 3.0.0, which was +It was created by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -2982,7 +2982,7 @@ fi # Define the identity of the package. PACKAGE='newlib' - VERSION='3.0.0' + VERSION='3.1.0' # Some tools Automake needs. @@ -12795,7 +12795,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by newlib $as_me 3.0.0, which was +This file was extended by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -12852,7 +12852,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -newlib config.status 3.0.0 +newlib config.status 3.1.0 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" diff --git a/newlib/libc/machine/a29k/configure b/newlib/libc/machine/a29k/configure index 6a6ad6044..24feba10f 100755 --- a/newlib/libc/machine/a29k/configure +++ b/newlib/libc/machine/a29k/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for newlib 3.0.0. +# Generated by GNU Autoconf 2.68 for newlib 3.1.0. # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -556,8 +556,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='newlib' PACKAGE_TARNAME='newlib' -PACKAGE_VERSION='3.0.0' -PACKAGE_STRING='newlib 3.0.0' +PACKAGE_VERSION='3.1.0' +PACKAGE_STRING='newlib 3.1.0' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1240,7 +1240,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures newlib 3.0.0 to adapt to many kinds of systems. +\`configure' configures newlib 3.1.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1310,7 +1310,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of newlib 3.0.0:";; + short | recursive ) echo "Configuration of newlib 3.1.0:";; esac cat <<\_ACEOF @@ -1402,7 +1402,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -newlib configure 3.0.0 +newlib configure 3.1.0 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -1457,7 +1457,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by newlib $as_me 3.0.0, which was +It was created by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -2541,7 +2541,7 @@ fi # Define the identity of the package. PACKAGE='newlib' - VERSION='3.0.0' + VERSION='3.1.0' # Some tools Automake needs. @@ -4025,7 +4025,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by newlib $as_me 3.0.0, which was +This file was extended by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -4082,7 +4082,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -newlib config.status 3.0.0 +newlib config.status 3.1.0 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" diff --git a/newlib/libc/machine/aarch64/configure b/newlib/libc/machine/aarch64/configure index 083cd071c..35078c605 100755 --- a/newlib/libc/machine/aarch64/configure +++ b/newlib/libc/machine/aarch64/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for newlib 3.0.0. +# Generated by GNU Autoconf 2.68 for newlib 3.1.0. # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -556,8 +556,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='newlib' PACKAGE_TARNAME='newlib' -PACKAGE_VERSION='3.0.0' -PACKAGE_STRING='newlib 3.0.0' +PACKAGE_VERSION='3.1.0' +PACKAGE_STRING='newlib 3.1.0' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1240,7 +1240,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures newlib 3.0.0 to adapt to many kinds of systems. +\`configure' configures newlib 3.1.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1310,7 +1310,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of newlib 3.0.0:";; + short | recursive ) echo "Configuration of newlib 3.1.0:";; esac cat <<\_ACEOF @@ -1402,7 +1402,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -newlib configure 3.0.0 +newlib configure 3.1.0 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -1457,7 +1457,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by newlib $as_me 3.0.0, which was +It was created by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -2541,7 +2541,7 @@ fi # Define the identity of the package. PACKAGE='newlib' - VERSION='3.0.0' + VERSION='3.1.0' # Some tools Automake needs. @@ -4025,7 +4025,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by newlib $as_me 3.0.0, which was +This file was extended by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -4082,7 +4082,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -newlib config.status 3.0.0 +newlib config.status 3.1.0 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" diff --git a/newlib/libc/machine/arc/configure b/newlib/libc/machine/arc/configure index 6a6ad6044..24feba10f 100755 --- a/newlib/libc/machine/arc/configure +++ b/newlib/libc/machine/arc/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for newlib 3.0.0. +# Generated by GNU Autoconf 2.68 for newlib 3.1.0. # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -556,8 +556,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='newlib' PACKAGE_TARNAME='newlib' -PACKAGE_VERSION='3.0.0' -PACKAGE_STRING='newlib 3.0.0' +PACKAGE_VERSION='3.1.0' +PACKAGE_STRING='newlib 3.1.0' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1240,7 +1240,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures newlib 3.0.0 to adapt to many kinds of systems. +\`configure' configures newlib 3.1.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1310,7 +1310,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of newlib 3.0.0:";; + short | recursive ) echo "Configuration of newlib 3.1.0:";; esac cat <<\_ACEOF @@ -1402,7 +1402,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -newlib configure 3.0.0 +newlib configure 3.1.0 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -1457,7 +1457,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by newlib $as_me 3.0.0, which was +It was created by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -2541,7 +2541,7 @@ fi # Define the identity of the package. PACKAGE='newlib' - VERSION='3.0.0' + VERSION='3.1.0' # Some tools Automake needs. @@ -4025,7 +4025,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by newlib $as_me 3.0.0, which was +This file was extended by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -4082,7 +4082,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -newlib config.status 3.0.0 +newlib config.status 3.1.0 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" diff --git a/newlib/libc/machine/arm/configure b/newlib/libc/machine/arm/configure index 4b9ac6739..e09e452da 100755 --- a/newlib/libc/machine/arm/configure +++ b/newlib/libc/machine/arm/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for newlib 3.0.0. +# Generated by GNU Autoconf 2.68 for newlib 3.1.0. # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -556,8 +556,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='newlib' PACKAGE_TARNAME='newlib' -PACKAGE_VERSION='3.0.0' -PACKAGE_STRING='newlib 3.0.0' +PACKAGE_VERSION='3.1.0' +PACKAGE_STRING='newlib 3.1.0' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1241,7 +1241,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures newlib 3.0.0 to adapt to many kinds of systems. +\`configure' configures newlib 3.1.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1311,7 +1311,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of newlib 3.0.0:";; + short | recursive ) echo "Configuration of newlib 3.1.0:";; esac cat <<\_ACEOF @@ -1403,7 +1403,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -newlib configure 3.0.0 +newlib configure 3.1.0 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -1458,7 +1458,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by newlib $as_me 3.0.0, which was +It was created by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -2542,7 +2542,7 @@ fi # Define the identity of the package. PACKAGE='newlib' - VERSION='3.0.0' + VERSION='3.1.0' # Some tools Automake needs. @@ -4028,7 +4028,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by newlib $as_me 3.0.0, which was +This file was extended by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -4085,7 +4085,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -newlib config.status 3.0.0 +newlib config.status 3.1.0 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" diff --git a/newlib/libc/machine/bfin/configure b/newlib/libc/machine/bfin/configure index 6a6ad6044..24feba10f 100755 --- a/newlib/libc/machine/bfin/configure +++ b/newlib/libc/machine/bfin/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for newlib 3.0.0. +# Generated by GNU Autoconf 2.68 for newlib 3.1.0. # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -556,8 +556,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='newlib' PACKAGE_TARNAME='newlib' -PACKAGE_VERSION='3.0.0' -PACKAGE_STRING='newlib 3.0.0' +PACKAGE_VERSION='3.1.0' +PACKAGE_STRING='newlib 3.1.0' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1240,7 +1240,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures newlib 3.0.0 to adapt to many kinds of systems. +\`configure' configures newlib 3.1.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1310,7 +1310,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of newlib 3.0.0:";; + short | recursive ) echo "Configuration of newlib 3.1.0:";; esac cat <<\_ACEOF @@ -1402,7 +1402,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -newlib configure 3.0.0 +newlib configure 3.1.0 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -1457,7 +1457,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by newlib $as_me 3.0.0, which was +It was created by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -2541,7 +2541,7 @@ fi # Define the identity of the package. PACKAGE='newlib' - VERSION='3.0.0' + VERSION='3.1.0' # Some tools Automake needs. @@ -4025,7 +4025,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by newlib $as_me 3.0.0, which was +This file was extended by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -4082,7 +4082,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -newlib config.status 3.0.0 +newlib config.status 3.1.0 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" diff --git a/newlib/libc/machine/configure b/newlib/libc/machine/configure index be295f6fd..f3229e942 100755 --- a/newlib/libc/machine/configure +++ b/newlib/libc/machine/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for newlib 3.0.0. +# Generated by GNU Autoconf 2.68 for newlib 3.1.0. # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -567,8 +567,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='newlib' PACKAGE_TARNAME='newlib' -PACKAGE_VERSION='3.0.0' -PACKAGE_STRING='newlib 3.0.0' +PACKAGE_VERSION='3.1.0' +PACKAGE_STRING='newlib 3.1.0' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1382,7 +1382,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures newlib 3.0.0 to adapt to many kinds of systems. +\`configure' configures newlib 3.1.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1452,7 +1452,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of newlib 3.0.0:";; + short | recursive ) echo "Configuration of newlib 3.1.0:";; esac cat <<\_ACEOF @@ -1564,7 +1564,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -newlib configure 3.0.0 +newlib configure 3.1.0 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -1842,7 +1842,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by newlib $as_me 3.0.0, which was +It was created by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -2926,7 +2926,7 @@ fi # Define the identity of the package. PACKAGE='newlib' - VERSION='3.0.0' + VERSION='3.1.0' # Some tools Automake needs. @@ -12587,7 +12587,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by newlib $as_me 3.0.0, which was +This file was extended by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -12644,7 +12644,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -newlib config.status 3.0.0 +newlib config.status 3.1.0 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" diff --git a/newlib/libc/machine/cr16/configure b/newlib/libc/machine/cr16/configure index 6a6ad6044..24feba10f 100644 --- a/newlib/libc/machine/cr16/configure +++ b/newlib/libc/machine/cr16/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for newlib 3.0.0. +# Generated by GNU Autoconf 2.68 for newlib 3.1.0. # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -556,8 +556,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='newlib' PACKAGE_TARNAME='newlib' -PACKAGE_VERSION='3.0.0' -PACKAGE_STRING='newlib 3.0.0' +PACKAGE_VERSION='3.1.0' +PACKAGE_STRING='newlib 3.1.0' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1240,7 +1240,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures newlib 3.0.0 to adapt to many kinds of systems. +\`configure' configures newlib 3.1.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1310,7 +1310,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of newlib 3.0.0:";; + short | recursive ) echo "Configuration of newlib 3.1.0:";; esac cat <<\_ACEOF @@ -1402,7 +1402,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -newlib configure 3.0.0 +newlib configure 3.1.0 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -1457,7 +1457,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by newlib $as_me 3.0.0, which was +It was created by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -2541,7 +2541,7 @@ fi # Define the identity of the package. PACKAGE='newlib' - VERSION='3.0.0' + VERSION='3.1.0' # Some tools Automake needs. @@ -4025,7 +4025,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by newlib $as_me 3.0.0, which was +This file was extended by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -4082,7 +4082,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -newlib config.status 3.0.0 +newlib config.status 3.1.0 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" diff --git a/newlib/libc/machine/cris/configure b/newlib/libc/machine/cris/configure index 017a4d5e7..714396acf 100755 --- a/newlib/libc/machine/cris/configure +++ b/newlib/libc/machine/cris/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for newlib 3.0.0. +# Generated by GNU Autoconf 2.68 for newlib 3.1.0. # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -556,8 +556,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='newlib' PACKAGE_TARNAME='newlib' -PACKAGE_VERSION='3.0.0' -PACKAGE_STRING='newlib 3.0.0' +PACKAGE_VERSION='3.1.0' +PACKAGE_STRING='newlib 3.1.0' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1240,7 +1240,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures newlib 3.0.0 to adapt to many kinds of systems. +\`configure' configures newlib 3.1.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1310,7 +1310,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of newlib 3.0.0:";; + short | recursive ) echo "Configuration of newlib 3.1.0:";; esac cat <<\_ACEOF @@ -1402,7 +1402,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -newlib configure 3.0.0 +newlib configure 3.1.0 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -1457,7 +1457,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by newlib $as_me 3.0.0, which was +It was created by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -2541,7 +2541,7 @@ fi # Define the identity of the package. PACKAGE='newlib' - VERSION='3.0.0' + VERSION='3.1.0' # Some tools Automake needs. @@ -4025,7 +4025,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by newlib $as_me 3.0.0, which was +This file was extended by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -4082,7 +4082,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -newlib config.status 3.0.0 +newlib config.status 3.1.0 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" diff --git a/newlib/libc/machine/crx/configure b/newlib/libc/machine/crx/configure index 6a6ad6044..24feba10f 100755 --- a/newlib/libc/machine/crx/configure +++ b/newlib/libc/machine/crx/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for newlib 3.0.0. +# Generated by GNU Autoconf 2.68 for newlib 3.1.0. # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -556,8 +556,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='newlib' PACKAGE_TARNAME='newlib' -PACKAGE_VERSION='3.0.0' -PACKAGE_STRING='newlib 3.0.0' +PACKAGE_VERSION='3.1.0' +PACKAGE_STRING='newlib 3.1.0' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1240,7 +1240,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures newlib 3.0.0 to adapt to many kinds of systems. +\`configure' configures newlib 3.1.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1310,7 +1310,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of newlib 3.0.0:";; + short | recursive ) echo "Configuration of newlib 3.1.0:";; esac cat <<\_ACEOF @@ -1402,7 +1402,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -newlib configure 3.0.0 +newlib configure 3.1.0 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -1457,7 +1457,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by newlib $as_me 3.0.0, which was +It was created by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -2541,7 +2541,7 @@ fi # Define the identity of the package. PACKAGE='newlib' - VERSION='3.0.0' + VERSION='3.1.0' # Some tools Automake needs. @@ -4025,7 +4025,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by newlib $as_me 3.0.0, which was +This file was extended by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -4082,7 +4082,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -newlib config.status 3.0.0 +newlib config.status 3.1.0 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" diff --git a/newlib/libc/machine/d10v/configure b/newlib/libc/machine/d10v/configure index 083cd071c..35078c605 100755 --- a/newlib/libc/machine/d10v/configure +++ b/newlib/libc/machine/d10v/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for newlib 3.0.0. +# Generated by GNU Autoconf 2.68 for newlib 3.1.0. # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -556,8 +556,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='newlib' PACKAGE_TARNAME='newlib' -PACKAGE_VERSION='3.0.0' -PACKAGE_STRING='newlib 3.0.0' +PACKAGE_VERSION='3.1.0' +PACKAGE_STRING='newlib 3.1.0' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1240,7 +1240,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures newlib 3.0.0 to adapt to many kinds of systems. +\`configure' configures newlib 3.1.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1310,7 +1310,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of newlib 3.0.0:";; + short | recursive ) echo "Configuration of newlib 3.1.0:";; esac cat <<\_ACEOF @@ -1402,7 +1402,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -newlib configure 3.0.0 +newlib configure 3.1.0 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -1457,7 +1457,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by newlib $as_me 3.0.0, which was +It was created by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -2541,7 +2541,7 @@ fi # Define the identity of the package. PACKAGE='newlib' - VERSION='3.0.0' + VERSION='3.1.0' # Some tools Automake needs. @@ -4025,7 +4025,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by newlib $as_me 3.0.0, which was +This file was extended by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -4082,7 +4082,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -newlib config.status 3.0.0 +newlib config.status 3.1.0 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" diff --git a/newlib/libc/machine/d30v/configure b/newlib/libc/machine/d30v/configure index 083cd071c..35078c605 100755 --- a/newlib/libc/machine/d30v/configure +++ b/newlib/libc/machine/d30v/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for newlib 3.0.0. +# Generated by GNU Autoconf 2.68 for newlib 3.1.0. # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -556,8 +556,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='newlib' PACKAGE_TARNAME='newlib' -PACKAGE_VERSION='3.0.0' -PACKAGE_STRING='newlib 3.0.0' +PACKAGE_VERSION='3.1.0' +PACKAGE_STRING='newlib 3.1.0' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1240,7 +1240,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures newlib 3.0.0 to adapt to many kinds of systems. +\`configure' configures newlib 3.1.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1310,7 +1310,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of newlib 3.0.0:";; + short | recursive ) echo "Configuration of newlib 3.1.0:";; esac cat <<\_ACEOF @@ -1402,7 +1402,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -newlib configure 3.0.0 +newlib configure 3.1.0 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -1457,7 +1457,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by newlib $as_me 3.0.0, which was +It was created by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -2541,7 +2541,7 @@ fi # Define the identity of the package. PACKAGE='newlib' - VERSION='3.0.0' + VERSION='3.1.0' # Some tools Automake needs. @@ -4025,7 +4025,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by newlib $as_me 3.0.0, which was +This file was extended by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -4082,7 +4082,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -newlib config.status 3.0.0 +newlib config.status 3.1.0 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" diff --git a/newlib/libc/machine/epiphany/configure b/newlib/libc/machine/epiphany/configure index 6a6ad6044..24feba10f 100755 --- a/newlib/libc/machine/epiphany/configure +++ b/newlib/libc/machine/epiphany/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for newlib 3.0.0. +# Generated by GNU Autoconf 2.68 for newlib 3.1.0. # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -556,8 +556,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='newlib' PACKAGE_TARNAME='newlib' -PACKAGE_VERSION='3.0.0' -PACKAGE_STRING='newlib 3.0.0' +PACKAGE_VERSION='3.1.0' +PACKAGE_STRING='newlib 3.1.0' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1240,7 +1240,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures newlib 3.0.0 to adapt to many kinds of systems. +\`configure' configures newlib 3.1.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1310,7 +1310,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of newlib 3.0.0:";; + short | recursive ) echo "Configuration of newlib 3.1.0:";; esac cat <<\_ACEOF @@ -1402,7 +1402,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -newlib configure 3.0.0 +newlib configure 3.1.0 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -1457,7 +1457,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by newlib $as_me 3.0.0, which was +It was created by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -2541,7 +2541,7 @@ fi # Define the identity of the package. PACKAGE='newlib' - VERSION='3.0.0' + VERSION='3.1.0' # Some tools Automake needs. @@ -4025,7 +4025,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by newlib $as_me 3.0.0, which was +This file was extended by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -4082,7 +4082,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -newlib config.status 3.0.0 +newlib config.status 3.1.0 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" diff --git a/newlib/libc/machine/fr30/configure b/newlib/libc/machine/fr30/configure index 6a6ad6044..24feba10f 100755 --- a/newlib/libc/machine/fr30/configure +++ b/newlib/libc/machine/fr30/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for newlib 3.0.0. +# Generated by GNU Autoconf 2.68 for newlib 3.1.0. # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -556,8 +556,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='newlib' PACKAGE_TARNAME='newlib' -PACKAGE_VERSION='3.0.0' -PACKAGE_STRING='newlib 3.0.0' +PACKAGE_VERSION='3.1.0' +PACKAGE_STRING='newlib 3.1.0' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1240,7 +1240,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures newlib 3.0.0 to adapt to many kinds of systems. +\`configure' configures newlib 3.1.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1310,7 +1310,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of newlib 3.0.0:";; + short | recursive ) echo "Configuration of newlib 3.1.0:";; esac cat <<\_ACEOF @@ -1402,7 +1402,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -newlib configure 3.0.0 +newlib configure 3.1.0 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -1457,7 +1457,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by newlib $as_me 3.0.0, which was +It was created by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -2541,7 +2541,7 @@ fi # Define the identity of the package. PACKAGE='newlib' - VERSION='3.0.0' + VERSION='3.1.0' # Some tools Automake needs. @@ -4025,7 +4025,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by newlib $as_me 3.0.0, which was +This file was extended by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -4082,7 +4082,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -newlib config.status 3.0.0 +newlib config.status 3.1.0 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" diff --git a/newlib/libc/machine/frv/configure b/newlib/libc/machine/frv/configure index 6a6ad6044..24feba10f 100755 --- a/newlib/libc/machine/frv/configure +++ b/newlib/libc/machine/frv/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for newlib 3.0.0. +# Generated by GNU Autoconf 2.68 for newlib 3.1.0. # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -556,8 +556,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='newlib' PACKAGE_TARNAME='newlib' -PACKAGE_VERSION='3.0.0' -PACKAGE_STRING='newlib 3.0.0' +PACKAGE_VERSION='3.1.0' +PACKAGE_STRING='newlib 3.1.0' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1240,7 +1240,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures newlib 3.0.0 to adapt to many kinds of systems. +\`configure' configures newlib 3.1.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1310,7 +1310,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of newlib 3.0.0:";; + short | recursive ) echo "Configuration of newlib 3.1.0:";; esac cat <<\_ACEOF @@ -1402,7 +1402,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -newlib configure 3.0.0 +newlib configure 3.1.0 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -1457,7 +1457,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by newlib $as_me 3.0.0, which was +It was created by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -2541,7 +2541,7 @@ fi # Define the identity of the package. PACKAGE='newlib' - VERSION='3.0.0' + VERSION='3.1.0' # Some tools Automake needs. @@ -4025,7 +4025,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by newlib $as_me 3.0.0, which was +This file was extended by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -4082,7 +4082,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -newlib config.status 3.0.0 +newlib config.status 3.1.0 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" diff --git a/newlib/libc/machine/ft32/configure b/newlib/libc/machine/ft32/configure index 6a6ad6044..24feba10f 100755 --- a/newlib/libc/machine/ft32/configure +++ b/newlib/libc/machine/ft32/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for newlib 3.0.0. +# Generated by GNU Autoconf 2.68 for newlib 3.1.0. # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -556,8 +556,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='newlib' PACKAGE_TARNAME='newlib' -PACKAGE_VERSION='3.0.0' -PACKAGE_STRING='newlib 3.0.0' +PACKAGE_VERSION='3.1.0' +PACKAGE_STRING='newlib 3.1.0' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1240,7 +1240,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures newlib 3.0.0 to adapt to many kinds of systems. +\`configure' configures newlib 3.1.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1310,7 +1310,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of newlib 3.0.0:";; + short | recursive ) echo "Configuration of newlib 3.1.0:";; esac cat <<\_ACEOF @@ -1402,7 +1402,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -newlib configure 3.0.0 +newlib configure 3.1.0 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -1457,7 +1457,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by newlib $as_me 3.0.0, which was +It was created by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -2541,7 +2541,7 @@ fi # Define the identity of the package. PACKAGE='newlib' - VERSION='3.0.0' + VERSION='3.1.0' # Some tools Automake needs. @@ -4025,7 +4025,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by newlib $as_me 3.0.0, which was +This file was extended by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -4082,7 +4082,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -newlib config.status 3.0.0 +newlib config.status 3.1.0 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" diff --git a/newlib/libc/machine/h8300/configure b/newlib/libc/machine/h8300/configure index d19497d9d..23fa94a9e 100755 --- a/newlib/libc/machine/h8300/configure +++ b/newlib/libc/machine/h8300/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for newlib 3.0.0. +# Generated by GNU Autoconf 2.68 for newlib 3.1.0. # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -556,8 +556,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='newlib' PACKAGE_TARNAME='newlib' -PACKAGE_VERSION='3.0.0' -PACKAGE_STRING='newlib 3.0.0' +PACKAGE_VERSION='3.1.0' +PACKAGE_STRING='newlib 3.1.0' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1240,7 +1240,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures newlib 3.0.0 to adapt to many kinds of systems. +\`configure' configures newlib 3.1.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1310,7 +1310,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of newlib 3.0.0:";; + short | recursive ) echo "Configuration of newlib 3.1.0:";; esac cat <<\_ACEOF @@ -1402,7 +1402,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -newlib configure 3.0.0 +newlib configure 3.1.0 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -1457,7 +1457,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by newlib $as_me 3.0.0, which was +It was created by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -2541,7 +2541,7 @@ fi # Define the identity of the package. PACKAGE='newlib' - VERSION='3.0.0' + VERSION='3.1.0' # Some tools Automake needs. @@ -4025,7 +4025,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by newlib $as_me 3.0.0, which was +This file was extended by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -4082,7 +4082,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -newlib config.status 3.0.0 +newlib config.status 3.1.0 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" diff --git a/newlib/libc/machine/h8500/configure b/newlib/libc/machine/h8500/configure index e475ddd1f..7106b2aca 100755 --- a/newlib/libc/machine/h8500/configure +++ b/newlib/libc/machine/h8500/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for newlib 3.0.0. +# Generated by GNU Autoconf 2.68 for newlib 3.1.0. # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -556,8 +556,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='newlib' PACKAGE_TARNAME='newlib' -PACKAGE_VERSION='3.0.0' -PACKAGE_STRING='newlib 3.0.0' +PACKAGE_VERSION='3.1.0' +PACKAGE_STRING='newlib 3.1.0' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1240,7 +1240,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures newlib 3.0.0 to adapt to many kinds of systems. +\`configure' configures newlib 3.1.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1310,7 +1310,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of newlib 3.0.0:";; + short | recursive ) echo "Configuration of newlib 3.1.0:";; esac cat <<\_ACEOF @@ -1402,7 +1402,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -newlib configure 3.0.0 +newlib configure 3.1.0 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -1457,7 +1457,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by newlib $as_me 3.0.0, which was +It was created by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -2541,7 +2541,7 @@ fi # Define the identity of the package. PACKAGE='newlib' - VERSION='3.0.0' + VERSION='3.1.0' # Some tools Automake needs. @@ -4025,7 +4025,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by newlib $as_me 3.0.0, which was +This file was extended by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -4082,7 +4082,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -newlib config.status 3.0.0 +newlib config.status 3.1.0 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" diff --git a/newlib/libc/machine/hppa/configure b/newlib/libc/machine/hppa/configure index 2b8a77c57..aea4a2920 100755 --- a/newlib/libc/machine/hppa/configure +++ b/newlib/libc/machine/hppa/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for newlib 3.0.0. +# Generated by GNU Autoconf 2.68 for newlib 3.1.0. # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -556,8 +556,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='newlib' PACKAGE_TARNAME='newlib' -PACKAGE_VERSION='3.0.0' -PACKAGE_STRING='newlib 3.0.0' +PACKAGE_VERSION='3.1.0' +PACKAGE_STRING='newlib 3.1.0' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1240,7 +1240,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures newlib 3.0.0 to adapt to many kinds of systems. +\`configure' configures newlib 3.1.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1310,7 +1310,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of newlib 3.0.0:";; + short | recursive ) echo "Configuration of newlib 3.1.0:";; esac cat <<\_ACEOF @@ -1402,7 +1402,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -newlib configure 3.0.0 +newlib configure 3.1.0 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -1457,7 +1457,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by newlib $as_me 3.0.0, which was +It was created by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -2541,7 +2541,7 @@ fi # Define the identity of the package. PACKAGE='newlib' - VERSION='3.0.0' + VERSION='3.1.0' # Some tools Automake needs. @@ -4025,7 +4025,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by newlib $as_me 3.0.0, which was +This file was extended by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -4082,7 +4082,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -newlib config.status 3.0.0 +newlib config.status 3.1.0 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" diff --git a/newlib/libc/machine/i386/configure b/newlib/libc/machine/i386/configure index 76c10c78f..34a14f79e 100755 --- a/newlib/libc/machine/i386/configure +++ b/newlib/libc/machine/i386/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for newlib 3.0.0. +# Generated by GNU Autoconf 2.68 for newlib 3.1.0. # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -567,8 +567,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='newlib' PACKAGE_TARNAME='newlib' -PACKAGE_VERSION='3.0.0' -PACKAGE_STRING='newlib 3.0.0' +PACKAGE_VERSION='3.1.0' +PACKAGE_STRING='newlib 3.1.0' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1325,7 +1325,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures newlib 3.0.0 to adapt to many kinds of systems. +\`configure' configures newlib 3.1.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1395,7 +1395,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of newlib 3.0.0:";; + short | recursive ) echo "Configuration of newlib 3.1.0:";; esac cat <<\_ACEOF @@ -1507,7 +1507,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -newlib configure 3.0.0 +newlib configure 3.1.0 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -1785,7 +1785,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by newlib $as_me 3.0.0, which was +It was created by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -2869,7 +2869,7 @@ fi # Define the identity of the package. PACKAGE='newlib' - VERSION='3.0.0' + VERSION='3.1.0' # Some tools Automake needs. @@ -12411,7 +12411,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by newlib $as_me 3.0.0, which was +This file was extended by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -12468,7 +12468,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -newlib config.status 3.0.0 +newlib config.status 3.1.0 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" diff --git a/newlib/libc/machine/i960/configure b/newlib/libc/machine/i960/configure index a2e46c224..6bbe3d5c8 100755 --- a/newlib/libc/machine/i960/configure +++ b/newlib/libc/machine/i960/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for newlib 3.0.0. +# Generated by GNU Autoconf 2.68 for newlib 3.1.0. # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -556,8 +556,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='newlib' PACKAGE_TARNAME='newlib' -PACKAGE_VERSION='3.0.0' -PACKAGE_STRING='newlib 3.0.0' +PACKAGE_VERSION='3.1.0' +PACKAGE_STRING='newlib 3.1.0' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1240,7 +1240,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures newlib 3.0.0 to adapt to many kinds of systems. +\`configure' configures newlib 3.1.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1310,7 +1310,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of newlib 3.0.0:";; + short | recursive ) echo "Configuration of newlib 3.1.0:";; esac cat <<\_ACEOF @@ -1402,7 +1402,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -newlib configure 3.0.0 +newlib configure 3.1.0 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -1457,7 +1457,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by newlib $as_me 3.0.0, which was +It was created by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -2541,7 +2541,7 @@ fi # Define the identity of the package. PACKAGE='newlib' - VERSION='3.0.0' + VERSION='3.1.0' # Some tools Automake needs. @@ -4025,7 +4025,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by newlib $as_me 3.0.0, which was +This file was extended by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -4082,7 +4082,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -newlib config.status 3.0.0 +newlib config.status 3.1.0 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" diff --git a/newlib/libc/machine/iq2000/configure b/newlib/libc/machine/iq2000/configure index 6a6ad6044..24feba10f 100755 --- a/newlib/libc/machine/iq2000/configure +++ b/newlib/libc/machine/iq2000/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for newlib 3.0.0. +# Generated by GNU Autoconf 2.68 for newlib 3.1.0. # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -556,8 +556,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='newlib' PACKAGE_TARNAME='newlib' -PACKAGE_VERSION='3.0.0' -PACKAGE_STRING='newlib 3.0.0' +PACKAGE_VERSION='3.1.0' +PACKAGE_STRING='newlib 3.1.0' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1240,7 +1240,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures newlib 3.0.0 to adapt to many kinds of systems. +\`configure' configures newlib 3.1.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1310,7 +1310,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of newlib 3.0.0:";; + short | recursive ) echo "Configuration of newlib 3.1.0:";; esac cat <<\_ACEOF @@ -1402,7 +1402,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -newlib configure 3.0.0 +newlib configure 3.1.0 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -1457,7 +1457,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by newlib $as_me 3.0.0, which was +It was created by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -2541,7 +2541,7 @@ fi # Define the identity of the package. PACKAGE='newlib' - VERSION='3.0.0' + VERSION='3.1.0' # Some tools Automake needs. @@ -4025,7 +4025,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by newlib $as_me 3.0.0, which was +This file was extended by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -4082,7 +4082,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -newlib config.status 3.0.0 +newlib config.status 3.1.0 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" diff --git a/newlib/libc/machine/lm32/configure b/newlib/libc/machine/lm32/configure index 083cd071c..35078c605 100755 --- a/newlib/libc/machine/lm32/configure +++ b/newlib/libc/machine/lm32/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for newlib 3.0.0. +# Generated by GNU Autoconf 2.68 for newlib 3.1.0. # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -556,8 +556,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='newlib' PACKAGE_TARNAME='newlib' -PACKAGE_VERSION='3.0.0' -PACKAGE_STRING='newlib 3.0.0' +PACKAGE_VERSION='3.1.0' +PACKAGE_STRING='newlib 3.1.0' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1240,7 +1240,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures newlib 3.0.0 to adapt to many kinds of systems. +\`configure' configures newlib 3.1.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1310,7 +1310,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of newlib 3.0.0:";; + short | recursive ) echo "Configuration of newlib 3.1.0:";; esac cat <<\_ACEOF @@ -1402,7 +1402,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -newlib configure 3.0.0 +newlib configure 3.1.0 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -1457,7 +1457,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by newlib $as_me 3.0.0, which was +It was created by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -2541,7 +2541,7 @@ fi # Define the identity of the package. PACKAGE='newlib' - VERSION='3.0.0' + VERSION='3.1.0' # Some tools Automake needs. @@ -4025,7 +4025,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by newlib $as_me 3.0.0, which was +This file was extended by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -4082,7 +4082,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -newlib config.status 3.0.0 +newlib config.status 3.1.0 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" diff --git a/newlib/libc/machine/m32c/configure b/newlib/libc/machine/m32c/configure index 083cd071c..35078c605 100755 --- a/newlib/libc/machine/m32c/configure +++ b/newlib/libc/machine/m32c/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for newlib 3.0.0. +# Generated by GNU Autoconf 2.68 for newlib 3.1.0. # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -556,8 +556,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='newlib' PACKAGE_TARNAME='newlib' -PACKAGE_VERSION='3.0.0' -PACKAGE_STRING='newlib 3.0.0' +PACKAGE_VERSION='3.1.0' +PACKAGE_STRING='newlib 3.1.0' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1240,7 +1240,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures newlib 3.0.0 to adapt to many kinds of systems. +\`configure' configures newlib 3.1.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1310,7 +1310,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of newlib 3.0.0:";; + short | recursive ) echo "Configuration of newlib 3.1.0:";; esac cat <<\_ACEOF @@ -1402,7 +1402,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -newlib configure 3.0.0 +newlib configure 3.1.0 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -1457,7 +1457,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by newlib $as_me 3.0.0, which was +It was created by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -2541,7 +2541,7 @@ fi # Define the identity of the package. PACKAGE='newlib' - VERSION='3.0.0' + VERSION='3.1.0' # Some tools Automake needs. @@ -4025,7 +4025,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by newlib $as_me 3.0.0, which was +This file was extended by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -4082,7 +4082,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -newlib config.status 3.0.0 +newlib config.status 3.1.0 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" diff --git a/newlib/libc/machine/m32r/configure b/newlib/libc/machine/m32r/configure index 083cd071c..35078c605 100755 --- a/newlib/libc/machine/m32r/configure +++ b/newlib/libc/machine/m32r/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for newlib 3.0.0. +# Generated by GNU Autoconf 2.68 for newlib 3.1.0. # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -556,8 +556,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='newlib' PACKAGE_TARNAME='newlib' -PACKAGE_VERSION='3.0.0' -PACKAGE_STRING='newlib 3.0.0' +PACKAGE_VERSION='3.1.0' +PACKAGE_STRING='newlib 3.1.0' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1240,7 +1240,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures newlib 3.0.0 to adapt to many kinds of systems. +\`configure' configures newlib 3.1.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1310,7 +1310,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of newlib 3.0.0:";; + short | recursive ) echo "Configuration of newlib 3.1.0:";; esac cat <<\_ACEOF @@ -1402,7 +1402,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -newlib configure 3.0.0 +newlib configure 3.1.0 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -1457,7 +1457,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by newlib $as_me 3.0.0, which was +It was created by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -2541,7 +2541,7 @@ fi # Define the identity of the package. PACKAGE='newlib' - VERSION='3.0.0' + VERSION='3.1.0' # Some tools Automake needs. @@ -4025,7 +4025,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by newlib $as_me 3.0.0, which was +This file was extended by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -4082,7 +4082,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -newlib config.status 3.0.0 +newlib config.status 3.1.0 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" diff --git a/newlib/libc/machine/m68hc11/configure b/newlib/libc/machine/m68hc11/configure index 083cd071c..35078c605 100755 --- a/newlib/libc/machine/m68hc11/configure +++ b/newlib/libc/machine/m68hc11/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for newlib 3.0.0. +# Generated by GNU Autoconf 2.68 for newlib 3.1.0. # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -556,8 +556,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='newlib' PACKAGE_TARNAME='newlib' -PACKAGE_VERSION='3.0.0' -PACKAGE_STRING='newlib 3.0.0' +PACKAGE_VERSION='3.1.0' +PACKAGE_STRING='newlib 3.1.0' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1240,7 +1240,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures newlib 3.0.0 to adapt to many kinds of systems. +\`configure' configures newlib 3.1.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1310,7 +1310,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of newlib 3.0.0:";; + short | recursive ) echo "Configuration of newlib 3.1.0:";; esac cat <<\_ACEOF @@ -1402,7 +1402,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -newlib configure 3.0.0 +newlib configure 3.1.0 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -1457,7 +1457,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by newlib $as_me 3.0.0, which was +It was created by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -2541,7 +2541,7 @@ fi # Define the identity of the package. PACKAGE='newlib' - VERSION='3.0.0' + VERSION='3.1.0' # Some tools Automake needs. @@ -4025,7 +4025,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by newlib $as_me 3.0.0, which was +This file was extended by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -4082,7 +4082,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -newlib config.status 3.0.0 +newlib config.status 3.1.0 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" diff --git a/newlib/libc/machine/m68k/configure b/newlib/libc/machine/m68k/configure index 083cd071c..35078c605 100755 --- a/newlib/libc/machine/m68k/configure +++ b/newlib/libc/machine/m68k/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for newlib 3.0.0. +# Generated by GNU Autoconf 2.68 for newlib 3.1.0. # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -556,8 +556,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='newlib' PACKAGE_TARNAME='newlib' -PACKAGE_VERSION='3.0.0' -PACKAGE_STRING='newlib 3.0.0' +PACKAGE_VERSION='3.1.0' +PACKAGE_STRING='newlib 3.1.0' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1240,7 +1240,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures newlib 3.0.0 to adapt to many kinds of systems. +\`configure' configures newlib 3.1.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1310,7 +1310,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of newlib 3.0.0:";; + short | recursive ) echo "Configuration of newlib 3.1.0:";; esac cat <<\_ACEOF @@ -1402,7 +1402,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -newlib configure 3.0.0 +newlib configure 3.1.0 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -1457,7 +1457,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by newlib $as_me 3.0.0, which was +It was created by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -2541,7 +2541,7 @@ fi # Define the identity of the package. PACKAGE='newlib' - VERSION='3.0.0' + VERSION='3.1.0' # Some tools Automake needs. @@ -4025,7 +4025,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by newlib $as_me 3.0.0, which was +This file was extended by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -4082,7 +4082,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -newlib config.status 3.0.0 +newlib config.status 3.1.0 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" diff --git a/newlib/libc/machine/m88k/configure b/newlib/libc/machine/m88k/configure index 083cd071c..35078c605 100755 --- a/newlib/libc/machine/m88k/configure +++ b/newlib/libc/machine/m88k/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for newlib 3.0.0. +# Generated by GNU Autoconf 2.68 for newlib 3.1.0. # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -556,8 +556,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='newlib' PACKAGE_TARNAME='newlib' -PACKAGE_VERSION='3.0.0' -PACKAGE_STRING='newlib 3.0.0' +PACKAGE_VERSION='3.1.0' +PACKAGE_STRING='newlib 3.1.0' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1240,7 +1240,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures newlib 3.0.0 to adapt to many kinds of systems. +\`configure' configures newlib 3.1.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1310,7 +1310,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of newlib 3.0.0:";; + short | recursive ) echo "Configuration of newlib 3.1.0:";; esac cat <<\_ACEOF @@ -1402,7 +1402,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -newlib configure 3.0.0 +newlib configure 3.1.0 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -1457,7 +1457,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by newlib $as_me 3.0.0, which was +It was created by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -2541,7 +2541,7 @@ fi # Define the identity of the package. PACKAGE='newlib' - VERSION='3.0.0' + VERSION='3.1.0' # Some tools Automake needs. @@ -4025,7 +4025,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by newlib $as_me 3.0.0, which was +This file was extended by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -4082,7 +4082,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -newlib config.status 3.0.0 +newlib config.status 3.1.0 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" diff --git a/newlib/libc/machine/mep/configure b/newlib/libc/machine/mep/configure index 6a6ad6044..24feba10f 100755 --- a/newlib/libc/machine/mep/configure +++ b/newlib/libc/machine/mep/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for newlib 3.0.0. +# Generated by GNU Autoconf 2.68 for newlib 3.1.0. # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -556,8 +556,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='newlib' PACKAGE_TARNAME='newlib' -PACKAGE_VERSION='3.0.0' -PACKAGE_STRING='newlib 3.0.0' +PACKAGE_VERSION='3.1.0' +PACKAGE_STRING='newlib 3.1.0' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1240,7 +1240,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures newlib 3.0.0 to adapt to many kinds of systems. +\`configure' configures newlib 3.1.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1310,7 +1310,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of newlib 3.0.0:";; + short | recursive ) echo "Configuration of newlib 3.1.0:";; esac cat <<\_ACEOF @@ -1402,7 +1402,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -newlib configure 3.0.0 +newlib configure 3.1.0 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -1457,7 +1457,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by newlib $as_me 3.0.0, which was +It was created by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -2541,7 +2541,7 @@ fi # Define the identity of the package. PACKAGE='newlib' - VERSION='3.0.0' + VERSION='3.1.0' # Some tools Automake needs. @@ -4025,7 +4025,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by newlib $as_me 3.0.0, which was +This file was extended by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -4082,7 +4082,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -newlib config.status 3.0.0 +newlib config.status 3.1.0 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" diff --git a/newlib/libc/machine/microblaze/configure b/newlib/libc/machine/microblaze/configure index 7ac546442..0968417d5 100644 --- a/newlib/libc/machine/microblaze/configure +++ b/newlib/libc/machine/microblaze/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for newlib 3.0.0. +# Generated by GNU Autoconf 2.68 for newlib 3.1.0. # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -556,8 +556,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='newlib' PACKAGE_TARNAME='newlib' -PACKAGE_VERSION='3.0.0' -PACKAGE_STRING='newlib 3.0.0' +PACKAGE_VERSION='3.1.0' +PACKAGE_STRING='newlib 3.1.0' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1240,7 +1240,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures newlib 3.0.0 to adapt to many kinds of systems. +\`configure' configures newlib 3.1.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1310,7 +1310,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of newlib 3.0.0:";; + short | recursive ) echo "Configuration of newlib 3.1.0:";; esac cat <<\_ACEOF @@ -1402,7 +1402,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -newlib configure 3.0.0 +newlib configure 3.1.0 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -1457,7 +1457,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by newlib $as_me 3.0.0, which was +It was created by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -2541,7 +2541,7 @@ fi # Define the identity of the package. PACKAGE='newlib' - VERSION='3.0.0' + VERSION='3.1.0' # Some tools Automake needs. @@ -4025,7 +4025,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by newlib $as_me 3.0.0, which was +This file was extended by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -4082,7 +4082,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -newlib config.status 3.0.0 +newlib config.status 3.1.0 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" diff --git a/newlib/libc/machine/mips/configure b/newlib/libc/machine/mips/configure index 083cd071c..35078c605 100755 --- a/newlib/libc/machine/mips/configure +++ b/newlib/libc/machine/mips/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for newlib 3.0.0. +# Generated by GNU Autoconf 2.68 for newlib 3.1.0. # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -556,8 +556,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='newlib' PACKAGE_TARNAME='newlib' -PACKAGE_VERSION='3.0.0' -PACKAGE_STRING='newlib 3.0.0' +PACKAGE_VERSION='3.1.0' +PACKAGE_STRING='newlib 3.1.0' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1240,7 +1240,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures newlib 3.0.0 to adapt to many kinds of systems. +\`configure' configures newlib 3.1.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1310,7 +1310,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of newlib 3.0.0:";; + short | recursive ) echo "Configuration of newlib 3.1.0:";; esac cat <<\_ACEOF @@ -1402,7 +1402,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -newlib configure 3.0.0 +newlib configure 3.1.0 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -1457,7 +1457,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by newlib $as_me 3.0.0, which was +It was created by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -2541,7 +2541,7 @@ fi # Define the identity of the package. PACKAGE='newlib' - VERSION='3.0.0' + VERSION='3.1.0' # Some tools Automake needs. @@ -4025,7 +4025,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by newlib $as_me 3.0.0, which was +This file was extended by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -4082,7 +4082,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -newlib config.status 3.0.0 +newlib config.status 3.1.0 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" diff --git a/newlib/libc/machine/mn10200/configure b/newlib/libc/machine/mn10200/configure index 083cd071c..35078c605 100755 --- a/newlib/libc/machine/mn10200/configure +++ b/newlib/libc/machine/mn10200/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for newlib 3.0.0. +# Generated by GNU Autoconf 2.68 for newlib 3.1.0. # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -556,8 +556,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='newlib' PACKAGE_TARNAME='newlib' -PACKAGE_VERSION='3.0.0' -PACKAGE_STRING='newlib 3.0.0' +PACKAGE_VERSION='3.1.0' +PACKAGE_STRING='newlib 3.1.0' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1240,7 +1240,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures newlib 3.0.0 to adapt to many kinds of systems. +\`configure' configures newlib 3.1.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1310,7 +1310,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of newlib 3.0.0:";; + short | recursive ) echo "Configuration of newlib 3.1.0:";; esac cat <<\_ACEOF @@ -1402,7 +1402,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -newlib configure 3.0.0 +newlib configure 3.1.0 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -1457,7 +1457,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by newlib $as_me 3.0.0, which was +It was created by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -2541,7 +2541,7 @@ fi # Define the identity of the package. PACKAGE='newlib' - VERSION='3.0.0' + VERSION='3.1.0' # Some tools Automake needs. @@ -4025,7 +4025,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by newlib $as_me 3.0.0, which was +This file was extended by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -4082,7 +4082,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -newlib config.status 3.0.0 +newlib config.status 3.1.0 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" diff --git a/newlib/libc/machine/mn10300/configure b/newlib/libc/machine/mn10300/configure index 2b8a77c57..aea4a2920 100755 --- a/newlib/libc/machine/mn10300/configure +++ b/newlib/libc/machine/mn10300/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for newlib 3.0.0. +# Generated by GNU Autoconf 2.68 for newlib 3.1.0. # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -556,8 +556,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='newlib' PACKAGE_TARNAME='newlib' -PACKAGE_VERSION='3.0.0' -PACKAGE_STRING='newlib 3.0.0' +PACKAGE_VERSION='3.1.0' +PACKAGE_STRING='newlib 3.1.0' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1240,7 +1240,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures newlib 3.0.0 to adapt to many kinds of systems. +\`configure' configures newlib 3.1.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1310,7 +1310,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of newlib 3.0.0:";; + short | recursive ) echo "Configuration of newlib 3.1.0:";; esac cat <<\_ACEOF @@ -1402,7 +1402,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -newlib configure 3.0.0 +newlib configure 3.1.0 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -1457,7 +1457,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by newlib $as_me 3.0.0, which was +It was created by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -2541,7 +2541,7 @@ fi # Define the identity of the package. PACKAGE='newlib' - VERSION='3.0.0' + VERSION='3.1.0' # Some tools Automake needs. @@ -4025,7 +4025,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by newlib $as_me 3.0.0, which was +This file was extended by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -4082,7 +4082,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -newlib config.status 3.0.0 +newlib config.status 3.1.0 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" diff --git a/newlib/libc/machine/moxie/configure b/newlib/libc/machine/moxie/configure index 6a6ad6044..24feba10f 100644 --- a/newlib/libc/machine/moxie/configure +++ b/newlib/libc/machine/moxie/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for newlib 3.0.0. +# Generated by GNU Autoconf 2.68 for newlib 3.1.0. # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -556,8 +556,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='newlib' PACKAGE_TARNAME='newlib' -PACKAGE_VERSION='3.0.0' -PACKAGE_STRING='newlib 3.0.0' +PACKAGE_VERSION='3.1.0' +PACKAGE_STRING='newlib 3.1.0' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1240,7 +1240,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures newlib 3.0.0 to adapt to many kinds of systems. +\`configure' configures newlib 3.1.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1310,7 +1310,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of newlib 3.0.0:";; + short | recursive ) echo "Configuration of newlib 3.1.0:";; esac cat <<\_ACEOF @@ -1402,7 +1402,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -newlib configure 3.0.0 +newlib configure 3.1.0 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -1457,7 +1457,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by newlib $as_me 3.0.0, which was +It was created by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -2541,7 +2541,7 @@ fi # Define the identity of the package. PACKAGE='newlib' - VERSION='3.0.0' + VERSION='3.1.0' # Some tools Automake needs. @@ -4025,7 +4025,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by newlib $as_me 3.0.0, which was +This file was extended by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -4082,7 +4082,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -newlib config.status 3.0.0 +newlib config.status 3.1.0 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" diff --git a/newlib/libc/machine/msp430/configure b/newlib/libc/machine/msp430/configure index 083cd071c..35078c605 100755 --- a/newlib/libc/machine/msp430/configure +++ b/newlib/libc/machine/msp430/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for newlib 3.0.0. +# Generated by GNU Autoconf 2.68 for newlib 3.1.0. # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -556,8 +556,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='newlib' PACKAGE_TARNAME='newlib' -PACKAGE_VERSION='3.0.0' -PACKAGE_STRING='newlib 3.0.0' +PACKAGE_VERSION='3.1.0' +PACKAGE_STRING='newlib 3.1.0' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1240,7 +1240,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures newlib 3.0.0 to adapt to many kinds of systems. +\`configure' configures newlib 3.1.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1310,7 +1310,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of newlib 3.0.0:";; + short | recursive ) echo "Configuration of newlib 3.1.0:";; esac cat <<\_ACEOF @@ -1402,7 +1402,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -newlib configure 3.0.0 +newlib configure 3.1.0 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -1457,7 +1457,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by newlib $as_me 3.0.0, which was +It was created by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -2541,7 +2541,7 @@ fi # Define the identity of the package. PACKAGE='newlib' - VERSION='3.0.0' + VERSION='3.1.0' # Some tools Automake needs. @@ -4025,7 +4025,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by newlib $as_me 3.0.0, which was +This file was extended by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -4082,7 +4082,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -newlib config.status 3.0.0 +newlib config.status 3.1.0 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" diff --git a/newlib/libc/machine/mt/configure b/newlib/libc/machine/mt/configure index 6a6ad6044..24feba10f 100755 --- a/newlib/libc/machine/mt/configure +++ b/newlib/libc/machine/mt/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for newlib 3.0.0. +# Generated by GNU Autoconf 2.68 for newlib 3.1.0. # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -556,8 +556,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='newlib' PACKAGE_TARNAME='newlib' -PACKAGE_VERSION='3.0.0' -PACKAGE_STRING='newlib 3.0.0' +PACKAGE_VERSION='3.1.0' +PACKAGE_STRING='newlib 3.1.0' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1240,7 +1240,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures newlib 3.0.0 to adapt to many kinds of systems. +\`configure' configures newlib 3.1.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1310,7 +1310,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of newlib 3.0.0:";; + short | recursive ) echo "Configuration of newlib 3.1.0:";; esac cat <<\_ACEOF @@ -1402,7 +1402,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -newlib configure 3.0.0 +newlib configure 3.1.0 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -1457,7 +1457,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by newlib $as_me 3.0.0, which was +It was created by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -2541,7 +2541,7 @@ fi # Define the identity of the package. PACKAGE='newlib' - VERSION='3.0.0' + VERSION='3.1.0' # Some tools Automake needs. @@ -4025,7 +4025,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by newlib $as_me 3.0.0, which was +This file was extended by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -4082,7 +4082,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -newlib config.status 3.0.0 +newlib config.status 3.1.0 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" diff --git a/newlib/libc/machine/nds32/configure b/newlib/libc/machine/nds32/configure index fb3b7a9ea..67aec061c 100755 --- a/newlib/libc/machine/nds32/configure +++ b/newlib/libc/machine/nds32/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for newlib 3.0.0. +# Generated by GNU Autoconf 2.68 for newlib 3.1.0. # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -556,8 +556,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='newlib' PACKAGE_TARNAME='newlib' -PACKAGE_VERSION='3.0.0' -PACKAGE_STRING='newlib 3.0.0' +PACKAGE_VERSION='3.1.0' +PACKAGE_STRING='newlib 3.1.0' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1254,7 +1254,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures newlib 3.0.0 to adapt to many kinds of systems. +\`configure' configures newlib 3.1.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1324,7 +1324,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of newlib 3.0.0:";; + short | recursive ) echo "Configuration of newlib 3.1.0:";; esac cat <<\_ACEOF @@ -1423,7 +1423,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -newlib configure 3.0.0 +newlib configure 3.1.0 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -1478,7 +1478,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by newlib $as_me 3.0.0, which was +It was created by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -2562,7 +2562,7 @@ fi # Define the identity of the package. PACKAGE='newlib' - VERSION='3.0.0' + VERSION='3.1.0' # Some tools Automake needs. @@ -5087,7 +5087,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by newlib $as_me 3.0.0, which was +This file was extended by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -5144,7 +5144,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -newlib config.status 3.0.0 +newlib config.status 3.1.0 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" diff --git a/newlib/libc/machine/necv70/configure b/newlib/libc/machine/necv70/configure index a45a4592f..70be4266b 100755 --- a/newlib/libc/machine/necv70/configure +++ b/newlib/libc/machine/necv70/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for newlib 3.0.0. +# Generated by GNU Autoconf 2.68 for newlib 3.1.0. # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -556,8 +556,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='newlib' PACKAGE_TARNAME='newlib' -PACKAGE_VERSION='3.0.0' -PACKAGE_STRING='newlib 3.0.0' +PACKAGE_VERSION='3.1.0' +PACKAGE_STRING='newlib 3.1.0' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1240,7 +1240,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures newlib 3.0.0 to adapt to many kinds of systems. +\`configure' configures newlib 3.1.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1310,7 +1310,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of newlib 3.0.0:";; + short | recursive ) echo "Configuration of newlib 3.1.0:";; esac cat <<\_ACEOF @@ -1402,7 +1402,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -newlib configure 3.0.0 +newlib configure 3.1.0 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -1457,7 +1457,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by newlib $as_me 3.0.0, which was +It was created by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -2541,7 +2541,7 @@ fi # Define the identity of the package. PACKAGE='newlib' - VERSION='3.0.0' + VERSION='3.1.0' # Some tools Automake needs. @@ -4025,7 +4025,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by newlib $as_me 3.0.0, which was +This file was extended by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -4082,7 +4082,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -newlib config.status 3.0.0 +newlib config.status 3.1.0 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" diff --git a/newlib/libc/machine/nios2/configure b/newlib/libc/machine/nios2/configure index 762b15336..e6fb5c02f 100755 --- a/newlib/libc/machine/nios2/configure +++ b/newlib/libc/machine/nios2/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for newlib 3.0.0. +# Generated by GNU Autoconf 2.68 for newlib 3.1.0. # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -556,8 +556,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='newlib' PACKAGE_TARNAME='newlib' -PACKAGE_VERSION='3.0.0' -PACKAGE_STRING='newlib 3.0.0' +PACKAGE_VERSION='3.1.0' +PACKAGE_STRING='newlib 3.1.0' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1240,7 +1240,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures newlib 3.0.0 to adapt to many kinds of systems. +\`configure' configures newlib 3.1.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1310,7 +1310,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of newlib 3.0.0:";; + short | recursive ) echo "Configuration of newlib 3.1.0:";; esac cat <<\_ACEOF @@ -1402,7 +1402,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -newlib configure 3.0.0 +newlib configure 3.1.0 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -1457,7 +1457,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by newlib $as_me 3.0.0, which was +It was created by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -2541,7 +2541,7 @@ fi # Define the identity of the package. PACKAGE='newlib' - VERSION='3.0.0' + VERSION='3.1.0' # Some tools Automake needs. @@ -4025,7 +4025,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by newlib $as_me 3.0.0, which was +This file was extended by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -4082,7 +4082,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -newlib config.status 3.0.0 +newlib config.status 3.1.0 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" diff --git a/newlib/libc/machine/nvptx/configure b/newlib/libc/machine/nvptx/configure index 6a6ad6044..24feba10f 100644 --- a/newlib/libc/machine/nvptx/configure +++ b/newlib/libc/machine/nvptx/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for newlib 3.0.0. +# Generated by GNU Autoconf 2.68 for newlib 3.1.0. # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -556,8 +556,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='newlib' PACKAGE_TARNAME='newlib' -PACKAGE_VERSION='3.0.0' -PACKAGE_STRING='newlib 3.0.0' +PACKAGE_VERSION='3.1.0' +PACKAGE_STRING='newlib 3.1.0' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1240,7 +1240,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures newlib 3.0.0 to adapt to many kinds of systems. +\`configure' configures newlib 3.1.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1310,7 +1310,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of newlib 3.0.0:";; + short | recursive ) echo "Configuration of newlib 3.1.0:";; esac cat <<\_ACEOF @@ -1402,7 +1402,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -newlib configure 3.0.0 +newlib configure 3.1.0 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -1457,7 +1457,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by newlib $as_me 3.0.0, which was +It was created by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -2541,7 +2541,7 @@ fi # Define the identity of the package. PACKAGE='newlib' - VERSION='3.0.0' + VERSION='3.1.0' # Some tools Automake needs. @@ -4025,7 +4025,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by newlib $as_me 3.0.0, which was +This file was extended by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -4082,7 +4082,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -newlib config.status 3.0.0 +newlib config.status 3.1.0 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" diff --git a/newlib/libc/machine/or1k/configure b/newlib/libc/machine/or1k/configure index 6a6ad6044..24feba10f 100755 --- a/newlib/libc/machine/or1k/configure +++ b/newlib/libc/machine/or1k/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for newlib 3.0.0. +# Generated by GNU Autoconf 2.68 for newlib 3.1.0. # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -556,8 +556,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='newlib' PACKAGE_TARNAME='newlib' -PACKAGE_VERSION='3.0.0' -PACKAGE_STRING='newlib 3.0.0' +PACKAGE_VERSION='3.1.0' +PACKAGE_STRING='newlib 3.1.0' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1240,7 +1240,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures newlib 3.0.0 to adapt to many kinds of systems. +\`configure' configures newlib 3.1.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1310,7 +1310,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of newlib 3.0.0:";; + short | recursive ) echo "Configuration of newlib 3.1.0:";; esac cat <<\_ACEOF @@ -1402,7 +1402,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -newlib configure 3.0.0 +newlib configure 3.1.0 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -1457,7 +1457,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by newlib $as_me 3.0.0, which was +It was created by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -2541,7 +2541,7 @@ fi # Define the identity of the package. PACKAGE='newlib' - VERSION='3.0.0' + VERSION='3.1.0' # Some tools Automake needs. @@ -4025,7 +4025,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by newlib $as_me 3.0.0, which was +This file was extended by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -4082,7 +4082,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -newlib config.status 3.0.0 +newlib config.status 3.1.0 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" diff --git a/newlib/libc/machine/powerpc/configure b/newlib/libc/machine/powerpc/configure index 1e98a3107..d9185ea1e 100755 --- a/newlib/libc/machine/powerpc/configure +++ b/newlib/libc/machine/powerpc/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for newlib 3.0.0. +# Generated by GNU Autoconf 2.68 for newlib 3.1.0. # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -556,8 +556,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='newlib' PACKAGE_TARNAME='newlib' -PACKAGE_VERSION='3.0.0' -PACKAGE_STRING='newlib 3.0.0' +PACKAGE_VERSION='3.1.0' +PACKAGE_STRING='newlib 3.1.0' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1241,7 +1241,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures newlib 3.0.0 to adapt to many kinds of systems. +\`configure' configures newlib 3.1.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1311,7 +1311,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of newlib 3.0.0:";; + short | recursive ) echo "Configuration of newlib 3.1.0:";; esac cat <<\_ACEOF @@ -1403,7 +1403,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -newlib configure 3.0.0 +newlib configure 3.1.0 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -1458,7 +1458,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by newlib $as_me 3.0.0, which was +It was created by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -2542,7 +2542,7 @@ fi # Define the identity of the package. PACKAGE='newlib' - VERSION='3.0.0' + VERSION='3.1.0' # Some tools Automake needs. @@ -4037,7 +4037,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by newlib $as_me 3.0.0, which was +This file was extended by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -4094,7 +4094,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -newlib config.status 3.0.0 +newlib config.status 3.1.0 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" diff --git a/newlib/libc/machine/riscv/configure b/newlib/libc/machine/riscv/configure index 0b9d601de..3b9f2df40 100755 --- a/newlib/libc/machine/riscv/configure +++ b/newlib/libc/machine/riscv/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for newlib 3.0.0. +# Generated by GNU Autoconf 2.68 for newlib 3.1.0. # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -556,8 +556,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='newlib' PACKAGE_TARNAME='newlib' -PACKAGE_VERSION='3.0.0' -PACKAGE_STRING='newlib 3.0.0' +PACKAGE_VERSION='3.1.0' +PACKAGE_STRING='newlib 3.1.0' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1240,7 +1240,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures newlib 3.0.0 to adapt to many kinds of systems. +\`configure' configures newlib 3.1.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1310,7 +1310,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of newlib 3.0.0:";; + short | recursive ) echo "Configuration of newlib 3.1.0:";; esac cat <<\_ACEOF @@ -1402,7 +1402,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -newlib configure 3.0.0 +newlib configure 3.1.0 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -1457,7 +1457,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by newlib $as_me 3.0.0, which was +It was created by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -2541,7 +2541,7 @@ fi # Define the identity of the package. PACKAGE='newlib' - VERSION='3.0.0' + VERSION='3.1.0' # Some tools Automake needs. @@ -4025,7 +4025,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by newlib $as_me 3.0.0, which was +This file was extended by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -4082,7 +4082,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -newlib config.status 3.0.0 +newlib config.status 3.1.0 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" diff --git a/newlib/libc/machine/rl78/configure b/newlib/libc/machine/rl78/configure index 083cd071c..35078c605 100755 --- a/newlib/libc/machine/rl78/configure +++ b/newlib/libc/machine/rl78/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for newlib 3.0.0. +# Generated by GNU Autoconf 2.68 for newlib 3.1.0. # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -556,8 +556,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='newlib' PACKAGE_TARNAME='newlib' -PACKAGE_VERSION='3.0.0' -PACKAGE_STRING='newlib 3.0.0' +PACKAGE_VERSION='3.1.0' +PACKAGE_STRING='newlib 3.1.0' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1240,7 +1240,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures newlib 3.0.0 to adapt to many kinds of systems. +\`configure' configures newlib 3.1.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1310,7 +1310,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of newlib 3.0.0:";; + short | recursive ) echo "Configuration of newlib 3.1.0:";; esac cat <<\_ACEOF @@ -1402,7 +1402,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -newlib configure 3.0.0 +newlib configure 3.1.0 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -1457,7 +1457,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by newlib $as_me 3.0.0, which was +It was created by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -2541,7 +2541,7 @@ fi # Define the identity of the package. PACKAGE='newlib' - VERSION='3.0.0' + VERSION='3.1.0' # Some tools Automake needs. @@ -4025,7 +4025,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by newlib $as_me 3.0.0, which was +This file was extended by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -4082,7 +4082,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -newlib config.status 3.0.0 +newlib config.status 3.1.0 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" diff --git a/newlib/libc/machine/rx/configure b/newlib/libc/machine/rx/configure index 6a6ad6044..24feba10f 100755 --- a/newlib/libc/machine/rx/configure +++ b/newlib/libc/machine/rx/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for newlib 3.0.0. +# Generated by GNU Autoconf 2.68 for newlib 3.1.0. # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -556,8 +556,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='newlib' PACKAGE_TARNAME='newlib' -PACKAGE_VERSION='3.0.0' -PACKAGE_STRING='newlib 3.0.0' +PACKAGE_VERSION='3.1.0' +PACKAGE_STRING='newlib 3.1.0' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1240,7 +1240,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures newlib 3.0.0 to adapt to many kinds of systems. +\`configure' configures newlib 3.1.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1310,7 +1310,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of newlib 3.0.0:";; + short | recursive ) echo "Configuration of newlib 3.1.0:";; esac cat <<\_ACEOF @@ -1402,7 +1402,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -newlib configure 3.0.0 +newlib configure 3.1.0 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -1457,7 +1457,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by newlib $as_me 3.0.0, which was +It was created by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -2541,7 +2541,7 @@ fi # Define the identity of the package. PACKAGE='newlib' - VERSION='3.0.0' + VERSION='3.1.0' # Some tools Automake needs. @@ -4025,7 +4025,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by newlib $as_me 3.0.0, which was +This file was extended by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -4082,7 +4082,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -newlib config.status 3.0.0 +newlib config.status 3.1.0 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" diff --git a/newlib/libc/machine/sh/configure b/newlib/libc/machine/sh/configure index fccf05913..7722e18cd 100755 --- a/newlib/libc/machine/sh/configure +++ b/newlib/libc/machine/sh/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for newlib 3.0.0. +# Generated by GNU Autoconf 2.68 for newlib 3.1.0. # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -557,8 +557,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='newlib' PACKAGE_TARNAME='newlib' -PACKAGE_VERSION='3.0.0' -PACKAGE_STRING='newlib 3.0.0' +PACKAGE_VERSION='3.1.0' +PACKAGE_STRING='newlib 3.1.0' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1259,7 +1259,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures newlib 3.0.0 to adapt to many kinds of systems. +\`configure' configures newlib 3.1.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1329,7 +1329,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of newlib 3.0.0:";; + short | recursive ) echo "Configuration of newlib 3.1.0:";; esac cat <<\_ACEOF @@ -1429,7 +1429,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -newlib configure 3.0.0 +newlib configure 3.1.0 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -1521,7 +1521,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by newlib $as_me 3.0.0, which was +It was created by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -2607,7 +2607,7 @@ fi # Define the identity of the package. PACKAGE='newlib' - VERSION='3.0.0' + VERSION='3.1.0' # Some tools Automake needs. @@ -5394,7 +5394,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by newlib $as_me 3.0.0, which was +This file was extended by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -5451,7 +5451,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -newlib config.status 3.0.0 +newlib config.status 3.1.0 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" diff --git a/newlib/libc/machine/sparc/configure b/newlib/libc/machine/sparc/configure index b36fb2643..466049551 100755 --- a/newlib/libc/machine/sparc/configure +++ b/newlib/libc/machine/sparc/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for newlib 3.0.0. +# Generated by GNU Autoconf 2.68 for newlib 3.1.0. # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -556,8 +556,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='newlib' PACKAGE_TARNAME='newlib' -PACKAGE_VERSION='3.0.0' -PACKAGE_STRING='newlib 3.0.0' +PACKAGE_VERSION='3.1.0' +PACKAGE_STRING='newlib 3.1.0' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1240,7 +1240,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures newlib 3.0.0 to adapt to many kinds of systems. +\`configure' configures newlib 3.1.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1310,7 +1310,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of newlib 3.0.0:";; + short | recursive ) echo "Configuration of newlib 3.1.0:";; esac cat <<\_ACEOF @@ -1402,7 +1402,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -newlib configure 3.0.0 +newlib configure 3.1.0 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -1457,7 +1457,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by newlib $as_me 3.0.0, which was +It was created by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -2541,7 +2541,7 @@ fi # Define the identity of the package. PACKAGE='newlib' - VERSION='3.0.0' + VERSION='3.1.0' # Some tools Automake needs. @@ -4025,7 +4025,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by newlib $as_me 3.0.0, which was +This file was extended by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -4082,7 +4082,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -newlib config.status 3.0.0 +newlib config.status 3.1.0 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" diff --git a/newlib/libc/machine/spu/configure b/newlib/libc/machine/spu/configure index 86a29dabb..906f1773e 100644 --- a/newlib/libc/machine/spu/configure +++ b/newlib/libc/machine/spu/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for newlib 3.0.0. +# Generated by GNU Autoconf 2.68 for newlib 3.1.0. # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -556,8 +556,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='newlib' PACKAGE_TARNAME='newlib' -PACKAGE_VERSION='3.0.0' -PACKAGE_STRING='newlib 3.0.0' +PACKAGE_VERSION='3.1.0' +PACKAGE_STRING='newlib 3.1.0' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1242,7 +1242,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures newlib 3.0.0 to adapt to many kinds of systems. +\`configure' configures newlib 3.1.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1312,7 +1312,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of newlib 3.0.0:";; + short | recursive ) echo "Configuration of newlib 3.1.0:";; esac cat <<\_ACEOF @@ -1404,7 +1404,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -newlib configure 3.0.0 +newlib configure 3.1.0 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -1459,7 +1459,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by newlib $as_me 3.0.0, which was +It was created by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -2543,7 +2543,7 @@ fi # Define the identity of the package. PACKAGE='newlib' - VERSION='3.0.0' + VERSION='3.1.0' # Some tools Automake needs. @@ -4059,7 +4059,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by newlib $as_me 3.0.0, which was +This file was extended by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -4116,7 +4116,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -newlib config.status 3.0.0 +newlib config.status 3.1.0 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" diff --git a/newlib/libc/machine/tic4x/configure b/newlib/libc/machine/tic4x/configure index 083cd071c..35078c605 100755 --- a/newlib/libc/machine/tic4x/configure +++ b/newlib/libc/machine/tic4x/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for newlib 3.0.0. +# Generated by GNU Autoconf 2.68 for newlib 3.1.0. # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -556,8 +556,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='newlib' PACKAGE_TARNAME='newlib' -PACKAGE_VERSION='3.0.0' -PACKAGE_STRING='newlib 3.0.0' +PACKAGE_VERSION='3.1.0' +PACKAGE_STRING='newlib 3.1.0' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1240,7 +1240,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures newlib 3.0.0 to adapt to many kinds of systems. +\`configure' configures newlib 3.1.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1310,7 +1310,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of newlib 3.0.0:";; + short | recursive ) echo "Configuration of newlib 3.1.0:";; esac cat <<\_ACEOF @@ -1402,7 +1402,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -newlib configure 3.0.0 +newlib configure 3.1.0 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -1457,7 +1457,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by newlib $as_me 3.0.0, which was +It was created by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -2541,7 +2541,7 @@ fi # Define the identity of the package. PACKAGE='newlib' - VERSION='3.0.0' + VERSION='3.1.0' # Some tools Automake needs. @@ -4025,7 +4025,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by newlib $as_me 3.0.0, which was +This file was extended by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -4082,7 +4082,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -newlib config.status 3.0.0 +newlib config.status 3.1.0 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" diff --git a/newlib/libc/machine/tic6x/configure b/newlib/libc/machine/tic6x/configure index 083cd071c..35078c605 100755 --- a/newlib/libc/machine/tic6x/configure +++ b/newlib/libc/machine/tic6x/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for newlib 3.0.0. +# Generated by GNU Autoconf 2.68 for newlib 3.1.0. # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -556,8 +556,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='newlib' PACKAGE_TARNAME='newlib' -PACKAGE_VERSION='3.0.0' -PACKAGE_STRING='newlib 3.0.0' +PACKAGE_VERSION='3.1.0' +PACKAGE_STRING='newlib 3.1.0' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1240,7 +1240,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures newlib 3.0.0 to adapt to many kinds of systems. +\`configure' configures newlib 3.1.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1310,7 +1310,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of newlib 3.0.0:";; + short | recursive ) echo "Configuration of newlib 3.1.0:";; esac cat <<\_ACEOF @@ -1402,7 +1402,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -newlib configure 3.0.0 +newlib configure 3.1.0 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -1457,7 +1457,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by newlib $as_me 3.0.0, which was +It was created by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -2541,7 +2541,7 @@ fi # Define the identity of the package. PACKAGE='newlib' - VERSION='3.0.0' + VERSION='3.1.0' # Some tools Automake needs. @@ -4025,7 +4025,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by newlib $as_me 3.0.0, which was +This file was extended by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -4082,7 +4082,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -newlib config.status 3.0.0 +newlib config.status 3.1.0 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" diff --git a/newlib/libc/machine/tic80/configure b/newlib/libc/machine/tic80/configure index 083cd071c..35078c605 100755 --- a/newlib/libc/machine/tic80/configure +++ b/newlib/libc/machine/tic80/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for newlib 3.0.0. +# Generated by GNU Autoconf 2.68 for newlib 3.1.0. # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -556,8 +556,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='newlib' PACKAGE_TARNAME='newlib' -PACKAGE_VERSION='3.0.0' -PACKAGE_STRING='newlib 3.0.0' +PACKAGE_VERSION='3.1.0' +PACKAGE_STRING='newlib 3.1.0' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1240,7 +1240,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures newlib 3.0.0 to adapt to many kinds of systems. +\`configure' configures newlib 3.1.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1310,7 +1310,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of newlib 3.0.0:";; + short | recursive ) echo "Configuration of newlib 3.1.0:";; esac cat <<\_ACEOF @@ -1402,7 +1402,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -newlib configure 3.0.0 +newlib configure 3.1.0 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -1457,7 +1457,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by newlib $as_me 3.0.0, which was +It was created by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -2541,7 +2541,7 @@ fi # Define the identity of the package. PACKAGE='newlib' - VERSION='3.0.0' + VERSION='3.1.0' # Some tools Automake needs. @@ -4025,7 +4025,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by newlib $as_me 3.0.0, which was +This file was extended by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -4082,7 +4082,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -newlib config.status 3.0.0 +newlib config.status 3.1.0 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" diff --git a/newlib/libc/machine/v850/configure b/newlib/libc/machine/v850/configure index 083cd071c..35078c605 100755 --- a/newlib/libc/machine/v850/configure +++ b/newlib/libc/machine/v850/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for newlib 3.0.0. +# Generated by GNU Autoconf 2.68 for newlib 3.1.0. # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -556,8 +556,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='newlib' PACKAGE_TARNAME='newlib' -PACKAGE_VERSION='3.0.0' -PACKAGE_STRING='newlib 3.0.0' +PACKAGE_VERSION='3.1.0' +PACKAGE_STRING='newlib 3.1.0' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1240,7 +1240,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures newlib 3.0.0 to adapt to many kinds of systems. +\`configure' configures newlib 3.1.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1310,7 +1310,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of newlib 3.0.0:";; + short | recursive ) echo "Configuration of newlib 3.1.0:";; esac cat <<\_ACEOF @@ -1402,7 +1402,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -newlib configure 3.0.0 +newlib configure 3.1.0 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -1457,7 +1457,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by newlib $as_me 3.0.0, which was +It was created by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -2541,7 +2541,7 @@ fi # Define the identity of the package. PACKAGE='newlib' - VERSION='3.0.0' + VERSION='3.1.0' # Some tools Automake needs. @@ -4025,7 +4025,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by newlib $as_me 3.0.0, which was +This file was extended by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -4082,7 +4082,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -newlib config.status 3.0.0 +newlib config.status 3.1.0 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" diff --git a/newlib/libc/machine/visium/configure b/newlib/libc/machine/visium/configure index 6a6ad6044..24feba10f 100755 --- a/newlib/libc/machine/visium/configure +++ b/newlib/libc/machine/visium/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for newlib 3.0.0. +# Generated by GNU Autoconf 2.68 for newlib 3.1.0. # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -556,8 +556,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='newlib' PACKAGE_TARNAME='newlib' -PACKAGE_VERSION='3.0.0' -PACKAGE_STRING='newlib 3.0.0' +PACKAGE_VERSION='3.1.0' +PACKAGE_STRING='newlib 3.1.0' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1240,7 +1240,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures newlib 3.0.0 to adapt to many kinds of systems. +\`configure' configures newlib 3.1.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1310,7 +1310,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of newlib 3.0.0:";; + short | recursive ) echo "Configuration of newlib 3.1.0:";; esac cat <<\_ACEOF @@ -1402,7 +1402,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -newlib configure 3.0.0 +newlib configure 3.1.0 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -1457,7 +1457,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by newlib $as_me 3.0.0, which was +It was created by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -2541,7 +2541,7 @@ fi # Define the identity of the package. PACKAGE='newlib' - VERSION='3.0.0' + VERSION='3.1.0' # Some tools Automake needs. @@ -4025,7 +4025,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by newlib $as_me 3.0.0, which was +This file was extended by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -4082,7 +4082,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -newlib config.status 3.0.0 +newlib config.status 3.1.0 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" diff --git a/newlib/libc/machine/w65/configure b/newlib/libc/machine/w65/configure index e475ddd1f..7106b2aca 100755 --- a/newlib/libc/machine/w65/configure +++ b/newlib/libc/machine/w65/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for newlib 3.0.0. +# Generated by GNU Autoconf 2.68 for newlib 3.1.0. # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -556,8 +556,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='newlib' PACKAGE_TARNAME='newlib' -PACKAGE_VERSION='3.0.0' -PACKAGE_STRING='newlib 3.0.0' +PACKAGE_VERSION='3.1.0' +PACKAGE_STRING='newlib 3.1.0' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1240,7 +1240,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures newlib 3.0.0 to adapt to many kinds of systems. +\`configure' configures newlib 3.1.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1310,7 +1310,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of newlib 3.0.0:";; + short | recursive ) echo "Configuration of newlib 3.1.0:";; esac cat <<\_ACEOF @@ -1402,7 +1402,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -newlib configure 3.0.0 +newlib configure 3.1.0 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -1457,7 +1457,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by newlib $as_me 3.0.0, which was +It was created by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -2541,7 +2541,7 @@ fi # Define the identity of the package. PACKAGE='newlib' - VERSION='3.0.0' + VERSION='3.1.0' # Some tools Automake needs. @@ -4025,7 +4025,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by newlib $as_me 3.0.0, which was +This file was extended by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -4082,7 +4082,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -newlib config.status 3.0.0 +newlib config.status 3.1.0 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" diff --git a/newlib/libc/machine/x86_64/configure b/newlib/libc/machine/x86_64/configure index 6a6ad6044..24feba10f 100755 --- a/newlib/libc/machine/x86_64/configure +++ b/newlib/libc/machine/x86_64/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for newlib 3.0.0. +# Generated by GNU Autoconf 2.68 for newlib 3.1.0. # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -556,8 +556,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='newlib' PACKAGE_TARNAME='newlib' -PACKAGE_VERSION='3.0.0' -PACKAGE_STRING='newlib 3.0.0' +PACKAGE_VERSION='3.1.0' +PACKAGE_STRING='newlib 3.1.0' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1240,7 +1240,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures newlib 3.0.0 to adapt to many kinds of systems. +\`configure' configures newlib 3.1.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1310,7 +1310,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of newlib 3.0.0:";; + short | recursive ) echo "Configuration of newlib 3.1.0:";; esac cat <<\_ACEOF @@ -1402,7 +1402,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -newlib configure 3.0.0 +newlib configure 3.1.0 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -1457,7 +1457,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by newlib $as_me 3.0.0, which was +It was created by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -2541,7 +2541,7 @@ fi # Define the identity of the package. PACKAGE='newlib' - VERSION='3.0.0' + VERSION='3.1.0' # Some tools Automake needs. @@ -4025,7 +4025,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by newlib $as_me 3.0.0, which was +This file was extended by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -4082,7 +4082,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -newlib config.status 3.0.0 +newlib config.status 3.1.0 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" diff --git a/newlib/libc/machine/xc16x/configure b/newlib/libc/machine/xc16x/configure index 083cd071c..35078c605 100644 --- a/newlib/libc/machine/xc16x/configure +++ b/newlib/libc/machine/xc16x/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for newlib 3.0.0. +# Generated by GNU Autoconf 2.68 for newlib 3.1.0. # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -556,8 +556,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='newlib' PACKAGE_TARNAME='newlib' -PACKAGE_VERSION='3.0.0' -PACKAGE_STRING='newlib 3.0.0' +PACKAGE_VERSION='3.1.0' +PACKAGE_STRING='newlib 3.1.0' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1240,7 +1240,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures newlib 3.0.0 to adapt to many kinds of systems. +\`configure' configures newlib 3.1.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1310,7 +1310,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of newlib 3.0.0:";; + short | recursive ) echo "Configuration of newlib 3.1.0:";; esac cat <<\_ACEOF @@ -1402,7 +1402,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -newlib configure 3.0.0 +newlib configure 3.1.0 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -1457,7 +1457,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by newlib $as_me 3.0.0, which was +It was created by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -2541,7 +2541,7 @@ fi # Define the identity of the package. PACKAGE='newlib' - VERSION='3.0.0' + VERSION='3.1.0' # Some tools Automake needs. @@ -4025,7 +4025,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by newlib $as_me 3.0.0, which was +This file was extended by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -4082,7 +4082,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -newlib config.status 3.0.0 +newlib config.status 3.1.0 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" diff --git a/newlib/libc/machine/xscale/configure b/newlib/libc/machine/xscale/configure index 6a6ad6044..24feba10f 100755 --- a/newlib/libc/machine/xscale/configure +++ b/newlib/libc/machine/xscale/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for newlib 3.0.0. +# Generated by GNU Autoconf 2.68 for newlib 3.1.0. # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -556,8 +556,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='newlib' PACKAGE_TARNAME='newlib' -PACKAGE_VERSION='3.0.0' -PACKAGE_STRING='newlib 3.0.0' +PACKAGE_VERSION='3.1.0' +PACKAGE_STRING='newlib 3.1.0' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1240,7 +1240,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures newlib 3.0.0 to adapt to many kinds of systems. +\`configure' configures newlib 3.1.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1310,7 +1310,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of newlib 3.0.0:";; + short | recursive ) echo "Configuration of newlib 3.1.0:";; esac cat <<\_ACEOF @@ -1402,7 +1402,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -newlib configure 3.0.0 +newlib configure 3.1.0 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -1457,7 +1457,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by newlib $as_me 3.0.0, which was +It was created by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -2541,7 +2541,7 @@ fi # Define the identity of the package. PACKAGE='newlib' - VERSION='3.0.0' + VERSION='3.1.0' # Some tools Automake needs. @@ -4025,7 +4025,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by newlib $as_me 3.0.0, which was +This file was extended by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -4082,7 +4082,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -newlib config.status 3.0.0 +newlib config.status 3.1.0 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" diff --git a/newlib/libc/machine/xstormy16/configure b/newlib/libc/machine/xstormy16/configure index 083cd071c..35078c605 100755 --- a/newlib/libc/machine/xstormy16/configure +++ b/newlib/libc/machine/xstormy16/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for newlib 3.0.0. +# Generated by GNU Autoconf 2.68 for newlib 3.1.0. # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -556,8 +556,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='newlib' PACKAGE_TARNAME='newlib' -PACKAGE_VERSION='3.0.0' -PACKAGE_STRING='newlib 3.0.0' +PACKAGE_VERSION='3.1.0' +PACKAGE_STRING='newlib 3.1.0' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1240,7 +1240,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures newlib 3.0.0 to adapt to many kinds of systems. +\`configure' configures newlib 3.1.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1310,7 +1310,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of newlib 3.0.0:";; + short | recursive ) echo "Configuration of newlib 3.1.0:";; esac cat <<\_ACEOF @@ -1402,7 +1402,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -newlib configure 3.0.0 +newlib configure 3.1.0 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -1457,7 +1457,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by newlib $as_me 3.0.0, which was +It was created by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -2541,7 +2541,7 @@ fi # Define the identity of the package. PACKAGE='newlib' - VERSION='3.0.0' + VERSION='3.1.0' # Some tools Automake needs. @@ -4025,7 +4025,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by newlib $as_me 3.0.0, which was +This file was extended by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -4082,7 +4082,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -newlib config.status 3.0.0 +newlib config.status 3.1.0 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" diff --git a/newlib/libc/machine/z8k/configure b/newlib/libc/machine/z8k/configure index 5291def96..18f4c511b 100755 --- a/newlib/libc/machine/z8k/configure +++ b/newlib/libc/machine/z8k/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for newlib 3.0.0. +# Generated by GNU Autoconf 2.68 for newlib 3.1.0. # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -556,8 +556,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='newlib' PACKAGE_TARNAME='newlib' -PACKAGE_VERSION='3.0.0' -PACKAGE_STRING='newlib 3.0.0' +PACKAGE_VERSION='3.1.0' +PACKAGE_STRING='newlib 3.1.0' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1240,7 +1240,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures newlib 3.0.0 to adapt to many kinds of systems. +\`configure' configures newlib 3.1.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1310,7 +1310,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of newlib 3.0.0:";; + short | recursive ) echo "Configuration of newlib 3.1.0:";; esac cat <<\_ACEOF @@ -1402,7 +1402,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -newlib configure 3.0.0 +newlib configure 3.1.0 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -1457,7 +1457,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by newlib $as_me 3.0.0, which was +It was created by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -2541,7 +2541,7 @@ fi # Define the identity of the package. PACKAGE='newlib' - VERSION='3.0.0' + VERSION='3.1.0' # Some tools Automake needs. @@ -4025,7 +4025,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by newlib $as_me 3.0.0, which was +This file was extended by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -4082,7 +4082,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -newlib config.status 3.0.0 +newlib config.status 3.1.0 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" diff --git a/newlib/libc/stdlib/Makefile.in b/newlib/libc/stdlib/Makefile.in index 1da271af3..699831f13 100644 --- a/newlib/libc/stdlib/Makefile.in +++ b/newlib/libc/stdlib/Makefile.in @@ -54,7 +54,9 @@ POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ @HAVE_LONG_DOUBLE_TRUE@am__append_1 = \ -@HAVE_LONG_DOUBLE_TRUE@ strtold.c \ +@HAVE_LONG_DOUBLE_TRUE@ strtodg.c \ +@HAVE_LONG_DOUBLE_TRUE@ strtold.c \ +@HAVE_LONG_DOUBLE_TRUE@ strtorx.c \ @HAVE_LONG_DOUBLE_TRUE@ wcstold.c DIST_COMMON = $(srcdir)/../../Makefile.shared $(srcdir)/Makefile.in \ @@ -79,7 +81,9 @@ lib_a_AR = $(AR) $(ARFLAGS) @ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_TRUE@am__DEPENDENCIES_1 = $(ELIX_2_OBJS) @ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_TRUE@am__DEPENDENCIES_1 = \ @ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_TRUE@ $(ELIX_2_OBJS) -@HAVE_LONG_DOUBLE_TRUE@am__objects_1 = lib_a-strtold.$(OBJEXT) \ +@HAVE_LONG_DOUBLE_TRUE@am__objects_1 = lib_a-strtodg.$(OBJEXT) \ +@HAVE_LONG_DOUBLE_TRUE@ lib_a-strtold.$(OBJEXT) \ +@HAVE_LONG_DOUBLE_TRUE@ lib_a-strtorx.$(OBJEXT) \ @HAVE_LONG_DOUBLE_TRUE@ lib_a-wcstold.$(OBJEXT) am__objects_2 = lib_a-__adjust.$(OBJEXT) lib_a-__atexit.$(OBJEXT) \ lib_a-__call_atexit.$(OBJEXT) lib_a-__exp10.$(OBJEXT) \ @@ -107,9 +111,8 @@ am__objects_2 = lib_a-__adjust.$(OBJEXT) lib_a-__atexit.$(OBJEXT) \ lib_a-rand_r.$(OBJEXT) lib_a-random.$(OBJEXT) \ lib_a-realloc.$(OBJEXT) lib_a-reallocarray.$(OBJEXT) \ lib_a-reallocf.$(OBJEXT) lib_a-sb_charsets.$(OBJEXT) \ - lib_a-strtod.$(OBJEXT) lib_a-strtodg.$(OBJEXT) \ - lib_a-strtoimax.$(OBJEXT) lib_a-strtol.$(OBJEXT) \ - lib_a-strtorx.$(OBJEXT) lib_a-strtoul.$(OBJEXT) \ + lib_a-strtod.$(OBJEXT) lib_a-strtoimax.$(OBJEXT) \ + lib_a-strtol.$(OBJEXT) lib_a-strtoul.$(OBJEXT) \ lib_a-strtoumax.$(OBJEXT) lib_a-utoa.$(OBJEXT) \ lib_a-wcstod.$(OBJEXT) lib_a-wcstoimax.$(OBJEXT) \ lib_a-wcstol.$(OBJEXT) lib_a-wcstoul.$(OBJEXT) \ @@ -154,8 +157,8 @@ am__objects_6 = lib_a-rpmatch.$(OBJEXT) lib_a-system.$(OBJEXT) @USE_LIBTOOL_FALSE@ $(am__objects_3) $(am__objects_7) lib_a_OBJECTS = $(am_lib_a_OBJECTS) LTLIBRARIES = $(noinst_LTLIBRARIES) -@HAVE_LONG_DOUBLE_TRUE@am__objects_8 = strtodg.lo strtold.lo strtorx.lo \ - wcstold.lo +@HAVE_LONG_DOUBLE_TRUE@am__objects_8 = strtodg.lo strtold.lo \ +@HAVE_LONG_DOUBLE_TRUE@ strtorx.lo wcstold.lo am__objects_9 = __adjust.lo __atexit.lo __call_atexit.lo __exp10.lo \ __ten_mu.lo _Exit.lo abort.lo abs.lo aligned_alloc.lo \ assert.lo atexit.lo atof.lo atoff.lo atoi.lo atol.lo calloc.lo \ @@ -371,10 +374,10 @@ GENERAL_SOURCES = __adjust.c __atexit.c __call_atexit.c __exp10.c \ labs.c ldiv.c ldtoa.c malloc.c mblen.c mblen_r.c mbstowcs.c \ mbstowcs_r.c mbtowc.c mbtowc_r.c mlock.c mprec.c mstats.c \ on_exit_args.c quick_exit.c rand.c rand_r.c random.c realloc.c \ - reallocarray.c reallocf.c sb_charsets.c strtod.c strtodg.c \ - strtoimax.c strtol.c strtorx.c strtoul.c strtoumax.c utoa.c \ - wcstod.c wcstoimax.c wcstol.c wcstoul.c wcstoumax.c wcstombs.c \ - wcstombs_r.c wctomb.c wctomb_r.c $(am__append_1) + reallocarray.c reallocf.c sb_charsets.c strtod.c strtoimax.c \ + strtol.c strtoul.c strtoumax.c utoa.c wcstod.c wcstoimax.c \ + wcstol.c wcstoul.c wcstoumax.c wcstombs.c wcstombs_r.c \ + wctomb.c wctomb_r.c $(am__append_1) @NEWLIB_NANO_MALLOC_FALSE@MALIGNR = malignr @NEWLIB_NANO_MALLOC_TRUE@MALIGNR = nano-malignr @NEWLIB_NANO_MALLOC_FALSE@MALLOPTR = malloptr @@ -943,12 +946,6 @@ lib_a-strtod.o: strtod.c lib_a-strtod.obj: strtod.c $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-strtod.obj `if test -f 'strtod.c'; then $(CYGPATH_W) 'strtod.c'; else $(CYGPATH_W) '$(srcdir)/strtod.c'; fi` -lib_a-strtodg.o: strtodg.c - $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-strtodg.o `test -f 'strtodg.c' || echo '$(srcdir)/'`strtodg.c - -lib_a-strtodg.obj: strtodg.c - $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-strtodg.obj `if test -f 'strtodg.c'; then $(CYGPATH_W) 'strtodg.c'; else $(CYGPATH_W) '$(srcdir)/strtodg.c'; fi` - lib_a-strtoimax.o: strtoimax.c $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-strtoimax.o `test -f 'strtoimax.c' || echo '$(srcdir)/'`strtoimax.c @@ -961,12 +958,6 @@ lib_a-strtol.o: strtol.c lib_a-strtol.obj: strtol.c $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-strtol.obj `if test -f 'strtol.c'; then $(CYGPATH_W) 'strtol.c'; else $(CYGPATH_W) '$(srcdir)/strtol.c'; fi` -lib_a-strtorx.o: strtorx.c - $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-strtorx.o `test -f 'strtorx.c' || echo '$(srcdir)/'`strtorx.c - -lib_a-strtorx.obj: strtorx.c - $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-strtorx.obj `if test -f 'strtorx.c'; then $(CYGPATH_W) 'strtorx.c'; else $(CYGPATH_W) '$(srcdir)/strtorx.c'; fi` - lib_a-strtoul.o: strtoul.c $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-strtoul.o `test -f 'strtoul.c' || echo '$(srcdir)/'`strtoul.c @@ -1039,12 +1030,24 @@ lib_a-wctomb_r.o: wctomb_r.c lib_a-wctomb_r.obj: wctomb_r.c $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-wctomb_r.obj `if test -f 'wctomb_r.c'; then $(CYGPATH_W) 'wctomb_r.c'; else $(CYGPATH_W) '$(srcdir)/wctomb_r.c'; fi` +lib_a-strtodg.o: strtodg.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-strtodg.o `test -f 'strtodg.c' || echo '$(srcdir)/'`strtodg.c + +lib_a-strtodg.obj: strtodg.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-strtodg.obj `if test -f 'strtodg.c'; then $(CYGPATH_W) 'strtodg.c'; else $(CYGPATH_W) '$(srcdir)/strtodg.c'; fi` + lib_a-strtold.o: strtold.c $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-strtold.o `test -f 'strtold.c' || echo '$(srcdir)/'`strtold.c lib_a-strtold.obj: strtold.c $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-strtold.obj `if test -f 'strtold.c'; then $(CYGPATH_W) 'strtold.c'; else $(CYGPATH_W) '$(srcdir)/strtold.c'; fi` +lib_a-strtorx.o: strtorx.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-strtorx.o `test -f 'strtorx.c' || echo '$(srcdir)/'`strtorx.c + +lib_a-strtorx.obj: strtorx.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-strtorx.obj `if test -f 'strtorx.c'; then $(CYGPATH_W) 'strtorx.c'; else $(CYGPATH_W) '$(srcdir)/strtorx.c'; fi` + lib_a-wcstold.o: wcstold.c $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-wcstold.o `test -f 'wcstold.c' || echo '$(srcdir)/'`wcstold.c diff --git a/newlib/libc/sys/a29khif/configure b/newlib/libc/sys/a29khif/configure index b8f9ce21e..9d5027e32 100755 --- a/newlib/libc/sys/a29khif/configure +++ b/newlib/libc/sys/a29khif/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for newlib 3.0.0. +# Generated by GNU Autoconf 2.68 for newlib 3.1.0. # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -556,8 +556,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='newlib' PACKAGE_TARNAME='newlib' -PACKAGE_VERSION='3.0.0' -PACKAGE_STRING='newlib 3.0.0' +PACKAGE_VERSION='3.1.0' +PACKAGE_STRING='newlib 3.1.0' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1240,7 +1240,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures newlib 3.0.0 to adapt to many kinds of systems. +\`configure' configures newlib 3.1.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1310,7 +1310,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of newlib 3.0.0:";; + short | recursive ) echo "Configuration of newlib 3.1.0:";; esac cat <<\_ACEOF @@ -1402,7 +1402,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -newlib configure 3.0.0 +newlib configure 3.1.0 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -1457,7 +1457,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by newlib $as_me 3.0.0, which was +It was created by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -2541,7 +2541,7 @@ fi # Define the identity of the package. PACKAGE='newlib' - VERSION='3.0.0' + VERSION='3.1.0' # Some tools Automake needs. @@ -4025,7 +4025,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by newlib $as_me 3.0.0, which was +This file was extended by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -4082,7 +4082,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -newlib config.status 3.0.0 +newlib config.status 3.1.0 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" diff --git a/newlib/libc/sys/arm/configure b/newlib/libc/sys/arm/configure index 5a500236d..3fb1e9af1 100755 --- a/newlib/libc/sys/arm/configure +++ b/newlib/libc/sys/arm/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for newlib 3.0.0. +# Generated by GNU Autoconf 2.68 for newlib 3.1.0. # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -556,8 +556,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='newlib' PACKAGE_TARNAME='newlib' -PACKAGE_VERSION='3.0.0' -PACKAGE_STRING='newlib 3.0.0' +PACKAGE_VERSION='3.1.0' +PACKAGE_STRING='newlib 3.1.0' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1240,7 +1240,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures newlib 3.0.0 to adapt to many kinds of systems. +\`configure' configures newlib 3.1.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1310,7 +1310,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of newlib 3.0.0:";; + short | recursive ) echo "Configuration of newlib 3.1.0:";; esac cat <<\_ACEOF @@ -1402,7 +1402,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -newlib configure 3.0.0 +newlib configure 3.1.0 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -1457,7 +1457,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by newlib $as_me 3.0.0, which was +It was created by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -2541,7 +2541,7 @@ fi # Define the identity of the package. PACKAGE='newlib' - VERSION='3.0.0' + VERSION='3.1.0' # Some tools Automake needs. @@ -4025,7 +4025,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by newlib $as_me 3.0.0, which was +This file was extended by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -4082,7 +4082,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -newlib config.status 3.0.0 +newlib config.status 3.1.0 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" diff --git a/newlib/libc/sys/configure b/newlib/libc/sys/configure index 209e79dbd..08485a1e9 100755 --- a/newlib/libc/sys/configure +++ b/newlib/libc/sys/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for newlib 3.0.0. +# Generated by GNU Autoconf 2.68 for newlib 3.1.0. # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -567,8 +567,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='newlib' PACKAGE_TARNAME='newlib' -PACKAGE_VERSION='3.0.0' -PACKAGE_STRING='newlib 3.0.0' +PACKAGE_VERSION='3.1.0' +PACKAGE_STRING='newlib 3.1.0' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1354,7 +1354,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures newlib 3.0.0 to adapt to many kinds of systems. +\`configure' configures newlib 3.1.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1424,7 +1424,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of newlib 3.0.0:";; + short | recursive ) echo "Configuration of newlib 3.1.0:";; esac cat <<\_ACEOF @@ -1536,7 +1536,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -newlib configure 3.0.0 +newlib configure 3.1.0 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -1814,7 +1814,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by newlib $as_me 3.0.0, which was +It was created by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -2898,7 +2898,7 @@ fi # Define the identity of the package. PACKAGE='newlib' - VERSION='3.0.0' + VERSION='3.1.0' # Some tools Automake needs. @@ -12507,7 +12507,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by newlib $as_me 3.0.0, which was +This file was extended by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -12564,7 +12564,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -newlib config.status 3.0.0 +newlib config.status 3.1.0 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" diff --git a/newlib/libc/sys/d10v/configure b/newlib/libc/sys/d10v/configure index 88091acf2..cf83e91e0 100755 --- a/newlib/libc/sys/d10v/configure +++ b/newlib/libc/sys/d10v/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for newlib 3.0.0. +# Generated by GNU Autoconf 2.68 for newlib 3.1.0. # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -556,8 +556,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='newlib' PACKAGE_TARNAME='newlib' -PACKAGE_VERSION='3.0.0' -PACKAGE_STRING='newlib 3.0.0' +PACKAGE_VERSION='3.1.0' +PACKAGE_STRING='newlib 3.1.0' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1240,7 +1240,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures newlib 3.0.0 to adapt to many kinds of systems. +\`configure' configures newlib 3.1.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1310,7 +1310,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of newlib 3.0.0:";; + short | recursive ) echo "Configuration of newlib 3.1.0:";; esac cat <<\_ACEOF @@ -1402,7 +1402,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -newlib configure 3.0.0 +newlib configure 3.1.0 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -1457,7 +1457,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by newlib $as_me 3.0.0, which was +It was created by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -2541,7 +2541,7 @@ fi # Define the identity of the package. PACKAGE='newlib' - VERSION='3.0.0' + VERSION='3.1.0' # Some tools Automake needs. @@ -4025,7 +4025,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by newlib $as_me 3.0.0, which was +This file was extended by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -4082,7 +4082,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -newlib config.status 3.0.0 +newlib config.status 3.1.0 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" diff --git a/newlib/libc/sys/decstation/configure b/newlib/libc/sys/decstation/configure index 0e6ea6bb9..eb614d13a 100755 --- a/newlib/libc/sys/decstation/configure +++ b/newlib/libc/sys/decstation/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for newlib 3.0.0. +# Generated by GNU Autoconf 2.68 for newlib 3.1.0. # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -556,8 +556,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='newlib' PACKAGE_TARNAME='newlib' -PACKAGE_VERSION='3.0.0' -PACKAGE_STRING='newlib 3.0.0' +PACKAGE_VERSION='3.1.0' +PACKAGE_STRING='newlib 3.1.0' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1240,7 +1240,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures newlib 3.0.0 to adapt to many kinds of systems. +\`configure' configures newlib 3.1.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1310,7 +1310,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of newlib 3.0.0:";; + short | recursive ) echo "Configuration of newlib 3.1.0:";; esac cat <<\_ACEOF @@ -1402,7 +1402,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -newlib configure 3.0.0 +newlib configure 3.1.0 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -1457,7 +1457,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by newlib $as_me 3.0.0, which was +It was created by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -2541,7 +2541,7 @@ fi # Define the identity of the package. PACKAGE='newlib' - VERSION='3.0.0' + VERSION='3.1.0' # Some tools Automake needs. @@ -4025,7 +4025,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by newlib $as_me 3.0.0, which was +This file was extended by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -4082,7 +4082,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -newlib config.status 3.0.0 +newlib config.status 3.1.0 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" diff --git a/newlib/libc/sys/epiphany/configure b/newlib/libc/sys/epiphany/configure index fbd964946..a01e71f44 100755 --- a/newlib/libc/sys/epiphany/configure +++ b/newlib/libc/sys/epiphany/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for newlib 3.0.0. +# Generated by GNU Autoconf 2.68 for newlib 3.1.0. # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -556,8 +556,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='newlib' PACKAGE_TARNAME='newlib' -PACKAGE_VERSION='3.0.0' -PACKAGE_STRING='newlib 3.0.0' +PACKAGE_VERSION='3.1.0' +PACKAGE_STRING='newlib 3.1.0' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1240,7 +1240,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures newlib 3.0.0 to adapt to many kinds of systems. +\`configure' configures newlib 3.1.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1310,7 +1310,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of newlib 3.0.0:";; + short | recursive ) echo "Configuration of newlib 3.1.0:";; esac cat <<\_ACEOF @@ -1402,7 +1402,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -newlib configure 3.0.0 +newlib configure 3.1.0 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -1457,7 +1457,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by newlib $as_me 3.0.0, which was +It was created by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -2541,7 +2541,7 @@ fi # Define the identity of the package. PACKAGE='newlib' - VERSION='3.0.0' + VERSION='3.1.0' # Some tools Automake needs. @@ -4025,7 +4025,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by newlib $as_me 3.0.0, which was +This file was extended by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -4082,7 +4082,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -newlib config.status 3.0.0 +newlib config.status 3.1.0 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" diff --git a/newlib/libc/sys/h8300hms/configure b/newlib/libc/sys/h8300hms/configure index 648527413..f984fc57e 100755 --- a/newlib/libc/sys/h8300hms/configure +++ b/newlib/libc/sys/h8300hms/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for newlib 3.0.0. +# Generated by GNU Autoconf 2.68 for newlib 3.1.0. # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -556,8 +556,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='newlib' PACKAGE_TARNAME='newlib' -PACKAGE_VERSION='3.0.0' -PACKAGE_STRING='newlib 3.0.0' +PACKAGE_VERSION='3.1.0' +PACKAGE_STRING='newlib 3.1.0' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1240,7 +1240,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures newlib 3.0.0 to adapt to many kinds of systems. +\`configure' configures newlib 3.1.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1310,7 +1310,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of newlib 3.0.0:";; + short | recursive ) echo "Configuration of newlib 3.1.0:";; esac cat <<\_ACEOF @@ -1402,7 +1402,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -newlib configure 3.0.0 +newlib configure 3.1.0 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -1457,7 +1457,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by newlib $as_me 3.0.0, which was +It was created by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -2541,7 +2541,7 @@ fi # Define the identity of the package. PACKAGE='newlib' - VERSION='3.0.0' + VERSION='3.1.0' # Some tools Automake needs. @@ -4025,7 +4025,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by newlib $as_me 3.0.0, which was +This file was extended by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -4082,7 +4082,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -newlib config.status 3.0.0 +newlib config.status 3.1.0 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" diff --git a/newlib/libc/sys/h8500hms/configure b/newlib/libc/sys/h8500hms/configure index 29755c072..8aa1c5356 100755 --- a/newlib/libc/sys/h8500hms/configure +++ b/newlib/libc/sys/h8500hms/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for newlib 3.0.0. +# Generated by GNU Autoconf 2.68 for newlib 3.1.0. # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -556,8 +556,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='newlib' PACKAGE_TARNAME='newlib' -PACKAGE_VERSION='3.0.0' -PACKAGE_STRING='newlib 3.0.0' +PACKAGE_VERSION='3.1.0' +PACKAGE_STRING='newlib 3.1.0' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1240,7 +1240,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures newlib 3.0.0 to adapt to many kinds of systems. +\`configure' configures newlib 3.1.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1310,7 +1310,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of newlib 3.0.0:";; + short | recursive ) echo "Configuration of newlib 3.1.0:";; esac cat <<\_ACEOF @@ -1402,7 +1402,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -newlib configure 3.0.0 +newlib configure 3.1.0 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -1457,7 +1457,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by newlib $as_me 3.0.0, which was +It was created by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -2541,7 +2541,7 @@ fi # Define the identity of the package. PACKAGE='newlib' - VERSION='3.0.0' + VERSION='3.1.0' # Some tools Automake needs. @@ -4025,7 +4025,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by newlib $as_me 3.0.0, which was +This file was extended by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -4082,7 +4082,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -newlib config.status 3.0.0 +newlib config.status 3.1.0 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" diff --git a/newlib/libc/sys/linux/configure b/newlib/libc/sys/linux/configure index 0a0a172a8..2ac723028 100755 --- a/newlib/libc/sys/linux/configure +++ b/newlib/libc/sys/linux/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for newlib 3.0.0. +# Generated by GNU Autoconf 2.68 for newlib 3.1.0. # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -567,8 +567,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='newlib' PACKAGE_TARNAME='newlib' -PACKAGE_VERSION='3.0.0' -PACKAGE_STRING='newlib 3.0.0' +PACKAGE_VERSION='3.1.0' +PACKAGE_STRING='newlib 3.1.0' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1329,7 +1329,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures newlib 3.0.0 to adapt to many kinds of systems. +\`configure' configures newlib 3.1.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1399,7 +1399,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of newlib 3.0.0:";; + short | recursive ) echo "Configuration of newlib 3.1.0:";; esac cat <<\_ACEOF @@ -1511,7 +1511,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -newlib configure 3.0.0 +newlib configure 3.1.0 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -1789,7 +1789,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by newlib $as_me 3.0.0, which was +It was created by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -2873,7 +2873,7 @@ fi # Define the identity of the package. PACKAGE='newlib' - VERSION='3.0.0' + VERSION='3.1.0' # Some tools Automake needs. @@ -12477,7 +12477,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by newlib $as_me 3.0.0, which was +This file was extended by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -12534,7 +12534,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -newlib config.status 3.0.0 +newlib config.status 3.1.0 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" diff --git a/newlib/libc/sys/linux/linuxthreads/configure b/newlib/libc/sys/linux/linuxthreads/configure index 14123ba53..ca62ff10e 100755 --- a/newlib/libc/sys/linux/linuxthreads/configure +++ b/newlib/libc/sys/linux/linuxthreads/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for newlib 3.0.0. +# Generated by GNU Autoconf 2.68 for newlib 3.1.0. # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -567,8 +567,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='newlib' PACKAGE_TARNAME='newlib' -PACKAGE_VERSION='3.0.0' -PACKAGE_STRING='newlib 3.0.0' +PACKAGE_VERSION='3.1.0' +PACKAGE_STRING='newlib 3.1.0' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1327,7 +1327,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures newlib 3.0.0 to adapt to many kinds of systems. +\`configure' configures newlib 3.1.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1397,7 +1397,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of newlib 3.0.0:";; + short | recursive ) echo "Configuration of newlib 3.1.0:";; esac cat <<\_ACEOF @@ -1509,7 +1509,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -newlib configure 3.0.0 +newlib configure 3.1.0 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -1787,7 +1787,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by newlib $as_me 3.0.0, which was +It was created by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -2871,7 +2871,7 @@ fi # Define the identity of the package. PACKAGE='newlib' - VERSION='3.0.0' + VERSION='3.1.0' # Some tools Automake needs. @@ -12454,7 +12454,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by newlib $as_me 3.0.0, which was +This file was extended by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -12511,7 +12511,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -newlib config.status 3.0.0 +newlib config.status 3.1.0 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" diff --git a/newlib/libc/sys/linux/linuxthreads/machine/configure b/newlib/libc/sys/linux/linuxthreads/machine/configure index 903600f59..dea024c08 100755 --- a/newlib/libc/sys/linux/linuxthreads/machine/configure +++ b/newlib/libc/sys/linux/linuxthreads/machine/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for newlib 3.0.0. +# Generated by GNU Autoconf 2.68 for newlib 3.1.0. # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -567,8 +567,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='newlib' PACKAGE_TARNAME='newlib' -PACKAGE_VERSION='3.0.0' -PACKAGE_STRING='newlib 3.0.0' +PACKAGE_VERSION='3.1.0' +PACKAGE_STRING='newlib 3.1.0' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1327,7 +1327,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures newlib 3.0.0 to adapt to many kinds of systems. +\`configure' configures newlib 3.1.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1397,7 +1397,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of newlib 3.0.0:";; + short | recursive ) echo "Configuration of newlib 3.1.0:";; esac cat <<\_ACEOF @@ -1509,7 +1509,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -newlib configure 3.0.0 +newlib configure 3.1.0 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -1787,7 +1787,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by newlib $as_me 3.0.0, which was +It was created by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -2871,7 +2871,7 @@ fi # Define the identity of the package. PACKAGE='newlib' - VERSION='3.0.0' + VERSION='3.1.0' # Some tools Automake needs. @@ -12422,7 +12422,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by newlib $as_me 3.0.0, which was +This file was extended by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -12479,7 +12479,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -newlib config.status 3.0.0 +newlib config.status 3.1.0 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" diff --git a/newlib/libc/sys/linux/linuxthreads/machine/i386/configure b/newlib/libc/sys/linux/linuxthreads/machine/i386/configure index e7d2f59dd..35a8c8118 100755 --- a/newlib/libc/sys/linux/linuxthreads/machine/i386/configure +++ b/newlib/libc/sys/linux/linuxthreads/machine/i386/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for newlib 3.0.0. +# Generated by GNU Autoconf 2.68 for newlib 3.1.0. # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -567,8 +567,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='newlib' PACKAGE_TARNAME='newlib' -PACKAGE_VERSION='3.0.0' -PACKAGE_STRING='newlib 3.0.0' +PACKAGE_VERSION='3.1.0' +PACKAGE_STRING='newlib 3.1.0' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1323,7 +1323,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures newlib 3.0.0 to adapt to many kinds of systems. +\`configure' configures newlib 3.1.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1393,7 +1393,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of newlib 3.0.0:";; + short | recursive ) echo "Configuration of newlib 3.1.0:";; esac cat <<\_ACEOF @@ -1505,7 +1505,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -newlib configure 3.0.0 +newlib configure 3.1.0 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -1783,7 +1783,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by newlib $as_me 3.0.0, which was +It was created by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -2867,7 +2867,7 @@ fi # Define the identity of the package. PACKAGE='newlib' - VERSION='3.0.0' + VERSION='3.1.0' # Some tools Automake needs. @@ -12438,7 +12438,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by newlib $as_me 3.0.0, which was +This file was extended by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -12495,7 +12495,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -newlib config.status 3.0.0 +newlib config.status 3.1.0 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" diff --git a/newlib/libc/sys/linux/machine/configure b/newlib/libc/sys/linux/machine/configure index 1be5b7f74..359b7a33a 100755 --- a/newlib/libc/sys/linux/machine/configure +++ b/newlib/libc/sys/linux/machine/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for newlib 3.0.0. +# Generated by GNU Autoconf 2.68 for newlib 3.1.0. # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -567,8 +567,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='newlib' PACKAGE_TARNAME='newlib' -PACKAGE_VERSION='3.0.0' -PACKAGE_STRING='newlib 3.0.0' +PACKAGE_VERSION='3.1.0' +PACKAGE_STRING='newlib 3.1.0' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1328,7 +1328,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures newlib 3.0.0 to adapt to many kinds of systems. +\`configure' configures newlib 3.1.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1398,7 +1398,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of newlib 3.0.0:";; + short | recursive ) echo "Configuration of newlib 3.1.0:";; esac cat <<\_ACEOF @@ -1510,7 +1510,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -newlib configure 3.0.0 +newlib configure 3.1.0 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -1788,7 +1788,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by newlib $as_me 3.0.0, which was +It was created by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -2872,7 +2872,7 @@ fi # Define the identity of the package. PACKAGE='newlib' - VERSION='3.0.0' + VERSION='3.1.0' # Some tools Automake needs. @@ -12429,7 +12429,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by newlib $as_me 3.0.0, which was +This file was extended by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -12486,7 +12486,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -newlib config.status 3.0.0 +newlib config.status 3.1.0 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" diff --git a/newlib/libc/sys/linux/machine/i386/configure b/newlib/libc/sys/linux/machine/i386/configure index f6aaca054..48ebb68a0 100755 --- a/newlib/libc/sys/linux/machine/i386/configure +++ b/newlib/libc/sys/linux/machine/i386/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for newlib 3.0.0. +# Generated by GNU Autoconf 2.68 for newlib 3.1.0. # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -567,8 +567,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='newlib' PACKAGE_TARNAME='newlib' -PACKAGE_VERSION='3.0.0' -PACKAGE_STRING='newlib 3.0.0' +PACKAGE_VERSION='3.1.0' +PACKAGE_STRING='newlib 3.1.0' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -760,6 +760,7 @@ enable_newlib_iconv enable_newlib_elix_level enable_newlib_io_float enable_newlib_supplied_syscalls +enable_newlib_fno_builtin enable_dependency_tracking enable_maintainer_mode enable_shared @@ -1322,7 +1323,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures newlib 3.0.0 to adapt to many kinds of systems. +\`configure' configures newlib 3.1.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1392,7 +1393,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of newlib 3.0.0:";; + short | recursive ) echo "Configuration of newlib 3.1.0:";; esac cat <<\_ACEOF @@ -1408,6 +1409,7 @@ Optional Features: --enable-newlib-elix-level supply desired elix library level (1-4) --disable-newlib-io-float disable printf/scanf family float support --disable-newlib-supplied-syscalls disable newlib from supplying syscalls + --disable-newlib-fno-builtin disable -fno-builtin flag to allow compiler to use builtin library functions --disable-dependency-tracking speeds up one-time build --enable-dependency-tracking do not reject slow dependency extractors --enable-maintainer-mode enable make rules and dependencies not useful @@ -1503,7 +1505,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -newlib configure 3.0.0 +newlib configure 3.1.0 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -1781,7 +1783,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by newlib $as_me 3.0.0, which was +It was created by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -2815,6 +2817,18 @@ else fi +# Check whether --enable-newlib-fno-builtin was given. +if test "${enable_newlib_fno_builtin+set}" = set; then : + enableval=$enable_newlib_fno_builtin; case "${enableval}" in + yes) newlib_fno_builtin=yes ;; + no) newlib_fno_builtin=no ;; + *) as_fn_error $? "bad value ${enableval} for newlib-fno-builtin option" "$LINENO" 5 ;; + esac +else + newlib_fno_builtin= +fi + + test -z "${with_target_subdir}" && with_target_subdir=. @@ -2853,7 +2867,7 @@ fi # Define the identity of the package. PACKAGE='newlib' - VERSION='3.0.0' + VERSION='3.1.0' # Some tools Automake needs. @@ -3661,8 +3675,6 @@ fi . ${newlib_basedir}/configure.host -newlib_cflags="${newlib_cflags} -fno-builtin" - NEWLIB_CFLAGS=${newlib_cflags} @@ -11473,7 +11485,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 11476 "configure" +#line 11488 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -11579,7 +11591,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 11582 "configure" +#line 11594 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -12426,7 +12438,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by newlib $as_me 3.0.0, which was +This file was extended by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -12483,7 +12495,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -newlib config.status 3.0.0 +newlib config.status 3.1.0 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" diff --git a/newlib/libc/sys/m88kbug/configure b/newlib/libc/sys/m88kbug/configure index 0d637ac33..35d89395b 100755 --- a/newlib/libc/sys/m88kbug/configure +++ b/newlib/libc/sys/m88kbug/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for newlib 3.0.0. +# Generated by GNU Autoconf 2.68 for newlib 3.1.0. # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -556,8 +556,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='newlib' PACKAGE_TARNAME='newlib' -PACKAGE_VERSION='3.0.0' -PACKAGE_STRING='newlib 3.0.0' +PACKAGE_VERSION='3.1.0' +PACKAGE_STRING='newlib 3.1.0' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1240,7 +1240,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures newlib 3.0.0 to adapt to many kinds of systems. +\`configure' configures newlib 3.1.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1310,7 +1310,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of newlib 3.0.0:";; + short | recursive ) echo "Configuration of newlib 3.1.0:";; esac cat <<\_ACEOF @@ -1402,7 +1402,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -newlib configure 3.0.0 +newlib configure 3.1.0 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -1457,7 +1457,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by newlib $as_me 3.0.0, which was +It was created by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -2541,7 +2541,7 @@ fi # Define the identity of the package. PACKAGE='newlib' - VERSION='3.0.0' + VERSION='3.1.0' # Some tools Automake needs. @@ -4025,7 +4025,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by newlib $as_me 3.0.0, which was +This file was extended by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -4082,7 +4082,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -newlib config.status 3.0.0 +newlib config.status 3.1.0 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" diff --git a/newlib/libc/sys/mmixware/configure b/newlib/libc/sys/mmixware/configure index 719158d1b..86caf6e57 100755 --- a/newlib/libc/sys/mmixware/configure +++ b/newlib/libc/sys/mmixware/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for newlib 3.0.0. +# Generated by GNU Autoconf 2.68 for newlib 3.1.0. # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -556,8 +556,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='newlib' PACKAGE_TARNAME='newlib' -PACKAGE_VERSION='3.0.0' -PACKAGE_STRING='newlib 3.0.0' +PACKAGE_VERSION='3.1.0' +PACKAGE_STRING='newlib 3.1.0' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1240,7 +1240,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures newlib 3.0.0 to adapt to many kinds of systems. +\`configure' configures newlib 3.1.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1310,7 +1310,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of newlib 3.0.0:";; + short | recursive ) echo "Configuration of newlib 3.1.0:";; esac cat <<\_ACEOF @@ -1402,7 +1402,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -newlib configure 3.0.0 +newlib configure 3.1.0 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -1457,7 +1457,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by newlib $as_me 3.0.0, which was +It was created by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -2541,7 +2541,7 @@ fi # Define the identity of the package. PACKAGE='newlib' - VERSION='3.0.0' + VERSION='3.1.0' # Some tools Automake needs. @@ -4025,7 +4025,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by newlib $as_me 3.0.0, which was +This file was extended by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -4082,7 +4082,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -newlib config.status 3.0.0 +newlib config.status 3.1.0 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" diff --git a/newlib/libc/sys/netware/configure b/newlib/libc/sys/netware/configure index 270e5783c..c299e44a2 100755 --- a/newlib/libc/sys/netware/configure +++ b/newlib/libc/sys/netware/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for newlib 3.0.0. +# Generated by GNU Autoconf 2.68 for newlib 3.1.0. # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -556,8 +556,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='newlib' PACKAGE_TARNAME='newlib' -PACKAGE_VERSION='3.0.0' -PACKAGE_STRING='newlib 3.0.0' +PACKAGE_VERSION='3.1.0' +PACKAGE_STRING='newlib 3.1.0' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1240,7 +1240,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures newlib 3.0.0 to adapt to many kinds of systems. +\`configure' configures newlib 3.1.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1310,7 +1310,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of newlib 3.0.0:";; + short | recursive ) echo "Configuration of newlib 3.1.0:";; esac cat <<\_ACEOF @@ -1402,7 +1402,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -newlib configure 3.0.0 +newlib configure 3.1.0 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -1457,7 +1457,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by newlib $as_me 3.0.0, which was +It was created by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -2541,7 +2541,7 @@ fi # Define the identity of the package. PACKAGE='newlib' - VERSION='3.0.0' + VERSION='3.1.0' # Some tools Automake needs. @@ -4025,7 +4025,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by newlib $as_me 3.0.0, which was +This file was extended by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -4082,7 +4082,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -newlib config.status 3.0.0 +newlib config.status 3.1.0 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" diff --git a/newlib/libc/sys/or1k/configure b/newlib/libc/sys/or1k/configure index 3b666e93e..8d854f9b7 100755 --- a/newlib/libc/sys/or1k/configure +++ b/newlib/libc/sys/or1k/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for newlib 3.0.0. +# Generated by GNU Autoconf 2.68 for newlib 3.1.0. # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -556,8 +556,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='newlib' PACKAGE_TARNAME='newlib' -PACKAGE_VERSION='3.0.0' -PACKAGE_STRING='newlib 3.0.0' +PACKAGE_VERSION='3.1.0' +PACKAGE_STRING='newlib 3.1.0' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1240,7 +1240,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures newlib 3.0.0 to adapt to many kinds of systems. +\`configure' configures newlib 3.1.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1310,7 +1310,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of newlib 3.0.0:";; + short | recursive ) echo "Configuration of newlib 3.1.0:";; esac cat <<\_ACEOF @@ -1402,7 +1402,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -newlib configure 3.0.0 +newlib configure 3.1.0 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -1457,7 +1457,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by newlib $as_me 3.0.0, which was +It was created by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -2541,7 +2541,7 @@ fi # Define the identity of the package. PACKAGE='newlib' - VERSION='3.0.0' + VERSION='3.1.0' # Some tools Automake needs. @@ -4025,7 +4025,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by newlib $as_me 3.0.0, which was +This file was extended by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -4082,7 +4082,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -newlib config.status 3.0.0 +newlib config.status 3.1.0 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" diff --git a/newlib/libc/sys/phoenix/configure b/newlib/libc/sys/phoenix/configure index 0cff3e936..55a2e8bea 100644 --- a/newlib/libc/sys/phoenix/configure +++ b/newlib/libc/sys/phoenix/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for newlib 3.0.0. +# Generated by GNU Autoconf 2.68 for newlib 3.1.0. # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -556,8 +556,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='newlib' PACKAGE_TARNAME='newlib' -PACKAGE_VERSION='3.0.0' -PACKAGE_STRING='newlib 3.0.0' +PACKAGE_VERSION='3.1.0' +PACKAGE_STRING='newlib 3.1.0' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1243,7 +1243,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures newlib 3.0.0 to adapt to many kinds of systems. +\`configure' configures newlib 3.1.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1313,7 +1313,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of newlib 3.0.0:";; + short | recursive ) echo "Configuration of newlib 3.1.0:";; esac cat <<\_ACEOF @@ -1405,7 +1405,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -newlib configure 3.0.0 +newlib configure 3.1.0 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -1460,7 +1460,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by newlib $as_me 3.0.0, which was +It was created by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -2544,7 +2544,7 @@ fi # Define the identity of the package. PACKAGE='newlib' - VERSION='3.0.0' + VERSION='3.1.0' # Some tools Automake needs. @@ -4036,7 +4036,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by newlib $as_me 3.0.0, which was +This file was extended by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -4093,7 +4093,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -newlib config.status 3.0.0 +newlib config.status 3.1.0 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" diff --git a/newlib/libc/sys/rdos/configure b/newlib/libc/sys/rdos/configure index 46913b413..f3de7073d 100755 --- a/newlib/libc/sys/rdos/configure +++ b/newlib/libc/sys/rdos/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for newlib 3.0.0. +# Generated by GNU Autoconf 2.68 for newlib 3.1.0. # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -556,8 +556,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='newlib' PACKAGE_TARNAME='newlib' -PACKAGE_VERSION='3.0.0' -PACKAGE_STRING='newlib 3.0.0' +PACKAGE_VERSION='3.1.0' +PACKAGE_STRING='newlib 3.1.0' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1240,7 +1240,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures newlib 3.0.0 to adapt to many kinds of systems. +\`configure' configures newlib 3.1.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1310,7 +1310,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of newlib 3.0.0:";; + short | recursive ) echo "Configuration of newlib 3.1.0:";; esac cat <<\_ACEOF @@ -1402,7 +1402,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -newlib configure 3.0.0 +newlib configure 3.1.0 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -1457,7 +1457,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by newlib $as_me 3.0.0, which was +It was created by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -2541,7 +2541,7 @@ fi # Define the identity of the package. PACKAGE='newlib' - VERSION='3.0.0' + VERSION='3.1.0' # Some tools Automake needs. @@ -4025,7 +4025,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by newlib $as_me 3.0.0, which was +This file was extended by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -4082,7 +4082,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -newlib config.status 3.0.0 +newlib config.status 3.1.0 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" diff --git a/newlib/libc/sys/rtems/configure b/newlib/libc/sys/rtems/configure index c44d04332..8142f78bc 100755 --- a/newlib/libc/sys/rtems/configure +++ b/newlib/libc/sys/rtems/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for newlib 3.0.0. +# Generated by GNU Autoconf 2.68 for newlib 3.1.0. # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -556,8 +556,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='newlib' PACKAGE_TARNAME='newlib' -PACKAGE_VERSION='3.0.0' -PACKAGE_STRING='newlib 3.0.0' +PACKAGE_VERSION='3.1.0' +PACKAGE_STRING='newlib 3.1.0' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1240,7 +1240,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures newlib 3.0.0 to adapt to many kinds of systems. +\`configure' configures newlib 3.1.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1310,7 +1310,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of newlib 3.0.0:";; + short | recursive ) echo "Configuration of newlib 3.1.0:";; esac cat <<\_ACEOF @@ -1402,7 +1402,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -newlib configure 3.0.0 +newlib configure 3.1.0 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -1457,7 +1457,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by newlib $as_me 3.0.0, which was +It was created by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -2541,7 +2541,7 @@ fi # Define the identity of the package. PACKAGE='newlib' - VERSION='3.0.0' + VERSION='3.1.0' # Some tools Automake needs. @@ -4025,7 +4025,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by newlib $as_me 3.0.0, which was +This file was extended by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -4082,7 +4082,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -newlib config.status 3.0.0 +newlib config.status 3.1.0 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" diff --git a/newlib/libc/sys/sh/configure b/newlib/libc/sys/sh/configure index 88091acf2..cf83e91e0 100755 --- a/newlib/libc/sys/sh/configure +++ b/newlib/libc/sys/sh/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for newlib 3.0.0. +# Generated by GNU Autoconf 2.68 for newlib 3.1.0. # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -556,8 +556,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='newlib' PACKAGE_TARNAME='newlib' -PACKAGE_VERSION='3.0.0' -PACKAGE_STRING='newlib 3.0.0' +PACKAGE_VERSION='3.1.0' +PACKAGE_STRING='newlib 3.1.0' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1240,7 +1240,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures newlib 3.0.0 to adapt to many kinds of systems. +\`configure' configures newlib 3.1.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1310,7 +1310,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of newlib 3.0.0:";; + short | recursive ) echo "Configuration of newlib 3.1.0:";; esac cat <<\_ACEOF @@ -1402,7 +1402,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -newlib configure 3.0.0 +newlib configure 3.1.0 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -1457,7 +1457,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by newlib $as_me 3.0.0, which was +It was created by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -2541,7 +2541,7 @@ fi # Define the identity of the package. PACKAGE='newlib' - VERSION='3.0.0' + VERSION='3.1.0' # Some tools Automake needs. @@ -4025,7 +4025,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by newlib $as_me 3.0.0, which was +This file was extended by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -4082,7 +4082,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -newlib config.status 3.0.0 +newlib config.status 3.1.0 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" diff --git a/newlib/libc/sys/sparc64/configure b/newlib/libc/sys/sparc64/configure index b77f8695e..52751ecde 100755 --- a/newlib/libc/sys/sparc64/configure +++ b/newlib/libc/sys/sparc64/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for newlib 3.0.0. +# Generated by GNU Autoconf 2.68 for newlib 3.1.0. # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -556,8 +556,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='newlib' PACKAGE_TARNAME='newlib' -PACKAGE_VERSION='3.0.0' -PACKAGE_STRING='newlib 3.0.0' +PACKAGE_VERSION='3.1.0' +PACKAGE_STRING='newlib 3.1.0' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1240,7 +1240,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures newlib 3.0.0 to adapt to many kinds of systems. +\`configure' configures newlib 3.1.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1310,7 +1310,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of newlib 3.0.0:";; + short | recursive ) echo "Configuration of newlib 3.1.0:";; esac cat <<\_ACEOF @@ -1402,7 +1402,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -newlib configure 3.0.0 +newlib configure 3.1.0 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -1457,7 +1457,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by newlib $as_me 3.0.0, which was +It was created by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -2541,7 +2541,7 @@ fi # Define the identity of the package. PACKAGE='newlib' - VERSION='3.0.0' + VERSION='3.1.0' # Some tools Automake needs. @@ -4025,7 +4025,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by newlib $as_me 3.0.0, which was +This file was extended by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -4082,7 +4082,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -newlib config.status 3.0.0 +newlib config.status 3.1.0 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" diff --git a/newlib/libc/sys/sun4/configure b/newlib/libc/sys/sun4/configure index daf2c663d..093c968c2 100755 --- a/newlib/libc/sys/sun4/configure +++ b/newlib/libc/sys/sun4/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for newlib 3.0.0. +# Generated by GNU Autoconf 2.68 for newlib 3.1.0. # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -556,8 +556,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='newlib' PACKAGE_TARNAME='newlib' -PACKAGE_VERSION='3.0.0' -PACKAGE_STRING='newlib 3.0.0' +PACKAGE_VERSION='3.1.0' +PACKAGE_STRING='newlib 3.1.0' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1240,7 +1240,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures newlib 3.0.0 to adapt to many kinds of systems. +\`configure' configures newlib 3.1.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1310,7 +1310,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of newlib 3.0.0:";; + short | recursive ) echo "Configuration of newlib 3.1.0:";; esac cat <<\_ACEOF @@ -1402,7 +1402,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -newlib configure 3.0.0 +newlib configure 3.1.0 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -1457,7 +1457,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by newlib $as_me 3.0.0, which was +It was created by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -2541,7 +2541,7 @@ fi # Define the identity of the package. PACKAGE='newlib' - VERSION='3.0.0' + VERSION='3.1.0' # Some tools Automake needs. @@ -4025,7 +4025,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by newlib $as_me 3.0.0, which was +This file was extended by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -4082,7 +4082,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -newlib config.status 3.0.0 +newlib config.status 3.1.0 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" diff --git a/newlib/libc/sys/sysmec/configure b/newlib/libc/sys/sysmec/configure index 648527413..f984fc57e 100755 --- a/newlib/libc/sys/sysmec/configure +++ b/newlib/libc/sys/sysmec/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for newlib 3.0.0. +# Generated by GNU Autoconf 2.68 for newlib 3.1.0. # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -556,8 +556,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='newlib' PACKAGE_TARNAME='newlib' -PACKAGE_VERSION='3.0.0' -PACKAGE_STRING='newlib 3.0.0' +PACKAGE_VERSION='3.1.0' +PACKAGE_STRING='newlib 3.1.0' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1240,7 +1240,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures newlib 3.0.0 to adapt to many kinds of systems. +\`configure' configures newlib 3.1.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1310,7 +1310,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of newlib 3.0.0:";; + short | recursive ) echo "Configuration of newlib 3.1.0:";; esac cat <<\_ACEOF @@ -1402,7 +1402,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -newlib configure 3.0.0 +newlib configure 3.1.0 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -1457,7 +1457,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by newlib $as_me 3.0.0, which was +It was created by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -2541,7 +2541,7 @@ fi # Define the identity of the package. PACKAGE='newlib' - VERSION='3.0.0' + VERSION='3.1.0' # Some tools Automake needs. @@ -4025,7 +4025,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by newlib $as_me 3.0.0, which was +This file was extended by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -4082,7 +4082,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -newlib config.status 3.0.0 +newlib config.status 3.1.0 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" diff --git a/newlib/libc/sys/sysnec810/configure b/newlib/libc/sys/sysnec810/configure index 2dd56346b..a64780588 100755 --- a/newlib/libc/sys/sysnec810/configure +++ b/newlib/libc/sys/sysnec810/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for newlib 3.0.0. +# Generated by GNU Autoconf 2.68 for newlib 3.1.0. # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -556,8 +556,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='newlib' PACKAGE_TARNAME='newlib' -PACKAGE_VERSION='3.0.0' -PACKAGE_STRING='newlib 3.0.0' +PACKAGE_VERSION='3.1.0' +PACKAGE_STRING='newlib 3.1.0' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1240,7 +1240,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures newlib 3.0.0 to adapt to many kinds of systems. +\`configure' configures newlib 3.1.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1310,7 +1310,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of newlib 3.0.0:";; + short | recursive ) echo "Configuration of newlib 3.1.0:";; esac cat <<\_ACEOF @@ -1402,7 +1402,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -newlib configure 3.0.0 +newlib configure 3.1.0 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -1457,7 +1457,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by newlib $as_me 3.0.0, which was +It was created by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -2541,7 +2541,7 @@ fi # Define the identity of the package. PACKAGE='newlib' - VERSION='3.0.0' + VERSION='3.1.0' # Some tools Automake needs. @@ -4025,7 +4025,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by newlib $as_me 3.0.0, which was +This file was extended by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -4082,7 +4082,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -newlib config.status 3.0.0 +newlib config.status 3.1.0 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" diff --git a/newlib/libc/sys/sysnecv850/configure b/newlib/libc/sys/sysnecv850/configure index 648527413..f984fc57e 100755 --- a/newlib/libc/sys/sysnecv850/configure +++ b/newlib/libc/sys/sysnecv850/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for newlib 3.0.0. +# Generated by GNU Autoconf 2.68 for newlib 3.1.0. # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -556,8 +556,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='newlib' PACKAGE_TARNAME='newlib' -PACKAGE_VERSION='3.0.0' -PACKAGE_STRING='newlib 3.0.0' +PACKAGE_VERSION='3.1.0' +PACKAGE_STRING='newlib 3.1.0' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1240,7 +1240,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures newlib 3.0.0 to adapt to many kinds of systems. +\`configure' configures newlib 3.1.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1310,7 +1310,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of newlib 3.0.0:";; + short | recursive ) echo "Configuration of newlib 3.1.0:";; esac cat <<\_ACEOF @@ -1402,7 +1402,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -newlib configure 3.0.0 +newlib configure 3.1.0 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -1457,7 +1457,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by newlib $as_me 3.0.0, which was +It was created by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -2541,7 +2541,7 @@ fi # Define the identity of the package. PACKAGE='newlib' - VERSION='3.0.0' + VERSION='3.1.0' # Some tools Automake needs. @@ -4025,7 +4025,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by newlib $as_me 3.0.0, which was +This file was extended by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -4082,7 +4082,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -newlib config.status 3.0.0 +newlib config.status 3.1.0 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" diff --git a/newlib/libc/sys/sysvi386/configure b/newlib/libc/sys/sysvi386/configure index 010fde4f6..c5d532e87 100755 --- a/newlib/libc/sys/sysvi386/configure +++ b/newlib/libc/sys/sysvi386/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for newlib 3.0.0. +# Generated by GNU Autoconf 2.68 for newlib 3.1.0. # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -556,8 +556,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='newlib' PACKAGE_TARNAME='newlib' -PACKAGE_VERSION='3.0.0' -PACKAGE_STRING='newlib 3.0.0' +PACKAGE_VERSION='3.1.0' +PACKAGE_STRING='newlib 3.1.0' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1240,7 +1240,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures newlib 3.0.0 to adapt to many kinds of systems. +\`configure' configures newlib 3.1.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1310,7 +1310,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of newlib 3.0.0:";; + short | recursive ) echo "Configuration of newlib 3.1.0:";; esac cat <<\_ACEOF @@ -1402,7 +1402,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -newlib configure 3.0.0 +newlib configure 3.1.0 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -1457,7 +1457,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by newlib $as_me 3.0.0, which was +It was created by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -2541,7 +2541,7 @@ fi # Define the identity of the package. PACKAGE='newlib' - VERSION='3.0.0' + VERSION='3.1.0' # Some tools Automake needs. @@ -4025,7 +4025,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by newlib $as_me 3.0.0, which was +This file was extended by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -4082,7 +4082,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -newlib config.status 3.0.0 +newlib config.status 3.1.0 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" diff --git a/newlib/libc/sys/sysvnecv70/configure b/newlib/libc/sys/sysvnecv70/configure index c6b12fbed..10614e9fa 100755 --- a/newlib/libc/sys/sysvnecv70/configure +++ b/newlib/libc/sys/sysvnecv70/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for newlib 3.0.0. +# Generated by GNU Autoconf 2.68 for newlib 3.1.0. # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -556,8 +556,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='newlib' PACKAGE_TARNAME='newlib' -PACKAGE_VERSION='3.0.0' -PACKAGE_STRING='newlib 3.0.0' +PACKAGE_VERSION='3.1.0' +PACKAGE_STRING='newlib 3.1.0' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1240,7 +1240,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures newlib 3.0.0 to adapt to many kinds of systems. +\`configure' configures newlib 3.1.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1310,7 +1310,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of newlib 3.0.0:";; + short | recursive ) echo "Configuration of newlib 3.1.0:";; esac cat <<\_ACEOF @@ -1402,7 +1402,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -newlib configure 3.0.0 +newlib configure 3.1.0 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -1457,7 +1457,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by newlib $as_me 3.0.0, which was +It was created by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -2541,7 +2541,7 @@ fi # Define the identity of the package. PACKAGE='newlib' - VERSION='3.0.0' + VERSION='3.1.0' # Some tools Automake needs. @@ -4025,7 +4025,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by newlib $as_me 3.0.0, which was +This file was extended by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -4082,7 +4082,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -newlib config.status 3.0.0 +newlib config.status 3.1.0 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" diff --git a/newlib/libc/sys/tic80/configure b/newlib/libc/sys/tic80/configure index 719158d1b..86caf6e57 100755 --- a/newlib/libc/sys/tic80/configure +++ b/newlib/libc/sys/tic80/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for newlib 3.0.0. +# Generated by GNU Autoconf 2.68 for newlib 3.1.0. # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -556,8 +556,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='newlib' PACKAGE_TARNAME='newlib' -PACKAGE_VERSION='3.0.0' -PACKAGE_STRING='newlib 3.0.0' +PACKAGE_VERSION='3.1.0' +PACKAGE_STRING='newlib 3.1.0' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1240,7 +1240,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures newlib 3.0.0 to adapt to many kinds of systems. +\`configure' configures newlib 3.1.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1310,7 +1310,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of newlib 3.0.0:";; + short | recursive ) echo "Configuration of newlib 3.1.0:";; esac cat <<\_ACEOF @@ -1402,7 +1402,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -newlib configure 3.0.0 +newlib configure 3.1.0 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -1457,7 +1457,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by newlib $as_me 3.0.0, which was +It was created by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -2541,7 +2541,7 @@ fi # Define the identity of the package. PACKAGE='newlib' - VERSION='3.0.0' + VERSION='3.1.0' # Some tools Automake needs. @@ -4025,7 +4025,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by newlib $as_me 3.0.0, which was +This file was extended by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -4082,7 +4082,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -newlib config.status 3.0.0 +newlib config.status 3.1.0 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" diff --git a/newlib/libc/sys/tirtos/configure b/newlib/libc/sys/tirtos/configure index 73407b954..ef219e061 100755 --- a/newlib/libc/sys/tirtos/configure +++ b/newlib/libc/sys/tirtos/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for newlib 3.0.0. +# Generated by GNU Autoconf 2.68 for newlib 3.1.0. # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -556,8 +556,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='newlib' PACKAGE_TARNAME='newlib' -PACKAGE_VERSION='3.0.0' -PACKAGE_STRING='newlib 3.0.0' +PACKAGE_VERSION='3.1.0' +PACKAGE_STRING='newlib 3.1.0' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1240,7 +1240,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures newlib 3.0.0 to adapt to many kinds of systems. +\`configure' configures newlib 3.1.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1310,7 +1310,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of newlib 3.0.0:";; + short | recursive ) echo "Configuration of newlib 3.1.0:";; esac cat <<\_ACEOF @@ -1402,7 +1402,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -newlib configure 3.0.0 +newlib configure 3.1.0 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -1457,7 +1457,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by newlib $as_me 3.0.0, which was +It was created by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -2541,7 +2541,7 @@ fi # Define the identity of the package. PACKAGE='newlib' - VERSION='3.0.0' + VERSION='3.1.0' # Some tools Automake needs. @@ -4025,7 +4025,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by newlib $as_me 3.0.0, which was +This file was extended by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -4082,7 +4082,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -newlib config.status 3.0.0 +newlib config.status 3.1.0 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" diff --git a/newlib/libc/sys/w65/configure b/newlib/libc/sys/w65/configure index 925fd47ed..110ee4624 100755 --- a/newlib/libc/sys/w65/configure +++ b/newlib/libc/sys/w65/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for newlib 3.0.0. +# Generated by GNU Autoconf 2.68 for newlib 3.1.0. # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -556,8 +556,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='newlib' PACKAGE_TARNAME='newlib' -PACKAGE_VERSION='3.0.0' -PACKAGE_STRING='newlib 3.0.0' +PACKAGE_VERSION='3.1.0' +PACKAGE_STRING='newlib 3.1.0' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1240,7 +1240,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures newlib 3.0.0 to adapt to many kinds of systems. +\`configure' configures newlib 3.1.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1310,7 +1310,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of newlib 3.0.0:";; + short | recursive ) echo "Configuration of newlib 3.1.0:";; esac cat <<\_ACEOF @@ -1402,7 +1402,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -newlib configure 3.0.0 +newlib configure 3.1.0 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -1457,7 +1457,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by newlib $as_me 3.0.0, which was +It was created by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -2541,7 +2541,7 @@ fi # Define the identity of the package. PACKAGE='newlib' - VERSION='3.0.0' + VERSION='3.1.0' # Some tools Automake needs. @@ -4025,7 +4025,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by newlib $as_me 3.0.0, which was +This file was extended by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -4082,7 +4082,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -newlib config.status 3.0.0 +newlib config.status 3.1.0 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" diff --git a/newlib/libc/sys/z8ksim/configure b/newlib/libc/sys/z8ksim/configure index 01e808889..64ea62907 100755 --- a/newlib/libc/sys/z8ksim/configure +++ b/newlib/libc/sys/z8ksim/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for newlib 3.0.0. +# Generated by GNU Autoconf 2.68 for newlib 3.1.0. # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -556,8 +556,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='newlib' PACKAGE_TARNAME='newlib' -PACKAGE_VERSION='3.0.0' -PACKAGE_STRING='newlib 3.0.0' +PACKAGE_VERSION='3.1.0' +PACKAGE_STRING='newlib 3.1.0' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1240,7 +1240,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures newlib 3.0.0 to adapt to many kinds of systems. +\`configure' configures newlib 3.1.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1310,7 +1310,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of newlib 3.0.0:";; + short | recursive ) echo "Configuration of newlib 3.1.0:";; esac cat <<\_ACEOF @@ -1402,7 +1402,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -newlib configure 3.0.0 +newlib configure 3.1.0 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -1457,7 +1457,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by newlib $as_me 3.0.0, which was +It was created by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -2541,7 +2541,7 @@ fi # Define the identity of the package. PACKAGE='newlib' - VERSION='3.0.0' + VERSION='3.1.0' # Some tools Automake needs. @@ -4025,7 +4025,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by newlib $as_me 3.0.0, which was +This file was extended by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -4082,7 +4082,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -newlib config.status 3.0.0 +newlib config.status 3.1.0 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" diff --git a/newlib/libm/configure b/newlib/libm/configure index 8932b51c1..e8a0a994a 100755 --- a/newlib/libm/configure +++ b/newlib/libm/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for newlib 3.0.0. +# Generated by GNU Autoconf 2.68 for newlib 3.1.0. # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -567,8 +567,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='newlib' PACKAGE_TARNAME='newlib' -PACKAGE_VERSION='3.0.0' -PACKAGE_STRING='newlib 3.0.0' +PACKAGE_VERSION='3.1.0' +PACKAGE_STRING='newlib 3.1.0' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1331,7 +1331,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures newlib 3.0.0 to adapt to many kinds of systems. +\`configure' configures newlib 3.1.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1401,7 +1401,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of newlib 3.0.0:";; + short | recursive ) echo "Configuration of newlib 3.1.0:";; esac cat <<\_ACEOF @@ -1514,7 +1514,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -newlib configure 3.0.0 +newlib configure 3.1.0 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -1792,7 +1792,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by newlib $as_me 3.0.0, which was +It was created by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -2931,7 +2931,7 @@ fi # Define the identity of the package. PACKAGE='newlib' - VERSION='3.0.0' + VERSION='3.1.0' # Some tools Automake needs. @@ -12484,7 +12484,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by newlib $as_me 3.0.0, which was +This file was extended by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -12541,7 +12541,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -newlib config.status 3.0.0 +newlib config.status 3.1.0 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" diff --git a/newlib/libm/machine/aarch64/configure b/newlib/libm/machine/aarch64/configure index 6a6ad6044..24feba10f 100755 --- a/newlib/libm/machine/aarch64/configure +++ b/newlib/libm/machine/aarch64/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for newlib 3.0.0. +# Generated by GNU Autoconf 2.68 for newlib 3.1.0. # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -556,8 +556,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='newlib' PACKAGE_TARNAME='newlib' -PACKAGE_VERSION='3.0.0' -PACKAGE_STRING='newlib 3.0.0' +PACKAGE_VERSION='3.1.0' +PACKAGE_STRING='newlib 3.1.0' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1240,7 +1240,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures newlib 3.0.0 to adapt to many kinds of systems. +\`configure' configures newlib 3.1.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1310,7 +1310,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of newlib 3.0.0:";; + short | recursive ) echo "Configuration of newlib 3.1.0:";; esac cat <<\_ACEOF @@ -1402,7 +1402,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -newlib configure 3.0.0 +newlib configure 3.1.0 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -1457,7 +1457,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by newlib $as_me 3.0.0, which was +It was created by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -2541,7 +2541,7 @@ fi # Define the identity of the package. PACKAGE='newlib' - VERSION='3.0.0' + VERSION='3.1.0' # Some tools Automake needs. @@ -4025,7 +4025,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by newlib $as_me 3.0.0, which was +This file was extended by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -4082,7 +4082,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -newlib config.status 3.0.0 +newlib config.status 3.1.0 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" diff --git a/newlib/libm/machine/arm/configure b/newlib/libm/machine/arm/configure index 6a6ad6044..24feba10f 100755 --- a/newlib/libm/machine/arm/configure +++ b/newlib/libm/machine/arm/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for newlib 3.0.0. +# Generated by GNU Autoconf 2.68 for newlib 3.1.0. # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -556,8 +556,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='newlib' PACKAGE_TARNAME='newlib' -PACKAGE_VERSION='3.0.0' -PACKAGE_STRING='newlib 3.0.0' +PACKAGE_VERSION='3.1.0' +PACKAGE_STRING='newlib 3.1.0' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1240,7 +1240,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures newlib 3.0.0 to adapt to many kinds of systems. +\`configure' configures newlib 3.1.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1310,7 +1310,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of newlib 3.0.0:";; + short | recursive ) echo "Configuration of newlib 3.1.0:";; esac cat <<\_ACEOF @@ -1402,7 +1402,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -newlib configure 3.0.0 +newlib configure 3.1.0 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -1457,7 +1457,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by newlib $as_me 3.0.0, which was +It was created by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -2541,7 +2541,7 @@ fi # Define the identity of the package. PACKAGE='newlib' - VERSION='3.0.0' + VERSION='3.1.0' # Some tools Automake needs. @@ -4025,7 +4025,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by newlib $as_me 3.0.0, which was +This file was extended by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -4082,7 +4082,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -newlib config.status 3.0.0 +newlib config.status 3.1.0 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" diff --git a/newlib/libm/machine/configure b/newlib/libm/machine/configure index 758639f9b..071a70c6f 100755 --- a/newlib/libm/machine/configure +++ b/newlib/libm/machine/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for newlib 3.0.0. +# Generated by GNU Autoconf 2.68 for newlib 3.1.0. # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -567,8 +567,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='newlib' PACKAGE_TARNAME='newlib' -PACKAGE_VERSION='3.0.0' -PACKAGE_STRING='newlib 3.0.0' +PACKAGE_VERSION='3.1.0' +PACKAGE_STRING='newlib 3.1.0' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -765,6 +765,7 @@ enable_newlib_iconv enable_newlib_elix_level enable_newlib_io_float enable_newlib_supplied_syscalls +enable_newlib_fno_builtin enable_dependency_tracking enable_maintainer_mode enable_shared @@ -1332,7 +1333,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures newlib 3.0.0 to adapt to many kinds of systems. +\`configure' configures newlib 3.1.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1402,7 +1403,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of newlib 3.0.0:";; + short | recursive ) echo "Configuration of newlib 3.1.0:";; esac cat <<\_ACEOF @@ -1418,6 +1419,7 @@ Optional Features: --enable-newlib-elix-level supply desired elix library level (1-4) --disable-newlib-io-float disable printf/scanf family float support --disable-newlib-supplied-syscalls disable newlib from supplying syscalls + --disable-newlib-fno-builtin disable -fno-builtin flag to allow compiler to use builtin library functions --disable-dependency-tracking speeds up one-time build --enable-dependency-tracking do not reject slow dependency extractors --enable-maintainer-mode enable make rules and dependencies not useful @@ -1513,7 +1515,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -newlib configure 3.0.0 +newlib configure 3.1.0 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -1791,7 +1793,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by newlib $as_me 3.0.0, which was +It was created by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -2825,6 +2827,18 @@ else fi +# Check whether --enable-newlib-fno-builtin was given. +if test "${enable_newlib_fno_builtin+set}" = set; then : + enableval=$enable_newlib_fno_builtin; case "${enableval}" in + yes) newlib_fno_builtin=yes ;; + no) newlib_fno_builtin=no ;; + *) as_fn_error $? "bad value ${enableval} for newlib-fno-builtin option" "$LINENO" 5 ;; + esac +else + newlib_fno_builtin= +fi + + test -z "${with_target_subdir}" && with_target_subdir=. @@ -2863,7 +2877,7 @@ fi # Define the identity of the package. PACKAGE='newlib' - VERSION='3.0.0' + VERSION='3.1.0' # Some tools Automake needs. @@ -11439,7 +11453,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 11442 "configure" +#line 11456 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -11545,7 +11559,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 11548 "configure" +#line 11562 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -12433,7 +12447,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by newlib $as_me 3.0.0, which was +This file was extended by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -12490,7 +12504,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -newlib config.status 3.0.0 +newlib config.status 3.1.0 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" diff --git a/newlib/libm/machine/i386/configure b/newlib/libm/machine/i386/configure index 7bf72e76a..f2625be55 100755 --- a/newlib/libm/machine/i386/configure +++ b/newlib/libm/machine/i386/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for newlib 3.0.0. +# Generated by GNU Autoconf 2.68 for newlib 3.1.0. # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -567,8 +567,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='newlib' PACKAGE_TARNAME='newlib' -PACKAGE_VERSION='3.0.0' -PACKAGE_STRING='newlib 3.0.0' +PACKAGE_VERSION='3.1.0' +PACKAGE_STRING='newlib 3.1.0' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1323,7 +1323,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures newlib 3.0.0 to adapt to many kinds of systems. +\`configure' configures newlib 3.1.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1393,7 +1393,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of newlib 3.0.0:";; + short | recursive ) echo "Configuration of newlib 3.1.0:";; esac cat <<\_ACEOF @@ -1505,7 +1505,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -newlib configure 3.0.0 +newlib configure 3.1.0 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -1783,7 +1783,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by newlib $as_me 3.0.0, which was +It was created by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -2867,7 +2867,7 @@ fi # Define the identity of the package. PACKAGE='newlib' - VERSION='3.0.0' + VERSION='3.1.0' # Some tools Automake needs. @@ -12396,7 +12396,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by newlib $as_me 3.0.0, which was +This file was extended by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -12453,7 +12453,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -newlib config.status 3.0.0 +newlib config.status 3.1.0 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" diff --git a/newlib/libm/machine/nds32/configure b/newlib/libm/machine/nds32/configure index c3de10651..a63428eb5 100644 --- a/newlib/libm/machine/nds32/configure +++ b/newlib/libm/machine/nds32/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for newlib 3.0.0. +# Generated by GNU Autoconf 2.68 for newlib 3.1.0. # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -556,8 +556,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='newlib' PACKAGE_TARNAME='newlib' -PACKAGE_VERSION='3.0.0' -PACKAGE_STRING='newlib 3.0.0' +PACKAGE_VERSION='3.1.0' +PACKAGE_STRING='newlib 3.1.0' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1256,7 +1256,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures newlib 3.0.0 to adapt to many kinds of systems. +\`configure' configures newlib 3.1.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1326,7 +1326,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of newlib 3.0.0:";; + short | recursive ) echo "Configuration of newlib 3.1.0:";; esac cat <<\_ACEOF @@ -1425,7 +1425,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -newlib configure 3.0.0 +newlib configure 3.1.0 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -1480,7 +1480,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by newlib $as_me 3.0.0, which was +It was created by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -2564,7 +2564,7 @@ fi # Define the identity of the package. PACKAGE='newlib' - VERSION='3.0.0' + VERSION='3.1.0' # Some tools Automake needs. @@ -5122,7 +5122,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by newlib $as_me 3.0.0, which was +This file was extended by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -5179,7 +5179,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -newlib config.status 3.0.0 +newlib config.status 3.1.0 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" diff --git a/newlib/libm/machine/riscv/configure b/newlib/libm/machine/riscv/configure index 6a6ad6044..24feba10f 100755 --- a/newlib/libm/machine/riscv/configure +++ b/newlib/libm/machine/riscv/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for newlib 3.0.0. +# Generated by GNU Autoconf 2.68 for newlib 3.1.0. # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -556,8 +556,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='newlib' PACKAGE_TARNAME='newlib' -PACKAGE_VERSION='3.0.0' -PACKAGE_STRING='newlib 3.0.0' +PACKAGE_VERSION='3.1.0' +PACKAGE_STRING='newlib 3.1.0' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1240,7 +1240,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures newlib 3.0.0 to adapt to many kinds of systems. +\`configure' configures newlib 3.1.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1310,7 +1310,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of newlib 3.0.0:";; + short | recursive ) echo "Configuration of newlib 3.1.0:";; esac cat <<\_ACEOF @@ -1402,7 +1402,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -newlib configure 3.0.0 +newlib configure 3.1.0 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -1457,7 +1457,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by newlib $as_me 3.0.0, which was +It was created by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -2541,7 +2541,7 @@ fi # Define the identity of the package. PACKAGE='newlib' - VERSION='3.0.0' + VERSION='3.1.0' # Some tools Automake needs. @@ -4025,7 +4025,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by newlib $as_me 3.0.0, which was +This file was extended by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -4082,7 +4082,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -newlib config.status 3.0.0 +newlib config.status 3.1.0 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" diff --git a/newlib/libm/machine/spu/configure b/newlib/libm/machine/spu/configure index 6a6ad6044..24feba10f 100644 --- a/newlib/libm/machine/spu/configure +++ b/newlib/libm/machine/spu/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for newlib 3.0.0. +# Generated by GNU Autoconf 2.68 for newlib 3.1.0. # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -556,8 +556,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='newlib' PACKAGE_TARNAME='newlib' -PACKAGE_VERSION='3.0.0' -PACKAGE_STRING='newlib 3.0.0' +PACKAGE_VERSION='3.1.0' +PACKAGE_STRING='newlib 3.1.0' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1240,7 +1240,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures newlib 3.0.0 to adapt to many kinds of systems. +\`configure' configures newlib 3.1.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1310,7 +1310,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of newlib 3.0.0:";; + short | recursive ) echo "Configuration of newlib 3.1.0:";; esac cat <<\_ACEOF @@ -1402,7 +1402,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -newlib configure 3.0.0 +newlib configure 3.1.0 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -1457,7 +1457,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by newlib $as_me 3.0.0, which was +It was created by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -2541,7 +2541,7 @@ fi # Define the identity of the package. PACKAGE='newlib' - VERSION='3.0.0' + VERSION='3.1.0' # Some tools Automake needs. @@ -4025,7 +4025,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by newlib $as_me 3.0.0, which was +This file was extended by newlib $as_me 3.1.0, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -4082,7 +4082,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -newlib config.status 3.0.0 +newlib config.status 3.1.0 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" From 353ebae30465606bd8b15bea1194f7a2881903fb Mon Sep 17 00:00:00 2001 From: Wilco Dijkstra Date: Mon, 31 Dec 2018 18:01:52 +0000 Subject: [PATCH 041/475] Improve performance of memmem MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch significantly improves performance of memmem using a novel modified Horspool algorithm.  Needles up to size 256 use a bad-character table indexed by hashed pairs of characters to quickly skip past mismatches. Long needles use a self-adapting filtering step to avoid comparing the whole needle repeatedly. By limiting the needle length to 256, the shift table only requires 8 bits per entry, lowering preprocessing overhead and minimizing cache effects. This limit also implies worst-case performance is linear. Small needles up to size 2 use a dedicated linear search.  Very long needles use the Two-Way algorithm (to avoid increasing stack size inlining is now disabled). The performance gain is 6.6 times on English text on AArch64 using random needles with average size 8 (this is even faster than the recently improved strstr algorithm, so I'll update that in the near future). The size-optimized memmem has also been rewritten from scratch to get a 2.7x performance gain. Tested against GLIBC testsuite and randomized tests. Message-Id: --- newlib/libc/string/memmem.c | 199 ++++++++++++++++++++++--------- newlib/libc/string/str-two-way.h | 3 +- 2 files changed, 144 insertions(+), 58 deletions(-) diff --git a/newlib/libc/string/memmem.c b/newlib/libc/string/memmem.c index 5c57eff9c..55d2459aa 100644 --- a/newlib/libc/string/memmem.c +++ b/newlib/libc/string/memmem.c @@ -1,8 +1,30 @@ -/* Byte-wise substring search, using the Two-Way algorithm. - * Copyright (C) 2008 Eric Blake - * Permission to use, copy, modify, and distribute this software - * is freely granted, provided that this notice is preserved. - */ +/* Optimized memmem function. + Copyright (c) 2018 Arm Ltd. All rights reserved. + + SPDX-License-Identifier: BSD-3-Clause + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. The name of the company may not be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY ARM LTD ``AS IS'' AND ANY EXPRESS OR IMPLIED + WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + IN NO EVENT SHALL ARM LTD BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* FUNCTION @@ -13,7 +35,7 @@ INDEX SYNOPSIS #include - char *memmem(const void *<[s1]>, size_t <[l1]>, const void *<[s2]>, + void *memmem(const void *<[s1]>, size_t <[l1]>, const void *<[s2]>, size_t <[l2]>); DESCRIPTION @@ -21,8 +43,8 @@ DESCRIPTION Locates the first occurrence in the memory region pointed to by <[s1]> with length <[l1]> of the sequence of bytes pointed to by <[s2]> of length <[l2]>. If you already know the - lengths of your haystack and needle, <> can be much - faster than <>. + lengths of your haystack and needle, <> is much faster + than <>. RETURNS Returns a pointer to the located segment, or a null pointer if @@ -38,64 +60,127 @@ QUICKREF */ #include - -#if !defined(PREFER_SIZE_OVER_SPEED) && !defined(__OPTIMIZE_SIZE__) -# define RETURN_TYPE void * -# define AVAILABLE(h, h_l, j, n_l) ((j) <= (h_l) - (n_l)) -# include "str-two-way.h" -#endif - -void * -memmem (const void *haystack_start, - size_t haystack_len, - const void *needle_start, - size_t needle_len) -{ - /* Abstract memory is considered to be an array of 'unsigned char' values, - not an array of 'char' values. See ISO C 99 section 6.2.6.1. */ - const unsigned char *haystack = (const unsigned char *) haystack_start; - const unsigned char *needle = (const unsigned char *) needle_start; - - if (needle_len == 0) - /* The first occurrence of the empty string is deemed to occur at - the beginning of the string. */ - return (void *) haystack; +#include #if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__) - /* Less code size, but quadratic performance in the worst case. */ - while (needle_len <= haystack_len) - { - if (!memcmp (haystack, needle, needle_len)) - return (void *) haystack; - haystack++; - haystack_len--; - } +/* Small and efficient memmem implementation (quadratic worst-case). */ +void * +memmem (const void *haystack, size_t hs_len, const void *needle, size_t ne_len) +{ + const char *hs = haystack; + const char *ne = needle; + + if (ne_len == 0) + return (void *)hs; + int i; + int c = ne[0]; + const char *end = hs + hs_len - ne_len; + + for ( ; hs <= end; hs++) + { + if (hs[0] != c) + continue; + for (i = ne_len - 1; i != 0; i--) + if (hs[i] != ne[i]) + break; + if (i == 0) + return (void *)hs; + } + return NULL; +} -#else /* compilation for speed */ +#else - /* Larger code size, but guaranteed linear performance. */ +# define RETURN_TYPE void * +# define AVAILABLE(h, h_l, j, n_l) ((j) <= (h_l) - (n_l)) +# include "str-two-way.h" - /* Sanity check, otherwise the loop might search through the whole - memory. */ - if (haystack_len < needle_len) +#define hash2(p) (((size_t)(p)[0] - ((size_t)(p)[-1] << 3)) % sizeof (shift)) + +/* Fast memmem algorithm with guaranteed linear-time performance. + Small needles up to size 2 use a dedicated linear search. Longer needles + up to size 256 use a novel modified Horspool algorithm. It hashes pairs + of characters to quickly skip past mismatches. The main search loop only + exits if the last 2 characters match, avoiding unnecessary calls to memcmp + and allowing for a larger skip if there is no match. A self-adapting + filtering check is used to quickly detect mismatches in long needles. + By limiting the needle length to 256, the shift table can be reduced to 8 + bits per entry, lowering preprocessing overhead and minimizing cache effects. + The limit also implies worst-case performance is linear. + Needles larger than 256 characters use the linear-time Two-Way algorithm. */ +void * +memmem (const void *haystack, size_t hs_len, const void *needle, size_t ne_len) +{ + const unsigned char *hs = haystack; + const unsigned char *ne = needle; + + if (ne_len == 0) + return (void *) hs; + if (ne_len == 1) + return (void *) memchr (hs, ne[0], hs_len); + + /* Ensure haystack length is >= needle length. */ + if (hs_len < ne_len) return NULL; - /* Use optimizations in memchr when possible, to reduce the search - size of haystack using a linear algorithm with a smaller - coefficient. However, avoid memchr for long needles, since we - can often achieve sublinear performance. */ - if (needle_len < LONG_NEEDLE_THRESHOLD) + const unsigned char *end = hs + hs_len - ne_len; + + if (ne_len == 2) { - haystack = memchr (haystack, *needle, haystack_len); - if (!haystack || needle_len == 1) - return (void *) haystack; - haystack_len -= haystack - (const unsigned char *) haystack_start; - if (haystack_len < needle_len) - return NULL; - return two_way_short_needle (haystack, haystack_len, needle, needle_len); + uint32_t nw = ne[0] << 16 | ne[1], hw = hs[0] << 16 | hs[1]; + for (hs++; hs <= end && hw != nw; ) + hw = hw << 16 | *++hs; + return hw == nw ? (void *)(hs - 1) : NULL; } - return two_way_long_needle (haystack, haystack_len, needle, needle_len); -#endif /* compilation for speed */ + + /* Use Two-Way algorithm for very long needles. */ + if (__builtin_expect (ne_len > 256, 0)) + return two_way_long_needle (hs, hs_len, ne, ne_len); + + uint8_t shift[256]; + size_t tmp, shift1; + size_t m1 = ne_len - 1; + size_t offset = 0; + + /* Initialize bad character shift hash table. */ + memset (shift, 0, sizeof (shift)); + for (int i = 1; i < m1; i++) + shift[hash2 (ne + i)] = i; + shift1 = m1 - shift[hash2 (ne + m1)]; + shift[hash2 (ne + m1)] = m1; + + for ( ; hs <= end; ) + { + /* Skip past character pairs not in the needle. */ + do + { + hs += m1; + tmp = shift[hash2 (hs)]; + } + while (hs <= end && tmp == 0); + + /* If the match is not at the end of the needle, shift to the end + and continue until we match the last 2 characters. */ + hs -= tmp; + if (tmp < m1) + continue; + + /* The last 2 characters match. If the needle is long, check a + fixed number of characters first to quickly filter out mismatches. */ + if (m1 <= 15 || memcmp (hs + offset, ne + offset, sizeof (long)) == 0) + { + if (memcmp (hs, ne, m1) == 0) + return (void *) hs; + + /* Adjust filter offset when it doesn't find the mismatch. */ + offset = (offset >= sizeof (long) ? offset : m1) - sizeof (long); + } + + /* Skip based on matching the last 2 characters. */ + hs += shift1; + } + return NULL; } +#endif /* Compilation for speed. */ diff --git a/newlib/libc/string/str-two-way.h b/newlib/libc/string/str-two-way.h index 416f9d29f..90345a8de 100644 --- a/newlib/libc/string/str-two-way.h +++ b/newlib/libc/string/str-two-way.h @@ -31,6 +31,7 @@ #include #include +#include <_ansi.h> /* We use the Two-Way string matching algorithm, which guarantees linear complexity with constant space. Additionally, for long @@ -288,7 +289,7 @@ two_way_short_needle (const unsigned char *haystack, size_t haystack_len, If AVAILABLE modifies HAYSTACK_LEN (as in strstr), then at most 3 * HAYSTACK_LEN - NEEDLE_LEN comparisons occur in searching, and sublinear performance is not possible. */ -static RETURN_TYPE +_NOINLINE_STATIC RETURN_TYPE two_way_long_needle (const unsigned char *haystack, size_t haystack_len, const unsigned char *needle, size_t needle_len) { From 34d9bb709390b14b4ed0b1ea2656bf6bf5a055c3 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Fri, 4 Jan 2019 11:00:57 +0100 Subject: [PATCH 042/475] Cygwin: drop disabled O_TMPFILE POSIX unlink code The commit message of commit 07e0a9584f9a5b2668c767ede0482a5fba498731 and the expectation set therein, are wrong. There's no POSIX semantics allowing to link a file with a link count of 0 and making it available in the file system again. In fact, the Linux linkat extension AT_EMPTY_PATH explicitely disallows to link a file descriptor to a file with a link count of 0, except for O_TMPFILE without O_EXCL. Signed-off-by: Corinna Vinschen --- winsup/cygwin/syscalls.cc | 40 --------------------------------------- 1 file changed, 40 deletions(-) diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc index 0d4809037..73c15b133 100644 --- a/winsup/cygwin/syscalls.cc +++ b/winsup/cygwin/syscalls.cc @@ -1467,46 +1467,6 @@ open (const char *unix_path, int flags, ...) if ((fh->is_fs_special () && fh->device_access_denied (flags)) || !fh->open_with_arch (flags, mode & 07777)) __leave; /* errno already set */ -#if 0 - /* Don't use W10 1709 POSIX unlink semantics here. - - Including W10 1809, NtSetInformationFile(FileLinkInformation) on a - HANDLE to a file unlinked with POSIX semantics fails with - STATUS_ACCESS_DENIED. Trying to remove the delete disposition on - the file prior to calling link fails with STATUS_FILE_DELETED. - This breaks - - fd = open(O_TMPFILE); - linkat("/proc/self/fd/); - - semantics. */ - if ((flags & O_TMPFILE) && wincap.has_posix_file_info () - && !fh->pc.isremote () && fh->pc.fs_is_ntfs ()) - { - HANDLE del_h; - OBJECT_ATTRIBUTES attr; - NTSTATUS status; - IO_STATUS_BLOCK io; - FILE_DISPOSITION_INFORMATION_EX fdie; - - status = NtOpenFile (&del_h, DELETE, - fh->pc.init_reopen_attr (attr, fh->get_handle ()), &io, - FILE_SHARE_VALID_FLAGS, FILE_OPEN_FOR_BACKUP_INTENT); - if (!NT_SUCCESS (status)) - debug_printf ("reopening tmpfile handle failed, status %y", status); - else - { - fdie.Flags = FILE_DISPOSITION_DELETE - | FILE_DISPOSITION_POSIX_SEMANTICS; - status = NtSetInformationFile (del_h, &io, &fdie, sizeof fdie, - FileDispositionInformationEx); - if (!NT_SUCCESS (status)) - debug_printf ("Setting POSIX delete disposition on tmpfile " - "failed, status = %y", status); - NtClose (del_h); - } - } -#endif fd = fh; if (fd <= 2) set_std_handle (fd); From 844a1b4fe40db93e266cd7045c3b5c443b5d703a Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Sat, 5 Jan 2019 11:31:52 +0100 Subject: [PATCH 043/475] Cygwin: path_conv: nobody cares if a path had symlinks after the fact remove set_has_symlinks/has_symlinks/PATH_HAS_SYMLINKS. Nobody's asking for this information. Signed-off-by: Corinna Vinschen --- winsup/cygwin/path.cc | 5 ----- winsup/cygwin/path.h | 3 --- 2 files changed, 8 deletions(-) diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc index 3cb46c9c8..ee15decf5 100644 --- a/winsup/cygwin/path.cc +++ b/winsup/cygwin/path.cc @@ -652,7 +652,6 @@ path_conv::check (const char *src, unsigned opt, char *THIS_path = tp.c_get (); symlink_info sym; bool need_directory = 0; - bool saw_symlinks = 0; bool add_ext = false; bool is_relpath; char *tail, *path_end; @@ -1007,7 +1006,6 @@ path_conv::check (const char *src, unsigned opt, these operations again on the newly derived path. */ else if (symlen > 0) { - saw_symlinks = 1; if (component == 0 && !need_directory && (!(opt & PC_SYM_FOLLOW) || (is_known_reparse_point () @@ -1228,9 +1226,6 @@ path_conv::check (const char *src, unsigned opt, } } - if (saw_symlinks) - set_has_symlinks (); - if (opt & PC_OPEN) path_flags |= PATH_OPEN; diff --git a/winsup/cygwin/path.h b/winsup/cygwin/path.h index 309247d5f..3f84da227 100644 --- a/winsup/cygwin/path.h +++ b/winsup/cygwin/path.h @@ -83,7 +83,6 @@ enum path_types PATH_LNK = 0x01000000, PATH_TEXT = 0x02000000, PATH_REP = 0x04000000, - PATH_HAS_SYMLINKS = 0x10000000, PATH_SOCKET = 0x40000000 }; @@ -168,7 +167,6 @@ class path_conv return (path_flags & PATH_SPARSE) && (fs_flags () & FILE_SUPPORTS_SPARSE_FILES); } - int has_symlinks () const {return path_flags & PATH_HAS_SYMLINKS;} int has_dos_filenames_only () const {return path_flags & PATH_DOS;} int has_buggy_reopen () const {return fs.has_buggy_reopen ();} int has_buggy_fileid_dirinfo () const {return fs.has_buggy_fileid_dirinfo ();} @@ -232,7 +230,6 @@ class path_conv } void set_symlink (DWORD n) {path_flags |= PATH_SYMLINK; symlink_length = n;} - void set_has_symlinks () {path_flags |= PATH_HAS_SYMLINKS;} void set_exec (int x = 1) {path_flags |= x ? PATH_EXEC : PATH_NOTEXEC;} void __reg3 check (const UNICODE_STRING *upath, unsigned opt = PC_SYM_FOLLOW, From 36ff506ddccb20c7a2c8ca35433b774d477dd694 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Sat, 5 Jan 2019 11:32:23 +0100 Subject: [PATCH 044/475] Cygwin: try_to_bin: fix typos in comments Signed-off-by: Corinna Vinschen --- winsup/cygwin/syscalls.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc index 73c15b133..3a7ecd218 100644 --- a/winsup/cygwin/syscalls.cc +++ b/winsup/cygwin/syscalls.cc @@ -271,7 +271,7 @@ try_to_bin (path_conv &pc, HANDLE &fh, ACCESS_MASK access, ULONG flags) if (RtlEqualUnicodeString (&fname, &recycler, TRUE)) goto out; /* Is fname really a subcomponent of the full path? If not, there's - a high probability we're acessing the file via a virtual drive + a high probability we're accessing the file via a virtual drive created with "subst". Check and accommodate it. Note that we only get here if the virtual drive is really pointing to a local drive. Otherwise pc.isremote () returns "true". */ @@ -313,7 +313,7 @@ try_to_bin (path_conv &pc, HANDLE &fh, ACCESS_MASK access, ULONG flags) /* Store length of recycler base dir, if it's necessary to create it. */ recycler_base_len = recycler.Length; /* On NTFS or ReFS the recycler dir contains user specific subdirs, which - are the actual recycle bins per user. The name if this dir is the + are the actual recycle bins per user. The name of this dir is the string representation of the user SID. */ if (fs_has_per_user_recycler) { From f72191ac0177883bb395d8d5f0ddc3f45b5dd29d Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Sat, 5 Jan 2019 21:36:34 +0100 Subject: [PATCH 045/475] Cygwin: return correct FH_PROCESSFD for files under /proc/PID/fd subdir This allows easier handling of fd symlinks. Signed-off-by: Corinna Vinschen --- winsup/cygwin/fhandler_proc.cc | 12 ++++++++++-- winsup/cygwin/path.cc | 2 +- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/winsup/cygwin/fhandler_proc.cc b/winsup/cygwin/fhandler_proc.cc index c9761b5b9..cda2f72a2 100644 --- a/winsup/cygwin/fhandler_proc.cc +++ b/winsup/cygwin/fhandler_proc.cc @@ -134,14 +134,22 @@ fhandler_proc::get_proc_fhandler (const char *path) if (entry) return entry->fhandler; - int pid = atoi (path); + char *e; + pid_t pid = strtoul (path, &e, 10); + if (*e != '/' && *e != '\0') + return FH_NADA; pinfo p (pid); /* If p->pid != pid, then pid is actually the Windows PID for an execed Cygwin process, and the pinfo entry is the additional entry created at exec time. We don't want to enable the user to access a process entry by using the Win32 PID, though. */ if (p && p->pid == pid) - return FH_PROCESS; + { + /* Check for entry in fd subdir */ + if (!strncmp (++e, "fd/", 3) && e[3] != '\0') + return FH_PROCESSFD; + return FH_PROCESS; + } bool has_subdir = false; while (*path) diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc index ee15decf5..3324395cb 100644 --- a/winsup/cygwin/path.cc +++ b/winsup/cygwin/path.cc @@ -806,7 +806,7 @@ path_conv::check (const char *src, unsigned opt, fh->fill_filebuf (); symlen = sym.set (fh->get_filebuf ()); } - else if (file_type == virt_fsdir && dev == FH_PROCESS) + else if (file_type == virt_fsdir && dev == FH_PROCESSFD) { /* FIXME: This is YA bad hack to workaround that we're checking for isvirtual_dev at this point. From a3a5d52b398887a5ee1ca75b23915d17a60ac10a Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Sat, 5 Jan 2019 21:41:01 +0100 Subject: [PATCH 046/475] Cygwin: introduce virt_fdsymlink to simplify /proc/PID/fd symlink handling Signed-off-by: Corinna Vinschen --- winsup/cygwin/fhandler.h | 1 + winsup/cygwin/fhandler_process.cc | 3 ++- winsup/cygwin/path.cc | 4 +++- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h index 07e8a1834..0ead0d90c 100644 --- a/winsup/cygwin/fhandler.h +++ b/winsup/cygwin/fhandler.h @@ -126,6 +126,7 @@ enum del_lock_called_from { }; enum virtual_ftype_t { + virt_fdsymlink = -8, /* Fd symlink (e.g. /proc//fd/0) */ virt_blk = -7, /* Block special */ virt_chr = -6, /* Character special */ virt_fsfile = -5, /* FS-based file via /proc/sys */ diff --git a/winsup/cygwin/fhandler_process.cc b/winsup/cygwin/fhandler_process.cc index b0fae4cce..24ef7d00c 100644 --- a/winsup/cygwin/fhandler_process.cc +++ b/winsup/cygwin/fhandler_process.cc @@ -175,6 +175,7 @@ fhandler_process::fstat (struct stat *buf) buf->st_nlink = 3; return 0; case virt_symlink: + case virt_fdsymlink: buf->st_uid = p->uid; buf->st_gid = p->gid; buf->st_mode = S_IFLNK | S_IRWXU | S_IRWXG | S_IRWXO; @@ -397,7 +398,7 @@ format_process_fd (void *data, char *&destbuf) return 0; } if (*e == '\0') - *((process_fd_t *) data)->fd_type = virt_symlink; + *((process_fd_t *) data)->fd_type = virt_fdsymlink; else /* trailing path */ { char *newbuf = (char *) cmalloc_abort (HEAP_STR, strlen (destbuf) diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc index 3324395cb..563ba0e80 100644 --- a/winsup/cygwin/path.cc +++ b/winsup/cygwin/path.cc @@ -801,7 +801,8 @@ path_conv::check (const char *src, unsigned opt, else { file_type = fh->exists (); - if (file_type == virt_symlink) + if (file_type == virt_symlink + || file_type == virt_fdsymlink) { fh->fill_filebuf (); symlen = sym.set (fh->get_filebuf ()); @@ -842,6 +843,7 @@ path_conv::check (const char *src, unsigned opt, if (component == 0) fileattr = 0; break; + case virt_fdsymlink: case virt_symlink: goto is_virtual_symlink; case virt_pipe: From 97d2fe2694ce935bc295ad6107ce9c7de55285b8 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Sat, 5 Jan 2019 21:42:33 +0100 Subject: [PATCH 047/475] Cygwin: pipe: use /proc/PID/fd/... or /proc/self/fd/... name Don't emit /dev/fd/... filename. This simplifies pipe path handling and avoids another symlink redirection. Signed-off-by: Corinna Vinschen --- winsup/cygwin/pipe.cc | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/winsup/cygwin/pipe.cc b/winsup/cygwin/pipe.cc index f1eace6a6..a75275d7c 100644 --- a/winsup/cygwin/pipe.cc +++ b/winsup/cygwin/pipe.cc @@ -73,8 +73,15 @@ fhandler_pipe::open (int flags, mode_t mode) bool inh; bool got_one = false; - sscanf (get_name (), "/proc/%d/fd/pipe:[%lld]", - &pid, (long long *) &uniq_id); + if (sscanf (get_name (), "/proc/self/fd/pipe:[%lld]", + (long long *) &uniq_id) == 1) + pid = myself->pid; + else if (sscanf (get_name (), "/proc/%d/fd/pipe:[%lld]", + &pid, (long long *) &uniq_id) < 2) + { + set_errno (ENOENT); + return 0; + } if (pid == myself->pid) { cygheap_fdenum cfd (true); @@ -439,8 +446,8 @@ pipe_worker (int filedes[2], unsigned int psize, int mode) { cygheap_fdnew fdin; cygheap_fdnew fdout (fdin, false); - char buf[sizeof ("/dev/fd/pipe:[9223372036854775807]")]; - __small_sprintf (buf, "/dev/fd/pipe:[%D]", fhs[0]->get_plain_ino ()); + char buf[sizeof ("/proc/self/fd/pipe:[9223372036854775807]")]; + __small_sprintf (buf, "/proc/self/fd/pipe:[%D]", fhs[0]->get_plain_ino ()); fhs[0]->pc.set_posix (buf); __small_sprintf (buf, "pipe:[%D]", fhs[1]->get_plain_ino ()); fhs[1]->pc.set_posix (buf); From c208ecd540c02773b0d25246e0fbaadcd416600a Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Sat, 5 Jan 2019 21:49:16 +0100 Subject: [PATCH 048/475] Cygwin: fhandler_base::open: allow to reopen file from handle So far io_handle is NULL when calling fhandler_base::open to open or create a file. Add a check for io_handle to allow priming the fhandler with a HANDLE value so we can reopen a file from a HANDLE on file systems supporting it. This allows to open already deleted files for further action. This will be used by open("/proc/PID/fd/DESCRIPTOR") scenarios. Signed-off-by: Corinna Vinschen --- winsup/cygwin/fhandler.cc | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/winsup/cygwin/fhandler.cc b/winsup/cygwin/fhandler.cc index f7e34c746..01afdb29b 100644 --- a/winsup/cygwin/fhandler.cc +++ b/winsup/cygwin/fhandler.cc @@ -552,7 +552,12 @@ fhandler_base::open (int flags, mode_t mode) syscall_printf ("(%S, %y)", pc.get_nt_native_path (), flags); - pc.get_object_attr (attr, *sec_none_cloexec (flags)); + /* Allow to reopen from handle. This is utilized by + open ("/proc/PID/fd/DESCRIPTOR", ...); */ + if (get_handle ()) + pc.init_reopen_attr (attr, get_handle ()); + else + pc.get_object_attr (attr, *sec_none_cloexec (flags)); options = FILE_OPEN_FOR_BACKUP_INTENT; switch (query_open ()) From 26d953689337a93c31c55083c2073f309ba33c38 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Sat, 5 Jan 2019 21:51:51 +0100 Subject: [PATCH 049/475] Cygwin: path_conv: reorder private method declarations Signed-off-by: Corinna Vinschen --- winsup/cygwin/path.h | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/winsup/cygwin/path.h b/winsup/cygwin/path.h index 3f84da227..b244b57b7 100644 --- a/winsup/cygwin/path.h +++ b/winsup/cygwin/path.h @@ -143,15 +143,19 @@ class path_conv DWORD fileattr; ULONG caseinsensitive; fs_info fs; + PWCHAR wide_path; UNICODE_STRING uni_path; - void add_ext_from_sym (symlink_info&); DWORD symlink_length; const char *path; unsigned path_flags; const char *suffix; const char *posix_path; path_conv_handle conv_handle; + + void add_ext_from_sym (symlink_info&); + char *modifiable_path () {return (char *) path;} + public: int error; device dev; @@ -407,8 +411,6 @@ class path_conv inline const char *get_posix () const { return posix_path; } void __reg2 set_posix (const char *); DWORD get_symlink_length () { return symlink_length; }; - private: - char *modifiable_path () {return (char *) path;} }; /* Symlink marker */ From 91b264c76c34290a31b14844e59bac0deeb62afd Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Sat, 5 Jan 2019 21:50:48 +0100 Subject: [PATCH 050/475] Cygwin: path_conv: add serialization/deserialization facility Signed-off-by: Corinna Vinschen --- winsup/cygwin/path.cc | 64 +++++++++++++++++++++++++++++++++++++++++++ winsup/cygwin/path.h | 3 ++ 2 files changed, 67 insertions(+) diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc index 563ba0e80..df11d5339 100644 --- a/winsup/cygwin/path.cc +++ b/winsup/cygwin/path.cc @@ -1258,6 +1258,70 @@ path_conv::check (const char *src, unsigned opt, __endtry } +struct pc_flat +{ + path_conv pc; + HANDLE hdl; + size_t name_len; + size_t posix_len; + char data[0]; +}; + +void * +path_conv::serialize (HANDLE h, unsigned int &n) const +{ + pc_flat *pcf; + size_t nlen = 0, plen = 0; + char *p; + + if (path) + nlen = strlen (path) + 1; + if (posix_path) + plen = strlen (posix_path) + 1; + n = sizeof (pc_flat) + nlen + plen; + pcf = (pc_flat *) cmalloc (HEAP_COMMUNE, n); + if (!pcf) + { + n = 0; + return NULL; + } + memcpy (&pcf->pc, this, sizeof *this); + pcf->hdl = h; + pcf->name_len = nlen; + pcf->posix_len = plen; + p = pcf->data; + if (nlen) + p = stpcpy (p, path) + 1; + if (plen) + stpcpy (p, posix_path); + return pcf; +} + +HANDLE +path_conv::deserialize (void *bufp) +{ + pc_flat *pcf = (pc_flat *) bufp; + char *p; + HANDLE ret; + + memcpy (this, &pcf->pc, sizeof *this); + wide_path = uni_path.Buffer = NULL; + uni_path.MaximumLength = uni_path.Length = 0; + path = posix_path = NULL; + p = pcf->data; + if (pcf->name_len) + { + set_path (p); + p += pcf->name_len; + } + if (pcf->posix_len) + set_posix (p); + dev.parse (pcf->pc.dev); + ret = pcf->hdl; + cfree (bufp); + return ret; +} + path_conv::~path_conv () { if (posix_path) diff --git a/winsup/cygwin/path.h b/winsup/cygwin/path.h index b244b57b7..1e3095ec9 100644 --- a/winsup/cygwin/path.h +++ b/winsup/cygwin/path.h @@ -160,6 +160,9 @@ class path_conv int error; device dev; + void *serialize (HANDLE, unsigned int &) const; + HANDLE deserialize (void *); + const char *known_suffix () { return suffix; } bool isremote () const {return fs.is_remote_drive ();} ULONG objcaseinsensitive () const {return caseinsensitive;} From c76468182b18272f3e40295e85186fda3d225c66 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Sat, 5 Jan 2019 21:57:03 +0100 Subject: [PATCH 051/475] Cygwin: pinfo: add method to send a serialized path_conv and HANDLE To allow reopening a file open in another process by HANDLE, introduce a matching file_pathconv method, taking a file descriptor as parameter. The result is a serialized path_conv and a HANDLE value. The HANDLE is valid in the foreign process and MUST be duplicated into the target process before usage. Signed-off-by: Corinna Vinschen --- winsup/cygwin/pinfo.cc | 36 +++++++++++++++++++++++++++++++++++- winsup/cygwin/pinfo.h | 4 +++- 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/winsup/cygwin/pinfo.cc b/winsup/cygwin/pinfo.cc index 6b6986c9e..00b3ed623 100644 --- a/winsup/cygwin/pinfo.cc +++ b/winsup/cygwin/pinfo.cc @@ -637,7 +637,7 @@ commune_process (void *arg) } case PICOM_PIPE_FHANDLER: { - sigproc_printf ("processing PICOM_FDS"); + sigproc_printf ("processing PICOM_PIPE_FHANDLER"); int64_t unique_id = si._si_commune._si_pipe_unique_id; unsigned int n = 0; cygheap_fdenum cfd; @@ -656,6 +656,26 @@ commune_process (void *arg) sigproc_printf ("WritePipeOverlapped sizeof hdl failed, %E"); break; } + case PICOM_FILE_PATHCONV: + { + sigproc_printf ("processing PICOM_FILE_PATHCONV"); + int fd = si._si_commune._si_fd; + unsigned int n = 0; + cygheap_fdget cfd (fd); + if (cfd >= 0) + { + fhandler_base *fh = cfd; + void *ser_buf = fh->pc.serialize (fh->get_handle (), n); + if (!WritePipeOverlapped (tothem, &n, sizeof n, &nr, 1000L)) + sigproc_printf ("WritePipeOverlapped sizeof hdl failed, %E"); + else if (!WritePipeOverlapped (tothem, ser_buf, n, &nr, 1000L)) + sigproc_printf ("WritePipeOverlapped hdl failed, %E"); + cfree (ser_buf); + } + else if (!WritePipeOverlapped (tothem, &n, sizeof n, &nr, 1000L)) + sigproc_printf ("WritePipeOverlapped sizeof hdl failed, %E"); + break; + } case PICOM_FD: { sigproc_printf ("processing PICOM_FD"); @@ -741,6 +761,7 @@ _pinfo::commune_request (__uint32_t code, ...) break; case PICOM_FD: + case PICOM_FILE_PATHCONV: si._si_commune._si_fd = va_arg (args, int); break; @@ -773,6 +794,7 @@ _pinfo::commune_request (__uint32_t code, ...) case PICOM_FDS: case PICOM_FD: case PICOM_PIPE_FHANDLER: + case PICOM_FILE_PATHCONV: if (!ReadPipeOverlapped (fromthem, &n, sizeof n, &nr, 1000L) || nr != sizeof n) { @@ -829,6 +851,18 @@ _pinfo::pipe_fhandler (int64_t unique_id, size_t &n) return (fhandler_pipe *) cr.s; } +void * +_pinfo::file_pathconv (int fd, size_t &n) +{ + if (!pid) + return NULL; + if (pid == myself->pid) + return NULL; + commune_result cr = commune_request (PICOM_FILE_PATHCONV, fd); + n = cr.n; + return (void *) cr.s; +} + char * _pinfo::fd (int fd, size_t &n) { diff --git a/winsup/cygwin/pinfo.h b/winsup/cygwin/pinfo.h index aedb3d400..8eb3c43ea 100644 --- a/winsup/cygwin/pinfo.h +++ b/winsup/cygwin/pinfo.h @@ -27,7 +27,8 @@ enum picom PICOM_FDS = 4, PICOM_FD = 5, PICOM_PIPE_FHANDLER = 6, - PICOM_ENVIRON = 7 + PICOM_FILE_PATHCONV = 7, + PICOM_ENVIRON = 8 }; #define EXITCODE_SET 0x8000000 @@ -102,6 +103,7 @@ public: commune_result commune_request (__uint32_t, ...); bool alive (); fhandler_pipe *pipe_fhandler (int64_t, size_t &); + void *file_pathconv (int, size_t &); char *fd (int fd, size_t &); char *fds (size_t &); char *root (size_t &); From 732613f30a5db6bfb4eb7a90e8822d4ee3c629bc Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Sat, 5 Jan 2019 22:13:42 +0100 Subject: [PATCH 052/475] Cygwin: implement /proc/PID/fd/DESCRIPTOR reopening by handle Allows expressions along the lines of `cat /proc/self/fd/0 < --- winsup/cygwin/fhandler.cc | 7 +++ winsup/cygwin/fhandler.h | 2 + winsup/cygwin/fhandler_process.cc | 78 +++++++++++++++++++++++++++++++ winsup/cygwin/path.cc | 4 ++ winsup/cygwin/path.h | 2 + winsup/cygwin/syscalls.cc | 20 ++++++-- 6 files changed, 108 insertions(+), 5 deletions(-) diff --git a/winsup/cygwin/fhandler.cc b/winsup/cygwin/fhandler.cc index 01afdb29b..4ecbf61ee 100644 --- a/winsup/cygwin/fhandler.cc +++ b/winsup/cygwin/fhandler.cc @@ -767,6 +767,13 @@ done: return res; } +fhandler_base * +fhandler_base::fd_reopen (int) +{ + /* This is implemented in fhandler_process only. */ + return NULL; +} + void fhandler_base::open_setup (int) { diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h index 0ead0d90c..74eb1d7cb 100644 --- a/winsup/cygwin/fhandler.h +++ b/winsup/cygwin/fhandler.h @@ -331,6 +331,7 @@ class fhandler_base int open_with_arch (int, mode_t = 0); int open_null (int flags); virtual int open (int, mode_t); + virtual fhandler_base *fd_reopen (int); virtual void open_setup (int flags); void set_unique_id (int64_t u) { unique_id = u; } void set_unique_id () { NtAllocateLocallyUniqueId ((PLUID) &unique_id); } @@ -2553,6 +2554,7 @@ class fhandler_process: public fhandler_proc int closedir (DIR *); int __reg3 readdir (DIR *, dirent *); int open (int flags, mode_t mode = 0); + virtual fhandler_base *fd_reopen (int); int __reg2 fstat (struct stat *buf); bool fill_filebuf (); diff --git a/winsup/cygwin/fhandler_process.cc b/winsup/cygwin/fhandler_process.cc index 24ef7d00c..0fad96fce 100644 --- a/winsup/cygwin/fhandler_process.cc +++ b/winsup/cygwin/fhandler_process.cc @@ -321,6 +321,84 @@ out: return res; } +fhandler_base * +fhandler_process::fd_reopen (int flags) +{ + const char *path; + char *e; + int fd; + HANDLE proc = NULL; + HANDLE hdl = NULL; + fhandler_base *fh = NULL; + + path = get_name () + proc_len + 1; + pid = strtoul (path, &e, 10); + path = e + 4; + fd = strtoul (path, &e, 10); + if (e == path || *e != '\0') + { + set_errno (ENOENT); + return NULL; + } + + if (pid == myself->pid) + { + cygheap_fdget cfd (fd); + if (cfd < 0) + return NULL; + fh = build_fh_pc (cfd->pc); + if (!fh) + goto err_out; + fh->set_io_handle (cfd->get_handle ()); + } + else + { + size_t size; + path_conv pc; + + pinfo p (pid); + if (!p) + { + set_errno (ENOENT); + return NULL; + } + if (!(proc = OpenProcess (PROCESS_DUP_HANDLE, false, p->dwProcessId))) + { + __seterrno (); + return NULL; + } + void *buf = p->file_pathconv (fd, size); + if (size == 0) + { + set_errno (EPERM); + goto err_out; + } + hdl = pc.deserialize (buf); + if (!DuplicateHandle (proc, hdl, GetCurrentProcess (), &hdl, + 0, FALSE, DUPLICATE_SAME_ACCESS)) + { + __seterrno (); + hdl = NULL; + goto err_out; + } + fh = build_fh_pc (pc); + if (!fh) + goto err_out; + fh->set_io_handle (hdl); + } + if (!fh->open_with_arch (flags, 0)) + { + delete fh; + fh = NULL; + } +err_out: + if (hdl) + CloseHandle (hdl); + if (proc) + CloseHandle (proc); + return fh; +} + struct process_fd_t { const char *path; _pinfo *p; diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc index df11d5339..b039801d5 100644 --- a/winsup/cygwin/path.cc +++ b/winsup/cygwin/path.cc @@ -844,6 +844,10 @@ path_conv::check (const char *src, unsigned opt, fileattr = 0; break; case virt_fdsymlink: + /* Allow open/linkat to do the right thing. */ + if (opt & PC_SYM_NOFOLLOW_PROCFD) + opt &= ~PC_SYM_FOLLOW; + /*FALLTHRU*/ case virt_symlink: goto is_virtual_symlink; case virt_pipe: diff --git a/winsup/cygwin/path.h b/winsup/cygwin/path.h index 1e3095ec9..981269995 100644 --- a/winsup/cygwin/path.h +++ b/winsup/cygwin/path.h @@ -47,10 +47,12 @@ enum pathconv_arg PC_SYM_CONTENTS = 0x0008, PC_NOFULL = 0x0010, PC_NULLEMPTY = 0x0020, + PC_DO_NOT_USE = 0x0040, PC_POSIX = 0x0080, PC_NOWARN = 0x0100, PC_OPEN = 0x0200, /* use open semantics */ PC_CTTY = 0x0400, /* could later be used as ctty */ + PC_SYM_NOFOLLOW_PROCFD = 0x0800, PC_KEEP_HANDLE = 0x00400000, PC_NO_ACCESS_CHECK = 0x00800000 }; diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc index 3a7ecd218..b15fa0aa7 100644 --- a/winsup/cygwin/syscalls.cc +++ b/winsup/cygwin/syscalls.cc @@ -1368,6 +1368,7 @@ open (const char *unix_path, int flags, ...) va_list ap; mode_t mode = 0; fhandler_base *fh = NULL; + fhandler_base *fh_file = NULL; pthread_testcancel (); @@ -1394,8 +1395,9 @@ open (const char *unix_path, int flags, ...) with a change in behavior that implements linux functionality: opening a tty should not automatically cause it to become the controlling tty for the process. */ - int opt = PC_OPEN | ((flags & (O_NOFOLLOW | O_EXCL)) - ? PC_SYM_NOFOLLOW : PC_SYM_FOLLOW); + int opt = PC_OPEN | PC_SYM_NOFOLLOW_PROCFD; + opt |= (flags & (O_NOFOLLOW | O_EXCL)) ? PC_SYM_NOFOLLOW + : PC_SYM_FOLLOW; if (!(flags & O_NOCTTY) && fd > 2 && myself->ctty != -2) { flags |= O_NOCTTY; @@ -1438,7 +1440,6 @@ open (const char *unix_path, int flags, ...) followed by an 8 byte unique hex number, followed by an 8 byte random hex number. */ int64_t rnd; - fhandler_base *fh_file; char *new_path; new_path = (char *) malloc (strlen (fh->get_name ()) @@ -1464,8 +1465,17 @@ open (const char *unix_path, int flags, ...) fh = fh_file; } - if ((fh->is_fs_special () && fh->device_access_denied (flags)) - || !fh->open_with_arch (flags, mode & 07777)) + if (fh->dev () == FH_PROCESSFD) + { + /* Reopen file by descriptor */ + fh_file = fh->fd_reopen (flags); + if (!fh_file) + __leave; + delete fh; + fh = fh_file; + } + else if ((fh->is_fs_special () && fh->device_access_denied (flags)) + || !fh->open_with_arch (flags, mode & 07777)) __leave; /* errno already set */ fd = fh; if (fd <= 2) From a1a750325e0673e3c0821de2aacce960140877ea Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Sat, 5 Jan 2019 21:44:12 +0100 Subject: [PATCH 053/475] Cygwin: try_to_bin: allow to move O_TMPFILE files into bin Signed-off-by: Corinna Vinschen --- winsup/cygwin/syscalls.cc | 59 ++++++++++++++++++++++----------------- 1 file changed, 33 insertions(+), 26 deletions(-) diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc index b15fa0aa7..2fb4bc442 100644 --- a/winsup/cygwin/syscalls.cc +++ b/winsup/cygwin/syscalls.cc @@ -328,34 +328,38 @@ try_to_bin (path_conv &pc, HANDLE &fh, ACCESS_MASK access, ULONG flags) } RtlAppendUnicodeToString (&recycler, L"\\"); } - /* Create hopefully unique filename. - Since we have to stick to the current directory on remote shares, make - the new filename at least very unlikely to match by accident. It starts - with ".cyg", with "cyg" transposed into the Unicode low surrogate area - starting at U+dc00. Use plain ASCII chars on filesystems not supporting - Unicode. The rest of the filename is the inode number in hex encoding - and a hash of the full NT path in hex. The combination allows to remove - multiple hardlinks to the same file. Samba doesn't like the transposed - names. */ - RtlAppendUnicodeToString (&recycler, - (pc.fs_flags () & FILE_UNICODE_ON_DISK - && !pc.fs_is_samba ()) - ? L".\xdc63\xdc79\xdc67" : L".cyg"); - pfii = (PFILE_INTERNAL_INFORMATION) infobuf; - /* Note: Modern Samba versions apparently don't like buffer sizes of more - than 65535 in some NtQueryInformationFile/NtSetInformationFile calls. - Therefore we better use exact buffer sizes from now on. */ - status = NtQueryInformationFile (fh, &io, pfii, sizeof *pfii, - FileInternalInformation); - if (!NT_SUCCESS (status)) + if (pc.file_attributes () & FILE_ATTRIBUTE_TEMPORARY) { - debug_printf ("NtQueryInformationFile (%S, FileInternalInformation) " - "failed, status = %y", pc.get_nt_native_path (), status); - goto out; + UNICODE_STRING basename; + + RtlSplitUnicodePath (pc.get_nt_native_path (), NULL, &basename); + RtlAppendUnicodeToString (&recycler, basename.Buffer); + } + else + { + /* Create unique filename. Start with a dot, followed by "cyg" + transposed into the Unicode low surrogate area (U+dc00) on file + systems supporting Unicode (except Samba), followed by the inode + number in hex, followed by a path hash in hex. The combination + allows to remove multiple hardlinks to the same file. */ + RtlAppendUnicodeToString (&recycler, + (pc.fs_flags () & FILE_UNICODE_ON_DISK + && !pc.fs_is_samba ()) + ? L".\xdc63\xdc79\xdc67" : L".cyg"); + pfii = (PFILE_INTERNAL_INFORMATION) infobuf; + status = NtQueryInformationFile (fh, &io, pfii, sizeof *pfii, + FileInternalInformation); + if (!NT_SUCCESS (status)) + { + debug_printf ("NtQueryInformationFile (%S, FileInternalInformation) " + "failed, status = %y", + pc.get_nt_native_path (), status); + goto out; + } + RtlInt64ToHexUnicodeString (pfii->IndexNumber.QuadPart, &recycler, TRUE); + RtlInt64ToHexUnicodeString (hash_path_name (0, pc.get_nt_native_path ()), + &recycler, TRUE); } - RtlInt64ToHexUnicodeString (pfii->IndexNumber.QuadPart, &recycler, TRUE); - RtlInt64ToHexUnicodeString (hash_path_name (0, pc.get_nt_native_path ()), - &recycler, TRUE); /* Shoot. */ pfri = (PFILE_RENAME_INFORMATION) infobuf; pfri->ReplaceIfExists = TRUE; @@ -461,6 +465,9 @@ try_to_bin (path_conv &pc, HANDLE &fh, ACCESS_MASK access, ULONG flags) } /* Moving to the bin worked. */ bin_stat = has_been_moved; + /* If we're only moving a just created O_TMPFILE, we're done here. */ + if (pc.file_attributes () & FILE_ATTRIBUTE_TEMPORARY) + goto out; /* Now we try to set the delete disposition. If that worked, we're done. We try this here first, as long as we still have the open handle. Otherwise the below code closes the handle to allow replacing the file. */ From 7dbe307e389b916ad4f34ea3c3258049abad2d2c Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Sat, 5 Jan 2019 22:15:58 +0100 Subject: [PATCH 054/475] Cygwin: Move O_TMPFILE to bin and allow linkat by handle Along the same lines as the previous patch: By reopening an O_TMPFILE by handle, we can now move the file to the bin at open time and thus free'ing up the parent dir and *still* open the file as /proc/PID/fd/DESCRIPTOR by linkat(2). --- winsup/cygwin/fhandler.h | 1 + winsup/cygwin/fhandler_process.cc | 82 +++++++++++++++++++++++++++++++ winsup/cygwin/syscalls.cc | 8 ++- 3 files changed, 90 insertions(+), 1 deletion(-) diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h index 74eb1d7cb..1c751c110 100644 --- a/winsup/cygwin/fhandler.h +++ b/winsup/cygwin/fhandler.h @@ -2555,6 +2555,7 @@ class fhandler_process: public fhandler_proc int __reg3 readdir (DIR *, dirent *); int open (int flags, mode_t mode = 0); virtual fhandler_base *fd_reopen (int); + int __reg2 link (const char *); int __reg2 fstat (struct stat *buf); bool fill_filebuf (); diff --git a/winsup/cygwin/fhandler_process.cc b/winsup/cygwin/fhandler_process.cc index 0fad96fce..a52314810 100644 --- a/winsup/cygwin/fhandler_process.cc +++ b/winsup/cygwin/fhandler_process.cc @@ -399,6 +399,88 @@ err_out: return fh; } +int +fhandler_process::link (const char *newpath) +{ + const char *path; + int fd; + char *e; + + path = get_name () + proc_len + 1; + pid = atoi (path); + while (*path != 0 && !isdirsep (*path)) + path++; + if (*path == 0) + goto err_out; + + virt_tab_t *entry; + entry = virt_tab_search (path + 1, true, process_tab, PROCESS_LINK_COUNT); + if (!entry || entry->fhandler != FH_PROCESSFD) + goto err_out; + if (path[3] != '/' || path[4] == '\0') + goto err_out; + + fd = strtoul (path + 4, &e, 10); + if (fd < 0 || e == path + 4 || (*e != '/' && *e != '\0')) + goto err_out; + if (pid == myself->pid) + { + cygheap_fdget cfd (fd); + if (cfd < 0) + goto err_out; + return cfd->link (newpath); + } + else + { + HANDLE proc; + size_t size; + void *buf; + path_conv pc; + HANDLE hdl; + fhandler_base *fh = NULL; + int ret = -1; + + pinfo p (pid); + if (!p) + { + set_errno (ENOENT); + return -1; + } + if (!(proc = OpenProcess (PROCESS_DUP_HANDLE, false, p->dwProcessId))) + goto err_out; + buf = p->file_pathconv (fd, size); + if (size == 0) + { + set_errno (EPERM); + goto err_out_close_proc; + } + hdl = pc.deserialize (buf); + if (!DuplicateHandle (proc, hdl, GetCurrentProcess (), &hdl, + 0, FALSE, DUPLICATE_SAME_ACCESS)) + { + __seterrno (); + goto err_out_close_proc; + } + fh = build_fh_pc (pc); + if (!fh) + goto err_out_close_dup; + + fh->set_io_handle (hdl); + ret = fh->link (newpath); + delete fh; + +err_out_close_dup: + CloseHandle (hdl); +err_out_close_proc: + CloseHandle (proc); + return ret; + } + +err_out: + set_errno (EPERM); + return -1; +} + struct process_fd_t { const char *path; _pinfo *p; diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc index 2fb4bc442..9f43512b2 100644 --- a/winsup/cygwin/syscalls.cc +++ b/winsup/cygwin/syscalls.cc @@ -1484,6 +1484,10 @@ open (const char *unix_path, int flags, ...) else if ((fh->is_fs_special () && fh->device_access_denied (flags)) || !fh->open_with_arch (flags, mode & 07777)) __leave; /* errno already set */ + /* Move O_TMPFILEs to the bin to avoid blocking the parent dir. */ + if ((flags & O_TMPFILE) && !fh->pc.isremote ()) + try_to_bin (fh->pc, fh->get_handle (), DELETE, + FILE_OPEN_FOR_BACKUP_INTENT); fd = fh; if (fd <= 2) set_std_handle (fd); @@ -4791,7 +4795,9 @@ linkat (int olddirfd, const char *oldpathname, __leave; if (flags & AT_SYMLINK_FOLLOW) { - path_conv old_name (oldpath, PC_SYM_FOLLOW | PC_POSIX, stat_suffixes); + path_conv old_name (oldpath, + PC_SYM_FOLLOW | PC_SYM_NOFOLLOW_PROCFD | PC_POSIX, + stat_suffixes); if (old_name.error) { set_errno (old_name.error); From c90f4c0e27a2d30497eeaab99c76c1906a6bf556 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Sat, 5 Jan 2019 22:16:30 +0100 Subject: [PATCH 055/475] Cygwin: Mark all O_TMPFILEs as deleted Signed-off-by: Corinna Vinschen --- winsup/cygwin/fhandler.cc | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/winsup/cygwin/fhandler.cc b/winsup/cygwin/fhandler.cc index 4ecbf61ee..1a7513763 100644 --- a/winsup/cygwin/fhandler.cc +++ b/winsup/cygwin/fhandler.cc @@ -140,11 +140,8 @@ char *fhandler_base::get_proc_fd_name (char *buf) IO_STATUS_BLOCK io; FILE_STANDARD_INFORMATION fsi; - /* If the file had been opened with O_TMPFILE | O_EXCL, don't - expose the filename. linkat is supposed to return ENOENT in this - case. FIXME: As soon as we open by handle from /proc//fd, - the O_EXCL test has to be moved to open. */ - if ((get_flags () & (O_TMPFILE | O_EXCL)) == (O_TMPFILE | O_EXCL) + /* If the file had been opened with O_TMPFILE, don't expose the filename. */ + if ((get_flags () & O_TMPFILE) || (get_device () == FH_FS && NT_SUCCESS (NtQueryInformationFile (get_handle (), &io, &fsi, sizeof fsi, From fde4eaa105912625b6a78fba79d1fc39ee0fd201 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Sun, 6 Jan 2019 14:29:53 +0100 Subject: [PATCH 056/475] Cygwin: path_conv: decouple pathconv_flags from path_types There's an unfortunate amalgamation of caller-provided pathconv_arg flags with path_types flags which in turn are mostly mount flags. This leads to a confusion of flag values in sylink_info::pflags and, in turn, in path_conv::path_flags. This patch decouples pathconv_flags from the other flags by making sure that a pathconv_flag is never copied into a variable used for path_types flags. Also, remove PATH_NO_ACCESS_CHECK since it's not necessary. Signed-off-by: Corinna Vinschen --- winsup/cygwin/path.cc | 19 +++++++++++-------- winsup/cygwin/path.h | 3 ++- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc index b039801d5..28b966692 100644 --- a/winsup/cygwin/path.cc +++ b/winsup/cygwin/path.cc @@ -80,7 +80,8 @@ struct symlink_info char contents[SYMLINK_MAX + 1]; char *ext_here; int extn; - unsigned pflags; + unsigned pflags; /* path flags, i.e. mount flags, special files, ... */ + unsigned pc_flags; /* Relevant flags from caller of path_conv */ DWORD fileattr; int issymlink; bool ext_tacked_on; @@ -735,9 +736,10 @@ path_conv::check (const char *src, unsigned opt, int symlen = 0; - for (unsigned pflags_or = opt & (PC_NO_ACCESS_CHECK | PC_KEEP_HANDLE); + /* Make sure to check certain flags on last component only. */ + for (unsigned pc_flags = opt & (PC_NO_ACCESS_CHECK | PC_KEEP_HANDLE); ; - pflags_or = 0) + pc_flags = 0) { const suffix_info *suff; char *full_path; @@ -764,7 +766,7 @@ path_conv::check (const char *src, unsigned opt, if (error) return; - sym.pflags |= pflags_or; + sym.pc_flags = pc_flags; if (!dev.exists ()) { @@ -1190,7 +1192,7 @@ path_conv::check (const char *src, unsigned opt, it will be figured out later by anything which cares about this. */ } - /* If the FS has been found to have unrelibale inodes, note + /* If the FS has been found to have unreliable inodes, note that in path_flags. */ if (!fs.hasgood_inode ()) path_flags |= PATH_IHASH; @@ -2721,7 +2723,8 @@ bool symlink_info::set_error (int in_errno) { bool res; - if (!(pflags & PATH_NO_ACCESS_CHECK) || in_errno == ENAMETOOLONG || in_errno == EIO) + if (!(pc_flags & PC_NO_ACCESS_CHECK) + || in_errno == ENAMETOOLONG || in_errno == EIO) { error = in_errno; res = true; @@ -3103,7 +3106,7 @@ restart: The handle has been opened with the FILE_OPEN_REPARSE_POINT flag, so it's a handle to the reparse point, not a handle to the volumes root dir. */ - pflags &= ~PC_KEEP_HANDLE; + pc_flags &= ~PC_KEEP_HANDLE; /* Volume mount point: The filesystem information for the top level directory should be for the volume top level directory, rather than for the reparse point itself. So we fetch the @@ -3202,7 +3205,7 @@ restart: if (h) { - if (pflags & PC_KEEP_HANDLE) + if (pc_flags & PC_KEEP_HANDLE) conv_hdl.set (h); else NtClose (h); diff --git a/winsup/cygwin/path.h b/winsup/cygwin/path.h index 981269995..297eaa609 100644 --- a/winsup/cygwin/path.h +++ b/winsup/cygwin/path.h @@ -39,6 +39,8 @@ struct suffix_info extern suffix_info stat_suffixes[]; +/* DO NOT copy any of these files into the same set of flags as the + below path_types. Ever. */ enum pathconv_arg { PC_SYM_FOLLOW = 0x0001, @@ -76,7 +78,6 @@ enum path_types PATH_DOS = MOUNT_DOS, PATH_IHASH = MOUNT_IHASH, PATH_ALL_EXEC = (PATH_CYGWIN_EXEC | PATH_EXEC), - PATH_NO_ACCESS_CHECK = PC_NO_ACCESS_CHECK, PATH_CTTY = 0x00400000, /* could later be used as ctty */ PATH_OPEN = 0x00800000, /* use open semantics */ /* FIXME? PATH_OPEN collides with From c1023ee353705671aa9a8e4e1179022277add2aa Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Sun, 6 Jan 2019 17:44:20 +0100 Subject: [PATCH 057/475] Cygwin: path_conv: decouple path_types from mount types - Remove another unfortunate amalgamation: Mount flags (MOUNT_xxx) are converted to path_types (PATH_xxx) and mixed with non-mount path_types flags in the same storage, leading to a tangled, pell-mell usage of mount flags and path flags in path_conv and symlink_info. - There's also the case of PC_NONULLEMPTY. It's used in exactly one place with a path_conv constructor only used in this single place, just to override the automatic PC_NULLEMPTY addition when calling the other path_conv constructors. Crazily, PC_NONULLEMPTY is a define, no path_types flag, despite its name. - It doesn't help that the binary flag exists as mount and path flag, while the text flag only exists as path flag. This leads to mount code using path flags to set text/binary. Very confusing is the fact that a text mount/path flag is not actually required; the mount code sets the text flag on non binary mounts anyway, so there are only two states. However, to puzzle people a bit more, path_conv::binary wrongly implies there's a third, non-binary/non-text state. Clean up this mess: - Store path flags separately from mount flags in path_conv and symlink_info classes and change all checks and testing inline methods accordingly. - Make PC_NONULLEMPTY a simple path_types flag and drop the redundant path_check constructor. - Clean up the definition of pathconv_arg, path_types, and mount flags. Use _BIT expression, newly define in cygwin/bits.h. Signed-off-by: Corinna Vinschen --- winsup/cygwin/include/cygwin/bits.h | 14 +++ winsup/cygwin/include/sys/mount.h | 44 +++++----- winsup/cygwin/mount.cc | 17 +--- winsup/cygwin/path.cc | 76 ++++++++-------- winsup/cygwin/path.h | 129 +++++++++++----------------- winsup/utils/path.cc | 1 + 6 files changed, 137 insertions(+), 144 deletions(-) create mode 100644 winsup/cygwin/include/cygwin/bits.h diff --git a/winsup/cygwin/include/cygwin/bits.h b/winsup/cygwin/include/cygwin/bits.h new file mode 100644 index 000000000..dee5d3dda --- /dev/null +++ b/winsup/cygwin/include/cygwin/bits.h @@ -0,0 +1,14 @@ +/* cygwin/bits.h + +This file is part of Cygwin. + +This software is a copyrighted work licensed under the terms of the +Cygwin license. Please consult the file "CYGWIN_LICENSE" for +details. */ + +#ifndef _CYGWIN_BITS_H +#define _CYGWIN_BITS_H + +#define _BIT(_bit) (1U << (_bit)) + +#endif /* _CYGWIN_BITS_H */ diff --git a/winsup/cygwin/include/sys/mount.h b/winsup/cygwin/include/sys/mount.h index bdc7f30ab..506158011 100644 --- a/winsup/cygwin/include/sys/mount.h +++ b/winsup/cygwin/include/sys/mount.h @@ -9,6 +9,10 @@ details. */ #ifndef _SYS_MOUNT_H #define _SYS_MOUNT_H +#ifdef __CYGWIN__ /* Build tweak for native Cygwin utils */ +#include +#endif + #define BLOCK_SIZE 1024 #define BLOCK_SIZE_BITS 10 @@ -18,31 +22,31 @@ extern "C" { enum { - MOUNT_SYMLINK = 0x00001, /* "mount point" is a symlink */ - MOUNT_BINARY = 0x00002, /* "binary" format read/writes */ - MOUNT_SYSTEM = 0x00008, /* mount point came from system table */ - MOUNT_EXEC = 0x00010, /* Any file in the mounted directory + MOUNT_BINARY = _BIT ( 1), /* "binary" format read/writes */ + MOUNT_SYSTEM = _BIT ( 3), /* mount point came from system table */ + MOUNT_EXEC = _BIT ( 4), /* Any file in the mounted directory gets 'x' bit */ - MOUNT_CYGDRIVE = 0x00020, /* mount point refers to cygdrive + MOUNT_CYGDRIVE = _BIT ( 5), /* mount point refers to cygdrive device mount */ - MOUNT_CYGWIN_EXEC = 0x00040, /* file or directory is or contains a + MOUNT_CYGWIN_EXEC = _BIT ( 6), /* file or directory is or contains a cygwin executable */ - MOUNT_SPARSE = 0x00080, /* Support automatic sparsifying of + MOUNT_SPARSE = _BIT ( 7), /* Support automatic sparsifying of files. */ - MOUNT_NOTEXEC = 0x00100, /* don't check files for executable magic */ - MOUNT_DEVFS = 0x00200, /* /device "filesystem" */ - MOUNT_PROC = 0x00400, /* /proc "filesystem" */ - MOUNT_RO = 0x01000, /* read-only "filesystem" */ - MOUNT_NOACL = 0x02000, /* support reading/writing ACLs */ - MOUNT_NOPOSIX = 0x04000, /* Case insensitve path handling */ - MOUNT_OVERRIDE = 0x08000, /* Allow overriding of root */ - MOUNT_IMMUTABLE = 0x10000, /* Mount point can't be changed */ - MOUNT_AUTOMATIC = 0x20000, /* Mount point was added automatically */ - MOUNT_DOS = 0x40000, /* convert leading spaces and trailing + MOUNT_NOTEXEC = _BIT ( 8), /* don't check files for executable magic */ + MOUNT_DEVFS = _BIT ( 9), /* /device "filesystem" */ + MOUNT_PROC = _BIT (10), /* /proc "filesystem" */ + MOUNT_RO = _BIT (12), /* read-only "filesystem" */ + MOUNT_NOACL = _BIT (13), /* support reading/writing ACLs */ + MOUNT_NOPOSIX = _BIT (14), /* Case insensitve path handling */ + MOUNT_OVERRIDE = _BIT (15), /* Allow overriding of root */ + MOUNT_IMMUTABLE = _BIT (16), /* Mount point can't be changed */ + MOUNT_AUTOMATIC = _BIT (17), /* Mount point was added automatically */ + MOUNT_DOS = _BIT (18), /* convert leading spaces and trailing dots and spaces to private use area */ - MOUNT_IHASH = 0x80000, /* Enforce hash values for inode numbers */ - MOUNT_BIND = 0x100000, /* Allows bind syntax in fstab file. */ - MOUNT_USER_TEMP = 0x200000 /* Mount the user's $TMP. */ + MOUNT_IHASH = _BIT (19), /* Enforce hash values for inode numbers */ + MOUNT_BIND = _BIT (20), /* Allows bind syntax in fstab file. */ + MOUNT_USER_TEMP = _BIT (21), /* Mount the user's $TMP. */ + MOUNT_DONT_USE = _BIT (31) /* conversion to signed happens. */ }; int mount (const char *, const char *, unsigned __flags); diff --git a/winsup/cygwin/mount.cc b/winsup/cygwin/mount.cc index 1844dd8d0..146b2b6cd 100644 --- a/winsup/cygwin/mount.cc +++ b/winsup/cygwin/mount.cc @@ -524,16 +524,7 @@ static void set_flags (unsigned *flags, unsigned val) { *flags = val; - if (!(*flags & PATH_BINARY)) - { - *flags |= PATH_TEXT; - debug_printf ("flags: text (%y)", *flags & (PATH_TEXT | PATH_BINARY)); - } - else - { - *flags |= PATH_BINARY; - debug_printf ("flags: binary (%y)", *flags & (PATH_TEXT | PATH_BINARY)); - } + debug_printf ("flags: binary (%y)", *flags & MOUNT_BINARY); } int @@ -626,7 +617,7 @@ mount_info::conv_to_win32_path (const char *src_path, char *dst, device& dev, if (!strchr (src_path + 2, '/')) { dev = *netdrive_dev; - set_flags (flags, PATH_BINARY); + set_flags (flags, MOUNT_BINARY); } else { @@ -647,7 +638,7 @@ mount_info::conv_to_win32_path (const char *src_path, char *dst, device& dev, dev = fhandler_proc::get_proc_fhandler (src_path); if (dev == FH_NADA) return ENOENT; - set_flags (flags, PATH_BINARY); + set_flags (flags, MOUNT_BINARY); if (isprocsys_dev (dev)) { if (src_path[procsys_len]) @@ -1008,7 +999,7 @@ mount_info::set_flags_from_win32_path (const char *p) mi.flags & MOUNT_NOPOSIX)) return mi.flags; } - return PATH_BINARY; + return MOUNT_BINARY; } inline char * diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc index 28b966692..0a68671fb 100644 --- a/winsup/cygwin/path.cc +++ b/winsup/cygwin/path.cc @@ -80,8 +80,9 @@ struct symlink_info char contents[SYMLINK_MAX + 1]; char *ext_here; int extn; - unsigned pflags; /* path flags, i.e. mount flags, special files, ... */ - unsigned pc_flags; /* Relevant flags from caller of path_conv */ + unsigned path_flags; + unsigned mount_flags; + unsigned pc_flags; /* Relevant pathconv_arg flags from path_conv caller */ DWORD fileattr; int issymlink; bool ext_tacked_on; @@ -671,6 +672,7 @@ path_conv::check (const char *src, unsigned opt, __try { int loop = 0; + mount_flags = 0; path_flags = 0; suffix = NULL; fileattr = INVALID_FILE_ATTRIBUTES; @@ -761,7 +763,7 @@ path_conv::check (const char *src, unsigned opt, /* Convert to native path spec sans symbolic link info. */ error = mount_table->conv_to_win32_path (path_copy, full_path, - dev, &sym.pflags); + dev, &sym.mount_flags); if (error) return; @@ -782,7 +784,7 @@ path_conv::check (const char *src, unsigned opt, else { fileattr = getfileattr (THIS_path, - sym.pflags & MOUNT_NOPOSIX); + sym.mount_flags & MOUNT_NOPOSIX); dev = FH_FS; } goto out; @@ -897,14 +899,15 @@ path_conv::check (const char *src, unsigned opt, goto virtual_component_retry; } if (component == 0 || dev != FH_NETDRIVE) - path_flags |= PATH_RO; + mount_flags |= MOUNT_RO; goto out; } /* devn should not be a device. If it is, then stop parsing. */ else if (dev != FH_FS) { fileattr = 0; - path_flags = sym.pflags; + mount_flags = sym.mount_flags; + path_flags = sym.path_flags; if (component) { error = ENOTDIR; @@ -928,7 +931,7 @@ path_conv::check (const char *src, unsigned opt, calling sym.check, otherwise the path is potentially treated casesensitive. */ if (is_msdos) - sym.pflags |= PATH_NOPOSIX | PATH_NOACL; + sym.mount_flags |= MOUNT_NOPOSIX | MOUNT_NOACL; is_fs_via_procsys: @@ -950,7 +953,7 @@ path_conv::check (const char *src, unsigned opt, goto out; } - if (sym.pflags & PATH_SOCKET) + if (sym.path_flags & PATH_SOCKET) { if (component) { @@ -959,12 +962,13 @@ path_conv::check (const char *src, unsigned opt, } fileattr = sym.fileattr; #ifdef __WITH_AF_UNIX - dev.parse ((sym.pflags & PATH_REP) ? FH_UNIX : FH_LOCAL); + dev.parse ((sym.path_flags & PATH_REP) ? FH_UNIX : FH_LOCAL); #else dev.parse (FH_LOCAL); #endif /* __WITH_AF_UNIX */ dev.setfs (1); - path_flags = sym.pflags; + mount_flags = sym.mount_flags; + path_flags = sym.path_flags; goto out; } @@ -973,7 +977,8 @@ path_conv::check (const char *src, unsigned opt, /* Make sure that /dev always exists. */ fileattr = isdev_dev (dev) ? FILE_ATTRIBUTE_DIRECTORY : sym.fileattr; - path_flags = sym.pflags; + mount_flags = sym.mount_flags; + path_flags = sym.path_flags; } else if (isdev_dev (dev)) { @@ -1184,23 +1189,23 @@ path_conv::check (const char *src, unsigned opt, debug_printf ("this->path(%s), has_acls(%d)", path, fs.has_acls ()); /* CV: We could use this->has_acls() but I want to make sure that - we don't forget that the PATH_NOACL flag must be taken into + we don't forget that the MOUNT_NOACL flag must be taken into account here. */ - if (!(path_flags & PATH_NOACL) && fs.has_acls ()) + if (!(mount_flags & MOUNT_NOACL) && fs.has_acls ()) set_exec (0); /* We really don't know if this is executable or not here but set it to not executable since it will be figured out later by anything which cares about this. */ } /* If the FS has been found to have unreliable inodes, note - that in path_flags. */ + that in mount_flags. */ if (!fs.hasgood_inode ()) - path_flags |= PATH_IHASH; + mount_flags |= MOUNT_IHASH; /* If the OS is caseinsensitive or the FS is caseinsensitive, don't handle path casesensitive. */ if (cygwin_shared->obcaseinsensitive || fs.caseinsensitive ()) - path_flags |= PATH_NOPOSIX; - caseinsensitive = (path_flags & PATH_NOPOSIX) + mount_flags |= MOUNT_NOPOSIX; + caseinsensitive = (mount_flags & MOUNT_NOPOSIX) ? OBJ_CASE_INSENSITIVE : 0; if (exec_state () != dont_know_if_executable) /* ok */; @@ -2272,7 +2277,7 @@ symlink_info::check_shortcut (HANDLE h) } } if (res) /* It's a symlink. */ - pflags |= PATH_SYMLINK | PATH_LNK; + path_flags |= PATH_SYMLINK | PATH_LNK; return res; } @@ -2302,24 +2307,24 @@ symlink_info::check_sysfile (HANDLE h) && memcmp (cookie_buf, SYMLINK_COOKIE, sizeof (cookie_buf)) == 0) { /* It's a symlink. */ - pflags |= PATH_SYMLINK; + path_flags |= PATH_SYMLINK; } else if (io.Information == sizeof (cookie_buf) && memcmp (cookie_buf, SOCKET_COOKIE, sizeof (cookie_buf)) == 0) - pflags |= PATH_SOCKET; + path_flags |= PATH_SOCKET; else if (io.Information >= sizeof (INTERIX_SYMLINK_COOKIE) && memcmp (cookie_buf, INTERIX_SYMLINK_COOKIE, sizeof (INTERIX_SYMLINK_COOKIE) - 1) == 0) { /* It's an Interix symlink. */ - pflags |= PATH_SYMLINK; + path_flags |= PATH_SYMLINK; interix_symlink = true; /* Interix symlink cookies are shorter than Cygwin symlink cookies, so in case of an Interix symlink cooky we have read too far into the file. Set file pointer back to the position right after the cookie. */ off.QuadPart = sizeof (INTERIX_SYMLINK_COOKIE) - 1; } - if (pflags & PATH_SYMLINK) + if (path_flags & PATH_SYMLINK) { status = NtReadFile (h, NULL, NULL, NULL, &io, srcbuf, NT_MAX_PATH, &off, NULL); @@ -2487,7 +2492,7 @@ symlink_info::check_reparse_point (HANDLE h, bool remote) return ret; } /* ret is > 0, so it's a known reparse point, path in symbuf. */ - pflags |= ret; + path_flags |= ret; if (ret & PATH_SYMLINK) sys_wcstombs (srcbuf, SYMLINK_MAX + 7, symbuf.Buffer, symbuf.Length / sizeof (WCHAR)); @@ -2523,7 +2528,7 @@ symlink_info::check_nfs_symlink (HANDLE h) (pffei->EaName + pffei->EaNameLength + 1); res = sys_wcstombs (contents, SYMLINK_MAX + 1, spath, pffei->EaValueLength); - pflags |= PATH_SYMLINK; + path_flags |= PATH_SYMLINK; } return res; } @@ -2803,7 +2808,8 @@ symlink_info::check (char *path, const suffix_info *suffixes, fs_info &fs, suffix_scan suffix; const ULONG ci_flag = cygwin_shared->obcaseinsensitive - || (pflags & PATH_NOPOSIX) ? OBJ_CASE_INSENSITIVE : 0; + || (mount_flags & MOUNT_NOPOSIX) + ? OBJ_CASE_INSENSITIVE : 0; /* TODO: Temporarily do all char->UNICODE conversion here. This should already be slightly faster than using Ascii functions. */ tmp_pathbuf tp; @@ -2823,7 +2829,8 @@ restart: major = 0; minor = 0; mode = 0; - pflags &= ~(PATH_SYMLINK | PATH_LNK | PATH_REP); + // mount_flags is an incoming value set in path_conv */ + path_flags = 0; PVOID eabuf = &nfs_aol_ffei; ULONG easize = sizeof nfs_aol_ffei; @@ -2842,7 +2849,7 @@ restart: while (suffix.next ()) { error = 0; - get_nt_native_path (suffix.path, upath, pflags & PATH_DOS); + get_nt_native_path (suffix.path, upath, mount_flags & MOUNT_DOS); if (h) { NtClose (h); @@ -2895,7 +2902,7 @@ restart: slow down normal operation. This extra check only kicks in if we encountered a STATUS_OBJECT_NAME_NOT_FOUND *and* we didn't already attach a suffix. */ - if (!restarted && !*ext_here && !(pflags & PATH_DOS)) + if (!restarted && !*ext_here && !(mount_flags & MOUNT_DOS)) { /* Check for trailing dot or space or leading space in last component. */ @@ -2917,7 +2924,7 @@ restart: /* If so, try again. Since we now know the FS, the filenames will be tweaked to follow DOS rules via the third parameter in the call to get_nt_native_path. */ - pflags |= PATH_DOS; + mount_flags |= MOUNT_DOS; restarted = true; goto restart; } @@ -3211,8 +3218,8 @@ restart: NtClose (h); } - syscall_printf ("%d = symlink.check(%s, %p) (%y)", - res, suffix.path, contents, pflags); + syscall_printf ("%d = symlink.check(%s, %p) (mount_flags %y, path_flags %y)", + res, suffix.path, contents, mount_flags, path_flags); return res; } @@ -3222,7 +3229,8 @@ int symlink_info::set (char *path) { strcpy (contents, path); - pflags = PATH_SYMLINK; + mount_flags = 0; + path_flags = PATH_SYMLINK; fileattr = FILE_ATTRIBUTE_NORMAL; error = 0; issymlink = true; @@ -3373,9 +3381,9 @@ chdir (const char *in_dir) syscall_printf ("dir '%s'", in_dir); - /* Convert path. First argument ensures that we don't check for + /* Convert path. PC_NONULLEMPTY ensures that we don't check for NULL/empty/invalid again. */ - path_conv path (PC_NONULLEMPTY, in_dir, PC_SYM_FOLLOW | PC_POSIX); + path_conv path (in_dir, PC_SYM_FOLLOW | PC_POSIX | PC_NONULLEMPTY); if (path.error) { set_errno (path.error); diff --git a/winsup/cygwin/path.h b/winsup/cygwin/path.h index 297eaa609..69da8fd93 100644 --- a/winsup/cygwin/path.h +++ b/winsup/cygwin/path.h @@ -11,6 +11,7 @@ details. */ #include "cygheap_malloc.h" #include "nfs.h" +#include #include #include #include @@ -43,50 +44,32 @@ extern suffix_info stat_suffixes[]; below path_types. Ever. */ enum pathconv_arg { - PC_SYM_FOLLOW = 0x0001, - PC_SYM_NOFOLLOW = 0x0002, - PC_SYM_NOFOLLOW_REP = 0x0004, - PC_SYM_CONTENTS = 0x0008, - PC_NOFULL = 0x0010, - PC_NULLEMPTY = 0x0020, - PC_DO_NOT_USE = 0x0040, - PC_POSIX = 0x0080, - PC_NOWARN = 0x0100, - PC_OPEN = 0x0200, /* use open semantics */ - PC_CTTY = 0x0400, /* could later be used as ctty */ - PC_SYM_NOFOLLOW_PROCFD = 0x0800, - PC_KEEP_HANDLE = 0x00400000, - PC_NO_ACCESS_CHECK = 0x00800000 + PC_SYM_FOLLOW = _BIT ( 0), + PC_SYM_NOFOLLOW = _BIT ( 1), + PC_SYM_NOFOLLOW_REP = _BIT ( 2), + PC_SYM_CONTENTS = _BIT ( 3), + PC_NOFULL = _BIT ( 4), + PC_NULLEMPTY = _BIT ( 5), + PC_NONULLEMPTY = _BIT ( 6), + PC_POSIX = _BIT ( 7), + PC_NOWARN = _BIT ( 8), + PC_OPEN = _BIT ( 9), /* use open semantics */ + PC_CTTY = _BIT (10), /* could later be used as ctty */ + PC_SYM_NOFOLLOW_PROCFD = _BIT (11), + PC_KEEP_HANDLE = _BIT (12), + PC_NO_ACCESS_CHECK = _BIT (13), + PC_DONT_USE = _BIT (31) /* conversion to signed happens. */ }; -#define PC_NONULLEMPTY -1 - -#include "sys/mount.h" - enum path_types { - PATH_NOTHING = 0, - PATH_SYMLINK = MOUNT_SYMLINK, - PATH_BINARY = MOUNT_BINARY, - PATH_EXEC = MOUNT_EXEC, - PATH_NOTEXEC = MOUNT_NOTEXEC, - PATH_CYGWIN_EXEC = MOUNT_CYGWIN_EXEC, - PATH_SPARSE = MOUNT_SPARSE, - PATH_RO = MOUNT_RO, - PATH_NOACL = MOUNT_NOACL, - PATH_NOPOSIX = MOUNT_NOPOSIX, - PATH_DOS = MOUNT_DOS, - PATH_IHASH = MOUNT_IHASH, - PATH_ALL_EXEC = (PATH_CYGWIN_EXEC | PATH_EXEC), - PATH_CTTY = 0x00400000, /* could later be used as ctty */ - PATH_OPEN = 0x00800000, /* use open semantics */ - /* FIXME? PATH_OPEN collides with - PATH_NO_ACCESS_CHECK, but it looks - like they are never used together. */ - PATH_LNK = 0x01000000, - PATH_TEXT = 0x02000000, - PATH_REP = 0x04000000, - PATH_SOCKET = 0x40000000 + PATH_CTTY = _BIT ( 0), /* could later be used as ctty */ + PATH_OPEN = _BIT ( 1), /* use open semantics */ + PATH_LNK = _BIT ( 2), + PATH_REP = _BIT ( 3), + PATH_SYMLINK = _BIT ( 4), + PATH_SOCKET = _BIT ( 5), + PATH_DONT_USE = _BIT (31) /* conversion to signed happens. */ }; NTSTATUS file_get_fai (HANDLE, PFILE_ALL_INFORMATION); @@ -151,7 +134,8 @@ class path_conv UNICODE_STRING uni_path; DWORD symlink_length; const char *path; - unsigned path_flags; + uint32_t mount_flags; + uint32_t path_flags; const char *suffix; const char *posix_path; path_conv_handle conv_handle; @@ -169,25 +153,24 @@ class path_conv const char *known_suffix () { return suffix; } bool isremote () const {return fs.is_remote_drive ();} ULONG objcaseinsensitive () const {return caseinsensitive;} - bool has_acls () const {return !(path_flags & PATH_NOACL) && fs.has_acls (); } - bool hasgood_inode () const {return !(path_flags & PATH_IHASH); } + bool has_acls () const {return !(mount_flags & MOUNT_NOACL) + && fs.has_acls (); } + bool hasgood_inode () const {return !(mount_flags & MOUNT_IHASH); } bool isgood_inode (ino_t ino) const; bool support_sparse () const { - return (path_flags & PATH_SPARSE) + return (mount_flags & MOUNT_SPARSE) && (fs_flags () & FILE_SUPPORTS_SPARSE_FILES); } - int has_dos_filenames_only () const {return path_flags & PATH_DOS;} + int has_dos_filenames_only () const {return mount_flags & MOUNT_DOS;} int has_buggy_reopen () const {return fs.has_buggy_reopen ();} int has_buggy_fileid_dirinfo () const {return fs.has_buggy_fileid_dirinfo ();} int has_buggy_basic_info () const {return fs.has_buggy_basic_info ();} int binmode () const { - if (path_flags & PATH_BINARY) + if (mount_flags & MOUNT_BINARY) return O_BINARY; - if (path_flags & PATH_TEXT) - return O_TEXT; - return 0; + return O_TEXT; } int issymlink () const {return path_flags & PATH_SYMLINK;} int is_lnk_symlink () const {return path_flags & PATH_LNK;} @@ -206,33 +189,33 @@ class path_conv #else int issocket () const {return dev.is_device (FH_LOCAL);} #endif /* __WITH_AF_UNIX */ - int iscygexec () const {return path_flags & PATH_CYGWIN_EXEC;} + int iscygexec () const {return mount_flags & MOUNT_CYGWIN_EXEC;} int isopen () const {return path_flags & PATH_OPEN;} int isctty_capable () const {return path_flags & PATH_CTTY;} void set_cygexec (bool isset) { if (isset) - path_flags |= PATH_CYGWIN_EXEC; + mount_flags |= MOUNT_CYGWIN_EXEC; else - path_flags &= ~PATH_CYGWIN_EXEC; + mount_flags &= ~MOUNT_CYGWIN_EXEC; } void set_cygexec (void *target) { if (target) - path_flags |= PATH_CYGWIN_EXEC; + mount_flags |= MOUNT_CYGWIN_EXEC; else - path_flags &= ~PATH_CYGWIN_EXEC; + mount_flags &= ~MOUNT_CYGWIN_EXEC; } - bool isro () const {return !!(path_flags & PATH_RO);} + bool isro () const {return !!(mount_flags & MOUNT_RO);} bool exists () const {return fileattr != INVALID_FILE_ATTRIBUTES;} bool has_attribute (DWORD x) const {return exists () && (fileattr & x);} int isdir () const {return has_attribute (FILE_ATTRIBUTE_DIRECTORY);} executable_states exec_state () { extern int _check_for_executable; - if (path_flags & PATH_ALL_EXEC) + if (mount_flags & (MOUNT_CYGWIN_EXEC | MOUNT_EXEC)) return is_executable; - if (path_flags & PATH_NOTEXEC) + if (mount_flags & MOUNT_NOTEXEC) return not_executable; if (!_check_for_executable) return dont_care_if_executable; @@ -240,48 +223,40 @@ class path_conv } void set_symlink (DWORD n) {path_flags |= PATH_SYMLINK; symlink_length = n;} - void set_exec (int x = 1) {path_flags |= x ? PATH_EXEC : PATH_NOTEXEC;} + void set_exec (int x = 1) {mount_flags |= x ? MOUNT_EXEC : MOUNT_NOTEXEC;} - void __reg3 check (const UNICODE_STRING *upath, unsigned opt = PC_SYM_FOLLOW, + void __reg3 check (const UNICODE_STRING *upath, uint32_t opt = PC_SYM_FOLLOW, const suffix_info *suffixes = NULL); - void __reg3 check (const char *src, unsigned opt = PC_SYM_FOLLOW, + void __reg3 check (const char *src, uint32_t opt = PC_SYM_FOLLOW, const suffix_info *suffixes = NULL); path_conv (const device& in_dev) : fileattr (INVALID_FILE_ATTRIBUTES), wide_path (NULL), path (NULL), - path_flags (0), suffix (NULL), posix_path (NULL), error (0), - dev (in_dev) + mount_flags (0), path_flags (0), suffix (NULL), posix_path (NULL), + error (0), dev (in_dev) { set_path (in_dev.native ()); } - path_conv (int, const char *src, unsigned opt = PC_SYM_FOLLOW, + path_conv (const UNICODE_STRING *src, uint32_t opt = PC_SYM_FOLLOW, const suffix_info *suffixes = NULL) : fileattr (INVALID_FILE_ATTRIBUTES), wide_path (NULL), path (NULL), - path_flags (0), suffix (NULL), posix_path (NULL), error (0) + mount_flags (0), path_flags (0), suffix (NULL), posix_path (NULL), error (0) { - check (src, opt, suffixes); + check (src, opt | ((opt & PC_NONULLEMPTY) ? 0 : PC_NULLEMPTY), suffixes); } - path_conv (const UNICODE_STRING *src, unsigned opt = PC_SYM_FOLLOW, + path_conv (const char *src, uint32_t opt = PC_SYM_FOLLOW, const suffix_info *suffixes = NULL) : fileattr (INVALID_FILE_ATTRIBUTES), wide_path (NULL), path (NULL), - path_flags (0), suffix (NULL), posix_path (NULL), error (0) + mount_flags (0), path_flags (0), suffix (NULL), posix_path (NULL), error (0) { - check (src, opt | PC_NULLEMPTY, suffixes); - } - - path_conv (const char *src, unsigned opt = PC_SYM_FOLLOW, - const suffix_info *suffixes = NULL) - : fileattr (INVALID_FILE_ATTRIBUTES), wide_path (NULL), path (NULL), - path_flags (0), suffix (NULL), posix_path (NULL), error (0) - { - check (src, opt | PC_NULLEMPTY, suffixes); + check (src, opt | ((opt & PC_NONULLEMPTY) ? 0 : PC_NULLEMPTY), suffixes); } path_conv () : fileattr (INVALID_FILE_ATTRIBUTES), wide_path (NULL), path (NULL), - path_flags (0), suffix (NULL), posix_path (NULL), error (0) + mount_flags (0), path_flags (0), suffix (NULL), posix_path (NULL), error (0) {} ~path_conv (); diff --git a/winsup/utils/path.cc b/winsup/utils/path.cc index 17ea3524d..1a14a8963 100644 --- a/winsup/utils/path.cc +++ b/winsup/utils/path.cc @@ -21,6 +21,7 @@ details. */ #include #include "path.h" #include "../cygwin/include/cygwin/version.h" +#include "../cygwin/include/cygwin/bits.h" #include "../cygwin/include/sys/mount.h" #define _NOMNTENT_MACROS #include "../cygwin/include/mntent.h" From ba12614f79347e6d67af79b7369869890aa5c741 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Sun, 6 Jan 2019 20:13:52 +0100 Subject: [PATCH 058/475] Cygwin: path_conv: add PATH_RESOLVE_PROCFD path_types flag path_conv now sets the PATH_RESOLVE_PROCFD flag in path_flags if the PC_SYM_NOFOLLOW_PROCFD pathconv_arg flag has been set on input *and* the file is actually a proc fd symlink. Add matching path_conv::follow_fd_symlink method for checking and use it in open(2). Signed-off-by: Corinna Vinschen --- winsup/cygwin/path.cc | 5 ++++- winsup/cygwin/path.h | 2 ++ winsup/cygwin/syscalls.cc | 8 ++++---- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc index 0a68671fb..158f1e5fb 100644 --- a/winsup/cygwin/path.cc +++ b/winsup/cygwin/path.cc @@ -850,7 +850,10 @@ path_conv::check (const char *src, unsigned opt, case virt_fdsymlink: /* Allow open/linkat to do the right thing. */ if (opt & PC_SYM_NOFOLLOW_PROCFD) - opt &= ~PC_SYM_FOLLOW; + { + opt &= ~PC_SYM_FOLLOW; + sym.path_flags |= PATH_RESOLVE_PROCFD; + } /*FALLTHRU*/ case virt_symlink: goto is_virtual_symlink; diff --git a/winsup/cygwin/path.h b/winsup/cygwin/path.h index 69da8fd93..af10321c5 100644 --- a/winsup/cygwin/path.h +++ b/winsup/cygwin/path.h @@ -69,6 +69,7 @@ enum path_types PATH_REP = _BIT ( 3), PATH_SYMLINK = _BIT ( 4), PATH_SOCKET = _BIT ( 5), + PATH_RESOLVE_PROCFD = _BIT ( 6), PATH_DONT_USE = _BIT (31) /* conversion to signed happens. */ }; @@ -192,6 +193,7 @@ class path_conv int iscygexec () const {return mount_flags & MOUNT_CYGWIN_EXEC;} int isopen () const {return path_flags & PATH_OPEN;} int isctty_capable () const {return path_flags & PATH_CTTY;} + int follow_fd_symlink () const {return path_flags & PATH_RESOLVE_PROCFD;} void set_cygexec (bool isset) { if (isset) diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc index 9f43512b2..60f66a63b 100644 --- a/winsup/cygwin/syscalls.cc +++ b/winsup/cygwin/syscalls.cc @@ -1398,13 +1398,13 @@ open (const char *unix_path, int flags, ...) if (fd < 0) __leave; /* errno already set */ + int opt = PC_OPEN | PC_SYM_NOFOLLOW_PROCFD; + opt |= (flags & (O_NOFOLLOW | O_EXCL)) ? PC_SYM_NOFOLLOW + : PC_SYM_FOLLOW; /* This is a temporary kludge until all utilities can catch up with a change in behavior that implements linux functionality: opening a tty should not automatically cause it to become the controlling tty for the process. */ - int opt = PC_OPEN | PC_SYM_NOFOLLOW_PROCFD; - opt |= (flags & (O_NOFOLLOW | O_EXCL)) ? PC_SYM_NOFOLLOW - : PC_SYM_FOLLOW; if (!(flags & O_NOCTTY) && fd > 2 && myself->ctty != -2) { flags |= O_NOCTTY; @@ -1472,7 +1472,7 @@ open (const char *unix_path, int flags, ...) fh = fh_file; } - if (fh->dev () == FH_PROCESSFD) + if (fh->dev () == FH_PROCESSFD && fh->pc.follow_fd_symlink ()) { /* Reopen file by descriptor */ fh_file = fh->fd_reopen (flags); From 7aca27b4fe553657d057dce90de13be97068fd4a Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Sun, 6 Jan 2019 20:18:14 +0100 Subject: [PATCH 059/475] Cygwin: introduce fhandler_process_fd and add stat(2) handling move special fd symlink code into own fhandler_process_fd class to simplify further additions to /proc/PID/fd/DESCRIPTOR symlink handling. Add a method to handle stat(2) on such a proc fd symlink by handle. This allows correct reply from stat(2) if the target file has been deleted. This eventually fixes `awk -f /dev/fd/3 3< --- winsup/cygwin/Makefile.in | 1 + winsup/cygwin/dtable.cc | 4 +- winsup/cygwin/fhandler.h | 32 +++++- winsup/cygwin/fhandler_process.cc | 160 --------------------------- winsup/cygwin/fhandler_process_fd.cc | 153 +++++++++++++++++++++++++ winsup/cygwin/syscalls.cc | 3 +- 6 files changed, 189 insertions(+), 164 deletions(-) create mode 100644 winsup/cygwin/fhandler_process_fd.cc diff --git a/winsup/cygwin/Makefile.in b/winsup/cygwin/Makefile.in index fb0195fc2..75c73bf92 100644 --- a/winsup/cygwin/Makefile.in +++ b/winsup/cygwin/Makefile.in @@ -288,6 +288,7 @@ DLL_OFILES:= \ fhandler_nodevice.o \ fhandler_proc.o \ fhandler_process.o \ + fhandler_process_fd.o \ fhandler_procnet.o \ fhandler_procsys.o \ fhandler_procsysvipc.o \ diff --git a/winsup/cygwin/dtable.cc b/winsup/cygwin/dtable.cc index 0ebeef058..780deb524 100644 --- a/winsup/cygwin/dtable.cc +++ b/winsup/cygwin/dtable.cc @@ -552,9 +552,11 @@ fh_alloc (path_conv& pc) fh = cnew (fhandler_registry); break; case FH_PROCESS: - case FH_PROCESSFD: fh = cnew (fhandler_process); break; + case FH_PROCESSFD: + fh = cnew (fhandler_process_fd); + break; case FH_PROCNET: fh = cnew (fhandler_procnet); break; diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h index 1c751c110..e32c219d3 100644 --- a/winsup/cygwin/fhandler.h +++ b/winsup/cygwin/fhandler.h @@ -2545,6 +2545,7 @@ class fhandler_registry: public fhandler_proc class pinfo; class fhandler_process: public fhandler_proc { + protected: pid_t pid; virtual_ftype_t fd_type; public: @@ -2554,8 +2555,6 @@ class fhandler_process: public fhandler_proc int closedir (DIR *); int __reg3 readdir (DIR *, dirent *); int open (int flags, mode_t mode = 0); - virtual fhandler_base *fd_reopen (int); - int __reg2 link (const char *); int __reg2 fstat (struct stat *buf); bool fill_filebuf (); @@ -2577,6 +2576,34 @@ class fhandler_process: public fhandler_proc } }; +class fhandler_process_fd : public fhandler_process +{ + fhandler_base *fetch_fh (HANDLE &); + + public: + fhandler_process_fd () : fhandler_process () {} + fhandler_process_fd (void *) {} + + virtual fhandler_base *fd_reopen (int); + int __reg2 fstat (struct stat *buf); + virtual int __reg2 link (const char *); + + void copyto (fhandler_base *x) + { + x->pc.free_strings (); + *reinterpret_cast (x) = *this; + x->reset (this); + } + + fhandler_process_fd *clone (cygheap_types malloc_type = HEAP_FHANDLER) + { + void *ptr = (void *) ccalloc (malloc_type, 1, sizeof (fhandler_process_fd)); + fhandler_process_fd *fh = new (ptr) fhandler_process_fd (ptr); + copyto (fh); + return fh; + } +}; + class fhandler_procnet: public fhandler_proc { pid_t pid; @@ -2638,6 +2665,7 @@ typedef union char __pipe[sizeof (fhandler_pipe)]; char __proc[sizeof (fhandler_proc)]; char __process[sizeof (fhandler_process)]; + char __process_fd[sizeof (fhandler_process_fd)]; char __procnet[sizeof (fhandler_procnet)]; char __procsys[sizeof (fhandler_procsys)]; char __procsysvipc[sizeof (fhandler_procsysvipc)]; diff --git a/winsup/cygwin/fhandler_process.cc b/winsup/cygwin/fhandler_process.cc index a52314810..24ef7d00c 100644 --- a/winsup/cygwin/fhandler_process.cc +++ b/winsup/cygwin/fhandler_process.cc @@ -321,166 +321,6 @@ out: return res; } -fhandler_base * -fhandler_process::fd_reopen (int flags) -{ - const char *path; - char *e; - int fd; - HANDLE proc = NULL; - HANDLE hdl = NULL; - fhandler_base *fh = NULL; - - path = get_name () + proc_len + 1; - pid = strtoul (path, &e, 10); - path = e + 4; - fd = strtoul (path, &e, 10); - if (e == path || *e != '\0') - { - set_errno (ENOENT); - return NULL; - } - - if (pid == myself->pid) - { - cygheap_fdget cfd (fd); - if (cfd < 0) - return NULL; - fh = build_fh_pc (cfd->pc); - if (!fh) - goto err_out; - fh->set_io_handle (cfd->get_handle ()); - } - else - { - size_t size; - path_conv pc; - - pinfo p (pid); - if (!p) - { - set_errno (ENOENT); - return NULL; - } - if (!(proc = OpenProcess (PROCESS_DUP_HANDLE, false, p->dwProcessId))) - { - __seterrno (); - return NULL; - } - void *buf = p->file_pathconv (fd, size); - if (size == 0) - { - set_errno (EPERM); - goto err_out; - } - hdl = pc.deserialize (buf); - if (!DuplicateHandle (proc, hdl, GetCurrentProcess (), &hdl, - 0, FALSE, DUPLICATE_SAME_ACCESS)) - { - __seterrno (); - hdl = NULL; - goto err_out; - } - fh = build_fh_pc (pc); - if (!fh) - goto err_out; - fh->set_io_handle (hdl); - } - if (!fh->open_with_arch (flags, 0)) - { - delete fh; - fh = NULL; - } -err_out: - if (hdl) - CloseHandle (hdl); - if (proc) - CloseHandle (proc); - return fh; -} - -int -fhandler_process::link (const char *newpath) -{ - const char *path; - int fd; - char *e; - - path = get_name () + proc_len + 1; - pid = atoi (path); - while (*path != 0 && !isdirsep (*path)) - path++; - if (*path == 0) - goto err_out; - - virt_tab_t *entry; - entry = virt_tab_search (path + 1, true, process_tab, PROCESS_LINK_COUNT); - if (!entry || entry->fhandler != FH_PROCESSFD) - goto err_out; - if (path[3] != '/' || path[4] == '\0') - goto err_out; - - fd = strtoul (path + 4, &e, 10); - if (fd < 0 || e == path + 4 || (*e != '/' && *e != '\0')) - goto err_out; - if (pid == myself->pid) - { - cygheap_fdget cfd (fd); - if (cfd < 0) - goto err_out; - return cfd->link (newpath); - } - else - { - HANDLE proc; - size_t size; - void *buf; - path_conv pc; - HANDLE hdl; - fhandler_base *fh = NULL; - int ret = -1; - - pinfo p (pid); - if (!p) - { - set_errno (ENOENT); - return -1; - } - if (!(proc = OpenProcess (PROCESS_DUP_HANDLE, false, p->dwProcessId))) - goto err_out; - buf = p->file_pathconv (fd, size); - if (size == 0) - { - set_errno (EPERM); - goto err_out_close_proc; - } - hdl = pc.deserialize (buf); - if (!DuplicateHandle (proc, hdl, GetCurrentProcess (), &hdl, - 0, FALSE, DUPLICATE_SAME_ACCESS)) - { - __seterrno (); - goto err_out_close_proc; - } - fh = build_fh_pc (pc); - if (!fh) - goto err_out_close_dup; - - fh->set_io_handle (hdl); - ret = fh->link (newpath); - delete fh; - -err_out_close_dup: - CloseHandle (hdl); -err_out_close_proc: - CloseHandle (proc); - return ret; - } - -err_out: - set_errno (EPERM); - return -1; -} - struct process_fd_t { const char *path; _pinfo *p; diff --git a/winsup/cygwin/fhandler_process_fd.cc b/winsup/cygwin/fhandler_process_fd.cc new file mode 100644 index 000000000..06d37c0e6 --- /dev/null +++ b/winsup/cygwin/fhandler_process_fd.cc @@ -0,0 +1,153 @@ +/* fhandler_process_fd.cc: fhandler for /proc//fd/ operations + +This file is part of Cygwin. + +This software is a copyrighted work licensed under the terms of the +Cygwin license. Please consult the file "CYGWIN_LICENSE" for +details. */ + +#include "winsup.h" +#include +#include +#include +#include "cygerrno.h" +#include "security.h" +#include "path.h" +#include "fhandler.h" +#include "fhandler_virtual.h" +#include "pinfo.h" +#include "shared_info.h" +#include "dtable.h" +#include "cygheap.h" +#include "ntdll.h" +#include "cygtls.h" +#include "mount.h" +#include "tls_pbuf.h" +#include +#include +#include + + +fhandler_base * +fhandler_process_fd::fetch_fh (HANDLE &out_hdl) +{ + const char *path; + char *e; + int fd; + HANDLE proc; + HANDLE hdl = NULL; + path_conv pc; + + path = get_name () + proc_len + 1; + pid = strtoul (path, &e, 10); + path = e + 4; + fd = strtoul (path, &e, 10); + + out_hdl = NULL; + if (pid == myself->pid) + { + cygheap_fdget cfd (fd, true); + if (cfd < 0) + return NULL; + proc = GetCurrentProcess (); + pc << cfd->pc; + hdl = cfd->get_handle (); + } + else + { + pinfo p (pid); + if (!p) + { + set_errno (ENOENT); + return NULL; + } + proc = OpenProcess (PROCESS_DUP_HANDLE, false, p->dwProcessId); + if (!proc) + { + __seterrno (); + return NULL; + } + size_t size; + void *buf = p->file_pathconv (fd, size); + if (size == 0) + { + set_errno (EPERM); + CloseHandle (proc); + return NULL; + } + hdl = pc.deserialize (buf); + } + BOOL ret = DuplicateHandle (proc, hdl, GetCurrentProcess (), &hdl, + 0, FALSE, DUPLICATE_SAME_ACCESS); + if (proc != GetCurrentProcess ()) + CloseHandle (proc); + if (!ret) + { + __seterrno (); + CloseHandle (hdl); + return NULL; + } + fhandler_base *fh = build_fh_pc (pc); + if (!fh) + { + CloseHandle (hdl); + return NULL; + } + out_hdl = hdl; + return fh; +} + +fhandler_base * +fhandler_process_fd::fd_reopen (int flags) +{ + fhandler_base *fh; + HANDLE hdl; + + fh = fetch_fh (hdl); + if (!fh) + return NULL; + fh->set_io_handle (hdl); + int ret = fh->open_with_arch (flags, 0); + CloseHandle (hdl); + if (!ret) + { + delete fh; + fh = NULL; + } + return fh; +} + +int __reg2 +fhandler_process_fd::fstat (struct stat *statbuf) +{ + if (!pc.follow_fd_symlink ()) + return fhandler_process::fstat (statbuf); + + fhandler_base *fh; + HANDLE hdl; + + fh = fetch_fh (hdl); + if (!fh) + return -1; + fh->set_io_handle (hdl); + int ret = fh->fstat (statbuf); + CloseHandle (hdl); + delete fh; + return ret; +} + +int +fhandler_process_fd::link (const char *newpath) +{ + fhandler_base *fh; + HANDLE hdl; + + fh = fetch_fh (hdl); + if (!fh) + return -1; + fh->set_io_handle (hdl); + int ret = fh->link (newpath); + CloseHandle (hdl); + delete fh; + return ret; +} diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc index 60f66a63b..5bb33bf0a 100644 --- a/winsup/cygwin/syscalls.cc +++ b/winsup/cygwin/syscalls.cc @@ -2005,7 +2005,8 @@ extern "C" int stat64 (const char *__restrict name, struct stat *__restrict buf) { syscall_printf ("entering"); - path_conv pc (name, PC_SYM_FOLLOW | PC_POSIX | PC_KEEP_HANDLE, + path_conv pc (name, PC_SYM_FOLLOW | PC_POSIX | PC_KEEP_HANDLE + | PC_SYM_NOFOLLOW_PROCFD, stat_suffixes); return stat_worker (pc, buf); } From 8a17b1b2bf7a503f3d586cc9f74e2291e6fce6ba Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Sun, 6 Jan 2019 20:28:48 +0100 Subject: [PATCH 060/475] Cygwin: document proc fd changes Signed-off-by: Corinna Vinschen --- winsup/cygwin/release/2.12.0 | 8 ++++++++ winsup/doc/new-features.xml | 5 +++++ 2 files changed, 13 insertions(+) diff --git a/winsup/cygwin/release/2.12.0 b/winsup/cygwin/release/2.12.0 index 65868adb7..03a6a3aaf 100644 --- a/winsup/cygwin/release/2.12.0 +++ b/winsup/cygwin/release/2.12.0 @@ -33,6 +33,9 @@ What changed: Deleting an in-use file now actually removes the file, rather than moving it to the recycler bin. +- open(..., O_TMPFILE) now moves the file to the trash bin immediately, + to free the parent directory. + Bug Fixes --------- @@ -44,3 +47,8 @@ Bug Fixes Addresses: https://cygwin.com/ml/cygwin/2018-11/msg00171.html - Fix a bug in recognizing remote FAT/FAT32/exFAT correctly. + +- Allow open(2)/stat(2)/linkat(2) of a file via /proc/PID/fd/DESCRIPTOR + even if file has been deleted. + Addresses: https://cygwin.com/ml/cygwin/2018-12/msg00125.html + https://cygwin.com/ml/cygwin/2018-12/msg00028.html diff --git a/winsup/doc/new-features.xml b/winsup/doc/new-features.xml index 4750c0e9a..a1a529d32 100644 --- a/winsup/doc/new-features.xml +++ b/winsup/doc/new-features.xml @@ -52,6 +52,11 @@ Use the new POSIX unlink semantics on NTFS starting with Windows 10 than moving it to the recycler bin. + +open(..., O_TMPFILE) now moves the file to the trash bin immediately, +to free the parent directory. + + From 9dae73edb8871f017251ddcba959e09457923a8e Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Sun, 6 Jan 2019 22:39:45 +0100 Subject: [PATCH 061/475] Cygwin: fix regression in O_TMPFILE | O_EXCL case The new proc fd code accidentally allowed to linkat an O_TMPFILE even if the file has been opened with O_EXCL. This patch fixes it. Signed-off-by: Corinna Vinschen --- winsup/cygwin/fhandler.h | 2 +- winsup/cygwin/fhandler_process_fd.cc | 18 ++++++++++++------ winsup/cygwin/include/cygwin/signal.h | 5 ++++- winsup/cygwin/path.h | 5 +++++ winsup/cygwin/pinfo.cc | 11 ++++++++--- winsup/cygwin/pinfo.h | 2 +- 6 files changed, 31 insertions(+), 12 deletions(-) diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h index e32c219d3..d02b9a913 100644 --- a/winsup/cygwin/fhandler.h +++ b/winsup/cygwin/fhandler.h @@ -2578,7 +2578,7 @@ class fhandler_process: public fhandler_proc class fhandler_process_fd : public fhandler_process { - fhandler_base *fetch_fh (HANDLE &); + fhandler_base *fetch_fh (HANDLE &, uint32_t); public: fhandler_process_fd () : fhandler_process () {} diff --git a/winsup/cygwin/fhandler_process_fd.cc b/winsup/cygwin/fhandler_process_fd.cc index 06d37c0e6..0c0452ab4 100644 --- a/winsup/cygwin/fhandler_process_fd.cc +++ b/winsup/cygwin/fhandler_process_fd.cc @@ -29,7 +29,7 @@ details. */ fhandler_base * -fhandler_process_fd::fetch_fh (HANDLE &out_hdl) +fhandler_process_fd::fetch_fh (HANDLE &out_hdl, uint32_t flags) { const char *path; char *e; @@ -49,6 +49,12 @@ fhandler_process_fd::fetch_fh (HANDLE &out_hdl) cygheap_fdget cfd (fd, true); if (cfd < 0) return NULL; + if ((flags & FFH_LINKAT) + && (cfd->get_flags () & (O_TMPFILE | O_EXCL)) == (O_TMPFILE | O_EXCL)) + { + set_errno (ENOENT); + return NULL; + } proc = GetCurrentProcess (); pc << cfd->pc; hdl = cfd->get_handle (); @@ -68,10 +74,10 @@ fhandler_process_fd::fetch_fh (HANDLE &out_hdl) return NULL; } size_t size; - void *buf = p->file_pathconv (fd, size); + void *buf = p->file_pathconv (fd, FFH_LINKAT, size); if (size == 0) { - set_errno (EPERM); + set_errno (ENOENT); CloseHandle (proc); return NULL; } @@ -103,7 +109,7 @@ fhandler_process_fd::fd_reopen (int flags) fhandler_base *fh; HANDLE hdl; - fh = fetch_fh (hdl); + fh = fetch_fh (hdl, 0); if (!fh) return NULL; fh->set_io_handle (hdl); @@ -126,7 +132,7 @@ fhandler_process_fd::fstat (struct stat *statbuf) fhandler_base *fh; HANDLE hdl; - fh = fetch_fh (hdl); + fh = fetch_fh (hdl, 0); if (!fh) return -1; fh->set_io_handle (hdl); @@ -142,7 +148,7 @@ fhandler_process_fd::link (const char *newpath) fhandler_base *fh; HANDLE hdl; - fh = fetch_fh (hdl); + fh = fetch_fh (hdl, FFH_LINKAT); if (!fh) return -1; fh->set_io_handle (hdl); diff --git a/winsup/cygwin/include/cygwin/signal.h b/winsup/cygwin/include/cygwin/signal.h index 9d9972740..e659d7ae0 100644 --- a/winsup/cygwin/include/cygwin/signal.h +++ b/winsup/cygwin/include/cygwin/signal.h @@ -187,7 +187,10 @@ struct _sigcommune void *_si_process_handle; __extension__ union { - int _si_fd; + struct { + int _si_fd; + uint32_t _si_flags; + }; int64_t _si_pipe_unique_id; char *_si_str; }; diff --git a/winsup/cygwin/path.h b/winsup/cygwin/path.h index af10321c5..2b885045d 100644 --- a/winsup/cygwin/path.h +++ b/winsup/cygwin/path.h @@ -73,6 +73,11 @@ enum path_types PATH_DONT_USE = _BIT (31) /* conversion to signed happens. */ }; +enum fetch_fh_flags +{ + FFH_LINKAT = (1 << 0), +}; + NTSTATUS file_get_fai (HANDLE, PFILE_ALL_INFORMATION); int check_reparse_point_target (HANDLE, bool, PREPARSE_DATA_BUFFER, PUNICODE_STRING); diff --git a/winsup/cygwin/pinfo.cc b/winsup/cygwin/pinfo.cc index 00b3ed623..90dfd2b7c 100644 --- a/winsup/cygwin/pinfo.cc +++ b/winsup/cygwin/pinfo.cc @@ -660,9 +660,13 @@ commune_process (void *arg) { sigproc_printf ("processing PICOM_FILE_PATHCONV"); int fd = si._si_commune._si_fd; + uint32_t flags = si._si_commune._si_flags; unsigned int n = 0; cygheap_fdget cfd (fd); - if (cfd >= 0) + if (cfd >= 0 + && (!(flags & FFH_LINKAT) + || (cfd->get_flags () & (O_TMPFILE | O_EXCL)) + != (O_TMPFILE | O_EXCL))) { fhandler_base *fh = cfd; void *ser_buf = fh->pc.serialize (fh->get_handle (), n); @@ -763,6 +767,7 @@ _pinfo::commune_request (__uint32_t code, ...) case PICOM_FD: case PICOM_FILE_PATHCONV: si._si_commune._si_fd = va_arg (args, int); + si._si_commune._si_flags = va_arg (args, uint32_t); break; break; @@ -852,13 +857,13 @@ _pinfo::pipe_fhandler (int64_t unique_id, size_t &n) } void * -_pinfo::file_pathconv (int fd, size_t &n) +_pinfo::file_pathconv (int fd, uint32_t flags, size_t &n) { if (!pid) return NULL; if (pid == myself->pid) return NULL; - commune_result cr = commune_request (PICOM_FILE_PATHCONV, fd); + commune_result cr = commune_request (PICOM_FILE_PATHCONV, fd, flags); n = cr.n; return (void *) cr.s; } diff --git a/winsup/cygwin/pinfo.h b/winsup/cygwin/pinfo.h index 8eb3c43ea..c4881c7f8 100644 --- a/winsup/cygwin/pinfo.h +++ b/winsup/cygwin/pinfo.h @@ -103,7 +103,7 @@ public: commune_result commune_request (__uint32_t, ...); bool alive (); fhandler_pipe *pipe_fhandler (int64_t, size_t &); - void *file_pathconv (int, size_t &); + void *file_pathconv (int, uint32_t, size_t &); char *fd (int fd, size_t &); char *fds (size_t &); char *root (size_t &); From 4c33add5b89714b58b30d7020935ab985257dc92 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Sun, 6 Jan 2019 22:40:17 +0100 Subject: [PATCH 062/475] Cygwin: drop redundant includes from fhandler_process_fd.cc Signed-off-by: Corinna Vinschen --- winsup/cygwin/fhandler_process_fd.cc | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/winsup/cygwin/fhandler_process_fd.cc b/winsup/cygwin/fhandler_process_fd.cc index 0c0452ab4..a9d085ae5 100644 --- a/winsup/cygwin/fhandler_process_fd.cc +++ b/winsup/cygwin/fhandler_process_fd.cc @@ -7,26 +7,12 @@ Cygwin license. Please consult the file "CYGWIN_LICENSE" for details. */ #include "winsup.h" -#include -#include -#include -#include "cygerrno.h" -#include "security.h" #include "path.h" #include "fhandler.h" #include "fhandler_virtual.h" #include "pinfo.h" -#include "shared_info.h" #include "dtable.h" #include "cygheap.h" -#include "ntdll.h" -#include "cygtls.h" -#include "mount.h" -#include "tls_pbuf.h" -#include -#include -#include - fhandler_base * fhandler_process_fd::fetch_fh (HANDLE &out_hdl, uint32_t flags) From 9db7f4d1dd09a7b498aa16affb1c85f8f7c0e59e Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Mon, 7 Jan 2019 12:29:07 +0100 Subject: [PATCH 063/475] Cygwin: move fhandler_cygdrive methods into own source file Signed-off-by: Corinna Vinschen --- winsup/cygwin/Makefile.in | 1 + winsup/cygwin/fhandler_cygdrive.cc | 158 ++++++++++++++++++++++++++++ winsup/cygwin/fhandler_disk_file.cc | 137 ------------------------ 3 files changed, 159 insertions(+), 137 deletions(-) create mode 100644 winsup/cygwin/fhandler_cygdrive.cc diff --git a/winsup/cygwin/Makefile.in b/winsup/cygwin/Makefile.in index 75c73bf92..733678e96 100644 --- a/winsup/cygwin/Makefile.in +++ b/winsup/cygwin/Makefile.in @@ -279,6 +279,7 @@ DLL_OFILES:= \ fhandler.o \ fhandler_clipboard.o \ fhandler_console.o \ + fhandler_cygdrive.o \ fhandler_dev.o \ fhandler_disk_file.o \ fhandler_dsp.o \ diff --git a/winsup/cygwin/fhandler_cygdrive.cc b/winsup/cygwin/fhandler_cygdrive.cc new file mode 100644 index 000000000..508cc3650 --- /dev/null +++ b/winsup/cygwin/fhandler_cygdrive.cc @@ -0,0 +1,158 @@ +/* fhandler_cygdrive.cc + +This file is part of Cygwin. + +This software is a copyrighted work licensed under the terms of the +Cygwin license. Please consult the file "CYGWIN_LICENSE" for +details. */ + +#include "winsup.h" +#include +#include +#include "cygerrno.h" +#include "security.h" +#include "path.h" +#include "fhandler.h" +#include "dtable.h" +#include "cygheap.h" +#include "shared_info.h" + +#define _COMPILING_NEWLIB +#include + +fhandler_cygdrive::fhandler_cygdrive () : + fhandler_disk_file () +{ +} + +int +fhandler_cygdrive::open (int flags, mode_t mode) +{ + if ((flags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL)) + { + set_errno (EEXIST); + return 0; + } + if (flags & O_WRONLY) + { + set_errno (EISDIR); + return 0; + } + /* Open a fake handle to \\Device\\Null */ + return open_null (flags); +} + +int +fhandler_cygdrive::fstat (struct stat *buf) +{ + fhandler_base::fstat (buf); + buf->st_ino = 2; + buf->st_mode = S_IFDIR | STD_RBITS | STD_XBITS; + buf->st_nlink = 1; + return 0; +} + +int __reg2 +fhandler_cygdrive::fstatvfs (struct statvfs *sfs) +{ + /* Virtual file system. Just return an empty buffer with a few values + set to something useful. Just as on Linux. */ + memset (sfs, 0, sizeof (*sfs)); + sfs->f_bsize = sfs->f_frsize = 4096; + sfs->f_flag = ST_RDONLY; + sfs->f_namemax = NAME_MAX; + return 0; +} + +#define MAX_DRIVE_BUF_LEN (sizeof ("x:\\") * 26 + 2) + +struct __DIR_drives +{ + char *pdrive; + char pbuf[MAX_DRIVE_BUF_LEN]; +}; + +#define d_drives(d) ((__DIR_drives *) (d)->__d_internal) + +DIR * +fhandler_cygdrive::opendir (int fd) +{ + DIR *dir; + + dir = fhandler_disk_file::opendir (fd); + if (dir) + { + dir->__d_internal = (uintptr_t) new __DIR_drives; + GetLogicalDriveStrings (MAX_DRIVE_BUF_LEN, d_drives(dir)->pbuf); + d_drives(dir)->pdrive = d_drives(dir)->pbuf; + } + + return dir; +} + +int +fhandler_cygdrive::readdir (DIR *dir, dirent *de) +{ + WCHAR drive[] = L"X:"; + + while (true) + { + if (!d_drives(dir)->pdrive || !*d_drives(dir)->pdrive) + { + if (!(dir->__flags & dirent_saw_dot)) + { + de->d_name[0] = '.'; + de->d_name[1] = '\0'; + de->d_ino = 2; + } + return ENMFILE; + } + disk_type dt = get_disk_type ((drive[0] = *d_drives(dir)->pdrive, drive)); + if (dt == DT_SHARE_SMB) + { + /* Calling NetUseGetInfo on SMB drives allows to fetch the + current state of the drive without trying to open a file + descriptor on the share (GetFileAttributes). This avoids + waiting for SMB timeouts. Of course, there's a downside: + If a drive becomes availabe again, it can take a couple of + minutes to recognize it. As long as this didn't happen, + the drive will not show up in the cygdrive dir. */ + PUSE_INFO_1 pui1; + DWORD status; + + if (NetUseGetInfo (NULL, drive, 1, (PBYTE *) &pui1) == NERR_Success) + { + status = pui1->ui1_status; + NetApiBufferFree (pui1); + if (status == USE_OK) + break; + } + } + else if (dt != DT_FLOPPY + && GetFileAttributes (d_drives(dir)->pdrive) != INVALID_FILE_ATTRIBUTES) + break; + d_drives(dir)->pdrive = strchr (d_drives(dir)->pdrive, '\0') + 1; + } + *de->d_name = cyg_tolower (*d_drives(dir)->pdrive); + de->d_name[1] = '\0'; + user_shared->warned_msdos = true; + de->d_ino = readdir_get_ino (d_drives(dir)->pdrive, false); + dir->__d_position++; + d_drives(dir)->pdrive = strchr (d_drives(dir)->pdrive, '\0') + 1; + syscall_printf ("%p = readdir (%p) (%s)", &de, dir, de->d_name); + return 0; +} + +void +fhandler_cygdrive::rewinddir (DIR *dir) +{ + d_drives(dir)->pdrive = d_drives(dir)->pbuf; + dir->__d_position = 0; +} + +int +fhandler_cygdrive::closedir (DIR *dir) +{ + delete d_drives(dir); + return 0; +} diff --git a/winsup/cygwin/fhandler_disk_file.cc b/winsup/cygwin/fhandler_disk_file.cc index e0a196fae..5a8463eff 100644 --- a/winsup/cygwin/fhandler_disk_file.cc +++ b/winsup/cygwin/fhandler_disk_file.cc @@ -2683,140 +2683,3 @@ fhandler_disk_file::ioctl (unsigned int cmd, void *p) syscall_printf ("%d = ioctl_file(%x, %p)", ret, cmd, p); return ret; } - -fhandler_cygdrive::fhandler_cygdrive () : - fhandler_disk_file () -{ -} - -int -fhandler_cygdrive::open (int flags, mode_t mode) -{ - if ((flags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL)) - { - set_errno (EEXIST); - return 0; - } - if (flags & O_WRONLY) - { - set_errno (EISDIR); - return 0; - } - /* Open a fake handle to \\Device\\Null */ - return open_null (flags); -} - -int -fhandler_cygdrive::fstat (struct stat *buf) -{ - fhandler_base::fstat (buf); - buf->st_ino = 2; - buf->st_mode = S_IFDIR | STD_RBITS | STD_XBITS; - buf->st_nlink = 1; - return 0; -} - -int __reg2 -fhandler_cygdrive::fstatvfs (struct statvfs *sfs) -{ - /* Virtual file system. Just return an empty buffer with a few values - set to something useful. Just as on Linux. */ - memset (sfs, 0, sizeof (*sfs)); - sfs->f_bsize = sfs->f_frsize = 4096; - sfs->f_flag = ST_RDONLY; - sfs->f_namemax = NAME_MAX; - return 0; -} - -#define MAX_DRIVE_BUF_LEN (sizeof ("x:\\") * 26 + 2) - -struct __DIR_drives -{ - char *pdrive; - char pbuf[MAX_DRIVE_BUF_LEN]; -}; - -#define d_drives(d) ((__DIR_drives *) (d)->__d_internal) - -DIR * -fhandler_cygdrive::opendir (int fd) -{ - DIR *dir; - - dir = fhandler_disk_file::opendir (fd); - if (dir) - { - dir->__d_internal = (uintptr_t) new __DIR_drives; - GetLogicalDriveStrings (MAX_DRIVE_BUF_LEN, d_drives(dir)->pbuf); - d_drives(dir)->pdrive = d_drives(dir)->pbuf; - } - - return dir; -} - -int -fhandler_cygdrive::readdir (DIR *dir, dirent *de) -{ - WCHAR drive[] = L"X:"; - - while (true) - { - if (!d_drives(dir)->pdrive || !*d_drives(dir)->pdrive) - { - if (!(dir->__flags & dirent_saw_dot)) - { - de->d_name[0] = '.'; - de->d_name[1] = '\0'; - de->d_ino = 2; - } - return ENMFILE; - } - disk_type dt = get_disk_type ((drive[0] = *d_drives(dir)->pdrive, drive)); - if (dt == DT_SHARE_SMB) - { - /* Calling NetUseGetInfo on SMB drives allows to fetch the - current state of the drive without trying to open a file - descriptor on the share (GetFileAttributes). This avoids - waiting for SMB timeouts. Of course, there's a downside: - If a drive becomes availabe again, it can take a couple of - minutes to recognize it. As long as this didn't happen, - the drive will not show up in the cygdrive dir. */ - PUSE_INFO_1 pui1; - DWORD status; - - if (NetUseGetInfo (NULL, drive, 1, (PBYTE *) &pui1) == NERR_Success) - { - status = pui1->ui1_status; - NetApiBufferFree (pui1); - if (status == USE_OK) - break; - } - } - else if (dt != DT_FLOPPY - && GetFileAttributes (d_drives(dir)->pdrive) != INVALID_FILE_ATTRIBUTES) - break; - d_drives(dir)->pdrive = strchr (d_drives(dir)->pdrive, '\0') + 1; - } - *de->d_name = cyg_tolower (*d_drives(dir)->pdrive); - de->d_name[1] = '\0'; - user_shared->warned_msdos = true; - de->d_ino = readdir_get_ino (d_drives(dir)->pdrive, false); - dir->__d_position++; - d_drives(dir)->pdrive = strchr (d_drives(dir)->pdrive, '\0') + 1; - syscall_printf ("%p = readdir (%p) (%s)", &de, dir, de->d_name); - return 0; -} - -void -fhandler_cygdrive::rewinddir (DIR *dir) -{ - d_drives(dir)->pdrive = d_drives(dir)->pbuf; - dir->__d_position = 0; -} - -int -fhandler_cygdrive::closedir (DIR *dir) -{ - delete d_drives(dir); - return 0; -} From 91ca95ae4a7ee353fb913d31da6c183b9b4a1656 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Mon, 7 Jan 2019 12:31:28 +0100 Subject: [PATCH 064/475] Cygwin: rename pipe.cc to fhandler_pipe.cc move pipe syscalls to syscalls.cc Signed-off-by: Corinna Vinschen --- winsup/cygwin/Makefile.in | 2 +- winsup/cygwin/{pipe.cc => fhandler_pipe.cc} | 70 --------------------- winsup/cygwin/syscalls.cc | 70 +++++++++++++++++++++ 3 files changed, 71 insertions(+), 71 deletions(-) rename winsup/cygwin/{pipe.cc => fhandler_pipe.cc} (87%) diff --git a/winsup/cygwin/Makefile.in b/winsup/cygwin/Makefile.in index 733678e96..e4ce31fda 100644 --- a/winsup/cygwin/Makefile.in +++ b/winsup/cygwin/Makefile.in @@ -287,6 +287,7 @@ DLL_OFILES:= \ fhandler_floppy.o \ fhandler_netdrive.o \ fhandler_nodevice.o \ + fhandler_pipe.o \ fhandler_proc.o \ fhandler_process.o \ fhandler_process_fd.o \ @@ -349,7 +350,6 @@ DLL_OFILES:= \ passwd.o \ path.o \ pinfo.o \ - pipe.o \ poll.o \ posix_ipc.o \ pseudo-reloc.o \ diff --git a/winsup/cygwin/pipe.cc b/winsup/cygwin/fhandler_pipe.cc similarity index 87% rename from winsup/cygwin/pipe.cc rename to winsup/cygwin/fhandler_pipe.cc index a75275d7c..eafaa8856 100644 --- a/winsup/cygwin/pipe.cc +++ b/winsup/cygwin/fhandler_pipe.cc @@ -436,73 +436,3 @@ fhandler_pipe::fstatvfs (struct statvfs *sfs) set_errno (EBADF); return -1; } - -static int __reg3 -pipe_worker (int filedes[2], unsigned int psize, int mode) -{ - fhandler_pipe *fhs[2]; - int res = fhandler_pipe::create (fhs, psize, mode); - if (!res) - { - cygheap_fdnew fdin; - cygheap_fdnew fdout (fdin, false); - char buf[sizeof ("/proc/self/fd/pipe:[9223372036854775807]")]; - __small_sprintf (buf, "/proc/self/fd/pipe:[%D]", fhs[0]->get_plain_ino ()); - fhs[0]->pc.set_posix (buf); - __small_sprintf (buf, "pipe:[%D]", fhs[1]->get_plain_ino ()); - fhs[1]->pc.set_posix (buf); - fdin = fhs[0]; - fdout = fhs[1]; - filedes[0] = fdin; - filedes[1] = fdout; - } - return res; -} - -extern "C" int -_pipe (int filedes[2], unsigned int psize, int mode) -{ - int res = pipe_worker (filedes, psize, mode); - int read, write; - if (res != 0) - read = write = -1; - else - { - read = filedes[0]; - write = filedes[1]; - } - syscall_printf ("%R = _pipe([%d, %d], %u, %y)", res, read, write, psize, mode); - return res; -} - -extern "C" int -pipe (int filedes[2]) -{ - int res = pipe_worker (filedes, DEFAULT_PIPEBUFSIZE, O_BINARY); - int read, write; - if (res != 0) - read = write = -1; - else - { - read = filedes[0]; - write = filedes[1]; - } - syscall_printf ("%R = pipe([%d, %d])", res, read, write); - return res; -} - -extern "C" int -pipe2 (int filedes[2], int mode) -{ - int res = pipe_worker (filedes, DEFAULT_PIPEBUFSIZE, mode); - int read, write; - if (res != 0) - read = write = -1; - else - { - read = filedes[0]; - write = filedes[1]; - } - syscall_printf ("%R = pipe2([%d, %d], %y)", res, read, write, mode); - return res; -} diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc index 5bb33bf0a..b99a21e8e 100644 --- a/winsup/cygwin/syscalls.cc +++ b/winsup/cygwin/syscalls.cc @@ -4959,3 +4959,73 @@ unlinkat (int dirfd, const char *pathname, int flags) __endtry return -1; } + +static int __reg3 +pipe_worker (int filedes[2], unsigned int psize, int mode) +{ + fhandler_pipe *fhs[2]; + int res = fhandler_pipe::create (fhs, psize, mode); + if (!res) + { + cygheap_fdnew fdin; + cygheap_fdnew fdout (fdin, false); + char buf[sizeof ("/proc/self/fd/pipe:[9223372036854775807]")]; + __small_sprintf (buf, "/proc/self/fd/pipe:[%D]", fhs[0]->get_plain_ino ()); + fhs[0]->pc.set_posix (buf); + __small_sprintf (buf, "pipe:[%D]", fhs[1]->get_plain_ino ()); + fhs[1]->pc.set_posix (buf); + fdin = fhs[0]; + fdout = fhs[1]; + filedes[0] = fdin; + filedes[1] = fdout; + } + return res; +} + +extern "C" int +_pipe (int filedes[2], unsigned int psize, int mode) +{ + int res = pipe_worker (filedes, psize, mode); + int read, write; + if (res != 0) + read = write = -1; + else + { + read = filedes[0]; + write = filedes[1]; + } + syscall_printf ("%R = _pipe([%d, %d], %u, %y)", res, read, write, psize, mode); + return res; +} + +extern "C" int +pipe (int filedes[2]) +{ + int res = pipe_worker (filedes, DEFAULT_PIPEBUFSIZE, O_BINARY); + int read, write; + if (res != 0) + read = write = -1; + else + { + read = filedes[0]; + write = filedes[1]; + } + syscall_printf ("%R = pipe([%d, %d])", res, read, write); + return res; +} + +extern "C" int +pipe2 (int filedes[2], int mode) +{ + int res = pipe_worker (filedes, DEFAULT_PIPEBUFSIZE, mode); + int read, write; + if (res != 0) + read = write = -1; + else + { + read = filedes[0]; + write = filedes[1]; + } + syscall_printf ("%R = pipe2([%d, %d], %y)", res, read, write, mode); + return res; +} From b93022a82dc523bcb731c2f69fb6e602c79060b5 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Mon, 7 Jan 2019 19:33:11 +0100 Subject: [PATCH 065/475] Cygwin: open: support Linux-specific O_PATH flag Signed-off-by: Corinna Vinschen --- newlib/libc/include/sys/_default_fcntl.h | 2 ++ winsup/cygwin/fhandler.cc | 3 ++ winsup/cygwin/ioctl.cc | 5 ++++ winsup/cygwin/mmap.cc | 5 ++++ winsup/cygwin/ntea.cc | 20 +++++++++++++ winsup/cygwin/release/2.12.0 | 2 ++ winsup/cygwin/syscalls.cc | 37 +++++++++++++++++++++--- winsup/doc/new-features.xml | 4 +++ 8 files changed, 74 insertions(+), 4 deletions(-) diff --git a/newlib/libc/include/sys/_default_fcntl.h b/newlib/libc/include/sys/_default_fcntl.h index 22fa10688..2dc0068c9 100644 --- a/newlib/libc/include/sys/_default_fcntl.h +++ b/newlib/libc/include/sys/_default_fcntl.h @@ -35,6 +35,7 @@ extern "C" { #if defined (__CYGWIN__) #define _FTMPFILE 0x800000 #define _FNOATIME 0x1000000 +#define _FPATH 0x2000000 #endif #define O_ACCMODE (O_RDONLY|O_WRONLY|O_RDWR) @@ -80,6 +81,7 @@ extern "C" { #if __GNU_VISIBLE #define O_TMPFILE _FTMPFILE #define O_NOATIME _FNOATIME +#define O_PATH _FPATH #endif #endif diff --git a/winsup/cygwin/fhandler.cc b/winsup/cygwin/fhandler.cc index 1a7513763..9f5e0094f 100644 --- a/winsup/cygwin/fhandler.cc +++ b/winsup/cygwin/fhandler.cc @@ -549,6 +549,9 @@ fhandler_base::open (int flags, mode_t mode) syscall_printf ("(%S, %y)", pc.get_nt_native_path (), flags); + if (flags & O_PATH) + query_open (query_read_attributes); + /* Allow to reopen from handle. This is utilized by open ("/proc/PID/fd/DESCRIPTOR", ...); */ if (get_handle ()) diff --git a/winsup/cygwin/ioctl.cc b/winsup/cygwin/ioctl.cc index 3f93160d8..242ef60cd 100644 --- a/winsup/cygwin/ioctl.cc +++ b/winsup/cygwin/ioctl.cc @@ -32,6 +32,11 @@ ioctl (int fd, int cmd, ...) debug_printf ("ioctl(fd %d, cmd %y)", fd, cmd); int res; + if (cfd->get_flags () & O_PATH) + { + set_errno (EBADF); + return -1; + } /* FIXME: This stinks. There are collisions between cmd types depending on whether fd is associated with a pty master or not. Something to fix for Cygwin2. CGF 2006-06-04 */ diff --git a/winsup/cygwin/mmap.cc b/winsup/cygwin/mmap.cc index d7d480fda..f48790a8a 100644 --- a/winsup/cygwin/mmap.cc +++ b/winsup/cygwin/mmap.cc @@ -930,6 +930,11 @@ mmap64 (void *addr, size_t len, int prot, int flags, int fd, off_t off) cygheap_fdget cfd (fd); if (cfd < 0) goto out; + if (cfd->get_flags () & O_PATH) + { + set_errno (EBADF); + goto out; + } fh = cfd; diff --git a/winsup/cygwin/ntea.cc b/winsup/cygwin/ntea.cc index 6896b880f..59a0081e1 100644 --- a/winsup/cygwin/ntea.cc +++ b/winsup/cygwin/ntea.cc @@ -426,6 +426,11 @@ fgetxattr (int fd, const char *name, void *value, size_t size) cygheap_fdget cfd (fd); if (cfd < 0) res = -1; + else if (cfd->get_flags () & O_PATH) + { + set_errno (EBADF); + res = -1; + } else res = cfd->fgetxattr (name, value, size); return res; @@ -453,6 +458,11 @@ flistxattr (int fd, char *list, size_t size) cygheap_fdget cfd (fd); if (cfd < 0) res = -1; + else if (cfd->get_flags () & O_PATH) + { + set_errno (EBADF); + res = -1; + } else res = cfd->fgetxattr (NULL, list, size); return res; @@ -523,6 +533,11 @@ fsetxattr (int fd, const char *name, const void *value, size_t size, int flags) cygheap_fdget cfd (fd); if (cfd < 0) res = -1; + else if (cfd->get_flags () & O_PATH) + { + set_errno (EBADF); + res = -1; + } else res = cfd->fsetxattr (name, value, size, flags); return res; @@ -550,6 +565,11 @@ fremovexattr (int fd, const char *name) cygheap_fdget cfd (fd); if (cfd < 0) res = -1; + else if (cfd->get_flags () & O_PATH) + { + set_errno (EBADF); + res = -1; + } else res = cfd->fsetxattr (name, NULL, 0, 0); return res; diff --git a/winsup/cygwin/release/2.12.0 b/winsup/cygwin/release/2.12.0 index 03a6a3aaf..c9e63a6ba 100644 --- a/winsup/cygwin/release/2.12.0 +++ b/winsup/cygwin/release/2.12.0 @@ -20,6 +20,8 @@ What's new: - Support for exFAT. +- Support Linux-specific open(2) flag O_PATH. + What changed: ------------- diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc index b99a21e8e..d6f81cab9 100644 --- a/winsup/cygwin/syscalls.cc +++ b/winsup/cygwin/syscalls.cc @@ -1193,7 +1193,8 @@ read (int fd, void *ptr, size_t len) if (cfd < 0) __leave; - if ((cfd->get_flags () & O_ACCMODE) == O_WRONLY) + if ((cfd->get_flags () & O_PATH) + || (cfd->get_flags () & O_ACCMODE) == O_WRONLY) { set_errno (EBADF); __leave; @@ -1235,7 +1236,8 @@ readv (int fd, const struct iovec *const iov, const int iovcnt) __leave; } - if ((cfd->get_flags () & O_ACCMODE) == O_WRONLY) + if ((cfd->get_flags () & O_PATH) + || (cfd->get_flags () & O_ACCMODE) == O_WRONLY) { set_errno (EBADF); __leave; @@ -1263,6 +1265,11 @@ pread (int fd, void *ptr, size_t len, off_t off) cygheap_fdget cfd (fd); if (cfd < 0) res = -1; + else if (cfd->get_flags () & O_PATH) + { + set_errno (EBADF); + res = -1; + } else res = cfd->pread (ptr, len, off); @@ -1283,7 +1290,8 @@ write (int fd, const void *ptr, size_t len) if (cfd < 0) __leave; - if ((cfd->get_flags () & O_ACCMODE) == O_RDONLY) + if ((cfd->get_flags () & O_PATH) + || (cfd->get_flags () & O_ACCMODE) == O_RDONLY) { set_errno (EBADF); __leave; @@ -1326,7 +1334,8 @@ writev (const int fd, const struct iovec *const iov, const int iovcnt) __leave; } - if ((cfd->get_flags () & O_ACCMODE) == O_RDONLY) + if ((cfd->get_flags () & O_PATH) + || (cfd->get_flags () & O_ACCMODE) == O_RDONLY) { set_errno (EBADF); __leave; @@ -1358,6 +1367,11 @@ pwrite (int fd, void *ptr, size_t len, off_t off) cygheap_fdget cfd (fd); if (cfd < 0) res = -1; + else if (cfd->get_flags () & O_PATH) + { + set_errno (EBADF); + res = -1; + } else res = cfd->pwrite (ptr, len, off); @@ -1398,6 +1412,11 @@ open (const char *unix_path, int flags, ...) if (fd < 0) __leave; /* errno already set */ + /* When O_PATH is specified in flags, flag bits other than O_CLOEXEC, + O_DIRECTORY, and O_NOFOLLOW are ignored. */ + if (flags & O_PATH) + flags &= (O_PATH | O_CLOEXEC | O_DIRECTORY | O_NOFOLLOW); + int opt = PC_OPEN | PC_SYM_NOFOLLOW_PROCFD; opt |= (flags & (O_NOFOLLOW | O_EXCL)) ? PC_SYM_NOFOLLOW : PC_SYM_FOLLOW; @@ -1685,6 +1704,11 @@ fchown32 (int fd, uid_t uid, gid_t gid) syscall_printf ("-1 = fchown (%d,...)", fd); return -1; } + else if (cfd->get_flags () & O_PATH) + { + set_errno (EBADF); + return -1; + } int res = cfd->fchown (uid, gid); @@ -1756,6 +1780,11 @@ fchmod (int fd, mode_t mode) syscall_printf ("-1 = fchmod (%d, 0%o)", fd, mode); return -1; } + else if (cfd->get_flags () & O_PATH) + { + set_errno (EBADF); + return -1; + } return cfd->fchmod (FILTERED_MODE (mode)); } diff --git a/winsup/doc/new-features.xml b/winsup/doc/new-features.xml index a1a529d32..b55e031bc 100644 --- a/winsup/doc/new-features.xml +++ b/winsup/doc/new-features.xml @@ -37,6 +37,10 @@ aforementioned new ioctl's on the command line. Support for exFAT. + +Support Linux-specific open(2) flag O_PATH. + + clock_nanosleep, pthread_condattr_setclock and timer_create now support all clocks, except CLOCK_PROCESS_CPUTIME_ID and CLOCK_THREAD_CPUTIME_ID. From 9443efe0990ad32c1896717ac7c38ff9c8c57073 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Mon, 7 Jan 2019 19:36:37 +0100 Subject: [PATCH 066/475] Cygwin: linkat: support Linux-specific AT_EMPTY_PATH flag Signed-off-by: Corinna Vinschen --- newlib/libc/include/sys/_default_fcntl.h | 1 + winsup/cygwin/release/2.12.0 | 2 ++ winsup/cygwin/syscalls.cc | 20 ++++++++++++++++++-- winsup/doc/new-features.xml | 4 ++++ 4 files changed, 25 insertions(+), 2 deletions(-) diff --git a/newlib/libc/include/sys/_default_fcntl.h b/newlib/libc/include/sys/_default_fcntl.h index 2dc0068c9..0647e590f 100644 --- a/newlib/libc/include/sys/_default_fcntl.h +++ b/newlib/libc/include/sys/_default_fcntl.h @@ -166,6 +166,7 @@ extern "C" { #define AT_SYMLINK_NOFOLLOW 2 #define AT_SYMLINK_FOLLOW 4 #define AT_REMOVEDIR 8 +#define AT_EMPTY_PATH 16 #endif #if __BSD_VISIBLE diff --git a/winsup/cygwin/release/2.12.0 b/winsup/cygwin/release/2.12.0 index c9e63a6ba..81a55b58d 100644 --- a/winsup/cygwin/release/2.12.0 +++ b/winsup/cygwin/release/2.12.0 @@ -22,6 +22,8 @@ What's new: - Support Linux-specific open(2) flag O_PATH. +- Support Linux-specific linkat(2) flag AT_EMPTY_PATH. + What changed: ------------- diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc index d6f81cab9..cb62a6242 100644 --- a/winsup/cygwin/syscalls.cc +++ b/winsup/cygwin/syscalls.cc @@ -4812,13 +4812,29 @@ linkat (int olddirfd, const char *oldpathname, tmp_pathbuf tp; __try { - if (flags & ~AT_SYMLINK_FOLLOW) + if (flags & ~(AT_SYMLINK_FOLLOW | AT_EMPTY_PATH)) { set_errno (EINVAL); __leave; } char *oldpath = tp.c_get (); - if (gen_full_path_at (oldpath, olddirfd, oldpathname)) + /* AT_EMPTY_PATH with an empty oldpathname is equivalent to + + linkat(AT_FDCWD, "/proc/self/fd/", newdirfd, + newname, AT_SYMLINK_FOLLOW); + + Convert the request accordingly. */ + if ((flags & AT_EMPTY_PATH) && oldpathname && oldpathname[0] == '\0') + { + if (olddirfd == AT_FDCWD) + { + set_errno (EPERM); + __leave; + } + __small_sprintf (oldpath, "/proc/%d/fd/%d", myself->pid, olddirfd); + flags = AT_SYMLINK_FOLLOW; + } + else if (gen_full_path_at (oldpath, olddirfd, oldpathname)) __leave; char *newpath = tp.c_get (); if (gen_full_path_at (newpath, newdirfd, newpathname)) diff --git a/winsup/doc/new-features.xml b/winsup/doc/new-features.xml index b55e031bc..f84a9c443 100644 --- a/winsup/doc/new-features.xml +++ b/winsup/doc/new-features.xml @@ -41,6 +41,10 @@ Support for exFAT. Support Linux-specific open(2) flag O_PATH. + +- Support Linux-specific linkat(2) flag AT_EMPTY_PATH. + + clock_nanosleep, pthread_condattr_setclock and timer_create now support all clocks, except CLOCK_PROCESS_CPUTIME_ID and CLOCK_THREAD_CPUTIME_ID. From fe8f406cc663f1930cce4bb1ef23c01623d93c14 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Mon, 7 Jan 2019 20:09:20 +0100 Subject: [PATCH 067/475] fcntl.h: expose AT_EMPTY_PATH with _GNU_SOURCE only Signed-off-by: Corinna Vinschen --- newlib/libc/include/sys/_default_fcntl.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/newlib/libc/include/sys/_default_fcntl.h b/newlib/libc/include/sys/_default_fcntl.h index 0647e590f..b3177dd69 100644 --- a/newlib/libc/include/sys/_default_fcntl.h +++ b/newlib/libc/include/sys/_default_fcntl.h @@ -166,8 +166,10 @@ extern "C" { #define AT_SYMLINK_NOFOLLOW 2 #define AT_SYMLINK_FOLLOW 4 #define AT_REMOVEDIR 8 +#if __GNU_VISIBLE #define AT_EMPTY_PATH 16 #endif +#endif #if __BSD_VISIBLE /* lock operations for flock(2) */ From 2d015e0e68f45d7b1a96e63e39086d35df48344b Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Tue, 8 Jan 2019 18:49:29 +0100 Subject: [PATCH 068/475] Cygwin: remove unused tmpbuf.h Signed-off-by: Corinna Vinschen --- winsup/cygwin/tmpbuf.h | 25 ------------------------- 1 file changed, 25 deletions(-) delete mode 100644 winsup/cygwin/tmpbuf.h diff --git a/winsup/cygwin/tmpbuf.h b/winsup/cygwin/tmpbuf.h deleted file mode 100644 index 1149ef9b1..000000000 --- a/winsup/cygwin/tmpbuf.h +++ /dev/null @@ -1,25 +0,0 @@ -/* tmpbuf.h - -This software is a copyrighted work licensed under the terms of the -Cygwin license. Please consult the file "CYGWIN_LICENSE" for -details. */ - -#ifndef _TMPBUF_H -#define _TMPBUF_H -class tmpbuf -{ - void *buf; -public: - tmpbuf (size_t size = NT_MAX_PATH) - { - buf = calloc (1, size); - if (!buf) - api_fatal ("allocation of temporary buffer failed"); - } - operator void * () {return buf;} - operator char * () {return (char *) buf;} - operator PSECURITY_DESCRIPTOR () {return (PSECURITY_DESCRIPTOR) buf;} - PSECURITY_DESCRIPTOR operator -> () {return (PSECURITY_DESCRIPTOR) buf;} - ~tmpbuf () {free (buf);} -}; -#endif /*_TMPBUF_H*/ From 9ba65ab8b5c5ece442931e585230d1e0422da538 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Tue, 8 Jan 2019 21:38:04 +0100 Subject: [PATCH 069/475] Cygwin: fhandler_process_fd: Fix spacing Signed-off-by: Corinna Vinschen --- winsup/cygwin/fhandler_process_fd.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/winsup/cygwin/fhandler_process_fd.cc b/winsup/cygwin/fhandler_process_fd.cc index a9d085ae5..a3691d9c8 100644 --- a/winsup/cygwin/fhandler_process_fd.cc +++ b/winsup/cygwin/fhandler_process_fd.cc @@ -70,7 +70,7 @@ fhandler_process_fd::fetch_fh (HANDLE &out_hdl, uint32_t flags) hdl = pc.deserialize (buf); } BOOL ret = DuplicateHandle (proc, hdl, GetCurrentProcess (), &hdl, - 0, FALSE, DUPLICATE_SAME_ACCESS); + 0, FALSE, DUPLICATE_SAME_ACCESS); if (proc != GetCurrentProcess ()) CloseHandle (proc); if (!ret) From 0c545f3264aaaac3d02d3ef785a2e2e9d77ed03f Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Tue, 8 Jan 2019 18:50:11 +0100 Subject: [PATCH 070/475] Cygwin: open: handle O_CLOEXEC when opening file from handle Signed-off-by: Corinna Vinschen --- winsup/cygwin/fhandler.cc | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/winsup/cygwin/fhandler.cc b/winsup/cygwin/fhandler.cc index 9f5e0094f..9af08d735 100644 --- a/winsup/cygwin/fhandler.cc +++ b/winsup/cygwin/fhandler.cc @@ -555,7 +555,11 @@ fhandler_base::open (int flags, mode_t mode) /* Allow to reopen from handle. This is utilized by open ("/proc/PID/fd/DESCRIPTOR", ...); */ if (get_handle ()) - pc.init_reopen_attr (attr, get_handle ()); + { + pc.init_reopen_attr (attr, get_handle ()); + if (!(flags & O_CLOEXEC)) + attr.Attributes |= OBJ_INHERIT; + } else pc.get_object_attr (attr, *sec_none_cloexec (flags)); From ec36c59f1a9349e690849e393251623f5936408c Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Tue, 8 Jan 2019 21:37:43 +0100 Subject: [PATCH 071/475] Cygwin: open: workaround reopen file w/ delete disposition set On pre-W10 systems there's no way to reopen a file by handle if the delete disposition is set. We try to get around with duplicating the handle. Signed-off-by: Corinna Vinschen --- winsup/cygwin/fhandler.cc | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/winsup/cygwin/fhandler.cc b/winsup/cygwin/fhandler.cc index 9af08d735..9643373b0 100644 --- a/winsup/cygwin/fhandler.cc +++ b/winsup/cygwin/fhandler.cc @@ -693,6 +693,23 @@ fhandler_base::open (int flags, mode_t mode) status = NtCreateFile (&fh, access, &attr, &io, NULL, file_attributes, shared, create_disposition, options, p, plen); + /* Pre-W10, we can't open a file by handle with delete disposition + set, so we have to lie our ass off. */ + if (get_handle () && status == STATUS_DELETE_PENDING) + { + BOOL ret = DuplicateHandle (GetCurrentProcess (), get_handle (), + GetCurrentProcess (), &fh, + access, !(flags & O_CLOEXEC), 0); + if (!ret) + ret = DuplicateHandle (GetCurrentProcess (), get_handle (), + GetCurrentProcess (), &fh, + 0, !(flags & O_CLOEXEC), + DUPLICATE_SAME_ACCESS); + if (!ret) + debug_printf ("DuplicateHandle after STATUS_DELETE_PENDING, %E"); + else + status = STATUS_SUCCESS; + } if (!NT_SUCCESS (status)) { /* Trying to create a directory should return EISDIR, not ENOENT. */ From dee6cb133a5876c636ca1c544a5f95167dab5d09 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Tue, 8 Jan 2019 21:43:25 +0100 Subject: [PATCH 072/475] Cygwin: try_to_bin: don't reopen the file So far we reopened the file if it was opened case sensitive to workaround the problem that the recycler could be named in camel back or all upper case, depending on who created it. That's a problem for O_TMPFILE on pre-W10. As soon as the original HANDLE gets closed, delete-on-close is converted to full delete disposition and all useful operations on the file cease to work (STATUS_ACCESS_DENIED or STATUS_FILE_DELETED). To avoid that problem drop the reopen code and check for the exact recycler filename, either $Recycle.Bin or $RECYCLE.BIN, if the file has been opened case sensitive. Signed-off-by: Corinna Vinschen --- winsup/cygwin/syscalls.cc | 55 +++++++++++++++++++++------------------ 1 file changed, 30 insertions(+), 25 deletions(-) diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc index cb62a6242..fcf2d8601 100644 --- a/winsup/cygwin/syscalls.cc +++ b/winsup/cygwin/syscalls.cc @@ -232,31 +232,6 @@ try_to_bin (path_conv &pc, HANDLE &fh, ACCESS_MASK access, ULONG flags) them into the recycler. */ if (pfni->FileNameLength == 2) /* root dir. */ goto out; - /* The recycler name is $Recycler.Bin by default. If the recycler dir - disappeared for some reason, the shell32.dll recreates the directory in - all upper case. So, we never know beforehand if the dir is written in - mixed case or in all upper case. That's a problem when using - casesensitivity. If the file handle given to FileRenameInformation - has been opened casesensitive, the call also handles the path to the - target dir casesensitive. Rather than trying to find the right name - of the recycler, we just reopen the file to move with OBJ_CASE_INSENSITIVE, - so the subsequent FileRenameInformation works caseinsensitive in terms of - the recycler directory name, too. */ - if (!pc.objcaseinsensitive ()) - { - InitializeObjectAttributes (&attr, &ro_u_empty, OBJ_CASE_INSENSITIVE, - fh, NULL); - status = NtOpenFile (&tmp_fh, access, &attr, &io, FILE_SHARE_VALID_FLAGS, - flags); - if (!NT_SUCCESS (status)) - debug_printf ("NtOpenFile (%S) for reopening caseinsensitive failed, " - "status = %y", pc.get_nt_native_path (), status); - else - { - NtClose (fh); - fh = tmp_fh; - } - } /* Initialize recycler path. */ RtlInitEmptyUnicodeString (&recycler, recyclerbuf, sizeof recyclerbuf); if (!pc.isremote ()) @@ -312,6 +287,36 @@ try_to_bin (path_conv &pc, HANDLE &fh, ACCESS_MASK access, ULONG flags) recycler.Length -= sizeof (WCHAR); /* Store length of recycler base dir, if it's necessary to create it. */ recycler_base_len = recycler.Length; + /* The recycler name is $Recycler.Bin by default. If the recycler dir + disappears for some reason, shell32.dll recreates it in all upper + case. So we never know if the dir is written in camel back or in + upper case. That's a problem when using casesensitivity: If the + file handle given to FileRenameInformation has been opened + casesensitive, the call also handles the path to the target dir + casesensitive. Check for the right name here. + + Note that, originally, we reopened the file case insensitive instead. + But that's a problem for O_TMPFILE on pre-W10. As soon as the + original HANDLE gets closed, delete-on-close is converted to full + delete disposition and all useful operations on the file cease to + work (STATUS_ACCESS_DENIED or STATUS_FILE_DELETED). */ + if (!pc.objcaseinsensitive ()) + { + PFILE_BASIC_INFORMATION pfbi; + + InitializeObjectAttributes (&attr, &recycler, 0, rootdir, NULL); + pfbi = (PFILE_BASIC_INFORMATION) infobuf; + status = NtQueryAttributesFile (&attr, pfbi); + if (status == STATUS_OBJECT_NAME_NOT_FOUND) + { + wcscpy (recycler.Buffer, L"$RECYCLE.BIN\\"); + status = NtQueryAttributesFile (&attr, pfbi); + /* Keep the uppercase name if it exists, otherwise revert to + camel back to create a nicer name than shell32.dll. */ + if (status == STATUS_OBJECT_NAME_NOT_FOUND) + wcscpy (recycler.Buffer, L"$Recycle.Bin\\"); + } + } /* On NTFS or ReFS the recycler dir contains user specific subdirs, which are the actual recycle bins per user. The name of this dir is the string representation of the user SID. */ From 15094d5d0135db0de71d02472a167904bef53cf7 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Wed, 9 Jan 2019 14:45:37 +0100 Subject: [PATCH 073/475] Cygwin: rename: rename incoming flags argument to at2flags Avoid name confusion with later used flags variable Signed-off-by: Corinna Vinschen --- winsup/cygwin/syscalls.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc index fcf2d8601..78ac44bdc 100644 --- a/winsup/cygwin/syscalls.cc +++ b/winsup/cygwin/syscalls.cc @@ -2209,14 +2209,14 @@ nt_path_has_executable_suffix (PUNICODE_STRING upath) of the rename is just to change the case of oldpath on a case-insensitive file system. */ static int -rename2 (const char *oldpath, const char *newpath, unsigned int flags) +rename2 (const char *oldpath, const char *newpath, unsigned int at2flags) { tmp_pathbuf tp; int res = -1; path_conv oldpc, newpc, new2pc, *dstpc, *removepc = NULL; bool old_dir_requested = false, new_dir_requested = false; bool old_explicit_suffix = false, new_explicit_suffix = false; - bool noreplace = flags & RENAME_NOREPLACE; + bool noreplace = at2flags & RENAME_NOREPLACE; size_t olen, nlen; bool equal_path; NTSTATUS status = STATUS_SUCCESS; @@ -2229,7 +2229,7 @@ rename2 (const char *oldpath, const char *newpath, unsigned int flags) __try { - if (flags & ~RENAME_NOREPLACE) + if (at2flags & ~RENAME_NOREPLACE) /* RENAME_NOREPLACE is the only flag currently supported. */ { set_errno (EINVAL); From ec457e0351eee30c0d7319524e6a1a36f94dfb35 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Wed, 9 Jan 2019 15:47:43 +0100 Subject: [PATCH 074/475] Cygwin: rename: use FILE_RENAME_POSIX_SEMANTICS if available starting with W10 1709 on local NTFS drives Signed-off-by: Corinna Vinschen --- winsup/cygwin/release/2.12.0 | 4 ++++ winsup/cygwin/syscalls.cc | 30 ++++++++++++++++++++++++++---- winsup/doc/new-features.xml | 6 ++++++ 3 files changed, 36 insertions(+), 4 deletions(-) diff --git a/winsup/cygwin/release/2.12.0 b/winsup/cygwin/release/2.12.0 index 81a55b58d..b77278238 100644 --- a/winsup/cygwin/release/2.12.0 +++ b/winsup/cygwin/release/2.12.0 @@ -37,6 +37,10 @@ What changed: Deleting an in-use file now actually removes the file, rather than moving it to the recycler bin. +- Use the new POSIX rename semantics on NTFS starting with Windows 10 1709. + Renaming a file to another in-use file now actually removes the other file, + rather than moving it to the recycler bin. + - open(..., O_TMPFILE) now moves the file to the trash bin immediately, to free the parent directory. diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc index 78ac44bdc..4f91f4b48 100644 --- a/winsup/cygwin/syscalls.cc +++ b/winsup/cygwin/syscalls.cc @@ -2216,6 +2216,7 @@ rename2 (const char *oldpath, const char *newpath, unsigned int at2flags) path_conv oldpc, newpc, new2pc, *dstpc, *removepc = NULL; bool old_dir_requested = false, new_dir_requested = false; bool old_explicit_suffix = false, new_explicit_suffix = false; + bool use_posix_semantics; bool noreplace = at2flags & RENAME_NOREPLACE; size_t olen, nlen; bool equal_path; @@ -2511,10 +2512,18 @@ rename2 (const char *oldpath, const char *newpath, unsigned int at2flags) __leave; } + /* POSIX semantics only on local NTFS drives. */ + use_posix_semantics = wincap.has_posix_file_info () + && !oldpc.isremote () + && oldpc.fs_is_ntfs (); + /* Opening the file must be part of the transaction. It's not sufficient to call only NtSetInformationFile under the transaction. Therefore we - have to start the transaction here, if necessary. */ - if ((dstpc->fs_flags () & FILE_SUPPORTS_TRANSACTIONS) + have to start the transaction here, if necessary. Don't start + transaction on W10 1709 or later on local NTFS. Use POSIX semantics + instead. */ + if (!use_posix_semantics + && (dstpc->fs_flags () & FILE_SUPPORTS_TRANSACTIONS) && (dstpc->isdir () || (!removepc && dstpc->has_attribute (FILE_ATTRIBUTE_READONLY)))) start_transaction (old_trans, trans); @@ -2578,6 +2587,9 @@ rename2 (const char *oldpath, const char *newpath, unsigned int at2flags) __leave; } + if (use_posix_semantics) + goto skip_pre_W10_checks; + /* Renaming a dir to another, existing dir fails always, even if ReplaceIfExists is set to TRUE and the existing dir is empty. So we have to remove the destination dir first. This also covers the @@ -2619,6 +2631,8 @@ rename2 (const char *oldpath, const char *newpath, unsigned int at2flags) } } +skip_pre_W10_checks: + /* SUSv3: If the old argument and the new argument resolve to the same existing file, rename() shall return successfully and perform no other action. @@ -2666,7 +2680,13 @@ rename2 (const char *oldpath, const char *newpath, unsigned int at2flags) __leave; } pfri = (PFILE_RENAME_INFORMATION) tp.w_get (); - pfri->ReplaceIfExists = !noreplace; + if (use_posix_semantics) + pfri->Flags = noreplace ? 0 + : (FILE_RENAME_REPLACE_IF_EXISTS + | FILE_RENAME_POSIX_SEMANTICS + | FILE_RENAME_IGNORE_READONLY_ATTRIBUTE); + else + pfri->ReplaceIfExists = !noreplace; pfri->RootDirectory = NULL; pfri->FileNameLength = dstpc->get_nt_native_path ()->Length; memcpy (&pfri->FileName, dstpc->get_nt_native_path ()->Buffer, @@ -2677,7 +2697,9 @@ rename2 (const char *oldpath, const char *newpath, unsigned int at2flags) ERROR_ALREADY_EXISTS ==> Cygwin error EEXIST. */ status = NtSetInformationFile (fh, &io, pfri, sizeof *pfri + pfri->FileNameLength, - FileRenameInformation); + use_posix_semantics + ? FileRenameInformationEx + : FileRenameInformation); /* This happens if the access rights don't allow deleting the destination. Even if the handle to the original file is opened with BACKUP and/or RECOVERY, these flags don't apply to the destination of the diff --git a/winsup/doc/new-features.xml b/winsup/doc/new-features.xml index f84a9c443..6af7270f9 100644 --- a/winsup/doc/new-features.xml +++ b/winsup/doc/new-features.xml @@ -54,6 +54,12 @@ all clocks, except CLOCK_PROCESS_CPUTIME_ID and CLOCK_THREAD_CPUTIME_ID. clock_setres is a no-op now. + +Use the new POSIX rename semantics on NTFS starting with Windows 10 +1709. Renaming a file to another in-use file now actually removes the +other file, rather than moving it to the recycler bin. + + Use the new POSIX unlink semantics on NTFS starting with Windows 10 1709. Deleting an in-use file now actually removes the file, rather From b7a6d357ee23d690a6559235600b85801d6ad025 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Wed, 9 Jan 2019 21:41:48 +0100 Subject: [PATCH 075/475] Cygwin: try_to_bin: fix rootdir handle after reopening If the first rename fails, we reopen the rootdir for creating a subdir. The rootdir handle can change its value at this point, but the code doesn't take this into account. The subsequent rename then fails with STATUS_INVALID_HANDLE. Fix this by copying the new rootdir value to pfri->RootDirectory. Signed-off-by: Corinna Vinschen --- winsup/cygwin/syscalls.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc index 4f91f4b48..728a6b1e5 100644 --- a/winsup/cygwin/syscalls.cc +++ b/winsup/cygwin/syscalls.cc @@ -389,6 +389,8 @@ try_to_bin (path_conv &pc, HANDLE &fh, ACCESS_MASK access, ULONG flags) &recycler, status); goto out; } + /* Correct the rootdir HANDLE in pfri after reopening the dir. */ + pfri->RootDirectory = rootdir; /* Then check if recycler exists by opening and potentially creating it. Yes, we can really do that. Typically the recycle bin is created by the first user actually using the bin. */ From fbd3835384fa586fd32ce80280d81bb51ab042ba Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Wed, 9 Jan 2019 21:14:58 +0100 Subject: [PATCH 076/475] Cygwin: try_to_bin: don't check recycler filename all the time So far we check the recycler name all the time, and the last interation also only managed to handle two ways to write the recycler. However, an adventurous user might change the case of the recycler arbitrarily. Fix this problem by keeping track of the name in a somewhat relaxed fashion. Use camel back on drive C by default, all upper case elsewhere. Only if the rename op fails do we fix the recycler name on the fly when trying to create it, and it turns out it already existed. Signed-off-by: Corinna Vinschen --- winsup/cygwin/syscalls.cc | 71 +++++++++++++++++++++------------------ 1 file changed, 38 insertions(+), 33 deletions(-) diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc index 728a6b1e5..2628d942b 100644 --- a/winsup/cygwin/syscalls.cc +++ b/winsup/cygwin/syscalls.cc @@ -195,6 +195,14 @@ enum bin_status dir_not_empty }; +/* Typically the recycler on drive C has been created at installation + time. The name is then written in camel back. On any other drive, + the recycler is created on first usage. shell32.dll then creates + the recycler in all upper case. That's only important if the entire + operation is running case sensitive. */ +static WCHAR recycler_basename_drive_c[] = L"\\$Recycle.Bin\\"; +static WCHAR recycler_basename_other[] = L"\\$RECYCLE.BIN\\"; + static bin_status try_to_bin (path_conv &pc, HANDLE &fh, ACCESS_MASK access, ULONG flags) { @@ -205,6 +213,7 @@ try_to_bin (path_conv &pc, HANDLE &fh, ACCESS_MASK access, ULONG flags) HANDLE rootdir = NULL, recyclerdir = NULL, tmp_fh = NULL; USHORT recycler_base_len = 0, recycler_user_len = 0; UNICODE_STRING root, recycler, fname; + PWCHAR recycler_basename = NULL; WCHAR recyclerbuf[NAME_MAX + 1]; /* Enough for recycler + SID + filename */ PFILE_NAME_INFORMATION pfni; PFILE_INTERNAL_INFORMATION pfii; @@ -217,7 +226,8 @@ try_to_bin (path_conv &pc, HANDLE &fh, ACCESS_MASK access, ULONG flags) PBYTE infobuf = (PBYTE) tp.w_get (); pfni = (PFILE_NAME_INFORMATION) infobuf; - status = NtQueryInformationFile (fh, &io, pfni, 65536, FileNameInformation); + status = NtQueryInformationFile (fh, &io, pfni, NT_MAX_PATH * sizeof (WCHAR), + FileNameInformation); if (!NT_SUCCESS (status)) { debug_printf ("NtQueryInformationFile (%S, FileNameInformation) " @@ -236,7 +246,11 @@ try_to_bin (path_conv &pc, HANDLE &fh, ACCESS_MASK access, ULONG flags) RtlInitEmptyUnicodeString (&recycler, recyclerbuf, sizeof recyclerbuf); if (!pc.isremote ()) { - RtlAppendUnicodeToString (&recycler, L"\\$Recycle.Bin\\"); + recycler_basename = wcsncmp (pc.get_nt_native_path ()->Buffer, + L"\\??\\C:\\", 7) + ? recycler_basename_other + : recycler_basename_drive_c; + RtlAppendUnicodeToString (&recycler, recycler_basename); RtlInitCountedUnicodeString(&fname, pfni->FileName, pfni->FileNameLength); /* Is the file a subdir of the recycler? */ if (RtlEqualUnicodePathPrefix (&fname, &recycler, TRUE)) @@ -287,36 +301,6 @@ try_to_bin (path_conv &pc, HANDLE &fh, ACCESS_MASK access, ULONG flags) recycler.Length -= sizeof (WCHAR); /* Store length of recycler base dir, if it's necessary to create it. */ recycler_base_len = recycler.Length; - /* The recycler name is $Recycler.Bin by default. If the recycler dir - disappears for some reason, shell32.dll recreates it in all upper - case. So we never know if the dir is written in camel back or in - upper case. That's a problem when using casesensitivity: If the - file handle given to FileRenameInformation has been opened - casesensitive, the call also handles the path to the target dir - casesensitive. Check for the right name here. - - Note that, originally, we reopened the file case insensitive instead. - But that's a problem for O_TMPFILE on pre-W10. As soon as the - original HANDLE gets closed, delete-on-close is converted to full - delete disposition and all useful operations on the file cease to - work (STATUS_ACCESS_DENIED or STATUS_FILE_DELETED). */ - if (!pc.objcaseinsensitive ()) - { - PFILE_BASIC_INFORMATION pfbi; - - InitializeObjectAttributes (&attr, &recycler, 0, rootdir, NULL); - pfbi = (PFILE_BASIC_INFORMATION) infobuf; - status = NtQueryAttributesFile (&attr, pfbi); - if (status == STATUS_OBJECT_NAME_NOT_FOUND) - { - wcscpy (recycler.Buffer, L"$RECYCLE.BIN\\"); - status = NtQueryAttributesFile (&attr, pfbi); - /* Keep the uppercase name if it exists, otherwise revert to - camel back to create a nicer name than shell32.dll. */ - if (status == STATUS_OBJECT_NAME_NOT_FOUND) - wcscpy (recycler.Buffer, L"$Recycle.Bin\\"); - } - } /* On NTFS or ReFS the recycler dir contains user specific subdirs, which are the actual recycle bins per user. The name of this dir is the string representation of the user SID. */ @@ -376,7 +360,8 @@ try_to_bin (path_conv &pc, HANDLE &fh, ACCESS_MASK access, ULONG flags) status = NtSetInformationFile (fh, &io, pfri, frisiz, FileRenameInformation); if (status == STATUS_OBJECT_PATH_NOT_FOUND && !pc.isremote ()) { - /* Ok, so the recycler and/or the recycler/SID directory don't exist. + /* The recycler and/or the recycler/SID directory don't exist, or the + case of recycler dir has changed and the rename op is case sensitive. First reopen root dir with permission to create subdirs. */ NtClose (rootdir); InitializeObjectAttributes (&attr, &root, OBJ_CASE_INSENSITIVE, @@ -412,6 +397,26 @@ try_to_bin (path_conv &pc, HANDLE &fh, ACCESS_MASK access, ULONG flags) &recycler, status); goto out; } + /* If we opened the recycler (in contrast to creating it) and our + rename op is case sensitive, fetch the actual case of the recycler + and store the name in recycler_basename, as well as in pfri->FileName + for the below 2nd try to rename the file. */ + if (io.Information == FILE_OPENED && !pc.objcaseinsensitive ()) + { + pfni = (PFILE_NAME_INFORMATION) tp.w_get (); + status = NtQueryInformationFile (recyclerdir, &io, pfni, + NT_MAX_PATH * sizeof (WCHAR), + FileNameInformation); + if (NT_SUCCESS (status)) + { + size_t len = pfni->FileNameLength / sizeof (WCHAR) - 1; + PWCHAR p = pfni->FileName + 1; + p[len] = L'\0'; + wcpncpy (pfri->FileName, p, len); + wcpncpy (recycler_basename + 1, p, len); + } + } + /* Next, if necessary, check if the recycler/SID dir exists and create it if not. */ if (fs_has_per_user_recycler) From 367df1d4e02dc1c6d636387d439533d4427d9b5b Mon Sep 17 00:00:00 2001 From: Ken Brown Date: Thu, 10 Jan 2019 17:56:55 +0000 Subject: [PATCH 077/475] Cygwin: af_unix_spinlock_t: add initializer Also fix a typo. --- winsup/cygwin/fhandler.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h index d02b9a913..7e460701c 100644 --- a/winsup/cygwin/fhandler.h +++ b/winsup/cygwin/fhandler.h @@ -832,9 +832,10 @@ class fhandler_socket_local: public fhandler_socket_wsock /* Sharable spinlock with low CPU profile. These locks are NOT recursive! */ class af_unix_spinlock_t { - LONG locked; /* 0 oder 1 */ + LONG locked; /* 0 or 1 */ public: + af_unix_spinlock_t () : locked (0) {} void lock () { LONG ret = InterlockedExchange (&locked, 1); From 8d1d8fc914725a88c3463895b36daa353ebd0d26 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Fri, 11 Jan 2019 15:13:11 +0100 Subject: [PATCH 078/475] Cygwin: timer: convert timer_tracker to a real C++ class ...with private members and all the jazz Signed-off-by: Corinna Vinschen --- winsup/cygwin/timer.cc | 139 +++++++++++++++++++++++++---------------- 1 file changed, 84 insertions(+), 55 deletions(-) diff --git a/winsup/cygwin/timer.cc b/winsup/cygwin/timer.cc index e1d78eb49..39a0f9d07 100644 --- a/winsup/cygwin/timer.cc +++ b/winsup/cygwin/timer.cc @@ -17,9 +17,11 @@ details. */ #include #define TT_MAGIC 0x513e4a1c -struct timer_tracker +class timer_tracker { unsigned magic; + timer_tracker *next; + clockid_t clock_id; sigevent evp; timespec it_interval; @@ -27,13 +29,20 @@ struct timer_tracker HANDLE syncthread; long long interval_us; long long sleepto_us; + bool cancel (); - struct timer_tracker *next; - int settime (int, const itimerspec *, itimerspec *); - void gettime (itimerspec *); + + public: timer_tracker (clockid_t, const sigevent *); ~timer_tracker (); - friend void fixup_timers_after_fork (); + inline bool is_timer_tracker () { return magic == TT_MAGIC; } + + void gettime (itimerspec *); + int settime (int, const itimerspec *, itimerspec *); + int clean_and_unhook (); + + DWORD thread_func (); + void fixup_after_fork (); }; timer_tracker NO_COPY ttstart (CLOCK_REALTIME, NULL); @@ -115,66 +124,65 @@ timespec_to_us (const timespec& ts) return res; } -static DWORD WINAPI -timer_thread (VOID *x) +DWORD +timer_tracker::thread_func () { - timer_tracker *tt = ((timer_tracker *) x); long long now; - long long sleepto_us = tt->sleepto_us; + long long cur_sleepto_us = sleepto_us; while (1) { long long sleep_us; LONG sleep_ms; /* Account for delays in starting thread and sending the signal */ - now = get_clock (tt->clock_id)->usecs (); - sleep_us = sleepto_us - now; + now = get_clock (clock_id)->usecs (); + sleep_us = cur_sleepto_us - now; if (sleep_us > 0) { - tt->sleepto_us = sleepto_us; + sleepto_us = cur_sleepto_us; sleep_ms = (sleep_us + (USPERSEC / MSPERSEC) - 1) / (USPERSEC / MSPERSEC); } else { - tt->sleepto_us = now; + sleepto_us = now; sleep_ms = 0; } - debug_printf ("%p waiting for %u ms", x, sleep_ms); - switch (WaitForSingleObject (tt->hcancel, sleep_ms)) + debug_printf ("%p waiting for %u ms", this, sleep_ms); + switch (WaitForSingleObject (hcancel, sleep_ms)) { case WAIT_TIMEOUT: debug_printf ("timed out"); break; case WAIT_OBJECT_0: - debug_printf ("%p cancelled", x); + debug_printf ("%p cancelled", this); goto out; default: - debug_printf ("%p wait failed, %E", x); + debug_printf ("%p wait failed, %E", this); goto out; } - switch (tt->evp.sigev_notify) + switch (evp.sigev_notify) { case SIGEV_SIGNAL: { siginfo_t si = {0}; - si.si_signo = tt->evp.sigev_signo; - si.si_sigval.sival_ptr = tt->evp.sigev_value.sival_ptr; + si.si_signo = evp.sigev_signo; + si.si_sigval.sival_ptr = evp.sigev_value.sival_ptr; si.si_code = SI_TIMER; - debug_printf ("%p sending signal %d", x, tt->evp.sigev_signo); + debug_printf ("%p sending signal %d", this, evp.sigev_signo); sig_send (myself_nowait, si); break; } case SIGEV_THREAD: { pthread_t notify_thread; - debug_printf ("%p starting thread", x); + debug_printf ("%p starting thread", this); pthread_attr_t *attr; pthread_attr_t default_attr; - if (tt->evp.sigev_notify_attributes) - attr = tt->evp.sigev_notify_attributes; + if (evp.sigev_notify_attributes) + attr = evp.sigev_notify_attributes; else { pthread_attr_init(attr = &default_attr); @@ -182,8 +190,8 @@ timer_thread (VOID *x) } int rc = pthread_create (¬ify_thread, attr, - (void * (*) (void *)) tt->evp.sigev_notify_function, - tt->evp.sigev_value.sival_ptr); + (void * (*) (void *)) evp.sigev_notify_function, + evp.sigev_value.sival_ptr); if (rc) { debug_printf ("thread creation failed, %E"); @@ -193,10 +201,10 @@ timer_thread (VOID *x) break; } } - if (!tt->interval_us) + if (!interval_us) break; - sleepto_us = tt->sleepto_us + tt->interval_us; + cur_sleepto_us = sleepto_us + interval_us; debug_printf ("looping"); } @@ -205,6 +213,13 @@ out: return 0; } +static DWORD WINAPI +timer_thread (VOID *x) +{ + timer_tracker *tt = ((timer_tracker *) x); + return tt->thread_func (); +} + static inline bool timespec_bad (const timespec& t) { @@ -282,6 +297,37 @@ timer_tracker::gettime (itimerspec *ovalue) } } +int +timer_tracker::clean_and_unhook () +{ + for (timer_tracker *tt = &ttstart; tt->next != NULL; tt = tt->next) + if (tt->next == this) + { + tt->next = this->next; + return 0; + } + return -1; +} + +void +timer_tracker::fixup_after_fork () +{ + hcancel = syncthread = NULL; + for (timer_tracker *tt = this; tt->next != NULL; /* nothing */) + { + timer_tracker *deleteme = tt->next; + tt->next = deleteme->next; + deleteme->hcancel = deleteme->syncthread = NULL; + delete deleteme; + } +} + +void +fixup_timers_after_fork () +{ + ttstart.fixup_after_fork (); +} + extern "C" int timer_gettime (timer_t timerid, struct itimerspec *ovalue) { @@ -290,7 +336,7 @@ timer_gettime (timer_t timerid, struct itimerspec *ovalue) __try { timer_tracker *tt = (timer_tracker *) timerid; - if (tt->magic != TT_MAGIC) + if (!tt->is_timer_tracker ()) { set_errno (EINVAL); return -1; @@ -342,7 +388,7 @@ timer_settime (timer_t timerid, int flags, __try { timer_tracker *tt = (timer_tracker *) timerid; - if (tt->magic != TT_MAGIC) + if (!tt->is_timer_tracker ()) { set_errno (EINVAL); __leave; @@ -362,43 +408,26 @@ timer_delete (timer_t timerid) __try { timer_tracker *in_tt = (timer_tracker *) timerid; - if (in_tt->magic != TT_MAGIC) + if (!in_tt->is_timer_tracker ()) { set_errno (EINVAL); __leave; } lock_timer_tracker here; - for (timer_tracker *tt = &ttstart; tt->next != NULL; tt = tt->next) - if (tt->next == in_tt) - { - tt->next = in_tt->next; - delete in_tt; - ret = 0; - __leave; - } - set_errno (EINVAL); - ret = 0; + if (in_tt->clean_and_unhook () == 0) + { + delete in_tt; + ret = 0; + } + else + set_errno (EINVAL); } __except (EFAULT) {} __endtry return ret; } -void -fixup_timers_after_fork () -{ - ttstart.hcancel = ttstart.syncthread = NULL; - for (timer_tracker *tt = &ttstart; tt->next != NULL; /* nothing */) - { - timer_tracker *deleteme = tt->next; - tt->next = deleteme->next; - deleteme->hcancel = deleteme->syncthread = NULL; - delete deleteme; - } -} - - extern "C" int setitimer (int which, const struct itimerval *__restrict value, struct itimerval *__restrict ovalue) From 9ef0cd6a6c4e748ef40e08c62ad84cf70f37161d Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Fri, 11 Jan 2019 15:15:32 +0100 Subject: [PATCH 079/475] Cygwin: clock_nanosleep is not supposed to crash, return EFAULT instead ...in case rqtp or rmtp specified invalid addresses. Signed-off-by: Corinna Vinschen --- winsup/cygwin/signal.cc | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/winsup/cygwin/signal.cc b/winsup/cygwin/signal.cc index 9e6fdc61a..b3e257b23 100644 --- a/winsup/cygwin/signal.cc +++ b/winsup/cygwin/signal.cc @@ -65,8 +65,16 @@ clock_nanosleep (clockid_t clk_id, int flags, const struct timespec *rqtp, sig_dispatch_pending (); pthread_testcancel (); - if (rqtp->tv_sec < 0 || rqtp->tv_nsec < 0 || rqtp->tv_nsec >= NSPERSEC) - return EINVAL; + __try + { + if (rqtp->tv_sec < 0 || rqtp->tv_nsec < 0 || rqtp->tv_nsec >= NSPERSEC) + return EINVAL; + } + __except (NO_ERROR) + { + return EFAULT; + } + __endtry /* Explicitly disallowed by POSIX. Needs to be checked first to avoid being caught by the following test. */ @@ -122,9 +130,17 @@ clock_nanosleep (clockid_t clk_id, int flags, const struct timespec *rqtp, /* according to POSIX, rmtp is used only if !abstime */ if (rmtp && !abstime) { - rmtp->tv_sec = (time_t) (timeout.QuadPart / NS100PERSEC); - rmtp->tv_nsec = (long) ((timeout.QuadPart % NS100PERSEC) - * (NSPERSEC/NS100PERSEC)); + __try + { + rmtp->tv_sec = (time_t) (timeout.QuadPart / NS100PERSEC); + rmtp->tv_nsec = (long) ((timeout.QuadPart % NS100PERSEC) + * (NSPERSEC/NS100PERSEC)); + } + __except (NO_ERROR) + { + res = EFAULT; + } + __endtry } syscall_printf ("%d = clock_nanosleep(%lu, %d, %ld.%09ld, %ld.%09.ld)", From c406bea20b45f8cf4bdbf18c6abaacfd16f6b4f2 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Fri, 11 Jan 2019 19:40:03 +0100 Subject: [PATCH 080/475] Cygwin: posix timers: move definition of timer_tracker class to new timer.h Signed-off-by: Corinna Vinschen --- winsup/cygwin/timer.cc | 30 +----------------------------- winsup/cygwin/timer.h | 41 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 29 deletions(-) create mode 100644 winsup/cygwin/timer.h diff --git a/winsup/cygwin/timer.cc b/winsup/cygwin/timer.cc index 39a0f9d07..e92cbad2a 100644 --- a/winsup/cygwin/timer.cc +++ b/winsup/cygwin/timer.cc @@ -14,37 +14,9 @@ details. */ #include "fhandler.h" #include "dtable.h" #include "cygheap.h" +#include "timer.h" #include -#define TT_MAGIC 0x513e4a1c -class timer_tracker -{ - unsigned magic; - timer_tracker *next; - - clockid_t clock_id; - sigevent evp; - timespec it_interval; - HANDLE hcancel; - HANDLE syncthread; - long long interval_us; - long long sleepto_us; - - bool cancel (); - - public: - timer_tracker (clockid_t, const sigevent *); - ~timer_tracker (); - inline bool is_timer_tracker () { return magic == TT_MAGIC; } - - void gettime (itimerspec *); - int settime (int, const itimerspec *, itimerspec *); - int clean_and_unhook (); - - DWORD thread_func (); - void fixup_after_fork (); -}; - timer_tracker NO_COPY ttstart (CLOCK_REALTIME, NULL); class lock_timer_tracker diff --git a/winsup/cygwin/timer.h b/winsup/cygwin/timer.h new file mode 100644 index 000000000..9a35eb316 --- /dev/null +++ b/winsup/cygwin/timer.h @@ -0,0 +1,41 @@ +/* timer.h: Define class timer_tracker, base class for timer handling + +This file is part of Cygwin. + +This software is a copyrighted work licensed under the terms of the +Cygwin license. Please consult the file "CYGWIN_LICENSE" for +details. */ + +#ifndef __TIMER_H__ +#define __TIMER_H__ + +#define TT_MAGIC 0x513e4a1c +class timer_tracker +{ + unsigned magic; + timer_tracker *next; + + clockid_t clock_id; + sigevent evp; + timespec it_interval; + HANDLE hcancel; + HANDLE syncthread; + long long interval_us; + long long sleepto_us; + + bool cancel (); + + public: + timer_tracker (clockid_t, const sigevent *); + ~timer_tracker (); + inline bool is_timer_tracker () { return magic == TT_MAGIC; } + + void gettime (itimerspec *); + int settime (int, const itimerspec *, itimerspec *); + int clean_and_unhook (); + + DWORD thread_func (); + void fixup_after_fork (); +}; + +#endif /* __TIMER_H__ */ From 92cbaa9f2365da2f94ac54819b9035fe13198400 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Fri, 11 Jan 2019 20:36:46 +0100 Subject: [PATCH 081/475] Cygwin: posix timers: convert timer_tracker::fixup_after_fork to static method Signed-off-by: Corinna Vinschen --- winsup/cygwin/timer.cc | 6 +++--- winsup/cygwin/timer.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/winsup/cygwin/timer.cc b/winsup/cygwin/timer.cc index e92cbad2a..802aa444a 100644 --- a/winsup/cygwin/timer.cc +++ b/winsup/cygwin/timer.cc @@ -284,8 +284,8 @@ timer_tracker::clean_and_unhook () void timer_tracker::fixup_after_fork () { - hcancel = syncthread = NULL; - for (timer_tracker *tt = this; tt->next != NULL; /* nothing */) + ttstart.hcancel = ttstart.syncthread = NULL; + for (timer_tracker *tt = &ttstart; tt->next != NULL; /* nothing */) { timer_tracker *deleteme = tt->next; tt->next = deleteme->next; @@ -297,7 +297,7 @@ timer_tracker::fixup_after_fork () void fixup_timers_after_fork () { - ttstart.fixup_after_fork (); + timer_tracker::fixup_after_fork (); } extern "C" int diff --git a/winsup/cygwin/timer.h b/winsup/cygwin/timer.h index 9a35eb316..4a961fcb0 100644 --- a/winsup/cygwin/timer.h +++ b/winsup/cygwin/timer.h @@ -35,7 +35,7 @@ class timer_tracker int clean_and_unhook (); DWORD thread_func (); - void fixup_after_fork (); + static void fixup_after_fork (); }; #endif /* __TIMER_H__ */ From 961be8d726a81918d8d34c9dae603e7820a2416f Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Sat, 12 Jan 2019 20:23:55 +0100 Subject: [PATCH 082/475] Cygwin: posix timers: some cleanup - use int64_t instead of long long - make is_timer_tracker const - improve copyright header comment Signed-off-by: Corinna Vinschen --- winsup/cygwin/timer.cc | 16 ++++++++-------- winsup/cygwin/timer.h | 8 ++++---- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/winsup/cygwin/timer.cc b/winsup/cygwin/timer.cc index 802aa444a..0aeba5830 100644 --- a/winsup/cygwin/timer.cc +++ b/winsup/cygwin/timer.cc @@ -1,4 +1,4 @@ -/* timer.cc +/* timer.cc: posix timers This file is part of Cygwin. @@ -87,10 +87,10 @@ timer_tracker::timer_tracker (clockid_t c, const sigevent *e) } } -static inline long long +static inline int64_t timespec_to_us (const timespec& ts) { - long long res = ts.tv_sec; + int64_t res = ts.tv_sec; res *= USPERSEC; res += (ts.tv_nsec + (NSPERSEC/USPERSEC) - 1) / (NSPERSEC/USPERSEC); return res; @@ -99,11 +99,11 @@ timespec_to_us (const timespec& ts) DWORD timer_tracker::thread_func () { - long long now; - long long cur_sleepto_us = sleepto_us; + int64_t now; + int64_t cur_sleepto_us = sleepto_us; while (1) { - long long sleep_us; + int64_t sleep_us; LONG sleep_ms; /* Account for delays in starting thread and sending the signal */ @@ -260,8 +260,8 @@ timer_tracker::gettime (itimerspec *ovalue) else { ovalue->it_interval = it_interval; - long long now = get_clock (clock_id)->usecs (); - long long left_us = sleepto_us - now; + int64_t now = get_clock (clock_id)->usecs (); + int64_t left_us = sleepto_us - now; if (left_us < 0) left_us = 0; ovalue->it_value.tv_sec = left_us / USPERSEC; diff --git a/winsup/cygwin/timer.h b/winsup/cygwin/timer.h index 4a961fcb0..0442c37d1 100644 --- a/winsup/cygwin/timer.h +++ b/winsup/cygwin/timer.h @@ -1,4 +1,4 @@ -/* timer.h: Define class timer_tracker, base class for timer handling +/* timer.h: Define class timer_tracker, base class for posix timers This file is part of Cygwin. @@ -20,15 +20,15 @@ class timer_tracker timespec it_interval; HANDLE hcancel; HANDLE syncthread; - long long interval_us; - long long sleepto_us; + int64_t interval_us; + int64_t sleepto_us; bool cancel (); public: timer_tracker (clockid_t, const sigevent *); ~timer_tracker (); - inline bool is_timer_tracker () { return magic == TT_MAGIC; } + inline bool is_timer_tracker () const { return magic == TT_MAGIC; } void gettime (itimerspec *); int settime (int, const itimerspec *, itimerspec *); From 9e295a8d193e138808931816f5858761ff08f402 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Sat, 12 Jan 2019 21:19:52 +0100 Subject: [PATCH 083/475] Cygwin: posix timers: implement timer_getoverrun - set DELAYTIMER_MAX to INT_MAX - make sure to set siginfo_t::si_overrun, as on Linux Signed-off-by: Corinna Vinschen --- winsup/cygwin/common.din | 1 + winsup/cygwin/exceptions.cc | 12 +++ winsup/cygwin/include/cygwin/version.h | 3 +- winsup/cygwin/include/limits.h | 2 +- winsup/cygwin/release/2.12.0 | 5 + winsup/cygwin/signal.cc | 7 ++ winsup/cygwin/timer.cc | 124 +++++++++++++++++++++++-- winsup/cygwin/timer.h | 7 ++ winsup/doc/new-features.xml | 9 ++ winsup/doc/posix.xml | 2 +- 10 files changed, 159 insertions(+), 13 deletions(-) diff --git a/winsup/cygwin/common.din b/winsup/cygwin/common.din index d1d955542..a6363e1ba 100644 --- a/winsup/cygwin/common.din +++ b/winsup/cygwin/common.din @@ -1484,6 +1484,7 @@ timegm NOSIGFE timelocal SIGFE timer_create SIGFE timer_delete SIGFE +timer_getoverrun SIGFE timer_gettime SIGFE timer_settime SIGFE times SIGFE diff --git a/winsup/cygwin/exceptions.cc b/winsup/cygwin/exceptions.cc index 419b0976f..8c1b3b4e6 100644 --- a/winsup/cygwin/exceptions.cc +++ b/winsup/cygwin/exceptions.cc @@ -27,6 +27,7 @@ details. */ #include "child_info.h" #include "ntdll.h" #include "exception.h" +#include "timer.h" /* Definitions for code simplification */ #ifdef __x86_64__ @@ -1473,6 +1474,8 @@ sigpacket::process () if (handler == SIG_IGN) { + if (si.si_code == SI_TIMER) + ((timer_tracker *) si.si_tid)->disarm_event (); sigproc_printf ("signal %d ignored", si.si_signo); goto done; } @@ -1496,6 +1499,8 @@ sigpacket::process () || si.si_signo == SIGCONT || si.si_signo == SIGWINCH || si.si_signo == SIGURG) { + if (si.si_code == SI_TIMER) + ((timer_tracker *) si.si_tid)->disarm_event (); sigproc_printf ("signal %d default is currently ignore", si.si_signo); goto done; } @@ -1620,6 +1625,13 @@ _cygtls::call_signal_handler () sigset_t this_oldmask = set_process_mask_delta (); + if (infodata.si_code == SI_TIMER) + { + timer_tracker *tt = (timer_tracker *) + infodata.si_tid; + infodata.si_overrun = tt->disarm_event (); + } + /* Save information locally on stack to pass to handler. */ int thissig = sig; siginfo_t thissi = infodata; diff --git a/winsup/cygwin/include/cygwin/version.h b/winsup/cygwin/include/cygwin/version.h index bb1fa9746..1bcec331f 100644 --- a/winsup/cygwin/include/cygwin/version.h +++ b/winsup/cygwin/include/cygwin/version.h @@ -501,12 +501,13 @@ details. */ 329: Export sched_getcpu. 330: Add CLOCK_REALTIME_COARSE, CLOCK_MONOTONIC_RAW, CLOCK_MONOTONIC_COARSE, CLOCK_BOOTTIME. + 331: Add timer_getoverrun, DELAYTIMER_MAX. Note that we forgot to bump the api for ualarm, strtoll, strtoull, sigaltstack, sethostname. */ #define CYGWIN_VERSION_API_MAJOR 0 -#define CYGWIN_VERSION_API_MINOR 330 +#define CYGWIN_VERSION_API_MINOR 331 /* There is also a compatibity version number associated with the shared memory regions. It is incremented when incompatible changes are made to the shared diff --git a/winsup/cygwin/include/limits.h b/winsup/cygwin/include/limits.h index 3550c4fcb..524a469e4 100644 --- a/winsup/cygwin/include/limits.h +++ b/winsup/cygwin/include/limits.h @@ -184,7 +184,7 @@ details. */ /* Maximum number of timer expiration overruns. Not yet implemented. */ #undef DELAYTIMER_MAX -/* #define DELAYTIMER_MAX >= _POSIX_DELAYTIMER_MAX */ +#define DELAYTIMER_MAX __INT_MAX__ /* Maximum length of a host name. */ #undef HOST_NAME_MAX diff --git a/winsup/cygwin/release/2.12.0 b/winsup/cygwin/release/2.12.0 index b77278238..15f07e021 100644 --- a/winsup/cygwin/release/2.12.0 +++ b/winsup/cygwin/release/2.12.0 @@ -24,6 +24,11 @@ What's new: - Support Linux-specific linkat(2) flag AT_EMPTY_PATH. +- Support overrun counter for posix timers (via timer_getoverrun() or + siginfo_t::si_overrun). + +- New API: timer_getoverrun. + What changed: ------------- diff --git a/winsup/cygwin/signal.cc b/winsup/cygwin/signal.cc index b3e257b23..74d6eb675 100644 --- a/winsup/cygwin/signal.cc +++ b/winsup/cygwin/signal.cc @@ -20,6 +20,7 @@ details. */ #include "dtable.h" #include "cygheap.h" #include "cygwait.h" +#include "timer.h" #define _SA_NORESTART 0x8000 @@ -611,6 +612,12 @@ sigwait_common (const sigset_t *set, siginfo_t *info, PLARGE_INTEGER waittime) else { _my_tls.lock (); + if (_my_tls.infodata.si_code == SI_TIMER) + { + timer_tracker *tt = (timer_tracker *) + _my_tls.infodata.si_tid; + _my_tls.infodata.si_overrun = tt->disarm_event (); + } if (info) *info = _my_tls.infodata; res = _my_tls.infodata.si_signo; diff --git a/winsup/cygwin/timer.cc b/winsup/cygwin/timer.cc index 0aeba5830..e38decb9a 100644 --- a/winsup/cygwin/timer.cc +++ b/winsup/cygwin/timer.cc @@ -17,6 +17,10 @@ details. */ #include "timer.h" #include +#define EVENT_DISARMED 0 +#define EVENT_ARMED -1 +#define EVENT_LOCK 1 + timer_tracker NO_COPY ttstart (CLOCK_REALTIME, NULL); class lock_timer_tracker @@ -79,6 +83,9 @@ timer_tracker::timer_tracker (clockid_t c, const sigevent *e) clock_id = c; magic = TT_MAGIC; hcancel = NULL; + event_running = EVENT_DISARMED; + overrun_count_curr = 0; + overrun_count = 0; if (this != &ttstart) { lock_timer_tracker here; @@ -96,6 +103,57 @@ timespec_to_us (const timespec& ts) return res; } +/* Returns 0 if arming successful, -1 if a signal is already queued. + If so, it also increments overrun_count. */ +LONG +timer_tracker::arm_event () +{ + LONG ret; + + while ((ret = InterlockedCompareExchange (&event_running, EVENT_ARMED, + EVENT_DISARMED)) == EVENT_LOCK) + yield (); + if (ret == EVENT_ARMED) + InterlockedIncrement64 (&overrun_count); + return ret; +} + +LONG +timer_tracker::disarm_event () +{ + LONG ret; + + while ((ret = InterlockedCompareExchange (&event_running, EVENT_LOCK, + EVENT_ARMED)) == EVENT_LOCK) + yield (); + if (ret == EVENT_ARMED) + { + LONG64 ov_cnt; + + InterlockedExchange64 (&ov_cnt, overrun_count); + if (ov_cnt > DELAYTIMER_MAX || ov_cnt < 0) + overrun_count_curr = DELAYTIMER_MAX; + else + overrun_count_curr = ov_cnt; + ret = overrun_count_curr; + InterlockedExchange64 (&overrun_count, 0); + InterlockedExchange (&event_running, EVENT_DISARMED); + } + return ret; +} + +static void * +notify_thread_wrapper (void *arg) +{ + timer_tracker *tt = (timer_tracker *) arg; + sigevent_t *evt = tt->sigevt (); + void * (*notify_func) (void *) = (void * (*) (void *)) + evt->sigev_notify_function; + + tt->disarm_event (); + return notify_func (evt->sigev_value.sival_ptr); +} + DWORD timer_tracker::thread_func () { @@ -117,7 +175,10 @@ timer_tracker::thread_func () } else { - sleepto_us = now; + int64_t num_intervals = (now - cur_sleepto_us) / interval_us; + InterlockedAdd64 (&overrun_count, num_intervals); + cur_sleepto_us += num_intervals * interval_us; + sleepto_us = cur_sleepto_us; sleep_ms = 0; } @@ -139,16 +200,27 @@ timer_tracker::thread_func () { case SIGEV_SIGNAL: { + if (arm_event ()) + { + debug_printf ("%p timer signal already queued", this); + break; + } siginfo_t si = {0}; si.si_signo = evp.sigev_signo; - si.si_sigval.sival_ptr = evp.sigev_value.sival_ptr; si.si_code = SI_TIMER; + si.si_tid = (timer_t) this; + si.si_sigval.sival_ptr = evp.sigev_value.sival_ptr; debug_printf ("%p sending signal %d", this, evp.sigev_signo); sig_send (myself_nowait, si); break; } case SIGEV_THREAD: { + if (arm_event ()) + { + debug_printf ("%p timer thread already queued", this); + break; + } pthread_t notify_thread; debug_printf ("%p starting thread", this); pthread_attr_t *attr; @@ -160,16 +232,13 @@ timer_tracker::thread_func () pthread_attr_init(attr = &default_attr); pthread_attr_setdetachstate (attr, PTHREAD_CREATE_DETACHED); } - int rc = pthread_create (¬ify_thread, attr, - (void * (*) (void *)) evp.sigev_notify_function, - evp.sigev_value.sival_ptr); + notify_thread_wrapper, this); if (rc) { debug_printf ("thread creation failed, %E"); return 0; } - // FIXME: pthread_join? break; } } @@ -219,9 +288,6 @@ timer_tracker::settime (int in_flags, const itimerspec *value, itimerspec *ovalu if (timespec_bad (value->it_value) || timespec_bad (value->it_interval)) __leave; - long long now = in_flags & TIMER_ABSTIME ? - 0 : get_clock (clock_id)->usecs (); - lock_timer_tracker here; cancel (); @@ -232,8 +298,23 @@ timer_tracker::settime (int in_flags, const itimerspec *value, itimerspec *ovalu interval_us = sleepto_us = 0; else { - sleepto_us = now + timespec_to_us (value->it_value); interval_us = timespec_to_us (value->it_interval); + if (in_flags & TIMER_ABSTIME) + { + int64_t now = get_clock (clock_id)->usecs (); + + sleepto_us = timespec_to_us (value->it_value); + if (sleepto_us <= now) + { + int64_t ov_cnt = (now - sleepto_us + (interval_us + 1)) + / interval_us; + InterlockedAdd64 (&overrun_count, ov_cnt); + sleepto_us += ov_cnt * interval_us; + } + } + else + sleepto_us = get_clock (clock_id)->usecs () + + timespec_to_us (value->it_value); it_interval = value->it_interval; if (!hcancel) hcancel = CreateEvent (&sec_none_nih, TRUE, FALSE, NULL); @@ -285,6 +366,9 @@ void timer_tracker::fixup_after_fork () { ttstart.hcancel = ttstart.syncthread = NULL; + ttstart.event_running = EVENT_DISARMED; + ttstart.overrun_count_curr = 0; + ttstart.overrun_count = 0; for (timer_tracker *tt = &ttstart; tt->next != NULL; /* nothing */) { timer_tracker *deleteme = tt->next; @@ -372,6 +456,26 @@ timer_settime (timer_t timerid, int flags, return ret; } +extern "C" int +timer_getoverrun (timer_t timerid) +{ + int ret = -1; + + __try + { + timer_tracker *tt = (timer_tracker *) timerid; + if (!tt->is_timer_tracker ()) + { + set_errno (EINVAL); + __leave; + } + ret = tt->getoverrun (); + } + __except (EFAULT) {} + __endtry + return ret; +} + extern "C" int timer_delete (timer_t timerid) { diff --git a/winsup/cygwin/timer.h b/winsup/cygwin/timer.h index 0442c37d1..f75cd487c 100644 --- a/winsup/cygwin/timer.h +++ b/winsup/cygwin/timer.h @@ -22,6 +22,9 @@ class timer_tracker HANDLE syncthread; int64_t interval_us; int64_t sleepto_us; + LONG event_running; + LONG overrun_count_curr; + LONG64 overrun_count; bool cancel (); @@ -29,10 +32,14 @@ class timer_tracker timer_tracker (clockid_t, const sigevent *); ~timer_tracker (); inline bool is_timer_tracker () const { return magic == TT_MAGIC; } + inline sigevent_t *sigevt () { return &evp; } + inline int getoverrun () const { return overrun_count_curr; } void gettime (itimerspec *); int settime (int, const itimerspec *, itimerspec *); int clean_and_unhook (); + LONG arm_event (); + LONG disarm_event (); DWORD thread_func (); static void fixup_after_fork (); diff --git a/winsup/doc/new-features.xml b/winsup/doc/new-features.xml index 6af7270f9..2e1645fbe 100644 --- a/winsup/doc/new-features.xml +++ b/winsup/doc/new-features.xml @@ -45,6 +45,15 @@ Support Linux-specific open(2) flag O_PATH. - Support Linux-specific linkat(2) flag AT_EMPTY_PATH. + +Support overrun counter for posix timers (via timer_getoverrun() or +siginfo_t::si_overrun). + + + +New API: timer_getoverrun. + + clock_nanosleep, pthread_condattr_setclock and timer_create now support all clocks, except CLOCK_PROCESS_CPUTIME_ID and CLOCK_THREAD_CPUTIME_ID. diff --git a/winsup/doc/posix.xml b/winsup/doc/posix.xml index afa1ca409..021b5962c 100644 --- a/winsup/doc/posix.xml +++ b/winsup/doc/posix.xml @@ -1003,6 +1003,7 @@ also IEEE Std 1003.1-2008 (POSIX.1-2008). time timer_create (see chapter "Implementation Notes") timer_delete + timer_getoverrun timer_gettime timer_settime times @@ -1587,7 +1588,6 @@ also IEEE Std 1003.1-2008 (POSIX.1-2008). pthread_mutex_consistent putmsg setnetent - timer_getoverrun ulimit waitid From d31f9f9c1327447a04bdded5b8cd23821789f67d Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Sun, 13 Jan 2019 22:30:33 +0100 Subject: [PATCH 084/475] Cygwin: fhandler_pipe: unify format directives The format directives in sscanf/__small_sprintf are not matching. Fix that. --- winsup/cygwin/fhandler_pipe.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/winsup/cygwin/fhandler_pipe.cc b/winsup/cygwin/fhandler_pipe.cc index eafaa8856..c74782416 100644 --- a/winsup/cygwin/fhandler_pipe.cc +++ b/winsup/cygwin/fhandler_pipe.cc @@ -73,10 +73,10 @@ fhandler_pipe::open (int flags, mode_t mode) bool inh; bool got_one = false; - if (sscanf (get_name (), "/proc/self/fd/pipe:[%lld]", + if (sscanf (get_name (), "/proc/self/fd/pipe:[%llu]", (long long *) &uniq_id) == 1) pid = myself->pid; - else if (sscanf (get_name (), "/proc/%d/fd/pipe:[%lld]", + else if (sscanf (get_name (), "/proc/%d/fd/pipe:[%llu]", &pid, (long long *) &uniq_id) < 2) { set_errno (ENOENT); @@ -184,7 +184,7 @@ fhandler_pipe::ftruncate (off_t length, bool allow_truncate) char * fhandler_pipe::get_proc_fd_name (char *buf) { - __small_sprintf (buf, "pipe:[%D]", get_plain_ino ()); + __small_sprintf (buf, "pipe:[%U]", get_plain_ino ()); return buf; } @@ -424,7 +424,7 @@ fhandler_pipe::fstat (struct stat *buf) { buf->st_dev = FH_PIPE; if (!(buf->st_ino = get_plain_ino ())) - sscanf (get_name (), "/proc/%*d/fd/pipe:[%lld]", + sscanf (get_name (), "/proc/%*d/fd/pipe:[%llu]", (long long *) &buf->st_ino); } return ret; From b6694df6198102911980af22721a561c7627ea2a Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Sun, 13 Jan 2019 22:43:52 +0100 Subject: [PATCH 085/475] Cygwin: select: fix overwriting fd sets if poll returns no fd There's a long-standing bug in select. If we have poll-only descriptors in the fd set, select overwrites the incoming fd sets with the polling result. If none of the fds is ready, select has to loop again. But now the fd sets are set to all zero and select hangs. Fix this by utilizing the local fd sets r, w, e as storage for the incoming fd sets and use them to initialize select_stuff. If we have to loop, overwritung the incoming fd sets doesn't matter. While at it, rename r, w, e to readfds_in, writefds_in, exceptfds_in. Signed-off-by: Corinna Vinschen --- winsup/cygwin/release/2.12.0 | 2 ++ winsup/cygwin/select.cc | 15 +++++++++------ 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/winsup/cygwin/release/2.12.0 b/winsup/cygwin/release/2.12.0 index 15f07e021..dbda7886e 100644 --- a/winsup/cygwin/release/2.12.0 +++ b/winsup/cygwin/release/2.12.0 @@ -65,3 +65,5 @@ Bug Fixes even if file has been deleted. Addresses: https://cygwin.com/ml/cygwin/2018-12/msg00125.html https://cygwin.com/ml/cygwin/2018-12/msg00028.html + +- Fix a bug in select(2) when polling HANDLE-less descriptors. diff --git a/winsup/cygwin/select.cc b/winsup/cygwin/select.cc index 0d82a5914..6ce679acf 100644 --- a/winsup/cygwin/select.cc +++ b/winsup/cygwin/select.cc @@ -164,17 +164,20 @@ select (int maxfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, select_stuff sel; sel.return_on_signal = 0; - /* Allocate some fd_set structures using the number of fds as a guide. */ - fd_set *r = allocfd_set (maxfds); - fd_set *w = allocfd_set (maxfds); - fd_set *e = allocfd_set (maxfds); + /* Allocate fd_set structures to store incoming fd sets. */ + fd_set *readfds_in = allocfd_set (maxfds); + fd_set *writefds_in = allocfd_set (maxfds); + fd_set *exceptfds_in = allocfd_set (maxfds); + memcpy (readfds_in, readfds, sizeof_fd_set (maxfds)); + memcpy (writefds_in, writefds, sizeof_fd_set (maxfds)); + memcpy (exceptfds_in, exceptfds, sizeof_fd_set (maxfds)); do { /* Build the select record per fd linked list and set state as needed. */ for (int i = 0; i < maxfds; i++) - if (!sel.test_and_set (i, readfds, writefds, exceptfds)) + if (!sel.test_and_set (i, readfds_in, writefds_in, exceptfds_in)) { select_printf ("aborting due to test_and_set error"); return -1; /* Invalid fd, maybe? */ @@ -186,7 +189,7 @@ select (int maxfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, wait_state = select_stuff::select_ok; else /* wait for an fd to become active or time out */ - wait_state = sel.wait (r, w, e, us); + wait_state = sel.wait (readfds, writefds, exceptfds, us); select_printf ("sel.wait returns %d", wait_state); From 7f601990327861fdcacadf5985c2ef5161cb2554 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Sun, 13 Jan 2019 22:48:43 +0100 Subject: [PATCH 086/475] Cygwin: minor cleanups Signed-off-by: Corinna Vinschen --- winsup/cygwin/fhandler.h | 3 +-- winsup/cygwin/net.cc | 2 +- winsup/cygwin/signal.cc | 7 ++++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h index 7e460701c..ec111de36 100644 --- a/winsup/cygwin/fhandler.h +++ b/winsup/cygwin/fhandler.h @@ -2610,14 +2610,13 @@ class fhandler_procnet: public fhandler_proc pid_t pid; public: fhandler_procnet (); + fhandler_procnet (void *) {} virtual_ftype_t exists(); int __reg3 readdir (DIR *, dirent *); int open (int flags, mode_t mode = 0); int __reg2 fstat (struct stat *buf); bool fill_filebuf (); - fhandler_procnet (void *) {} - void copyto (fhandler_base *x) { x->pc.free_strings (); diff --git a/winsup/cygwin/net.cc b/winsup/cygwin/net.cc index 4494bf71c..cfd29d191 100644 --- a/winsup/cygwin/net.cc +++ b/winsup/cygwin/net.cc @@ -61,7 +61,7 @@ get (const int fd) cygheap_fdget cfd (fd); if (cfd < 0) - return 0; + return NULL; fhandler_socket *const fh = cfd->is_socket (); diff --git a/winsup/cygwin/signal.cc b/winsup/cygwin/signal.cc index 74d6eb675..c5e9d017e 100644 --- a/winsup/cygwin/signal.cc +++ b/winsup/cygwin/signal.cc @@ -635,9 +635,10 @@ sigwait_common (const sigset_t *set, siginfo_t *info, PLARGE_INTEGER waittime) break; } } - __except (EFAULT) { - res = -1; - } + __except (EFAULT) + { + res = -1; + } __endtry sigproc_printf ("returning signal %d", res); return res; From 8ae26f96ae710f8562162fd5d4e9a5d7434beb7b Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Sun, 13 Jan 2019 23:09:48 +0100 Subject: [PATCH 087/475] Cygwin: proc fd: return EACCES for HANDLE-less fds Signed-off-by: Corinna Vinschen --- winsup/cygwin/fhandler_process_fd.cc | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/winsup/cygwin/fhandler_process_fd.cc b/winsup/cygwin/fhandler_process_fd.cc index a3691d9c8..a33fd7539 100644 --- a/winsup/cygwin/fhandler_process_fd.cc +++ b/winsup/cygwin/fhandler_process_fd.cc @@ -69,6 +69,13 @@ fhandler_process_fd::fetch_fh (HANDLE &out_hdl, uint32_t flags) } hdl = pc.deserialize (buf); } + if (hdl == NULL) + { + if (proc != GetCurrentProcess ()) + CloseHandle (proc); + set_errno (EACCES); + return NULL; + } BOOL ret = DuplicateHandle (proc, hdl, GetCurrentProcess (), &hdl, 0, FALSE, DUPLICATE_SAME_ACCESS); if (proc != GetCurrentProcess ()) From 9d13a2995cb4b6fd26cd7b7a2c478ad85115e055 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Sun, 13 Jan 2019 23:13:33 +0100 Subject: [PATCH 088/475] Cygwin: signal: implement signalfd First cut of a signalfd implementation. Still TODO: Non-polling select. This should mostly work as on Linux except for missing support for some members of struct signalfd_siginfo, namely ssi_fd, ssi_band (both SIGIO/SIGPOLL, not fully implemented) and ssi_trapno (HW exception, required HW support). Signed-off-by: Corinna Vinschen --- winsup/cygwin/Makefile.in | 1 + winsup/cygwin/common.din | 1 + winsup/cygwin/devices.cc | 3 + winsup/cygwin/devices.h | 4 + winsup/cygwin/devices.in | 3 + winsup/cygwin/dtable.cc | 3 + winsup/cygwin/fhandler.cc | 3 + winsup/cygwin/fhandler.h | 40 +++++++ winsup/cygwin/fhandler_signalfd.cc | 153 +++++++++++++++++++++++++ winsup/cygwin/include/cygwin/version.h | 3 +- winsup/cygwin/include/sys/signalfd.h | 54 +++++++++ winsup/cygwin/release/2.12.0 | 2 +- winsup/cygwin/select.cc | 65 +++++++++++ winsup/cygwin/signal.cc | 62 +++++++++- winsup/cygwin/sigproc.h | 1 + winsup/doc/new-features.xml | 2 +- winsup/doc/posix.xml | 1 + 17 files changed, 397 insertions(+), 4 deletions(-) create mode 100644 winsup/cygwin/fhandler_signalfd.cc create mode 100644 winsup/cygwin/include/sys/signalfd.h diff --git a/winsup/cygwin/Makefile.in b/winsup/cygwin/Makefile.in index e4ce31fda..6147e7c9f 100644 --- a/winsup/cygwin/Makefile.in +++ b/winsup/cygwin/Makefile.in @@ -298,6 +298,7 @@ DLL_OFILES:= \ fhandler_raw.o \ fhandler_registry.o \ fhandler_serial.o \ + fhandler_signalfd.o \ fhandler_socket.o \ fhandler_socket_inet.o \ fhandler_socket_local.o \ diff --git a/winsup/cygwin/common.din b/winsup/cygwin/common.din index a6363e1ba..b7f39f9c0 100644 --- a/winsup/cygwin/common.din +++ b/winsup/cygwin/common.din @@ -1333,6 +1333,7 @@ siginterrupt SIGFE sigismember SIGFE siglongjmp NOSIGFE signal SIGFE +signalfd SIGFE significand NOSIGFE significandf NOSIGFE sigpause SIGFE diff --git a/winsup/cygwin/devices.cc b/winsup/cygwin/devices.cc index a830b3202..31fd64fa2 100644 --- a/winsup/cygwin/devices.cc +++ b/winsup/cygwin/devices.cc @@ -120,6 +120,9 @@ const _device dev_piper_storage = const _device dev_pipew_storage = {"", {FH_PIPEW}, "", exists_internal}; +const _device dev_signalfd_storage = + {"", {FH_SIGNALFD}, "", exists_internal}; + const _device dev_socket_storage = {"", {FH_SOCKET}, "", exists_internal}; diff --git a/winsup/cygwin/devices.h b/winsup/cygwin/devices.h index 0c1bf2631..065f77e0e 100644 --- a/winsup/cygwin/devices.h +++ b/winsup/cygwin/devices.h @@ -72,6 +72,8 @@ enum fh_devices FH_DEV = FHDEV (DEV_VIRTFS_MAJOR, 193), FH_CYGDRIVE= FHDEV (DEV_VIRTFS_MAJOR, 192), + FH_SIGNALFD= FHDEV (DEV_VIRTFS_MAJOR, 13), + DEV_FLOPPY_MAJOR = 2, FH_FLOPPY = FHDEV (DEV_FLOPPY_MAJOR, 0), @@ -400,6 +402,8 @@ extern const _device dev_af_local_storage; extern const _device dev_af_unix_storage; #define af_unix_dev ((device *) &dev_af_unix_storage) +extern const _device dev_signalfd_storage; +#define signalfd_dev ((device *) &dev_signalfd_storage) extern const _device dev_piper_storage; #define piper_dev ((device *) &dev_piper_storage) extern const _device dev_pipew_storage; diff --git a/winsup/cygwin/devices.in b/winsup/cygwin/devices.in index 9ad87389e..79a7fe726 100644 --- a/winsup/cygwin/devices.in +++ b/winsup/cygwin/devices.in @@ -116,6 +116,9 @@ const _device dev_piper_storage = const _device dev_pipew_storage = {"", {FH_PIPEW}, "", exists_internal}; +const _device dev_signalfd_storage = + {"", {FH_SIGNALFD}, "", exists_internal}; + const _device dev_socket_storage = {"", {FH_SOCKET}, "", exists_internal}; diff --git a/winsup/cygwin/dtable.cc b/winsup/cygwin/dtable.cc index 780deb524..c8aecfa1a 100644 --- a/winsup/cygwin/dtable.cc +++ b/winsup/cygwin/dtable.cc @@ -575,6 +575,9 @@ fh_alloc (path_conv& pc) case FH_CYGDRIVE: fh = cnew (fhandler_cygdrive); break; + case FH_SIGNALFD: + fh = cnew (fhandler_signalfd); + break; case FH_TTY: if (!pc.isopen ()) { diff --git a/winsup/cygwin/fhandler.cc b/winsup/cygwin/fhandler.cc index 9643373b0..2c1fcb7db 100644 --- a/winsup/cygwin/fhandler.cc +++ b/winsup/cygwin/fhandler.cc @@ -1345,6 +1345,9 @@ fhandler_base::fstat (struct stat *buf) case FH_PIPER: buf->st_mode = S_IFIFO | S_IRUSR; break; + case FH_SIGNALFD: + buf->st_mode = S_IRUSR | S_IWUSR; + break; default: buf->st_mode = S_IFCHR | STD_RBITS | STD_WBITS | S_IWGRP | S_IWOTH; break; diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h index ec111de36..a908964e0 100644 --- a/winsup/cygwin/fhandler.h +++ b/winsup/cygwin/fhandler.h @@ -420,6 +420,7 @@ public: virtual class fhandler_socket *is_socket () { return NULL; } virtual class fhandler_socket_wsock *is_wsock_socket () { return NULL; } virtual class fhandler_console *is_console () { return 0; } + virtual class fhandler_signalfd *is_signalfd () { return NULL; } virtual int is_windows () {return 0; } virtual void __reg3 raw_read (void *ptr, size_t& ulen); @@ -2633,6 +2634,44 @@ class fhandler_procnet: public fhandler_proc } }; +class fhandler_signalfd : public fhandler_base +{ + sigset_t sigset; + + public: + fhandler_signalfd (); + fhandler_signalfd (void *) {} + + fhandler_signalfd *is_signalfd () { return this; } + + char *get_proc_fd_name (char *buf); + + int signalfd (const sigset_t *mask, int flags); + int __reg2 fstat (struct stat *buf); + void __reg3 read (void *ptr, size_t& len); + + int poll (); + + select_record *select_read (select_stuff *); + select_record *select_write (select_stuff *); + select_record *select_except (select_stuff *); + + void copyto (fhandler_base *x) + { + x->pc.free_strings (); + *reinterpret_cast (x) = *this; + x->reset (this); + } + + fhandler_signalfd *clone (cygheap_types malloc_type = HEAP_FHANDLER) + { + void *ptr = (void *) ccalloc (malloc_type, 1, sizeof (fhandler_signalfd)); + fhandler_signalfd *fh = new (ptr) fhandler_signalfd (ptr); + copyto (fh); + return fh; + } +}; + struct fhandler_nodevice: public fhandler_base { fhandler_nodevice (); @@ -2672,6 +2711,7 @@ typedef union char __pty_master[sizeof (fhandler_pty_master)]; char __registry[sizeof (fhandler_registry)]; char __serial[sizeof (fhandler_serial)]; + char __signalfd[sizeof (fhandler_signalfd)]; char __socket_inet[sizeof (fhandler_socket_inet)]; char __socket_local[sizeof (fhandler_socket_local)]; #ifdef __WITH_AF_UNIX diff --git a/winsup/cygwin/fhandler_signalfd.cc b/winsup/cygwin/fhandler_signalfd.cc new file mode 100644 index 000000000..ec80948fb --- /dev/null +++ b/winsup/cygwin/fhandler_signalfd.cc @@ -0,0 +1,153 @@ +/* fhandler_signalfd.cc: fhandler for /proc//fd/ operations + +This file is part of Cygwin. + +This software is a copyrighted work licensed under the terms of the +Cygwin license. Please consult the file "CYGWIN_LICENSE" for +details. */ + +#include "winsup.h" +#include "path.h" +#include "fhandler.h" +#include "pinfo.h" +#include "dtable.h" +#include "cygheap.h" +#include "sigproc.h" +#include +#include + +fhandler_signalfd::fhandler_signalfd () : + fhandler_base (), + sigset (0) +{ +} + +char * +fhandler_signalfd::get_proc_fd_name (char *buf) +{ + return strcpy (buf, "anon_inode:[signalfd]"); +} + +int +fhandler_signalfd::signalfd (const sigset_t *mask, int flags) +{ + __try + { + sigset = *mask & ~(SIGKILL | SIGSTOP); + } + __except (EINVAL) + { + return -1; + } + __endtry + if (flags & SFD_NONBLOCK) + set_nonblocking (true); + if (flags & SFD_CLOEXEC) + set_close_on_exec (true); + if (get_unique_id () == 0) + { + nohandle (true); + set_unique_id (); + set_ino (get_unique_id ()); + } + return 0; +} + +int __reg2 +fhandler_signalfd::fstat (struct stat *buf) +{ + int ret = fhandler_base::fstat (buf); + if (!ret) + { + buf->st_dev = FH_SIGNALFD; + buf->st_ino = get_unique_id (); + } + return ret; +} + +static inline void +copy_siginfo_to_signalfd (struct signalfd_siginfo *sfd, + const siginfo_t * const si) +{ + sfd->ssi_signo = si->si_signo; + sfd->ssi_errno = si->si_errno; + sfd->ssi_code = si->si_code; + sfd->ssi_pid = si->si_pid; + sfd->ssi_uid = si->si_uid; + sfd->ssi_fd = -1; + sfd->ssi_tid = si->si_tid; + sfd->ssi_band = 0; + sfd->ssi_overrun = si->si_overrun; + sfd->ssi_trapno = 0; + sfd->ssi_status = si->si_status; + sfd->ssi_int = si->si_value.sival_int; + sfd->ssi_ptr = (uint64_t) si->si_value.sival_ptr; + sfd->ssi_utime = si->si_utime; + sfd->ssi_stime = si->si_stime; + sfd->ssi_addr = (uint64_t) si->si_addr; +} + +void __reg3 +fhandler_signalfd::read (void *ptr, size_t& len) +{ + const LARGE_INTEGER poll = { QuadPart : 0 }; + siginfo_t si; + int ret, old_errno; + size_t curlen = 0; + signalfd_siginfo *sfd_ptr = (signalfd_siginfo *) ptr; + + if (len < sizeof (struct signalfd_siginfo)) + { + set_errno (EINVAL); + len = (size_t) -1; + return; + } + old_errno = get_errno (); + do + { + /* Even when read is blocking, only one pending signal is actually + required to return. Subsequently use sigtimedwait to just poll + if some more signal is available. */ + ret = sigwait_common (&sigset, &si, (is_nonblocking () || curlen) + ? (PLARGE_INTEGER) &poll : NULL); + if (ret == -1) + { + if (curlen == 0) + { + if (get_errno () == EINTR && curlen == 0) + continue; + set_errno (old_errno); + } + len = curlen ?: (size_t) -1; + return; + } + __try + { + copy_siginfo_to_signalfd (sfd_ptr, &si); + } + __except (EFAULT) + { + len = (size_t) -1; + return; + } + __endtry + sfd_ptr++; + curlen += sizeof (*sfd_ptr); + } + while ((len - curlen >= sizeof (struct signalfd_siginfo))); + set_errno (old_errno); + len = curlen; + return; +} + +int +fhandler_signalfd::poll () +{ + Sleep (1L); /* BAD HACK, FIXME, need a non-polling technique. */ + sigset_t outset = (sigset_t) sig_send (myself, __SIGPENDING, &_my_tls); + if (outset == SIG_BAD_MASK) + return -1; + if ((outset & sigset) != 0) + return 0; + return -1; +} diff --git a/winsup/cygwin/include/cygwin/version.h b/winsup/cygwin/include/cygwin/version.h index 1bcec331f..ec5f55fa9 100644 --- a/winsup/cygwin/include/cygwin/version.h +++ b/winsup/cygwin/include/cygwin/version.h @@ -502,12 +502,13 @@ details. */ 330: Add CLOCK_REALTIME_COARSE, CLOCK_MONOTONIC_RAW, CLOCK_MONOTONIC_COARSE, CLOCK_BOOTTIME. 331: Add timer_getoverrun, DELAYTIMER_MAX. + 332: Add signalfd. Note that we forgot to bump the api for ualarm, strtoll, strtoull, sigaltstack, sethostname. */ #define CYGWIN_VERSION_API_MAJOR 0 -#define CYGWIN_VERSION_API_MINOR 331 +#define CYGWIN_VERSION_API_MINOR 332 /* There is also a compatibity version number associated with the shared memory regions. It is incremented when incompatible changes are made to the shared diff --git a/winsup/cygwin/include/sys/signalfd.h b/winsup/cygwin/include/sys/signalfd.h new file mode 100644 index 000000000..f4e5bd5c1 --- /dev/null +++ b/winsup/cygwin/include/sys/signalfd.h @@ -0,0 +1,54 @@ +/* sys/signalfd.h: define signalfd(2) and struct signalfd_siginfo + +This file is part of Cygwin. + +This software is a copyrighted work licensed under the terms of the +Cygwin license. Please consult the file "CYGWIN_LICENSE" for +details. */ + +#ifndef _SYS_SIGNALFD_H +#define _SYS_SIGNALFD_H + +#include +#include + +enum +{ + SFD_CLOEXEC = O_CLOEXEC, + SFD_NONBLOCK = O_NONBLOCK +}; +#define SFD_CLOEXEC SFD_CLOEXEC +#define SFD_NONBLOCK SFD_NONBLOCK + +struct signalfd_siginfo +{ + uint32_t ssi_signo; + int32_t ssi_errno; + int32_t ssi_code; + uint32_t ssi_pid; + uint32_t ssi_uid; + int32_t ssi_fd; + uint32_t ssi_tid; + uint32_t ssi_band; + uint32_t ssi_overrun; + uint32_t ssi_trapno; + int32_t ssi_status; + int32_t ssi_int; + uint64_t ssi_ptr; + uint64_t ssi_utime; + uint64_t ssi_stime; + uint64_t ssi_addr; + uint8_t pad[48]; +}; + +#ifdef __cplusplus +extern "C" { +#endif + +extern int signalfd (int, const sigset_t *, int); + +#ifdef __cplusplus +} +#endif + +#endif /* _SYS_SIGNALFD_H */ diff --git a/winsup/cygwin/release/2.12.0 b/winsup/cygwin/release/2.12.0 index dbda7886e..299ea6d3d 100644 --- a/winsup/cygwin/release/2.12.0 +++ b/winsup/cygwin/release/2.12.0 @@ -27,7 +27,7 @@ What's new: - Support overrun counter for posix timers (via timer_getoverrun() or siginfo_t::si_overrun). -- New API: timer_getoverrun. +- New API: signalfd, timer_getoverrun. What changed: diff --git a/winsup/cygwin/select.cc b/winsup/cygwin/select.cc index 6ce679acf..3927b9885 100644 --- a/winsup/cygwin/select.cc +++ b/winsup/cygwin/select.cc @@ -1731,3 +1731,68 @@ fhandler_windows::select_except (select_stuff *ss) s->windows_handle = true; return s; } + +static int +peek_signalfd (select_record *me, bool) +{ + if (((fhandler_signalfd *) me->fh)->poll () == 0) + { + select_printf ("signalfd %d ready", me->fd); + return 1; + } + + select_printf ("signalfd %d not ready", me->fd); + return 0; +} + +static int +verify_signalfd (select_record *me, fd_set *rfds, fd_set *wfds, + fd_set *efds) +{ + return peek_signalfd (me, true); +} + +select_record * +fhandler_signalfd::select_read (select_stuff *ss) +{ + select_record *s = ss->start.next; + if (!s->startup) + { + s->startup = no_startup; + } + s->verify = verify_signalfd; + s->peek = peek_signalfd; + s->read_selected = true; + s->read_ready = true; + return s; +} + +select_record * +fhandler_signalfd::select_write (select_stuff *ss) +{ + select_record *s = ss->start.next; + if (!s->startup) + { + s->startup = no_startup; + s->verify = no_verify; + } + s->peek = NULL; + s->write_selected = false; + s->write_ready = false; + return s; +} + +select_record * +fhandler_signalfd::select_except (select_stuff *ss) +{ + select_record *s = ss->start.next; + if (!s->startup) + { + s->startup = no_startup; + s->verify = no_verify; + } + s->peek = NULL; + s->except_selected = false; + s->except_ready = false; + return s; +} diff --git a/winsup/cygwin/signal.cc b/winsup/cygwin/signal.cc index c5e9d017e..5dee40229 100644 --- a/winsup/cygwin/signal.cc +++ b/winsup/cygwin/signal.cc @@ -12,6 +12,7 @@ details. */ #include "winsup.h" #include #include +#include #include "pinfo.h" #include "sigproc.h" #include "cygtls.h" @@ -592,7 +593,7 @@ siginterrupt (int sig, int flag) return res; } -static inline int +int sigwait_common (const sigset_t *set, siginfo_t *info, PLARGE_INTEGER waittime) { int res = -1; @@ -781,3 +782,62 @@ sigaltstack (const stack_t *ss, stack_t *oss) __endtry return 0; } + +extern "C" int +signalfd (int fd_in, const sigset_t *mask, int flags) +{ + int ret = -1; + fhandler_signalfd *fh; + + debug_printf ("signalfd (%d, %p, %y)", fd_in, mask, flags); + + if ((flags & ~(SFD_NONBLOCK | SFD_CLOEXEC)) != 0) + { + set_errno (EINVAL); + goto done; + } + + if (fd_in != -1) + { + /* Change signal mask. */ + cygheap_fdget fd (fd_in); + + if (fd < 0) + goto done; + fh = fd->is_signalfd (); + if (!fh) + { + set_errno (EINVAL); + goto done; + } + __try + { + if (fh->signalfd (mask, flags) == 0) + ret = fd_in; + } + __except (EINVAL) {} + __endtry + } + else + { + /* Create new signalfd descriptor. */ + cygheap_fdnew fd; + + if (fd < 0) + goto done; + fh = (fhandler_signalfd *) build_fh_dev (*signalfd_dev); + if (fh && fh->signalfd (mask, flags) == 0) + { + fd = fh; + if (fd <= 2) + set_std_handle (fd); + ret = fd; + } + else + delete fh; + } + +done: + syscall_printf ("%R = signalfd (%d, %p, %y)", ret, fd_in, mask, flags); + return ret; +} diff --git a/winsup/cygwin/sigproc.h b/winsup/cygwin/sigproc.h index f2cd1132b..9beb31dcf 100644 --- a/winsup/cygwin/sigproc.h +++ b/winsup/cygwin/sigproc.h @@ -79,6 +79,7 @@ void __stdcall sigalloc (); int kill_pgrp (pid_t, siginfo_t&); void __reg1 exit_thread (DWORD) __attribute__ ((noreturn)); void __reg1 setup_signal_exit (int); +int sigwait_common (const sigset_t *, siginfo_t *, PLARGE_INTEGER); class no_thread_exit_protect { diff --git a/winsup/doc/new-features.xml b/winsup/doc/new-features.xml index 2e1645fbe..17071309e 100644 --- a/winsup/doc/new-features.xml +++ b/winsup/doc/new-features.xml @@ -51,7 +51,7 @@ siginfo_t::si_overrun). -New API: timer_getoverrun. +New API: signalfd, timer_getoverrun. diff --git a/winsup/doc/posix.xml b/winsup/doc/posix.xml index 021b5962c..365a8f0b5 100644 --- a/winsup/doc/posix.xml +++ b/winsup/doc/posix.xml @@ -1378,6 +1378,7 @@ also IEEE Std 1003.1-2008 (POSIX.1-2008). scandirat sched_getcpu setxattr + signalfd sincos sincosf sincosl From 30062d409dcc3ec19024e0a10f9fca84c581855f Mon Sep 17 00:00:00 2001 From: Thomas Wolff Date: Sat, 12 Jan 2019 11:57:59 +0100 Subject: [PATCH 089/475] map WEOF to undefined rather than the control char category Fixes https://cygwin.com/ml/cygwin/2018-12/msg00173.html --- newlib/libc/ctype/categories.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/newlib/libc/ctype/categories.c b/newlib/libc/ctype/categories.c index 85328ef2e..a8de1f129 100644 --- a/newlib/libc/ctype/categories.c +++ b/newlib/libc/ctype/categories.c @@ -19,7 +19,7 @@ bisearch_cat(wint_t ucs, const struct _category *table, int max) int mid; if (ucs < table[0].first || ucs > table[max].first + table[max].delta) - return 0; + return -1; while (max >= min) { mid = (min + max) / 2; From 41397e13ce38034841ccb85cec9fc5c745611a9e Mon Sep 17 00:00:00 2001 From: Thomas Wolff Date: Sat, 12 Jan 2019 12:35:18 +0100 Subject: [PATCH 090/475] update to Unicode 11.0 --- newlib/libc/ctype/caseconv.t | 8 ++- newlib/libc/ctype/categories.t | 125 ++++++++++++++++++++++++--------- newlib/libc/string/combining.t | 106 ++++++++++++++-------------- newlib/libc/string/wide.t | 13 ++-- 4 files changed, 159 insertions(+), 93 deletions(-) diff --git a/newlib/libc/ctype/caseconv.t b/newlib/libc/ctype/caseconv.t index 5e132d3e1..31eb503fa 100644 --- a/newlib/libc/ctype/caseconv.t +++ b/newlib/libc/ctype/caseconv.t @@ -165,6 +165,8 @@ {0x10A0, 37, TOLO, 7264}, {0x10C7, 0, TOLO, 7264}, {0x10CD, 0, TOLO, 7264}, + {0x10D0, 42, TOUP, 3008}, + {0x10FD, 2, TOUP, 3008}, {0x13A0, 79, TOLO, 38864}, {0x13F0, 5, TOLO, 8}, {0x13F8, 5, TOUP, -8}, @@ -176,6 +178,8 @@ {0x1C86, 0, TOUP, -6236}, {0x1C87, 0, TOUP, -6181}, {0x1C88, 0, TOUP, 35266}, + {0x1C90, 42, TOLO, -3008}, + {0x1CBD, 2, TOLO, -3008}, {0x1D79, 0, TOUP, 35332}, {0x1D7D, 0, TOUP, 3814}, {0x1E00, 149, TO1, EVENCAP}, @@ -287,7 +291,7 @@ {0xA7B1, 0, TOLO, -42282}, {0xA7B2, 0, TOLO, -42261}, {0xA7B3, 0, TOLO, 928}, - {0xA7B4, 3, TO1, EVENCAP}, + {0xA7B4, 5, TO1, EVENCAP}, {0xAB53, 0, TOUP, -928}, {0xAB70, 79, TOUP, -38864}, {0xFF21, 25, TOLO, 32}, @@ -300,5 +304,7 @@ {0x10CC0, 50, TOUP, -64}, {0x118A0, 31, TOLO, 32}, {0x118C0, 31, TOUP, -32}, + {0x16E40, 31, TOLO, 32}, + {0x16E60, 31, TOUP, -32}, {0x1E900, 33, TOLO, 34}, {0x1E922, 33, TOUP, -34}, diff --git a/newlib/libc/ctype/categories.t b/newlib/libc/ctype/categories.t index 670457713..ca7671051 100644 --- a/newlib/libc/ctype/categories.t +++ b/newlib/libc/ctype/categories.t @@ -168,8 +168,9 @@ {CAT_LC, 0x0531, 37}, {CAT_Lm, 0x0559, 0}, {CAT_Po, 0x055A, 5}, + {CAT_Ll, 0x0560, 0}, {CAT_LC, 0x0561, 37}, - {CAT_Ll, 0x0587, 0}, + {CAT_Ll, 0x0587, 1}, {CAT_Po, 0x0589, 0}, {CAT_Pd, 0x058A, 0}, {CAT_So, 0x058D, 1}, @@ -184,7 +185,7 @@ {CAT_Po, 0x05C6, 0}, {CAT_Mn, 0x05C7, 0}, {CAT_Lo, 0x05D0, 26}, - {CAT_Lo, 0x05F0, 2}, + {CAT_Lo, 0x05EF, 3}, {CAT_Po, 0x05F3, 1}, {CAT_Cf, 0x0600, 5}, {CAT_Sm, 0x0606, 2}, @@ -236,6 +237,8 @@ {CAT_So, 0x07F6, 0}, {CAT_Po, 0x07F7, 2}, {CAT_Lm, 0x07FA, 0}, + {CAT_Mn, 0x07FD, 0}, + {CAT_Sc, 0x07FE, 1}, {CAT_Lo, 0x0800, 21}, {CAT_Mn, 0x0816, 3}, {CAT_Lm, 0x081A, 0}, @@ -251,7 +254,7 @@ {CAT_Lo, 0x0860, 10}, {CAT_Lo, 0x08A0, 20}, {CAT_Lo, 0x08B6, 7}, - {CAT_Mn, 0x08D4, 13}, + {CAT_Mn, 0x08D3, 14}, {CAT_Cf, 0x08E2, 0}, {CAT_Mn, 0x08E3, 31}, {CAT_Mc, 0x0903, 0}, @@ -302,6 +305,7 @@ {CAT_Sc, 0x09FB, 0}, {CAT_Lo, 0x09FC, 0}, {CAT_Po, 0x09FD, 0}, + {CAT_Mn, 0x09FE, 0}, {CAT_Mn, 0x0A01, 1}, {CAT_Mc, 0x0A03, 0}, {CAT_Lo, 0x0A05, 5}, @@ -323,6 +327,7 @@ {CAT_Mn, 0x0A70, 1}, {CAT_Lo, 0x0A72, 2}, {CAT_Mn, 0x0A75, 0}, + {CAT_Po, 0x0A76, 0}, {CAT_Mn, 0x0A81, 1}, {CAT_Mc, 0x0A83, 0}, {CAT_Lo, 0x0A85, 8}, @@ -399,6 +404,7 @@ {CAT_So, 0x0BFA, 0}, {CAT_Mn, 0x0C00, 0}, {CAT_Mc, 0x0C01, 2}, + {CAT_Mn, 0x0C04, 0}, {CAT_Lo, 0x0C05, 7}, {CAT_Lo, 0x0C0E, 2}, {CAT_Lo, 0x0C12, 22}, @@ -418,6 +424,7 @@ {CAT_Lo, 0x0C80, 0}, {CAT_Mn, 0x0C81, 0}, {CAT_Mc, 0x0C82, 1}, + {CAT_Po, 0x0C84, 0}, {CAT_Lo, 0x0C85, 7}, {CAT_Lo, 0x0C8E, 2}, {CAT_Lo, 0x0C92, 22}, @@ -584,10 +591,11 @@ {CAT_LC, 0x10A0, 37}, {CAT_LC, 0x10C7, 0}, {CAT_LC, 0x10CD, 0}, - {CAT_Lo, 0x10D0, 42}, + {CAT_LC, 0x10D0, 42}, {CAT_Po, 0x10FB, 0}, {CAT_Lm, 0x10FC, 0}, - {CAT_Lo, 0x10FD, 331}, + {CAT_LC, 0x10FD, 2}, + {CAT_Lo, 0x1100, 328}, {CAT_Lo, 0x124A, 3}, {CAT_Lo, 0x1250, 6}, {CAT_Lo, 0x1258, 0}, @@ -657,7 +665,7 @@ {CAT_Nd, 0x1810, 9}, {CAT_Lo, 0x1820, 34}, {CAT_Lm, 0x1843, 0}, - {CAT_Lo, 0x1844, 51}, + {CAT_Lo, 0x1844, 52}, {CAT_Lo, 0x1880, 4}, {CAT_Mn, 0x1885, 1}, {CAT_Lo, 0x1887, 33}, @@ -759,6 +767,8 @@ {CAT_Lm, 0x1C78, 5}, {CAT_Po, 0x1C7E, 1}, {CAT_LC, 0x1C80, 8}, + {CAT_LC, 0x1C90, 42}, + {CAT_LC, 0x1CBD, 2}, {CAT_Po, 0x1CC0, 7}, {CAT_Mn, 0x1CD0, 2}, {CAT_Po, 0x1CD3, 0}, @@ -1066,10 +1076,8 @@ {CAT_Sm, 0x2B47, 5}, {CAT_So, 0x2B4D, 38}, {CAT_So, 0x2B76, 31}, - {CAT_So, 0x2B98, 33}, - {CAT_So, 0x2BBD, 11}, - {CAT_So, 0x2BCA, 8}, - {CAT_So, 0x2BEC, 3}, + {CAT_So, 0x2B98, 48}, + {CAT_So, 0x2BCA, 52}, {CAT_LC, 0x2C00, 46}, {CAT_LC, 0x2C30, 46}, {CAT_LC, 0x2C60, 16}, @@ -1142,7 +1150,7 @@ {CAT_Pd, 0x2E40, 0}, {CAT_Po, 0x2E41, 0}, {CAT_Ps, 0x2E42, 0}, - {CAT_Po, 0x2E43, 6}, + {CAT_Po, 0x2E43, 11}, {CAT_So, 0x2E80, 25}, {CAT_So, 0x2E9B, 88}, {CAT_So, 0x2F00, 213}, @@ -1197,7 +1205,7 @@ {CAT_Po, 0x30FB, 0}, {CAT_Lm, 0x30FC, 2}, {CAT_Lo, 0x30FF, 0}, - {CAT_Lo, 0x3105, 41}, + {CAT_Lo, 0x3105, 42}, {CAT_Lo, 0x3131, 93}, {CAT_So, 0x3190, 1}, {CAT_No, 0x3192, 3}, @@ -1219,7 +1227,7 @@ {CAT_So, 0x3300, 255}, {CAT_Lo, 0x3400, 6581}, {CAT_So, 0x4DC0, 63}, - {CAT_Lo, 0x4E00, 20970}, + {CAT_Lo, 0x4E00, 20975}, {CAT_Lo, 0xA000, 20}, {CAT_Lm, 0xA015, 0}, {CAT_Lo, 0xA016, 1142}, @@ -1265,7 +1273,8 @@ {CAT_LC, 0xA790, 3}, {CAT_Ll, 0xA794, 1}, {CAT_LC, 0xA796, 24}, - {CAT_LC, 0xA7B0, 7}, + {CAT_Ll, 0xA7AF, 0}, + {CAT_LC, 0xA7B0, 9}, {CAT_Lo, 0xA7F7, 0}, {CAT_Lm, 0xA7F8, 1}, {CAT_Ll, 0xA7FA, 0}, @@ -1297,7 +1306,8 @@ {CAT_Po, 0xA8F8, 2}, {CAT_Lo, 0xA8FB, 0}, {CAT_Po, 0xA8FC, 0}, - {CAT_Lo, 0xA8FD, 0}, + {CAT_Lo, 0xA8FD, 1}, + {CAT_Mn, 0xA8FF, 0}, {CAT_Nd, 0xA900, 9}, {CAT_Lo, 0xA90A, 27}, {CAT_Mn, 0xA926, 7}, @@ -1599,10 +1609,10 @@ {CAT_Mn, 0x10A0C, 3}, {CAT_Lo, 0x10A10, 3}, {CAT_Lo, 0x10A15, 2}, - {CAT_Lo, 0x10A19, 26}, + {CAT_Lo, 0x10A19, 28}, {CAT_Mn, 0x10A38, 2}, {CAT_Mn, 0x10A3F, 0}, - {CAT_No, 0x10A40, 7}, + {CAT_No, 0x10A40, 8}, {CAT_Po, 0x10A50, 8}, {CAT_Lo, 0x10A60, 28}, {CAT_No, 0x10A7D, 1}, @@ -1628,7 +1638,17 @@ {CAT_LC, 0x10C80, 50}, {CAT_LC, 0x10CC0, 50}, {CAT_No, 0x10CFA, 5}, + {CAT_Lo, 0x10D00, 35}, + {CAT_Mn, 0x10D24, 3}, + {CAT_Nd, 0x10D30, 9}, {CAT_No, 0x10E60, 30}, + {CAT_Lo, 0x10F00, 28}, + {CAT_No, 0x10F1D, 9}, + {CAT_Lo, 0x10F27, 0}, + {CAT_Lo, 0x10F30, 21}, + {CAT_Mn, 0x10F46, 10}, + {CAT_No, 0x10F51, 3}, + {CAT_Po, 0x10F55, 4}, {CAT_Mc, 0x11000, 0}, {CAT_Mn, 0x11001, 0}, {CAT_Mc, 0x11002, 0}, @@ -1647,6 +1667,7 @@ {CAT_Po, 0x110BB, 1}, {CAT_Cf, 0x110BD, 0}, {CAT_Po, 0x110BE, 3}, + {CAT_Cf, 0x110CD, 0}, {CAT_Lo, 0x110D0, 24}, {CAT_Nd, 0x110F0, 9}, {CAT_Mn, 0x11100, 2}, @@ -1656,6 +1677,8 @@ {CAT_Mn, 0x1112D, 7}, {CAT_Nd, 0x11136, 9}, {CAT_Po, 0x11140, 3}, + {CAT_Lo, 0x11144, 0}, + {CAT_Mc, 0x11145, 1}, {CAT_Lo, 0x11150, 34}, {CAT_Mn, 0x11173, 0}, {CAT_Po, 0x11174, 1}, @@ -1667,8 +1690,8 @@ {CAT_Mn, 0x111B6, 8}, {CAT_Mc, 0x111BF, 1}, {CAT_Lo, 0x111C1, 3}, - {CAT_Po, 0x111C5, 4}, - {CAT_Mn, 0x111CA, 2}, + {CAT_Po, 0x111C5, 3}, + {CAT_Mn, 0x111C9, 3}, {CAT_Po, 0x111CD, 0}, {CAT_Nd, 0x111D0, 9}, {CAT_Lo, 0x111DA, 0}, @@ -1705,7 +1728,7 @@ {CAT_Lo, 0x1132A, 6}, {CAT_Lo, 0x11332, 1}, {CAT_Lo, 0x11335, 4}, - {CAT_Mn, 0x1133C, 0}, + {CAT_Mn, 0x1133B, 1}, {CAT_Lo, 0x1133D, 0}, {CAT_Mc, 0x1133E, 1}, {CAT_Mn, 0x11340, 0}, @@ -1730,6 +1753,7 @@ {CAT_Nd, 0x11450, 9}, {CAT_Po, 0x1145B, 0}, {CAT_Po, 0x1145D, 0}, + {CAT_Mn, 0x1145E, 0}, {CAT_Lo, 0x11480, 47}, {CAT_Mc, 0x114B0, 2}, {CAT_Mn, 0x114B3, 5}, @@ -1773,7 +1797,7 @@ {CAT_Mc, 0x116B6, 0}, {CAT_Mn, 0x116B7, 0}, {CAT_Nd, 0x116C0, 9}, - {CAT_Lo, 0x11700, 25}, + {CAT_Lo, 0x11700, 26}, {CAT_Mn, 0x1171D, 2}, {CAT_Mc, 0x11720, 1}, {CAT_Mn, 0x11722, 3}, @@ -1783,14 +1807,18 @@ {CAT_No, 0x1173A, 1}, {CAT_Po, 0x1173C, 2}, {CAT_So, 0x1173F, 0}, + {CAT_Lo, 0x11800, 43}, + {CAT_Mc, 0x1182C, 2}, + {CAT_Mn, 0x1182F, 8}, + {CAT_Mc, 0x11838, 0}, + {CAT_Mn, 0x11839, 1}, + {CAT_Po, 0x1183B, 0}, {CAT_LC, 0x118A0, 63}, {CAT_Nd, 0x118E0, 9}, {CAT_No, 0x118EA, 8}, {CAT_Lo, 0x118FF, 0}, {CAT_Lo, 0x11A00, 0}, - {CAT_Mn, 0x11A01, 5}, - {CAT_Mc, 0x11A07, 1}, - {CAT_Mn, 0x11A09, 1}, + {CAT_Mn, 0x11A01, 9}, {CAT_Lo, 0x11A0B, 39}, {CAT_Mn, 0x11A33, 5}, {CAT_Mc, 0x11A39, 0}, @@ -1808,6 +1836,7 @@ {CAT_Mc, 0x11A97, 0}, {CAT_Mn, 0x11A98, 1}, {CAT_Po, 0x11A9A, 2}, + {CAT_Lo, 0x11A9D, 0}, {CAT_Po, 0x11A9E, 4}, {CAT_Lo, 0x11AC0, 56}, {CAT_Lo, 0x11C00, 8}, @@ -1840,6 +1869,21 @@ {CAT_Lo, 0x11D46, 0}, {CAT_Mn, 0x11D47, 0}, {CAT_Nd, 0x11D50, 9}, + {CAT_Lo, 0x11D60, 5}, + {CAT_Lo, 0x11D67, 1}, + {CAT_Lo, 0x11D6A, 31}, + {CAT_Mc, 0x11D8A, 4}, + {CAT_Mn, 0x11D90, 1}, + {CAT_Mc, 0x11D93, 1}, + {CAT_Mn, 0x11D95, 0}, + {CAT_Mc, 0x11D96, 0}, + {CAT_Mn, 0x11D97, 0}, + {CAT_Lo, 0x11D98, 0}, + {CAT_Nd, 0x11DA0, 9}, + {CAT_Lo, 0x11EE0, 18}, + {CAT_Mn, 0x11EF3, 1}, + {CAT_Mc, 0x11EF5, 1}, + {CAT_Po, 0x11EF7, 1}, {CAT_Lo, 0x12000, 921}, {CAT_Nl, 0x12400, 110}, {CAT_Po, 0x12470, 4}, @@ -1864,13 +1908,16 @@ {CAT_No, 0x16B5B, 6}, {CAT_Lo, 0x16B63, 20}, {CAT_Lo, 0x16B7D, 18}, + {CAT_LC, 0x16E40, 63}, + {CAT_No, 0x16E80, 22}, + {CAT_Po, 0x16E97, 3}, {CAT_Lo, 0x16F00, 68}, {CAT_Lo, 0x16F50, 0}, {CAT_Mc, 0x16F51, 45}, {CAT_Mn, 0x16F8F, 3}, {CAT_Lm, 0x16F93, 12}, {CAT_Lm, 0x16FE0, 1}, - {CAT_Lo, 0x17000, 6124}, + {CAT_Lo, 0x17000, 6129}, {CAT_Lo, 0x18800, 754}, {CAT_Lo, 0x1B000, 286}, {CAT_Lo, 0x1B170, 395}, @@ -1899,8 +1946,9 @@ {CAT_So, 0x1D200, 65}, {CAT_Mn, 0x1D242, 2}, {CAT_So, 0x1D245, 0}, + {CAT_No, 0x1D2E0, 19}, {CAT_So, 0x1D300, 86}, - {CAT_No, 0x1D360, 17}, + {CAT_No, 0x1D360, 24}, {CAT_Lu, 0x1D400, 25}, {CAT_Ll, 0x1D41A, 25}, {CAT_Lu, 0x1D434, 25}, @@ -1995,6 +2043,11 @@ {CAT_Mn, 0x1E944, 6}, {CAT_Nd, 0x1E950, 9}, {CAT_Po, 0x1E95E, 1}, + {CAT_No, 0x1EC71, 58}, + {CAT_So, 0x1ECAC, 0}, + {CAT_No, 0x1ECAD, 2}, + {CAT_Sc, 0x1ECB0, 0}, + {CAT_No, 0x1ECB1, 3}, {CAT_Lo, 0x1EE00, 3}, {CAT_Lo, 0x1EE05, 26}, {CAT_Lo, 0x1EE21, 1}, @@ -2036,8 +2089,7 @@ {CAT_So, 0x1F0C1, 14}, {CAT_So, 0x1F0D1, 36}, {CAT_No, 0x1F100, 12}, - {CAT_So, 0x1F110, 30}, - {CAT_So, 0x1F130, 59}, + {CAT_So, 0x1F110, 91}, {CAT_So, 0x1F170, 60}, {CAT_So, 0x1F1E6, 28}, {CAT_So, 0x1F210, 43}, @@ -2048,9 +2100,9 @@ {CAT_Sk, 0x1F3FB, 4}, {CAT_So, 0x1F400, 724}, {CAT_So, 0x1F6E0, 12}, - {CAT_So, 0x1F6F0, 8}, + {CAT_So, 0x1F6F0, 9}, {CAT_So, 0x1F700, 115}, - {CAT_So, 0x1F780, 84}, + {CAT_So, 0x1F780, 88}, {CAT_So, 0x1F800, 11}, {CAT_So, 0x1F810, 55}, {CAT_So, 0x1F850, 9}, @@ -2058,11 +2110,14 @@ {CAT_So, 0x1F890, 29}, {CAT_So, 0x1F900, 11}, {CAT_So, 0x1F910, 46}, - {CAT_So, 0x1F940, 12}, - {CAT_So, 0x1F950, 27}, - {CAT_So, 0x1F980, 23}, - {CAT_So, 0x1F9C0, 0}, - {CAT_So, 0x1F9D0, 22}, + {CAT_So, 0x1F940, 48}, + {CAT_So, 0x1F973, 3}, + {CAT_So, 0x1F97A, 0}, + {CAT_So, 0x1F97C, 38}, + {CAT_So, 0x1F9B0, 9}, + {CAT_So, 0x1F9C0, 2}, + {CAT_So, 0x1F9D0, 47}, + {CAT_So, 0x1FA60, 13}, {CAT_Lo, 0x20000, 42710}, {CAT_Lo, 0x2A700, 4148}, {CAT_Lo, 0x2B740, 221}, diff --git a/newlib/libc/string/combining.t b/newlib/libc/string/combining.t index 629d8f891..105cacbdf 100644 --- a/newlib/libc/string/combining.t +++ b/newlib/libc/string/combining.t @@ -6,21 +6,22 @@ { 0x06D6, 0x06DD }, { 0x06DF, 0x06E4 }, { 0x06E7, 0x06E8 }, { 0x06EA, 0x06ED }, { 0x070F, 0x070F }, { 0x0711, 0x0711 }, { 0x0730, 0x074A }, { 0x07A6, 0x07B0 }, { 0x07EB, 0x07F3 }, - { 0x0816, 0x0819 }, { 0x081B, 0x0823 }, { 0x0825, 0x0827 }, - { 0x0829, 0x082D }, { 0x0859, 0x085B }, { 0x08D4, 0x0902 }, - { 0x093A, 0x093A }, { 0x093C, 0x093C }, { 0x0941, 0x0948 }, - { 0x094D, 0x094D }, { 0x0951, 0x0957 }, { 0x0962, 0x0963 }, - { 0x0981, 0x0981 }, { 0x09BC, 0x09BC }, { 0x09C1, 0x09C4 }, - { 0x09CD, 0x09CD }, { 0x09E2, 0x09E3 }, { 0x0A01, 0x0A02 }, - { 0x0A3C, 0x0A3C }, { 0x0A41, 0x0A42 }, { 0x0A47, 0x0A48 }, - { 0x0A4B, 0x0A4D }, { 0x0A51, 0x0A51 }, { 0x0A70, 0x0A71 }, - { 0x0A75, 0x0A75 }, { 0x0A81, 0x0A82 }, { 0x0ABC, 0x0ABC }, - { 0x0AC1, 0x0AC5 }, { 0x0AC7, 0x0AC8 }, { 0x0ACD, 0x0ACD }, - { 0x0AE2, 0x0AE3 }, { 0x0AFA, 0x0AFF }, { 0x0B01, 0x0B01 }, - { 0x0B3C, 0x0B3C }, { 0x0B3F, 0x0B3F }, { 0x0B41, 0x0B44 }, - { 0x0B4D, 0x0B4D }, { 0x0B56, 0x0B56 }, { 0x0B62, 0x0B63 }, - { 0x0B82, 0x0B82 }, { 0x0BC0, 0x0BC0 }, { 0x0BCD, 0x0BCD }, - { 0x0C00, 0x0C00 }, { 0x0C3E, 0x0C40 }, { 0x0C46, 0x0C48 }, + { 0x07FD, 0x07FD }, { 0x0816, 0x0819 }, { 0x081B, 0x0823 }, + { 0x0825, 0x0827 }, { 0x0829, 0x082D }, { 0x0859, 0x085B }, + { 0x08D3, 0x0902 }, { 0x093A, 0x093A }, { 0x093C, 0x093C }, + { 0x0941, 0x0948 }, { 0x094D, 0x094D }, { 0x0951, 0x0957 }, + { 0x0962, 0x0963 }, { 0x0981, 0x0981 }, { 0x09BC, 0x09BC }, + { 0x09C1, 0x09C4 }, { 0x09CD, 0x09CD }, { 0x09E2, 0x09E3 }, + { 0x09FE, 0x09FE }, { 0x0A01, 0x0A02 }, { 0x0A3C, 0x0A3C }, + { 0x0A41, 0x0A42 }, { 0x0A47, 0x0A48 }, { 0x0A4B, 0x0A4D }, + { 0x0A51, 0x0A51 }, { 0x0A70, 0x0A71 }, { 0x0A75, 0x0A75 }, + { 0x0A81, 0x0A82 }, { 0x0ABC, 0x0ABC }, { 0x0AC1, 0x0AC5 }, + { 0x0AC7, 0x0AC8 }, { 0x0ACD, 0x0ACD }, { 0x0AE2, 0x0AE3 }, + { 0x0AFA, 0x0AFF }, { 0x0B01, 0x0B01 }, { 0x0B3C, 0x0B3C }, + { 0x0B3F, 0x0B3F }, { 0x0B41, 0x0B44 }, { 0x0B4D, 0x0B4D }, + { 0x0B56, 0x0B56 }, { 0x0B62, 0x0B63 }, { 0x0B82, 0x0B82 }, + { 0x0BC0, 0x0BC0 }, { 0x0BCD, 0x0BCD }, { 0x0C00, 0x0C00 }, + { 0x0C04, 0x0C04 }, { 0x0C3E, 0x0C40 }, { 0x0C46, 0x0C48 }, { 0x0C4A, 0x0C4D }, { 0x0C55, 0x0C56 }, { 0x0C62, 0x0C63 }, { 0x0C81, 0x0C81 }, { 0x0CBC, 0x0CBC }, { 0x0CBF, 0x0CBF }, { 0x0CC6, 0x0CC6 }, { 0x0CCC, 0x0CCD }, { 0x0CE2, 0x0CE3 }, @@ -60,48 +61,51 @@ { 0xA674, 0xA67D }, { 0xA69E, 0xA69F }, { 0xA6F0, 0xA6F1 }, { 0xA802, 0xA802 }, { 0xA806, 0xA806 }, { 0xA80B, 0xA80B }, { 0xA825, 0xA826 }, { 0xA8C4, 0xA8C5 }, { 0xA8E0, 0xA8F1 }, - { 0xA926, 0xA92D }, { 0xA947, 0xA951 }, { 0xA980, 0xA982 }, - { 0xA9B3, 0xA9B3 }, { 0xA9B6, 0xA9B9 }, { 0xA9BC, 0xA9BC }, - { 0xA9E5, 0xA9E5 }, { 0xAA29, 0xAA2E }, { 0xAA31, 0xAA32 }, - { 0xAA35, 0xAA36 }, { 0xAA43, 0xAA43 }, { 0xAA4C, 0xAA4C }, - { 0xAA7C, 0xAA7C }, { 0xAAB0, 0xAAB0 }, { 0xAAB2, 0xAAB4 }, - { 0xAAB7, 0xAAB8 }, { 0xAABE, 0xAABF }, { 0xAAC1, 0xAAC1 }, - { 0xAAEC, 0xAAED }, { 0xAAF6, 0xAAF6 }, { 0xABE5, 0xABE5 }, - { 0xABE8, 0xABE8 }, { 0xABED, 0xABED }, { 0xD7B0, 0xD7C6 }, - { 0xD7CB, 0xD7FB }, { 0xFB1E, 0xFB1E }, { 0xFE00, 0xFE0F }, - { 0xFE20, 0xFE2F }, { 0xFEFF, 0xFEFF }, { 0xFFF9, 0xFFFB }, - { 0x101FD, 0x101FD }, { 0x102E0, 0x102E0 }, { 0x10376, 0x1037A }, - { 0x10A01, 0x10A03 }, { 0x10A05, 0x10A06 }, { 0x10A0C, 0x10A0F }, - { 0x10A38, 0x10A3A }, { 0x10A3F, 0x10A3F }, { 0x10AE5, 0x10AE6 }, + { 0xA8FF, 0xA8FF }, { 0xA926, 0xA92D }, { 0xA947, 0xA951 }, + { 0xA980, 0xA982 }, { 0xA9B3, 0xA9B3 }, { 0xA9B6, 0xA9B9 }, + { 0xA9BC, 0xA9BC }, { 0xA9E5, 0xA9E5 }, { 0xAA29, 0xAA2E }, + { 0xAA31, 0xAA32 }, { 0xAA35, 0xAA36 }, { 0xAA43, 0xAA43 }, + { 0xAA4C, 0xAA4C }, { 0xAA7C, 0xAA7C }, { 0xAAB0, 0xAAB0 }, + { 0xAAB2, 0xAAB4 }, { 0xAAB7, 0xAAB8 }, { 0xAABE, 0xAABF }, + { 0xAAC1, 0xAAC1 }, { 0xAAEC, 0xAAED }, { 0xAAF6, 0xAAF6 }, + { 0xABE5, 0xABE5 }, { 0xABE8, 0xABE8 }, { 0xABED, 0xABED }, + { 0xD7B0, 0xD7C6 }, { 0xD7CB, 0xD7FB }, { 0xFB1E, 0xFB1E }, + { 0xFE00, 0xFE0F }, { 0xFE20, 0xFE2F }, { 0xFEFF, 0xFEFF }, + { 0xFFF9, 0xFFFB }, { 0x101FD, 0x101FD }, { 0x102E0, 0x102E0 }, + { 0x10376, 0x1037A }, { 0x10A01, 0x10A03 }, { 0x10A05, 0x10A06 }, + { 0x10A0C, 0x10A0F }, { 0x10A38, 0x10A3A }, { 0x10A3F, 0x10A3F }, + { 0x10AE5, 0x10AE6 }, { 0x10D24, 0x10D27 }, { 0x10F46, 0x10F50 }, { 0x11001, 0x11001 }, { 0x11038, 0x11046 }, { 0x1107F, 0x11081 }, { 0x110B3, 0x110B6 }, { 0x110B9, 0x110BA }, { 0x110BD, 0x110BD }, - { 0x11100, 0x11102 }, { 0x11127, 0x1112B }, { 0x1112D, 0x11134 }, - { 0x11173, 0x11173 }, { 0x11180, 0x11181 }, { 0x111B6, 0x111BE }, - { 0x111CA, 0x111CC }, { 0x1122F, 0x11231 }, { 0x11234, 0x11234 }, - { 0x11236, 0x11237 }, { 0x1123E, 0x1123E }, { 0x112DF, 0x112DF }, - { 0x112E3, 0x112EA }, { 0x11300, 0x11301 }, { 0x1133C, 0x1133C }, - { 0x11340, 0x11340 }, { 0x11366, 0x1136C }, { 0x11370, 0x11374 }, - { 0x11438, 0x1143F }, { 0x11442, 0x11444 }, { 0x11446, 0x11446 }, - { 0x114B3, 0x114B8 }, { 0x114BA, 0x114BA }, { 0x114BF, 0x114C0 }, - { 0x114C2, 0x114C3 }, { 0x115B2, 0x115B5 }, { 0x115BC, 0x115BD }, - { 0x115BF, 0x115C0 }, { 0x115DC, 0x115DD }, { 0x11633, 0x1163A }, - { 0x1163D, 0x1163D }, { 0x1163F, 0x11640 }, { 0x116AB, 0x116AB }, - { 0x116AD, 0x116AD }, { 0x116B0, 0x116B5 }, { 0x116B7, 0x116B7 }, - { 0x1171D, 0x1171F }, { 0x11722, 0x11725 }, { 0x11727, 0x1172B }, - { 0x11A01, 0x11A06 }, { 0x11A09, 0x11A0A }, { 0x11A33, 0x11A38 }, + { 0x110CD, 0x110CD }, { 0x11100, 0x11102 }, { 0x11127, 0x1112B }, + { 0x1112D, 0x11134 }, { 0x11173, 0x11173 }, { 0x11180, 0x11181 }, + { 0x111B6, 0x111BE }, { 0x111C9, 0x111CC }, { 0x1122F, 0x11231 }, + { 0x11234, 0x11234 }, { 0x11236, 0x11237 }, { 0x1123E, 0x1123E }, + { 0x112DF, 0x112DF }, { 0x112E3, 0x112EA }, { 0x11300, 0x11301 }, + { 0x1133B, 0x1133C }, { 0x11340, 0x11340 }, { 0x11366, 0x1136C }, + { 0x11370, 0x11374 }, { 0x11438, 0x1143F }, { 0x11442, 0x11444 }, + { 0x11446, 0x11446 }, { 0x1145E, 0x1145E }, { 0x114B3, 0x114B8 }, + { 0x114BA, 0x114BA }, { 0x114BF, 0x114C0 }, { 0x114C2, 0x114C3 }, + { 0x115B2, 0x115B5 }, { 0x115BC, 0x115BD }, { 0x115BF, 0x115C0 }, + { 0x115DC, 0x115DD }, { 0x11633, 0x1163A }, { 0x1163D, 0x1163D }, + { 0x1163F, 0x11640 }, { 0x116AB, 0x116AB }, { 0x116AD, 0x116AD }, + { 0x116B0, 0x116B5 }, { 0x116B7, 0x116B7 }, { 0x1171D, 0x1171F }, + { 0x11722, 0x11725 }, { 0x11727, 0x1172B }, { 0x1182F, 0x11837 }, + { 0x11839, 0x1183A }, { 0x11A01, 0x11A0A }, { 0x11A33, 0x11A38 }, { 0x11A3B, 0x11A3E }, { 0x11A47, 0x11A47 }, { 0x11A51, 0x11A56 }, { 0x11A59, 0x11A5B }, { 0x11A8A, 0x11A96 }, { 0x11A98, 0x11A99 }, { 0x11C30, 0x11C36 }, { 0x11C38, 0x11C3D }, { 0x11C3F, 0x11C3F }, { 0x11C92, 0x11CA7 }, { 0x11CAA, 0x11CB0 }, { 0x11CB2, 0x11CB3 }, { 0x11CB5, 0x11CB6 }, { 0x11D31, 0x11D36 }, { 0x11D3A, 0x11D3A }, { 0x11D3C, 0x11D3D }, { 0x11D3F, 0x11D45 }, { 0x11D47, 0x11D47 }, - { 0x16AF0, 0x16AF4 }, { 0x16B30, 0x16B36 }, { 0x16F8F, 0x16F92 }, - { 0x1BC9D, 0x1BC9E }, { 0x1BCA0, 0x1BCA3 }, { 0x1D167, 0x1D169 }, - { 0x1D173, 0x1D182 }, { 0x1D185, 0x1D18B }, { 0x1D1AA, 0x1D1AD }, - { 0x1D242, 0x1D244 }, { 0x1DA00, 0x1DA36 }, { 0x1DA3B, 0x1DA6C }, - { 0x1DA75, 0x1DA75 }, { 0x1DA84, 0x1DA84 }, { 0x1DA9B, 0x1DA9F }, - { 0x1DAA1, 0x1DAAF }, { 0x1E000, 0x1E006 }, { 0x1E008, 0x1E018 }, - { 0x1E01B, 0x1E021 }, { 0x1E023, 0x1E024 }, { 0x1E026, 0x1E02A }, - { 0x1E8D0, 0x1E8D6 }, { 0x1E944, 0x1E94A }, { 0xE0001, 0xE0001 }, - { 0xE0020, 0xE007F }, { 0xE0100, 0xE01EF } + { 0x11D90, 0x11D91 }, { 0x11D95, 0x11D95 }, { 0x11D97, 0x11D97 }, + { 0x11EF3, 0x11EF4 }, { 0x16AF0, 0x16AF4 }, { 0x16B30, 0x16B36 }, + { 0x16F8F, 0x16F92 }, { 0x1BC9D, 0x1BC9E }, { 0x1BCA0, 0x1BCA3 }, + { 0x1D167, 0x1D169 }, { 0x1D173, 0x1D182 }, { 0x1D185, 0x1D18B }, + { 0x1D1AA, 0x1D1AD }, { 0x1D242, 0x1D244 }, { 0x1DA00, 0x1DA36 }, + { 0x1DA3B, 0x1DA6C }, { 0x1DA75, 0x1DA75 }, { 0x1DA84, 0x1DA84 }, + { 0x1DA9B, 0x1DA9F }, { 0x1DAA1, 0x1DAAF }, { 0x1E000, 0x1E006 }, + { 0x1E008, 0x1E018 }, { 0x1E01B, 0x1E021 }, { 0x1E023, 0x1E024 }, + { 0x1E026, 0x1E02A }, { 0x1E8D0, 0x1E8D6 }, { 0x1E944, 0x1E94A }, + { 0xE0001, 0xE0001 }, { 0xE0020, 0xE007F }, { 0xE0100, 0xE01EF } }; diff --git a/newlib/libc/string/wide.t b/newlib/libc/string/wide.t index 8d0e243d2..d33a5954e 100644 --- a/newlib/libc/string/wide.t +++ b/newlib/libc/string/wide.t @@ -1,5 +1,5 @@ -//# EastAsianWidth-10.0.0.txt -//# Blocks-10.0.0.txt +//# EastAsianWidth-11.0.0.txt +//# Blocks-11.0.0.txt { { 0x1100, 0x115F }, { 0x231A, 0x231B }, { 0x2329, 0x232A }, { 0x23E9, 0x23EC }, { 0x23F0, 0x23F0 }, { 0x23F3, 0x23F3 }, @@ -26,8 +26,9 @@ { 0x1F4FF, 0x1F53D }, { 0x1F54B, 0x1F54E }, { 0x1F550, 0x1F567 }, { 0x1F57A, 0x1F57A }, { 0x1F595, 0x1F596 }, { 0x1F5A4, 0x1F5A4 }, { 0x1F5FB, 0x1F64F }, { 0x1F680, 0x1F6C5 }, { 0x1F6CC, 0x1F6CC }, - { 0x1F6D0, 0x1F6D2 }, { 0x1F6EB, 0x1F6EC }, { 0x1F6F4, 0x1F6F8 }, - { 0x1F910, 0x1F93E }, { 0x1F940, 0x1F94C }, { 0x1F950, 0x1F96B }, - { 0x1F980, 0x1F997 }, { 0x1F9C0, 0x1F9C0 }, { 0x1F9D0, 0x1F9E6 }, - { 0x20000, 0x2FFFD }, { 0x30000, 0x3FFFD } + { 0x1F6D0, 0x1F6D2 }, { 0x1F6EB, 0x1F6EC }, { 0x1F6F4, 0x1F6F9 }, + { 0x1F910, 0x1F93E }, { 0x1F940, 0x1F970 }, { 0x1F973, 0x1F976 }, + { 0x1F97A, 0x1F97A }, { 0x1F97C, 0x1F9A2 }, { 0x1F9B0, 0x1F9B9 }, + { 0x1F9C0, 0x1F9C2 }, { 0x1F9D0, 0x1F9FF }, { 0x20000, 0x2FFFD }, + { 0x30000, 0x3FFFD } }; From 19b7c7ab2e2fdfb70722bb016e67229c7184a173 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Sun, 13 Jan 2019 23:35:28 +0100 Subject: [PATCH 091/475] Cygwin: document wctype changes Signed-off-by: Corinna Vinschen --- winsup/cygwin/release/2.12.0 | 5 +++++ winsup/doc/new-features.xml | 4 ++++ 2 files changed, 9 insertions(+) diff --git a/winsup/cygwin/release/2.12.0 b/winsup/cygwin/release/2.12.0 index 299ea6d3d..d739a5cb2 100644 --- a/winsup/cygwin/release/2.12.0 +++ b/winsup/cygwin/release/2.12.0 @@ -49,6 +49,8 @@ What changed: - open(..., O_TMPFILE) now moves the file to the trash bin immediately, to free the parent directory. +- Wctype functions updated to Unicode 11.0. + Bug Fixes --------- @@ -67,3 +69,6 @@ Bug Fixes https://cygwin.com/ml/cygwin/2018-12/msg00028.html - Fix a bug in select(2) when polling HANDLE-less descriptors. + +- Fix WEOF handling in wctype functions. + Addresses: https://cygwin.com/ml/cygwin/2018-12/msg00173.html diff --git a/winsup/doc/new-features.xml b/winsup/doc/new-features.xml index 17071309e..5aee22b9c 100644 --- a/winsup/doc/new-features.xml +++ b/winsup/doc/new-features.xml @@ -80,6 +80,10 @@ open(..., O_TMPFILE) now moves the file to the trash bin immediately, to free the parent directory. + +Wctype functions updated to Unicode 11.0. + + From 752151e715f5b20e6380e137ec4c884617372372 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Mon, 14 Jan 2019 17:03:39 +0100 Subject: [PATCH 092/475] Cygwin: select: always store the running thread's TLS into select_record This allows select threads to access our current tls if required. Signed-off-by: Corinna Vinschen --- winsup/cygwin/select.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/winsup/cygwin/select.h b/winsup/cygwin/select.h index 1db8ad5db..9a737c39e 100644 --- a/winsup/cygwin/select.h +++ b/winsup/cygwin/select.h @@ -14,6 +14,7 @@ struct select_record int fd; HANDLE h; fhandler_base *fh; + _cygtls *tls; int thread_errno; bool windows_handle; bool read_ready, write_ready, except_ready; @@ -27,7 +28,8 @@ struct select_record void set_select_errno () {__seterrno (); thread_errno = errno;} int saw_error () {return thread_errno;} select_record (int): next (NULL) {} - select_record (): fd (0), h (NULL), fh (NULL), thread_errno (0), + select_record () : + fd (0), h (NULL), fh (NULL), tls (&_my_tls), thread_errno (0), windows_handle (false), read_ready (false), write_ready (false), except_ready (false), read_selected (false), write_selected (false), except_selected (false), except_on_write (false), From f42776fa781de858a927bc03aa966a0f3096b581 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Mon, 14 Jan 2019 17:19:37 +0100 Subject: [PATCH 093/475] Cygwin: signalfd: implement non-polling select Allow the signal thread to recognize we're called in consequence of select on a signalfd. If the signal is part of the wait mask, don't call any signal handler and don't remove the signal from the queue, so a subsequent read (or sigwaitinfo/sigtimedwait) still gets the signal. Instead, just signal the event object at _cygtls::signalfd_select_wait for the thread running select. The addition of signalfd_select_wait to _cygtls unearthed the alignment problem of the context member again. To make sure this doesn't get lost, improve the related comment in the header file so that this (hopefully) doesn't get lost (again). Signed-off-by: Corinna Vinschen --- winsup/cygwin/cygtls.h | 5 +- winsup/cygwin/exceptions.cc | 8 +++ winsup/cygwin/fhandler.h | 1 + winsup/cygwin/fhandler_signalfd.cc | 2 +- winsup/cygwin/select.cc | 98 ++++++++++++++++++++++++++---- winsup/cygwin/select.h | 12 +++- winsup/cygwin/signal.cc | 4 +- winsup/cygwin/tlsoffsets.h | 16 ++--- winsup/cygwin/tlsoffsets64.h | 16 ++--- 9 files changed, 129 insertions(+), 33 deletions(-) diff --git a/winsup/cygwin/cygtls.h b/winsup/cygwin/cygtls.h index 39dba1380..65a905c32 100644 --- a/winsup/cygwin/cygtls.h +++ b/winsup/cygwin/cygtls.h @@ -189,8 +189,11 @@ public: stack_t altstack; siginfo_t *sigwait_info; HANDLE signal_arrived; + HANDLE signalfd_select_wait; bool will_wait_for_signal; - long __align; /* Needed to align context to 16 byte. */ + /* context MUST be aligned to 16 byte, otherwise RtlCaptureContext fails. + If you prepend cygtls members here, make sure context stays 16 byte + aligned. */ ucontext_t context; DWORD thread_id; siginfo_t infodata; diff --git a/winsup/cygwin/exceptions.cc b/winsup/cygwin/exceptions.cc index 8c1b3b4e6..205ad850e 100644 --- a/winsup/cygwin/exceptions.cc +++ b/winsup/cygwin/exceptions.cc @@ -1469,6 +1469,14 @@ sigpacket::process () if (issig_wait) { tls->sigwait_mask = 0; + /* If the catching thread is running select on a signalfd, don't call + the signal handler and don't remove the signal from the queue. */ + if (tls->signalfd_select_wait) + { + SetEvent (tls->signalfd_select_wait); + rc = 0; + goto done; + } goto dosig; } diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h index a908964e0..f4a8b5463 100644 --- a/winsup/cygwin/fhandler.h +++ b/winsup/cygwin/fhandler.h @@ -2651,6 +2651,7 @@ class fhandler_signalfd : public fhandler_base void __reg3 read (void *ptr, size_t& len); int poll (); + inline sigset_t get_sigset () const { return sigset; } select_record *select_read (select_stuff *); select_record *select_write (select_stuff *); diff --git a/winsup/cygwin/fhandler_signalfd.cc b/winsup/cygwin/fhandler_signalfd.cc index ec80948fb..1bb0d1422 100644 --- a/winsup/cygwin/fhandler_signalfd.cc +++ b/winsup/cygwin/fhandler_signalfd.cc @@ -140,10 +140,10 @@ fhandler_signalfd::read (void *ptr, size_t& len) return; } +/* Called from select */ int fhandler_signalfd::poll () { - Sleep (1L); /* BAD HACK, FIXME, need a non-polling technique. */ sigset_t outset = (sigset_t) sig_send (myself, __SIGPENDING, &_my_tls); if (outset == SIG_BAD_MASK) return -1; diff --git a/winsup/cygwin/select.cc b/winsup/cygwin/select.cc index 3927b9885..d1ae3c649 100644 --- a/winsup/cygwin/select.cc +++ b/winsup/cygwin/select.cc @@ -1732,45 +1732,119 @@ fhandler_windows::select_except (select_stuff *ss) return s; } +static int start_thread_signalfd (select_record *, select_stuff *); + +static DWORD WINAPI +thread_signalfd (void *arg) +{ + select_signalfd_info *si = (select_signalfd_info *) arg; + bool event = false; + + while (!event) + { + sigset_t set = 0; + _cygtls *tls = si->start->tls; + + for (select_record *s = si->start; (s = s->next); ) + if (s->startup == start_thread_signalfd) + set |= ((fhandler_signalfd *) s->fh)->get_sigset (); + set_signal_mask (tls->sigwait_mask, set); + tls->signalfd_select_wait = si->evt; + sig_dispatch_pending (true); + switch (WaitForSingleObject (si->evt, INFINITE)) + { + case WAIT_OBJECT_0: + tls->signalfd_select_wait = NULL; + event = true; + break; + default: + break; + } + if (si->stop_thread) + break; + if (!event) + Sleep (1L); + } + CloseHandle (si->evt); + return 0; +} + +static int +start_thread_signalfd (select_record *me, select_stuff *stuff) +{ + select_signalfd_info *si; + + if ((si = stuff->device_specific_signalfd)) + { + me->h = *si->thread; + return 1; + } + si = new select_signalfd_info; + si->start = &stuff->start; + si->stop_thread = false; + si->evt = CreateEventW (&sec_none_nih, TRUE, FALSE, NULL); + si->thread = new cygthread (thread_signalfd, si, "signalfdsel"); + me->h = *si->thread; + stuff->device_specific_signalfd = si; + return 1; +} + +static void +signalfd_cleanup (select_record *, select_stuff *stuff) +{ + select_signalfd_info *si; + + if (!(si = stuff->device_specific_signalfd)) + return; + if (si->thread) + { + si->stop_thread = true; + SetEvent (si->evt); + si->thread->detach (); + } + delete si; + stuff->device_specific_signalfd = NULL; +} + static int peek_signalfd (select_record *me, bool) { if (((fhandler_signalfd *) me->fh)->poll () == 0) { select_printf ("signalfd %d ready", me->fd); + me->read_ready = true; return 1; } - select_printf ("signalfd %d not ready", me->fd); return 0; } static int -verify_signalfd (select_record *me, fd_set *rfds, fd_set *wfds, - fd_set *efds) +verify_signalfd (select_record *me, fd_set *rfds, fd_set *wfds, fd_set *efds) { return peek_signalfd (me, true); } select_record * -fhandler_signalfd::select_read (select_stuff *ss) +fhandler_signalfd::select_read (select_stuff *stuff) { - select_record *s = ss->start.next; + select_record *s = stuff->start.next; if (!s->startup) { - s->startup = no_startup; + s->startup = start_thread_signalfd; + s->verify = verify_signalfd; + s->cleanup = signalfd_cleanup; } - s->verify = verify_signalfd; s->peek = peek_signalfd; s->read_selected = true; - s->read_ready = true; + s->read_ready = false; return s; } select_record * -fhandler_signalfd::select_write (select_stuff *ss) +fhandler_signalfd::select_write (select_stuff *stuff) { - select_record *s = ss->start.next; + select_record *s = stuff->start.next; if (!s->startup) { s->startup = no_startup; @@ -1783,9 +1857,9 @@ fhandler_signalfd::select_write (select_stuff *ss) } select_record * -fhandler_signalfd::select_except (select_stuff *ss) +fhandler_signalfd::select_except (select_stuff *stuff) { - select_record *s = ss->start.next; + select_record *s = stuff->start.next; if (!s->startup) { s->startup = no_startup; diff --git a/winsup/cygwin/select.h b/winsup/cygwin/select.h index 9a737c39e..71821f76c 100644 --- a/winsup/cygwin/select.h +++ b/winsup/cygwin/select.h @@ -66,6 +66,12 @@ struct select_serial_info: public select_info select_serial_info (): select_info () {} }; +struct select_signalfd_info: public select_info +{ + HANDLE evt; + select_signalfd_info (): select_info () {} +}; + class select_stuff { public: @@ -85,6 +91,7 @@ public: select_pipe_info *device_specific_pipe; select_socket_info *device_specific_socket; select_serial_info *device_specific_serial; + select_signalfd_info *device_specific_signalfd; bool test_and_set (int, fd_set *, fd_set *, fd_set *); int poll (fd_set *, fd_set *, fd_set *); @@ -93,10 +100,11 @@ public: void destroy (); select_stuff (): return_on_signal (false), always_ready (false), - windows_used (false), start (0), + windows_used (false), start (), device_specific_pipe (NULL), device_specific_socket (NULL), - device_specific_serial (NULL) {} + device_specific_serial (NULL), + device_specific_signalfd (NULL) {} }; extern "C" int cygwin_select (int , fd_set *, fd_set *, fd_set *, diff --git a/winsup/cygwin/signal.cc b/winsup/cygwin/signal.cc index 5dee40229..5759cc4d6 100644 --- a/winsup/cygwin/signal.cc +++ b/winsup/cygwin/signal.cc @@ -603,9 +603,11 @@ sigwait_common (const sigset_t *set, siginfo_t *info, PLARGE_INTEGER waittime) __try { set_signal_mask (_my_tls.sigwait_mask, *set); + _my_tls.signalfd_select_wait = NULL; sig_dispatch_pending (true); - switch (cygwait (NULL, waittime, cw_sig_eintr | cw_cancel | cw_cancel_self)) + switch (cygwait (NULL, waittime, + cw_sig_eintr | cw_cancel | cw_cancel_self)) { case WAIT_SIGNALED: if (!sigismember (set, _my_tls.infodata.si_signo)) diff --git a/winsup/cygwin/tlsoffsets.h b/winsup/cygwin/tlsoffsets.h index 13d1003e3..8003a1fff 100644 --- a/winsup/cygwin/tlsoffsets.h +++ b/winsup/cygwin/tlsoffsets.h @@ -29,10 +29,10 @@ //; $tls::psigwait_info = 2852; //; $tls::signal_arrived = -9844; //; $tls::psignal_arrived = 2856; -//; $tls::will_wait_for_signal = -9840; -//; $tls::pwill_wait_for_signal = 2860; -//; $tls::__align = -9836; -//; $tls::p__align = 2864; +//; $tls::signalfd_select_wait = -9840; +//; $tls::psignalfd_select_wait = 2860; +//; $tls::will_wait_for_signal = -9836; +//; $tls::pwill_wait_for_signal = 2864; //; $tls::context = -9832; //; $tls::pcontext = 2868; //; $tls::thread_id = -9084; @@ -91,10 +91,10 @@ #define tls_psigwait_info (2852) #define tls_signal_arrived (-9844) #define tls_psignal_arrived (2856) -#define tls_will_wait_for_signal (-9840) -#define tls_pwill_wait_for_signal (2860) -#define tls___align (-9836) -#define tls_p__align (2864) +#define tls_signalfd_select_wait (-9840) +#define tls_psignalfd_select_wait (2860) +#define tls_will_wait_for_signal (-9836) +#define tls_pwill_wait_for_signal (2864) #define tls_context (-9832) #define tls_pcontext (2868) #define tls_thread_id (-9084) diff --git a/winsup/cygwin/tlsoffsets64.h b/winsup/cygwin/tlsoffsets64.h index d137408d0..735622172 100644 --- a/winsup/cygwin/tlsoffsets64.h +++ b/winsup/cygwin/tlsoffsets64.h @@ -29,10 +29,10 @@ //; $tls::psigwait_info = 4144; //; $tls::signal_arrived = -8648; //; $tls::psignal_arrived = 4152; -//; $tls::will_wait_for_signal = -8640; -//; $tls::pwill_wait_for_signal = 4160; -//; $tls::__align = -8632; -//; $tls::p__align = 4168; +//; $tls::signalfd_select_wait = -8640; +//; $tls::psignalfd_select_wait = 4160; +//; $tls::will_wait_for_signal = -8632; +//; $tls::pwill_wait_for_signal = 4168; //; $tls::context = -8624; //; $tls::pcontext = 4176; //; $tls::thread_id = -7328; @@ -91,10 +91,10 @@ #define tls_psigwait_info (4144) #define tls_signal_arrived (-8648) #define tls_psignal_arrived (4152) -#define tls_will_wait_for_signal (-8640) -#define tls_pwill_wait_for_signal (4160) -#define tls___align (-8632) -#define tls_p__align (4168) +#define tls_sigwait_for_select (-8640) +#define tls_psigwait_for_select (4160) +#define tls_will_wait_for_signal (-8632) +#define tls_pwill_wait_for_signal (4168) #define tls_context (-8624) #define tls_pcontext (4176) #define tls_thread_id (-7328) From 5275b3e3f20387716c4216905a57155ce63c4360 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Mon, 14 Jan 2019 20:38:24 +0100 Subject: [PATCH 094/475] Cygwin: wincap: split has_posix_file_info While FileRenameInformationEx is defined starting with Windows 10 1709 per MSDN, it only starts working in W10 1809, apparently. Users of 1803 report "Function not implemented". Introduce wincap_10_1809 and change the version check in wincapc::init accordingly. Split has_posix_file_info into has_posix_unlink_semantics and has_posix_rename_semantics. Enable the latter only starting with W10 1809. Signed-off-by: Corinna Vinschen --- winsup/cygwin/syscalls.cc | 5 ++-- winsup/cygwin/wincap.cc | 51 ++++++++++++++++++++++++++++++++------- winsup/cygwin/wincap.h | 6 +++-- 3 files changed, 49 insertions(+), 13 deletions(-) diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc index 2628d942b..04035a9ab 100644 --- a/winsup/cygwin/syscalls.cc +++ b/winsup/cygwin/syscalls.cc @@ -698,7 +698,8 @@ unlink_nt (path_conv &pc) /* First check if we can use POSIX unlink semantics: W10 1709++, local NTFS. With POSIX unlink semantics the entire job gets MUCH easier and faster. Just try to do it and if it fails, it fails. */ - if (wincap.has_posix_file_info () && !pc.isremote () && pc.fs_is_ntfs ()) + if (wincap.has_posix_unlink_semantics () + && !pc.isremote () && pc.fs_is_ntfs ()) { FILE_DISPOSITION_INFORMATION_EX fdie; @@ -2520,7 +2521,7 @@ rename2 (const char *oldpath, const char *newpath, unsigned int at2flags) } /* POSIX semantics only on local NTFS drives. */ - use_posix_semantics = wincap.has_posix_file_info () + use_posix_semantics = wincap.has_posix_rename_semantics () && !oldpc.isremote () && oldpc.fs_is_ntfs (); diff --git a/winsup/cygwin/wincap.cc b/winsup/cygwin/wincap.cc index d9aea8ac4..4c1c7b401 100644 --- a/winsup/cygwin/wincap.cc +++ b/winsup/cygwin/wincap.cc @@ -35,8 +35,9 @@ wincaps wincap_vista __attribute__((section (".cygwin_dll_common"), shared)) = { has_unprivileged_createsymlink:false, has_unbiased_interrupt_time:false, has_precise_interrupt_time:false, - has_posix_file_info:false, + has_posix_unlink_semantics:false, has_case_sensitive_dirs:false, + has_posix_rename_semantics:false, }, }; @@ -57,8 +58,9 @@ wincaps wincap_7 __attribute__((section (".cygwin_dll_common"), shared)) = { has_unprivileged_createsymlink:false, has_unbiased_interrupt_time:true, has_precise_interrupt_time:false, - has_posix_file_info:false, + has_posix_unlink_semantics:false, has_case_sensitive_dirs:false, + has_posix_rename_semantics:false, }, }; @@ -79,8 +81,9 @@ wincaps wincap_8 __attribute__((section (".cygwin_dll_common"), shared)) = { has_unprivileged_createsymlink:false, has_unbiased_interrupt_time:true, has_precise_interrupt_time:false, - has_posix_file_info:false, + has_posix_unlink_semantics:false, has_case_sensitive_dirs:false, + has_posix_rename_semantics:false, }, }; @@ -101,8 +104,9 @@ wincaps wincap_10_1507 __attribute__((section (".cygwin_dll_common"), shared)) has_unprivileged_createsymlink:false, has_unbiased_interrupt_time:true, has_precise_interrupt_time:true, - has_posix_file_info:false, + has_posix_unlink_semantics:false, has_case_sensitive_dirs:false, + has_posix_rename_semantics:false, }, }; @@ -123,8 +127,9 @@ wincaps wincap_10_1511 __attribute__((section (".cygwin_dll_common"), shared)) = has_unprivileged_createsymlink:false, has_unbiased_interrupt_time:true, has_precise_interrupt_time:true, - has_posix_file_info:false, + has_posix_unlink_semantics:false, has_case_sensitive_dirs:false, + has_posix_rename_semantics:false, }, }; @@ -145,8 +150,9 @@ wincaps wincap_10_1703 __attribute__((section (".cygwin_dll_common"), shared)) = has_unprivileged_createsymlink:true, has_unbiased_interrupt_time:true, has_precise_interrupt_time:true, - has_posix_file_info:false, + has_posix_unlink_semantics:false, has_case_sensitive_dirs:false, + has_posix_rename_semantics:false, }, }; @@ -167,8 +173,9 @@ wincaps wincap_10_1709 __attribute__((section (".cygwin_dll_common"), shared)) = has_unprivileged_createsymlink:true, has_unbiased_interrupt_time:true, has_precise_interrupt_time:true, - has_posix_file_info:true, + has_posix_unlink_semantics:true, has_case_sensitive_dirs:false, + has_posix_rename_semantics:false, }, }; @@ -189,8 +196,32 @@ wincaps wincap_10_1803 __attribute__((section (".cygwin_dll_common"), shared)) = has_unprivileged_createsymlink:true, has_unbiased_interrupt_time:true, has_precise_interrupt_time:true, - has_posix_file_info:true, + has_posix_unlink_semantics:true, has_case_sensitive_dirs:true, + has_posix_rename_semantics:false, + }, +}; + +wincaps wincap_10_1809 __attribute__((section (".cygwin_dll_common"), shared)) = { + def_guard_pages:2, + { + is_server:false, + needs_count_in_si_lpres2:false, + has_gaa_largeaddress_bug:false, + has_broken_alloc_console:true, + has_console_logon_sid:true, + has_precise_system_time:true, + has_microsoft_accounts:true, + has_processor_groups:true, + has_broken_prefetchvm:false, + has_new_pebteb_region:true, + has_broken_whoami:false, + has_unprivileged_createsymlink:true, + has_unbiased_interrupt_time:true, + has_precise_interrupt_time:true, + has_posix_unlink_semantics:true, + has_case_sensitive_dirs:true, + has_posix_rename_semantics:true, }, }; @@ -234,7 +265,9 @@ wincapc::init () break; case 10: default: - if (likely (version.dwBuildNumber >= 17134)) + if (likely (version.dwBuildNumber >= 17763)) + caps = &wincap_10_1809; + else if (version.dwBuildNumber >= 17134) caps = &wincap_10_1803; else if (version.dwBuildNumber >= 16299) caps = &wincap_10_1709; diff --git a/winsup/cygwin/wincap.h b/winsup/cygwin/wincap.h index 967ddbdfe..d89fd71b4 100644 --- a/winsup/cygwin/wincap.h +++ b/winsup/cygwin/wincap.h @@ -29,8 +29,9 @@ struct wincaps unsigned has_unprivileged_createsymlink : 1; unsigned has_unbiased_interrupt_time : 1; unsigned has_precise_interrupt_time : 1; - unsigned has_posix_file_info : 1; + unsigned has_posix_unlink_semantics : 1; unsigned has_case_sensitive_dirs : 1; + unsigned has_posix_rename_semantics : 1; }; }; @@ -80,8 +81,9 @@ public: bool IMPLEMENT (has_unprivileged_createsymlink) bool IMPLEMENT (has_unbiased_interrupt_time) bool IMPLEMENT (has_precise_interrupt_time) - bool IMPLEMENT (has_posix_file_info) + bool IMPLEMENT (has_posix_unlink_semantics) bool IMPLEMENT (has_case_sensitive_dirs) + bool IMPLEMENT (has_posix_rename_semantics) void disable_case_sensitive_dirs () { From 837eb2af5b77a42137bf729d594fc3b80bedfcca Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Mon, 14 Jan 2019 21:57:38 +0100 Subject: [PATCH 095/475] Cygwin: document POSIX rename semantics availability with W10 1809 only Signed-off-by: Corinna Vinschen --- winsup/cygwin/release/2.12.0 | 2 +- winsup/doc/new-features.xml | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/winsup/cygwin/release/2.12.0 b/winsup/cygwin/release/2.12.0 index d739a5cb2..a0dce6ffd 100644 --- a/winsup/cygwin/release/2.12.0 +++ b/winsup/cygwin/release/2.12.0 @@ -42,7 +42,7 @@ What changed: Deleting an in-use file now actually removes the file, rather than moving it to the recycler bin. -- Use the new POSIX rename semantics on NTFS starting with Windows 10 1709. +- Use the new POSIX rename semantics on NTFS starting with Windows 10 1809. Renaming a file to another in-use file now actually removes the other file, rather than moving it to the recycler bin. diff --git a/winsup/doc/new-features.xml b/winsup/doc/new-features.xml index 5aee22b9c..d4fc74510 100644 --- a/winsup/doc/new-features.xml +++ b/winsup/doc/new-features.xml @@ -63,18 +63,18 @@ all clocks, except CLOCK_PROCESS_CPUTIME_ID and CLOCK_THREAD_CPUTIME_ID. clock_setres is a no-op now. - -Use the new POSIX rename semantics on NTFS starting with Windows 10 -1709. Renaming a file to another in-use file now actually removes the -other file, rather than moving it to the recycler bin. - - Use the new POSIX unlink semantics on NTFS starting with Windows 10 1709. Deleting an in-use file now actually removes the file, rather than moving it to the recycler bin. + +Use the new POSIX rename semantics on NTFS starting with Windows 10 +1809. Renaming a file to another in-use file now actually removes the +other file, rather than moving it to the recycler bin. + + open(..., O_TMPFILE) now moves the file to the trash bin immediately, to free the parent directory. From 704068e4f994aa98ad4eb4bfc4a2ca3324cb4a00 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Tue, 15 Jan 2019 09:58:30 +0100 Subject: [PATCH 096/475] Cygwin: signalfd: drop incorrect handling of EINTR in read(2) In case sigwait_common returns EINTR, read wrongly ignores it, so read can't be interrupt by a signal. Fix that. Signed-off-by: Corinna Vinschen --- winsup/cygwin/fhandler_signalfd.cc | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/winsup/cygwin/fhandler_signalfd.cc b/winsup/cygwin/fhandler_signalfd.cc index 1bb0d1422..1547c64cd 100644 --- a/winsup/cygwin/fhandler_signalfd.cc +++ b/winsup/cygwin/fhandler_signalfd.cc @@ -112,13 +112,11 @@ fhandler_signalfd::read (void *ptr, size_t& len) ? (PLARGE_INTEGER) &poll : NULL); if (ret == -1) { - if (curlen == 0) - { - if (get_errno () == EINTR && curlen == 0) - continue; - set_errno (old_errno); - } - len = curlen ?: (size_t) -1; + /* If we already read a signal so the buffer isn't empty, just + return success. */ + if (curlen > 0) + break; + len = -1; return; } __try From f7566c83c6a3709fd7ef6e072b8010ca28509271 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Tue, 15 Jan 2019 12:25:12 +0100 Subject: [PATCH 097/475] Cygwin: tlsoffsets64.h: regenerate Signed-off-by: Corinna Vinschen --- winsup/cygwin/tlsoffsets64.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/winsup/cygwin/tlsoffsets64.h b/winsup/cygwin/tlsoffsets64.h index 735622172..2e9d590c3 100644 --- a/winsup/cygwin/tlsoffsets64.h +++ b/winsup/cygwin/tlsoffsets64.h @@ -91,8 +91,8 @@ #define tls_psigwait_info (4144) #define tls_signal_arrived (-8648) #define tls_psignal_arrived (4152) -#define tls_sigwait_for_select (-8640) -#define tls_psigwait_for_select (4160) +#define tls_signalfd_select_wait (-8640) +#define tls_psignalfd_select_wait (4160) #define tls_will_wait_for_signal (-8632) #define tls_pwill_wait_for_signal (4168) #define tls_context (-8624) From 4d2d891b99840e4dc73f8d5f7ec45a5d616db59d Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Tue, 15 Jan 2019 13:19:41 +0100 Subject: [PATCH 098/475] Cygwin: gentls_offsets: Remove obsolte 'o' regex option Signed-off-by: Corinna Vinschen --- winsup/cygwin/gentls_offsets | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/winsup/cygwin/gentls_offsets b/winsup/cygwin/gentls_offsets index 745ea27a0..59080c331 100755 --- a/winsup/cygwin/gentls_offsets +++ b/winsup/cygwin/gentls_offsets @@ -26,21 +26,21 @@ substr($tls, 0, length($pre)) = ''; $pre .= "\n//*/"; $tls =~ s%/\*\s*gentls_offsets.*?/\*\s*gentls_offsets\s*\*/%%ogs; foreach ($tls =~ /^.*\n/mg) { - /^}|\s*(?:typedef|const)/o and do { + /^}|\s*(?:typedef|const)/ and do { $def .= $_ ; next; }; $def .= $_ if $struct; - if (!s/;.*$//o) { - if (!$struct && /^\s*(?:struct|class)\s*([a-z_0-9]+)/o) { + if (!s/;.*$//) { + if (!$struct && /^\s*(?:struct|class)\s*([a-z_0-9]+)/) { $def .= $_; $struct = $1 } next; } - s/(?:\[[^\]]*\]|struct|class)//o; - s/^\s+\S+\s+//o; - s/[\*\s()]+//go; + s/(?:\[[^\]]*\]|struct|class)//; + s/^\s+\S+\s+//; + s/[\*\s()]+//g; for my $f (split(/,/)) { push(@fields, $f); } From 1787e9d033e9e7746ced90bd6d848eb088a5b8ab Mon Sep 17 00:00:00 2001 From: Jeff Johnston Date: Tue, 15 Jan 2019 10:36:50 -0500 Subject: [PATCH 099/475] AMD GCN Port contributed by Andrew Stubbs Add support for the AMD GCN GPU architecture. This is primarily intended for use with OpenMP and OpenACC offloading. It can also be used for stand-alone programs, but this is intended mostly for testing the compiler and is not expected to be useful in general. The GPU architecture is highly parallel, and therefore Newlib must be configured to use dynamic re-entrancy, and thread-safe malloc. The only I/O available is a via a shared-memory interface provided by libgomp and the gcn-run tool included with GCC. At this time this is limited to stdout, argc/argv, and the return code. --- COPYING.NEWLIB | 14 + newlib/configure.host | 8 + newlib/libc/include/machine/ieeefp.h | 4 + newlib/libc/include/sys/config.h | 4 + newlib/libc/machine/amdgcn/Makefile.am | 15 + newlib/libc/machine/amdgcn/Makefile.in | 469 ++ newlib/libc/machine/amdgcn/abort.c | 25 + newlib/libc/machine/amdgcn/aclocal.m4 | 1012 ++++ newlib/libc/machine/amdgcn/atexit.c | 25 + newlib/libc/machine/amdgcn/configure | 4766 +++++++++++++++++++ newlib/libc/machine/amdgcn/configure.in | 14 + newlib/libc/machine/amdgcn/exit-value.h | 48 + newlib/libc/machine/amdgcn/exit.c | 23 + newlib/libc/machine/amdgcn/getreent.c | 79 + newlib/libc/machine/amdgcn/malloc_support.c | 111 + newlib/libc/machine/amdgcn/signal.c | 10 + newlib/libc/machine/configure | 7 +- newlib/libc/machine/configure.in | 1 + newlib/libc/ssp/stack_protector.c | 6 + newlib/libc/sys/amdgcn/Makefile.am | 16 + newlib/libc/sys/amdgcn/Makefile.in | 470 ++ newlib/libc/sys/amdgcn/aclocal.m4 | 1012 ++++ newlib/libc/sys/amdgcn/close.c | 24 + newlib/libc/sys/amdgcn/configure | 4766 +++++++++++++++++++ newlib/libc/sys/amdgcn/configure.in | 14 + newlib/libc/sys/amdgcn/fstat.c | 23 + newlib/libc/sys/amdgcn/isatty.c | 23 + newlib/libc/sys/amdgcn/lseek.c | 24 + newlib/libc/sys/amdgcn/read.c | 21 + newlib/libc/sys/amdgcn/write.c | 88 + newlib/libc/sys/configure | 7 +- newlib/libc/sys/configure.in | 1 + 32 files changed, 13126 insertions(+), 4 deletions(-) create mode 100644 newlib/libc/machine/amdgcn/Makefile.am create mode 100644 newlib/libc/machine/amdgcn/Makefile.in create mode 100644 newlib/libc/machine/amdgcn/abort.c create mode 100644 newlib/libc/machine/amdgcn/aclocal.m4 create mode 100644 newlib/libc/machine/amdgcn/atexit.c create mode 100755 newlib/libc/machine/amdgcn/configure create mode 100644 newlib/libc/machine/amdgcn/configure.in create mode 100644 newlib/libc/machine/amdgcn/exit-value.h create mode 100644 newlib/libc/machine/amdgcn/exit.c create mode 100644 newlib/libc/machine/amdgcn/getreent.c create mode 100644 newlib/libc/machine/amdgcn/malloc_support.c create mode 100644 newlib/libc/machine/amdgcn/signal.c create mode 100644 newlib/libc/sys/amdgcn/Makefile.am create mode 100644 newlib/libc/sys/amdgcn/Makefile.in create mode 100644 newlib/libc/sys/amdgcn/aclocal.m4 create mode 100644 newlib/libc/sys/amdgcn/close.c create mode 100755 newlib/libc/sys/amdgcn/configure create mode 100644 newlib/libc/sys/amdgcn/configure.in create mode 100644 newlib/libc/sys/amdgcn/fstat.c create mode 100644 newlib/libc/sys/amdgcn/isatty.c create mode 100644 newlib/libc/sys/amdgcn/lseek.c create mode 100644 newlib/libc/sys/amdgcn/read.c create mode 100644 newlib/libc/sys/amdgcn/write.c diff --git a/COPYING.NEWLIB b/COPYING.NEWLIB index 7242a44ac..0c39f9031 100644 --- a/COPYING.NEWLIB +++ b/COPYING.NEWLIB @@ -1179,3 +1179,17 @@ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +(51) Mentor Graphics (amdgcn-* targets) + +Copyright (c) 2014-2017 Mentor Graphics. + +The authors hereby grant permission to use, copy, modify, distribute, +and license this software and its documentation for any purpose, provided +that existing copyright notices are retained in all copies and that this +notice is included verbatim in any distributions. No written agreement, +license, or royalty fee is required for any of the authorized uses. +Modifications to this software may be copyrighted by their authors +and need not follow the licensing terms described here, provided that +the new terms are clearly indicated on the first page of each file where +they apply. + diff --git a/newlib/configure.host b/newlib/configure.host index 6c49cb750..fa805d61a 100644 --- a/newlib/configure.host +++ b/newlib/configure.host @@ -118,6 +118,10 @@ case "${host_cpu}" in machine_dir=aarch64 libm_machine_dir=aarch64 ;; + amdgcn*) + newlib_cflags="${newlib_cflags} -D__DYNAMIC_REENT__" + machine_dir=amdgcn + ;; arc*) machine_dir=arc ;; @@ -442,6 +446,10 @@ case "${host}" in aarch64*-*-*) newlib_cflags="${newlib_cflags} -D_COMPILING_NEWLIB" ;; + amdgcn*) + sys_dir=amdgcn + have_crt0="no" + ;; arm*-*-*) newlib_cflags="${newlib_cflags} -D_COMPILING_NEWLIB" sys_dir=arm diff --git a/newlib/libc/include/machine/ieeefp.h b/newlib/libc/include/machine/ieeefp.h index a40975248..911eeb51e 100644 --- a/newlib/libc/include/machine/ieeefp.h +++ b/newlib/libc/include/machine/ieeefp.h @@ -452,6 +452,10 @@ #define __IEEE_BIG_ENDIAN #endif +#ifdef __AMDGCN__ +#define __IEEE_LITTLE_ENDIAN +#endif + #ifdef __CYGWIN__ #define __OBSOLETE_MATH_DEFAULT 0 #endif diff --git a/newlib/libc/include/sys/config.h b/newlib/libc/include/sys/config.h index 49b62ebf6..d746b15fc 100644 --- a/newlib/libc/include/sys/config.h +++ b/newlib/libc/include/sys/config.h @@ -8,6 +8,10 @@ #define MALLOC_ALIGNMENT 16 #endif +#ifdef __AMDGCN__ +#define __DYNAMIC_REENT__ +#endif + /* exceptions first */ #if defined(__H8500__) || defined(__W65__) #define __SMALL_BITFIELDS diff --git a/newlib/libc/machine/amdgcn/Makefile.am b/newlib/libc/machine/amdgcn/Makefile.am new file mode 100644 index 000000000..f672115bd --- /dev/null +++ b/newlib/libc/machine/amdgcn/Makefile.am @@ -0,0 +1,15 @@ +## Process this file with automake to generate Makefile.in + +AUTOMAKE_OPTIONS = cygnus + +INCLUDES = $(NEWLIB_CFLAGS) $(CROSS_CFLAGS) $(TARGET_CFLAGS) + +AM_CCASFLAGS = $(INCLUDES) + +noinst_LIBRARIES = lib.a + +lib_a_SOURCES = abort.c exit.c atexit.c malloc_support.c getreent.c signal.c +lib_a_CFLAGS = $(AM_CFLAGS) + +ACLOCAL_AMFLAGS = -I ../../.. -I ../../../.. +CONFIG_STATUS_DEPENDENCIES = $(newlib_basedir)/configure.host diff --git a/newlib/libc/machine/amdgcn/Makefile.in b/newlib/libc/machine/amdgcn/Makefile.in new file mode 100644 index 000000000..4e51393f9 --- /dev/null +++ b/newlib/libc/machine/amdgcn/Makefile.in @@ -0,0 +1,469 @@ +# Makefile.in generated by automake 1.11.6 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software +# Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +am__make_dryrun = \ + { \ + am__dry=no; \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ + | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ + *) \ + for am__flg in $$MAKEFLAGS; do \ + case $$am__flg in \ + *=*|--*) ;; \ + *n*) am__dry=yes; break;; \ + esac; \ + done;; \ + esac; \ + test $$am__dry = yes; \ + } +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = . +DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ + $(top_srcdir)/configure $(am__configure_deps) \ + $(srcdir)/../../../../mkinstalldirs +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/../../../acinclude.m4 \ + $(top_srcdir)/configure.in +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ + configure.lineno config.status.lineno +mkinstalldirs = $(SHELL) $(top_srcdir)/../../../../mkinstalldirs +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +LIBRARIES = $(noinst_LIBRARIES) +ARFLAGS = cru +lib_a_AR = $(AR) $(ARFLAGS) +lib_a_LIBADD = +am_lib_a_OBJECTS = lib_a-abort.$(OBJEXT) lib_a-exit.$(OBJEXT) \ + lib_a-atexit.$(OBJEXT) lib_a-malloc_support.$(OBJEXT) \ + lib_a-getreent.$(OBJEXT) lib_a-signal.$(OBJEXT) +lib_a_OBJECTS = $(am_lib_a_OBJECTS) +DEFAULT_INCLUDES = -I.@am__isrc@ +depcomp = +am__depfiles_maybe = +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +SOURCES = $(lib_a_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +ETAGS = etags +CTAGS = ctags +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCAS = @CCAS@ +CCASFLAGS = @CCASFLAGS@ +CCDEPMODE = @CCDEPMODE@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +NEWLIB_CFLAGS = @NEWLIB_CFLAGS@ +NO_INCLUDE_LIST = @NO_INCLUDE_LIST@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +READELF = @READELF@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +aext = @aext@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +libm_machine_dir = @libm_machine_dir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +lpfx = @lpfx@ +machine_dir = @machine_dir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +newlib_basedir = @newlib_basedir@ +oext = @oext@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sys_dir = @sys_dir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +AUTOMAKE_OPTIONS = cygnus +INCLUDES = $(NEWLIB_CFLAGS) $(CROSS_CFLAGS) $(TARGET_CFLAGS) +AM_CCASFLAGS = $(INCLUDES) +noinst_LIBRARIES = lib.a +lib_a_SOURCES = abort.c exit.c atexit.c malloc_support.c getreent.c signal.c +lib_a_CFLAGS = $(AM_CFLAGS) +ACLOCAL_AMFLAGS = -I ../../.. -I ../../../.. +CONFIG_STATUS_DEPENDENCIES = $(newlib_basedir)/configure.host +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .o .obj +am--refresh: Makefile + @: +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + echo ' cd $(srcdir) && $(AUTOMAKE) --cygnus'; \ + $(am__cd) $(srcdir) && $(AUTOMAKE) --cygnus \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --cygnus Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --cygnus Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + echo ' $(SHELL) ./config.status'; \ + $(SHELL) ./config.status;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + $(SHELL) ./config.status --recheck + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + $(am__cd) $(srcdir) && $(AUTOCONF) +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) +$(am__aclocal_m4_deps): + +clean-noinstLIBRARIES: + -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) +lib.a: $(lib_a_OBJECTS) $(lib_a_DEPENDENCIES) $(EXTRA_lib_a_DEPENDENCIES) + -rm -f lib.a + $(lib_a_AR) lib.a $(lib_a_OBJECTS) $(lib_a_LIBADD) + $(RANLIB) lib.a + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +.c.o: + $(COMPILE) -c $< + +.c.obj: + $(COMPILE) -c `$(CYGPATH_W) '$<'` + +lib_a-abort.o: abort.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-abort.o `test -f 'abort.c' || echo '$(srcdir)/'`abort.c + +lib_a-abort.obj: abort.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-abort.obj `if test -f 'abort.c'; then $(CYGPATH_W) 'abort.c'; else $(CYGPATH_W) '$(srcdir)/abort.c'; fi` + +lib_a-exit.o: exit.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-exit.o `test -f 'exit.c' || echo '$(srcdir)/'`exit.c + +lib_a-exit.obj: exit.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-exit.obj `if test -f 'exit.c'; then $(CYGPATH_W) 'exit.c'; else $(CYGPATH_W) '$(srcdir)/exit.c'; fi` + +lib_a-atexit.o: atexit.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-atexit.o `test -f 'atexit.c' || echo '$(srcdir)/'`atexit.c + +lib_a-atexit.obj: atexit.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-atexit.obj `if test -f 'atexit.c'; then $(CYGPATH_W) 'atexit.c'; else $(CYGPATH_W) '$(srcdir)/atexit.c'; fi` + +lib_a-malloc_support.o: malloc_support.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-malloc_support.o `test -f 'malloc_support.c' || echo '$(srcdir)/'`malloc_support.c + +lib_a-malloc_support.obj: malloc_support.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-malloc_support.obj `if test -f 'malloc_support.c'; then $(CYGPATH_W) 'malloc_support.c'; else $(CYGPATH_W) '$(srcdir)/malloc_support.c'; fi` + +lib_a-getreent.o: getreent.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-getreent.o `test -f 'getreent.c' || echo '$(srcdir)/'`getreent.c + +lib_a-getreent.obj: getreent.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-getreent.obj `if test -f 'getreent.c'; then $(CYGPATH_W) 'getreent.c'; else $(CYGPATH_W) '$(srcdir)/getreent.c'; fi` + +lib_a-signal.o: signal.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-signal.o `test -f 'signal.c' || echo '$(srcdir)/'`signal.c + +lib_a-signal.obj: signal.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-signal.obj `if test -f 'signal.c'; then $(CYGPATH_W) 'signal.c'; else $(CYGPATH_W) '$(srcdir)/signal.c'; fi` + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags +check-am: +check: check-am +all-am: Makefile $(LIBRARIES) +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-noinstLIBRARIES mostlyclean-am + +distclean: distclean-am + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -rf $(top_srcdir)/autom4te.cache + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am am--refresh check check-am clean \ + clean-generic clean-noinstLIBRARIES ctags distclean \ + distclean-compile distclean-generic distclean-tags dvi dvi-am \ + html html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-pdf install-pdf-am \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \ + uninstall-am + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/newlib/libc/machine/amdgcn/abort.c b/newlib/libc/machine/amdgcn/abort.c new file mode 100644 index 000000000..ccbca726a --- /dev/null +++ b/newlib/libc/machine/amdgcn/abort.c @@ -0,0 +1,25 @@ +/* + * Support file for amdgcn in newlib. + * Copyright (c) 2014-2017 Mentor Graphics. + * + * The authors hereby grant permission to use, copy, modify, distribute, + * and license this software and its documentation for any purpose, provided + * that existing copyright notices are retained in all copies and that this + * notice is included verbatim in any distributions. No written agreement, + * license, or royalty fee is required for any of the authorized uses. + * Modifications to this software may be copyrighted by their authors + * and need not follow the licensing terms described here, provided that + * the new terms are clearly indicated on the first page of each file where + * they apply. + */ + +#include +#include +#include "exit-value.h" + +void __attribute__((noreturn)) +abort (void) +{ + write (2, "GCN Kernel Aborted\n", 19); + exit_with_status_and_signal (0, SIGABRT); +} diff --git a/newlib/libc/machine/amdgcn/aclocal.m4 b/newlib/libc/machine/amdgcn/aclocal.m4 new file mode 100644 index 000000000..18dab02aa --- /dev/null +++ b/newlib/libc/machine/amdgcn/aclocal.m4 @@ -0,0 +1,1012 @@ +# generated automatically by aclocal 1.11.6 -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, +# 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, +# Inc. +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +m4_ifndef([AC_AUTOCONF_VERSION], + [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl +m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.68],, +[m4_warning([this file was generated for autoconf 2.68. +You have another version of autoconf. It may work, but is not guaranteed to. +If you have problems, you may need to regenerate the build system entirely. +To do so, use the procedure documented by the package, typically `autoreconf'.])]) + +# Copyright (C) 2002, 2003, 2005, 2006, 2007, 2008, 2011 Free Software +# Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 1 + +# AM_AUTOMAKE_VERSION(VERSION) +# ---------------------------- +# Automake X.Y traces this macro to ensure aclocal.m4 has been +# generated from the m4 files accompanying Automake X.Y. +# (This private macro should not be called outside this file.) +AC_DEFUN([AM_AUTOMAKE_VERSION], +[am__api_version='1.11' +dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to +dnl require some minimum version. Point them to the right macro. +m4_if([$1], [1.11.6], [], + [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl +]) + +# _AM_AUTOCONF_VERSION(VERSION) +# ----------------------------- +# aclocal traces this macro to find the Autoconf version. +# This is a private macro too. Using m4_define simplifies +# the logic in aclocal, which can simply ignore this definition. +m4_define([_AM_AUTOCONF_VERSION], []) + +# AM_SET_CURRENT_AUTOMAKE_VERSION +# ------------------------------- +# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. +# This function is AC_REQUIREd by AM_INIT_AUTOMAKE. +AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], +[AM_AUTOMAKE_VERSION([1.11.6])dnl +m4_ifndef([AC_AUTOCONF_VERSION], + [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl +_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) + +# AM_AUX_DIR_EXPAND -*- Autoconf -*- + +# Copyright (C) 2001, 2003, 2005, 2011 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 1 + +# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets +# $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to +# `$srcdir', `$srcdir/..', or `$srcdir/../..'. +# +# Of course, Automake must honor this variable whenever it calls a +# tool from the auxiliary directory. The problem is that $srcdir (and +# therefore $ac_aux_dir as well) can be either absolute or relative, +# depending on how configure is run. This is pretty annoying, since +# it makes $ac_aux_dir quite unusable in subdirectories: in the top +# source directory, any form will work fine, but in subdirectories a +# relative path needs to be adjusted first. +# +# $ac_aux_dir/missing +# fails when called from a subdirectory if $ac_aux_dir is relative +# $top_srcdir/$ac_aux_dir/missing +# fails if $ac_aux_dir is absolute, +# fails when called from a subdirectory in a VPATH build with +# a relative $ac_aux_dir +# +# The reason of the latter failure is that $top_srcdir and $ac_aux_dir +# are both prefixed by $srcdir. In an in-source build this is usually +# harmless because $srcdir is `.', but things will broke when you +# start a VPATH build or use an absolute $srcdir. +# +# So we could use something similar to $top_srcdir/$ac_aux_dir/missing, +# iff we strip the leading $srcdir from $ac_aux_dir. That would be: +# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` +# and then we would define $MISSING as +# MISSING="\${SHELL} $am_aux_dir/missing" +# This will work as long as MISSING is not called from configure, because +# unfortunately $(top_srcdir) has no meaning in configure. +# However there are other variables, like CC, which are often used in +# configure, and could therefore not use this "fixed" $ac_aux_dir. +# +# Another solution, used here, is to always expand $ac_aux_dir to an +# absolute PATH. The drawback is that using absolute paths prevent a +# configured tree to be moved without reconfiguration. + +AC_DEFUN([AM_AUX_DIR_EXPAND], +[dnl Rely on autoconf to set up CDPATH properly. +AC_PREREQ([2.50])dnl +# expand $ac_aux_dir to an absolute path +am_aux_dir=`cd $ac_aux_dir && pwd` +]) + +# AM_CONDITIONAL -*- Autoconf -*- + +# Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005, 2006, 2008 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 9 + +# AM_CONDITIONAL(NAME, SHELL-CONDITION) +# ------------------------------------- +# Define a conditional. +AC_DEFUN([AM_CONDITIONAL], +[AC_PREREQ(2.52)dnl + ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], + [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl +AC_SUBST([$1_TRUE])dnl +AC_SUBST([$1_FALSE])dnl +_AM_SUBST_NOTMAKE([$1_TRUE])dnl +_AM_SUBST_NOTMAKE([$1_FALSE])dnl +m4_define([_AM_COND_VALUE_$1], [$2])dnl +if $2; then + $1_TRUE= + $1_FALSE='#' +else + $1_TRUE='#' + $1_FALSE= +fi +AC_CONFIG_COMMANDS_PRE( +[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then + AC_MSG_ERROR([[conditional "$1" was never defined. +Usually this means the macro was only invoked conditionally.]]) +fi])]) + +# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2009, +# 2010, 2011 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 12 + +# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be +# written in clear, in which case automake, when reading aclocal.m4, +# will think it sees a *use*, and therefore will trigger all it's +# C support machinery. Also note that it means that autoscan, seeing +# CC etc. in the Makefile, will ask for an AC_PROG_CC use... + + +# _AM_DEPENDENCIES(NAME) +# ---------------------- +# See how the compiler implements dependency checking. +# NAME is "CC", "CXX", "GCJ", or "OBJC". +# We try a few techniques and use that to set a single cache variable. +# +# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was +# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular +# dependency, and given that the user is not expected to run this macro, +# just rely on AC_PROG_CC. +AC_DEFUN([_AM_DEPENDENCIES], +[AC_REQUIRE([AM_SET_DEPDIR])dnl +AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl +AC_REQUIRE([AM_MAKE_INCLUDE])dnl +AC_REQUIRE([AM_DEP_TRACK])dnl + +ifelse([$1], CC, [depcc="$CC" am_compiler_list=], + [$1], CXX, [depcc="$CXX" am_compiler_list=], + [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'], + [$1], UPC, [depcc="$UPC" am_compiler_list=], + [$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'], + [depcc="$$1" am_compiler_list=]) + +AC_CACHE_CHECK([dependency style of $depcc], + [am_cv_$1_dependencies_compiler_type], +[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named `D' -- because `-MD' means `put the output + # in D'. + rm -rf conftest.dir + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_$1_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` + fi + am__universal=false + m4_case([$1], [CC], + [case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac], + [CXX], + [case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac]) + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with + # Solaris 8's {/usr,}/bin/sh. + touch sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with `-c' and `-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle `-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # after this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvc7 | msvc7msys | msvisualcpp | msvcmsys) + # This compiler won't grok `-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_$1_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_$1_dependencies_compiler_type=none +fi +]) +AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) +AM_CONDITIONAL([am__fastdep$1], [ + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) +]) + + +# AM_SET_DEPDIR +# ------------- +# Choose a directory name for dependency files. +# This macro is AC_REQUIREd in _AM_DEPENDENCIES +AC_DEFUN([AM_SET_DEPDIR], +[AC_REQUIRE([AM_SET_LEADING_DOT])dnl +AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl +]) + + +# AM_DEP_TRACK +# ------------ +AC_DEFUN([AM_DEP_TRACK], +[AC_ARG_ENABLE(dependency-tracking, +[ --disable-dependency-tracking speeds up one-time build + --enable-dependency-tracking do not reject slow dependency extractors]) +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' + am__nodep='_no' +fi +AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) +AC_SUBST([AMDEPBACKSLASH])dnl +_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl +AC_SUBST([am__nodep])dnl +_AM_SUBST_NOTMAKE([am__nodep])dnl +]) + +# Generate code to set up dependency tracking. -*- Autoconf -*- + +# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2008 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +#serial 5 + +# _AM_OUTPUT_DEPENDENCY_COMMANDS +# ------------------------------ +AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], +[{ + # Autoconf 2.62 quotes --file arguments for eval, but not when files + # are listed without --file. Let's play safe and only enable the eval + # if we detect the quoting. + case $CONFIG_FILES in + *\'*) eval set x "$CONFIG_FILES" ;; + *) set x $CONFIG_FILES ;; + esac + shift + for mf + do + # Strip MF so we end up with the name of the file. + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named `Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # Grep'ing the whole file is not good either: AIX grep has a line + # limit of 2048, but all sed's we know have understand at least 4000. + if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then + dirpart=`AS_DIRNAME("$mf")` + else + continue + fi + # Extract the definition of DEPDIR, am__include, and am__quote + # from the Makefile without running `make'. + DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` + test -z "$DEPDIR" && continue + am__include=`sed -n 's/^am__include = //p' < "$mf"` + test -z "am__include" && continue + am__quote=`sed -n 's/^am__quote = //p' < "$mf"` + # When using ansi2knr, U may be empty or an underscore; expand it + U=`sed -n 's/^U = //p' < "$mf"` + # Find all dependency output files, they are included files with + # $(DEPDIR) in their names. We invoke sed twice because it is the + # simplest approach to changing $(DEPDIR) to its actual value in the + # expansion. + for file in `sed -n " + s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do + # Make sure the directory exists. + test -f "$dirpart/$file" && continue + fdir=`AS_DIRNAME(["$file"])` + AS_MKDIR_P([$dirpart/$fdir]) + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done + done +} +])# _AM_OUTPUT_DEPENDENCY_COMMANDS + + +# AM_OUTPUT_DEPENDENCY_COMMANDS +# ----------------------------- +# This macro should only be invoked once -- use via AC_REQUIRE. +# +# This code is only required when automatic dependency tracking +# is enabled. FIXME. This creates each `.P' file that we will +# need in order to bootstrap the dependency handling code. +AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], +[AC_CONFIG_COMMANDS([depfiles], + [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], + [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) +]) + +# Do all the work for Automake. -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, +# 2005, 2006, 2008, 2009 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 16 + +# This macro actually does too much. Some checks are only needed if +# your package does certain things. But this isn't really a big deal. + +# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) +# AM_INIT_AUTOMAKE([OPTIONS]) +# ----------------------------------------------- +# The call with PACKAGE and VERSION arguments is the old style +# call (pre autoconf-2.50), which is being phased out. PACKAGE +# and VERSION should now be passed to AC_INIT and removed from +# the call to AM_INIT_AUTOMAKE. +# We support both call styles for the transition. After +# the next Automake release, Autoconf can make the AC_INIT +# arguments mandatory, and then we can depend on a new Autoconf +# release and drop the old call support. +AC_DEFUN([AM_INIT_AUTOMAKE], +[AC_PREREQ([2.62])dnl +dnl Autoconf wants to disallow AM_ names. We explicitly allow +dnl the ones we care about. +m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl +AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl +AC_REQUIRE([AC_PROG_INSTALL])dnl +if test "`cd $srcdir && pwd`" != "`pwd`"; then + # Use -I$(srcdir) only when $(srcdir) != ., so that make's output + # is not polluted with repeated "-I." + AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl + # test to see if srcdir already configured + if test -f $srcdir/config.status; then + AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) + fi +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi +AC_SUBST([CYGPATH_W]) + +# Define the identity of the package. +dnl Distinguish between old-style and new-style calls. +m4_ifval([$2], +[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl + AC_SUBST([PACKAGE], [$1])dnl + AC_SUBST([VERSION], [$2])], +[_AM_SET_OPTIONS([$1])dnl +dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. +m4_if(m4_ifdef([AC_PACKAGE_NAME], 1)m4_ifdef([AC_PACKAGE_VERSION], 1), 11,, + [m4_fatal([AC_INIT should be called with package and version arguments])])dnl + AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl + AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl + +_AM_IF_OPTION([no-define],, +[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) + AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl + +# Some tools Automake needs. +AC_REQUIRE([AM_SANITY_CHECK])dnl +AC_REQUIRE([AC_ARG_PROGRAM])dnl +AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version}) +AM_MISSING_PROG(AUTOCONF, autoconf) +AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version}) +AM_MISSING_PROG(AUTOHEADER, autoheader) +AM_MISSING_PROG(MAKEINFO, makeinfo) +AC_REQUIRE([AM_PROG_INSTALL_SH])dnl +AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl +AC_REQUIRE([AM_PROG_MKDIR_P])dnl +# We need awk for the "check" target. The system "awk" is bad on +# some platforms. +AC_REQUIRE([AC_PROG_AWK])dnl +AC_REQUIRE([AC_PROG_MAKE_SET])dnl +AC_REQUIRE([AM_SET_LEADING_DOT])dnl +_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], + [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], + [_AM_PROG_TAR([v7])])]) +_AM_IF_OPTION([no-dependencies],, +[AC_PROVIDE_IFELSE([AC_PROG_CC], + [_AM_DEPENDENCIES(CC)], + [define([AC_PROG_CC], + defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl +AC_PROVIDE_IFELSE([AC_PROG_CXX], + [_AM_DEPENDENCIES(CXX)], + [define([AC_PROG_CXX], + defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl +AC_PROVIDE_IFELSE([AC_PROG_OBJC], + [_AM_DEPENDENCIES(OBJC)], + [define([AC_PROG_OBJC], + defn([AC_PROG_OBJC])[_AM_DEPENDENCIES(OBJC)])])dnl +]) +_AM_IF_OPTION([silent-rules], [AC_REQUIRE([AM_SILENT_RULES])])dnl +dnl The `parallel-tests' driver may need to know about EXEEXT, so add the +dnl `am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This macro +dnl is hooked onto _AC_COMPILER_EXEEXT early, see below. +AC_CONFIG_COMMANDS_PRE(dnl +[m4_provide_if([_AM_COMPILER_EXEEXT], + [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl +]) + +dnl Hook into `_AC_COMPILER_EXEEXT' early to learn its expansion. Do not +dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further +dnl mangled by Autoconf and run in a shell conditional statement. +m4_define([_AC_COMPILER_EXEEXT], +m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])]) + + +# When config.status generates a header, we must update the stamp-h file. +# This file resides in the same directory as the config header +# that is generated. The stamp files are numbered to have different names. + +# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the +# loop where config.status creates the headers, so we can generate +# our stamp files there. +AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], +[# Compute $1's index in $config_headers. +_am_arg=$1 +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $_am_arg | $_am_arg:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) + +# Copyright (C) 2001, 2003, 2005, 2008, 2011 Free Software Foundation, +# Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 1 + +# AM_PROG_INSTALL_SH +# ------------------ +# Define $install_sh. +AC_DEFUN([AM_PROG_INSTALL_SH], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +if test x"${install_sh}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; + *) + install_sh="\${SHELL} $am_aux_dir/install-sh" + esac +fi +AC_SUBST(install_sh)]) + +# Copyright (C) 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 2 + +# Check whether the underlying file-system supports filenames +# with a leading dot. For instance MS-DOS doesn't. +AC_DEFUN([AM_SET_LEADING_DOT], +[rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null +AC_SUBST([am__leading_dot])]) + +# Add --enable-maintainer-mode option to configure. -*- Autoconf -*- +# From Jim Meyering + +# Copyright (C) 1996, 1998, 2000, 2001, 2002, 2003, 2004, 2005, 2008, +# 2011 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 5 + +# AM_MAINTAINER_MODE([DEFAULT-MODE]) +# ---------------------------------- +# Control maintainer-specific portions of Makefiles. +# Default is to disable them, unless `enable' is passed literally. +# For symmetry, `disable' may be passed as well. Anyway, the user +# can override the default with the --enable/--disable switch. +AC_DEFUN([AM_MAINTAINER_MODE], +[m4_case(m4_default([$1], [disable]), + [enable], [m4_define([am_maintainer_other], [disable])], + [disable], [m4_define([am_maintainer_other], [enable])], + [m4_define([am_maintainer_other], [enable]) + m4_warn([syntax], [unexpected argument to AM@&t@_MAINTAINER_MODE: $1])]) +AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles]) + dnl maintainer-mode's default is 'disable' unless 'enable' is passed + AC_ARG_ENABLE([maintainer-mode], +[ --][am_maintainer_other][-maintainer-mode am_maintainer_other make rules and dependencies not useful + (and sometimes confusing) to the casual installer], + [USE_MAINTAINER_MODE=$enableval], + [USE_MAINTAINER_MODE=]m4_if(am_maintainer_other, [enable], [no], [yes])) + AC_MSG_RESULT([$USE_MAINTAINER_MODE]) + AM_CONDITIONAL([MAINTAINER_MODE], [test $USE_MAINTAINER_MODE = yes]) + MAINT=$MAINTAINER_MODE_TRUE + AC_SUBST([MAINT])dnl +] +) + +AU_DEFUN([jm_MAINTAINER_MODE], [AM_MAINTAINER_MODE]) + +# Check to see how 'make' treats includes. -*- Autoconf -*- + +# Copyright (C) 2001, 2002, 2003, 2005, 2009 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 4 + +# AM_MAKE_INCLUDE() +# ----------------- +# Check to see how make treats includes. +AC_DEFUN([AM_MAKE_INCLUDE], +[am_make=${MAKE-make} +cat > confinc << 'END' +am__doit: + @echo this is the am__doit target +.PHONY: am__doit +END +# If we don't find an include directive, just comment out the code. +AC_MSG_CHECKING([for style of include used by $am_make]) +am__include="#" +am__quote= +_am_result=none +# First try GNU make style include. +echo "include confinc" > confmf +# Ignore all kinds of additional output from `make'. +case `$am_make -s -f confmf 2> /dev/null` in #( +*the\ am__doit\ target*) + am__include=include + am__quote= + _am_result=GNU + ;; +esac +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + case `$am_make -s -f confmf 2> /dev/null` in #( + *the\ am__doit\ target*) + am__include=.include + am__quote="\"" + _am_result=BSD + ;; + esac +fi +AC_SUBST([am__include]) +AC_SUBST([am__quote]) +AC_MSG_RESULT([$_am_result]) +rm -f confinc confmf +]) + +# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- + +# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2004, 2005, 2008 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 6 + +# AM_MISSING_PROG(NAME, PROGRAM) +# ------------------------------ +AC_DEFUN([AM_MISSING_PROG], +[AC_REQUIRE([AM_MISSING_HAS_RUN]) +$1=${$1-"${am_missing_run}$2"} +AC_SUBST($1)]) + + +# AM_MISSING_HAS_RUN +# ------------------ +# Define MISSING if not defined so far and test if it supports --run. +# If it does, set am_missing_run to use it, otherwise, to nothing. +AC_DEFUN([AM_MISSING_HAS_RUN], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +AC_REQUIRE_AUX_FILE([missing])dnl +if test x"${MISSING+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; + *) + MISSING="\${SHELL} $am_aux_dir/missing" ;; + esac +fi +# Use eval to expand $SHELL +if eval "$MISSING --run true"; then + am_missing_run="$MISSING --run " +else + am_missing_run= + AC_MSG_WARN([`missing' script is too old or missing]) +fi +]) + +# Copyright (C) 2003, 2004, 2005, 2006, 2011 Free Software Foundation, +# Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 1 + +# AM_PROG_MKDIR_P +# --------------- +# Check for `mkdir -p'. +AC_DEFUN([AM_PROG_MKDIR_P], +[AC_PREREQ([2.60])dnl +AC_REQUIRE([AC_PROG_MKDIR_P])dnl +dnl Automake 1.8 to 1.9.6 used to define mkdir_p. We now use MKDIR_P, +dnl while keeping a definition of mkdir_p for backward compatibility. +dnl @MKDIR_P@ is magic: AC_OUTPUT adjusts its value for each Makefile. +dnl However we cannot define mkdir_p as $(MKDIR_P) for the sake of +dnl Makefile.ins that do not define MKDIR_P, so we do our own +dnl adjustment using top_builddir (which is defined more often than +dnl MKDIR_P). +AC_SUBST([mkdir_p], ["$MKDIR_P"])dnl +case $mkdir_p in + [[\\/$]]* | ?:[[\\/]]*) ;; + */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; +esac +]) + +# Helper functions for option handling. -*- Autoconf -*- + +# Copyright (C) 2001, 2002, 2003, 2005, 2008, 2010 Free Software +# Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 5 + +# _AM_MANGLE_OPTION(NAME) +# ----------------------- +AC_DEFUN([_AM_MANGLE_OPTION], +[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) + +# _AM_SET_OPTION(NAME) +# -------------------- +# Set option NAME. Presently that only means defining a flag for this option. +AC_DEFUN([_AM_SET_OPTION], +[m4_define(_AM_MANGLE_OPTION([$1]), 1)]) + +# _AM_SET_OPTIONS(OPTIONS) +# ------------------------ +# OPTIONS is a space-separated list of Automake options. +AC_DEFUN([_AM_SET_OPTIONS], +[m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) + +# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) +# ------------------------------------------- +# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. +AC_DEFUN([_AM_IF_OPTION], +[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) + +# Check to make sure that the build environment is sane. -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005, 2008 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 5 + +# AM_SANITY_CHECK +# --------------- +AC_DEFUN([AM_SANITY_CHECK], +[AC_MSG_CHECKING([whether build environment is sane]) +# Just in case +sleep 1 +echo timestamp > conftest.file +# Reject unsafe characters in $srcdir or the absolute working directory +# name. Accept space and tab only in the latter. +am_lf=' +' +case `pwd` in + *[[\\\"\#\$\&\'\`$am_lf]]*) + AC_MSG_ERROR([unsafe absolute working directory name]);; +esac +case $srcdir in + *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*) + AC_MSG_ERROR([unsafe srcdir value: `$srcdir']);; +esac + +# Do `set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` + if test "$[*]" = "X"; then + # -L didn't work. + set X `ls -t "$srcdir/configure" conftest.file` + fi + rm -f conftest.file + if test "$[*]" != "X $srcdir/configure conftest.file" \ + && test "$[*]" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken +alias in your environment]) + fi + + test "$[2]" = conftest.file + ) +then + # Ok. + : +else + AC_MSG_ERROR([newly created file is older than distributed files! +Check your system clock]) +fi +AC_MSG_RESULT(yes)]) + +# Copyright (C) 2001, 2003, 2005, 2011 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 1 + +# AM_PROG_INSTALL_STRIP +# --------------------- +# One issue with vendor `install' (even GNU) is that you can't +# specify the program used to strip binaries. This is especially +# annoying in cross-compiling environments, where the build's strip +# is unlikely to handle the host's binaries. +# Fortunately install-sh will honor a STRIPPROG variable, so we +# always use install-sh in `make install-strip', and initialize +# STRIPPROG with the value of the STRIP variable (set by the user). +AC_DEFUN([AM_PROG_INSTALL_STRIP], +[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl +# Installed binaries are usually stripped using `strip' when the user +# run `make install-strip'. However `strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the `STRIP' environment variable to overrule this program. +dnl Don't test for $cross_compiling = yes, because it might be `maybe'. +if test "$cross_compiling" != no; then + AC_CHECK_TOOL([STRIP], [strip], :) +fi +INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" +AC_SUBST([INSTALL_STRIP_PROGRAM])]) + +# Copyright (C) 2006, 2008, 2010 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 3 + +# _AM_SUBST_NOTMAKE(VARIABLE) +# --------------------------- +# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. +# This macro is traced by Automake. +AC_DEFUN([_AM_SUBST_NOTMAKE]) + +# AM_SUBST_NOTMAKE(VARIABLE) +# -------------------------- +# Public sister of _AM_SUBST_NOTMAKE. +AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) + +# Check how to create a tarball. -*- Autoconf -*- + +# Copyright (C) 2004, 2005, 2012 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 2 + +# _AM_PROG_TAR(FORMAT) +# -------------------- +# Check how to create a tarball in format FORMAT. +# FORMAT should be one of `v7', `ustar', or `pax'. +# +# Substitute a variable $(am__tar) that is a command +# writing to stdout a FORMAT-tarball containing the directory +# $tardir. +# tardir=directory && $(am__tar) > result.tar +# +# Substitute a variable $(am__untar) that extract such +# a tarball read from stdin. +# $(am__untar) < result.tar +AC_DEFUN([_AM_PROG_TAR], +[# Always define AMTAR for backward compatibility. Yes, it's still used +# in the wild :-( We should find a proper way to deprecate it ... +AC_SUBST([AMTAR], ['$${TAR-tar}']) +m4_if([$1], [v7], + [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'], + [m4_case([$1], [ustar],, [pax],, + [m4_fatal([Unknown tar format])]) +AC_MSG_CHECKING([how to create a $1 tar archive]) +# Loop over all known methods to create a tar archive until one works. +_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' +_am_tools=${am_cv_prog_tar_$1-$_am_tools} +# Do not fold the above two line into one, because Tru64 sh and +# Solaris sh will not grok spaces in the rhs of `-'. +for _am_tool in $_am_tools +do + case $_am_tool in + gnutar) + for _am_tar in tar gnutar gtar; + do + AM_RUN_LOG([$_am_tar --version]) && break + done + am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' + am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' + am__untar="$_am_tar -xf -" + ;; + plaintar) + # Must skip GNU tar: if it does not support --format= it doesn't create + # ustar tarball either. + (tar --version) >/dev/null 2>&1 && continue + am__tar='tar chf - "$$tardir"' + am__tar_='tar chf - "$tardir"' + am__untar='tar xf -' + ;; + pax) + am__tar='pax -L -x $1 -w "$$tardir"' + am__tar_='pax -L -x $1 -w "$tardir"' + am__untar='pax -r' + ;; + cpio) + am__tar='find "$$tardir" -print | cpio -o -H $1 -L' + am__tar_='find "$tardir" -print | cpio -o -H $1 -L' + am__untar='cpio -i -H $1 -d' + ;; + none) + am__tar=false + am__tar_=false + am__untar=false + ;; + esac + + # If the value was cached, stop now. We just wanted to have am__tar + # and am__untar set. + test -n "${am_cv_prog_tar_$1}" && break + + # tar/untar a dummy directory, and stop if the command works + rm -rf conftest.dir + mkdir conftest.dir + echo GrepMe > conftest.dir/file + AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) + rm -rf conftest.dir + if test -s conftest.tar; then + AM_RUN_LOG([$am__untar /dev/null 2>&1 && break + fi +done +rm -rf conftest.dir + +AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) +AC_MSG_RESULT([$am_cv_prog_tar_$1])]) +AC_SUBST([am__tar]) +AC_SUBST([am__untar]) +]) # _AM_PROG_TAR + +m4_include([../../../acinclude.m4]) diff --git a/newlib/libc/machine/amdgcn/atexit.c b/newlib/libc/machine/amdgcn/atexit.c new file mode 100644 index 000000000..674571435 --- /dev/null +++ b/newlib/libc/machine/amdgcn/atexit.c @@ -0,0 +1,25 @@ +/* + * Support file for amdgcn in newlib. + * Copyright (c) 2014-2017 Mentor Graphics. + * + * The authors hereby grant permission to use, copy, modify, distribute, + * and license this software and its documentation for any purpose, provided + * that existing copyright notices are retained in all copies and that this + * notice is included verbatim in any distributions. No written agreement, + * license, or royalty fee is required for any of the authorized uses. + * Modifications to this software may be copyrighted by their authors + * and need not follow the licensing terms described here, provided that + * the new terms are clearly indicated on the first page of each file where + * they apply. + */ + +#include + +int +atexit (void (*function)(void)) +{ + /* Our current implementation of exit does not run functions registered with + atexit, so fail here. */ + abort (); + return 1; +} diff --git a/newlib/libc/machine/amdgcn/configure b/newlib/libc/machine/amdgcn/configure new file mode 100755 index 000000000..24feba10f --- /dev/null +++ b/newlib/libc/machine/amdgcn/configure @@ -0,0 +1,4766 @@ +#! /bin/sh +# Guess values for system-dependent variables and create Makefiles. +# Generated by GNU Autoconf 2.68 for newlib 3.1.0. +# +# +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, +# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software +# Foundation, Inc. +# +# +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +if test "x$CONFIG_SHELL" = x; then + as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which + # is contrary to our usage. Disable this feature. + alias -g '\${1+\"\$@\"}'='\"\$@\"' + setopt NO_GLOB_SUBST +else + case \`(set -o) 2>/dev/null\` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi +" + as_required="as_fn_return () { (exit \$1); } +as_fn_success () { as_fn_return 0; } +as_fn_failure () { as_fn_return 1; } +as_fn_ret_success () { return 0; } +as_fn_ret_failure () { return 1; } + +exitcode=0 +as_fn_success || { exitcode=1; echo as_fn_success failed.; } +as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } +as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } +as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } +if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : + +else + exitcode=1; echo positional parameters were not saved. +fi +test x\$exitcode = x0 || exit 1" + as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO + as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO + eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && + test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1" + if (eval "$as_required") 2>/dev/null; then : + as_have_required=yes +else + as_have_required=no +fi + if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : + +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +as_found=false +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + as_found=: + case $as_dir in #( + /*) + for as_base in sh bash ksh sh5; do + # Try only shells that exist, to save several forks. + as_shell=$as_dir/$as_base + if { test -f "$as_shell" || test -f "$as_shell.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : + CONFIG_SHELL=$as_shell as_have_required=yes + if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : + break 2 +fi +fi + done;; + esac + as_found=false +done +$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : + CONFIG_SHELL=$SHELL as_have_required=yes +fi; } +IFS=$as_save_IFS + + + if test "x$CONFIG_SHELL" != x; then : + # We cannot yet assume a decent shell, so we have to provide a + # neutralization value for shells without unset; and this also + # works around shells that cannot unset nonexistent variables. + # Preserve -v and -x to the replacement shell. + BASH_ENV=/dev/null + ENV=/dev/null + (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV + export CONFIG_SHELL + case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; + esac + exec "$CONFIG_SHELL" $as_opts "$as_myself" ${1+"$@"} +fi + + if test x$as_have_required = xno; then : + $as_echo "$0: This script requires a shell more modern than all" + $as_echo "$0: the shells that I found on your system." + if test x${ZSH_VERSION+set} = xset ; then + $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" + $as_echo "$0: be upgraded to zsh 4.3.4 or later." + else + $as_echo "$0: Please tell bug-autoconf@gnu.org about your system, +$0: including any error possibly output before this +$0: message. Then install a modern shell, or manually run +$0: the script under such a shell if you do have one." + fi + exit 1 +fi +fi +fi +SHELL=${CONFIG_SHELL-/bin/sh} +export SHELL +# Unset more variables known to interfere with behavior of common tools. +CLICOLOR_FORCE= GREP_OPTIONS= +unset CLICOLOR_FORCE GREP_OPTIONS + +## --------------------- ## +## M4sh Shell Functions. ## +## --------------------- ## +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + $as_echo "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + + + as_lineno_1=$LINENO as_lineno_1a=$LINENO + as_lineno_2=$LINENO as_lineno_2a=$LINENO + eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && + test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { + # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) + sed -n ' + p + /[$]LINENO/= + ' <$as_myself | + sed ' + s/[$]LINENO.*/&-/ + t lineno + b + :lineno + N + :loop + s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ + t loop + s/-\n.*// + ' >$as_me.lineno && + chmod +x "$as_me.lineno" || + { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } + + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensitive to this). + . "./$as_me.lineno" + # Exit status is that of the last command. + exit +} + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -p'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -p' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -p' + fi +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +if test -x / >/dev/null 2>&1; then + as_test_x='test -x' +else + if ls -dL / >/dev/null 2>&1; then + as_ls_L_option=L + else + as_ls_L_option= + fi + as_test_x=' + eval sh -c '\'' + if test -d "$1"; then + test -d "$1/."; + else + case $1 in #( + -*)set "./$1";; + esac; + case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( + ???[sx]*):;;*)false;;esac;fi + '\'' sh + ' +fi +as_executable_p=$as_test_x + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +test -n "$DJDIR" || exec 7<&0 &1 + +# Name of the host. +# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, +# so uname gets run too. +ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` + +# +# Initializations. +# +ac_default_prefix=/usr/local +ac_clean_files= +ac_config_libobj_dir=. +LIBOBJS= +cross_compiling=no +subdirs= +MFLAGS= +MAKEFLAGS= + +# Identity of this package. +PACKAGE_NAME='newlib' +PACKAGE_TARNAME='newlib' +PACKAGE_VERSION='3.1.0' +PACKAGE_STRING='newlib 3.1.0' +PACKAGE_BUGREPORT='' +PACKAGE_URL='' + +ac_unique_file="Makefile.am" +ac_subst_vars='LTLIBOBJS +LIBOBJS +sys_dir +machine_dir +libm_machine_dir +lpfx +aext +oext +OBJEXT +USE_LIBTOOL_FALSE +USE_LIBTOOL_TRUE +ELIX_LEVEL_4_FALSE +ELIX_LEVEL_4_TRUE +ELIX_LEVEL_3_FALSE +ELIX_LEVEL_3_TRUE +ELIX_LEVEL_2_FALSE +ELIX_LEVEL_2_TRUE +ELIX_LEVEL_1_FALSE +ELIX_LEVEL_1_TRUE +ELIX_LEVEL_0_FALSE +ELIX_LEVEL_0_TRUE +LDFLAGS +NO_INCLUDE_LIST +NEWLIB_CFLAGS +CCASFLAGS +CCAS +MAINT +MAINTAINER_MODE_FALSE +MAINTAINER_MODE_TRUE +READELF +RANLIB +AR +AS +am__fastdepCC_FALSE +am__fastdepCC_TRUE +CCDEPMODE +am__nodep +AMDEPBACKSLASH +AMDEP_FALSE +AMDEP_TRUE +am__quote +am__include +DEPDIR +CC +am__untar +am__tar +AMTAR +am__leading_dot +SET_MAKE +AWK +mkdir_p +MKDIR_P +INSTALL_STRIP_PROGRAM +STRIP +install_sh +MAKEINFO +AUTOHEADER +AUTOMAKE +AUTOCONF +ACLOCAL +VERSION +PACKAGE +CYGPATH_W +am__isrc +INSTALL_DATA +INSTALL_SCRIPT +INSTALL_PROGRAM +host_os +host_vendor +host_cpu +host +build_os +build_vendor +build_cpu +build +newlib_basedir +MAY_SUPPLY_SYSCALLS_FALSE +MAY_SUPPLY_SYSCALLS_TRUE +target_alias +host_alias +build_alias +LIBS +ECHO_T +ECHO_N +ECHO_C +DEFS +mandir +localedir +libdir +psdir +pdfdir +dvidir +htmldir +infodir +docdir +oldincludedir +includedir +localstatedir +sharedstatedir +sysconfdir +datadir +datarootdir +libexecdir +sbindir +bindir +program_transform_name +prefix +exec_prefix +PACKAGE_URL +PACKAGE_BUGREPORT +PACKAGE_STRING +PACKAGE_VERSION +PACKAGE_TARNAME +PACKAGE_NAME +PATH_SEPARATOR +SHELL' +ac_subst_files='' +ac_user_opts=' +enable_option_checking +enable_multilib +enable_target_optspace +enable_malloc_debugging +enable_newlib_multithread +enable_newlib_iconv +enable_newlib_elix_level +enable_newlib_io_float +enable_newlib_supplied_syscalls +enable_newlib_fno_builtin +enable_dependency_tracking +enable_maintainer_mode +' + ac_precious_vars='build_alias +host_alias +target_alias +CCAS +CCASFLAGS' + + +# Initialize some variables set by options. +ac_init_help= +ac_init_version=false +ac_unrecognized_opts= +ac_unrecognized_sep= +# The variables have the same names as the options, with +# dashes changed to underlines. +cache_file=/dev/null +exec_prefix=NONE +no_create= +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +verbose= +x_includes=NONE +x_libraries=NONE + +# Installation directory options. +# These are left unexpanded so users can "make install exec_prefix=/foo" +# and all the variables that are supposed to be based on exec_prefix +# by default will actually change. +# Use braces instead of parens because sh, perl, etc. also accept them. +# (The list follows the same order as the GNU Coding Standards.) +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datarootdir='${prefix}/share' +datadir='${datarootdir}' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +includedir='${prefix}/include' +oldincludedir='/usr/include' +docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' +infodir='${datarootdir}/info' +htmldir='${docdir}' +dvidir='${docdir}' +pdfdir='${docdir}' +psdir='${docdir}' +libdir='${exec_prefix}/lib' +localedir='${datarootdir}/locale' +mandir='${datarootdir}/man' + +ac_prev= +ac_dashdash= +for ac_option +do + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval $ac_prev=\$ac_option + ac_prev= + continue + fi + + case $ac_option in + *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; + *=) ac_optarg= ;; + *) ac_optarg=yes ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case $ac_dashdash$ac_option in + --) + ac_dashdash=yes ;; + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir=$ac_optarg ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build_alias ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build_alias=$ac_optarg ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file=$ac_optarg ;; + + --config-cache | -C) + cache_file=config.cache ;; + + -datadir | --datadir | --datadi | --datad) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=*) + datadir=$ac_optarg ;; + + -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ + | --dataroo | --dataro | --datar) + ac_prev=datarootdir ;; + -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ + | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) + datarootdir=$ac_optarg ;; + + -disable-* | --disable-*) + ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=no ;; + + -docdir | --docdir | --docdi | --doc | --do) + ac_prev=docdir ;; + -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) + docdir=$ac_optarg ;; + + -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) + ac_prev=dvidir ;; + -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) + dvidir=$ac_optarg ;; + + -enable-* | --enable-*) + ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=\$ac_optarg ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix=$ac_optarg ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he | -h) + ac_init_help=long ;; + -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) + ac_init_help=recursive ;; + -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) + ac_init_help=short ;; + + -host | --host | --hos | --ho) + ac_prev=host_alias ;; + -host=* | --host=* | --hos=* | --ho=*) + host_alias=$ac_optarg ;; + + -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) + ac_prev=htmldir ;; + -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ + | --ht=*) + htmldir=$ac_optarg ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir=$ac_optarg ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir=$ac_optarg ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir=$ac_optarg ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir=$ac_optarg ;; + + -localedir | --localedir | --localedi | --localed | --locale) + ac_prev=localedir ;; + -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) + localedir=$ac_optarg ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst | --locals) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) + localstatedir=$ac_optarg ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir=$ac_optarg ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c | -n) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir=$ac_optarg ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix=$ac_optarg ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix=$ac_optarg ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix=$ac_optarg ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name=$ac_optarg ;; + + -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) + ac_prev=pdfdir ;; + -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) + pdfdir=$ac_optarg ;; + + -psdir | --psdir | --psdi | --psd | --ps) + ac_prev=psdir ;; + -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) + psdir=$ac_optarg ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir=$ac_optarg ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir=$ac_optarg ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site=$ac_optarg ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir=$ac_optarg ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir=$ac_optarg ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target_alias ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target_alias=$ac_optarg ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers | -V) + ac_init_version=: ;; + + -with-* | --with-*) + ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=\$ac_optarg ;; + + -without-* | --without-*) + ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=no ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes=$ac_optarg ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries=$ac_optarg ;; + + -*) as_fn_error $? "unrecognized option: \`$ac_option' +Try \`$0 --help' for more information" + ;; + + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + case $ac_envvar in #( + '' | [0-9]* | *[!_$as_cr_alnum]* ) + as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; + esac + eval $ac_envvar=\$ac_optarg + export $ac_envvar ;; + + *) + # FIXME: should be removed in autoconf 3.0. + $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && + $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 + : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" + ;; + + esac +done + +if test -n "$ac_prev"; then + ac_option=--`echo $ac_prev | sed 's/_/-/g'` + as_fn_error $? "missing argument to $ac_option" +fi + +if test -n "$ac_unrecognized_opts"; then + case $enable_option_checking in + no) ;; + fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; + *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; + esac +fi + +# Check all directory arguments for consistency. +for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ + datadir sysconfdir sharedstatedir localstatedir includedir \ + oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ + libdir localedir mandir +do + eval ac_val=\$$ac_var + # Remove trailing slashes. + case $ac_val in + */ ) + ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` + eval $ac_var=\$ac_val;; + esac + # Be sure to have absolute directory names. + case $ac_val in + [\\/$]* | ?:[\\/]* ) continue;; + NONE | '' ) case $ac_var in *prefix ) continue;; esac;; + esac + as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" +done + +# There might be people who depend on the old broken behavior: `$host' +# used to hold the argument of --host etc. +# FIXME: To remove some day. +build=$build_alias +host=$host_alias +target=$target_alias + +# FIXME: To remove some day. +if test "x$host_alias" != x; then + if test "x$build_alias" = x; then + cross_compiling=maybe + $as_echo "$as_me: WARNING: if you wanted to set the --build type, don't use --host. + If a cross compiler is detected then cross compile mode will be used" >&2 + elif test "x$build_alias" != "x$host_alias"; then + cross_compiling=yes + fi +fi + +ac_tool_prefix= +test -n "$host_alias" && ac_tool_prefix=$host_alias- + +test "$silent" = yes && exec 6>/dev/null + + +ac_pwd=`pwd` && test -n "$ac_pwd" && +ac_ls_di=`ls -di .` && +ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || + as_fn_error $? "working directory cannot be determined" +test "X$ac_ls_di" = "X$ac_pwd_ls_di" || + as_fn_error $? "pwd does not report name of working directory" + + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then the parent directory. + ac_confdir=`$as_dirname -- "$as_myself" || +$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_myself" : 'X\(//\)[^/]' \| \ + X"$as_myself" : 'X\(//\)$' \| \ + X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_myself" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + srcdir=$ac_confdir + if test ! -r "$srcdir/$ac_unique_file"; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r "$srcdir/$ac_unique_file"; then + test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." + as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" +fi +ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" +ac_abs_confdir=`( + cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" + pwd)` +# When building in place, set srcdir=. +if test "$ac_abs_confdir" = "$ac_pwd"; then + srcdir=. +fi +# Remove unnecessary trailing slashes from srcdir. +# Double slashes in file names in object file debugging info +# mess up M-x gdb in Emacs. +case $srcdir in +*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; +esac +for ac_var in $ac_precious_vars; do + eval ac_env_${ac_var}_set=\${${ac_var}+set} + eval ac_env_${ac_var}_value=\$${ac_var} + eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} + eval ac_cv_env_${ac_var}_value=\$${ac_var} +done + +# +# Report the --help message. +# +if test "$ac_init_help" = "long"; then + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat <<_ACEOF +\`configure' configures newlib 3.1.0 to adapt to many kinds of systems. + +Usage: $0 [OPTION]... [VAR=VALUE]... + +To assign environment variables (e.g., CC, CFLAGS...), specify them as +VAR=VALUE. See below for descriptions of some of the useful variables. + +Defaults for the options are specified in brackets. + +Configuration: + -h, --help display this help and exit + --help=short display options specific to this package + --help=recursive display the short help of all the included packages + -V, --version display version information and exit + -q, --quiet, --silent do not print \`checking ...' messages + --cache-file=FILE cache test results in FILE [disabled] + -C, --config-cache alias for \`--cache-file=config.cache' + -n, --no-create do not create output files + --srcdir=DIR find the sources in DIR [configure dir or \`..'] + +Installation directories: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [PREFIX] + +By default, \`make install' will install all the files in +\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify +an installation prefix other than \`$ac_default_prefix' using \`--prefix', +for instance \`--prefix=\$HOME'. + +For better control, use the options below. + +Fine tuning of the installation directories: + --bindir=DIR user executables [EPREFIX/bin] + --sbindir=DIR system admin executables [EPREFIX/sbin] + --libexecdir=DIR program executables [EPREFIX/libexec] + --sysconfdir=DIR read-only single-machine data [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] + --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --libdir=DIR object code libraries [EPREFIX/lib] + --includedir=DIR C header files [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc [/usr/include] + --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] + --datadir=DIR read-only architecture-independent data [DATAROOTDIR] + --infodir=DIR info documentation [DATAROOTDIR/info] + --localedir=DIR locale-dependent data [DATAROOTDIR/locale] + --mandir=DIR man documentation [DATAROOTDIR/man] + --docdir=DIR documentation root [DATAROOTDIR/doc/newlib] + --htmldir=DIR html documentation [DOCDIR] + --dvidir=DIR dvi documentation [DOCDIR] + --pdfdir=DIR pdf documentation [DOCDIR] + --psdir=DIR ps documentation [DOCDIR] +_ACEOF + + cat <<\_ACEOF + +Program names: + --program-prefix=PREFIX prepend PREFIX to installed program names + --program-suffix=SUFFIX append SUFFIX to installed program names + --program-transform-name=PROGRAM run sed PROGRAM on installed program names + +System types: + --build=BUILD configure for building on BUILD [guessed] + --host=HOST cross-compile to build programs to run on HOST [BUILD] +_ACEOF +fi + +if test -n "$ac_init_help"; then + case $ac_init_help in + short | recursive ) echo "Configuration of newlib 3.1.0:";; + esac + cat <<\_ACEOF + +Optional Features: + --disable-option-checking ignore unrecognized --enable/--with options + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --enable-multilib build many library versions (default) + --enable-target-optspace optimize for space + --enable-malloc-debugging indicate malloc debugging requested + --enable-newlib-multithread enable support for multiple threads + --enable-newlib-iconv enable iconv library support + --enable-newlib-elix-level supply desired elix library level (1-4) + --disable-newlib-io-float disable printf/scanf family float support + --disable-newlib-supplied-syscalls disable newlib from supplying syscalls + --disable-newlib-fno-builtin disable -fno-builtin flag to allow compiler to use builtin library functions + --disable-dependency-tracking speeds up one-time build + --enable-dependency-tracking do not reject slow dependency extractors + --enable-maintainer-mode enable make rules and dependencies not useful + (and sometimes confusing) to the casual installer + +Some influential environment variables: + CCAS assembler compiler command (defaults to CC) + CCASFLAGS assembler compiler flags (defaults to CFLAGS) + +Use these variables to override the choices made by `configure' or to help +it to find libraries and programs with nonstandard names/locations. + +Report bugs to the package provider. +_ACEOF +ac_status=$? +fi + +if test "$ac_init_help" = "recursive"; then + # If there are subdirs, report their specific --help. + for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue + test -d "$ac_dir" || + { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || + continue + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + cd "$ac_dir" || { ac_status=$?; continue; } + # Check for guested configure. + if test -f "$ac_srcdir/configure.gnu"; then + echo && + $SHELL "$ac_srcdir/configure.gnu" --help=recursive + elif test -f "$ac_srcdir/configure"; then + echo && + $SHELL "$ac_srcdir/configure" --help=recursive + else + $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + fi || ac_status=$? + cd "$ac_pwd" || { ac_status=$?; break; } + done +fi + +test -n "$ac_init_help" && exit $ac_status +if $ac_init_version; then + cat <<\_ACEOF +newlib configure 3.1.0 +generated by GNU Autoconf 2.68 + +Copyright (C) 2010 Free Software Foundation, Inc. +This configure script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it. +_ACEOF + exit +fi + +## ------------------------ ## +## Autoconf initialization. ## +## ------------------------ ## + +# ac_fn_c_try_compile LINENO +# -------------------------- +# Try to compile conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext + if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_compile +cat >config.log <<_ACEOF +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by newlib $as_me 3.1.0, which was +generated by GNU Autoconf 2.68. Invocation command line was + + $ $0 $@ + +_ACEOF +exec 5>>config.log +{ +cat <<_ASUNAME +## --------- ## +## Platform. ## +## --------- ## + +hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` + +/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` +/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` +/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` +/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` + +_ASUNAME + +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + $as_echo "PATH: $as_dir" + done +IFS=$as_save_IFS + +} >&5 + +cat >&5 <<_ACEOF + + +## ----------- ## +## Core tests. ## +## ----------- ## + +_ACEOF + + +# Keep a trace of the command line. +# Strip out --no-create and --no-recursion so they do not pile up. +# Strip out --silent because we don't want to record it for future runs. +# Also quote any args containing shell meta-characters. +# Make two passes to allow for proper duplicate-argument suppression. +ac_configure_args= +ac_configure_args0= +ac_configure_args1= +ac_must_keep_next=false +for ac_pass in 1 2 +do + for ac_arg + do + case $ac_arg in + -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + continue ;; + *\'*) + ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + case $ac_pass in + 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; + 2) + as_fn_append ac_configure_args1 " '$ac_arg'" + if test $ac_must_keep_next = true; then + ac_must_keep_next=false # Got value, back to normal. + else + case $ac_arg in + *=* | --config-cache | -C | -disable-* | --disable-* \ + | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ + | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ + | -with-* | --with-* | -without-* | --without-* | --x) + case "$ac_configure_args0 " in + "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; + esac + ;; + -* ) ac_must_keep_next=true ;; + esac + fi + as_fn_append ac_configure_args " '$ac_arg'" + ;; + esac + done +done +{ ac_configure_args0=; unset ac_configure_args0;} +{ ac_configure_args1=; unset ac_configure_args1;} + +# When interrupted or exit'd, cleanup temporary files, and complete +# config.log. We remove comments because anyway the quotes in there +# would cause problems or look ugly. +# WARNING: Use '\'' to represent an apostrophe within the trap. +# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. +trap 'exit_status=$? + # Save into config.log some information that might help in debugging. + { + echo + + $as_echo "## ---------------- ## +## Cache variables. ## +## ---------------- ##" + echo + # The following way of writing the cache mishandles newlines in values, +( + for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + (set) 2>&1 | + case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + sed -n \ + "s/'\''/'\''\\\\'\'''\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" + ;; #( + *) + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) + echo + + $as_echo "## ----------------- ## +## Output variables. ## +## ----------------- ##" + echo + for ac_var in $ac_subst_vars + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + + if test -n "$ac_subst_files"; then + $as_echo "## ------------------- ## +## File substitutions. ## +## ------------------- ##" + echo + for ac_var in $ac_subst_files + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + fi + + if test -s confdefs.h; then + $as_echo "## ----------- ## +## confdefs.h. ## +## ----------- ##" + echo + cat confdefs.h + echo + fi + test "$ac_signal" != 0 && + $as_echo "$as_me: caught signal $ac_signal" + $as_echo "$as_me: exit $exit_status" + } >&5 + rm -f core *.core core.conftest.* && + rm -f -r conftest* confdefs* conf$$* $ac_clean_files && + exit $exit_status +' 0 +for ac_signal in 1 2 13 15; do + trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal +done +ac_signal=0 + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -f -r conftest* confdefs.h + +$as_echo "/* confdefs.h */" > confdefs.h + +# Predefined preprocessor variables. + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_NAME "$PACKAGE_NAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_TARNAME "$PACKAGE_TARNAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_VERSION "$PACKAGE_VERSION" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_STRING "$PACKAGE_STRING" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_URL "$PACKAGE_URL" +_ACEOF + + +# Let the site file select an alternate cache file if it wants to. +# Prefer an explicitly selected file to automatically selected ones. +ac_site_file1=NONE +ac_site_file2=NONE +if test -n "$CONFIG_SITE"; then + # We do not want a PATH search for config.site. + case $CONFIG_SITE in #(( + -*) ac_site_file1=./$CONFIG_SITE;; + */*) ac_site_file1=$CONFIG_SITE;; + *) ac_site_file1=./$CONFIG_SITE;; + esac +elif test "x$prefix" != xNONE; then + ac_site_file1=$prefix/share/config.site + ac_site_file2=$prefix/etc/config.site +else + ac_site_file1=$ac_default_prefix/share/config.site + ac_site_file2=$ac_default_prefix/etc/config.site +fi +for ac_site_file in "$ac_site_file1" "$ac_site_file2" +do + test "x$ac_site_file" = xNONE && continue + if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 +$as_echo "$as_me: loading site script $ac_site_file" >&6;} + sed 's/^/| /' "$ac_site_file" >&5 + . "$ac_site_file" \ + || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "failed to load site script $ac_site_file +See \`config.log' for more details" "$LINENO" 5; } + fi +done + +if test -r "$cache_file"; then + # Some versions of bash will fail to source /dev/null (special files + # actually), so we avoid doing that. DJGPP emulates it as a regular file. + if test /dev/null != "$cache_file" && test -f "$cache_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 +$as_echo "$as_me: loading cache $cache_file" >&6;} + case $cache_file in + [\\/]* | ?:[\\/]* ) . "$cache_file";; + *) . "./$cache_file";; + esac + fi +else + { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 +$as_echo "$as_me: creating cache $cache_file" >&6;} + >$cache_file +fi + +# Check that the precious variables saved in the cache have kept the same +# value. +ac_cache_corrupted=false +for ac_var in $ac_precious_vars; do + eval ac_old_set=\$ac_cv_env_${ac_var}_set + eval ac_new_set=\$ac_env_${ac_var}_set + eval ac_old_val=\$ac_cv_env_${ac_var}_value + eval ac_new_val=\$ac_env_${ac_var}_value + case $ac_old_set,$ac_new_set in + set,) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,);; + *) + if test "x$ac_old_val" != "x$ac_new_val"; then + # differences in whitespace do not lead to failure. + ac_old_val_w=`echo x $ac_old_val` + ac_new_val_w=`echo x $ac_new_val` + if test "$ac_old_val_w" != "$ac_new_val_w"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 +$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + ac_cache_corrupted=: + else + { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 +$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} + eval $ac_var=\$ac_old_val + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 +$as_echo "$as_me: former value: \`$ac_old_val'" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 +$as_echo "$as_me: current value: \`$ac_new_val'" >&2;} + fi;; + esac + # Pass precious variables to config.status. + if test "$ac_new_set" = set; then + case $ac_new_val in + *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *) ac_arg=$ac_var=$ac_new_val ;; + esac + case " $ac_configure_args " in + *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. + *) as_fn_append ac_configure_args " '$ac_arg'" ;; + esac + fi +done +if $ac_cache_corrupted; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 +$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} + as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 +fi +## -------------------- ## +## Main body of script. ## +## -------------------- ## + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + + +ac_aux_dir= +for ac_dir in ../../../.. "$srcdir"/../../../..; do + if test -f "$ac_dir/install-sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f "$ac_dir/install.sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + elif test -f "$ac_dir/shtool"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/shtool install -c" + break + fi +done +if test -z "$ac_aux_dir"; then + as_fn_error $? "cannot find install-sh, install.sh, or shtool in ../../../.. \"$srcdir\"/../../../.." "$LINENO" 5 +fi + +# These three variables are undocumented and unsupported, +# and are intended to be withdrawn in a future Autoconf release. +# They can cause serious problems if a builder's source tree is in a directory +# whose full name contains unusual characters. +ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. +ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. +ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. + + + + +# Make sure we can run config.sub. +$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || + as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 +$as_echo_n "checking build system type... " >&6; } +if ${ac_cv_build+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_build_alias=$build_alias +test "x$ac_build_alias" = x && + ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` +test "x$ac_build_alias" = x && + as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 +ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || + as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 +$as_echo "$ac_cv_build" >&6; } +case $ac_cv_build in +*-*-*) ;; +*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; +esac +build=$ac_cv_build +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_build +shift +build_cpu=$1 +build_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +build_os=$* +IFS=$ac_save_IFS +case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 +$as_echo_n "checking host system type... " >&6; } +if ${ac_cv_host+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "x$host_alias" = x; then + ac_cv_host=$ac_cv_build +else + ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || + as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 +$as_echo "$ac_cv_host" >&6; } +case $ac_cv_host in +*-*-*) ;; +*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; +esac +host=$ac_cv_host +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_host +shift +host_cpu=$1 +host_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +host_os=$* +IFS=$ac_save_IFS +case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac + + +am__api_version='1.11' + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AmigaOS /C/install, which installs bootblocks on floppy discs +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# OS/2's system install, which has a completely different semantic +# ./install, which can be erroneously created by make from ./install.sh. +# Reject install programs that cannot install multiple files. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 +$as_echo_n "checking for a BSD-compatible install... " >&6; } +if test -z "$INSTALL"; then +if ${ac_cv_path_install+:} false; then : + $as_echo_n "(cached) " >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + # Account for people who put trailing slashes in PATH elements. +case $as_dir/ in #(( + ./ | .// | /[cC]/* | \ + /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ + ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ + /usr/ucb/* ) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then + if test $ac_prog = install && + grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + elif test $ac_prog = install && + grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # program-specific install script used by HP pwplus--don't use. + : + else + rm -rf conftest.one conftest.two conftest.dir + echo one > conftest.one + echo two > conftest.two + mkdir conftest.dir + if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && + test -s conftest.one && test -s conftest.two && + test -s conftest.dir/conftest.one && + test -s conftest.dir/conftest.two + then + ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" + break 3 + fi + fi + fi + done + done + ;; +esac + + done +IFS=$as_save_IFS + +rm -rf conftest.one conftest.two conftest.dir + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL=$ac_cv_path_install + else + # As a last resort, use the slow shell script. Don't cache a + # value for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + INSTALL=$ac_install_sh + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 +$as_echo "$INSTALL" >&6; } + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 +$as_echo_n "checking whether build environment is sane... " >&6; } +# Just in case +sleep 1 +echo timestamp > conftest.file +# Reject unsafe characters in $srcdir or the absolute working directory +# name. Accept space and tab only in the latter. +am_lf=' +' +case `pwd` in + *[\\\"\#\$\&\'\`$am_lf]*) + as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;; +esac +case $srcdir in + *[\\\"\#\$\&\'\`$am_lf\ \ ]*) + as_fn_error $? "unsafe srcdir value: \`$srcdir'" "$LINENO" 5;; +esac + +# Do `set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` + if test "$*" = "X"; then + # -L didn't work. + set X `ls -t "$srcdir/configure" conftest.file` + fi + rm -f conftest.file + if test "$*" != "X $srcdir/configure conftest.file" \ + && test "$*" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + as_fn_error $? "ls -t appears to fail. Make sure there is not a broken +alias in your environment" "$LINENO" 5 + fi + + test "$2" = conftest.file + ) +then + # Ok. + : +else + as_fn_error $? "newly created file is older than distributed files! +Check your system clock" "$LINENO" 5 +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +test "$program_prefix" != NONE && + program_transform_name="s&^&$program_prefix&;$program_transform_name" +# Use a double $ so make ignores it. +test "$program_suffix" != NONE && + program_transform_name="s&\$&$program_suffix&;$program_transform_name" +# Double any \ or $. +# By default was `s,x,x', remove it if useless. +ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' +program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` + +# expand $ac_aux_dir to an absolute path +am_aux_dir=`cd $ac_aux_dir && pwd` + +if test x"${MISSING+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; + *) + MISSING="\${SHELL} $am_aux_dir/missing" ;; + esac +fi +# Use eval to expand $SHELL +if eval "$MISSING --run true"; then + am_missing_run="$MISSING --run " +else + am_missing_run= + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`missing' script is too old or missing" >&5 +$as_echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;} +fi + +if test x"${install_sh}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; + *) + install_sh="\${SHELL} $am_aux_dir/install-sh" + esac +fi + +# Installed binaries are usually stripped using `strip' when the user +# run `make install-strip'. However `strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the `STRIP' environment variable to overrule this program. +if test "$cross_compiling" != no; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. +set dummy ${ac_tool_prefix}strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_STRIP="${ac_tool_prefix}strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +STRIP=$ac_cv_prog_STRIP +if test -n "$STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 +$as_echo "$STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_STRIP"; then + ac_ct_STRIP=$STRIP + # Extract the first word of "strip", so it can be a program name with args. +set dummy strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_STRIP"; then + ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_STRIP="strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP +if test -n "$ac_ct_STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 +$as_echo "$ac_ct_STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_STRIP" = x; then + STRIP=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + STRIP=$ac_ct_STRIP + fi +else + STRIP="$ac_cv_prog_STRIP" +fi + +fi +INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5 +$as_echo_n "checking for a thread-safe mkdir -p... " >&6; } +if test -z "$MKDIR_P"; then + if ${ac_cv_path_mkdir+:} false; then : + $as_echo_n "(cached) " >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in mkdir gmkdir; do + for ac_exec_ext in '' $ac_executable_extensions; do + { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; } || continue + case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( + 'mkdir (GNU coreutils) '* | \ + 'mkdir (coreutils) '* | \ + 'mkdir (fileutils) '4.1*) + ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext + break 3;; + esac + done + done + done +IFS=$as_save_IFS + +fi + + test -d ./--version && rmdir ./--version + if test "${ac_cv_path_mkdir+set}" = set; then + MKDIR_P="$ac_cv_path_mkdir -p" + else + # As a last resort, use the slow shell script. Don't cache a + # value for MKDIR_P within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + MKDIR_P="$ac_install_sh -d" + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 +$as_echo "$MKDIR_P" >&6; } + +mkdir_p="$MKDIR_P" +case $mkdir_p in + [\\/$]* | ?:[\\/]*) ;; + */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; +esac + +for ac_prog in gawk mawk nawk awk +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_AWK+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$AWK"; then + ac_cv_prog_AWK="$AWK" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_AWK="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +AWK=$ac_cv_prog_AWK +if test -n "$AWK"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 +$as_echo "$AWK" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$AWK" && break +done + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 +$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } +set x ${MAKE-make} +ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` +if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat >conftest.make <<\_ACEOF +SHELL = /bin/sh +all: + @echo '@@@%%%=$(MAKE)=@@@%%%' +_ACEOF +# GNU make sometimes prints "make[1]: Entering ...", which would confuse us. +case `${MAKE-make} -f conftest.make 2>/dev/null` in + *@@@%%%=?*=@@@%%%*) + eval ac_cv_prog_make_${ac_make}_set=yes;; + *) + eval ac_cv_prog_make_${ac_make}_set=no;; +esac +rm -f conftest.make +fi +if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + SET_MAKE= +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + SET_MAKE="MAKE=${MAKE-make}" +fi + +rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null + +DEPDIR="${am__leading_dot}deps" + +ac_config_commands="$ac_config_commands depfiles" + + +am_make=${MAKE-make} +cat > confinc << 'END' +am__doit: + @echo this is the am__doit target +.PHONY: am__doit +END +# If we don't find an include directive, just comment out the code. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5 +$as_echo_n "checking for style of include used by $am_make... " >&6; } +am__include="#" +am__quote= +_am_result=none +# First try GNU make style include. +echo "include confinc" > confmf +# Ignore all kinds of additional output from `make'. +case `$am_make -s -f confmf 2> /dev/null` in #( +*the\ am__doit\ target*) + am__include=include + am__quote= + _am_result=GNU + ;; +esac +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + case `$am_make -s -f confmf 2> /dev/null` in #( + *the\ am__doit\ target*) + am__include=.include + am__quote="\"" + _am_result=BSD + ;; + esac +fi + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5 +$as_echo "$_am_result" >&6; } +rm -f confinc confmf + +# Check whether --enable-dependency-tracking was given. +if test "${enable_dependency_tracking+set}" = set; then : + enableval=$enable_dependency_tracking; +fi + +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' + am__nodep='_no' +fi + if test "x$enable_dependency_tracking" != xno; then + AMDEP_TRUE= + AMDEP_FALSE='#' +else + AMDEP_TRUE='#' + AMDEP_FALSE= +fi + + + +# Check whether --enable-multilib was given. +if test "${enable_multilib+set}" = set; then : + enableval=$enable_multilib; case "${enableval}" in + yes) multilib=yes ;; + no) multilib=no ;; + *) as_fn_error $? "bad value ${enableval} for multilib option" "$LINENO" 5 ;; + esac +else + multilib=yes +fi + +# Check whether --enable-target-optspace was given. +if test "${enable_target_optspace+set}" = set; then : + enableval=$enable_target_optspace; case "${enableval}" in + yes) target_optspace=yes ;; + no) target_optspace=no ;; + *) as_fn_error $? "bad value ${enableval} for target-optspace option" "$LINENO" 5 ;; + esac +else + target_optspace= +fi + +# Check whether --enable-malloc-debugging was given. +if test "${enable_malloc_debugging+set}" = set; then : + enableval=$enable_malloc_debugging; case "${enableval}" in + yes) malloc_debugging=yes ;; + no) malloc_debugging=no ;; + *) as_fn_error $? "bad value ${enableval} for malloc-debugging option" "$LINENO" 5 ;; + esac +else + malloc_debugging= +fi + +# Check whether --enable-newlib-multithread was given. +if test "${enable_newlib_multithread+set}" = set; then : + enableval=$enable_newlib_multithread; case "${enableval}" in + yes) newlib_multithread=yes ;; + no) newlib_multithread=no ;; + *) as_fn_error $? "bad value ${enableval} for newlib-multithread option" "$LINENO" 5 ;; + esac +else + newlib_multithread=yes +fi + +# Check whether --enable-newlib-iconv was given. +if test "${enable_newlib_iconv+set}" = set; then : + enableval=$enable_newlib_iconv; if test "${newlib_iconv+set}" != set; then + case "${enableval}" in + yes) newlib_iconv=yes ;; + no) newlib_iconv=no ;; + *) as_fn_error $? "bad value ${enableval} for newlib-iconv option" "$LINENO" 5 ;; + esac + fi +else + newlib_iconv=${newlib_iconv} +fi + +# Check whether --enable-newlib-elix-level was given. +if test "${enable_newlib_elix_level+set}" = set; then : + enableval=$enable_newlib_elix_level; case "${enableval}" in + 0) newlib_elix_level=0 ;; + 1) newlib_elix_level=1 ;; + 2) newlib_elix_level=2 ;; + 3) newlib_elix_level=3 ;; + 4) newlib_elix_level=4 ;; + *) as_fn_error $? "bad value ${enableval} for newlib-elix-level option" "$LINENO" 5 ;; + esac +else + newlib_elix_level=0 +fi + +# Check whether --enable-newlib-io-float was given. +if test "${enable_newlib_io_float+set}" = set; then : + enableval=$enable_newlib_io_float; case "${enableval}" in + yes) newlib_io_float=yes ;; + no) newlib_io_float=no ;; + *) as_fn_error $? "bad value ${enableval} for newlib-io-float option" "$LINENO" 5 ;; + esac +else + newlib_io_float=yes +fi + +# Check whether --enable-newlib-supplied-syscalls was given. +if test "${enable_newlib_supplied_syscalls+set}" = set; then : + enableval=$enable_newlib_supplied_syscalls; case "${enableval}" in + yes) newlib_may_supply_syscalls=yes ;; + no) newlib_may_supply_syscalls=no ;; + *) as_fn_error $? "bad value ${enableval} for newlib-supplied-syscalls option" "$LINENO" 5 ;; + esac +else + newlib_may_supply_syscalls=yes +fi + + if test x${newlib_may_supply_syscalls} = xyes; then + MAY_SUPPLY_SYSCALLS_TRUE= + MAY_SUPPLY_SYSCALLS_FALSE='#' +else + MAY_SUPPLY_SYSCALLS_TRUE='#' + MAY_SUPPLY_SYSCALLS_FALSE= +fi + + +# Check whether --enable-newlib-fno-builtin was given. +if test "${enable_newlib_fno_builtin+set}" = set; then : + enableval=$enable_newlib_fno_builtin; case "${enableval}" in + yes) newlib_fno_builtin=yes ;; + no) newlib_fno_builtin=no ;; + *) as_fn_error $? "bad value ${enableval} for newlib-fno-builtin option" "$LINENO" 5 ;; + esac +else + newlib_fno_builtin= +fi + + + +test -z "${with_target_subdir}" && with_target_subdir=. + +if test "${srcdir}" = "."; then + if test "${with_target_subdir}" != "."; then + newlib_basedir="${srcdir}/${with_multisrctop}../../../.." + else + newlib_basedir="${srcdir}/${with_multisrctop}../../.." + fi +else + newlib_basedir="${srcdir}/../../.." +fi + + + + +if test "`cd $srcdir && pwd`" != "`pwd`"; then + # Use -I$(srcdir) only when $(srcdir) != ., so that make's output + # is not polluted with repeated "-I." + am__isrc=' -I$(srcdir)' + # test to see if srcdir already configured + if test -f $srcdir/config.status; then + as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5 + fi +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi + + +# Define the identity of the package. + PACKAGE='newlib' + VERSION='3.1.0' + + +# Some tools Automake needs. + +ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} + + +AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} + + +AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} + + +AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} + + +MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} + +# We need awk for the "check" target. The system "awk" is bad on +# some platforms. +# Always define AMTAR for backward compatibility. Yes, it's still used +# in the wild :-( We should find a proper way to deprecate it ... +AMTAR='$${TAR-tar}' + +am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -' + + + + + + +# FIXME: We temporarily define our own version of AC_PROG_CC. This is +# copied from autoconf 2.12, but does not call AC_PROG_CC_WORKS. We +# are probably using a cross compiler, which will not be able to fully +# link an executable. This should really be fixed in autoconf +# itself. + + + + + + + +# Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + +depcc="$CC" am_compiler_list= + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 +$as_echo_n "checking dependency style of $depcc... " >&6; } +if ${am_cv_CC_dependencies_compiler_type+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named `D' -- because `-MD' means `put the output + # in D'. + rm -rf conftest.dir + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_CC_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` + fi + am__universal=false + case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with + # Solaris 8's {/usr,}/bin/sh. + touch sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with `-c' and `-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle `-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # after this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvc7 | msvc7msys | msvisualcpp | msvcmsys) + # This compiler won't grok `-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_CC_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_CC_dependencies_compiler_type=none +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 +$as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } +CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type + + if + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then + am__fastdepCC_TRUE= + am__fastdepCC_FALSE='#' +else + am__fastdepCC_TRUE='#' + am__fastdepCC_FALSE= +fi + + +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -z "$CC" && as_fn_error $? "no acceptable cc found in \$PATH" "$LINENO" 5 +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using GNU C" >&5 +$as_echo_n "checking whether we are using GNU C... " >&6; } +if ${ac_cv_c_compiler_gnu+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat > conftest.c <&5 + (eval $ac_try) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; } | egrep yes >/dev/null 2>&1; then + ac_cv_c_compiler_gnu=yes +else + ac_cv_c_compiler_gnu=no +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 +$as_echo "$ac_cv_c_compiler_gnu" >&6; } + +if test $ac_cv_c_compiler_gnu = yes; then + GCC=yes + ac_test_CFLAGS="${CFLAGS+set}" + ac_save_CFLAGS="$CFLAGS" + ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 +$as_echo_n "checking whether $CC accepts -g... " >&6; } +if ${ac_cv_prog_cc_g+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_save_c_werror_flag=$ac_c_werror_flag + ac_c_werror_flag=yes + ac_cv_prog_cc_g=no + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +else + CFLAGS="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + ac_c_werror_flag=$ac_save_c_werror_flag + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_c_werror_flag=$ac_save_c_werror_flag +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 +$as_echo "$ac_cv_prog_cc_g" >&6; } +if test "$ac_test_CFLAGS" = set; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi + if test "$ac_test_CFLAGS" = set; then + CFLAGS="$ac_save_CFLAGS" + elif test $ac_cv_prog_cc_g = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-O2" + fi +else + GCC= + test "${CFLAGS+set}" = set || CFLAGS="-g" +fi + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}as", so it can be a program name with args. +set dummy ${ac_tool_prefix}as; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_AS+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$AS"; then + ac_cv_prog_AS="$AS" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_AS="${ac_tool_prefix}as" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +AS=$ac_cv_prog_AS +if test -n "$AS"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AS" >&5 +$as_echo "$AS" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_AS"; then + ac_ct_AS=$AS + # Extract the first word of "as", so it can be a program name with args. +set dummy as; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_AS+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_AS"; then + ac_cv_prog_ac_ct_AS="$ac_ct_AS" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_AS="as" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_AS=$ac_cv_prog_ac_ct_AS +if test -n "$ac_ct_AS"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AS" >&5 +$as_echo "$ac_ct_AS" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_AS" = x; then + AS="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + AS=$ac_ct_AS + fi +else + AS="$ac_cv_prog_AS" +fi + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args. +set dummy ${ac_tool_prefix}ar; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_AR+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$AR"; then + ac_cv_prog_AR="$AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_AR="${ac_tool_prefix}ar" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +AR=$ac_cv_prog_AR +if test -n "$AR"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 +$as_echo "$AR" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_AR"; then + ac_ct_AR=$AR + # Extract the first word of "ar", so it can be a program name with args. +set dummy ar; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_AR+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_AR"; then + ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_AR="ar" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_AR=$ac_cv_prog_ac_ct_AR +if test -n "$ac_ct_AR"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 +$as_echo "$ac_ct_AR" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_AR" = x; then + AR="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + AR=$ac_ct_AR + fi +else + AR="$ac_cv_prog_AR" +fi + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. +set dummy ${ac_tool_prefix}ranlib; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_RANLIB+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +RANLIB=$ac_cv_prog_RANLIB +if test -n "$RANLIB"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 +$as_echo "$RANLIB" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_RANLIB"; then + ac_ct_RANLIB=$RANLIB + # Extract the first word of "ranlib", so it can be a program name with args. +set dummy ranlib; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_RANLIB+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_RANLIB"; then + ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_RANLIB="ranlib" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB +if test -n "$ac_ct_RANLIB"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 +$as_echo "$ac_ct_RANLIB" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_RANLIB" = x; then + RANLIB=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + RANLIB=$ac_ct_RANLIB + fi +else + RANLIB="$ac_cv_prog_RANLIB" +fi + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}readelf", so it can be a program name with args. +set dummy ${ac_tool_prefix}readelf; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_READELF+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$READELF"; then + ac_cv_prog_READELF="$READELF" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_READELF="${ac_tool_prefix}readelf" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +READELF=$ac_cv_prog_READELF +if test -n "$READELF"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $READELF" >&5 +$as_echo "$READELF" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_READELF"; then + ac_ct_READELF=$READELF + # Extract the first word of "readelf", so it can be a program name with args. +set dummy readelf; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_READELF+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_READELF"; then + ac_cv_prog_ac_ct_READELF="$ac_ct_READELF" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_READELF="readelf" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_READELF=$ac_cv_prog_ac_ct_READELF +if test -n "$ac_ct_READELF"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_READELF" >&5 +$as_echo "$ac_ct_READELF" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_READELF" = x; then + READELF=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + READELF=$ac_ct_READELF + fi +else + READELF="$ac_cv_prog_READELF" +fi + + + + +# Hack to ensure that INSTALL won't be set to "../" with autoconf 2.13. */ +ac_given_INSTALL=$INSTALL + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable maintainer-specific portions of Makefiles" >&5 +$as_echo_n "checking whether to enable maintainer-specific portions of Makefiles... " >&6; } + # Check whether --enable-maintainer-mode was given. +if test "${enable_maintainer_mode+set}" = set; then : + enableval=$enable_maintainer_mode; USE_MAINTAINER_MODE=$enableval +else + USE_MAINTAINER_MODE=no +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $USE_MAINTAINER_MODE" >&5 +$as_echo "$USE_MAINTAINER_MODE" >&6; } + if test $USE_MAINTAINER_MODE = yes; then + MAINTAINER_MODE_TRUE= + MAINTAINER_MODE_FALSE='#' +else + MAINTAINER_MODE_TRUE='#' + MAINTAINER_MODE_FALSE= +fi + + MAINT=$MAINTAINER_MODE_TRUE + + +# By default we simply use the C compiler to build assembly code. + +test "${CCAS+set}" = set || CCAS=$CC +test "${CCASFLAGS+set}" = set || CCASFLAGS=$CFLAGS + + + + +# We need AC_EXEEXT to keep automake happy in cygnus mode. However, +# at least currently, we never actually build a program, so we never +# need to use $(EXEEXT). Moreover, the test for EXEEXT normally +# fails, because we are probably configuring with a cross compiler +# which can't create executables. So we include AC_EXEEXT to keep +# automake happy, but we don't execute it, since we don't care about +# the result. +if false; then + + dummy_var=1 +fi + +. ${newlib_basedir}/configure.host + +NEWLIB_CFLAGS=${newlib_cflags} + + +NO_INCLUDE_LIST=${noinclude} + + +LDFLAGS=${ldflags} + + + if test x${newlib_elix_level} = x0; then + ELIX_LEVEL_0_TRUE= + ELIX_LEVEL_0_FALSE='#' +else + ELIX_LEVEL_0_TRUE='#' + ELIX_LEVEL_0_FALSE= +fi + + if test x${newlib_elix_level} = x1; then + ELIX_LEVEL_1_TRUE= + ELIX_LEVEL_1_FALSE='#' +else + ELIX_LEVEL_1_TRUE='#' + ELIX_LEVEL_1_FALSE= +fi + + if test x${newlib_elix_level} = x2; then + ELIX_LEVEL_2_TRUE= + ELIX_LEVEL_2_FALSE='#' +else + ELIX_LEVEL_2_TRUE='#' + ELIX_LEVEL_2_FALSE= +fi + + if test x${newlib_elix_level} = x3; then + ELIX_LEVEL_3_TRUE= + ELIX_LEVEL_3_FALSE='#' +else + ELIX_LEVEL_3_TRUE='#' + ELIX_LEVEL_3_FALSE= +fi + + if test x${newlib_elix_level} = x4; then + ELIX_LEVEL_4_TRUE= + ELIX_LEVEL_4_FALSE='#' +else + ELIX_LEVEL_4_TRUE='#' + ELIX_LEVEL_4_FALSE= +fi + + + if test x${use_libtool} = xyes; then + USE_LIBTOOL_TRUE= + USE_LIBTOOL_FALSE='#' +else + USE_LIBTOOL_TRUE='#' + USE_LIBTOOL_FALSE= +fi + + +# Emit any target-specific warnings. +if test "x${newlib_msg_warn}" != "x"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: ${newlib_msg_warn}" >&5 +$as_echo "$as_me: WARNING: ${newlib_msg_warn}" >&2;} +fi + +# Hard-code OBJEXT. Normally it is set by AC_OBJEXT, but we +# use oext, which is set in configure.host based on the target platform. +OBJEXT=${oext} + + + + + + + + + + + +ac_config_files="$ac_config_files Makefile" + +cat >confcache <<\_ACEOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs, see configure's option --config-cache. +# It is not useful on other systems. If it contains results you don't +# want to keep, you may remove or edit it. +# +# config.status only pays attention to the cache file if you give it +# the --recheck option to rerun configure. +# +# `ac_cv_env_foo' variables (set or unset) will be overridden when +# loading this file, other *unset* `ac_cv_foo' will be assigned the +# following values. + +_ACEOF + +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, we kill variables containing newlines. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +( + for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + + (set) 2>&1 | + case $as_nl`(ac_space=' '; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + # `set' does not quote correctly, so add quotes: double-quote + # substitution turns \\\\ into \\, and sed turns \\ into \. + sed -n \ + "s/'/'\\\\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" + ;; #( + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) | + sed ' + /^ac_cv_env_/b end + t clear + :clear + s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ + t end + s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + :end' >>confcache +if diff "$cache_file" confcache >/dev/null 2>&1; then :; else + if test -w "$cache_file"; then + if test "x$cache_file" != "x/dev/null"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 +$as_echo "$as_me: updating cache $cache_file" >&6;} + if test ! -f "$cache_file" || test -h "$cache_file"; then + cat confcache >"$cache_file" + else + case $cache_file in #( + */* | ?:*) + mv -f confcache "$cache_file"$$ && + mv -f "$cache_file"$$ "$cache_file" ;; #( + *) + mv -f confcache "$cache_file" ;; + esac + fi + fi + else + { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 +$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} + fi +fi +rm -f confcache + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +# Transform confdefs.h into DEFS. +# Protect against shell expansion while executing Makefile rules. +# Protect against Makefile macro expansion. +# +# If the first sed substitution is executed (which looks for macros that +# take arguments), then branch to the quote section. Otherwise, +# look for a macro that doesn't take arguments. +ac_script=' +:mline +/\\$/{ + N + s,\\\n,, + b mline +} +t clear +:clear +s/^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*([^)]*)\)[ ]*\(.*\)/-D\1=\2/g +t quote +s/^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)/-D\1=\2/g +t quote +b any +:quote +s/[ `~#$^&*(){}\\|;'\''"<>?]/\\&/g +s/\[/\\&/g +s/\]/\\&/g +s/\$/$$/g +H +:any +${ + g + s/^\n// + s/\n/ /g + p +} +' +DEFS=`sed -n "$ac_script" confdefs.h` + + +ac_libobjs= +ac_ltlibobjs= +U= +for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue + # 1. Remove the extension, and $U if already installed. + ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' + ac_i=`$as_echo "$ac_i" | sed "$ac_script"` + # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR + # will be set to the directory where LIBOBJS objects are built. + as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" + as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' +done +LIBOBJS=$ac_libobjs + +LTLIBOBJS=$ac_ltlibobjs + + +if test -z "${MAY_SUPPLY_SYSCALLS_TRUE}" && test -z "${MAY_SUPPLY_SYSCALLS_FALSE}"; then + as_fn_error $? "conditional \"MAY_SUPPLY_SYSCALLS\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi + +if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then + as_fn_error $? "conditional \"AMDEP\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then + as_fn_error $? "conditional \"am__fastdepCC\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then + as_fn_error $? "conditional \"MAINTAINER_MODE\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${ELIX_LEVEL_0_TRUE}" && test -z "${ELIX_LEVEL_0_FALSE}"; then + as_fn_error $? "conditional \"ELIX_LEVEL_0\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${ELIX_LEVEL_1_TRUE}" && test -z "${ELIX_LEVEL_1_FALSE}"; then + as_fn_error $? "conditional \"ELIX_LEVEL_1\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${ELIX_LEVEL_2_TRUE}" && test -z "${ELIX_LEVEL_2_FALSE}"; then + as_fn_error $? "conditional \"ELIX_LEVEL_2\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${ELIX_LEVEL_3_TRUE}" && test -z "${ELIX_LEVEL_3_FALSE}"; then + as_fn_error $? "conditional \"ELIX_LEVEL_3\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${ELIX_LEVEL_4_TRUE}" && test -z "${ELIX_LEVEL_4_FALSE}"; then + as_fn_error $? "conditional \"ELIX_LEVEL_4\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${USE_LIBTOOL_TRUE}" && test -z "${USE_LIBTOOL_FALSE}"; then + as_fn_error $? "conditional \"USE_LIBTOOL\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi + +: "${CONFIG_STATUS=./config.status}" +ac_write_fail=0 +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files $CONFIG_STATUS" +{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 +$as_echo "$as_me: creating $CONFIG_STATUS" >&6;} +as_write_fail=0 +cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 +#! $SHELL +# Generated by $as_me. +# Run this file to recreate the current configuration. +# Compiler output produced by configure, useful for debugging +# configure, is in config.log if it exists. + +debug=false +ac_cs_recheck=false +ac_cs_silent=false + +SHELL=\${CONFIG_SHELL-$SHELL} +export SHELL +_ASEOF +cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + $as_echo "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -p'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -p' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -p' + fi +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +if test -x / >/dev/null 2>&1; then + as_test_x='test -x' +else + if ls -dL / >/dev/null 2>&1; then + as_ls_L_option=L + else + as_ls_L_option= + fi + as_test_x=' + eval sh -c '\'' + if test -d "$1"; then + test -d "$1/."; + else + case $1 in #( + -*)set "./$1";; + esac; + case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( + ???[sx]*):;;*)false;;esac;fi + '\'' sh + ' +fi +as_executable_p=$as_test_x + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +exec 6>&1 +## ----------------------------------- ## +## Main body of $CONFIG_STATUS script. ## +## ----------------------------------- ## +_ASEOF +test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# Save the log message, to keep $0 and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. +ac_log=" +This file was extended by newlib $as_me 3.1.0, which was +generated by GNU Autoconf 2.68. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +on `(hostname || uname -n) 2>/dev/null | sed 1q` +" + +_ACEOF + +case $ac_config_files in *" +"*) set x $ac_config_files; shift; ac_config_files=$*;; +esac + + + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# Files that config.status was made for. +config_files="$ac_config_files" +config_commands="$ac_config_commands" + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +ac_cs_usage="\ +\`$as_me' instantiates files and other configuration actions +from templates according to the current configuration. Unless the files +and actions are specified as TAGs, all are instantiated by default. + +Usage: $0 [OPTION]... [TAG]... + + -h, --help print this help, then exit + -V, --version print version number and configuration settings, then exit + --config print configuration, then exit + -q, --quiet, --silent + do not print progress messages + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + +Configuration files: +$config_files + +Configuration commands: +$config_commands + +Report bugs to the package provider." + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" +ac_cs_version="\\ +newlib config.status 3.1.0 +configured by $0, generated by GNU Autoconf 2.68, + with options \\"\$ac_cs_config\\" + +Copyright (C) 2010 Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." + +ac_pwd='$ac_pwd' +srcdir='$srcdir' +INSTALL='$INSTALL' +MKDIR_P='$MKDIR_P' +AWK='$AWK' +test -n "\$AWK" || AWK=awk +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# The default lists apply if the user does not specify any file. +ac_need_defaults=: +while test $# != 0 +do + case $1 in + --*=?*) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` + ac_shift=: + ;; + --*=) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg= + ac_shift=: + ;; + *) + ac_option=$1 + ac_optarg=$2 + ac_shift=shift + ;; + esac + + case $ac_option in + # Handling of the options. + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + ac_cs_recheck=: ;; + --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) + $as_echo "$ac_cs_version"; exit ;; + --config | --confi | --conf | --con | --co | --c ) + $as_echo "$ac_cs_config"; exit ;; + --debug | --debu | --deb | --de | --d | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + '') as_fn_error $? "missing file argument" ;; + esac + as_fn_append CONFIG_FILES " '$ac_optarg'" + ac_need_defaults=false;; + --he | --h | --help | --hel | -h ) + $as_echo "$ac_cs_usage"; exit ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil | --si | --s) + ac_cs_silent=: ;; + + # This is an error. + -*) as_fn_error $? "unrecognized option: \`$1' +Try \`$0 --help' for more information." ;; + + *) as_fn_append ac_config_targets " $1" + ac_need_defaults=false ;; + + esac + shift +done + +ac_configure_extra_args= + +if $ac_cs_silent; then + exec 6>/dev/null + ac_configure_extra_args="$ac_configure_extra_args --silent" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +if \$ac_cs_recheck; then + set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion + shift + \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 + CONFIG_SHELL='$SHELL' + export CONFIG_SHELL + exec "\$@" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX + $as_echo "$ac_log" +} >&5 + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# +# INIT-COMMANDS +# +AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + +# Handling of arguments. +for ac_config_target in $ac_config_targets +do + case $ac_config_target in + "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; + "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; + + *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; + esac +done + + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files + test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands +fi + +# Have a temporary directory for convenience. Make it in the build tree +# simply because there is no reason against having it here, and in addition, +# creating and moving files from /tmp can sometimes cause problems. +# Hook for its removal unless debugging. +# Note that there is a small window in which the directory will not be cleaned: +# after its creation but before its name has been assigned to `$tmp'. +$debug || +{ + tmp= ac_tmp= + trap 'exit_status=$? + : "${ac_tmp:=$tmp}" + { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status +' 0 + trap 'as_fn_exit 1' 1 2 13 15 +} +# Create a (secure) tmp directory for tmp files. + +{ + tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && + test -d "$tmp" +} || +{ + tmp=./conf$$-$RANDOM + (umask 077 && mkdir "$tmp") +} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 +ac_tmp=$tmp + +# Set up the scripts for CONFIG_FILES section. +# No need to generate them if there are no CONFIG_FILES. +# This happens for instance with `./config.status config.h'. +if test -n "$CONFIG_FILES"; then + + +ac_cr=`echo X | tr X '\015'` +# On cygwin, bash can eat \r inside `` if the user requested igncr. +# But we know of no other shell where ac_cr would be empty at this +# point, so we can use a bashism as a fallback. +if test "x$ac_cr" = x; then + eval ac_cr=\$\'\\r\' +fi +ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` +if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then + ac_cs_awk_cr='\\r' +else + ac_cs_awk_cr=$ac_cr +fi + +echo 'BEGIN {' >"$ac_tmp/subs1.awk" && +_ACEOF + + +{ + echo "cat >conf$$subs.awk <<_ACEOF" && + echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && + echo "_ACEOF" +} >conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 +ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` +ac_delim='%!_!# ' +for ac_last_try in false false false false false :; do + . ./conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + + ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` + if test $ac_delim_n = $ac_delim_num; then + break + elif $ac_last_try; then + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done +rm -f conf$$subs.sh + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && +_ACEOF +sed -n ' +h +s/^/S["/; s/!.*/"]=/ +p +g +s/^[^!]*!// +:repl +t repl +s/'"$ac_delim"'$// +t delim +:nl +h +s/\(.\{148\}\)..*/\1/ +t more1 +s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ +p +n +b repl +:more1 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t nl +:delim +h +s/\(.\{148\}\)..*/\1/ +t more2 +s/["\\]/\\&/g; s/^/"/; s/$/"/ +p +b +:more2 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t delim +' >$CONFIG_STATUS || ac_write_fail=1 +rm -f conf$$subs.awk +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +_ACAWK +cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && + for (key in S) S_is_set[key] = 1 + FS = "" + +} +{ + line = $ 0 + nfields = split(line, field, "@") + substed = 0 + len = length(field[1]) + for (i = 2; i < nfields; i++) { + key = field[i] + keylen = length(key) + if (S_is_set[key]) { + value = S[key] + line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) + len += length(value) + length(field[++i]) + substed = 1 + } else + len += 1 + keylen + } + + print line +} + +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then + sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" +else + cat +fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ + || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 +_ACEOF + +# VPATH may cause trouble with some makes, so we remove sole $(srcdir), +# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and +# trailing colons and then remove the whole line if VPATH becomes empty +# (actually we leave an empty line to preserve line numbers). +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ +h +s/// +s/^/:/ +s/[ ]*$/:/ +s/:\$(srcdir):/:/g +s/:\${srcdir}:/:/g +s/:@srcdir@:/:/g +s/^:*// +s/:*$// +x +s/\(=[ ]*\).*/\1/ +G +s/\n// +s/^[^=]*=[ ]*$// +}' +fi + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +fi # test -n "$CONFIG_FILES" + + +eval set X " :F $CONFIG_FILES :C $CONFIG_COMMANDS" +shift +for ac_tag +do + case $ac_tag in + :[FHLC]) ac_mode=$ac_tag; continue;; + esac + case $ac_mode$ac_tag in + :[FHL]*:*);; + :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; + :[FH]-) ac_tag=-:-;; + :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; + esac + ac_save_IFS=$IFS + IFS=: + set x $ac_tag + IFS=$ac_save_IFS + shift + ac_file=$1 + shift + + case $ac_mode in + :L) ac_source=$1;; + :[FH]) + ac_file_inputs= + for ac_f + do + case $ac_f in + -) ac_f="$ac_tmp/stdin";; + *) # Look for the file first in the build tree, then in the source tree + # (if the path is not absolute). The absolute path cannot be DOS-style, + # because $ac_f cannot contain `:'. + test -f "$ac_f" || + case $ac_f in + [\\/$]*) false;; + *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; + esac || + as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; + esac + case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac + as_fn_append ac_file_inputs " '$ac_f'" + done + + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + configure_input='Generated from '` + $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' + `' by configure.' + if test x"$ac_file" != x-; then + configure_input="$ac_file. $configure_input" + { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 +$as_echo "$as_me: creating $ac_file" >&6;} + fi + # Neutralize special characters interpreted by sed in replacement strings. + case $configure_input in #( + *\&* | *\|* | *\\* ) + ac_sed_conf_input=`$as_echo "$configure_input" | + sed 's/[\\\\&|]/\\\\&/g'`;; #( + *) ac_sed_conf_input=$configure_input;; + esac + + case $ac_tag in + *:-:* | *:-) cat >"$ac_tmp/stdin" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; + esac + ;; + esac + + ac_dir=`$as_dirname -- "$ac_file" || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + as_dir="$ac_dir"; as_fn_mkdir_p + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + + case $ac_mode in + :F) + # + # CONFIG_FILE + # + + case $INSTALL in + [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; + *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; + esac + ac_MKDIR_P=$MKDIR_P + case $MKDIR_P in + [\\/$]* | ?:[\\/]* ) ;; + */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; + esac +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# If the template does not know about datarootdir, expand it. +# FIXME: This hack should be removed a few years after 2.60. +ac_datarootdir_hack=; ac_datarootdir_seen= +ac_sed_dataroot=' +/datarootdir/ { + p + q +} +/@datadir@/p +/@docdir@/p +/@infodir@/p +/@localedir@/p +/@mandir@/p' +case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in +*datarootdir*) ac_datarootdir_seen=yes;; +*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 +$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + ac_datarootdir_hack=' + s&@datadir@&$datadir&g + s&@docdir@&$docdir&g + s&@infodir@&$infodir&g + s&@localedir@&$localedir&g + s&@mandir@&$mandir&g + s&\\\${datarootdir}&$datarootdir&g' ;; +esac +_ACEOF + +# Neutralize VPATH when `$srcdir' = `.'. +# Shell code in configure.ac might set extrasub. +# FIXME: do we really want to maintain this feature? +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_sed_extra="$ac_vpsub +$extrasub +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s|@configure_input@|$ac_sed_conf_input|;t t +s&@top_builddir@&$ac_top_builddir_sub&;t t +s&@top_build_prefix@&$ac_top_build_prefix&;t t +s&@srcdir@&$ac_srcdir&;t t +s&@abs_srcdir@&$ac_abs_srcdir&;t t +s&@top_srcdir@&$ac_top_srcdir&;t t +s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t +s&@builddir@&$ac_builddir&;t t +s&@abs_builddir@&$ac_abs_builddir&;t t +s&@abs_top_builddir@&$ac_abs_top_builddir&;t t +s&@INSTALL@&$ac_INSTALL&;t t +s&@MKDIR_P@&$ac_MKDIR_P&;t t +$ac_datarootdir_hack +" +eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ + >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + +test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && + { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && + { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ + "$ac_tmp/out"`; test -z "$ac_out"; } && + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&5 +$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&2;} + + rm -f "$ac_tmp/stdin" + case $ac_file in + -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; + *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; + esac \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + ;; + + + :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 +$as_echo "$as_me: executing $ac_file commands" >&6;} + ;; + esac + + + case $ac_file$ac_mode in + "depfiles":C) test x"$AMDEP_TRUE" != x"" || { + # Autoconf 2.62 quotes --file arguments for eval, but not when files + # are listed without --file. Let's play safe and only enable the eval + # if we detect the quoting. + case $CONFIG_FILES in + *\'*) eval set x "$CONFIG_FILES" ;; + *) set x $CONFIG_FILES ;; + esac + shift + for mf + do + # Strip MF so we end up with the name of the file. + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named `Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # Grep'ing the whole file is not good either: AIX grep has a line + # limit of 2048, but all sed's we know have understand at least 4000. + if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then + dirpart=`$as_dirname -- "$mf" || +$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$mf" : 'X\(//\)[^/]' \| \ + X"$mf" : 'X\(//\)$' \| \ + X"$mf" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$mf" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + else + continue + fi + # Extract the definition of DEPDIR, am__include, and am__quote + # from the Makefile without running `make'. + DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` + test -z "$DEPDIR" && continue + am__include=`sed -n 's/^am__include = //p' < "$mf"` + test -z "am__include" && continue + am__quote=`sed -n 's/^am__quote = //p' < "$mf"` + # When using ansi2knr, U may be empty or an underscore; expand it + U=`sed -n 's/^U = //p' < "$mf"` + # Find all dependency output files, they are included files with + # $(DEPDIR) in their names. We invoke sed twice because it is the + # simplest approach to changing $(DEPDIR) to its actual value in the + # expansion. + for file in `sed -n " + s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do + # Make sure the directory exists. + test -f "$dirpart/$file" && continue + fdir=`$as_dirname -- "$file" || +$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$file" : 'X\(//\)[^/]' \| \ + X"$file" : 'X\(//\)$' \| \ + X"$file" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + as_dir=$dirpart/$fdir; as_fn_mkdir_p + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done + done +} + ;; + + esac +done # for ac_tag + + +as_fn_exit 0 +_ACEOF +ac_clean_files=$ac_clean_files_save + +test $ac_write_fail = 0 || + as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 + + +# configure is writing to config.log, and then calls config.status. +# config.status does its own redirection, appending to config.log. +# Unfortunately, on DOS this fails, as config.log is still kept open +# by configure, so config.status won't be able to write to it; its +# output is simply discarded. So we exec the FD to /dev/null, +# effectively closing config.log, so it can be properly (re)opened and +# appended to by config.status. When coming back to configure, we +# need to make the FD available again. +if test "$no_create" != yes; then + ac_cs_success=: + ac_config_status_args= + test "$silent" = yes && + ac_config_status_args="$ac_config_status_args --quiet" + exec 5>/dev/null + $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false + exec 5>>config.log + # Use ||, not &&, to avoid exiting from the if with $? = 1, which + # would make configure fail if this is the last instruction. + $ac_cs_success || as_fn_exit 1 +fi +if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 +$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} +fi + diff --git a/newlib/libc/machine/amdgcn/configure.in b/newlib/libc/machine/amdgcn/configure.in new file mode 100644 index 000000000..028e9d7e0 --- /dev/null +++ b/newlib/libc/machine/amdgcn/configure.in @@ -0,0 +1,14 @@ +dnl This is the newlib/libc/machine/amdgcn configure.in file. +dnl Process this file with autoconf to produce a configure script. + +AC_PREREQ(2.59) +AC_INIT([newlib],[NEWLIB_VERSION]) +AC_CONFIG_SRCDIR([Makefile.am]) + +dnl Can't be done in NEWLIB_CONFIGURE because that confuses automake. +AC_CONFIG_AUX_DIR(../../../..) + +NEWLIB_CONFIGURE(../../..) + +AC_CONFIG_FILES([Makefile]) +AC_OUTPUT diff --git a/newlib/libc/machine/amdgcn/exit-value.h b/newlib/libc/machine/amdgcn/exit-value.h new file mode 100644 index 000000000..6e88625b7 --- /dev/null +++ b/newlib/libc/machine/amdgcn/exit-value.h @@ -0,0 +1,48 @@ +/* + * Support file for amdgcn in newlib. + * Copyright (c) 2017 Mentor Graphics. + * + * The authors hereby grant permission to use, copy, modify, distribute, + * and license this software and its documentation for any purpose, provided + * that existing copyright notices are retained in all copies and that this + * notice is included verbatim in any distributions. No written agreement, + * license, or royalty fee is required for any of the authorized uses. + * Modifications to this software may be copyrighted by their authors + * and need not follow the licensing terms described here, provided that + * the new terms are clearly indicated on the first page of each file where + * they apply. + */ + +#ifndef _AMDGCN_EXIT_VALUE_H_ +#define _AMDGCN_EXIT_VALUE_H_ + +static inline void __attribute__((noreturn)) +exit_with_int (int val) +{ + /* Write the exit value to the conventional place. */ + int *return_value; + asm ("s_load_dwordx2 %0, s[8:9], 16 glc\n\t" + "s_waitcnt 0" : "=Sg"(return_value)); + *return_value = val; + + /* Terminate the current kernel. */ + asm ("s_dcache_wb"); + asm ("s_endpgm"); + __builtin_unreachable (); +} + +static inline void __attribute__((noreturn)) +exit_with_status_and_signal (int val, int signal) +{ + if (signal == 0) + val = val & 0xff; + else + { + val = (128 + signal) & 0xff; + signal = signal & 0xff; + } + + exit_with_int ((0xffff << 16) | (signal << 8) | val); +} + +#endif diff --git a/newlib/libc/machine/amdgcn/exit.c b/newlib/libc/machine/amdgcn/exit.c new file mode 100644 index 000000000..bdd532edd --- /dev/null +++ b/newlib/libc/machine/amdgcn/exit.c @@ -0,0 +1,23 @@ +/* + * Support file for amdgcn in newlib. + * Copyright (c) 2014-2017 Mentor Graphics. + * + * The authors hereby grant permission to use, copy, modify, distribute, + * and license this software and its documentation for any purpose, provided + * that existing copyright notices are retained in all copies and that this + * notice is included verbatim in any distributions. No written agreement, + * license, or royalty fee is required for any of the authorized uses. + * Modifications to this software may be copyrighted by their authors + * and need not follow the licensing terms described here, provided that + * the new terms are clearly indicated on the first page of each file where + * they apply. + */ + +#include +#include "exit-value.h" + +void __attribute__((noreturn)) +exit (int val) +{ + exit_with_status_and_signal (val, 0); +} diff --git a/newlib/libc/machine/amdgcn/getreent.c b/newlib/libc/machine/amdgcn/getreent.c new file mode 100644 index 000000000..acf10a97f --- /dev/null +++ b/newlib/libc/machine/amdgcn/getreent.c @@ -0,0 +1,79 @@ +/* get thread-specific reentrant pointer */ + +#include +#include +#include + +/* Copied from the HSA documentation. */ +typedef struct hsa_signal_s { + uint64_t handle; +} hsa_signal_t; +typedef struct hsa_kernel_dispatch_packet_s { + uint16_t header ; + uint16_t setup; + uint16_t workgroup_size_x ; + uint16_t workgroup_size_y ; + uint16_t workgroup_size_z; + uint16_t reserved0; + uint32_t grid_size_x ; + uint32_t grid_size_y ; + uint32_t grid_size_z; + uint32_t private_segment_size; + uint32_t group_segment_size; + uint64_t kernel_object; + uint64_t reserved2; + hsa_signal_t completion_signal; +} hsa_kernel_dispatch_packet_t; + +struct _reent * +__getreent (void) +{ + /* Place the reent data at the top of the stack allocation. + s[0:1] contains a 48-bit private segment base address. + s11 contains the offset to the base of the stack. + s[4:5] contains the dispatch pointer. + + WARNING: this code will break if s[0:3] is ever used for anything! */ + const register long buffer_descriptor asm("s0"); + long private_segment = buffer_descriptor & 0x0000ffffffffffff; + const register int stack_offset asm("s11"); + const register hsa_kernel_dispatch_packet_t *dispatch_ptr asm("s4"); + + struct data { + int marker; + struct _reent reent; + } *data; + + long stack_base = private_segment + stack_offset; + long stack_end = stack_base + dispatch_ptr->private_segment_size * 64; + long addr = (stack_end - sizeof(struct data)) & ~7; + data = (struct data *)addr; + + register long sp asm("s16"); + if (sp >= addr) + goto stackoverflow; + + /* Place a marker in s3 to indicate that the reent data is initialized. + The register is known to hold part of an unused buffer descriptor + when the kernel is launched. This may not be unused forever, but + we already used s0 and s1 above, so this doesn't do extra harm. */ + register int s3 asm("s3"); + if (s3 != 123456) + { + asm("s_mov_b32 s3, 123456"); + data->marker = 123456; + + __builtin_memset (&data->reent, 0, sizeof(struct _reent)); + _REENT_INIT_PTR_ZEROED (&data->reent); + } + else if (data->marker != 123456) + goto stackoverflow; + + + return &data->reent; + +stackoverflow: + write (2, "GCN Stack Overflow!\n", 20); + abort (); +} + diff --git a/newlib/libc/machine/amdgcn/malloc_support.c b/newlib/libc/machine/amdgcn/malloc_support.c new file mode 100644 index 000000000..4848c978c --- /dev/null +++ b/newlib/libc/machine/amdgcn/malloc_support.c @@ -0,0 +1,111 @@ +/* + * Support file for AMDGCN in newlib. + * Copyright (c) 2017 Mentor Graphics. + * + * The authors hereby grant permission to use, copy, modify, distribute, + * and license this software and its documentation for any purpose, provided + * that existing copyright notices are retained in all copies and that this + * notice is included verbatim in any distributions. No written agreement, + * license, or royalty fee is required for any of the authorized uses. + * Modifications to this software may be copyrighted by their authors + * and need not follow the licensing terms described here, provided that + * the new terms are clearly indicated on the first page of each file where + * they apply. + */ + +#include +#include +#include + +/* _sbrk_r expects us to use the real errno, not the reentrant one. */ +#include +#undef errno +extern int errno; + +/* The runtime passes in heap space like this. */ +struct heap { + int64_t size; + char data[0]; +}; + +static char *__heap_ptr = (char*)-1; +static char *__heap_end = (char*)-1; +static int __heap_lock = 0; +static void *__heap_lock_id = NULL; +static int __heap_lock_cnt = 0; + +void * +sbrk (ptrdiff_t nbytes) +{ + if (__heap_ptr == (char *)-1) + { + /* Find the heap from kernargs. + The kernargs pointer is in s[8:9]. + This will break if the enable_sgpr_* flags are ever changed. */ + char *kernargs; + asm ("s_mov_b64 %0, s[8:9]" : "=Sg"(kernargs)); + + /* The heap data is at kernargs[3]. */ + struct heap *heap = *(struct heap **)(kernargs + 24); + + __heap_ptr = heap->data; + __heap_end = __heap_ptr + heap->size; + } + + if ((__heap_ptr + nbytes) >= __heap_end) + { + errno = ENOMEM; + return (void*)-1; + } + + char *base = __heap_ptr; + __heap_ptr += nbytes; + + return base; +} + +void +__malloc_lock (struct _reent *reent) +{ + void *id = reent; + + if (id == __heap_lock_id) + { + if (__heap_lock_cnt < 1) + abort (); + ++__heap_lock_cnt; + return; + } + + while (__sync_lock_test_and_set (&__heap_lock, 1)) + /* A sleep seems like it should allow the wavefront to yeild (maybe?) + Use the shortest possible sleep time of 1*64 cycles. */ + asm volatile ("s_sleep\t1" ::: "memory"); + + if (__heap_lock_id != NULL) + abort (); + if (__heap_lock_cnt != 0) + abort (); + + __heap_lock_cnt = 1; + __heap_lock_id = id; +} + +void +__malloc_unlock (struct _reent *reent) +{ + void *id = reent; + + if (id != __heap_lock_id) + abort (); + if (__heap_lock_cnt < 1) + abort (); + + --__heap_lock_cnt; + + if (__heap_lock_cnt > 0) + return; + + __heap_lock_id = NULL; + __sync_lock_release (&__heap_lock); +} diff --git a/newlib/libc/machine/amdgcn/signal.c b/newlib/libc/machine/amdgcn/signal.c new file mode 100644 index 000000000..033d8e5cc --- /dev/null +++ b/newlib/libc/machine/amdgcn/signal.c @@ -0,0 +1,10 @@ +#include +#include + +_sig_func_ptr +signal (int sig, + _sig_func_ptr func) +{ + errno = EINVAL; + return NULL; +} diff --git a/newlib/libc/machine/configure b/newlib/libc/machine/configure index f3229e942..de68f32fb 100755 --- a/newlib/libc/machine/configure +++ b/newlib/libc/machine/configure @@ -787,6 +787,7 @@ CPPFLAGS CPP' ac_subdirs_all='a29k aarch64 +amdgcn arc arm bfin @@ -11502,7 +11503,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 11505 "configure" +#line 11506 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -11608,7 +11609,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 11611 "configure" +#line 11612 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -11854,6 +11855,8 @@ if test -n "${machine_dir}"; then subdirs="$subdirs a29k" ;; aarch64) subdirs="$subdirs aarch64" + ;; + amdgcn) subdirs="$subdirs amdgcn" ;; arc) subdirs="$subdirs arc" ;; diff --git a/newlib/libc/machine/configure.in b/newlib/libc/machine/configure.in index 8ebe68bdb..0d4068c13 100644 --- a/newlib/libc/machine/configure.in +++ b/newlib/libc/machine/configure.in @@ -25,6 +25,7 @@ if test -n "${machine_dir}"; then case ${machine_dir} in a29k) AC_CONFIG_SUBDIRS(a29k) ;; aarch64) AC_CONFIG_SUBDIRS(aarch64) ;; + amdgcn) AC_CONFIG_SUBDIRS(amdgcn) ;; arc) AC_CONFIG_SUBDIRS(arc) ;; arm) AC_CONFIG_SUBDIRS(arm) ;; bfin) AC_CONFIG_SUBDIRS(bfin) ;; diff --git a/newlib/libc/ssp/stack_protector.c b/newlib/libc/ssp/stack_protector.c index ee014b69d..cd51543f0 100644 --- a/newlib/libc/ssp/stack_protector.c +++ b/newlib/libc/ssp/stack_protector.c @@ -5,6 +5,11 @@ #include #include +#if defined(__AMDGCN__) +/* GCN does not support constructors, yet. */ +uintptr_t __stack_chk_guard = 0x00000aff; /* 0, 0, '\n', 255 */ + +#else uintptr_t __stack_chk_guard = 0; void @@ -24,6 +29,7 @@ __stack_chk_init (void) ((unsigned char *)&__stack_chk_guard)[3] = 255; #endif } +#endif void __attribute__((__noreturn__)) diff --git a/newlib/libc/sys/amdgcn/Makefile.am b/newlib/libc/sys/amdgcn/Makefile.am new file mode 100644 index 000000000..171677694 --- /dev/null +++ b/newlib/libc/sys/amdgcn/Makefile.am @@ -0,0 +1,16 @@ +## Process this file with automake to generate Makefile.in + +AUTOMAKE_OPTIONS = cygnus + +INCLUDES = $(NEWLIB_CFLAGS) $(CROSS_CFLAGS) $(TARGET_CFLAGS) + +AM_CCASFLAGS = $(INCLUDES) $(CFLAGS) + +noinst_LIBRARIES = lib.a + +lib_a_SOURCES = close.c fstat.c isatty.c lseek.c read.c write.c +lib_a_CCASFLAGS = $(AM_CCASFLAGS) +lib_a_CFLAGS = $(AM_CFLAGS) + +ACLOCAL_AMFLAGS = -I ../../.. -I ../../../.. +CONFIG_STATUS_DEPENDENCIES = $(newlib_basedir)/configure.host diff --git a/newlib/libc/sys/amdgcn/Makefile.in b/newlib/libc/sys/amdgcn/Makefile.in new file mode 100644 index 000000000..dc22992e5 --- /dev/null +++ b/newlib/libc/sys/amdgcn/Makefile.in @@ -0,0 +1,470 @@ +# Makefile.in generated by automake 1.11.6 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software +# Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +am__make_dryrun = \ + { \ + am__dry=no; \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ + | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ + *) \ + for am__flg in $$MAKEFLAGS; do \ + case $$am__flg in \ + *=*|--*) ;; \ + *n*) am__dry=yes; break;; \ + esac; \ + done;; \ + esac; \ + test $$am__dry = yes; \ + } +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = . +DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ + $(top_srcdir)/configure $(am__configure_deps) \ + $(srcdir)/../../../../mkinstalldirs +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/../../../acinclude.m4 \ + $(top_srcdir)/configure.in +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ + configure.lineno config.status.lineno +mkinstalldirs = $(SHELL) $(top_srcdir)/../../../../mkinstalldirs +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +LIBRARIES = $(noinst_LIBRARIES) +ARFLAGS = cru +lib_a_AR = $(AR) $(ARFLAGS) +lib_a_LIBADD = +am_lib_a_OBJECTS = lib_a-close.$(OBJEXT) lib_a-fstat.$(OBJEXT) \ + lib_a-isatty.$(OBJEXT) lib_a-lseek.$(OBJEXT) \ + lib_a-read.$(OBJEXT) lib_a-write.$(OBJEXT) +lib_a_OBJECTS = $(am_lib_a_OBJECTS) +DEFAULT_INCLUDES = -I.@am__isrc@ +depcomp = +am__depfiles_maybe = +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +SOURCES = $(lib_a_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +ETAGS = etags +CTAGS = ctags +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCAS = @CCAS@ +CCASFLAGS = @CCASFLAGS@ +CCDEPMODE = @CCDEPMODE@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +NEWLIB_CFLAGS = @NEWLIB_CFLAGS@ +NO_INCLUDE_LIST = @NO_INCLUDE_LIST@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +READELF = @READELF@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +aext = @aext@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +libm_machine_dir = @libm_machine_dir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +lpfx = @lpfx@ +machine_dir = @machine_dir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +newlib_basedir = @newlib_basedir@ +oext = @oext@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sys_dir = @sys_dir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +AUTOMAKE_OPTIONS = cygnus +INCLUDES = $(NEWLIB_CFLAGS) $(CROSS_CFLAGS) $(TARGET_CFLAGS) +AM_CCASFLAGS = $(INCLUDES) $(CFLAGS) +noinst_LIBRARIES = lib.a +lib_a_SOURCES = close.c fstat.c isatty.c lseek.c read.c write.c +lib_a_CCASFLAGS = $(AM_CCASFLAGS) +lib_a_CFLAGS = $(AM_CFLAGS) +ACLOCAL_AMFLAGS = -I ../../.. -I ../../../.. +CONFIG_STATUS_DEPENDENCIES = $(newlib_basedir)/configure.host +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .o .obj +am--refresh: Makefile + @: +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + echo ' cd $(srcdir) && $(AUTOMAKE) --cygnus'; \ + $(am__cd) $(srcdir) && $(AUTOMAKE) --cygnus \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --cygnus Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --cygnus Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + echo ' $(SHELL) ./config.status'; \ + $(SHELL) ./config.status;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + $(SHELL) ./config.status --recheck + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + $(am__cd) $(srcdir) && $(AUTOCONF) +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) +$(am__aclocal_m4_deps): + +clean-noinstLIBRARIES: + -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) +lib.a: $(lib_a_OBJECTS) $(lib_a_DEPENDENCIES) $(EXTRA_lib_a_DEPENDENCIES) + -rm -f lib.a + $(lib_a_AR) lib.a $(lib_a_OBJECTS) $(lib_a_LIBADD) + $(RANLIB) lib.a + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +.c.o: + $(COMPILE) -c $< + +.c.obj: + $(COMPILE) -c `$(CYGPATH_W) '$<'` + +lib_a-close.o: close.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-close.o `test -f 'close.c' || echo '$(srcdir)/'`close.c + +lib_a-close.obj: close.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-close.obj `if test -f 'close.c'; then $(CYGPATH_W) 'close.c'; else $(CYGPATH_W) '$(srcdir)/close.c'; fi` + +lib_a-fstat.o: fstat.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-fstat.o `test -f 'fstat.c' || echo '$(srcdir)/'`fstat.c + +lib_a-fstat.obj: fstat.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-fstat.obj `if test -f 'fstat.c'; then $(CYGPATH_W) 'fstat.c'; else $(CYGPATH_W) '$(srcdir)/fstat.c'; fi` + +lib_a-isatty.o: isatty.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-isatty.o `test -f 'isatty.c' || echo '$(srcdir)/'`isatty.c + +lib_a-isatty.obj: isatty.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-isatty.obj `if test -f 'isatty.c'; then $(CYGPATH_W) 'isatty.c'; else $(CYGPATH_W) '$(srcdir)/isatty.c'; fi` + +lib_a-lseek.o: lseek.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-lseek.o `test -f 'lseek.c' || echo '$(srcdir)/'`lseek.c + +lib_a-lseek.obj: lseek.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-lseek.obj `if test -f 'lseek.c'; then $(CYGPATH_W) 'lseek.c'; else $(CYGPATH_W) '$(srcdir)/lseek.c'; fi` + +lib_a-read.o: read.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-read.o `test -f 'read.c' || echo '$(srcdir)/'`read.c + +lib_a-read.obj: read.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-read.obj `if test -f 'read.c'; then $(CYGPATH_W) 'read.c'; else $(CYGPATH_W) '$(srcdir)/read.c'; fi` + +lib_a-write.o: write.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-write.o `test -f 'write.c' || echo '$(srcdir)/'`write.c + +lib_a-write.obj: write.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-write.obj `if test -f 'write.c'; then $(CYGPATH_W) 'write.c'; else $(CYGPATH_W) '$(srcdir)/write.c'; fi` + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags +check-am: +check: check-am +all-am: Makefile $(LIBRARIES) +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-noinstLIBRARIES mostlyclean-am + +distclean: distclean-am + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -rf $(top_srcdir)/autom4te.cache + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am am--refresh check check-am clean \ + clean-generic clean-noinstLIBRARIES ctags distclean \ + distclean-compile distclean-generic distclean-tags dvi dvi-am \ + html html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-pdf install-pdf-am \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \ + uninstall-am + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/newlib/libc/sys/amdgcn/aclocal.m4 b/newlib/libc/sys/amdgcn/aclocal.m4 new file mode 100644 index 000000000..18dab02aa --- /dev/null +++ b/newlib/libc/sys/amdgcn/aclocal.m4 @@ -0,0 +1,1012 @@ +# generated automatically by aclocal 1.11.6 -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, +# 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, +# Inc. +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +m4_ifndef([AC_AUTOCONF_VERSION], + [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl +m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.68],, +[m4_warning([this file was generated for autoconf 2.68. +You have another version of autoconf. It may work, but is not guaranteed to. +If you have problems, you may need to regenerate the build system entirely. +To do so, use the procedure documented by the package, typically `autoreconf'.])]) + +# Copyright (C) 2002, 2003, 2005, 2006, 2007, 2008, 2011 Free Software +# Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 1 + +# AM_AUTOMAKE_VERSION(VERSION) +# ---------------------------- +# Automake X.Y traces this macro to ensure aclocal.m4 has been +# generated from the m4 files accompanying Automake X.Y. +# (This private macro should not be called outside this file.) +AC_DEFUN([AM_AUTOMAKE_VERSION], +[am__api_version='1.11' +dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to +dnl require some minimum version. Point them to the right macro. +m4_if([$1], [1.11.6], [], + [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl +]) + +# _AM_AUTOCONF_VERSION(VERSION) +# ----------------------------- +# aclocal traces this macro to find the Autoconf version. +# This is a private macro too. Using m4_define simplifies +# the logic in aclocal, which can simply ignore this definition. +m4_define([_AM_AUTOCONF_VERSION], []) + +# AM_SET_CURRENT_AUTOMAKE_VERSION +# ------------------------------- +# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. +# This function is AC_REQUIREd by AM_INIT_AUTOMAKE. +AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], +[AM_AUTOMAKE_VERSION([1.11.6])dnl +m4_ifndef([AC_AUTOCONF_VERSION], + [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl +_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) + +# AM_AUX_DIR_EXPAND -*- Autoconf -*- + +# Copyright (C) 2001, 2003, 2005, 2011 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 1 + +# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets +# $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to +# `$srcdir', `$srcdir/..', or `$srcdir/../..'. +# +# Of course, Automake must honor this variable whenever it calls a +# tool from the auxiliary directory. The problem is that $srcdir (and +# therefore $ac_aux_dir as well) can be either absolute or relative, +# depending on how configure is run. This is pretty annoying, since +# it makes $ac_aux_dir quite unusable in subdirectories: in the top +# source directory, any form will work fine, but in subdirectories a +# relative path needs to be adjusted first. +# +# $ac_aux_dir/missing +# fails when called from a subdirectory if $ac_aux_dir is relative +# $top_srcdir/$ac_aux_dir/missing +# fails if $ac_aux_dir is absolute, +# fails when called from a subdirectory in a VPATH build with +# a relative $ac_aux_dir +# +# The reason of the latter failure is that $top_srcdir and $ac_aux_dir +# are both prefixed by $srcdir. In an in-source build this is usually +# harmless because $srcdir is `.', but things will broke when you +# start a VPATH build or use an absolute $srcdir. +# +# So we could use something similar to $top_srcdir/$ac_aux_dir/missing, +# iff we strip the leading $srcdir from $ac_aux_dir. That would be: +# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` +# and then we would define $MISSING as +# MISSING="\${SHELL} $am_aux_dir/missing" +# This will work as long as MISSING is not called from configure, because +# unfortunately $(top_srcdir) has no meaning in configure. +# However there are other variables, like CC, which are often used in +# configure, and could therefore not use this "fixed" $ac_aux_dir. +# +# Another solution, used here, is to always expand $ac_aux_dir to an +# absolute PATH. The drawback is that using absolute paths prevent a +# configured tree to be moved without reconfiguration. + +AC_DEFUN([AM_AUX_DIR_EXPAND], +[dnl Rely on autoconf to set up CDPATH properly. +AC_PREREQ([2.50])dnl +# expand $ac_aux_dir to an absolute path +am_aux_dir=`cd $ac_aux_dir && pwd` +]) + +# AM_CONDITIONAL -*- Autoconf -*- + +# Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005, 2006, 2008 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 9 + +# AM_CONDITIONAL(NAME, SHELL-CONDITION) +# ------------------------------------- +# Define a conditional. +AC_DEFUN([AM_CONDITIONAL], +[AC_PREREQ(2.52)dnl + ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], + [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl +AC_SUBST([$1_TRUE])dnl +AC_SUBST([$1_FALSE])dnl +_AM_SUBST_NOTMAKE([$1_TRUE])dnl +_AM_SUBST_NOTMAKE([$1_FALSE])dnl +m4_define([_AM_COND_VALUE_$1], [$2])dnl +if $2; then + $1_TRUE= + $1_FALSE='#' +else + $1_TRUE='#' + $1_FALSE= +fi +AC_CONFIG_COMMANDS_PRE( +[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then + AC_MSG_ERROR([[conditional "$1" was never defined. +Usually this means the macro was only invoked conditionally.]]) +fi])]) + +# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2009, +# 2010, 2011 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 12 + +# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be +# written in clear, in which case automake, when reading aclocal.m4, +# will think it sees a *use*, and therefore will trigger all it's +# C support machinery. Also note that it means that autoscan, seeing +# CC etc. in the Makefile, will ask for an AC_PROG_CC use... + + +# _AM_DEPENDENCIES(NAME) +# ---------------------- +# See how the compiler implements dependency checking. +# NAME is "CC", "CXX", "GCJ", or "OBJC". +# We try a few techniques and use that to set a single cache variable. +# +# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was +# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular +# dependency, and given that the user is not expected to run this macro, +# just rely on AC_PROG_CC. +AC_DEFUN([_AM_DEPENDENCIES], +[AC_REQUIRE([AM_SET_DEPDIR])dnl +AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl +AC_REQUIRE([AM_MAKE_INCLUDE])dnl +AC_REQUIRE([AM_DEP_TRACK])dnl + +ifelse([$1], CC, [depcc="$CC" am_compiler_list=], + [$1], CXX, [depcc="$CXX" am_compiler_list=], + [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'], + [$1], UPC, [depcc="$UPC" am_compiler_list=], + [$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'], + [depcc="$$1" am_compiler_list=]) + +AC_CACHE_CHECK([dependency style of $depcc], + [am_cv_$1_dependencies_compiler_type], +[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named `D' -- because `-MD' means `put the output + # in D'. + rm -rf conftest.dir + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_$1_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` + fi + am__universal=false + m4_case([$1], [CC], + [case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac], + [CXX], + [case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac]) + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with + # Solaris 8's {/usr,}/bin/sh. + touch sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with `-c' and `-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle `-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # after this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvc7 | msvc7msys | msvisualcpp | msvcmsys) + # This compiler won't grok `-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_$1_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_$1_dependencies_compiler_type=none +fi +]) +AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) +AM_CONDITIONAL([am__fastdep$1], [ + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) +]) + + +# AM_SET_DEPDIR +# ------------- +# Choose a directory name for dependency files. +# This macro is AC_REQUIREd in _AM_DEPENDENCIES +AC_DEFUN([AM_SET_DEPDIR], +[AC_REQUIRE([AM_SET_LEADING_DOT])dnl +AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl +]) + + +# AM_DEP_TRACK +# ------------ +AC_DEFUN([AM_DEP_TRACK], +[AC_ARG_ENABLE(dependency-tracking, +[ --disable-dependency-tracking speeds up one-time build + --enable-dependency-tracking do not reject slow dependency extractors]) +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' + am__nodep='_no' +fi +AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) +AC_SUBST([AMDEPBACKSLASH])dnl +_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl +AC_SUBST([am__nodep])dnl +_AM_SUBST_NOTMAKE([am__nodep])dnl +]) + +# Generate code to set up dependency tracking. -*- Autoconf -*- + +# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2008 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +#serial 5 + +# _AM_OUTPUT_DEPENDENCY_COMMANDS +# ------------------------------ +AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], +[{ + # Autoconf 2.62 quotes --file arguments for eval, but not when files + # are listed without --file. Let's play safe and only enable the eval + # if we detect the quoting. + case $CONFIG_FILES in + *\'*) eval set x "$CONFIG_FILES" ;; + *) set x $CONFIG_FILES ;; + esac + shift + for mf + do + # Strip MF so we end up with the name of the file. + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named `Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # Grep'ing the whole file is not good either: AIX grep has a line + # limit of 2048, but all sed's we know have understand at least 4000. + if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then + dirpart=`AS_DIRNAME("$mf")` + else + continue + fi + # Extract the definition of DEPDIR, am__include, and am__quote + # from the Makefile without running `make'. + DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` + test -z "$DEPDIR" && continue + am__include=`sed -n 's/^am__include = //p' < "$mf"` + test -z "am__include" && continue + am__quote=`sed -n 's/^am__quote = //p' < "$mf"` + # When using ansi2knr, U may be empty or an underscore; expand it + U=`sed -n 's/^U = //p' < "$mf"` + # Find all dependency output files, they are included files with + # $(DEPDIR) in their names. We invoke sed twice because it is the + # simplest approach to changing $(DEPDIR) to its actual value in the + # expansion. + for file in `sed -n " + s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do + # Make sure the directory exists. + test -f "$dirpart/$file" && continue + fdir=`AS_DIRNAME(["$file"])` + AS_MKDIR_P([$dirpart/$fdir]) + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done + done +} +])# _AM_OUTPUT_DEPENDENCY_COMMANDS + + +# AM_OUTPUT_DEPENDENCY_COMMANDS +# ----------------------------- +# This macro should only be invoked once -- use via AC_REQUIRE. +# +# This code is only required when automatic dependency tracking +# is enabled. FIXME. This creates each `.P' file that we will +# need in order to bootstrap the dependency handling code. +AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], +[AC_CONFIG_COMMANDS([depfiles], + [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], + [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) +]) + +# Do all the work for Automake. -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, +# 2005, 2006, 2008, 2009 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 16 + +# This macro actually does too much. Some checks are only needed if +# your package does certain things. But this isn't really a big deal. + +# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) +# AM_INIT_AUTOMAKE([OPTIONS]) +# ----------------------------------------------- +# The call with PACKAGE and VERSION arguments is the old style +# call (pre autoconf-2.50), which is being phased out. PACKAGE +# and VERSION should now be passed to AC_INIT and removed from +# the call to AM_INIT_AUTOMAKE. +# We support both call styles for the transition. After +# the next Automake release, Autoconf can make the AC_INIT +# arguments mandatory, and then we can depend on a new Autoconf +# release and drop the old call support. +AC_DEFUN([AM_INIT_AUTOMAKE], +[AC_PREREQ([2.62])dnl +dnl Autoconf wants to disallow AM_ names. We explicitly allow +dnl the ones we care about. +m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl +AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl +AC_REQUIRE([AC_PROG_INSTALL])dnl +if test "`cd $srcdir && pwd`" != "`pwd`"; then + # Use -I$(srcdir) only when $(srcdir) != ., so that make's output + # is not polluted with repeated "-I." + AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl + # test to see if srcdir already configured + if test -f $srcdir/config.status; then + AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) + fi +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi +AC_SUBST([CYGPATH_W]) + +# Define the identity of the package. +dnl Distinguish between old-style and new-style calls. +m4_ifval([$2], +[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl + AC_SUBST([PACKAGE], [$1])dnl + AC_SUBST([VERSION], [$2])], +[_AM_SET_OPTIONS([$1])dnl +dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. +m4_if(m4_ifdef([AC_PACKAGE_NAME], 1)m4_ifdef([AC_PACKAGE_VERSION], 1), 11,, + [m4_fatal([AC_INIT should be called with package and version arguments])])dnl + AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl + AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl + +_AM_IF_OPTION([no-define],, +[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) + AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl + +# Some tools Automake needs. +AC_REQUIRE([AM_SANITY_CHECK])dnl +AC_REQUIRE([AC_ARG_PROGRAM])dnl +AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version}) +AM_MISSING_PROG(AUTOCONF, autoconf) +AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version}) +AM_MISSING_PROG(AUTOHEADER, autoheader) +AM_MISSING_PROG(MAKEINFO, makeinfo) +AC_REQUIRE([AM_PROG_INSTALL_SH])dnl +AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl +AC_REQUIRE([AM_PROG_MKDIR_P])dnl +# We need awk for the "check" target. The system "awk" is bad on +# some platforms. +AC_REQUIRE([AC_PROG_AWK])dnl +AC_REQUIRE([AC_PROG_MAKE_SET])dnl +AC_REQUIRE([AM_SET_LEADING_DOT])dnl +_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], + [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], + [_AM_PROG_TAR([v7])])]) +_AM_IF_OPTION([no-dependencies],, +[AC_PROVIDE_IFELSE([AC_PROG_CC], + [_AM_DEPENDENCIES(CC)], + [define([AC_PROG_CC], + defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl +AC_PROVIDE_IFELSE([AC_PROG_CXX], + [_AM_DEPENDENCIES(CXX)], + [define([AC_PROG_CXX], + defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl +AC_PROVIDE_IFELSE([AC_PROG_OBJC], + [_AM_DEPENDENCIES(OBJC)], + [define([AC_PROG_OBJC], + defn([AC_PROG_OBJC])[_AM_DEPENDENCIES(OBJC)])])dnl +]) +_AM_IF_OPTION([silent-rules], [AC_REQUIRE([AM_SILENT_RULES])])dnl +dnl The `parallel-tests' driver may need to know about EXEEXT, so add the +dnl `am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This macro +dnl is hooked onto _AC_COMPILER_EXEEXT early, see below. +AC_CONFIG_COMMANDS_PRE(dnl +[m4_provide_if([_AM_COMPILER_EXEEXT], + [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl +]) + +dnl Hook into `_AC_COMPILER_EXEEXT' early to learn its expansion. Do not +dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further +dnl mangled by Autoconf and run in a shell conditional statement. +m4_define([_AC_COMPILER_EXEEXT], +m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])]) + + +# When config.status generates a header, we must update the stamp-h file. +# This file resides in the same directory as the config header +# that is generated. The stamp files are numbered to have different names. + +# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the +# loop where config.status creates the headers, so we can generate +# our stamp files there. +AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], +[# Compute $1's index in $config_headers. +_am_arg=$1 +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $_am_arg | $_am_arg:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) + +# Copyright (C) 2001, 2003, 2005, 2008, 2011 Free Software Foundation, +# Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 1 + +# AM_PROG_INSTALL_SH +# ------------------ +# Define $install_sh. +AC_DEFUN([AM_PROG_INSTALL_SH], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +if test x"${install_sh}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; + *) + install_sh="\${SHELL} $am_aux_dir/install-sh" + esac +fi +AC_SUBST(install_sh)]) + +# Copyright (C) 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 2 + +# Check whether the underlying file-system supports filenames +# with a leading dot. For instance MS-DOS doesn't. +AC_DEFUN([AM_SET_LEADING_DOT], +[rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null +AC_SUBST([am__leading_dot])]) + +# Add --enable-maintainer-mode option to configure. -*- Autoconf -*- +# From Jim Meyering + +# Copyright (C) 1996, 1998, 2000, 2001, 2002, 2003, 2004, 2005, 2008, +# 2011 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 5 + +# AM_MAINTAINER_MODE([DEFAULT-MODE]) +# ---------------------------------- +# Control maintainer-specific portions of Makefiles. +# Default is to disable them, unless `enable' is passed literally. +# For symmetry, `disable' may be passed as well. Anyway, the user +# can override the default with the --enable/--disable switch. +AC_DEFUN([AM_MAINTAINER_MODE], +[m4_case(m4_default([$1], [disable]), + [enable], [m4_define([am_maintainer_other], [disable])], + [disable], [m4_define([am_maintainer_other], [enable])], + [m4_define([am_maintainer_other], [enable]) + m4_warn([syntax], [unexpected argument to AM@&t@_MAINTAINER_MODE: $1])]) +AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles]) + dnl maintainer-mode's default is 'disable' unless 'enable' is passed + AC_ARG_ENABLE([maintainer-mode], +[ --][am_maintainer_other][-maintainer-mode am_maintainer_other make rules and dependencies not useful + (and sometimes confusing) to the casual installer], + [USE_MAINTAINER_MODE=$enableval], + [USE_MAINTAINER_MODE=]m4_if(am_maintainer_other, [enable], [no], [yes])) + AC_MSG_RESULT([$USE_MAINTAINER_MODE]) + AM_CONDITIONAL([MAINTAINER_MODE], [test $USE_MAINTAINER_MODE = yes]) + MAINT=$MAINTAINER_MODE_TRUE + AC_SUBST([MAINT])dnl +] +) + +AU_DEFUN([jm_MAINTAINER_MODE], [AM_MAINTAINER_MODE]) + +# Check to see how 'make' treats includes. -*- Autoconf -*- + +# Copyright (C) 2001, 2002, 2003, 2005, 2009 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 4 + +# AM_MAKE_INCLUDE() +# ----------------- +# Check to see how make treats includes. +AC_DEFUN([AM_MAKE_INCLUDE], +[am_make=${MAKE-make} +cat > confinc << 'END' +am__doit: + @echo this is the am__doit target +.PHONY: am__doit +END +# If we don't find an include directive, just comment out the code. +AC_MSG_CHECKING([for style of include used by $am_make]) +am__include="#" +am__quote= +_am_result=none +# First try GNU make style include. +echo "include confinc" > confmf +# Ignore all kinds of additional output from `make'. +case `$am_make -s -f confmf 2> /dev/null` in #( +*the\ am__doit\ target*) + am__include=include + am__quote= + _am_result=GNU + ;; +esac +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + case `$am_make -s -f confmf 2> /dev/null` in #( + *the\ am__doit\ target*) + am__include=.include + am__quote="\"" + _am_result=BSD + ;; + esac +fi +AC_SUBST([am__include]) +AC_SUBST([am__quote]) +AC_MSG_RESULT([$_am_result]) +rm -f confinc confmf +]) + +# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- + +# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2004, 2005, 2008 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 6 + +# AM_MISSING_PROG(NAME, PROGRAM) +# ------------------------------ +AC_DEFUN([AM_MISSING_PROG], +[AC_REQUIRE([AM_MISSING_HAS_RUN]) +$1=${$1-"${am_missing_run}$2"} +AC_SUBST($1)]) + + +# AM_MISSING_HAS_RUN +# ------------------ +# Define MISSING if not defined so far and test if it supports --run. +# If it does, set am_missing_run to use it, otherwise, to nothing. +AC_DEFUN([AM_MISSING_HAS_RUN], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +AC_REQUIRE_AUX_FILE([missing])dnl +if test x"${MISSING+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; + *) + MISSING="\${SHELL} $am_aux_dir/missing" ;; + esac +fi +# Use eval to expand $SHELL +if eval "$MISSING --run true"; then + am_missing_run="$MISSING --run " +else + am_missing_run= + AC_MSG_WARN([`missing' script is too old or missing]) +fi +]) + +# Copyright (C) 2003, 2004, 2005, 2006, 2011 Free Software Foundation, +# Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 1 + +# AM_PROG_MKDIR_P +# --------------- +# Check for `mkdir -p'. +AC_DEFUN([AM_PROG_MKDIR_P], +[AC_PREREQ([2.60])dnl +AC_REQUIRE([AC_PROG_MKDIR_P])dnl +dnl Automake 1.8 to 1.9.6 used to define mkdir_p. We now use MKDIR_P, +dnl while keeping a definition of mkdir_p for backward compatibility. +dnl @MKDIR_P@ is magic: AC_OUTPUT adjusts its value for each Makefile. +dnl However we cannot define mkdir_p as $(MKDIR_P) for the sake of +dnl Makefile.ins that do not define MKDIR_P, so we do our own +dnl adjustment using top_builddir (which is defined more often than +dnl MKDIR_P). +AC_SUBST([mkdir_p], ["$MKDIR_P"])dnl +case $mkdir_p in + [[\\/$]]* | ?:[[\\/]]*) ;; + */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; +esac +]) + +# Helper functions for option handling. -*- Autoconf -*- + +# Copyright (C) 2001, 2002, 2003, 2005, 2008, 2010 Free Software +# Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 5 + +# _AM_MANGLE_OPTION(NAME) +# ----------------------- +AC_DEFUN([_AM_MANGLE_OPTION], +[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) + +# _AM_SET_OPTION(NAME) +# -------------------- +# Set option NAME. Presently that only means defining a flag for this option. +AC_DEFUN([_AM_SET_OPTION], +[m4_define(_AM_MANGLE_OPTION([$1]), 1)]) + +# _AM_SET_OPTIONS(OPTIONS) +# ------------------------ +# OPTIONS is a space-separated list of Automake options. +AC_DEFUN([_AM_SET_OPTIONS], +[m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) + +# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) +# ------------------------------------------- +# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. +AC_DEFUN([_AM_IF_OPTION], +[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) + +# Check to make sure that the build environment is sane. -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005, 2008 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 5 + +# AM_SANITY_CHECK +# --------------- +AC_DEFUN([AM_SANITY_CHECK], +[AC_MSG_CHECKING([whether build environment is sane]) +# Just in case +sleep 1 +echo timestamp > conftest.file +# Reject unsafe characters in $srcdir or the absolute working directory +# name. Accept space and tab only in the latter. +am_lf=' +' +case `pwd` in + *[[\\\"\#\$\&\'\`$am_lf]]*) + AC_MSG_ERROR([unsafe absolute working directory name]);; +esac +case $srcdir in + *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*) + AC_MSG_ERROR([unsafe srcdir value: `$srcdir']);; +esac + +# Do `set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` + if test "$[*]" = "X"; then + # -L didn't work. + set X `ls -t "$srcdir/configure" conftest.file` + fi + rm -f conftest.file + if test "$[*]" != "X $srcdir/configure conftest.file" \ + && test "$[*]" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken +alias in your environment]) + fi + + test "$[2]" = conftest.file + ) +then + # Ok. + : +else + AC_MSG_ERROR([newly created file is older than distributed files! +Check your system clock]) +fi +AC_MSG_RESULT(yes)]) + +# Copyright (C) 2001, 2003, 2005, 2011 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 1 + +# AM_PROG_INSTALL_STRIP +# --------------------- +# One issue with vendor `install' (even GNU) is that you can't +# specify the program used to strip binaries. This is especially +# annoying in cross-compiling environments, where the build's strip +# is unlikely to handle the host's binaries. +# Fortunately install-sh will honor a STRIPPROG variable, so we +# always use install-sh in `make install-strip', and initialize +# STRIPPROG with the value of the STRIP variable (set by the user). +AC_DEFUN([AM_PROG_INSTALL_STRIP], +[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl +# Installed binaries are usually stripped using `strip' when the user +# run `make install-strip'. However `strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the `STRIP' environment variable to overrule this program. +dnl Don't test for $cross_compiling = yes, because it might be `maybe'. +if test "$cross_compiling" != no; then + AC_CHECK_TOOL([STRIP], [strip], :) +fi +INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" +AC_SUBST([INSTALL_STRIP_PROGRAM])]) + +# Copyright (C) 2006, 2008, 2010 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 3 + +# _AM_SUBST_NOTMAKE(VARIABLE) +# --------------------------- +# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. +# This macro is traced by Automake. +AC_DEFUN([_AM_SUBST_NOTMAKE]) + +# AM_SUBST_NOTMAKE(VARIABLE) +# -------------------------- +# Public sister of _AM_SUBST_NOTMAKE. +AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) + +# Check how to create a tarball. -*- Autoconf -*- + +# Copyright (C) 2004, 2005, 2012 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 2 + +# _AM_PROG_TAR(FORMAT) +# -------------------- +# Check how to create a tarball in format FORMAT. +# FORMAT should be one of `v7', `ustar', or `pax'. +# +# Substitute a variable $(am__tar) that is a command +# writing to stdout a FORMAT-tarball containing the directory +# $tardir. +# tardir=directory && $(am__tar) > result.tar +# +# Substitute a variable $(am__untar) that extract such +# a tarball read from stdin. +# $(am__untar) < result.tar +AC_DEFUN([_AM_PROG_TAR], +[# Always define AMTAR for backward compatibility. Yes, it's still used +# in the wild :-( We should find a proper way to deprecate it ... +AC_SUBST([AMTAR], ['$${TAR-tar}']) +m4_if([$1], [v7], + [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'], + [m4_case([$1], [ustar],, [pax],, + [m4_fatal([Unknown tar format])]) +AC_MSG_CHECKING([how to create a $1 tar archive]) +# Loop over all known methods to create a tar archive until one works. +_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' +_am_tools=${am_cv_prog_tar_$1-$_am_tools} +# Do not fold the above two line into one, because Tru64 sh and +# Solaris sh will not grok spaces in the rhs of `-'. +for _am_tool in $_am_tools +do + case $_am_tool in + gnutar) + for _am_tar in tar gnutar gtar; + do + AM_RUN_LOG([$_am_tar --version]) && break + done + am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' + am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' + am__untar="$_am_tar -xf -" + ;; + plaintar) + # Must skip GNU tar: if it does not support --format= it doesn't create + # ustar tarball either. + (tar --version) >/dev/null 2>&1 && continue + am__tar='tar chf - "$$tardir"' + am__tar_='tar chf - "$tardir"' + am__untar='tar xf -' + ;; + pax) + am__tar='pax -L -x $1 -w "$$tardir"' + am__tar_='pax -L -x $1 -w "$tardir"' + am__untar='pax -r' + ;; + cpio) + am__tar='find "$$tardir" -print | cpio -o -H $1 -L' + am__tar_='find "$tardir" -print | cpio -o -H $1 -L' + am__untar='cpio -i -H $1 -d' + ;; + none) + am__tar=false + am__tar_=false + am__untar=false + ;; + esac + + # If the value was cached, stop now. We just wanted to have am__tar + # and am__untar set. + test -n "${am_cv_prog_tar_$1}" && break + + # tar/untar a dummy directory, and stop if the command works + rm -rf conftest.dir + mkdir conftest.dir + echo GrepMe > conftest.dir/file + AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) + rm -rf conftest.dir + if test -s conftest.tar; then + AM_RUN_LOG([$am__untar /dev/null 2>&1 && break + fi +done +rm -rf conftest.dir + +AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) +AC_MSG_RESULT([$am_cv_prog_tar_$1])]) +AC_SUBST([am__tar]) +AC_SUBST([am__untar]) +]) # _AM_PROG_TAR + +m4_include([../../../acinclude.m4]) diff --git a/newlib/libc/sys/amdgcn/close.c b/newlib/libc/sys/amdgcn/close.c new file mode 100644 index 000000000..5bce5570b --- /dev/null +++ b/newlib/libc/sys/amdgcn/close.c @@ -0,0 +1,24 @@ +/* + * Support file for amdgcn in newlib. + * Copyright (c) 2017 Mentor Graphics. + * + * The authors hereby grant permission to use, copy, modify, distribute, + * and license this software and its documentation for any purpose, provided + * that existing copyright notices are retained in all copies and that this + * notice is included verbatim in any distributions. No written agreement, + * license, or royalty fee is required for any of the authorized uses. + * Modifications to this software may be copyrighted by their authors + * and need not follow the licensing terms described here, provided that + * the new terms are clearly indicated on the first page of each file where + * they apply. + */ + +#include +#include + +int close(int fildes) +{ + errno = EIO; + return -1; +} + diff --git a/newlib/libc/sys/amdgcn/configure b/newlib/libc/sys/amdgcn/configure new file mode 100755 index 000000000..f3de7073d --- /dev/null +++ b/newlib/libc/sys/amdgcn/configure @@ -0,0 +1,4766 @@ +#! /bin/sh +# Guess values for system-dependent variables and create Makefiles. +# Generated by GNU Autoconf 2.68 for newlib 3.1.0. +# +# +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, +# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software +# Foundation, Inc. +# +# +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +if test "x$CONFIG_SHELL" = x; then + as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which + # is contrary to our usage. Disable this feature. + alias -g '\${1+\"\$@\"}'='\"\$@\"' + setopt NO_GLOB_SUBST +else + case \`(set -o) 2>/dev/null\` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi +" + as_required="as_fn_return () { (exit \$1); } +as_fn_success () { as_fn_return 0; } +as_fn_failure () { as_fn_return 1; } +as_fn_ret_success () { return 0; } +as_fn_ret_failure () { return 1; } + +exitcode=0 +as_fn_success || { exitcode=1; echo as_fn_success failed.; } +as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } +as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } +as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } +if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : + +else + exitcode=1; echo positional parameters were not saved. +fi +test x\$exitcode = x0 || exit 1" + as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO + as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO + eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && + test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1" + if (eval "$as_required") 2>/dev/null; then : + as_have_required=yes +else + as_have_required=no +fi + if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : + +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +as_found=false +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + as_found=: + case $as_dir in #( + /*) + for as_base in sh bash ksh sh5; do + # Try only shells that exist, to save several forks. + as_shell=$as_dir/$as_base + if { test -f "$as_shell" || test -f "$as_shell.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : + CONFIG_SHELL=$as_shell as_have_required=yes + if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : + break 2 +fi +fi + done;; + esac + as_found=false +done +$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : + CONFIG_SHELL=$SHELL as_have_required=yes +fi; } +IFS=$as_save_IFS + + + if test "x$CONFIG_SHELL" != x; then : + # We cannot yet assume a decent shell, so we have to provide a + # neutralization value for shells without unset; and this also + # works around shells that cannot unset nonexistent variables. + # Preserve -v and -x to the replacement shell. + BASH_ENV=/dev/null + ENV=/dev/null + (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV + export CONFIG_SHELL + case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; + esac + exec "$CONFIG_SHELL" $as_opts "$as_myself" ${1+"$@"} +fi + + if test x$as_have_required = xno; then : + $as_echo "$0: This script requires a shell more modern than all" + $as_echo "$0: the shells that I found on your system." + if test x${ZSH_VERSION+set} = xset ; then + $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" + $as_echo "$0: be upgraded to zsh 4.3.4 or later." + else + $as_echo "$0: Please tell bug-autoconf@gnu.org about your system, +$0: including any error possibly output before this +$0: message. Then install a modern shell, or manually run +$0: the script under such a shell if you do have one." + fi + exit 1 +fi +fi +fi +SHELL=${CONFIG_SHELL-/bin/sh} +export SHELL +# Unset more variables known to interfere with behavior of common tools. +CLICOLOR_FORCE= GREP_OPTIONS= +unset CLICOLOR_FORCE GREP_OPTIONS + +## --------------------- ## +## M4sh Shell Functions. ## +## --------------------- ## +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + $as_echo "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + + + as_lineno_1=$LINENO as_lineno_1a=$LINENO + as_lineno_2=$LINENO as_lineno_2a=$LINENO + eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && + test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { + # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) + sed -n ' + p + /[$]LINENO/= + ' <$as_myself | + sed ' + s/[$]LINENO.*/&-/ + t lineno + b + :lineno + N + :loop + s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ + t loop + s/-\n.*// + ' >$as_me.lineno && + chmod +x "$as_me.lineno" || + { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } + + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensitive to this). + . "./$as_me.lineno" + # Exit status is that of the last command. + exit +} + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -p'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -p' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -p' + fi +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +if test -x / >/dev/null 2>&1; then + as_test_x='test -x' +else + if ls -dL / >/dev/null 2>&1; then + as_ls_L_option=L + else + as_ls_L_option= + fi + as_test_x=' + eval sh -c '\'' + if test -d "$1"; then + test -d "$1/."; + else + case $1 in #( + -*)set "./$1";; + esac; + case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( + ???[sx]*):;;*)false;;esac;fi + '\'' sh + ' +fi +as_executable_p=$as_test_x + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +test -n "$DJDIR" || exec 7<&0 &1 + +# Name of the host. +# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, +# so uname gets run too. +ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` + +# +# Initializations. +# +ac_default_prefix=/usr/local +ac_clean_files= +ac_config_libobj_dir=. +LIBOBJS= +cross_compiling=no +subdirs= +MFLAGS= +MAKEFLAGS= + +# Identity of this package. +PACKAGE_NAME='newlib' +PACKAGE_TARNAME='newlib' +PACKAGE_VERSION='3.1.0' +PACKAGE_STRING='newlib 3.1.0' +PACKAGE_BUGREPORT='' +PACKAGE_URL='' + +ac_unique_file="close.c" +ac_subst_vars='LTLIBOBJS +LIBOBJS +sys_dir +machine_dir +libm_machine_dir +lpfx +aext +oext +OBJEXT +USE_LIBTOOL_FALSE +USE_LIBTOOL_TRUE +ELIX_LEVEL_4_FALSE +ELIX_LEVEL_4_TRUE +ELIX_LEVEL_3_FALSE +ELIX_LEVEL_3_TRUE +ELIX_LEVEL_2_FALSE +ELIX_LEVEL_2_TRUE +ELIX_LEVEL_1_FALSE +ELIX_LEVEL_1_TRUE +ELIX_LEVEL_0_FALSE +ELIX_LEVEL_0_TRUE +LDFLAGS +NO_INCLUDE_LIST +NEWLIB_CFLAGS +CCASFLAGS +CCAS +MAINT +MAINTAINER_MODE_FALSE +MAINTAINER_MODE_TRUE +READELF +RANLIB +AR +AS +am__fastdepCC_FALSE +am__fastdepCC_TRUE +CCDEPMODE +am__nodep +AMDEPBACKSLASH +AMDEP_FALSE +AMDEP_TRUE +am__quote +am__include +DEPDIR +CC +am__untar +am__tar +AMTAR +am__leading_dot +SET_MAKE +AWK +mkdir_p +MKDIR_P +INSTALL_STRIP_PROGRAM +STRIP +install_sh +MAKEINFO +AUTOHEADER +AUTOMAKE +AUTOCONF +ACLOCAL +VERSION +PACKAGE +CYGPATH_W +am__isrc +INSTALL_DATA +INSTALL_SCRIPT +INSTALL_PROGRAM +host_os +host_vendor +host_cpu +host +build_os +build_vendor +build_cpu +build +newlib_basedir +MAY_SUPPLY_SYSCALLS_FALSE +MAY_SUPPLY_SYSCALLS_TRUE +target_alias +host_alias +build_alias +LIBS +ECHO_T +ECHO_N +ECHO_C +DEFS +mandir +localedir +libdir +psdir +pdfdir +dvidir +htmldir +infodir +docdir +oldincludedir +includedir +localstatedir +sharedstatedir +sysconfdir +datadir +datarootdir +libexecdir +sbindir +bindir +program_transform_name +prefix +exec_prefix +PACKAGE_URL +PACKAGE_BUGREPORT +PACKAGE_STRING +PACKAGE_VERSION +PACKAGE_TARNAME +PACKAGE_NAME +PATH_SEPARATOR +SHELL' +ac_subst_files='' +ac_user_opts=' +enable_option_checking +enable_multilib +enable_target_optspace +enable_malloc_debugging +enable_newlib_multithread +enable_newlib_iconv +enable_newlib_elix_level +enable_newlib_io_float +enable_newlib_supplied_syscalls +enable_newlib_fno_builtin +enable_dependency_tracking +enable_maintainer_mode +' + ac_precious_vars='build_alias +host_alias +target_alias +CCAS +CCASFLAGS' + + +# Initialize some variables set by options. +ac_init_help= +ac_init_version=false +ac_unrecognized_opts= +ac_unrecognized_sep= +# The variables have the same names as the options, with +# dashes changed to underlines. +cache_file=/dev/null +exec_prefix=NONE +no_create= +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +verbose= +x_includes=NONE +x_libraries=NONE + +# Installation directory options. +# These are left unexpanded so users can "make install exec_prefix=/foo" +# and all the variables that are supposed to be based on exec_prefix +# by default will actually change. +# Use braces instead of parens because sh, perl, etc. also accept them. +# (The list follows the same order as the GNU Coding Standards.) +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datarootdir='${prefix}/share' +datadir='${datarootdir}' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +includedir='${prefix}/include' +oldincludedir='/usr/include' +docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' +infodir='${datarootdir}/info' +htmldir='${docdir}' +dvidir='${docdir}' +pdfdir='${docdir}' +psdir='${docdir}' +libdir='${exec_prefix}/lib' +localedir='${datarootdir}/locale' +mandir='${datarootdir}/man' + +ac_prev= +ac_dashdash= +for ac_option +do + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval $ac_prev=\$ac_option + ac_prev= + continue + fi + + case $ac_option in + *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; + *=) ac_optarg= ;; + *) ac_optarg=yes ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case $ac_dashdash$ac_option in + --) + ac_dashdash=yes ;; + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir=$ac_optarg ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build_alias ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build_alias=$ac_optarg ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file=$ac_optarg ;; + + --config-cache | -C) + cache_file=config.cache ;; + + -datadir | --datadir | --datadi | --datad) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=*) + datadir=$ac_optarg ;; + + -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ + | --dataroo | --dataro | --datar) + ac_prev=datarootdir ;; + -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ + | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) + datarootdir=$ac_optarg ;; + + -disable-* | --disable-*) + ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=no ;; + + -docdir | --docdir | --docdi | --doc | --do) + ac_prev=docdir ;; + -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) + docdir=$ac_optarg ;; + + -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) + ac_prev=dvidir ;; + -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) + dvidir=$ac_optarg ;; + + -enable-* | --enable-*) + ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=\$ac_optarg ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix=$ac_optarg ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he | -h) + ac_init_help=long ;; + -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) + ac_init_help=recursive ;; + -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) + ac_init_help=short ;; + + -host | --host | --hos | --ho) + ac_prev=host_alias ;; + -host=* | --host=* | --hos=* | --ho=*) + host_alias=$ac_optarg ;; + + -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) + ac_prev=htmldir ;; + -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ + | --ht=*) + htmldir=$ac_optarg ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir=$ac_optarg ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir=$ac_optarg ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir=$ac_optarg ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir=$ac_optarg ;; + + -localedir | --localedir | --localedi | --localed | --locale) + ac_prev=localedir ;; + -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) + localedir=$ac_optarg ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst | --locals) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) + localstatedir=$ac_optarg ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir=$ac_optarg ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c | -n) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir=$ac_optarg ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix=$ac_optarg ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix=$ac_optarg ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix=$ac_optarg ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name=$ac_optarg ;; + + -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) + ac_prev=pdfdir ;; + -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) + pdfdir=$ac_optarg ;; + + -psdir | --psdir | --psdi | --psd | --ps) + ac_prev=psdir ;; + -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) + psdir=$ac_optarg ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir=$ac_optarg ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir=$ac_optarg ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site=$ac_optarg ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir=$ac_optarg ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir=$ac_optarg ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target_alias ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target_alias=$ac_optarg ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers | -V) + ac_init_version=: ;; + + -with-* | --with-*) + ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=\$ac_optarg ;; + + -without-* | --without-*) + ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=no ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes=$ac_optarg ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries=$ac_optarg ;; + + -*) as_fn_error $? "unrecognized option: \`$ac_option' +Try \`$0 --help' for more information" + ;; + + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + case $ac_envvar in #( + '' | [0-9]* | *[!_$as_cr_alnum]* ) + as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; + esac + eval $ac_envvar=\$ac_optarg + export $ac_envvar ;; + + *) + # FIXME: should be removed in autoconf 3.0. + $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && + $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 + : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" + ;; + + esac +done + +if test -n "$ac_prev"; then + ac_option=--`echo $ac_prev | sed 's/_/-/g'` + as_fn_error $? "missing argument to $ac_option" +fi + +if test -n "$ac_unrecognized_opts"; then + case $enable_option_checking in + no) ;; + fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; + *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; + esac +fi + +# Check all directory arguments for consistency. +for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ + datadir sysconfdir sharedstatedir localstatedir includedir \ + oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ + libdir localedir mandir +do + eval ac_val=\$$ac_var + # Remove trailing slashes. + case $ac_val in + */ ) + ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` + eval $ac_var=\$ac_val;; + esac + # Be sure to have absolute directory names. + case $ac_val in + [\\/$]* | ?:[\\/]* ) continue;; + NONE | '' ) case $ac_var in *prefix ) continue;; esac;; + esac + as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" +done + +# There might be people who depend on the old broken behavior: `$host' +# used to hold the argument of --host etc. +# FIXME: To remove some day. +build=$build_alias +host=$host_alias +target=$target_alias + +# FIXME: To remove some day. +if test "x$host_alias" != x; then + if test "x$build_alias" = x; then + cross_compiling=maybe + $as_echo "$as_me: WARNING: if you wanted to set the --build type, don't use --host. + If a cross compiler is detected then cross compile mode will be used" >&2 + elif test "x$build_alias" != "x$host_alias"; then + cross_compiling=yes + fi +fi + +ac_tool_prefix= +test -n "$host_alias" && ac_tool_prefix=$host_alias- + +test "$silent" = yes && exec 6>/dev/null + + +ac_pwd=`pwd` && test -n "$ac_pwd" && +ac_ls_di=`ls -di .` && +ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || + as_fn_error $? "working directory cannot be determined" +test "X$ac_ls_di" = "X$ac_pwd_ls_di" || + as_fn_error $? "pwd does not report name of working directory" + + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then the parent directory. + ac_confdir=`$as_dirname -- "$as_myself" || +$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_myself" : 'X\(//\)[^/]' \| \ + X"$as_myself" : 'X\(//\)$' \| \ + X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_myself" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + srcdir=$ac_confdir + if test ! -r "$srcdir/$ac_unique_file"; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r "$srcdir/$ac_unique_file"; then + test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." + as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" +fi +ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" +ac_abs_confdir=`( + cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" + pwd)` +# When building in place, set srcdir=. +if test "$ac_abs_confdir" = "$ac_pwd"; then + srcdir=. +fi +# Remove unnecessary trailing slashes from srcdir. +# Double slashes in file names in object file debugging info +# mess up M-x gdb in Emacs. +case $srcdir in +*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; +esac +for ac_var in $ac_precious_vars; do + eval ac_env_${ac_var}_set=\${${ac_var}+set} + eval ac_env_${ac_var}_value=\$${ac_var} + eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} + eval ac_cv_env_${ac_var}_value=\$${ac_var} +done + +# +# Report the --help message. +# +if test "$ac_init_help" = "long"; then + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat <<_ACEOF +\`configure' configures newlib 3.1.0 to adapt to many kinds of systems. + +Usage: $0 [OPTION]... [VAR=VALUE]... + +To assign environment variables (e.g., CC, CFLAGS...), specify them as +VAR=VALUE. See below for descriptions of some of the useful variables. + +Defaults for the options are specified in brackets. + +Configuration: + -h, --help display this help and exit + --help=short display options specific to this package + --help=recursive display the short help of all the included packages + -V, --version display version information and exit + -q, --quiet, --silent do not print \`checking ...' messages + --cache-file=FILE cache test results in FILE [disabled] + -C, --config-cache alias for \`--cache-file=config.cache' + -n, --no-create do not create output files + --srcdir=DIR find the sources in DIR [configure dir or \`..'] + +Installation directories: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [PREFIX] + +By default, \`make install' will install all the files in +\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify +an installation prefix other than \`$ac_default_prefix' using \`--prefix', +for instance \`--prefix=\$HOME'. + +For better control, use the options below. + +Fine tuning of the installation directories: + --bindir=DIR user executables [EPREFIX/bin] + --sbindir=DIR system admin executables [EPREFIX/sbin] + --libexecdir=DIR program executables [EPREFIX/libexec] + --sysconfdir=DIR read-only single-machine data [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] + --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --libdir=DIR object code libraries [EPREFIX/lib] + --includedir=DIR C header files [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc [/usr/include] + --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] + --datadir=DIR read-only architecture-independent data [DATAROOTDIR] + --infodir=DIR info documentation [DATAROOTDIR/info] + --localedir=DIR locale-dependent data [DATAROOTDIR/locale] + --mandir=DIR man documentation [DATAROOTDIR/man] + --docdir=DIR documentation root [DATAROOTDIR/doc/newlib] + --htmldir=DIR html documentation [DOCDIR] + --dvidir=DIR dvi documentation [DOCDIR] + --pdfdir=DIR pdf documentation [DOCDIR] + --psdir=DIR ps documentation [DOCDIR] +_ACEOF + + cat <<\_ACEOF + +Program names: + --program-prefix=PREFIX prepend PREFIX to installed program names + --program-suffix=SUFFIX append SUFFIX to installed program names + --program-transform-name=PROGRAM run sed PROGRAM on installed program names + +System types: + --build=BUILD configure for building on BUILD [guessed] + --host=HOST cross-compile to build programs to run on HOST [BUILD] +_ACEOF +fi + +if test -n "$ac_init_help"; then + case $ac_init_help in + short | recursive ) echo "Configuration of newlib 3.1.0:";; + esac + cat <<\_ACEOF + +Optional Features: + --disable-option-checking ignore unrecognized --enable/--with options + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --enable-multilib build many library versions (default) + --enable-target-optspace optimize for space + --enable-malloc-debugging indicate malloc debugging requested + --enable-newlib-multithread enable support for multiple threads + --enable-newlib-iconv enable iconv library support + --enable-newlib-elix-level supply desired elix library level (1-4) + --disable-newlib-io-float disable printf/scanf family float support + --disable-newlib-supplied-syscalls disable newlib from supplying syscalls + --disable-newlib-fno-builtin disable -fno-builtin flag to allow compiler to use builtin library functions + --disable-dependency-tracking speeds up one-time build + --enable-dependency-tracking do not reject slow dependency extractors + --enable-maintainer-mode enable make rules and dependencies not useful + (and sometimes confusing) to the casual installer + +Some influential environment variables: + CCAS assembler compiler command (defaults to CC) + CCASFLAGS assembler compiler flags (defaults to CFLAGS) + +Use these variables to override the choices made by `configure' or to help +it to find libraries and programs with nonstandard names/locations. + +Report bugs to the package provider. +_ACEOF +ac_status=$? +fi + +if test "$ac_init_help" = "recursive"; then + # If there are subdirs, report their specific --help. + for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue + test -d "$ac_dir" || + { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || + continue + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + cd "$ac_dir" || { ac_status=$?; continue; } + # Check for guested configure. + if test -f "$ac_srcdir/configure.gnu"; then + echo && + $SHELL "$ac_srcdir/configure.gnu" --help=recursive + elif test -f "$ac_srcdir/configure"; then + echo && + $SHELL "$ac_srcdir/configure" --help=recursive + else + $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + fi || ac_status=$? + cd "$ac_pwd" || { ac_status=$?; break; } + done +fi + +test -n "$ac_init_help" && exit $ac_status +if $ac_init_version; then + cat <<\_ACEOF +newlib configure 3.1.0 +generated by GNU Autoconf 2.68 + +Copyright (C) 2010 Free Software Foundation, Inc. +This configure script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it. +_ACEOF + exit +fi + +## ------------------------ ## +## Autoconf initialization. ## +## ------------------------ ## + +# ac_fn_c_try_compile LINENO +# -------------------------- +# Try to compile conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext + if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_compile +cat >config.log <<_ACEOF +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by newlib $as_me 3.1.0, which was +generated by GNU Autoconf 2.68. Invocation command line was + + $ $0 $@ + +_ACEOF +exec 5>>config.log +{ +cat <<_ASUNAME +## --------- ## +## Platform. ## +## --------- ## + +hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` + +/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` +/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` +/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` +/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` + +_ASUNAME + +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + $as_echo "PATH: $as_dir" + done +IFS=$as_save_IFS + +} >&5 + +cat >&5 <<_ACEOF + + +## ----------- ## +## Core tests. ## +## ----------- ## + +_ACEOF + + +# Keep a trace of the command line. +# Strip out --no-create and --no-recursion so they do not pile up. +# Strip out --silent because we don't want to record it for future runs. +# Also quote any args containing shell meta-characters. +# Make two passes to allow for proper duplicate-argument suppression. +ac_configure_args= +ac_configure_args0= +ac_configure_args1= +ac_must_keep_next=false +for ac_pass in 1 2 +do + for ac_arg + do + case $ac_arg in + -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + continue ;; + *\'*) + ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + case $ac_pass in + 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; + 2) + as_fn_append ac_configure_args1 " '$ac_arg'" + if test $ac_must_keep_next = true; then + ac_must_keep_next=false # Got value, back to normal. + else + case $ac_arg in + *=* | --config-cache | -C | -disable-* | --disable-* \ + | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ + | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ + | -with-* | --with-* | -without-* | --without-* | --x) + case "$ac_configure_args0 " in + "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; + esac + ;; + -* ) ac_must_keep_next=true ;; + esac + fi + as_fn_append ac_configure_args " '$ac_arg'" + ;; + esac + done +done +{ ac_configure_args0=; unset ac_configure_args0;} +{ ac_configure_args1=; unset ac_configure_args1;} + +# When interrupted or exit'd, cleanup temporary files, and complete +# config.log. We remove comments because anyway the quotes in there +# would cause problems or look ugly. +# WARNING: Use '\'' to represent an apostrophe within the trap. +# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. +trap 'exit_status=$? + # Save into config.log some information that might help in debugging. + { + echo + + $as_echo "## ---------------- ## +## Cache variables. ## +## ---------------- ##" + echo + # The following way of writing the cache mishandles newlines in values, +( + for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + (set) 2>&1 | + case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + sed -n \ + "s/'\''/'\''\\\\'\'''\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" + ;; #( + *) + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) + echo + + $as_echo "## ----------------- ## +## Output variables. ## +## ----------------- ##" + echo + for ac_var in $ac_subst_vars + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + + if test -n "$ac_subst_files"; then + $as_echo "## ------------------- ## +## File substitutions. ## +## ------------------- ##" + echo + for ac_var in $ac_subst_files + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + fi + + if test -s confdefs.h; then + $as_echo "## ----------- ## +## confdefs.h. ## +## ----------- ##" + echo + cat confdefs.h + echo + fi + test "$ac_signal" != 0 && + $as_echo "$as_me: caught signal $ac_signal" + $as_echo "$as_me: exit $exit_status" + } >&5 + rm -f core *.core core.conftest.* && + rm -f -r conftest* confdefs* conf$$* $ac_clean_files && + exit $exit_status +' 0 +for ac_signal in 1 2 13 15; do + trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal +done +ac_signal=0 + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -f -r conftest* confdefs.h + +$as_echo "/* confdefs.h */" > confdefs.h + +# Predefined preprocessor variables. + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_NAME "$PACKAGE_NAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_TARNAME "$PACKAGE_TARNAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_VERSION "$PACKAGE_VERSION" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_STRING "$PACKAGE_STRING" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_URL "$PACKAGE_URL" +_ACEOF + + +# Let the site file select an alternate cache file if it wants to. +# Prefer an explicitly selected file to automatically selected ones. +ac_site_file1=NONE +ac_site_file2=NONE +if test -n "$CONFIG_SITE"; then + # We do not want a PATH search for config.site. + case $CONFIG_SITE in #(( + -*) ac_site_file1=./$CONFIG_SITE;; + */*) ac_site_file1=$CONFIG_SITE;; + *) ac_site_file1=./$CONFIG_SITE;; + esac +elif test "x$prefix" != xNONE; then + ac_site_file1=$prefix/share/config.site + ac_site_file2=$prefix/etc/config.site +else + ac_site_file1=$ac_default_prefix/share/config.site + ac_site_file2=$ac_default_prefix/etc/config.site +fi +for ac_site_file in "$ac_site_file1" "$ac_site_file2" +do + test "x$ac_site_file" = xNONE && continue + if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 +$as_echo "$as_me: loading site script $ac_site_file" >&6;} + sed 's/^/| /' "$ac_site_file" >&5 + . "$ac_site_file" \ + || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "failed to load site script $ac_site_file +See \`config.log' for more details" "$LINENO" 5; } + fi +done + +if test -r "$cache_file"; then + # Some versions of bash will fail to source /dev/null (special files + # actually), so we avoid doing that. DJGPP emulates it as a regular file. + if test /dev/null != "$cache_file" && test -f "$cache_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 +$as_echo "$as_me: loading cache $cache_file" >&6;} + case $cache_file in + [\\/]* | ?:[\\/]* ) . "$cache_file";; + *) . "./$cache_file";; + esac + fi +else + { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 +$as_echo "$as_me: creating cache $cache_file" >&6;} + >$cache_file +fi + +# Check that the precious variables saved in the cache have kept the same +# value. +ac_cache_corrupted=false +for ac_var in $ac_precious_vars; do + eval ac_old_set=\$ac_cv_env_${ac_var}_set + eval ac_new_set=\$ac_env_${ac_var}_set + eval ac_old_val=\$ac_cv_env_${ac_var}_value + eval ac_new_val=\$ac_env_${ac_var}_value + case $ac_old_set,$ac_new_set in + set,) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,);; + *) + if test "x$ac_old_val" != "x$ac_new_val"; then + # differences in whitespace do not lead to failure. + ac_old_val_w=`echo x $ac_old_val` + ac_new_val_w=`echo x $ac_new_val` + if test "$ac_old_val_w" != "$ac_new_val_w"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 +$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + ac_cache_corrupted=: + else + { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 +$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} + eval $ac_var=\$ac_old_val + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 +$as_echo "$as_me: former value: \`$ac_old_val'" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 +$as_echo "$as_me: current value: \`$ac_new_val'" >&2;} + fi;; + esac + # Pass precious variables to config.status. + if test "$ac_new_set" = set; then + case $ac_new_val in + *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *) ac_arg=$ac_var=$ac_new_val ;; + esac + case " $ac_configure_args " in + *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. + *) as_fn_append ac_configure_args " '$ac_arg'" ;; + esac + fi +done +if $ac_cache_corrupted; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 +$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} + as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 +fi +## -------------------- ## +## Main body of script. ## +## -------------------- ## + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + + +ac_aux_dir= +for ac_dir in ../../../.. "$srcdir"/../../../..; do + if test -f "$ac_dir/install-sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f "$ac_dir/install.sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + elif test -f "$ac_dir/shtool"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/shtool install -c" + break + fi +done +if test -z "$ac_aux_dir"; then + as_fn_error $? "cannot find install-sh, install.sh, or shtool in ../../../.. \"$srcdir\"/../../../.." "$LINENO" 5 +fi + +# These three variables are undocumented and unsupported, +# and are intended to be withdrawn in a future Autoconf release. +# They can cause serious problems if a builder's source tree is in a directory +# whose full name contains unusual characters. +ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. +ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. +ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. + + + + +# Make sure we can run config.sub. +$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || + as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 +$as_echo_n "checking build system type... " >&6; } +if ${ac_cv_build+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_build_alias=$build_alias +test "x$ac_build_alias" = x && + ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` +test "x$ac_build_alias" = x && + as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 +ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || + as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 +$as_echo "$ac_cv_build" >&6; } +case $ac_cv_build in +*-*-*) ;; +*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; +esac +build=$ac_cv_build +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_build +shift +build_cpu=$1 +build_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +build_os=$* +IFS=$ac_save_IFS +case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 +$as_echo_n "checking host system type... " >&6; } +if ${ac_cv_host+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "x$host_alias" = x; then + ac_cv_host=$ac_cv_build +else + ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || + as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 +$as_echo "$ac_cv_host" >&6; } +case $ac_cv_host in +*-*-*) ;; +*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; +esac +host=$ac_cv_host +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_host +shift +host_cpu=$1 +host_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +host_os=$* +IFS=$ac_save_IFS +case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac + + +am__api_version='1.11' + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AmigaOS /C/install, which installs bootblocks on floppy discs +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# OS/2's system install, which has a completely different semantic +# ./install, which can be erroneously created by make from ./install.sh. +# Reject install programs that cannot install multiple files. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 +$as_echo_n "checking for a BSD-compatible install... " >&6; } +if test -z "$INSTALL"; then +if ${ac_cv_path_install+:} false; then : + $as_echo_n "(cached) " >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + # Account for people who put trailing slashes in PATH elements. +case $as_dir/ in #(( + ./ | .// | /[cC]/* | \ + /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ + ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ + /usr/ucb/* ) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then + if test $ac_prog = install && + grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + elif test $ac_prog = install && + grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # program-specific install script used by HP pwplus--don't use. + : + else + rm -rf conftest.one conftest.two conftest.dir + echo one > conftest.one + echo two > conftest.two + mkdir conftest.dir + if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && + test -s conftest.one && test -s conftest.two && + test -s conftest.dir/conftest.one && + test -s conftest.dir/conftest.two + then + ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" + break 3 + fi + fi + fi + done + done + ;; +esac + + done +IFS=$as_save_IFS + +rm -rf conftest.one conftest.two conftest.dir + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL=$ac_cv_path_install + else + # As a last resort, use the slow shell script. Don't cache a + # value for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + INSTALL=$ac_install_sh + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 +$as_echo "$INSTALL" >&6; } + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 +$as_echo_n "checking whether build environment is sane... " >&6; } +# Just in case +sleep 1 +echo timestamp > conftest.file +# Reject unsafe characters in $srcdir or the absolute working directory +# name. Accept space and tab only in the latter. +am_lf=' +' +case `pwd` in + *[\\\"\#\$\&\'\`$am_lf]*) + as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;; +esac +case $srcdir in + *[\\\"\#\$\&\'\`$am_lf\ \ ]*) + as_fn_error $? "unsafe srcdir value: \`$srcdir'" "$LINENO" 5;; +esac + +# Do `set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` + if test "$*" = "X"; then + # -L didn't work. + set X `ls -t "$srcdir/configure" conftest.file` + fi + rm -f conftest.file + if test "$*" != "X $srcdir/configure conftest.file" \ + && test "$*" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + as_fn_error $? "ls -t appears to fail. Make sure there is not a broken +alias in your environment" "$LINENO" 5 + fi + + test "$2" = conftest.file + ) +then + # Ok. + : +else + as_fn_error $? "newly created file is older than distributed files! +Check your system clock" "$LINENO" 5 +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +test "$program_prefix" != NONE && + program_transform_name="s&^&$program_prefix&;$program_transform_name" +# Use a double $ so make ignores it. +test "$program_suffix" != NONE && + program_transform_name="s&\$&$program_suffix&;$program_transform_name" +# Double any \ or $. +# By default was `s,x,x', remove it if useless. +ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' +program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` + +# expand $ac_aux_dir to an absolute path +am_aux_dir=`cd $ac_aux_dir && pwd` + +if test x"${MISSING+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; + *) + MISSING="\${SHELL} $am_aux_dir/missing" ;; + esac +fi +# Use eval to expand $SHELL +if eval "$MISSING --run true"; then + am_missing_run="$MISSING --run " +else + am_missing_run= + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`missing' script is too old or missing" >&5 +$as_echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;} +fi + +if test x"${install_sh}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; + *) + install_sh="\${SHELL} $am_aux_dir/install-sh" + esac +fi + +# Installed binaries are usually stripped using `strip' when the user +# run `make install-strip'. However `strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the `STRIP' environment variable to overrule this program. +if test "$cross_compiling" != no; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. +set dummy ${ac_tool_prefix}strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_STRIP="${ac_tool_prefix}strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +STRIP=$ac_cv_prog_STRIP +if test -n "$STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 +$as_echo "$STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_STRIP"; then + ac_ct_STRIP=$STRIP + # Extract the first word of "strip", so it can be a program name with args. +set dummy strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_STRIP"; then + ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_STRIP="strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP +if test -n "$ac_ct_STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 +$as_echo "$ac_ct_STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_STRIP" = x; then + STRIP=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + STRIP=$ac_ct_STRIP + fi +else + STRIP="$ac_cv_prog_STRIP" +fi + +fi +INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5 +$as_echo_n "checking for a thread-safe mkdir -p... " >&6; } +if test -z "$MKDIR_P"; then + if ${ac_cv_path_mkdir+:} false; then : + $as_echo_n "(cached) " >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in mkdir gmkdir; do + for ac_exec_ext in '' $ac_executable_extensions; do + { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; } || continue + case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( + 'mkdir (GNU coreutils) '* | \ + 'mkdir (coreutils) '* | \ + 'mkdir (fileutils) '4.1*) + ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext + break 3;; + esac + done + done + done +IFS=$as_save_IFS + +fi + + test -d ./--version && rmdir ./--version + if test "${ac_cv_path_mkdir+set}" = set; then + MKDIR_P="$ac_cv_path_mkdir -p" + else + # As a last resort, use the slow shell script. Don't cache a + # value for MKDIR_P within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + MKDIR_P="$ac_install_sh -d" + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 +$as_echo "$MKDIR_P" >&6; } + +mkdir_p="$MKDIR_P" +case $mkdir_p in + [\\/$]* | ?:[\\/]*) ;; + */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; +esac + +for ac_prog in gawk mawk nawk awk +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_AWK+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$AWK"; then + ac_cv_prog_AWK="$AWK" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_AWK="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +AWK=$ac_cv_prog_AWK +if test -n "$AWK"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 +$as_echo "$AWK" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$AWK" && break +done + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 +$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } +set x ${MAKE-make} +ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` +if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat >conftest.make <<\_ACEOF +SHELL = /bin/sh +all: + @echo '@@@%%%=$(MAKE)=@@@%%%' +_ACEOF +# GNU make sometimes prints "make[1]: Entering ...", which would confuse us. +case `${MAKE-make} -f conftest.make 2>/dev/null` in + *@@@%%%=?*=@@@%%%*) + eval ac_cv_prog_make_${ac_make}_set=yes;; + *) + eval ac_cv_prog_make_${ac_make}_set=no;; +esac +rm -f conftest.make +fi +if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + SET_MAKE= +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + SET_MAKE="MAKE=${MAKE-make}" +fi + +rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null + +DEPDIR="${am__leading_dot}deps" + +ac_config_commands="$ac_config_commands depfiles" + + +am_make=${MAKE-make} +cat > confinc << 'END' +am__doit: + @echo this is the am__doit target +.PHONY: am__doit +END +# If we don't find an include directive, just comment out the code. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5 +$as_echo_n "checking for style of include used by $am_make... " >&6; } +am__include="#" +am__quote= +_am_result=none +# First try GNU make style include. +echo "include confinc" > confmf +# Ignore all kinds of additional output from `make'. +case `$am_make -s -f confmf 2> /dev/null` in #( +*the\ am__doit\ target*) + am__include=include + am__quote= + _am_result=GNU + ;; +esac +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + case `$am_make -s -f confmf 2> /dev/null` in #( + *the\ am__doit\ target*) + am__include=.include + am__quote="\"" + _am_result=BSD + ;; + esac +fi + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5 +$as_echo "$_am_result" >&6; } +rm -f confinc confmf + +# Check whether --enable-dependency-tracking was given. +if test "${enable_dependency_tracking+set}" = set; then : + enableval=$enable_dependency_tracking; +fi + +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' + am__nodep='_no' +fi + if test "x$enable_dependency_tracking" != xno; then + AMDEP_TRUE= + AMDEP_FALSE='#' +else + AMDEP_TRUE='#' + AMDEP_FALSE= +fi + + + +# Check whether --enable-multilib was given. +if test "${enable_multilib+set}" = set; then : + enableval=$enable_multilib; case "${enableval}" in + yes) multilib=yes ;; + no) multilib=no ;; + *) as_fn_error $? "bad value ${enableval} for multilib option" "$LINENO" 5 ;; + esac +else + multilib=yes +fi + +# Check whether --enable-target-optspace was given. +if test "${enable_target_optspace+set}" = set; then : + enableval=$enable_target_optspace; case "${enableval}" in + yes) target_optspace=yes ;; + no) target_optspace=no ;; + *) as_fn_error $? "bad value ${enableval} for target-optspace option" "$LINENO" 5 ;; + esac +else + target_optspace= +fi + +# Check whether --enable-malloc-debugging was given. +if test "${enable_malloc_debugging+set}" = set; then : + enableval=$enable_malloc_debugging; case "${enableval}" in + yes) malloc_debugging=yes ;; + no) malloc_debugging=no ;; + *) as_fn_error $? "bad value ${enableval} for malloc-debugging option" "$LINENO" 5 ;; + esac +else + malloc_debugging= +fi + +# Check whether --enable-newlib-multithread was given. +if test "${enable_newlib_multithread+set}" = set; then : + enableval=$enable_newlib_multithread; case "${enableval}" in + yes) newlib_multithread=yes ;; + no) newlib_multithread=no ;; + *) as_fn_error $? "bad value ${enableval} for newlib-multithread option" "$LINENO" 5 ;; + esac +else + newlib_multithread=yes +fi + +# Check whether --enable-newlib-iconv was given. +if test "${enable_newlib_iconv+set}" = set; then : + enableval=$enable_newlib_iconv; if test "${newlib_iconv+set}" != set; then + case "${enableval}" in + yes) newlib_iconv=yes ;; + no) newlib_iconv=no ;; + *) as_fn_error $? "bad value ${enableval} for newlib-iconv option" "$LINENO" 5 ;; + esac + fi +else + newlib_iconv=${newlib_iconv} +fi + +# Check whether --enable-newlib-elix-level was given. +if test "${enable_newlib_elix_level+set}" = set; then : + enableval=$enable_newlib_elix_level; case "${enableval}" in + 0) newlib_elix_level=0 ;; + 1) newlib_elix_level=1 ;; + 2) newlib_elix_level=2 ;; + 3) newlib_elix_level=3 ;; + 4) newlib_elix_level=4 ;; + *) as_fn_error $? "bad value ${enableval} for newlib-elix-level option" "$LINENO" 5 ;; + esac +else + newlib_elix_level=0 +fi + +# Check whether --enable-newlib-io-float was given. +if test "${enable_newlib_io_float+set}" = set; then : + enableval=$enable_newlib_io_float; case "${enableval}" in + yes) newlib_io_float=yes ;; + no) newlib_io_float=no ;; + *) as_fn_error $? "bad value ${enableval} for newlib-io-float option" "$LINENO" 5 ;; + esac +else + newlib_io_float=yes +fi + +# Check whether --enable-newlib-supplied-syscalls was given. +if test "${enable_newlib_supplied_syscalls+set}" = set; then : + enableval=$enable_newlib_supplied_syscalls; case "${enableval}" in + yes) newlib_may_supply_syscalls=yes ;; + no) newlib_may_supply_syscalls=no ;; + *) as_fn_error $? "bad value ${enableval} for newlib-supplied-syscalls option" "$LINENO" 5 ;; + esac +else + newlib_may_supply_syscalls=yes +fi + + if test x${newlib_may_supply_syscalls} = xyes; then + MAY_SUPPLY_SYSCALLS_TRUE= + MAY_SUPPLY_SYSCALLS_FALSE='#' +else + MAY_SUPPLY_SYSCALLS_TRUE='#' + MAY_SUPPLY_SYSCALLS_FALSE= +fi + + +# Check whether --enable-newlib-fno-builtin was given. +if test "${enable_newlib_fno_builtin+set}" = set; then : + enableval=$enable_newlib_fno_builtin; case "${enableval}" in + yes) newlib_fno_builtin=yes ;; + no) newlib_fno_builtin=no ;; + *) as_fn_error $? "bad value ${enableval} for newlib-fno-builtin option" "$LINENO" 5 ;; + esac +else + newlib_fno_builtin= +fi + + + +test -z "${with_target_subdir}" && with_target_subdir=. + +if test "${srcdir}" = "."; then + if test "${with_target_subdir}" != "."; then + newlib_basedir="${srcdir}/${with_multisrctop}../../../.." + else + newlib_basedir="${srcdir}/${with_multisrctop}../../.." + fi +else + newlib_basedir="${srcdir}/../../.." +fi + + + + +if test "`cd $srcdir && pwd`" != "`pwd`"; then + # Use -I$(srcdir) only when $(srcdir) != ., so that make's output + # is not polluted with repeated "-I." + am__isrc=' -I$(srcdir)' + # test to see if srcdir already configured + if test -f $srcdir/config.status; then + as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5 + fi +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi + + +# Define the identity of the package. + PACKAGE='newlib' + VERSION='3.1.0' + + +# Some tools Automake needs. + +ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} + + +AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} + + +AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} + + +AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} + + +MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} + +# We need awk for the "check" target. The system "awk" is bad on +# some platforms. +# Always define AMTAR for backward compatibility. Yes, it's still used +# in the wild :-( We should find a proper way to deprecate it ... +AMTAR='$${TAR-tar}' + +am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -' + + + + + + +# FIXME: We temporarily define our own version of AC_PROG_CC. This is +# copied from autoconf 2.12, but does not call AC_PROG_CC_WORKS. We +# are probably using a cross compiler, which will not be able to fully +# link an executable. This should really be fixed in autoconf +# itself. + + + + + + + +# Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + +depcc="$CC" am_compiler_list= + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 +$as_echo_n "checking dependency style of $depcc... " >&6; } +if ${am_cv_CC_dependencies_compiler_type+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named `D' -- because `-MD' means `put the output + # in D'. + rm -rf conftest.dir + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_CC_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` + fi + am__universal=false + case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with + # Solaris 8's {/usr,}/bin/sh. + touch sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with `-c' and `-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle `-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # after this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvc7 | msvc7msys | msvisualcpp | msvcmsys) + # This compiler won't grok `-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_CC_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_CC_dependencies_compiler_type=none +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 +$as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } +CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type + + if + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then + am__fastdepCC_TRUE= + am__fastdepCC_FALSE='#' +else + am__fastdepCC_TRUE='#' + am__fastdepCC_FALSE= +fi + + +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -z "$CC" && as_fn_error $? "no acceptable cc found in \$PATH" "$LINENO" 5 +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using GNU C" >&5 +$as_echo_n "checking whether we are using GNU C... " >&6; } +if ${ac_cv_c_compiler_gnu+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat > conftest.c <&5 + (eval $ac_try) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; } | egrep yes >/dev/null 2>&1; then + ac_cv_c_compiler_gnu=yes +else + ac_cv_c_compiler_gnu=no +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 +$as_echo "$ac_cv_c_compiler_gnu" >&6; } + +if test $ac_cv_c_compiler_gnu = yes; then + GCC=yes + ac_test_CFLAGS="${CFLAGS+set}" + ac_save_CFLAGS="$CFLAGS" + ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 +$as_echo_n "checking whether $CC accepts -g... " >&6; } +if ${ac_cv_prog_cc_g+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_save_c_werror_flag=$ac_c_werror_flag + ac_c_werror_flag=yes + ac_cv_prog_cc_g=no + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +else + CFLAGS="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + ac_c_werror_flag=$ac_save_c_werror_flag + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_c_werror_flag=$ac_save_c_werror_flag +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 +$as_echo "$ac_cv_prog_cc_g" >&6; } +if test "$ac_test_CFLAGS" = set; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi + if test "$ac_test_CFLAGS" = set; then + CFLAGS="$ac_save_CFLAGS" + elif test $ac_cv_prog_cc_g = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-O2" + fi +else + GCC= + test "${CFLAGS+set}" = set || CFLAGS="-g" +fi + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}as", so it can be a program name with args. +set dummy ${ac_tool_prefix}as; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_AS+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$AS"; then + ac_cv_prog_AS="$AS" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_AS="${ac_tool_prefix}as" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +AS=$ac_cv_prog_AS +if test -n "$AS"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AS" >&5 +$as_echo "$AS" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_AS"; then + ac_ct_AS=$AS + # Extract the first word of "as", so it can be a program name with args. +set dummy as; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_AS+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_AS"; then + ac_cv_prog_ac_ct_AS="$ac_ct_AS" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_AS="as" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_AS=$ac_cv_prog_ac_ct_AS +if test -n "$ac_ct_AS"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AS" >&5 +$as_echo "$ac_ct_AS" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_AS" = x; then + AS="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + AS=$ac_ct_AS + fi +else + AS="$ac_cv_prog_AS" +fi + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args. +set dummy ${ac_tool_prefix}ar; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_AR+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$AR"; then + ac_cv_prog_AR="$AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_AR="${ac_tool_prefix}ar" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +AR=$ac_cv_prog_AR +if test -n "$AR"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 +$as_echo "$AR" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_AR"; then + ac_ct_AR=$AR + # Extract the first word of "ar", so it can be a program name with args. +set dummy ar; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_AR+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_AR"; then + ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_AR="ar" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_AR=$ac_cv_prog_ac_ct_AR +if test -n "$ac_ct_AR"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 +$as_echo "$ac_ct_AR" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_AR" = x; then + AR="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + AR=$ac_ct_AR + fi +else + AR="$ac_cv_prog_AR" +fi + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. +set dummy ${ac_tool_prefix}ranlib; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_RANLIB+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +RANLIB=$ac_cv_prog_RANLIB +if test -n "$RANLIB"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 +$as_echo "$RANLIB" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_RANLIB"; then + ac_ct_RANLIB=$RANLIB + # Extract the first word of "ranlib", so it can be a program name with args. +set dummy ranlib; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_RANLIB+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_RANLIB"; then + ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_RANLIB="ranlib" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB +if test -n "$ac_ct_RANLIB"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 +$as_echo "$ac_ct_RANLIB" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_RANLIB" = x; then + RANLIB=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + RANLIB=$ac_ct_RANLIB + fi +else + RANLIB="$ac_cv_prog_RANLIB" +fi + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}readelf", so it can be a program name with args. +set dummy ${ac_tool_prefix}readelf; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_READELF+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$READELF"; then + ac_cv_prog_READELF="$READELF" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_READELF="${ac_tool_prefix}readelf" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +READELF=$ac_cv_prog_READELF +if test -n "$READELF"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $READELF" >&5 +$as_echo "$READELF" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_READELF"; then + ac_ct_READELF=$READELF + # Extract the first word of "readelf", so it can be a program name with args. +set dummy readelf; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_READELF+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_READELF"; then + ac_cv_prog_ac_ct_READELF="$ac_ct_READELF" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_READELF="readelf" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_READELF=$ac_cv_prog_ac_ct_READELF +if test -n "$ac_ct_READELF"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_READELF" >&5 +$as_echo "$ac_ct_READELF" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_READELF" = x; then + READELF=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + READELF=$ac_ct_READELF + fi +else + READELF="$ac_cv_prog_READELF" +fi + + + + +# Hack to ensure that INSTALL won't be set to "../" with autoconf 2.13. */ +ac_given_INSTALL=$INSTALL + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable maintainer-specific portions of Makefiles" >&5 +$as_echo_n "checking whether to enable maintainer-specific portions of Makefiles... " >&6; } + # Check whether --enable-maintainer-mode was given. +if test "${enable_maintainer_mode+set}" = set; then : + enableval=$enable_maintainer_mode; USE_MAINTAINER_MODE=$enableval +else + USE_MAINTAINER_MODE=no +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $USE_MAINTAINER_MODE" >&5 +$as_echo "$USE_MAINTAINER_MODE" >&6; } + if test $USE_MAINTAINER_MODE = yes; then + MAINTAINER_MODE_TRUE= + MAINTAINER_MODE_FALSE='#' +else + MAINTAINER_MODE_TRUE='#' + MAINTAINER_MODE_FALSE= +fi + + MAINT=$MAINTAINER_MODE_TRUE + + +# By default we simply use the C compiler to build assembly code. + +test "${CCAS+set}" = set || CCAS=$CC +test "${CCASFLAGS+set}" = set || CCASFLAGS=$CFLAGS + + + + +# We need AC_EXEEXT to keep automake happy in cygnus mode. However, +# at least currently, we never actually build a program, so we never +# need to use $(EXEEXT). Moreover, the test for EXEEXT normally +# fails, because we are probably configuring with a cross compiler +# which can't create executables. So we include AC_EXEEXT to keep +# automake happy, but we don't execute it, since we don't care about +# the result. +if false; then + + dummy_var=1 +fi + +. ${newlib_basedir}/configure.host + +NEWLIB_CFLAGS=${newlib_cflags} + + +NO_INCLUDE_LIST=${noinclude} + + +LDFLAGS=${ldflags} + + + if test x${newlib_elix_level} = x0; then + ELIX_LEVEL_0_TRUE= + ELIX_LEVEL_0_FALSE='#' +else + ELIX_LEVEL_0_TRUE='#' + ELIX_LEVEL_0_FALSE= +fi + + if test x${newlib_elix_level} = x1; then + ELIX_LEVEL_1_TRUE= + ELIX_LEVEL_1_FALSE='#' +else + ELIX_LEVEL_1_TRUE='#' + ELIX_LEVEL_1_FALSE= +fi + + if test x${newlib_elix_level} = x2; then + ELIX_LEVEL_2_TRUE= + ELIX_LEVEL_2_FALSE='#' +else + ELIX_LEVEL_2_TRUE='#' + ELIX_LEVEL_2_FALSE= +fi + + if test x${newlib_elix_level} = x3; then + ELIX_LEVEL_3_TRUE= + ELIX_LEVEL_3_FALSE='#' +else + ELIX_LEVEL_3_TRUE='#' + ELIX_LEVEL_3_FALSE= +fi + + if test x${newlib_elix_level} = x4; then + ELIX_LEVEL_4_TRUE= + ELIX_LEVEL_4_FALSE='#' +else + ELIX_LEVEL_4_TRUE='#' + ELIX_LEVEL_4_FALSE= +fi + + + if test x${use_libtool} = xyes; then + USE_LIBTOOL_TRUE= + USE_LIBTOOL_FALSE='#' +else + USE_LIBTOOL_TRUE='#' + USE_LIBTOOL_FALSE= +fi + + +# Emit any target-specific warnings. +if test "x${newlib_msg_warn}" != "x"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: ${newlib_msg_warn}" >&5 +$as_echo "$as_me: WARNING: ${newlib_msg_warn}" >&2;} +fi + +# Hard-code OBJEXT. Normally it is set by AC_OBJEXT, but we +# use oext, which is set in configure.host based on the target platform. +OBJEXT=${oext} + + + + + + + + + + + +ac_config_files="$ac_config_files Makefile" + +cat >confcache <<\_ACEOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs, see configure's option --config-cache. +# It is not useful on other systems. If it contains results you don't +# want to keep, you may remove or edit it. +# +# config.status only pays attention to the cache file if you give it +# the --recheck option to rerun configure. +# +# `ac_cv_env_foo' variables (set or unset) will be overridden when +# loading this file, other *unset* `ac_cv_foo' will be assigned the +# following values. + +_ACEOF + +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, we kill variables containing newlines. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +( + for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + + (set) 2>&1 | + case $as_nl`(ac_space=' '; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + # `set' does not quote correctly, so add quotes: double-quote + # substitution turns \\\\ into \\, and sed turns \\ into \. + sed -n \ + "s/'/'\\\\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" + ;; #( + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) | + sed ' + /^ac_cv_env_/b end + t clear + :clear + s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ + t end + s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + :end' >>confcache +if diff "$cache_file" confcache >/dev/null 2>&1; then :; else + if test -w "$cache_file"; then + if test "x$cache_file" != "x/dev/null"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 +$as_echo "$as_me: updating cache $cache_file" >&6;} + if test ! -f "$cache_file" || test -h "$cache_file"; then + cat confcache >"$cache_file" + else + case $cache_file in #( + */* | ?:*) + mv -f confcache "$cache_file"$$ && + mv -f "$cache_file"$$ "$cache_file" ;; #( + *) + mv -f confcache "$cache_file" ;; + esac + fi + fi + else + { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 +$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} + fi +fi +rm -f confcache + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +# Transform confdefs.h into DEFS. +# Protect against shell expansion while executing Makefile rules. +# Protect against Makefile macro expansion. +# +# If the first sed substitution is executed (which looks for macros that +# take arguments), then branch to the quote section. Otherwise, +# look for a macro that doesn't take arguments. +ac_script=' +:mline +/\\$/{ + N + s,\\\n,, + b mline +} +t clear +:clear +s/^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*([^)]*)\)[ ]*\(.*\)/-D\1=\2/g +t quote +s/^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)/-D\1=\2/g +t quote +b any +:quote +s/[ `~#$^&*(){}\\|;'\''"<>?]/\\&/g +s/\[/\\&/g +s/\]/\\&/g +s/\$/$$/g +H +:any +${ + g + s/^\n// + s/\n/ /g + p +} +' +DEFS=`sed -n "$ac_script" confdefs.h` + + +ac_libobjs= +ac_ltlibobjs= +U= +for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue + # 1. Remove the extension, and $U if already installed. + ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' + ac_i=`$as_echo "$ac_i" | sed "$ac_script"` + # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR + # will be set to the directory where LIBOBJS objects are built. + as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" + as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' +done +LIBOBJS=$ac_libobjs + +LTLIBOBJS=$ac_ltlibobjs + + +if test -z "${MAY_SUPPLY_SYSCALLS_TRUE}" && test -z "${MAY_SUPPLY_SYSCALLS_FALSE}"; then + as_fn_error $? "conditional \"MAY_SUPPLY_SYSCALLS\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi + +if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then + as_fn_error $? "conditional \"AMDEP\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then + as_fn_error $? "conditional \"am__fastdepCC\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then + as_fn_error $? "conditional \"MAINTAINER_MODE\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${ELIX_LEVEL_0_TRUE}" && test -z "${ELIX_LEVEL_0_FALSE}"; then + as_fn_error $? "conditional \"ELIX_LEVEL_0\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${ELIX_LEVEL_1_TRUE}" && test -z "${ELIX_LEVEL_1_FALSE}"; then + as_fn_error $? "conditional \"ELIX_LEVEL_1\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${ELIX_LEVEL_2_TRUE}" && test -z "${ELIX_LEVEL_2_FALSE}"; then + as_fn_error $? "conditional \"ELIX_LEVEL_2\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${ELIX_LEVEL_3_TRUE}" && test -z "${ELIX_LEVEL_3_FALSE}"; then + as_fn_error $? "conditional \"ELIX_LEVEL_3\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${ELIX_LEVEL_4_TRUE}" && test -z "${ELIX_LEVEL_4_FALSE}"; then + as_fn_error $? "conditional \"ELIX_LEVEL_4\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${USE_LIBTOOL_TRUE}" && test -z "${USE_LIBTOOL_FALSE}"; then + as_fn_error $? "conditional \"USE_LIBTOOL\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi + +: "${CONFIG_STATUS=./config.status}" +ac_write_fail=0 +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files $CONFIG_STATUS" +{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 +$as_echo "$as_me: creating $CONFIG_STATUS" >&6;} +as_write_fail=0 +cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 +#! $SHELL +# Generated by $as_me. +# Run this file to recreate the current configuration. +# Compiler output produced by configure, useful for debugging +# configure, is in config.log if it exists. + +debug=false +ac_cs_recheck=false +ac_cs_silent=false + +SHELL=\${CONFIG_SHELL-$SHELL} +export SHELL +_ASEOF +cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + $as_echo "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -p'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -p' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -p' + fi +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +if test -x / >/dev/null 2>&1; then + as_test_x='test -x' +else + if ls -dL / >/dev/null 2>&1; then + as_ls_L_option=L + else + as_ls_L_option= + fi + as_test_x=' + eval sh -c '\'' + if test -d "$1"; then + test -d "$1/."; + else + case $1 in #( + -*)set "./$1";; + esac; + case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( + ???[sx]*):;;*)false;;esac;fi + '\'' sh + ' +fi +as_executable_p=$as_test_x + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +exec 6>&1 +## ----------------------------------- ## +## Main body of $CONFIG_STATUS script. ## +## ----------------------------------- ## +_ASEOF +test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# Save the log message, to keep $0 and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. +ac_log=" +This file was extended by newlib $as_me 3.1.0, which was +generated by GNU Autoconf 2.68. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +on `(hostname || uname -n) 2>/dev/null | sed 1q` +" + +_ACEOF + +case $ac_config_files in *" +"*) set x $ac_config_files; shift; ac_config_files=$*;; +esac + + + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# Files that config.status was made for. +config_files="$ac_config_files" +config_commands="$ac_config_commands" + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +ac_cs_usage="\ +\`$as_me' instantiates files and other configuration actions +from templates according to the current configuration. Unless the files +and actions are specified as TAGs, all are instantiated by default. + +Usage: $0 [OPTION]... [TAG]... + + -h, --help print this help, then exit + -V, --version print version number and configuration settings, then exit + --config print configuration, then exit + -q, --quiet, --silent + do not print progress messages + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + +Configuration files: +$config_files + +Configuration commands: +$config_commands + +Report bugs to the package provider." + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" +ac_cs_version="\\ +newlib config.status 3.1.0 +configured by $0, generated by GNU Autoconf 2.68, + with options \\"\$ac_cs_config\\" + +Copyright (C) 2010 Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." + +ac_pwd='$ac_pwd' +srcdir='$srcdir' +INSTALL='$INSTALL' +MKDIR_P='$MKDIR_P' +AWK='$AWK' +test -n "\$AWK" || AWK=awk +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# The default lists apply if the user does not specify any file. +ac_need_defaults=: +while test $# != 0 +do + case $1 in + --*=?*) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` + ac_shift=: + ;; + --*=) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg= + ac_shift=: + ;; + *) + ac_option=$1 + ac_optarg=$2 + ac_shift=shift + ;; + esac + + case $ac_option in + # Handling of the options. + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + ac_cs_recheck=: ;; + --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) + $as_echo "$ac_cs_version"; exit ;; + --config | --confi | --conf | --con | --co | --c ) + $as_echo "$ac_cs_config"; exit ;; + --debug | --debu | --deb | --de | --d | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + '') as_fn_error $? "missing file argument" ;; + esac + as_fn_append CONFIG_FILES " '$ac_optarg'" + ac_need_defaults=false;; + --he | --h | --help | --hel | -h ) + $as_echo "$ac_cs_usage"; exit ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil | --si | --s) + ac_cs_silent=: ;; + + # This is an error. + -*) as_fn_error $? "unrecognized option: \`$1' +Try \`$0 --help' for more information." ;; + + *) as_fn_append ac_config_targets " $1" + ac_need_defaults=false ;; + + esac + shift +done + +ac_configure_extra_args= + +if $ac_cs_silent; then + exec 6>/dev/null + ac_configure_extra_args="$ac_configure_extra_args --silent" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +if \$ac_cs_recheck; then + set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion + shift + \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 + CONFIG_SHELL='$SHELL' + export CONFIG_SHELL + exec "\$@" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX + $as_echo "$ac_log" +} >&5 + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# +# INIT-COMMANDS +# +AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + +# Handling of arguments. +for ac_config_target in $ac_config_targets +do + case $ac_config_target in + "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; + "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; + + *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; + esac +done + + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files + test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands +fi + +# Have a temporary directory for convenience. Make it in the build tree +# simply because there is no reason against having it here, and in addition, +# creating and moving files from /tmp can sometimes cause problems. +# Hook for its removal unless debugging. +# Note that there is a small window in which the directory will not be cleaned: +# after its creation but before its name has been assigned to `$tmp'. +$debug || +{ + tmp= ac_tmp= + trap 'exit_status=$? + : "${ac_tmp:=$tmp}" + { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status +' 0 + trap 'as_fn_exit 1' 1 2 13 15 +} +# Create a (secure) tmp directory for tmp files. + +{ + tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && + test -d "$tmp" +} || +{ + tmp=./conf$$-$RANDOM + (umask 077 && mkdir "$tmp") +} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 +ac_tmp=$tmp + +# Set up the scripts for CONFIG_FILES section. +# No need to generate them if there are no CONFIG_FILES. +# This happens for instance with `./config.status config.h'. +if test -n "$CONFIG_FILES"; then + + +ac_cr=`echo X | tr X '\015'` +# On cygwin, bash can eat \r inside `` if the user requested igncr. +# But we know of no other shell where ac_cr would be empty at this +# point, so we can use a bashism as a fallback. +if test "x$ac_cr" = x; then + eval ac_cr=\$\'\\r\' +fi +ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` +if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then + ac_cs_awk_cr='\\r' +else + ac_cs_awk_cr=$ac_cr +fi + +echo 'BEGIN {' >"$ac_tmp/subs1.awk" && +_ACEOF + + +{ + echo "cat >conf$$subs.awk <<_ACEOF" && + echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && + echo "_ACEOF" +} >conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 +ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` +ac_delim='%!_!# ' +for ac_last_try in false false false false false :; do + . ./conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + + ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` + if test $ac_delim_n = $ac_delim_num; then + break + elif $ac_last_try; then + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done +rm -f conf$$subs.sh + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && +_ACEOF +sed -n ' +h +s/^/S["/; s/!.*/"]=/ +p +g +s/^[^!]*!// +:repl +t repl +s/'"$ac_delim"'$// +t delim +:nl +h +s/\(.\{148\}\)..*/\1/ +t more1 +s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ +p +n +b repl +:more1 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t nl +:delim +h +s/\(.\{148\}\)..*/\1/ +t more2 +s/["\\]/\\&/g; s/^/"/; s/$/"/ +p +b +:more2 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t delim +' >$CONFIG_STATUS || ac_write_fail=1 +rm -f conf$$subs.awk +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +_ACAWK +cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && + for (key in S) S_is_set[key] = 1 + FS = "" + +} +{ + line = $ 0 + nfields = split(line, field, "@") + substed = 0 + len = length(field[1]) + for (i = 2; i < nfields; i++) { + key = field[i] + keylen = length(key) + if (S_is_set[key]) { + value = S[key] + line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) + len += length(value) + length(field[++i]) + substed = 1 + } else + len += 1 + keylen + } + + print line +} + +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then + sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" +else + cat +fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ + || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 +_ACEOF + +# VPATH may cause trouble with some makes, so we remove sole $(srcdir), +# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and +# trailing colons and then remove the whole line if VPATH becomes empty +# (actually we leave an empty line to preserve line numbers). +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ +h +s/// +s/^/:/ +s/[ ]*$/:/ +s/:\$(srcdir):/:/g +s/:\${srcdir}:/:/g +s/:@srcdir@:/:/g +s/^:*// +s/:*$// +x +s/\(=[ ]*\).*/\1/ +G +s/\n// +s/^[^=]*=[ ]*$// +}' +fi + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +fi # test -n "$CONFIG_FILES" + + +eval set X " :F $CONFIG_FILES :C $CONFIG_COMMANDS" +shift +for ac_tag +do + case $ac_tag in + :[FHLC]) ac_mode=$ac_tag; continue;; + esac + case $ac_mode$ac_tag in + :[FHL]*:*);; + :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; + :[FH]-) ac_tag=-:-;; + :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; + esac + ac_save_IFS=$IFS + IFS=: + set x $ac_tag + IFS=$ac_save_IFS + shift + ac_file=$1 + shift + + case $ac_mode in + :L) ac_source=$1;; + :[FH]) + ac_file_inputs= + for ac_f + do + case $ac_f in + -) ac_f="$ac_tmp/stdin";; + *) # Look for the file first in the build tree, then in the source tree + # (if the path is not absolute). The absolute path cannot be DOS-style, + # because $ac_f cannot contain `:'. + test -f "$ac_f" || + case $ac_f in + [\\/$]*) false;; + *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; + esac || + as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; + esac + case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac + as_fn_append ac_file_inputs " '$ac_f'" + done + + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + configure_input='Generated from '` + $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' + `' by configure.' + if test x"$ac_file" != x-; then + configure_input="$ac_file. $configure_input" + { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 +$as_echo "$as_me: creating $ac_file" >&6;} + fi + # Neutralize special characters interpreted by sed in replacement strings. + case $configure_input in #( + *\&* | *\|* | *\\* ) + ac_sed_conf_input=`$as_echo "$configure_input" | + sed 's/[\\\\&|]/\\\\&/g'`;; #( + *) ac_sed_conf_input=$configure_input;; + esac + + case $ac_tag in + *:-:* | *:-) cat >"$ac_tmp/stdin" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; + esac + ;; + esac + + ac_dir=`$as_dirname -- "$ac_file" || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + as_dir="$ac_dir"; as_fn_mkdir_p + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + + case $ac_mode in + :F) + # + # CONFIG_FILE + # + + case $INSTALL in + [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; + *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; + esac + ac_MKDIR_P=$MKDIR_P + case $MKDIR_P in + [\\/$]* | ?:[\\/]* ) ;; + */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; + esac +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# If the template does not know about datarootdir, expand it. +# FIXME: This hack should be removed a few years after 2.60. +ac_datarootdir_hack=; ac_datarootdir_seen= +ac_sed_dataroot=' +/datarootdir/ { + p + q +} +/@datadir@/p +/@docdir@/p +/@infodir@/p +/@localedir@/p +/@mandir@/p' +case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in +*datarootdir*) ac_datarootdir_seen=yes;; +*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 +$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + ac_datarootdir_hack=' + s&@datadir@&$datadir&g + s&@docdir@&$docdir&g + s&@infodir@&$infodir&g + s&@localedir@&$localedir&g + s&@mandir@&$mandir&g + s&\\\${datarootdir}&$datarootdir&g' ;; +esac +_ACEOF + +# Neutralize VPATH when `$srcdir' = `.'. +# Shell code in configure.ac might set extrasub. +# FIXME: do we really want to maintain this feature? +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_sed_extra="$ac_vpsub +$extrasub +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s|@configure_input@|$ac_sed_conf_input|;t t +s&@top_builddir@&$ac_top_builddir_sub&;t t +s&@top_build_prefix@&$ac_top_build_prefix&;t t +s&@srcdir@&$ac_srcdir&;t t +s&@abs_srcdir@&$ac_abs_srcdir&;t t +s&@top_srcdir@&$ac_top_srcdir&;t t +s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t +s&@builddir@&$ac_builddir&;t t +s&@abs_builddir@&$ac_abs_builddir&;t t +s&@abs_top_builddir@&$ac_abs_top_builddir&;t t +s&@INSTALL@&$ac_INSTALL&;t t +s&@MKDIR_P@&$ac_MKDIR_P&;t t +$ac_datarootdir_hack +" +eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ + >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + +test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && + { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && + { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ + "$ac_tmp/out"`; test -z "$ac_out"; } && + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&5 +$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&2;} + + rm -f "$ac_tmp/stdin" + case $ac_file in + -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; + *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; + esac \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + ;; + + + :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 +$as_echo "$as_me: executing $ac_file commands" >&6;} + ;; + esac + + + case $ac_file$ac_mode in + "depfiles":C) test x"$AMDEP_TRUE" != x"" || { + # Autoconf 2.62 quotes --file arguments for eval, but not when files + # are listed without --file. Let's play safe and only enable the eval + # if we detect the quoting. + case $CONFIG_FILES in + *\'*) eval set x "$CONFIG_FILES" ;; + *) set x $CONFIG_FILES ;; + esac + shift + for mf + do + # Strip MF so we end up with the name of the file. + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named `Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # Grep'ing the whole file is not good either: AIX grep has a line + # limit of 2048, but all sed's we know have understand at least 4000. + if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then + dirpart=`$as_dirname -- "$mf" || +$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$mf" : 'X\(//\)[^/]' \| \ + X"$mf" : 'X\(//\)$' \| \ + X"$mf" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$mf" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + else + continue + fi + # Extract the definition of DEPDIR, am__include, and am__quote + # from the Makefile without running `make'. + DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` + test -z "$DEPDIR" && continue + am__include=`sed -n 's/^am__include = //p' < "$mf"` + test -z "am__include" && continue + am__quote=`sed -n 's/^am__quote = //p' < "$mf"` + # When using ansi2knr, U may be empty or an underscore; expand it + U=`sed -n 's/^U = //p' < "$mf"` + # Find all dependency output files, they are included files with + # $(DEPDIR) in their names. We invoke sed twice because it is the + # simplest approach to changing $(DEPDIR) to its actual value in the + # expansion. + for file in `sed -n " + s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do + # Make sure the directory exists. + test -f "$dirpart/$file" && continue + fdir=`$as_dirname -- "$file" || +$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$file" : 'X\(//\)[^/]' \| \ + X"$file" : 'X\(//\)$' \| \ + X"$file" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + as_dir=$dirpart/$fdir; as_fn_mkdir_p + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done + done +} + ;; + + esac +done # for ac_tag + + +as_fn_exit 0 +_ACEOF +ac_clean_files=$ac_clean_files_save + +test $ac_write_fail = 0 || + as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 + + +# configure is writing to config.log, and then calls config.status. +# config.status does its own redirection, appending to config.log. +# Unfortunately, on DOS this fails, as config.log is still kept open +# by configure, so config.status won't be able to write to it; its +# output is simply discarded. So we exec the FD to /dev/null, +# effectively closing config.log, so it can be properly (re)opened and +# appended to by config.status. When coming back to configure, we +# need to make the FD available again. +if test "$no_create" != yes; then + ac_cs_success=: + ac_config_status_args= + test "$silent" = yes && + ac_config_status_args="$ac_config_status_args --quiet" + exec 5>/dev/null + $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false + exec 5>>config.log + # Use ||, not &&, to avoid exiting from the if with $? = 1, which + # would make configure fail if this is the last instruction. + $ac_cs_success || as_fn_exit 1 +fi +if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 +$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} +fi + diff --git a/newlib/libc/sys/amdgcn/configure.in b/newlib/libc/sys/amdgcn/configure.in new file mode 100644 index 000000000..74edb0a13 --- /dev/null +++ b/newlib/libc/sys/amdgcn/configure.in @@ -0,0 +1,14 @@ +dnl This is the newlib/libc/sys/amdgcn configure.in file. +dnl Process this file with autoconf to produce a configure script. + +AC_PREREQ(2.59) +AC_INIT([newlib],[NEWLIB_VERSION]) +AC_CONFIG_SRCDIR([close.c]) + +dnl Can't be done in NEWLIB_CONFIGURE because that confuses automake. +AC_CONFIG_AUX_DIR(../../../..) + +NEWLIB_CONFIGURE(../../..) + +AC_CONFIG_FILES([Makefile]) +AC_OUTPUT diff --git a/newlib/libc/sys/amdgcn/fstat.c b/newlib/libc/sys/amdgcn/fstat.c new file mode 100644 index 000000000..b78715857 --- /dev/null +++ b/newlib/libc/sys/amdgcn/fstat.c @@ -0,0 +1,23 @@ +/* + * Support file for amdgcn in newlib. + * Copyright (c) 2017 Mentor Graphics. + * + * The authors hereby grant permission to use, copy, modify, distribute, + * and license this software and its documentation for any purpose, provided + * that existing copyright notices are retained in all copies and that this + * notice is included verbatim in any distributions. No written agreement, + * license, or royalty fee is required for any of the authorized uses. + * Modifications to this software may be copyrighted by their authors + * and need not follow the licensing terms described here, provided that + * the new terms are clearly indicated on the first page of each file where + * they apply. + */ + +#include +#include + +int fstat(int fildes, struct stat *buf) +{ + errno = EIO; + return -1; +} diff --git a/newlib/libc/sys/amdgcn/isatty.c b/newlib/libc/sys/amdgcn/isatty.c new file mode 100644 index 000000000..4268f2cdb --- /dev/null +++ b/newlib/libc/sys/amdgcn/isatty.c @@ -0,0 +1,23 @@ +/* + * Support file for amdgcn in newlib. + * Copyright (c) 2017 Mentor Graphics. + * + * The authors hereby grant permission to use, copy, modify, distribute, + * and license this software and its documentation for any purpose, provided + * that existing copyright notices are retained in all copies and that this + * notice is included verbatim in any distributions. No written agreement, + * license, or royalty fee is required for any of the authorized uses. + * Modifications to this software may be copyrighted by their authors + * and need not follow the licensing terms described here, provided that + * the new terms are clearly indicated on the first page of each file where + * they apply. + */ + +#include +#include + +int isatty(int fd) +{ + errno = EINVAL; + return 0; +} diff --git a/newlib/libc/sys/amdgcn/lseek.c b/newlib/libc/sys/amdgcn/lseek.c new file mode 100644 index 000000000..be3220be3 --- /dev/null +++ b/newlib/libc/sys/amdgcn/lseek.c @@ -0,0 +1,24 @@ +/* + * Support file for amdgcn in newlib. + * Copyright (c) 2017 Mentor Graphics. + * + * The authors hereby grant permission to use, copy, modify, distribute, + * and license this software and its documentation for any purpose, provided + * that existing copyright notices are retained in all copies and that this + * notice is included verbatim in any distributions. No written agreement, + * license, or royalty fee is required for any of the authorized uses. + * Modifications to this software may be copyrighted by their authors + * and need not follow the licensing terms described here, provided that + * the new terms are clearly indicated on the first page of each file where + * they apply. + */ + +#include +#include + +off_t lseek(int fildes, off_t offset, int whence) +{ + errno = ESPIPE; + return -1; +} + diff --git a/newlib/libc/sys/amdgcn/read.c b/newlib/libc/sys/amdgcn/read.c new file mode 100644 index 000000000..97385e917 --- /dev/null +++ b/newlib/libc/sys/amdgcn/read.c @@ -0,0 +1,21 @@ +/* + * Support file for amdgcn in newlib. + * Copyright (c) 2017 Mentor Graphics. + * + * The authors hereby grant permission to use, copy, modify, distribute, + * and license this software and its documentation for any purpose, provided + * that existing copyright notices are retained in all copies and that this + * notice is included verbatim in any distributions. No written agreement, + * license, or royalty fee is required for any of the authorized uses. + * Modifications to this software may be copyrighted by their authors + * and need not follow the licensing terms described here, provided that + * the new terms are clearly indicated on the first page of each file where + * they apply. + */ + +#include + +_READ_WRITE_RETURN_TYPE read (int fildes, void *buf, size_t nbyte) +{ + return 0; +} diff --git a/newlib/libc/sys/amdgcn/write.c b/newlib/libc/sys/amdgcn/write.c new file mode 100644 index 000000000..ce5bd360c --- /dev/null +++ b/newlib/libc/sys/amdgcn/write.c @@ -0,0 +1,88 @@ +/* + * Support file for amdgcn in newlib. + * Copyright (c) 2014, 2017 Mentor Graphics. + * + * The authors hereby grant permission to use, copy, modify, distribute, + * and license this software and its documentation for any purpose, provided + * that existing copyright notices are retained in all copies and that this + * notice is included verbatim in any distributions. No written agreement, + * license, or royalty fee is required for any of the authorized uses. + * Modifications to this software may be copyrighted by their authors + * and need not follow the licensing terms described here, provided that + * the new terms are clearly indicated on the first page of each file where + * they apply. + */ + +#include +#include +#include +#include +#include + +/* This struct must match the one used by gcn-run and libgomp. + It holds all the data output from a kernel (besides mapping data). + + The base address pointer can be found at kernargs+16. + + The next_output counter must be atomically incremented for each + print output. Only when the print data is fully written can the + "written" flag be set. */ +struct output { + int return_value; + int next_output; + struct printf_data { + int written; + char msg[128]; + int type; + union { + int64_t ivalue; + double dvalue; + char text[128]; + }; + } queue[1000]; +}; + +_READ_WRITE_RETURN_TYPE write (int fd, const void *buf, size_t count) +{ + if (fd != 1 && fd != 2) + { + errno = EBADF; + return -1; + } + + /* The output data is at ((void*)kernargs)[2]. */ + register void **kernargs asm("s8"); + struct output *data = (struct output *)kernargs[2]; + + /* Each output slot allows 256 bytes, so reserve as many as we need. */ + int slot_count = ((count+1)/256)+1; + int index = __atomic_fetch_add (&data->next_output, slot_count, + __ATOMIC_ACQUIRE); + for (int c = count; + c >= 0 && index < 1000; + buf += 256, c -= 256, index++) + { + if (c < 128) + { + memcpy (data->queue[index].msg, buf, c); + data->queue[index].msg[c] = '\0'; + data->queue[index].text[0] = '\0'; + } + else if (c < 256) + { + memcpy (data->queue[index].msg, buf, 128); + memcpy (data->queue[index].text, buf+128, c-128); + data->queue[index].text[c-128] = '\0'; + } + else + { + memcpy (data->queue[index].msg, buf, 128); + memcpy (data->queue[index].text, buf+128, 128); + } + + data->queue[index].type = 3; /* Raw. */ + __atomic_store_n (&data->queue[index].written, 1, __ATOMIC_RELEASE); + } + + return count; +} diff --git a/newlib/libc/sys/configure b/newlib/libc/sys/configure index 08485a1e9..153dd25b2 100755 --- a/newlib/libc/sys/configure +++ b/newlib/libc/sys/configure @@ -787,6 +787,7 @@ LIBS CPPFLAGS CPP' ac_subdirs_all='a29khif +amdgcn arm d10v decstation @@ -11474,7 +11475,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 11477 "configure" +#line 11478 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -11580,7 +11581,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 11583 "configure" +#line 11584 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -11824,6 +11825,8 @@ if test -n "${sys_dir}"; then a29khif) subdirs="$subdirs a29khif" + ;; + amdgcn) subdirs="$subdirs amdgcn" ;; arm) subdirs="$subdirs arm" ;; diff --git a/newlib/libc/sys/configure.in b/newlib/libc/sys/configure.in index bc6cb881c..a65d1e71f 100644 --- a/newlib/libc/sys/configure.in +++ b/newlib/libc/sys/configure.in @@ -23,6 +23,7 @@ fi if test -n "${sys_dir}"; then case ${sys_dir} in a29khif) AC_CONFIG_SUBDIRS(a29khif) ;; + amdgcn) AC_CONFIG_SUBDIRS(amdgcn) ;; arm) AC_CONFIG_SUBDIRS(arm) ;; d10v) AC_CONFIG_SUBDIRS(d10v) ;; decstation) AC_CONFIG_SUBDIRS(decstation) ;; From 17f8dfd3140968bd05bb817b148a981e8a298a2f Mon Sep 17 00:00:00 2001 From: Jeff Johnston Date: Tue, 15 Jan 2019 14:13:30 -0500 Subject: [PATCH 100/475] Update config.guess, config.sub to gcc master branch versions --- config.guess | 116 +++-- config.sub | 1193 +++++++++++++++++++++++++------------------------- 2 files changed, 662 insertions(+), 647 deletions(-) diff --git a/config.guess b/config.guess index 445c40683..8e2a58b86 100755 --- a/config.guess +++ b/config.guess @@ -1,8 +1,8 @@ #! /bin/sh # Attempt to guess a canonical system name. -# Copyright 1992-2018 Free Software Foundation, Inc. +# Copyright 1992-2019 Free Software Foundation, Inc. -timestamp='2018-06-26' +timestamp='2019-01-03' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by @@ -50,7 +50,7 @@ version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. -Copyright 1992-2018 Free Software Foundation, Inc. +Copyright 1992-2019 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." @@ -84,8 +84,6 @@ if test $# != 0; then exit 1 fi -trap 'exit 1' 1 2 15 - # CC_FOR_BUILD -- compiler used by this script. Note that the use of a # compiler to aid in system detection is discouraged as it requires # temporary files to be created and, as you can see below, it is a @@ -96,34 +94,38 @@ trap 'exit 1' 1 2 15 # Portable tmp directory creation inspired by the Autoconf team. -set_cc_for_build=' -trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; -trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; -: ${TMPDIR=/tmp} ; - { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || - { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || - { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || - { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; -dummy=$tmp/dummy ; -tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; -case ${CC_FOR_BUILD-},${HOST_CC-},${CC-} in - ,,) echo "int x;" > "$dummy.c" ; - for c in cc gcc c89 c99 ; do - if ($c -c -o "$dummy.o" "$dummy.c") >/dev/null 2>&1 ; then - CC_FOR_BUILD="$c"; break ; - fi ; - done ; - if test x"$CC_FOR_BUILD" = x ; then - CC_FOR_BUILD=no_compiler_found ; - fi - ;; - ,,*) CC_FOR_BUILD=$CC ;; - ,*,*) CC_FOR_BUILD=$HOST_CC ;; -esac ; set_cc_for_build= ;' +tmp= +# shellcheck disable=SC2172 +trap 'test -z "$tmp" || rm -fr "$tmp"' 0 1 2 13 15 + +set_cc_for_build() { + : "${TMPDIR=/tmp}" + # shellcheck disable=SC2039 + { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || + { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir "$tmp" 2>/dev/null) ; } || + { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir "$tmp" 2>/dev/null) && echo "Warning: creating insecure temp directory" >&2 ; } || + { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } + dummy=$tmp/dummy + case ${CC_FOR_BUILD-},${HOST_CC-},${CC-} in + ,,) echo "int x;" > "$dummy.c" + for driver in cc gcc c89 c99 ; do + if ($driver -c -o "$dummy.o" "$dummy.c") >/dev/null 2>&1 ; then + CC_FOR_BUILD="$driver" + break + fi + done + if test x"$CC_FOR_BUILD" = x ; then + CC_FOR_BUILD=no_compiler_found + fi + ;; + ,,*) CC_FOR_BUILD=$CC ;; + ,*,*) CC_FOR_BUILD=$HOST_CC ;; + esac +} # This is needed to find uname on a Pyramid OSx when run in the BSD universe. # (ghazi@noc.rutgers.edu 1994-08-24) -if (test -f /.attbin/uname) >/dev/null 2>&1 ; then +if test -f /.attbin/uname ; then PATH=$PATH:/.attbin ; export PATH fi @@ -138,7 +140,7 @@ Linux|GNU|GNU/*) # We could probably try harder. LIBC=gnu - eval "$set_cc_for_build" + set_cc_for_build cat <<-EOF > "$dummy.c" #include #if defined(__UCLIBC__) @@ -199,7 +201,7 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in os=netbsdelf ;; arm*|i386|m68k|ns32k|sh3*|sparc|vax) - eval "$set_cc_for_build" + set_cc_for_build if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ELF__ then @@ -383,13 +385,26 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in echo sparc-hal-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" exit ;; sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) - echo sparc-sun-solaris2"`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`" + set_cc_for_build + SUN_ARCH=sparc + # If there is a compiler, see if it is configured for 64-bit objects. + # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. + # This test works for both compilers. + if [ "$CC_FOR_BUILD" != no_compiler_found ]; then + if (echo '#ifdef __sparcv9'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + SUN_ARCH=sparcv9 + fi + fi + echo "$SUN_ARCH"-sun-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" exit ;; i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) echo i386-pc-auroraux"$UNAME_RELEASE" exit ;; i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) - eval "$set_cc_for_build" + set_cc_for_build SUN_ARCH=i386 # If there is a compiler, see if it is configured for 64-bit objects. # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. @@ -482,7 +497,7 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in echo clipper-intergraph-clix"$UNAME_RELEASE" exit ;; mips:*:*:UMIPS | mips:*:*:RISCos) - eval "$set_cc_for_build" + set_cc_for_build sed 's/^ //' << EOF > "$dummy.c" #ifdef __cplusplus #include /* for printf() prototype */ @@ -579,7 +594,7 @@ EOF exit ;; *:AIX:2:3) if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then - eval "$set_cc_for_build" + set_cc_for_build sed 's/^ //' << EOF > "$dummy.c" #include @@ -660,7 +675,7 @@ EOF esac fi if [ "$HP_ARCH" = "" ]; then - eval "$set_cc_for_build" + set_cc_for_build sed 's/^ //' << EOF > "$dummy.c" #define _HPUX_SOURCE @@ -700,7 +715,7 @@ EOF esac if [ "$HP_ARCH" = hppa2.0w ] then - eval "$set_cc_for_build" + set_cc_for_build # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler @@ -726,7 +741,7 @@ EOF echo ia64-hp-hpux"$HPUX_REV" exit ;; 3050*:HI-UX:*:*) - eval "$set_cc_for_build" + set_cc_for_build sed 's/^ //' << EOF > "$dummy.c" #include int @@ -840,6 +855,17 @@ EOF *:BSD/OS:*:*) echo "$UNAME_MACHINE"-unknown-bsdi"$UNAME_RELEASE" exit ;; + arm:FreeBSD:*:*) + UNAME_PROCESSOR=`uname -p` + set_cc_for_build + if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_PCS_VFP + then + echo "${UNAME_PROCESSOR}"-unknown-freebsd"`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`"-gnueabi + else + echo "${UNAME_PROCESSOR}"-unknown-freebsd"`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`"-gnueabihf + fi + exit ;; *:FreeBSD:*:*) UNAME_PROCESSOR=`/usr/bin/uname -p` case "$UNAME_PROCESSOR" in @@ -881,7 +907,7 @@ EOF echo "$UNAME_MACHINE"-pc-uwin exit ;; amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) - echo x86_64-unknown-cygwin + echo x86_64-pc-cygwin exit ;; prep*:SunOS:5.*:*) echo powerpcle-unknown-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" @@ -922,7 +948,7 @@ EOF echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; arm*:Linux:*:*) - eval "$set_cc_for_build" + set_cc_for_build if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_EABI__ then @@ -971,7 +997,7 @@ EOF echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; mips:Linux:*:* | mips64:Linux:*:*) - eval "$set_cc_for_build" + set_cc_for_build sed 's/^ //' << EOF > "$dummy.c" #undef CPU #undef ${UNAME_MACHINE} @@ -1285,7 +1311,7 @@ EOF exit ;; *:Darwin:*:*) UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown - eval "$set_cc_for_build" + set_cc_for_build if test "$UNAME_PROCESSOR" = unknown ; then UNAME_PROCESSOR=powerpc fi @@ -1358,6 +1384,7 @@ EOF # "uname -m" is not consistent, so use $cputype instead. 386 # is converted to i386 for consistency with other x86 # operating systems. + # shellcheck disable=SC2154 if test "$cputype" = 386; then UNAME_MACHINE=i386 else @@ -1414,6 +1441,9 @@ EOF amd64:Isilon\ OneFS:*:*) echo x86_64-unknown-onefs exit ;; + *:Unleashed:*:*) + echo "$UNAME_MACHINE"-unknown-unleashed"$UNAME_RELEASE" + exit ;; esac echo "$0: unable to guess system type" >&2 diff --git a/config.sub b/config.sub index c95acc681..75bb6a313 100755 --- a/config.sub +++ b/config.sub @@ -1,8 +1,8 @@ #! /bin/sh # Configuration validation subroutine script. -# Copyright 1992-2018 Free Software Foundation, Inc. +# Copyright 1992-2019 Free Software Foundation, Inc. -timestamp='2018-07-03' +timestamp='2019-01-01' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by @@ -67,7 +67,7 @@ Report bugs and patches to ." version="\ GNU config.sub ($timestamp) -Copyright 1992-2018 Free Software Foundation, Inc. +Copyright 1992-2019 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." @@ -89,7 +89,7 @@ while test $# -gt 0 ; do - ) # Use stdin as input. break ;; -* ) - echo "$me: invalid option $1$help" + echo "$me: invalid option $1$help" >&2 exit 1 ;; *local*) @@ -111,7 +111,8 @@ case $# in esac # Split fields of configuration type -IFS="-" read -r field1 field2 field3 field4 <&2 - exit 1 + cpu=$basic_machine + vendor=unknown + ;; +esac + +unset -v basic_machine + +# Decode basic machines in the full and proper CPU-Company form. +case $cpu-$vendor in + # Here we handle the default manufacturer of certain CPU types in canonical form. It is in + # some cases the only manufacturer, in others, it is the most popular. + craynv-unknown) + vendor=cray + os=${os:-unicosmp} + ;; + c90-unknown | c90-cray) + vendor=cray + os=${os:-unicos} + ;; + fx80-unknown) + vendor=alliant + ;; + romp-unknown) + vendor=ibm + ;; + mmix-unknown) + vendor=knuth + ;; + microblaze-unknown | microblazeel-unknown) + vendor=xilinx + ;; + rs6000-unknown) + vendor=ibm + ;; + vax-unknown) + vendor=dec + ;; + pdp11-unknown) + vendor=dec + ;; + we32k-unknown) + vendor=att + ;; + cydra-unknown) + vendor=cydrome + ;; + i370-ibm*) + vendor=ibm + ;; + orion-unknown) + vendor=highlevel + ;; + xps-unknown | xps100-unknown) + cpu=xps100 + vendor=honeywell + ;; + + # Here we normalize CPU types with a missing or matching vendor + dpx20-unknown | dpx20-bull) + cpu=rs6000 + vendor=bull + os=${os:-bosx} + ;; + + # Here we normalize CPU types irrespective of the vendor + amd64-*) + cpu=x86_64 + ;; + blackfin-*) + cpu=bfin + os=linux + ;; + c54x-*) + cpu=tic54x + ;; + c55x-*) + cpu=tic55x + ;; + c6x-*) + cpu=tic6x + ;; + e500v[12]-*) + cpu=powerpc + os=$os"spe" + ;; + mips3*-*) + cpu=mips64 + ;; + ms1-*) + cpu=mt + ;; + m68knommu-*) + cpu=m68k + os=linux + ;; + m9s12z-* | m68hcs12z-* | hcs12z-* | s12z-*) + cpu=s12z + ;; + openrisc-*) + cpu=or32 + ;; + parisc-*) + cpu=hppa + os=linux + ;; + pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) + cpu=i586 + ;; + pentiumpro-* | p6-* | 6x86-* | athlon-* | athalon_*-*) + cpu=i686 + ;; + pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) + cpu=i686 + ;; + pentium4-*) + cpu=i786 + ;; + pc98-*) + cpu=i386 + ;; + ppc-* | ppcbe-*) + cpu=powerpc + ;; + ppcle-* | powerpclittle-*) + cpu=powerpcle + ;; + ppc64-*) + cpu=powerpc64 + ;; + ppc64le-* | powerpc64little-*) + cpu=powerpc64le + ;; + sb1-*) + cpu=mipsisa64sb1 + ;; + sb1el-*) + cpu=mipsisa64sb1el + ;; + sh5e[lb]-*) + cpu=`echo "$cpu" | sed 's/^\(sh.\)e\(.\)$/\1\2e/'` + ;; + spur-*) + cpu=spur + ;; + strongarm-* | thumb-*) + cpu=arm + ;; + tx39-*) + cpu=mipstx39 + ;; + tx39el-*) + cpu=mipstx39el + ;; + x64-*) + cpu=x86_64 + ;; + xscale-* | xscalee[bl]-*) + cpu=`echo "$cpu" | sed 's/^xscale/arm/'` + ;; + + # Recognize the canonical CPU Types that limit and/or modify the + # company names they are paired with. + cr16-*) + os=${os:-elf} + ;; + crisv32-* | etraxfs*-*) + cpu=crisv32 + vendor=axis + ;; + cris-* | etrax*-*) + cpu=cris + vendor=axis + ;; + crx-*) + os=${os:-elf} + ;; + neo-tandem) + cpu=neo + vendor=tandem + ;; + nse-tandem) + cpu=nse + vendor=tandem + ;; + nsr-tandem) + cpu=nsr + vendor=tandem + ;; + nsv-tandem) + cpu=nsv + vendor=tandem + ;; + nsx-tandem) + cpu=nsx + vendor=tandem + ;; + s390-*) + cpu=s390 + vendor=ibm + ;; + s390x-*) + cpu=s390x + vendor=ibm + ;; + tile*-*) + os=${os:-linux-gnu} + ;; + + *) + # Recognize the canonical CPU types that are allowed with any + # company name. + case $cpu in + 1750a | 580 \ + | a29k \ + | aarch64 | aarch64_be \ + | abacus \ + | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] \ + | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] \ + | alphapca5[67] | alpha64pca5[67] \ + | am33_2.0 \ + | amdgcn \ + | arc | arceb \ + | arm | arm[lb]e | arme[lb] | armv* \ + | avr | avr32 \ + | asmjs \ + | ba \ + | be32 | be64 \ + | bfin | bs2000 \ + | c[123]* | c30 | [cjt]90 | c4x \ + | c8051 | clipper | craynv | csky | cydra \ + | d10v | d30v | dlx | dsp16xx \ + | e2k | elxsi | epiphany \ + | f30[01] | f700 | fido | fr30 | frv | ft32 | fx80 \ + | h8300 | h8500 \ + | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ + | hexagon \ + | i370 | i*86 | i860 | i960 | ia16 | ia64 \ + | ip2k | iq2000 \ + | k1om \ + | le32 | le64 \ + | lm32 \ + | m32c | m32r | m32rle \ + | m5200 | m68000 | m680[012346]0 | m68360 | m683?2 | m68k | v70 | w65 \ + | m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip \ + | m88110 | m88k | maxq | mb | mcore | mep | metag \ + | microblaze | microblazeel \ + | mips | mipsbe | mipseb | mipsel | mipsle \ + | mips16 \ + | mips64 | mips64el \ + | mips64octeon | mips64octeonel \ + | mips64orion | mips64orionel \ + | mips64r5900 | mips64r5900el \ + | mips64vr | mips64vrel \ + | mips64vr4100 | mips64vr4100el \ + | mips64vr4300 | mips64vr4300el \ + | mips64vr5000 | mips64vr5000el \ + | mips64vr5900 | mips64vr5900el \ + | mipsisa32 | mipsisa32el \ + | mipsisa32r2 | mipsisa32r2el \ + | mipsisa32r6 | mipsisa32r6el \ + | mipsisa64 | mipsisa64el \ + | mipsisa64r2 | mipsisa64r2el \ + | mipsisa64r6 | mipsisa64r6el \ + | mipsisa64sb1 | mipsisa64sb1el \ + | mipsisa64sr71k | mipsisa64sr71kel \ + | mipsr5900 | mipsr5900el \ + | mipstx39 | mipstx39el \ + | mmix \ + | mn10200 | mn10300 \ + | moxie \ + | mt \ + | msp430 \ + | nds32 | nds32le | nds32be \ + | nfp \ + | nios | nios2 | nios2eb | nios2el \ + | none | np1 | ns16k | ns32k \ + | open8 \ + | or1k* \ + | or32 \ + | orion \ + | pdp10 | pdp11 | pj | pjl | pn | power \ + | powerpc | powerpc64 | powerpc64le | powerpcle | powerpcspe \ + | pru \ + | pyramid \ + | riscv | riscv32 | riscv64 \ + | rl78 | romp | rs6000 | rx \ + | score \ + | sh | sh[1234] | sh[24]a | sh[24]ae[lb] | sh[23]e | she[lb] | sh[lb]e \ + | sh[1234]e[lb] | sh[12345][lb]e | sh[23]ele | sh64 | sh64le \ + | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet \ + | sparclite \ + | sparcv8 | sparcv9 | sparcv9b | sparcv9v | sv1 | sx* \ + | spu \ + | tahoe \ + | tic30 | tic4x | tic54x | tic55x | tic6x | tic80 \ + | tron \ + | ubicom32 \ + | v850 | v850e | v850e1 | v850es | v850e2 | v850e2v3 \ + | vax \ + | visium \ + | wasm32 \ + | we32k \ + | x86 | x86_64 | xc16x | xgate | xps100 \ + | xstormy16 | xtensa* \ + | ymp \ + | z8k | z80) + ;; + + *) + echo Invalid configuration \`"$1"\': machine \`"$cpu-$vendor"\' not recognized 1>&2 + exit 1 + ;; + esac ;; esac # Here we canonicalize certain aliases for manufacturers. -case $basic_machine in - *-digital*) - basic_machine=`echo "$basic_machine" | sed 's/digital.*/dec/'` +case $vendor in + digital*) + vendor=dec ;; - *-commodore*) - basic_machine=`echo "$basic_machine" | sed 's/commodore.*/cbm/'` + commodore*) + vendor=cbm ;; *) ;; @@ -1356,7 +1343,7 @@ case $os in | amigaos* | amigados* | msdos* | newsos* | unicos* | aof* \ | aos* | aros* | cloudabi* | sortix* \ | nindy* | vxsim* | vxworks* | ebmon* | hms* | mvs* \ - | clix* | riscos* | uniplus* | iris* | rtu* | xenix* \ + | clix* | riscos* | uniplus* | iris* | isc* | rtu* | xenix* \ | knetbsd* | mirbsd* | netbsd* \ | bitrig* | openbsd* | solidbsd* | libertybsd* \ | ekkobsd* | kfreebsd* | freebsd* | riscix* | lynxos* \ @@ -1376,12 +1363,12 @@ case $os in | powermax* | dnix* | nx6 | nx7 | sei* | dragonfly* \ | skyos* | haiku* | rdos* | toppers* | drops* | es* \ | onefs* | tirtos* | phoenix* | fuchsia* | redox* | bme* \ - | midnightbsd*) + | midnightbsd* | amdhsa* | unleashed* | emscripten*) # Remember, each alternative MUST END IN *, to match a version number. ;; qnx*) - case $basic_machine in - x86-* | i*86-*) + case $cpu in + x86 | i*86) ;; *) os=nto-$os @@ -1507,7 +1494,7 @@ case $os in # Until real need of OS specific support for # particular features comes up, bare metal # configurations are quite functional. - case $basic_machine in + case $cpu in arm*) os=eabi ;; @@ -1541,7 +1528,7 @@ else # will signal an error saying that MANUFACTURER isn't an operating # system, and we'll never get to this point. -case $basic_machine in +case $cpu-$vendor in score-*) os=elf ;; @@ -1722,9 +1709,8 @@ fi # Here we handle the case where we know the os, and the CPU type, but not the # manufacturer. We pick the logical manufacturer. -vendor=unknown -case $basic_machine in - *-unknown) +case $vendor in + unknown) case $os in riscix*) vendor=acorn @@ -1793,11 +1779,10 @@ case $basic_machine in vendor=stratus ;; esac - basic_machine=`echo "$basic_machine" | sed "s/unknown/$vendor/"` ;; esac -echo "$basic_machine-$os" +echo "$cpu-$vendor-$os" exit # Local variables: From 9b2318c428f24073673cb43bd09d23a2a30a8b6e Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Tue, 15 Jan 2019 15:32:15 +0100 Subject: [PATCH 101/475] Cygwin: signalfd: fix comment Signed-off-by: Corinna Vinschen --- winsup/cygwin/fhandler_signalfd.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/winsup/cygwin/fhandler_signalfd.cc b/winsup/cygwin/fhandler_signalfd.cc index 1547c64cd..24cf403b6 100644 --- a/winsup/cygwin/fhandler_signalfd.cc +++ b/winsup/cygwin/fhandler_signalfd.cc @@ -1,4 +1,4 @@ -/* fhandler_signalfd.cc: fhandler for /proc//fd/ operations +/* fhandler_signalfd.cc: fhandler for signalfd This file is part of Cygwin. From b6f53617a7512082abb7e249d93cbbbe02f19255 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Tue, 15 Jan 2019 21:49:52 +0100 Subject: [PATCH 102/475] Cygwin: signalfd: set st_mode in fhandler_signalfd::fstat Signed-off-by: Corinna Vinschen --- winsup/cygwin/fhandler.cc | 3 --- winsup/cygwin/fhandler_signalfd.cc | 1 + 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/winsup/cygwin/fhandler.cc b/winsup/cygwin/fhandler.cc index 2c1fcb7db..9643373b0 100644 --- a/winsup/cygwin/fhandler.cc +++ b/winsup/cygwin/fhandler.cc @@ -1345,9 +1345,6 @@ fhandler_base::fstat (struct stat *buf) case FH_PIPER: buf->st_mode = S_IFIFO | S_IRUSR; break; - case FH_SIGNALFD: - buf->st_mode = S_IRUSR | S_IWUSR; - break; default: buf->st_mode = S_IFCHR | STD_RBITS | STD_WBITS | S_IWGRP | S_IWOTH; break; diff --git a/winsup/cygwin/fhandler_signalfd.cc b/winsup/cygwin/fhandler_signalfd.cc index 24cf403b6..d8e17a8fc 100644 --- a/winsup/cygwin/fhandler_signalfd.cc +++ b/winsup/cygwin/fhandler_signalfd.cc @@ -59,6 +59,7 @@ fhandler_signalfd::fstat (struct stat *buf) int ret = fhandler_base::fstat (buf); if (!ret) { + buf->st_mode = S_IRUSR | S_IWUSR; buf->st_dev = FH_SIGNALFD; buf->st_ino = get_unique_id (); } From 068182e26c7b397df579b69a18f745092844d1b4 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Tue, 15 Jan 2019 22:02:33 +0100 Subject: [PATCH 103/475] Cygwin: timers: implement timerfd First cut of a timerfd implementation. Still TODO: - fork/exec semantics - timerfd_settime TFD_TIMER_CANCEL_ON_SET flag - ioctl(TFD_IOC_SET_TICKS) - bug fixes Signed-off-by: Corinna Vinschen --- winsup/cygwin/Makefile.in | 1 + winsup/cygwin/common.din | 3 + winsup/cygwin/devices.cc | 3 + winsup/cygwin/devices.h | 3 + winsup/cygwin/devices.in | 3 + winsup/cygwin/dtable.cc | 3 + winsup/cygwin/fhandler.h | 51 +++++ winsup/cygwin/fhandler_timerfd.cc | 198 +++++++++++++++++++ winsup/cygwin/include/cygwin/version.h | 3 +- winsup/cygwin/include/sys/timerfd.h | 45 +++++ winsup/cygwin/release/2.12.0 | 3 +- winsup/cygwin/select.cc | 45 +++++ winsup/cygwin/timer.cc | 256 ++++++++++++++++++++----- winsup/cygwin/timer.h | 21 +- winsup/doc/new-features.xml | 3 +- winsup/doc/posix.xml | 3 + 16 files changed, 592 insertions(+), 52 deletions(-) create mode 100644 winsup/cygwin/fhandler_timerfd.cc create mode 100644 winsup/cygwin/include/sys/timerfd.h diff --git a/winsup/cygwin/Makefile.in b/winsup/cygwin/Makefile.in index 6147e7c9f..8481851c0 100644 --- a/winsup/cygwin/Makefile.in +++ b/winsup/cygwin/Makefile.in @@ -305,6 +305,7 @@ DLL_OFILES:= \ fhandler_socket_unix.o \ fhandler_tape.o \ fhandler_termios.o \ + fhandler_timerfd.o \ fhandler_tty.o \ fhandler_virtual.o \ fhandler_windows.o \ diff --git a/winsup/cygwin/common.din b/winsup/cygwin/common.din index b7f39f9c0..384cf0b15 100644 --- a/winsup/cygwin/common.din +++ b/winsup/cygwin/common.din @@ -1488,6 +1488,9 @@ timer_delete SIGFE timer_getoverrun SIGFE timer_gettime SIGFE timer_settime SIGFE +timerfd_create SIGFE +timerfd_gettime SIGFE +timerfd_settime SIGFE times SIGFE timezone SIGFE timingsafe_bcmp NOSIGFE diff --git a/winsup/cygwin/devices.cc b/winsup/cygwin/devices.cc index 31fd64fa2..2e31ca366 100644 --- a/winsup/cygwin/devices.cc +++ b/winsup/cygwin/devices.cc @@ -123,6 +123,9 @@ const _device dev_pipew_storage = const _device dev_signalfd_storage = {"", {FH_SIGNALFD}, "", exists_internal}; +const _device dev_timerfd_storage = + {"", {FH_TIMERFD}, "", exists_internal}; + const _device dev_socket_storage = {"", {FH_SOCKET}, "", exists_internal}; diff --git a/winsup/cygwin/devices.h b/winsup/cygwin/devices.h index 065f77e0e..47156f275 100644 --- a/winsup/cygwin/devices.h +++ b/winsup/cygwin/devices.h @@ -73,6 +73,7 @@ enum fh_devices FH_CYGDRIVE= FHDEV (DEV_VIRTFS_MAJOR, 192), FH_SIGNALFD= FHDEV (DEV_VIRTFS_MAJOR, 13), + FH_TIMERFD = FHDEV (DEV_VIRTFS_MAJOR, 14), DEV_FLOPPY_MAJOR = 2, FH_FLOPPY = FHDEV (DEV_FLOPPY_MAJOR, 0), @@ -404,6 +405,8 @@ extern const _device dev_af_unix_storage; extern const _device dev_signalfd_storage; #define signalfd_dev ((device *) &dev_signalfd_storage) +extern const _device dev_timerfd_storage; +#define timerfd_dev ((device *) &dev_timerfd_storage) extern const _device dev_piper_storage; #define piper_dev ((device *) &dev_piper_storage) extern const _device dev_pipew_storage; diff --git a/winsup/cygwin/devices.in b/winsup/cygwin/devices.in index 79a7fe726..59f5f00d2 100644 --- a/winsup/cygwin/devices.in +++ b/winsup/cygwin/devices.in @@ -119,6 +119,9 @@ const _device dev_pipew_storage = const _device dev_signalfd_storage = {"", {FH_SIGNALFD}, "", exists_internal}; +const _device dev_timerfd_storage = + {"", {FH_TIMERFD}, "", exists_internal}; + const _device dev_socket_storage = {"", {FH_SOCKET}, "", exists_internal}; diff --git a/winsup/cygwin/dtable.cc b/winsup/cygwin/dtable.cc index c8aecfa1a..663f99b34 100644 --- a/winsup/cygwin/dtable.cc +++ b/winsup/cygwin/dtable.cc @@ -578,6 +578,9 @@ fh_alloc (path_conv& pc) case FH_SIGNALFD: fh = cnew (fhandler_signalfd); break; + case FH_TIMERFD: + fh = cnew (fhandler_timerfd); + break; case FH_TTY: if (!pc.isopen ()) { diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h index f4a8b5463..898f85db2 100644 --- a/winsup/cygwin/fhandler.h +++ b/winsup/cygwin/fhandler.h @@ -421,6 +421,7 @@ public: virtual class fhandler_socket_wsock *is_wsock_socket () { return NULL; } virtual class fhandler_console *is_console () { return 0; } virtual class fhandler_signalfd *is_signalfd () { return NULL; } + virtual class fhandler_timerfd *is_timerfd () { return NULL; } virtual int is_windows () {return 0; } virtual void __reg3 raw_read (void *ptr, size_t& ulen); @@ -2673,6 +2674,55 @@ class fhandler_signalfd : public fhandler_base } }; +class fhandler_timerfd : public fhandler_base +{ + timer_t timerid; + + public: + fhandler_timerfd (); + fhandler_timerfd (void *) {} + + fhandler_timerfd *is_timerfd () { return this; } + + char *get_proc_fd_name (char *buf); + + int timerfd (clockid_t clock_id, int flags); + int settime (int flags, const struct itimerspec *value, + struct itimerspec *ovalue); + int gettime (struct itimerspec *ovalue); + + int __reg2 fstat (struct stat *buf); + void __reg3 read (void *ptr, size_t& len); + int dup (fhandler_base *child, int); + int ioctl (unsigned int, void *); + int close (); + + HANDLE get_timerfd_handle (); + + void fixup_after_fork_exec (bool); + void fixup_after_exec () {fixup_after_fork_exec (true);} + void fixup_after_fork (HANDLE) {fixup_after_fork_exec (false);} + + select_record *select_read (select_stuff *); + select_record *select_write (select_stuff *); + select_record *select_except (select_stuff *); + + void copyto (fhandler_base *x) + { + x->pc.free_strings (); + *reinterpret_cast (x) = *this; + x->reset (this); + } + + fhandler_timerfd *clone (cygheap_types malloc_type = HEAP_FHANDLER) + { + void *ptr = (void *) ccalloc (malloc_type, 1, sizeof (fhandler_timerfd)); + fhandler_timerfd *fh = new (ptr) fhandler_timerfd (ptr); + copyto (fh); + return fh; + } +}; + struct fhandler_nodevice: public fhandler_base { fhandler_nodevice (); @@ -2713,6 +2763,7 @@ typedef union char __registry[sizeof (fhandler_registry)]; char __serial[sizeof (fhandler_serial)]; char __signalfd[sizeof (fhandler_signalfd)]; + char __timerfd[sizeof (fhandler_timerfd)]; char __socket_inet[sizeof (fhandler_socket_inet)]; char __socket_local[sizeof (fhandler_socket_local)]; #ifdef __WITH_AF_UNIX diff --git a/winsup/cygwin/fhandler_timerfd.cc b/winsup/cygwin/fhandler_timerfd.cc new file mode 100644 index 000000000..b88c797ef --- /dev/null +++ b/winsup/cygwin/fhandler_timerfd.cc @@ -0,0 +1,198 @@ +/* fhandler_timerfd.cc: fhandler for timerfd + +This file is part of Cygwin. + +This software is a copyrighted work licensed under the terms of the +Cygwin license. Please consult the file "CYGWIN_LICENSE" for +details. */ + +#include "winsup.h" +#include "path.h" +#include "fhandler.h" +#include "pinfo.h" +#include "dtable.h" +#include "cygheap.h" +#include "timer.h" +#include +#include + +fhandler_timerfd::fhandler_timerfd () : + fhandler_base () +{ +} + +char * +fhandler_timerfd::get_proc_fd_name (char *buf) +{ + return strcpy (buf, "anon_inode:[timerfd]"); +} + +int +fhandler_timerfd::timerfd (clockid_t clock_id, int flags) +{ + timerid = (timer_t) new timer_tracker (clock_id, NULL, true); + if (flags & TFD_NONBLOCK) + set_nonblocking (true); + if (flags & TFD_CLOEXEC) + set_close_on_exec (true); + if (get_unique_id () == 0) + { + nohandle (true); + set_unique_id (); + set_ino (get_unique_id ()); + } + return 0; +} + +int +fhandler_timerfd::settime (int flags, const itimerspec *value, + itimerspec *ovalue) +{ + int ret = -1; + + __try + { + timer_tracker *tt = (timer_tracker *) timerid; + ret = tt->settime (flags, value, ovalue); + } + __except (EFAULT) {} + __endtry + return ret; +} + +int +fhandler_timerfd::gettime (itimerspec *ovalue) +{ + int ret = -1; + + __try + { + timer_tracker *tt = (timer_tracker *) timerid; + tt->gettime (ovalue); + ret = 0; + } + __except (EFAULT) {} + __endtry + return ret; +} + +int __reg2 +fhandler_timerfd::fstat (struct stat *buf) +{ + int ret = fhandler_base::fstat (buf); + if (!ret) + { + buf->st_mode = S_IRUSR | S_IWUSR; + buf->st_dev = FH_TIMERFD; + buf->st_ino = get_unique_id (); + } + return ret; +} + +void __reg3 +fhandler_timerfd::read (void *ptr, size_t& len) +{ + if (len < sizeof (LONG64)) + { + set_errno (EINVAL); + len = (size_t) -1; + return; + } + + __try + { + timer_tracker *tt = (timer_tracker *) timerid; + LONG64 ret = tt->wait (is_nonblocking ()); + if (ret == -1) + __leave; + PLONG64 pl64 = (PLONG64) ptr; + *pl64 = ret + 1; + len = sizeof (LONG64); + return; + } + __except (EFAULT) {} + __endtry + len = (size_t) -1; + return; +} + +HANDLE +fhandler_timerfd::get_timerfd_handle () +{ + __try + { + timer_tracker *tt = (timer_tracker *) timerid; + return tt->get_timerfd_handle (); + } + __except (EFAULT) {} + __endtry + return NULL; +} + +int +fhandler_timerfd::dup (fhandler_base *child, int flags) +{ + int ret = fhandler_base::dup (child, flags); + + if (!ret) + { + fhandler_timerfd *fhc = (fhandler_timerfd *) child; + __try + { + timer_tracker *tt = (timer_tracker *) fhc->timerid; + tt->increment_instances (); + ret = 0; + } + __except (EFAULT) {} + __endtry + } + return ret; +} + +void +fhandler_timerfd::fixup_after_fork_exec (bool execing) +{ + if (!execing) + { + /* TODO after fork */ + } + else if (!close_on_exec ()) + { + /* TODO after exec */ + } +} + +int +fhandler_timerfd::ioctl (unsigned int cmd, void *p) +{ + int ret = -1; + + switch (cmd) + { + case TFD_IOC_SET_TICKS: + /* TODO */ + ret = 0; + break; + default: + set_errno (EINVAL); + break; + } + syscall_printf ("%d = ioctl_timerfd(%x, %p)", ret, cmd, p); + return ret; +} + +int +fhandler_timerfd::close () +{ + int ret = -1; + + __try + { + timer_tracker *tt = (timer_tracker *) timerid; + timer_tracker::close (tt); + ret = 0; + } + __except (EFAULT) {} + __endtry + return ret; +} diff --git a/winsup/cygwin/include/cygwin/version.h b/winsup/cygwin/include/cygwin/version.h index ec5f55fa9..d6dcbea0e 100644 --- a/winsup/cygwin/include/cygwin/version.h +++ b/winsup/cygwin/include/cygwin/version.h @@ -503,12 +503,13 @@ details. */ CLOCK_BOOTTIME. 331: Add timer_getoverrun, DELAYTIMER_MAX. 332: Add signalfd. + 333: Add timerfd_create, timerfd_gettime, timerfd_settime. Note that we forgot to bump the api for ualarm, strtoll, strtoull, sigaltstack, sethostname. */ #define CYGWIN_VERSION_API_MAJOR 0 -#define CYGWIN_VERSION_API_MINOR 332 +#define CYGWIN_VERSION_API_MINOR 333 /* There is also a compatibity version number associated with the shared memory regions. It is incremented when incompatible changes are made to the shared diff --git a/winsup/cygwin/include/sys/timerfd.h b/winsup/cygwin/include/sys/timerfd.h new file mode 100644 index 000000000..bf3ce2ae0 --- /dev/null +++ b/winsup/cygwin/include/sys/timerfd.h @@ -0,0 +1,45 @@ +/* sys/timerfd.h: define timerfd_create(2) and friends + +This file is part of Cygwin. + +This software is a copyrighted work licensed under the terms of the +Cygwin license. Please consult the file "CYGWIN_LICENSE" for +details. */ + +#ifndef _SYS_TIMERFD_H +#define _SYS_TIMERFD_H + +#include +#include +#include + +enum +{ + /* timerfd_create */ + TFD_CLOEXEC = O_CLOEXEC, + TFD_NONBLOCK = O_NONBLOCK, + /* timerfd_settime */ + TFD_TIMER_ABSTIME = TIMER_ABSTIME, + TFD_TIMER_CANCEL_ON_SET = (TIMER_ABSTIME << 1) +}; +#define TFD_CLOEXEC TFD_CLOEXEC +#define TFD_NONBLOCK TFD_NONBLOCK +#define TFD_TIMER_ABSTIME TFD_TIMER_ABSTIME +#define TFD_TIMER_CANCEL_ON_SET TFD_TIMER_CANCEL_ON_SET + +#define TFD_IOC_SET_TICKS _IOW('T', 0, __uint64_t) + +#ifdef __cplusplus +extern "C" { +#endif + +extern int timerfd_create (clockid_t, int); +extern int timerfd_settime (int, int, const struct itimerspec *, + struct itimerspec *); +extern int timerfd_gettime (int, struct itimerspec *); + +#ifdef __cplusplus +} +#endif + +#endif /* _SYS_TIMERFD_H */ diff --git a/winsup/cygwin/release/2.12.0 b/winsup/cygwin/release/2.12.0 index a0dce6ffd..80d0c6fba 100644 --- a/winsup/cygwin/release/2.12.0 +++ b/winsup/cygwin/release/2.12.0 @@ -27,7 +27,8 @@ What's new: - Support overrun counter for posix timers (via timer_getoverrun() or siginfo_t::si_overrun). -- New API: signalfd, timer_getoverrun. +- New APIs: signalfd, timerfd_create, timerfd_gettime, timerfd_settime, + timer_getoverrun. What changed: diff --git a/winsup/cygwin/select.cc b/winsup/cygwin/select.cc index d1ae3c649..d6757e4ed 100644 --- a/winsup/cygwin/select.cc +++ b/winsup/cygwin/select.cc @@ -1870,3 +1870,48 @@ fhandler_signalfd::select_except (select_stuff *stuff) s->except_ready = false; return s; } + +select_record * +fhandler_timerfd::select_read (select_stuff *stuff) +{ + select_record *s = stuff->start.next; + if (!s->startup) + { + s->startup = no_startup; + s->verify = verify_ok; + } + s->h = get_timerfd_handle (); + s->read_selected = true; + s->read_ready = true; + return s; +} + +select_record * +fhandler_timerfd::select_write (select_stuff *stuff) +{ + select_record *s = stuff->start.next; + if (!s->startup) + { + s->startup = no_startup; + s->verify = no_verify; + } + s->peek = NULL; + s->write_selected = false; + s->write_ready = false; + return s; +} + +select_record * +fhandler_timerfd::select_except (select_stuff *stuff) +{ + select_record *s = stuff->start.next; + if (!s->startup) + { + s->startup = no_startup; + s->verify = no_verify; + } + s->peek = NULL; + s->except_selected = false; + s->except_ready = false; + return s; +} diff --git a/winsup/cygwin/timer.cc b/winsup/cygwin/timer.cc index e38decb9a..93e4714e2 100644 --- a/winsup/cygwin/timer.cc +++ b/winsup/cygwin/timer.cc @@ -15,13 +15,14 @@ details. */ #include "dtable.h" #include "cygheap.h" #include "timer.h" +#include #include #define EVENT_DISARMED 0 #define EVENT_ARMED -1 #define EVENT_LOCK 1 -timer_tracker NO_COPY ttstart (CLOCK_REALTIME, NULL); +timer_tracker NO_COPY ttstart (CLOCK_REALTIME, NULL, false); class lock_timer_tracker { @@ -58,34 +59,45 @@ timer_tracker::cancel () timer_tracker::~timer_tracker () { + HANDLE hdl; + + deleting = true; if (cancel ()) { - CloseHandle (hcancel); -#ifdef DEBUGGING - hcancel = NULL; -#endif + HANDLE hdl = InterlockedExchangePointer (&hcancel, NULL); + CloseHandle (hdl); + hdl = InterlockedExchangePointer (&timerfd_event, NULL); + if (hdl) + CloseHandle (hdl); } - if (syncthread) - CloseHandle (syncthread); + hdl = InterlockedExchangePointer (&syncthread, NULL); + if (hdl) + CloseHandle (hdl); magic = 0; } -timer_tracker::timer_tracker (clockid_t c, const sigevent *e) +/* fd is true for timerfd timers. */ +timer_tracker::timer_tracker (clockid_t c, const sigevent *e, bool fd) +: magic (TT_MAGIC), instance_count (1), clock_id (c), deleting (false), + hcancel (NULL), syncthread (NULL), event_running (EVENT_DISARMED), + overrun_count_curr (0), overrun_count (0) { if (e != NULL) evp = *e; + else if (fd) + { + evp.sigev_notify = SIGEV_NONE; + evp.sigev_signo = 0; + evp.sigev_value.sival_ptr = this; + } else { evp.sigev_notify = SIGEV_SIGNAL; evp.sigev_signo = SIGALRM; evp.sigev_value.sival_ptr = this; } - clock_id = c; - magic = TT_MAGIC; - hcancel = NULL; - event_running = EVENT_DISARMED; - overrun_count_curr = 0; - overrun_count = 0; + if (fd) + timerfd_event = CreateEvent (&sec_none_nih, TRUE, FALSE, NULL); if (this != &ttstart) { lock_timer_tracker here; @@ -94,6 +106,16 @@ timer_tracker::timer_tracker (clockid_t c, const sigevent *e) } } +void timer_tracker::increment_instances () +{ + InterlockedIncrement (&instance_count); +} + +LONG timer_tracker::decrement_instances () +{ + return InterlockedDecrement (&instance_count); +} + static inline int64_t timespec_to_us (const timespec& ts) { @@ -118,8 +140,8 @@ timer_tracker::arm_event () return ret; } -LONG -timer_tracker::disarm_event () +LONG64 +timer_tracker::_disarm_event () { LONG ret; @@ -128,13 +150,8 @@ timer_tracker::disarm_event () yield (); if (ret == EVENT_ARMED) { - LONG64 ov_cnt; - InterlockedExchange64 (&ov_cnt, overrun_count); - if (ov_cnt > DELAYTIMER_MAX || ov_cnt < 0) - overrun_count_curr = DELAYTIMER_MAX; - else - overrun_count_curr = ov_cnt; + InterlockedExchange64 (&overrun_count_curr, overrun_count); ret = overrun_count_curr; InterlockedExchange64 (&overrun_count, 0); InterlockedExchange (&event_running, EVENT_DISARMED); @@ -142,6 +159,51 @@ timer_tracker::disarm_event () return ret; } +unsigned int +timer_tracker::disarm_event () +{ + LONG64 ov = _disarm_event (); + if (ov > DELAYTIMER_MAX || ov < 0) + return DELAYTIMER_MAX; + return (unsigned int) ov; +} + +LONG64 +timer_tracker::wait (bool nonblocking) +{ + HANDLE w4[3] = { NULL, hcancel, timerfd_event }; + LONG64 ret = -1; + + wait_signal_arrived here (w4[0]); +repeat: + switch (WaitForMultipleObjects (3, w4, FALSE, nonblocking ? 0 : INFINITE)) + { + case WAIT_OBJECT_0: /* signal */ + if (_my_tls.call_signal_handler ()) + goto repeat; + set_errno (EINTR); + break; + case WAIT_OBJECT_0 + 1: /* settime oder timer delete */ + if (deleting) + { + set_errno (EIO); + break; + } + /*FALLTHRU*/ + case WAIT_OBJECT_0 + 2: /* timer event */ + ret = _disarm_event (); + ResetEvent (timerfd_event); + break; + case WAIT_TIMEOUT: + set_errno (EAGAIN); + break; + default: + __seterrno (); + break; + } + return ret; +} + static void * notify_thread_wrapper (void *arg) { @@ -198,6 +260,14 @@ timer_tracker::thread_func () switch (evp.sigev_notify) { + case SIGEV_NONE: + { + if (!timerfd_event) + break; + arm_event (); + SetEvent (timerfd_event); + break; + } case SIGEV_SIGNAL: { if (arm_event ()) @@ -350,9 +420,17 @@ timer_tracker::gettime (itimerspec *ovalue) } } +/* Returns + + 1 if we still have to keep the timer around + 0 if we can delete the timer + -1 if we can't find the timer in the list +*/ int timer_tracker::clean_and_unhook () { + if (decrement_instances () > 0) + return 1; for (timer_tracker *tt = &ttstart; tt->next != NULL; tt = tt->next) if (tt->next == this) { @@ -362,9 +440,26 @@ timer_tracker::clean_and_unhook () return -1; } +int +timer_tracker::close (timer_tracker *tt) +{ + lock_timer_tracker here; + int ret = tt->clean_and_unhook (); + if (ret >= 0) + { + if (ret == 0) + delete tt; + ret = 0; + } + else + set_errno (EINVAL); + return ret; +} + void timer_tracker::fixup_after_fork () { + /* TODO: Keep timerfd timers available and restart them */ ttstart.hcancel = ttstart.syncthread = NULL; ttstart.event_running = EVENT_DISARMED; ttstart.overrun_count_curr = 0; @@ -412,21 +507,21 @@ timer_create (clockid_t clock_id, struct sigevent *__restrict evp, { int ret = -1; + if (CLOCKID_IS_PROCESS (clock_id) || CLOCKID_IS_THREAD (clock_id)) + { + set_errno (ENOTSUP); + return -1; + } + + if (clock_id >= MAX_CLOCKS) + { + set_errno (EINVAL); + return -1; + } + __try { - if (CLOCKID_IS_PROCESS (clock_id) || CLOCKID_IS_THREAD (clock_id)) - { - set_errno (ENOTSUP); - return -1; - } - - if (clock_id >= MAX_CLOCKS) - { - set_errno (EINVAL); - return -1; - } - - *timerid = (timer_t) new timer_tracker (clock_id, evp); + *timerid = (timer_t) new timer_tracker (clock_id, evp, false); ret = 0; } __except (EFAULT) {} @@ -489,15 +584,7 @@ timer_delete (timer_t timerid) set_errno (EINVAL); __leave; } - - lock_timer_tracker here; - if (in_tt->clean_and_unhook () == 0) - { - delete in_tt; - ret = 0; - } - else - set_errno (EINVAL); + ret = timer_tracker::close (in_tt); } __except (EFAULT) {} __endtry @@ -604,3 +691,84 @@ ualarm (useconds_t value, useconds_t interval) syscall_printf ("%d = ualarm(%ld , %ld)", ret, value, interval); return ret; } + +extern "C" +timerfd_create (clockid_t clock_id, int flags) +{ + int ret = -1; + fhandler_timerfd *fh; + + debug_printf ("timerfd (%lu, %y)", clock_id, flags); + + if (clock_id != CLOCK_REALTIME + && clock_id != CLOCK_MONOTONIC + && clock_id != CLOCK_BOOTTIME) + { + set_errno (EINVAL); + return -1; + } + if ((flags & ~(TFD_NONBLOCK | TFD_CLOEXEC)) != 0) + { + set_errno (EINVAL); + goto done; + } + + { + /* Create new timerfd descriptor. */ + cygheap_fdnew fd; + + if (fd < 0) + goto done; + fh = (fhandler_timerfd *) build_fh_dev (*timerfd_dev); + if (fh && fh->timerfd (clock_id, flags) == 0) + { + fd = fh; + if (fd <= 2) + set_std_handle (fd); + ret = fd; + } + else + delete fh; + } + +done: + syscall_printf ("%R = timerfd (%lu, %y)", ret, clock_id, flags); + return ret; +} + +extern "C" int +timerfd_settime (int fd_in, int flags, const struct itimerspec *value, + struct itimerspec *ovalue) +{ + if ((flags & ~(TFD_TIMER_ABSTIME | TFD_TIMER_CANCEL_ON_SET)) != 0) + { + set_errno (EINVAL); + return -1; + } + + cygheap_fdget fd (fd_in); + if (fd < 0) + return -1; + fhandler_timerfd *fh = fd->is_timerfd (); + if (!fh) + { + set_errno (EINVAL); + return -1; + } + return fh->settime (flags, value, ovalue); +} + +extern "C" int +timerfd_gettime (int fd_in, struct itimerspec *ovalue) +{ + cygheap_fdget fd (fd_in); + if (fd < 0) + return -1; + fhandler_timerfd *fh = fd->is_timerfd (); + if (!fh) + { + set_errno (EINVAL); + return -1; + } + return fh->gettime (ovalue); +} diff --git a/winsup/cygwin/timer.h b/winsup/cygwin/timer.h index f75cd487c..2a31e3e77 100644 --- a/winsup/cygwin/timer.h +++ b/winsup/cygwin/timer.h @@ -14,35 +14,46 @@ class timer_tracker { unsigned magic; timer_tracker *next; + LONG instance_count; clockid_t clock_id; sigevent evp; timespec it_interval; + bool deleting; HANDLE hcancel; HANDLE syncthread; + HANDLE timerfd_event; int64_t interval_us; int64_t sleepto_us; LONG event_running; - LONG overrun_count_curr; + LONG64 overrun_count_curr; LONG64 overrun_count; bool cancel (); + LONG decrement_instances (); + int clean_and_unhook (); + LONG64 _disarm_event (); public: - timer_tracker (clockid_t, const sigevent *); + timer_tracker (clockid_t, const sigevent *, bool); ~timer_tracker (); inline bool is_timer_tracker () const { return magic == TT_MAGIC; } + + void increment_instances (); + LONG64 wait (bool nonblocking); + HANDLE get_timerfd_handle () const { return timerfd_event; } + inline sigevent_t *sigevt () { return &evp; } - inline int getoverrun () const { return overrun_count_curr; } + inline LONG64 getoverrun () const { return overrun_count_curr; } void gettime (itimerspec *); int settime (int, const itimerspec *, itimerspec *); - int clean_and_unhook (); LONG arm_event (); - LONG disarm_event (); + unsigned int disarm_event (); DWORD thread_func (); static void fixup_after_fork (); + static int close (timer_tracker *tt); }; #endif /* __TIMER_H__ */ diff --git a/winsup/doc/new-features.xml b/winsup/doc/new-features.xml index d4fc74510..2c4b3e43f 100644 --- a/winsup/doc/new-features.xml +++ b/winsup/doc/new-features.xml @@ -51,7 +51,8 @@ siginfo_t::si_overrun). -New API: signalfd, timer_getoverrun. +New APIs: signalfd, timerfd_create, timerfd_gettime, timerfd_settime, +timer_getoverrun. diff --git a/winsup/doc/posix.xml b/winsup/doc/posix.xml index 365a8f0b5..8e9b1a511 100644 --- a/winsup/doc/posix.xml +++ b/winsup/doc/posix.xml @@ -1394,6 +1394,9 @@ also IEEE Std 1003.1-2008 (POSIX.1-2008). strverscmp sysinfo tdestroy + timerfd_create + timerfd_gettime + timerfd_settime timegm timelocal toascii_l From 5b147c76d24f990c9fb7ab9617defe12c62dc2b2 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Wed, 16 Jan 2019 09:24:55 +0100 Subject: [PATCH 104/475] Cygwin: timerfd_create: add missing type Signed-off-by: Corinna Vinschen --- winsup/cygwin/timer.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/winsup/cygwin/timer.cc b/winsup/cygwin/timer.cc index 93e4714e2..657407fe4 100644 --- a/winsup/cygwin/timer.cc +++ b/winsup/cygwin/timer.cc @@ -692,7 +692,7 @@ ualarm (useconds_t value, useconds_t interval) return ret; } -extern "C" +extern "C" int timerfd_create (clockid_t clock_id, int flags) { int ret = -1; From 89a99d3b580083818fa8d4117fd4916bf8a8fe00 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Wed, 16 Jan 2019 00:11:03 +0100 Subject: [PATCH 105/475] Cygwin: posix timers: fix overrun computation - Drop initial overrun computation from timer_tracker::settimer. It's performed in timer_tracker::thread_func anyway. - Fix regression in returning correct overrun count narrowed down to int from timer_getoverrun. This has been introduced by changing overrun_count_curr to LONG64. Signed-off-by: Corinna Vinschen --- winsup/cygwin/timer.cc | 25 ++++++++----------------- 1 file changed, 8 insertions(+), 17 deletions(-) diff --git a/winsup/cygwin/timer.cc b/winsup/cygwin/timer.cc index 657407fe4..c429af6ee 100644 --- a/winsup/cygwin/timer.cc +++ b/winsup/cygwin/timer.cc @@ -369,22 +369,9 @@ timer_tracker::settime (int in_flags, const itimerspec *value, itimerspec *ovalu else { interval_us = timespec_to_us (value->it_interval); - if (in_flags & TIMER_ABSTIME) - { - int64_t now = get_clock (clock_id)->usecs (); - - sleepto_us = timespec_to_us (value->it_value); - if (sleepto_us <= now) - { - int64_t ov_cnt = (now - sleepto_us + (interval_us + 1)) - / interval_us; - InterlockedAdd64 (&overrun_count, ov_cnt); - sleepto_us += ov_cnt * interval_us; - } - } - else - sleepto_us = get_clock (clock_id)->usecs () - + timespec_to_us (value->it_value); + sleepto_us = timespec_to_us (value->it_value); + if (!(in_flags & TIMER_ABSTIME)) + sleepto_us += get_clock (clock_id)->usecs (); it_interval = value->it_interval; if (!hcancel) hcancel = CreateEvent (&sec_none_nih, TRUE, FALSE, NULL); @@ -564,7 +551,11 @@ timer_getoverrun (timer_t timerid) set_errno (EINVAL); __leave; } - ret = tt->getoverrun (); + LONG64 ov_cnt = tt->getoverrun (); + if (ov_cnt > DELAYTIMER_MAX || ov_cnt < 0) + ret = DELAYTIMER_MAX; + else + ret = ov_cnt; } __except (EFAULT) {} __endtry From f5808867cf4ccedc1d91949ee75fe102f0d11c1b Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Wed, 16 Jan 2019 12:59:27 +0100 Subject: [PATCH 106/475] Cygwin: fork: move extern declarations to appropriate headers Signed-off-by: Corinna Vinschen --- winsup/cygwin/fork.cc | 3 +-- winsup/cygwin/timer.h | 2 ++ winsup/cygwin/winsup.h | 1 + 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/winsup/cygwin/fork.cc b/winsup/cygwin/fork.cc index c6fef6755..5cfdd9559 100644 --- a/winsup/cygwin/fork.cc +++ b/winsup/cygwin/fork.cc @@ -22,6 +22,7 @@ details. */ #include "tls_pbuf.h" #include "dll_init.h" #include "cygmalloc.h" +#include "timer.h" #include "ntdll.h" #define NPIDS_HELD 4 @@ -129,8 +130,6 @@ int __stdcall frok::child (volatile char * volatile here) { HANDLE& hParent = ch.parent; - extern void fixup_hooks_after_fork (); - extern void fixup_timers_after_fork (); /* NOTE: Logically this belongs in dll_list::load_after_fork, but by doing it here, before the first sync_with_parent, we can exploit diff --git a/winsup/cygwin/timer.h b/winsup/cygwin/timer.h index 2a31e3e77..595d9fe9b 100644 --- a/winsup/cygwin/timer.h +++ b/winsup/cygwin/timer.h @@ -56,4 +56,6 @@ class timer_tracker static int close (timer_tracker *tt); }; +extern void fixup_timers_after_fork (); + #endif /* __TIMER_H__ */ diff --git a/winsup/cygwin/winsup.h b/winsup/cygwin/winsup.h index d5babd6cd..3a5f5d538 100644 --- a/winsup/cygwin/winsup.h +++ b/winsup/cygwin/winsup.h @@ -185,6 +185,7 @@ extern "C" void error_start_init (const char*); extern "C" int try_to_debug (bool waitloop = 1); void ld_preload (); +void fixup_hooks_after_fork (); const char *find_first_notloaded_dll (class path_conv &); /**************************** Miscellaneous ******************************/ From 4195bae67f19b02e860678c8d2c2db3eddd4276a Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Wed, 16 Jan 2019 15:33:15 +0100 Subject: [PATCH 107/475] Cygwin: timerfd: implement fork semantics - Puzzeling: Commit ec98d19a08c2e4678e8a6f40fea0c9bbeaa4a2c7 changed ttstart to NO_COPY but kept all the code to handle fixup after fork. Revert to not-NO_COPY and make timerfd fork work. - On fixup_after_fork, keep timerfd timers and restart thread if they were armed in the parent. - Move timerfd timer_trackers to cygheap. Overload timer_tracker new and delete methods to handle timers accordingly. This is not exactly required for fork, but exec will be grateful. - Give up on TFD_TIMER_CANCEL_ON_SET for now. There's no easy way to recognize a discontinuous change in a clock. - Be paranoid when cleaning out ttstart. - Fix some minor issues. Signed-off-by: Corinna Vinschen --- winsup/cygwin/fhandler.h | 4 +-- winsup/cygwin/fhandler_timerfd.cc | 19 +++++++----- winsup/cygwin/timer.cc | 49 ++++++++++++++++++++++++------- winsup/cygwin/timer.h | 6 ++++ 4 files changed, 58 insertions(+), 20 deletions(-) diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h index 898f85db2..f0c612d8a 100644 --- a/winsup/cygwin/fhandler.h +++ b/winsup/cygwin/fhandler.h @@ -2699,9 +2699,7 @@ class fhandler_timerfd : public fhandler_base HANDLE get_timerfd_handle (); - void fixup_after_fork_exec (bool); - void fixup_after_exec () {fixup_after_fork_exec (true);} - void fixup_after_fork (HANDLE) {fixup_after_fork_exec (false);} + void fixup_after_exec (); select_record *select_read (select_stuff *); select_record *select_write (select_stuff *); diff --git a/winsup/cygwin/fhandler_timerfd.cc b/winsup/cygwin/fhandler_timerfd.cc index b88c797ef..8ce91af86 100644 --- a/winsup/cygwin/fhandler_timerfd.cc +++ b/winsup/cygwin/fhandler_timerfd.cc @@ -27,10 +27,19 @@ fhandler_timerfd::get_proc_fd_name (char *buf) return strcpy (buf, "anon_inode:[timerfd]"); } +/* The timers connected to a descriptor are stored on the cygheap + together with their fhandler. */ + +#define cnew(name, ...) \ + ({ \ + void* ptr = (void*) ccalloc (HEAP_FHANDLER, 1, sizeof (name)); \ + ptr ? new (ptr) name (__VA_ARGS__) : NULL; \ + }) + int fhandler_timerfd::timerfd (clockid_t clock_id, int flags) { - timerid = (timer_t) new timer_tracker (clock_id, NULL, true); + timerid = (timer_t) cnew (timer_tracker, clock_id, NULL, true); if (flags & TFD_NONBLOCK) set_nonblocking (true); if (flags & TFD_CLOEXEC) @@ -150,13 +159,9 @@ fhandler_timerfd::dup (fhandler_base *child, int flags) } void -fhandler_timerfd::fixup_after_fork_exec (bool execing) +fhandler_timerfd::fixup_after_exec () { - if (!execing) - { - /* TODO after fork */ - } - else if (!close_on_exec ()) + if (!close_on_exec ()) { /* TODO after exec */ } diff --git a/winsup/cygwin/timer.cc b/winsup/cygwin/timer.cc index c429af6ee..bd412f0e2 100644 --- a/winsup/cygwin/timer.cc +++ b/winsup/cygwin/timer.cc @@ -22,7 +22,8 @@ details. */ #define EVENT_ARMED -1 #define EVENT_LOCK 1 -timer_tracker NO_COPY ttstart (CLOCK_REALTIME, NULL, false); +/* Must not be NO_COPY, otherwise timerfd breaks. */ +timer_tracker ttstart (CLOCK_REALTIME, NULL, false); class lock_timer_tracker { @@ -79,7 +80,8 @@ timer_tracker::~timer_tracker () /* fd is true for timerfd timers. */ timer_tracker::timer_tracker (clockid_t c, const sigevent *e, bool fd) : magic (TT_MAGIC), instance_count (1), clock_id (c), deleting (false), - hcancel (NULL), syncthread (NULL), event_running (EVENT_DISARMED), + hcancel (NULL), syncthread (NULL), timerfd_event (NULL), + interval_us(0), sleepto_us(0), event_running (EVENT_DISARMED), overrun_count_curr (0), overrun_count (0) { if (e != NULL) @@ -171,7 +173,7 @@ timer_tracker::disarm_event () LONG64 timer_tracker::wait (bool nonblocking) { - HANDLE w4[3] = { NULL, hcancel, timerfd_event }; + HANDLE w4[3] = { NULL, hcancel, get_timerfd_handle () }; LONG64 ret = -1; wait_signal_arrived here (w4[0]); @@ -264,7 +266,11 @@ timer_tracker::thread_func () { if (!timerfd_event) break; - arm_event (); + if (arm_event ()) + { + debug_printf ("%p timerfd already queued", this); + break; + } SetEvent (timerfd_event); break; } @@ -443,20 +449,41 @@ timer_tracker::close (timer_tracker *tt) return ret; } +void +timer_tracker::restart () +{ + timerfd_event = CreateEvent (&sec_none_nih, TRUE, FALSE, NULL); + if (interval_us != 0 || sleepto_us != 0) + { + hcancel = CreateEvent (&sec_none_nih, TRUE, FALSE, NULL); + syncthread = CreateEvent (&sec_none_nih, TRUE, FALSE, NULL); + new cygthread (timer_thread, this, "itimer", syncthread); + } +} + void timer_tracker::fixup_after_fork () { - /* TODO: Keep timerfd timers available and restart them */ ttstart.hcancel = ttstart.syncthread = NULL; + ttstart.interval_us = ttstart.sleepto_us = 0; ttstart.event_running = EVENT_DISARMED; - ttstart.overrun_count_curr = 0; - ttstart.overrun_count = 0; + ttstart.overrun_count_curr = ttstart.overrun_count = 0; for (timer_tracker *tt = &ttstart; tt->next != NULL; /* nothing */) { timer_tracker *deleteme = tt->next; - tt->next = deleteme->next; - deleteme->hcancel = deleteme->syncthread = NULL; - delete deleteme; + if (deleteme->get_timerfd_handle ()) + { + tt = deleteme; + tt->restart (); + } + else + { + tt->next = deleteme->next; + deleteme->timerfd_event = NULL; + deleteme->hcancel = NULL; + deleteme->syncthread = NULL; + delete deleteme; + } } } @@ -731,6 +758,8 @@ extern "C" int timerfd_settime (int fd_in, int flags, const struct itimerspec *value, struct itimerspec *ovalue) { + /* There's no easy way to implement TFD_TIMER_CANCEL_ON_SET, but + we should at least accept the flag. */ if ((flags & ~(TFD_TIMER_ABSTIME | TFD_TIMER_CANCEL_ON_SET)) != 0) { set_errno (EINVAL); diff --git a/winsup/cygwin/timer.h b/winsup/cygwin/timer.h index 595d9fe9b..f4c89bc6b 100644 --- a/winsup/cygwin/timer.h +++ b/winsup/cygwin/timer.h @@ -33,8 +33,14 @@ class timer_tracker LONG decrement_instances (); int clean_and_unhook (); LONG64 _disarm_event (); + void restart (); public: + void *operator new (size_t size) __attribute__ ((nothrow)) + { return malloc (size); } + void *operator new (size_t, void *p) __attribute__ ((nothrow)) {return p;} + void operator delete(void *p) { incygheap (p) ? cfree (p) : free (p); } + timer_tracker (clockid_t, const sigevent *, bool); ~timer_tracker (); inline bool is_timer_tracker () const { return magic == TT_MAGIC; } From 0e8c7b8689d18b75371ee3411a3ac68ed37fa3ef Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Wed, 16 Jan 2019 18:40:26 +0100 Subject: [PATCH 108/475] Cygwin: timerfd: implement execve semantics Signed-off-by: Corinna Vinschen --- winsup/cygwin/fhandler_timerfd.cc | 9 +++++++-- winsup/cygwin/timer.cc | 28 +++++++++++++++++----------- winsup/cygwin/timer.h | 6 ++++-- 3 files changed, 28 insertions(+), 15 deletions(-) diff --git a/winsup/cygwin/fhandler_timerfd.cc b/winsup/cygwin/fhandler_timerfd.cc index 8ce91af86..cbcbefdcb 100644 --- a/winsup/cygwin/fhandler_timerfd.cc +++ b/winsup/cygwin/fhandler_timerfd.cc @@ -161,10 +161,15 @@ fhandler_timerfd::dup (fhandler_base *child, int flags) void fhandler_timerfd::fixup_after_exec () { - if (!close_on_exec ()) + if (close_on_exec ()) + return; + __try { - /* TODO after exec */ + timer_tracker *tt = (timer_tracker *) timerid; + tt->fixup_after_exec (); } + __except (EFAULT) {} + __endtry } int diff --git a/winsup/cygwin/timer.cc b/winsup/cygwin/timer.cc index bd412f0e2..be3fcf7c5 100644 --- a/winsup/cygwin/timer.cc +++ b/winsup/cygwin/timer.cc @@ -108,16 +108,6 @@ timer_tracker::timer_tracker (clockid_t c, const sigevent *e, bool fd) } } -void timer_tracker::increment_instances () -{ - InterlockedIncrement (&instance_count); -} - -LONG timer_tracker::decrement_instances () -{ - return InterlockedDecrement (&instance_count); -} - static inline int64_t timespec_to_us (const timespec& ts) { @@ -152,7 +142,6 @@ timer_tracker::_disarm_event () yield (); if (ret == EVENT_ARMED) { - InterlockedExchange64 (&overrun_count_curr, overrun_count); ret = overrun_count_curr; InterlockedExchange64 (&overrun_count, 0); @@ -461,6 +450,23 @@ timer_tracker::restart () } } +/* Only called from fhandler_timerfd::fixup_after_exec. Note that + we don't touch the instance count. This is handled by closing + the timer from fhandler_timerfd::close on O_CLOEXEC. Ultimately + the instance count should be correct after execve. */ +void +timer_tracker::fixup_after_exec () +{ + lock_timer_tracker here; + /* Check if timer is already in the list. If so, skip it. */ + for (timer_tracker *tt = &ttstart; tt->next != NULL; tt = tt->next) + if (tt->next == this) + return; + next = ttstart.next; + ttstart.next = this; + restart (); +} + void timer_tracker::fixup_after_fork () { diff --git a/winsup/cygwin/timer.h b/winsup/cygwin/timer.h index f4c89bc6b..3b426a308 100644 --- a/winsup/cygwin/timer.h +++ b/winsup/cygwin/timer.h @@ -30,7 +30,7 @@ class timer_tracker LONG64 overrun_count; bool cancel (); - LONG decrement_instances (); + LONG decrement_instances () { return InterlockedDecrement (&instance_count); } int clean_and_unhook (); LONG64 _disarm_event (); void restart (); @@ -45,7 +45,8 @@ class timer_tracker ~timer_tracker (); inline bool is_timer_tracker () const { return magic == TT_MAGIC; } - void increment_instances (); + + void increment_instances () { InterlockedIncrement (&instance_count); } LONG64 wait (bool nonblocking); HANDLE get_timerfd_handle () const { return timerfd_event; } @@ -58,6 +59,7 @@ class timer_tracker unsigned int disarm_event (); DWORD thread_func (); + void fixup_after_exec (); static void fixup_after_fork (); static int close (timer_tracker *tt); }; From 173e067a31bde9812c0f0ad19de082fb5e176427 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Wed, 16 Jan 2019 18:40:53 +0100 Subject: [PATCH 109/475] Cygwin: timerfd: implement TFD_IOC_SET_TICKS ioctl Signed-off-by: Corinna Vinschen --- winsup/cygwin/fhandler_timerfd.cc | 18 ++++++++++++++++-- winsup/cygwin/timer.cc | 16 ++++++++++++++++ winsup/cygwin/timer.h | 2 ++ 3 files changed, 34 insertions(+), 2 deletions(-) diff --git a/winsup/cygwin/fhandler_timerfd.cc b/winsup/cygwin/fhandler_timerfd.cc index cbcbefdcb..360731ca1 100644 --- a/winsup/cygwin/fhandler_timerfd.cc +++ b/winsup/cygwin/fhandler_timerfd.cc @@ -176,15 +176,29 @@ int fhandler_timerfd::ioctl (unsigned int cmd, void *p) { int ret = -1; + uint64_t ov_cnt; switch (cmd) { case TFD_IOC_SET_TICKS: - /* TODO */ + __try + { + timer_tracker *tt = (timer_tracker *) timerid; + + ov_cnt = *(uint64_t *) p; + if (!ov_cnt) + { + set_errno (EINVAL); + break; + } + tt->set_event (ov_cnt); + } + __except (EFAULT) {} + __endtry ret = 0; break; default: - set_errno (EINVAL); + ret = fhandler_base::ioctl (cmd, p); break; } syscall_printf ("%d = ioctl_timerfd(%x, %p)", ret, cmd, p); diff --git a/winsup/cygwin/timer.cc b/winsup/cygwin/timer.cc index be3fcf7c5..c97274538 100644 --- a/winsup/cygwin/timer.cc +++ b/winsup/cygwin/timer.cc @@ -132,6 +132,22 @@ timer_tracker::arm_event () return ret; } +void +timer_tracker::set_event (uint64_t ov_cnt) +{ + LONG ret; + + while ((ret = InterlockedCompareExchange (&event_running, EVENT_LOCK, + EVENT_DISARMED)) == EVENT_LOCK) + yield (); + InterlockedExchange64 (&overrun_count, ov_cnt); + if (ret == EVENT_DISARMED) + { + SetEvent (get_timerfd_handle ()); + InterlockedExchange (&event_running, EVENT_ARMED); + } +} + LONG64 timer_tracker::_disarm_event () { diff --git a/winsup/cygwin/timer.h b/winsup/cygwin/timer.h index 3b426a308..b9a072e6d 100644 --- a/winsup/cygwin/timer.h +++ b/winsup/cygwin/timer.h @@ -55,7 +55,9 @@ class timer_tracker void gettime (itimerspec *); int settime (int, const itimerspec *, itimerspec *); + LONG arm_event (); + void set_event (uint64_t ov_cnt); unsigned int disarm_event (); DWORD thread_func (); From 7f983079d4a62e3f906a97bf091908a1dad29bb6 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Thu, 17 Jan 2019 11:51:11 +0100 Subject: [PATCH 110/475] Cygwin: timerfd/signalfd: return EINVAL from write Linux returns EINVAL, "fd is attached to an object which is unsuitable for writing". If we don't handle write locally, write returns EBADF. Signed-off-by: Corinna Vinschen --- winsup/cygwin/fhandler.h | 2 ++ winsup/cygwin/fhandler_signalfd.cc | 8 ++++++++ winsup/cygwin/fhandler_timerfd.cc | 17 +++++++++++------ 3 files changed, 21 insertions(+), 6 deletions(-) diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h index f0c612d8a..497612ae1 100644 --- a/winsup/cygwin/fhandler.h +++ b/winsup/cygwin/fhandler.h @@ -2650,6 +2650,7 @@ class fhandler_signalfd : public fhandler_base int signalfd (const sigset_t *mask, int flags); int __reg2 fstat (struct stat *buf); void __reg3 read (void *ptr, size_t& len); + ssize_t __stdcall write (const void *, size_t); int poll (); inline sigset_t get_sigset () const { return sigset; } @@ -2693,6 +2694,7 @@ class fhandler_timerfd : public fhandler_base int __reg2 fstat (struct stat *buf); void __reg3 read (void *ptr, size_t& len); + ssize_t __stdcall write (const void *, size_t); int dup (fhandler_base *child, int); int ioctl (unsigned int, void *); int close (); diff --git a/winsup/cygwin/fhandler_signalfd.cc b/winsup/cygwin/fhandler_signalfd.cc index d8e17a8fc..6c7da02e9 100644 --- a/winsup/cygwin/fhandler_signalfd.cc +++ b/winsup/cygwin/fhandler_signalfd.cc @@ -49,6 +49,7 @@ fhandler_signalfd::signalfd (const sigset_t *mask, int flags) nohandle (true); set_unique_id (); set_ino (get_unique_id ()); + set_flags (O_RDWR | O_BINARY); } return 0; } @@ -139,6 +140,13 @@ fhandler_signalfd::read (void *ptr, size_t& len) return; } +ssize_t __stdcall +fhandler_signalfd::write (const void *, size_t) +{ + set_errno (EINVAL); + return -1; +} + /* Called from select */ int fhandler_signalfd::poll () diff --git a/winsup/cygwin/fhandler_timerfd.cc b/winsup/cygwin/fhandler_timerfd.cc index 360731ca1..c7ff9c162 100644 --- a/winsup/cygwin/fhandler_timerfd.cc +++ b/winsup/cygwin/fhandler_timerfd.cc @@ -44,12 +44,10 @@ fhandler_timerfd::timerfd (clockid_t clock_id, int flags) set_nonblocking (true); if (flags & TFD_CLOEXEC) set_close_on_exec (true); - if (get_unique_id () == 0) - { - nohandle (true); - set_unique_id (); - set_ino (get_unique_id ()); - } + nohandle (true); + set_unique_id (); + set_ino (get_unique_id ()); + set_flags (O_RDWR | O_BINARY); return 0; } @@ -125,6 +123,13 @@ fhandler_timerfd::read (void *ptr, size_t& len) return; } +ssize_t __stdcall +fhandler_timerfd::write (const void *, size_t) +{ + set_errno (EINVAL); + return -1; +} + HANDLE fhandler_timerfd::get_timerfd_handle () { From 397526dee858e4b43b0e4ecca470a1df92f09d5d Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Fri, 18 Jan 2019 14:31:01 +0100 Subject: [PATCH 111/475] Cygwin: clock.h: add valid_timespec() to check timespec for validity Use throughout, drop local timespec_bad() in timer.cc. Signed-off-by: Corinna Vinschen --- winsup/cygwin/aio.cc | 2 +- winsup/cygwin/clock.h | 8 ++++++++ winsup/cygwin/posix_ipc.cc | 4 +--- winsup/cygwin/signal.cc | 5 ++--- winsup/cygwin/thread.cc | 4 +--- winsup/cygwin/timer.cc | 19 ++++++------------- 6 files changed, 19 insertions(+), 23 deletions(-) diff --git a/winsup/cygwin/aio.cc b/winsup/cygwin/aio.cc index b245bdd02..f38ea4d11 100644 --- a/winsup/cygwin/aio.cc +++ b/winsup/cygwin/aio.cc @@ -766,7 +766,7 @@ aiosuspend (const struct aiocb *const aiolist[], if (timeout) { to = *timeout; - if (to.tv_sec < 0 || to.tv_nsec < 0 || to.tv_nsec > NSPERSEC) + if (!valid_timespec (to)) { set_errno (EINVAL); return -1; diff --git a/winsup/cygwin/clock.h b/winsup/cygwin/clock.h index c05bf477c..538b4b284 100644 --- a/winsup/cygwin/clock.h +++ b/winsup/cygwin/clock.h @@ -166,4 +166,12 @@ ts_diff (const struct timespec &ts0, struct timespec &ts1) ts1.tv_sec -= ts0.tv_sec; } +static inline bool +valid_timespec (const timespec& ts) +{ + if (ts.tv_nsec < 0 || ts.tv_nsec >= NSPERSEC || ts.tv_sec < 0) + return false; + return true; +} + #endif /*__CLOCK_H__*/ diff --git a/winsup/cygwin/posix_ipc.cc b/winsup/cygwin/posix_ipc.cc index 36e9ed9cf..86734c96a 100644 --- a/winsup/cygwin/posix_ipc.cc +++ b/winsup/cygwin/posix_ipc.cc @@ -181,9 +181,7 @@ ipc_cond_timedwait (HANDLE evt, HANDLE mtx, const struct timespec *abstime) ++cnt; if (abstime) { - if (abstime->tv_sec < 0 - || abstime->tv_nsec < 0 - || abstime->tv_nsec >= NSPERSEC) + if (!valid_timespec (*abstime)) return EINVAL; /* If a timeout is set, we create a waitable timer to wait for. diff --git a/winsup/cygwin/signal.cc b/winsup/cygwin/signal.cc index 5759cc4d6..fdde26058 100644 --- a/winsup/cygwin/signal.cc +++ b/winsup/cygwin/signal.cc @@ -69,7 +69,7 @@ clock_nanosleep (clockid_t clk_id, int flags, const struct timespec *rqtp, __try { - if (rqtp->tv_sec < 0 || rqtp->tv_nsec < 0 || rqtp->tv_nsec >= NSPERSEC) + if (!valid_timespec (*rqtp)) return EINVAL; } __except (NO_ERROR) @@ -654,8 +654,7 @@ sigtimedwait (const sigset_t *set, siginfo_t *info, const timespec *timeout) if (timeout) { - if (timeout->tv_sec < 0 - || timeout->tv_nsec < 0 || timeout->tv_nsec > NSPERSEC) + if (!valid_timespec (*timeout)) { set_errno (EINVAL); return -1; diff --git a/winsup/cygwin/thread.cc b/winsup/cygwin/thread.cc index f0f7b0a5f..c7b7e5157 100644 --- a/winsup/cygwin/thread.cc +++ b/winsup/cygwin/thread.cc @@ -2549,9 +2549,7 @@ pthread_convert_abstime (clockid_t clock_id, const struct timespec *abstime, struct timespec tp; /* According to SUSv3, the abstime value must be checked for validity. */ - if (abstime->tv_sec < 0 - || abstime->tv_nsec < 0 - || abstime->tv_nsec >= NSPERSEC) + if (!valid_timespec (*abstime)) return EINVAL; /* Check for immediate timeout before converting */ diff --git a/winsup/cygwin/timer.cc b/winsup/cygwin/timer.cc index c97274538..e817dab81 100644 --- a/winsup/cygwin/timer.cc +++ b/winsup/cygwin/timer.cc @@ -342,17 +342,6 @@ timer_thread (VOID *x) return tt->thread_func (); } -static inline bool -timespec_bad (const timespec& t) -{ - if (t.tv_nsec < 0 || t.tv_nsec >= NSPERSEC || t.tv_sec < 0) - { - set_errno (EINVAL); - return true; - } - return false; -} - int timer_tracker::settime (int in_flags, const itimerspec *value, itimerspec *ovalue) { @@ -366,8 +355,12 @@ timer_tracker::settime (int in_flags, const itimerspec *value, itimerspec *ovalu __leave; } - if (timespec_bad (value->it_value) || timespec_bad (value->it_interval)) - __leave; + if (!valid_timespec (value->it_value) + || !valid_timespec (value->it_interval)) + { + set_errno (EINVAL); + __leave; + } lock_timer_tracker here; cancel (); From 40481dbabb1cce2c33a67ccb5ddb368ee3491562 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Sat, 19 Jan 2019 19:53:48 +0100 Subject: [PATCH 112/475] Cygwin: timerfd: reimplement from scratch Using posix timers "timer_tracker" as base class for timerfd was flawed. Posix timers are not inherited by child processes and don't survive execve. The method used by posix timers didn't allow to share timers between processes. The timers were still per-process timers and worked entirely separate from each other. Reading from these timers via different descriptors was only synchronized within the same process. This does not reflect the timerfd semantics in Linux: The per-file timers can be dup'ed and survive fork and execve. They are still just descriptors pointing to the same timer object originally created by timerfd_create. Synchronization is performed between all descriptor instances of the same timer, system-wide. Thus, reimplement timerfd using a timer instance in shared memory, a kernel timer, and a handful of sync objects. Every process maintains a per-process timerfd struct on the cygheap maintaining a per-process thread. Every process sharing the same timerfd will run this thread checking the state of the timer, similar to the posix timer thread, just working on the shared objects and synchronizing its job with each other thread. Drop the timerfd implementation in the posix timer code and move the public API to fhandler_timerfd.c. Keep the ttstart timer_tracker anchor out of "NO_COPY" since the fixup_after_fork code should run to avoid memory leakage. Signed-off-by: Corinna Vinschen --- winsup/cygwin/Makefile.in | 1 + winsup/cygwin/fhandler.h | 2 + winsup/cygwin/fhandler_timerfd.cc | 193 +++++++++-- winsup/cygwin/timer.cc | 339 ++++---------------- winsup/cygwin/timer.h | 31 +- winsup/cygwin/timerfd.cc | 515 ++++++++++++++++++++++++++++++ winsup/cygwin/timerfd.h | 160 ++++++++++ 7 files changed, 909 insertions(+), 332 deletions(-) create mode 100644 winsup/cygwin/timerfd.cc create mode 100644 winsup/cygwin/timerfd.h diff --git a/winsup/cygwin/Makefile.in b/winsup/cygwin/Makefile.in index 8481851c0..374272f4c 100644 --- a/winsup/cygwin/Makefile.in +++ b/winsup/cygwin/Makefile.in @@ -396,6 +396,7 @@ DLL_OFILES:= \ termios.o \ thread.o \ timer.o \ + timerfd.o \ times.o \ tls_pbuf.o \ tty.o \ diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h index 497612ae1..97804ed30 100644 --- a/winsup/cygwin/fhandler.h +++ b/winsup/cygwin/fhandler.h @@ -2682,6 +2682,7 @@ class fhandler_timerfd : public fhandler_base public: fhandler_timerfd (); fhandler_timerfd (void *) {} + ~fhandler_timerfd (); fhandler_timerfd *is_timerfd () { return this; } @@ -2701,6 +2702,7 @@ class fhandler_timerfd : public fhandler_base HANDLE get_timerfd_handle (); + void fixup_after_fork (HANDLE); void fixup_after_exec (); select_record *select_read (select_stuff *); diff --git a/winsup/cygwin/fhandler_timerfd.cc b/winsup/cygwin/fhandler_timerfd.cc index c7ff9c162..8d3085692 100644 --- a/winsup/cygwin/fhandler_timerfd.cc +++ b/winsup/cygwin/fhandler_timerfd.cc @@ -1,4 +1,4 @@ -/* fhandler_timerfd.cc: fhandler for timerfd +/* fhandler_timerfd.cc: fhandler for timerfd, public timerfd API This file is part of Cygwin. @@ -12,7 +12,7 @@ details. */ #include "pinfo.h" #include "dtable.h" #include "cygheap.h" -#include "timer.h" +#include "timerfd.h" #include #include @@ -39,7 +39,19 @@ fhandler_timerfd::get_proc_fd_name (char *buf) int fhandler_timerfd::timerfd (clockid_t clock_id, int flags) { - timerid = (timer_t) cnew (timer_tracker, clock_id, NULL, true); + timerfd_tracker *tfd = cnew (timerfd_tracker); + if (!tfd) + { + set_errno (ENOMEM); + return -1; + } + int ret = tfd->create (clock_id); + if (ret < 0) + { + cfree (tfd); + set_errno (-ret); + return -1; + } if (flags & TFD_NONBLOCK) set_nonblocking (true); if (flags & TFD_CLOEXEC) @@ -48,19 +60,25 @@ fhandler_timerfd::timerfd (clockid_t clock_id, int flags) set_unique_id (); set_ino (get_unique_id ()); set_flags (O_RDWR | O_BINARY); + timerid = (timer_t) tfd; return 0; } int -fhandler_timerfd::settime (int flags, const itimerspec *value, - itimerspec *ovalue) +fhandler_timerfd::settime (int flags, const struct itimerspec *new_value, + struct itimerspec *old_value) { int ret = -1; __try { - timer_tracker *tt = (timer_tracker *) timerid; - ret = tt->settime (flags, value, ovalue); + timerfd_tracker *tfd = (timerfd_tracker *) timerid; + ret = tfd->settime (flags, new_value, old_value); + if (ret < 0) + { + set_errno (-ret); + ret = -1; + } } __except (EFAULT) {} __endtry @@ -68,15 +86,19 @@ fhandler_timerfd::settime (int flags, const itimerspec *value, } int -fhandler_timerfd::gettime (itimerspec *ovalue) +fhandler_timerfd::gettime (struct itimerspec *ovalue) { int ret = -1; __try { - timer_tracker *tt = (timer_tracker *) timerid; - tt->gettime (ovalue); - ret = 0; + timerfd_tracker *tfd = (timerfd_tracker *) timerid; + ret = tfd->gettime (ovalue); + if (ret < 0) + { + set_errno (-ret); + ret = -1; + } } __except (EFAULT) {} __endtry @@ -108,12 +130,14 @@ fhandler_timerfd::read (void *ptr, size_t& len) __try { - timer_tracker *tt = (timer_tracker *) timerid; - LONG64 ret = tt->wait (is_nonblocking ()); - if (ret == -1) - __leave; - PLONG64 pl64 = (PLONG64) ptr; - *pl64 = ret + 1; + timerfd_tracker *tfd = (timerfd_tracker *) timerid; + LONG64 ret = tfd->wait (is_nonblocking ()); + if (ret < 0) + { + set_errno (-ret); + __leave; + } + *(PLONG64) ptr = ret; len = sizeof (LONG64); return; } @@ -135,8 +159,8 @@ fhandler_timerfd::get_timerfd_handle () { __try { - timer_tracker *tt = (timer_tracker *) timerid; - return tt->get_timerfd_handle (); + timerfd_tracker *tfd = (timerfd_tracker *) timerid; + return tfd->get_timerfd_handle (); } __except (EFAULT) {} __endtry @@ -153,8 +177,8 @@ fhandler_timerfd::dup (fhandler_base *child, int flags) fhandler_timerfd *fhc = (fhandler_timerfd *) child; __try { - timer_tracker *tt = (timer_tracker *) fhc->timerid; - tt->increment_instances (); + timerfd_tracker *tfd = (timerfd_tracker *) fhc->timerid; + tfd->increment_instances (); ret = 0; } __except (EFAULT) {} @@ -164,14 +188,27 @@ fhandler_timerfd::dup (fhandler_base *child, int flags) } void -fhandler_timerfd::fixup_after_exec () +fhandler_timerfd::fixup_after_fork (HANDLE) { - if (close_on_exec ()) - return; __try { - timer_tracker *tt = (timer_tracker *) timerid; - tt->fixup_after_exec (); + timerfd_tracker *tfd = (timerfd_tracker *) timerid; + tfd->fixup_after_fork (); + } + __except (EFAULT) {} + __endtry +} + +void +fhandler_timerfd::fixup_after_exec () +{ + __try + { + timerfd_tracker *tfd = (timerfd_tracker *) timerid; + if (close_on_exec ()) + tfd->decrement_instances (); + else + tfd->fixup_after_exec (); } __except (EFAULT) {} __endtry @@ -188,7 +225,7 @@ fhandler_timerfd::ioctl (unsigned int cmd, void *p) case TFD_IOC_SET_TICKS: __try { - timer_tracker *tt = (timer_tracker *) timerid; + timerfd_tracker *tfd = (timerfd_tracker *) timerid; ov_cnt = *(uint64_t *) p; if (!ov_cnt) @@ -196,11 +233,11 @@ fhandler_timerfd::ioctl (unsigned int cmd, void *p) set_errno (EINVAL); break; } - tt->set_event (ov_cnt); + tfd->ioctl_set_ticks (ov_cnt); + ret = 0; } __except (EFAULT) {} __endtry - ret = 0; break; default: ret = fhandler_base::ioctl (cmd, p); @@ -210,6 +247,17 @@ fhandler_timerfd::ioctl (unsigned int cmd, void *p) return ret; } +fhandler_timerfd::~fhandler_timerfd () +{ + __try + { + timerfd_tracker *tfd = (timerfd_tracker *) timerid; + timerfd_tracker::dtor (tfd); + } + __except (EFAULT) {} + __endtry +} + int fhandler_timerfd::close () { @@ -217,11 +265,94 @@ fhandler_timerfd::close () __try { - timer_tracker *tt = (timer_tracker *) timerid; - timer_tracker::close (tt); + timerfd_tracker *tfd = (timerfd_tracker *) timerid; + tfd->close (); ret = 0; } __except (EFAULT) {} __endtry return ret; } + +extern "C" int +timerfd_create (clockid_t clock_id, int flags) +{ + int ret = -1; + fhandler_timerfd *fh; + + debug_printf ("timerfd_create (%lu, %y)", clock_id, flags); + + if (clock_id != CLOCK_REALTIME + && clock_id != CLOCK_MONOTONIC + && clock_id != CLOCK_BOOTTIME) + { + set_errno (EINVAL); + goto done; + } + if ((flags & ~(TFD_NONBLOCK | TFD_CLOEXEC)) != 0) + { + set_errno (EINVAL); + goto done; + } + + { + /* Create new timerfd descriptor. */ + cygheap_fdnew fd; + + if (fd < 0) + goto done; + fh = (fhandler_timerfd *) build_fh_dev (*timerfd_dev); + if (fh && fh->timerfd (clock_id, flags) == 0) + { + fd = fh; + if (fd <= 2) + set_std_handle (fd); + ret = fd; + } + else + delete fh; + } + +done: + syscall_printf ("%R = timerfd_create (%lu, %y)", ret, clock_id, flags); + return ret; +} + +extern "C" int +timerfd_settime (int fd_in, int flags, const struct itimerspec *value, + struct itimerspec *ovalue) +{ + /* TODO: There's no easy way to implement TFD_TIMER_CANCEL_ON_SET, + but we should at least accept the flag. */ + if ((flags & ~(TFD_TIMER_ABSTIME | TFD_TIMER_CANCEL_ON_SET)) != 0) + { + set_errno (EINVAL); + return -1; + } + + cygheap_fdget fd (fd_in); + if (fd < 0) + return -1; + fhandler_timerfd *fh = fd->is_timerfd (); + if (!fh) + { + set_errno (EINVAL); + return -1; + } + return fh->settime (flags, value, ovalue); +} + +extern "C" int +timerfd_gettime (int fd_in, struct itimerspec *ovalue) +{ + cygheap_fdget fd (fd_in); + if (fd < 0) + return -1; + fhandler_timerfd *fh = fd->is_timerfd (); + if (!fh) + { + set_errno (EINVAL); + return -1; + } + return fh->gettime (ovalue); +} diff --git a/winsup/cygwin/timer.cc b/winsup/cygwin/timer.cc index e817dab81..e24edd5e9 100644 --- a/winsup/cygwin/timer.cc +++ b/winsup/cygwin/timer.cc @@ -15,15 +15,14 @@ details. */ #include "dtable.h" #include "cygheap.h" #include "timer.h" -#include #include #define EVENT_DISARMED 0 #define EVENT_ARMED -1 #define EVENT_LOCK 1 -/* Must not be NO_COPY, otherwise timerfd breaks. */ -timer_tracker ttstart (CLOCK_REALTIME, NULL, false); +/* Must not be NO_COPY to avoid memory leak after fork. */ +timer_tracker ttstart (CLOCK_REALTIME, NULL); class lock_timer_tracker { @@ -60,46 +59,34 @@ timer_tracker::cancel () timer_tracker::~timer_tracker () { - HANDLE hdl; - - deleting = true; if (cancel ()) { - HANDLE hdl = InterlockedExchangePointer (&hcancel, NULL); - CloseHandle (hdl); - hdl = InterlockedExchangePointer (&timerfd_event, NULL); - if (hdl) - CloseHandle (hdl); + CloseHandle (hcancel); +#ifdef DEBUGGING + hcancel = NULL; +#endif } - hdl = InterlockedExchangePointer (&syncthread, NULL); - if (hdl) - CloseHandle (hdl); + if (syncthread) + CloseHandle (syncthread); magic = 0; } -/* fd is true for timerfd timers. */ -timer_tracker::timer_tracker (clockid_t c, const sigevent *e, bool fd) -: magic (TT_MAGIC), instance_count (1), clock_id (c), deleting (false), - hcancel (NULL), syncthread (NULL), timerfd_event (NULL), - interval_us(0), sleepto_us(0), event_running (EVENT_DISARMED), - overrun_count_curr (0), overrun_count (0) +timer_tracker::timer_tracker (clockid_t c, const sigevent *e) { if (e != NULL) evp = *e; - else if (fd) - { - evp.sigev_notify = SIGEV_NONE; - evp.sigev_signo = 0; - evp.sigev_value.sival_ptr = this; - } else { evp.sigev_notify = SIGEV_SIGNAL; evp.sigev_signo = SIGALRM; evp.sigev_value.sival_ptr = this; } - if (fd) - timerfd_event = CreateEvent (&sec_none_nih, TRUE, FALSE, NULL); + clock_id = c; + magic = TT_MAGIC; + hcancel = NULL; + event_running = EVENT_DISARMED; + overrun_count_curr = 0; + overrun_count = 0; if (this != &ttstart) { lock_timer_tracker here; @@ -132,24 +119,8 @@ timer_tracker::arm_event () return ret; } -void -timer_tracker::set_event (uint64_t ov_cnt) -{ - LONG ret; - - while ((ret = InterlockedCompareExchange (&event_running, EVENT_LOCK, - EVENT_DISARMED)) == EVENT_LOCK) - yield (); - InterlockedExchange64 (&overrun_count, ov_cnt); - if (ret == EVENT_DISARMED) - { - SetEvent (get_timerfd_handle ()); - InterlockedExchange (&event_running, EVENT_ARMED); - } -} - -LONG64 -timer_tracker::_disarm_event () +LONG +timer_tracker::disarm_event () { LONG ret; @@ -158,7 +129,13 @@ timer_tracker::_disarm_event () yield (); if (ret == EVENT_ARMED) { - InterlockedExchange64 (&overrun_count_curr, overrun_count); + LONG64 ov_cnt; + + InterlockedExchange64 (&ov_cnt, overrun_count); + if (ov_cnt > DELAYTIMER_MAX || ov_cnt < 0) + overrun_count_curr = DELAYTIMER_MAX; + else + overrun_count_curr = ov_cnt; ret = overrun_count_curr; InterlockedExchange64 (&overrun_count, 0); InterlockedExchange (&event_running, EVENT_DISARMED); @@ -166,51 +143,6 @@ timer_tracker::_disarm_event () return ret; } -unsigned int -timer_tracker::disarm_event () -{ - LONG64 ov = _disarm_event (); - if (ov > DELAYTIMER_MAX || ov < 0) - return DELAYTIMER_MAX; - return (unsigned int) ov; -} - -LONG64 -timer_tracker::wait (bool nonblocking) -{ - HANDLE w4[3] = { NULL, hcancel, get_timerfd_handle () }; - LONG64 ret = -1; - - wait_signal_arrived here (w4[0]); -repeat: - switch (WaitForMultipleObjects (3, w4, FALSE, nonblocking ? 0 : INFINITE)) - { - case WAIT_OBJECT_0: /* signal */ - if (_my_tls.call_signal_handler ()) - goto repeat; - set_errno (EINTR); - break; - case WAIT_OBJECT_0 + 1: /* settime oder timer delete */ - if (deleting) - { - set_errno (EIO); - break; - } - /*FALLTHRU*/ - case WAIT_OBJECT_0 + 2: /* timer event */ - ret = _disarm_event (); - ResetEvent (timerfd_event); - break; - case WAIT_TIMEOUT: - set_errno (EAGAIN); - break; - default: - __seterrno (); - break; - } - return ret; -} - static void * notify_thread_wrapper (void *arg) { @@ -267,18 +199,6 @@ timer_tracker::thread_func () switch (evp.sigev_notify) { - case SIGEV_NONE: - { - if (!timerfd_event) - break; - if (arm_event ()) - { - debug_printf ("%p timerfd already queued", this); - break; - } - SetEvent (timerfd_event); - break; - } case SIGEV_SIGNAL: { if (arm_event ()) @@ -342,6 +262,17 @@ timer_thread (VOID *x) return tt->thread_func (); } +static inline bool +timespec_bad (const timespec& t) +{ + if (t.tv_nsec < 0 || t.tv_nsec >= NSPERSEC || t.tv_sec < 0) + { + set_errno (EINVAL); + return true; + } + return false; +} + int timer_tracker::settime (int in_flags, const itimerspec *value, itimerspec *ovalue) { @@ -355,12 +286,8 @@ timer_tracker::settime (int in_flags, const itimerspec *value, itimerspec *ovalu __leave; } - if (!valid_timespec (value->it_value) - || !valid_timespec (value->it_interval)) - { - set_errno (EINVAL); - __leave; - } + if (timespec_bad (value->it_value) || timespec_bad (value->it_interval)) + __leave; lock_timer_tracker here; cancel (); @@ -411,17 +338,9 @@ timer_tracker::gettime (itimerspec *ovalue) } } -/* Returns - - 1 if we still have to keep the timer around - 0 if we can delete the timer - -1 if we can't find the timer in the list -*/ int timer_tracker::clean_and_unhook () { - if (decrement_instances () > 0) - return 1; for (timer_tracker *tt = &ttstart; tt->next != NULL; tt = tt->next) if (tt->next == this) { @@ -431,74 +350,19 @@ timer_tracker::clean_and_unhook () return -1; } -int -timer_tracker::close (timer_tracker *tt) -{ - lock_timer_tracker here; - int ret = tt->clean_and_unhook (); - if (ret >= 0) - { - if (ret == 0) - delete tt; - ret = 0; - } - else - set_errno (EINVAL); - return ret; -} - -void -timer_tracker::restart () -{ - timerfd_event = CreateEvent (&sec_none_nih, TRUE, FALSE, NULL); - if (interval_us != 0 || sleepto_us != 0) - { - hcancel = CreateEvent (&sec_none_nih, TRUE, FALSE, NULL); - syncthread = CreateEvent (&sec_none_nih, TRUE, FALSE, NULL); - new cygthread (timer_thread, this, "itimer", syncthread); - } -} - -/* Only called from fhandler_timerfd::fixup_after_exec. Note that - we don't touch the instance count. This is handled by closing - the timer from fhandler_timerfd::close on O_CLOEXEC. Ultimately - the instance count should be correct after execve. */ -void -timer_tracker::fixup_after_exec () -{ - lock_timer_tracker here; - /* Check if timer is already in the list. If so, skip it. */ - for (timer_tracker *tt = &ttstart; tt->next != NULL; tt = tt->next) - if (tt->next == this) - return; - next = ttstart.next; - ttstart.next = this; - restart (); -} - void timer_tracker::fixup_after_fork () { ttstart.hcancel = ttstart.syncthread = NULL; - ttstart.interval_us = ttstart.sleepto_us = 0; ttstart.event_running = EVENT_DISARMED; - ttstart.overrun_count_curr = ttstart.overrun_count = 0; + ttstart.overrun_count_curr = 0; + ttstart.overrun_count = 0; for (timer_tracker *tt = &ttstart; tt->next != NULL; /* nothing */) { timer_tracker *deleteme = tt->next; - if (deleteme->get_timerfd_handle ()) - { - tt = deleteme; - tt->restart (); - } - else - { - tt->next = deleteme->next; - deleteme->timerfd_event = NULL; - deleteme->hcancel = NULL; - deleteme->syncthread = NULL; - delete deleteme; - } + tt->next = deleteme->next; + deleteme->hcancel = deleteme->syncthread = NULL; + delete deleteme; } } @@ -536,21 +400,21 @@ timer_create (clockid_t clock_id, struct sigevent *__restrict evp, { int ret = -1; - if (CLOCKID_IS_PROCESS (clock_id) || CLOCKID_IS_THREAD (clock_id)) - { - set_errno (ENOTSUP); - return -1; - } - - if (clock_id >= MAX_CLOCKS) - { - set_errno (EINVAL); - return -1; - } - __try { - *timerid = (timer_t) new timer_tracker (clock_id, evp, false); + if (CLOCKID_IS_PROCESS (clock_id) || CLOCKID_IS_THREAD (clock_id)) + { + set_errno (ENOTSUP); + return -1; + } + + if (clock_id >= MAX_CLOCKS) + { + set_errno (EINVAL); + return -1; + } + + *timerid = (timer_t) new timer_tracker (clock_id, evp); ret = 0; } __except (EFAULT) {} @@ -617,7 +481,15 @@ timer_delete (timer_t timerid) set_errno (EINVAL); __leave; } - ret = timer_tracker::close (in_tt); + + lock_timer_tracker here; + if (in_tt->clean_and_unhook () == 0) + { + delete in_tt; + ret = 0; + } + else + set_errno (EINVAL); } __except (EFAULT) {} __endtry @@ -724,86 +596,3 @@ ualarm (useconds_t value, useconds_t interval) syscall_printf ("%d = ualarm(%ld , %ld)", ret, value, interval); return ret; } - -extern "C" int -timerfd_create (clockid_t clock_id, int flags) -{ - int ret = -1; - fhandler_timerfd *fh; - - debug_printf ("timerfd (%lu, %y)", clock_id, flags); - - if (clock_id != CLOCK_REALTIME - && clock_id != CLOCK_MONOTONIC - && clock_id != CLOCK_BOOTTIME) - { - set_errno (EINVAL); - return -1; - } - if ((flags & ~(TFD_NONBLOCK | TFD_CLOEXEC)) != 0) - { - set_errno (EINVAL); - goto done; - } - - { - /* Create new timerfd descriptor. */ - cygheap_fdnew fd; - - if (fd < 0) - goto done; - fh = (fhandler_timerfd *) build_fh_dev (*timerfd_dev); - if (fh && fh->timerfd (clock_id, flags) == 0) - { - fd = fh; - if (fd <= 2) - set_std_handle (fd); - ret = fd; - } - else - delete fh; - } - -done: - syscall_printf ("%R = timerfd (%lu, %y)", ret, clock_id, flags); - return ret; -} - -extern "C" int -timerfd_settime (int fd_in, int flags, const struct itimerspec *value, - struct itimerspec *ovalue) -{ - /* There's no easy way to implement TFD_TIMER_CANCEL_ON_SET, but - we should at least accept the flag. */ - if ((flags & ~(TFD_TIMER_ABSTIME | TFD_TIMER_CANCEL_ON_SET)) != 0) - { - set_errno (EINVAL); - return -1; - } - - cygheap_fdget fd (fd_in); - if (fd < 0) - return -1; - fhandler_timerfd *fh = fd->is_timerfd (); - if (!fh) - { - set_errno (EINVAL); - return -1; - } - return fh->settime (flags, value, ovalue); -} - -extern "C" int -timerfd_gettime (int fd_in, struct itimerspec *ovalue) -{ - cygheap_fdget fd (fd_in); - if (fd < 0) - return -1; - fhandler_timerfd *fh = fd->is_timerfd (); - if (!fh) - { - set_errno (EINVAL); - return -1; - } - return fh->gettime (ovalue); -} diff --git a/winsup/cygwin/timer.h b/winsup/cygwin/timer.h index b9a072e6d..dd5b165c7 100644 --- a/winsup/cygwin/timer.h +++ b/winsup/cygwin/timer.h @@ -14,56 +14,35 @@ class timer_tracker { unsigned magic; timer_tracker *next; - LONG instance_count; clockid_t clock_id; sigevent evp; timespec it_interval; - bool deleting; HANDLE hcancel; HANDLE syncthread; - HANDLE timerfd_event; int64_t interval_us; int64_t sleepto_us; LONG event_running; - LONG64 overrun_count_curr; + LONG overrun_count_curr; LONG64 overrun_count; bool cancel (); - LONG decrement_instances () { return InterlockedDecrement (&instance_count); } - int clean_and_unhook (); - LONG64 _disarm_event (); - void restart (); public: - void *operator new (size_t size) __attribute__ ((nothrow)) - { return malloc (size); } - void *operator new (size_t, void *p) __attribute__ ((nothrow)) {return p;} - void operator delete(void *p) { incygheap (p) ? cfree (p) : free (p); } - - timer_tracker (clockid_t, const sigevent *, bool); + timer_tracker (clockid_t, const sigevent *); ~timer_tracker (); inline bool is_timer_tracker () const { return magic == TT_MAGIC; } - - - void increment_instances () { InterlockedIncrement (&instance_count); } - LONG64 wait (bool nonblocking); - HANDLE get_timerfd_handle () const { return timerfd_event; } - inline sigevent_t *sigevt () { return &evp; } - inline LONG64 getoverrun () const { return overrun_count_curr; } + inline int getoverrun () const { return overrun_count_curr; } void gettime (itimerspec *); int settime (int, const itimerspec *, itimerspec *); - + int clean_and_unhook (); LONG arm_event (); - void set_event (uint64_t ov_cnt); - unsigned int disarm_event (); + LONG disarm_event (); DWORD thread_func (); - void fixup_after_exec (); static void fixup_after_fork (); - static int close (timer_tracker *tt); }; extern void fixup_timers_after_fork (); diff --git a/winsup/cygwin/timerfd.cc b/winsup/cygwin/timerfd.cc new file mode 100644 index 000000000..145f3a665 --- /dev/null +++ b/winsup/cygwin/timerfd.cc @@ -0,0 +1,515 @@ +/* timerfd.cc: timerfd helper classes + +This file is part of Cygwin. + +This software is a copyrighted work licensed under the terms of the +Cygwin license. Please consult the file "CYGWIN_LICENSE" for +details. */ + +#include "winsup.h" +#include "path.h" +#include "fhandler.h" +#include "pinfo.h" +#include "dtable.h" +#include "cygheap.h" +#include "cygerrno.h" +#include +#include "timerfd.h" + +DWORD +timerfd_tracker::thread_func () +{ + /* Outer loop: Is the timer armed? If not, wait for it. */ + HANDLE armed[2] = { tfd_shared->arm_evt (), + cancel_evt }; + + while (1) + { + switch (WaitForMultipleObjects (2, armed, FALSE, INFINITE)) + { + case WAIT_OBJECT_0: + break; + case WAIT_OBJECT_0 + 1: + goto canceled; + default: + continue; + } + + /* Inner loop: Timer expired? If not, wait for it. */ + HANDLE expired[3] = { tfd_shared->timer (), + tfd_shared->disarm_evt (), + cancel_evt }; + while (1) + { + switch (WaitForMultipleObjects (3, expired, FALSE, INFINITE)) + { + case WAIT_OBJECT_0: + break; + case WAIT_OBJECT_0 + 1: + goto disarmed; + case WAIT_OBJECT_0 + 2: + goto canceled; + default: + continue; + } + + if (!enter_critical_section ()) + continue; + /* One-shot timer? */ + if (!get_interval ()) + { + /* Set overrun count, disarm timer */ + increment_overrun_count (1); + disarm_timer (); + } + else + { + /* Compute overrun count. */ + LONG64 now = get_clock_now (); + LONG64 ts = get_exp_ts (); + + increment_overrun_count ((now - ts + get_interval () - 1) + / get_interval ()); + /* Set exp_ts to current timestamp. Make sure exp_ts ends up + bigger than "now" and fix overrun count as required */ + while ((ts += get_interval ()) <= (now = get_clock_now ())) + increment_overrun_count ((now - ts + get_interval () - 1) + / get_interval ()); + set_exp_ts (ts); + /* NtSetTimer allows periods of up to 24 days only. If the time + is longer, we set the timer up as one-shot timer for each + interval. Restart timer here with new due time. */ + if (get_interval () > INT_MAX * (NS100PERSEC / MSPERSEC)) + { + /* TODO: CLOCK_REALTIME_ALARM / CLOCK_BOOTTIME_ALARM + See comment in arm_timer */ + BOOL Resume = FALSE; + LARGE_INTEGER DueTime = { QuadPart: -get_interval () }; + + NtSetTimer (tfd_shared->timer (), &DueTime, NULL, NULL, + Resume, 0, NULL); + } + } + /* Arm the expiry object */ + timer_expired (); + leave_critical_section (); + } +disarmed: + ; + } + +canceled: + _my_tls._ctinfo->auto_release (); /* automatically return the cygthread to the cygthread pool */ + return 0; +} + +static DWORD WINAPI +timerfd_thread (VOID *arg) +{ + timerfd_tracker *tt = ((timerfd_tracker *) arg); + return tt->thread_func (); +} + +int +timerfd_shared::create (clockid_t clock_id) +{ + int ret; + NTSTATUS status; + OBJECT_ATTRIBUTES attr; + + /* Create access mutex */ + InitializeObjectAttributes (&attr, NULL, OBJ_INHERIT, NULL, + sec_none.lpSecurityDescriptor); + status = NtCreateMutant (&_access_mtx, MUTEX_ALL_ACCESS, &attr, FALSE); + if (!NT_SUCCESS (status)) + { + ret = -geterrno_from_nt_status (status); + goto err; + } + /* Create "timer is armed" event, set to "Unsignaled" at creation time */ + status = NtCreateEvent (&_arm_evt, EVENT_ALL_ACCESS, &attr, + NotificationEvent, FALSE); + if (!NT_SUCCESS (status)) + { + ret = -geterrno_from_nt_status (status); + goto err_close_access_mtx; + } + /* Create "timer is disarmed" event, set to "Signaled" at creation time */ + status = NtCreateEvent (&_disarm_evt, EVENT_ALL_ACCESS, &attr, + NotificationEvent, TRUE); + if (!NT_SUCCESS (status)) + { + ret = -geterrno_from_nt_status (status); + goto err_close_arm_evt; + } + /* Create timer */ + status = NtCreateTimer (&_timer, TIMER_ALL_ACCESS, &attr, + SynchronizationTimer); + if (!NT_SUCCESS (status)) + { + ret = -geterrno_from_nt_status (status); + goto err_close_disarm_evt; + } + /* Create "timer expired" semaphore */ + status = NtCreateEvent (&_expired_evt, EVENT_ALL_ACCESS, &attr, + NotificationEvent, FALSE); + if (!NT_SUCCESS (status)) + { + ret = -geterrno_from_nt_status (status); + goto err_close_timer; + } + instance_count = 1; + _clockid = clock_id; + return 0; + +err_close_timer: + NtClose (_timer); +err_close_disarm_evt: + NtClose (_disarm_evt); +err_close_arm_evt: + NtClose (_arm_evt); +err_close_access_mtx: + NtClose (_access_mtx); +err: + return ret; +} + +int +timerfd_tracker::create (clockid_t clock_id) +{ + int ret; + clk_t *clock; + NTSTATUS status; + OBJECT_ATTRIBUTES attr; + + const ACCESS_MASK access = STANDARD_RIGHTS_REQUIRED + | SECTION_MAP_READ | SECTION_MAP_WRITE; + SIZE_T vsize = PAGE_SIZE; + LARGE_INTEGER sectionsize = { QuadPart: PAGE_SIZE }; + + /* Valid clock? */ + clock = get_clock (clock_id); + if (!clock) + { + ret = -EINVAL; + goto err; + } + /* Create shared section. */ + InitializeObjectAttributes (&attr, NULL, OBJ_INHERIT, NULL, + sec_none.lpSecurityDescriptor); + status = NtCreateSection (&tfd_shared_hdl, access, &attr, + §ionsize, PAGE_READWRITE, + SEC_COMMIT, NULL); + if (!NT_SUCCESS (status)) + { + ret = -geterrno_from_nt_status (status); + goto err; + } + /* Create section mapping (has to be repeated after fork/exec */ + status = NtMapViewOfSection (tfd_shared_hdl, NtCurrentProcess (), + (void **) &tfd_shared, 0, PAGE_SIZE, NULL, + &vsize, ViewShare, MEM_TOP_DOWN, PAGE_READWRITE); + if (!NT_SUCCESS (status)) + { + ret = -geterrno_from_nt_status (status); + goto err_close_tfd_shared_hdl; + } + /* Create cancel even for this processes timer thread */ + InitializeObjectAttributes (&attr, NULL, 0, NULL, + sec_none_nih.lpSecurityDescriptor); + status = NtCreateEvent (&cancel_evt, EVENT_ALL_ACCESS, &attr, + NotificationEvent, FALSE); + if (!NT_SUCCESS (status)) + { + ret = -geterrno_from_nt_status (status); + goto err_unmap_tfd_shared; + } + ret = tfd_shared->create (clock_id); + if (ret < 0) + goto err_close_cancel_evt; + winpid = GetCurrentProcessId (); + new cygthread (timerfd_thread, this, "timerfd", sync_thr); + return 0; + +err_close_cancel_evt: + NtClose (cancel_evt); +err_unmap_tfd_shared: + NtUnmapViewOfSection (NtCurrentProcess (), tfd_shared); +err_close_tfd_shared_hdl: + NtClose (tfd_shared_hdl); +err: + return ret; +} + +/* Return true if this was the last instance of a timerfd, session-wide, + false otherwise */ +bool +timerfd_shared::dtor () +{ + if (instance_count > 0) + { + return false; + } + timer_expired (); + disarm_timer (); + NtClose (_timer); + NtClose (_arm_evt); + NtClose (_disarm_evt); + NtClose (_expired_evt); + NtClose (_access_mtx); + return true; +} + +/* Return true if this was the last instance of a timerfd, session-wide, + false otherwise. Basically this is a destructor, but one which may + notify the caller NOT to deleted the object. */ +bool +timerfd_tracker::dtor () +{ + if (enter_critical_section ()) + { + if (local_instance_count > 0) + { + leave_critical_section (); + return false; + } + SetEvent (cancel_evt); + WaitForSingleObject (sync_thr, INFINITE); + if (tfd_shared->dtor ()) + { + NtUnmapViewOfSection (NtCurrentProcess (), tfd_shared); + NtClose (tfd_shared_hdl); + } + else + leave_critical_section (); + } + NtClose (cancel_evt); + NtClose (sync_thr); + return true; +} + +void +timerfd_tracker::dtor (timerfd_tracker *tfd) +{ + if (tfd->dtor ()) + cfree (tfd); +} + +void +timerfd_tracker::close () +{ + InterlockedDecrement (&local_instance_count); + InterlockedDecrement (&tfd_shared->instance_count); +} + +void +timerfd_tracker::ioctl_set_ticks (uint64_t ov_cnt) +{ + set_overrun_count (ov_cnt); + timer_expired (); +} + +void +timerfd_tracker::fixup_after_fork_exec (bool execing) +{ + NTSTATUS status; + OBJECT_ATTRIBUTES attr; + SIZE_T vsize = PAGE_SIZE; + + /* Run this only once per process */ + if (winpid == GetCurrentProcessId ()) + return; + /* Recreate shared section mapping */ + status = NtMapViewOfSection (tfd_shared_hdl, NtCurrentProcess (), + (void **) &tfd_shared, 0, PAGE_SIZE, NULL, + &vsize, ViewShare, MEM_TOP_DOWN, PAGE_READWRITE); + if (!NT_SUCCESS (status)) + api_fatal ("Can't recreate shared timerfd section during %s!", + execing ? "execve" : "fork"); + /* Increment global instance count by the number of instances in this + process */ + InterlockedAdd (&tfd_shared->instance_count, local_instance_count); + /* Create cancel even for this processes timer thread */ + InitializeObjectAttributes (&attr, NULL, 0, NULL, + sec_none_nih.lpSecurityDescriptor); + status = NtCreateEvent (&cancel_evt, EVENT_ALL_ACCESS, &attr, + NotificationEvent, FALSE); + if (!NT_SUCCESS (status)) + api_fatal ("Can't recreate timerfd cancel event during %s!", + execing ? "execve" : "fork"); + /* Set winpid so we don't run this twice */ + winpid = GetCurrentProcessId (); + new cygthread (timerfd_thread, this, "timerfd", sync_thr); +} + +LONG64 +timerfd_tracker::wait (bool nonblocking) +{ + HANDLE w4[2] = { get_timerfd_handle (), NULL }; + LONG64 ret; + + wait_signal_arrived here (w4[1]); +repeat: + switch (WaitForMultipleObjects (2, w4, FALSE, nonblocking ? 0 : INFINITE)) + { + case WAIT_OBJECT_0: /* timer event */ + if (!enter_critical_section ()) + ret = -EIO; + else + { + ret = read_and_reset_overrun_count (); + leave_critical_section (); + if (ret) + break; + /* A 0 overrun count indicates another read was quicker. + Continue as if we didn't catch the expiry. */ + if (!nonblocking) + { + Sleep (100L); + goto repeat; + } + ret = -EAGAIN; + } + break; + case WAIT_OBJECT_0 + 1: /* signal */ + if (_my_tls.call_signal_handler ()) + goto repeat; + ret = -EINTR; + break; + case WAIT_TIMEOUT: + ret = -EAGAIN; + break; + default: + ret = -geterrno_from_win_error (); + break; + } + return ret; +} + +int +timerfd_tracker::gettime (struct itimerspec *curr_value) +{ + int ret = 0; + + __try + { + if (!enter_critical_section ()) + { + ret = -EBADF; + __leave; + } + LONG64 next_relative_exp = get_exp_ts () - get_clock_now (); + curr_value->it_value.tv_sec = next_relative_exp / NS100PERSEC; + next_relative_exp -= curr_value->it_value.tv_sec * NS100PERSEC; + curr_value->it_value.tv_nsec = next_relative_exp + * (NSPERSEC / NS100PERSEC); + leave_critical_section (); + ret = 0; + } + __except (NO_ERROR) + { + ret = -EFAULT; + } + __endtry + return ret; +} + +int +timerfd_shared::arm_timer (int flags, const struct itimerspec *new_value) +{ + LONG64 ts; + NTSTATUS status; + LARGE_INTEGER DueTime; + BOOLEAN Resume; + LONG Period; + + ResetEvent (_disarm_evt); + + /* Convert incoming itimerspec into 100ns interval and timestamp */ + _interval = new_value->it_interval.tv_sec * NS100PERSEC + + (new_value->it_interval.tv_nsec + (NSPERSEC / NS100PERSEC) - 1) + / (NSPERSEC / NS100PERSEC); + ts = new_value->it_value.tv_sec * NS100PERSEC + + (new_value->it_value.tv_nsec + (NSPERSEC / NS100PERSEC) - 1) + / (NSPERSEC / NS100PERSEC); + _flags = flags; + if (flags & TFD_TIMER_ABSTIME) + { + if (_clockid == CLOCK_REALTIME) + DueTime.QuadPart = ts + FACTOR; + else /* non-REALTIME clocks require relative DueTime. */ + { + DueTime.QuadPart = ts - get_clock_now (); + /* If the timestamp was earlier than now, compute number + of overruns and offset DueTime to expire immediately. */ + if (DueTime.QuadPart >= 0) + { + LONG64 num_intervals = DueTime.QuadPart / _interval; + increment_overrun_count (num_intervals); + DueTime.QuadPart = -1LL; + } + } + } + else + { + /* Keep relative timestamps relative for the timer, but store the + expiry timestamp absolute for the timer thread. */ + DueTime.QuadPart = -ts; + ts += get_clock_now (); + } + set_exp_ts (ts); + /* TODO: CLOCK_REALTIME_ALARM / CLOCK_BOOTTIME_ALARM + Note: Advanced Power Settings -> Sleep -> Allow Wake Timers + since W10 1709 */ + Resume = FALSE; + if (_interval > INT_MAX * (NS100PERSEC / MSPERSEC)) + Period = 0; + else + Period = (_interval + (NS100PERSEC / MSPERSEC) - 1) + / (NS100PERSEC / MSPERSEC); + status = NtSetTimer (timer (), &DueTime, NULL, NULL, Resume, Period, NULL); + if (!NT_SUCCESS (status)) + { + disarm_timer (); + return -geterrno_from_nt_status (status); + } + + SetEvent (_arm_evt); + return 0; +} + +int +timerfd_tracker::settime (int flags, const struct itimerspec *new_value, + struct itimerspec *old_value) +{ + int ret = 0; + + __try + { + if (!valid_timespec (new_value->it_value) + || !valid_timespec (new_value->it_interval)) + { + ret = -EINVAL; + __leave; + } + if (!enter_critical_section ()) + { + ret = -EBADF; + __leave; + } + if (old_value) + gettime (old_value); + if (new_value->it_value.tv_sec == 0 && new_value->it_value.tv_nsec == 0) + ret = disarm_timer (); + else + ret = arm_timer (flags, new_value); + leave_critical_section (); + ret = 0; + } + __except (NO_ERROR) + { + ret = -EFAULT; + } + __endtry + return ret; +} diff --git a/winsup/cygwin/timerfd.h b/winsup/cygwin/timerfd.h new file mode 100644 index 000000000..6c42d91f4 --- /dev/null +++ b/winsup/cygwin/timerfd.h @@ -0,0 +1,160 @@ +/* timerfd.h: Define timerfd classes + +This file is part of Cygwin. + +This software is a copyrighted work licensed under the terms of the +Cygwin license. Please consult the file "CYGWIN_LICENSE" for +details. */ + +#ifndef __TIMERFD_H__ +#define __TIMERFD_H__ + +#include "clock.h" +#include "ntdll.h" + +class timerfd_shared +{ + HANDLE _access_mtx; /* controls access to shared data */ + HANDLE _arm_evt; /* settimer sets event when timer is armed, + unsets event when timer gets disarmed. */ + HANDLE _disarm_evt; /* settimer sets event when timer is armed, + unsets event when timer gets disarmed. */ + HANDLE _timer; /* SynchronizationTimer */ + HANDLE _expired_evt; /* Signal if timer expired, Unsignal on read. */ + LONG instance_count; /* each open fd increments this. + If 0 -> delete timerfd_shared */ + + clockid_t _clockid; /* clockid */ + struct itimerspec _time_spec; /* original incoming itimerspec */ + LARGE_INTEGER _exp_ts; /* start timestamp or next expire timestamp + in 100ns */ + LONG64 _interval; /* timer interval in 100ns */ + LONG64 _overrun_count; /* expiry counter */ + int _flags; /* settime flags */ + + int create (clockid_t); + bool dtor (); + + /* read access methods */ + HANDLE arm_evt () const { return _arm_evt; } + HANDLE disarm_evt () const { return _disarm_evt; } + HANDLE timer () const { return _timer; } + HANDLE expired_evt () const { return _expired_evt; } + LONG64 get_clock_now () const { return get_clock (_clockid)->n100secs (); } + struct itimerspec &time_spec () { return _time_spec; } + int flags () const { return _flags; } + LONG64 overrun_count () const { return _overrun_count; } + void increment_overrun_count (LONG64 add) + { InterlockedAdd64 (&_overrun_count, add); } + void set_overrun_count (LONG64 newval) + { InterlockedExchange64 (&_overrun_count, newval); } + LONG64 read_and_reset_overrun_count () + { + LONG64 ret = InterlockedExchange64 (&_overrun_count, 0); + if (ret) + ResetEvent (_expired_evt); + return ret; + } + + /* write access methods */ + bool enter_cs () + { + return WaitForSingleObject (_access_mtx, INFINITE) == WAIT_OBJECT_0; + } + void leave_cs () + { + ReleaseMutex (_access_mtx); + } + int arm_timer (int, const struct itimerspec *); + int disarm_timer () + { + ResetEvent (_arm_evt); + memset (&_time_spec, 0, sizeof _time_spec); + _exp_ts.QuadPart = 0; + _interval = 0; + _flags = 0; + NtCancelTimer (timer (), NULL); + SetEvent (_disarm_evt); + return 0; + } + void timer_expired () { SetEvent (_expired_evt); } + void set_exp_ts (LONG64 ts) { _exp_ts.QuadPart = ts; } + + friend class timerfd_tracker; +}; + +class timerfd_tracker /* cygheap! */ +{ + DWORD winpid; /* This is used @ fork/exec time to know if + this tracker already has been fixed up. */ + HANDLE tfd_shared_hdl; /* handle auf shared mem */ + timerfd_shared *tfd_shared; /* pointer auf shared mem, needs + NtMapViewOfSection in each new process. */ + + HANDLE cancel_evt; /* Signal thread to exit. */ + HANDLE sync_thr; /* cygthread sync object. */ + LONG local_instance_count; /* each open fd increments this. + If 0 -> cancel thread. */ + + bool dtor (); + + bool enter_critical_section () const { return tfd_shared->enter_cs (); } + void leave_critical_section () const { tfd_shared->leave_cs (); } + + int arm_timer (int flags, const struct itimerspec *new_value) const + { return tfd_shared->arm_timer (flags, new_value); } + int disarm_timer () const { return tfd_shared->disarm_timer (); } + void timer_expired () const { tfd_shared->timer_expired (); } + + void increment_overrun_count (LONG64 add) const + { tfd_shared->increment_overrun_count (add); } + void set_overrun_count (uint64_t ov_cnt) const + { tfd_shared->set_overrun_count ((LONG64) ov_cnt); } + LONG64 read_and_reset_overrun_count () const + { return tfd_shared->read_and_reset_overrun_count (); } + + struct timespec it_value () const + { return tfd_shared->time_spec ().it_value; } + struct timespec it_interval () const + { return tfd_shared->time_spec ().it_interval; } + + LONG64 get_clock_now () const { return tfd_shared->get_clock_now (); } + LONG64 get_exp_ts () const { return tfd_shared->_exp_ts.QuadPart; } + LONG64 get_interval () const { return tfd_shared->_interval; } + + void set_exp_ts (LONG64 ts) const { tfd_shared->set_exp_ts (ts); } + + public: + void *operator new (size_t, void *p) __attribute__ ((nothrow)) {return p;} + timerfd_tracker () + : tfd_shared_hdl (NULL), tfd_shared (NULL), cancel_evt (NULL), + sync_thr (NULL), local_instance_count (1) {} + int create (clockid_t); + int gettime (struct itimerspec *); + int settime (int, const struct itimerspec *, struct itimerspec *); + static void dtor (timerfd_tracker *); + void close (); + void ioctl_set_ticks (uint64_t); + void fixup_after_fork_exec (bool); + void fixup_after_fork () { fixup_after_fork_exec (false); } + void fixup_after_exec () { fixup_after_fork_exec (true); } + HANDLE get_timerfd_handle () const { return tfd_shared->expired_evt (); } + HANDLE get_disarm_evt () const { return tfd_shared->disarm_evt (); } + LONG64 wait (bool); + void increment_global_instances () + { InterlockedIncrement (&tfd_shared->instance_count); } + void increment_instances () + { + InterlockedIncrement (&tfd_shared->instance_count); + InterlockedIncrement (&local_instance_count); + } + void decrement_instances () + { + InterlockedDecrement (&tfd_shared->instance_count); + InterlockedDecrement (&local_instance_count); + } + + DWORD thread_func (); +}; + +#endif /* __TIMERFD_H__ */ From 3bfe18c643edfcc3c89f88972e4fd33e4248ba4e Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Sat, 19 Jan 2019 20:02:54 +0100 Subject: [PATCH 113/475] Cygwin: fhandler_pipe: fix comment Signed-off-by: Corinna Vinschen --- winsup/cygwin/fhandler_pipe.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/winsup/cygwin/fhandler_pipe.cc b/winsup/cygwin/fhandler_pipe.cc index c74782416..3a70565de 100644 --- a/winsup/cygwin/fhandler_pipe.cc +++ b/winsup/cygwin/fhandler_pipe.cc @@ -1,4 +1,4 @@ -/* pipe.cc: pipe for Cygwin. +/* fhandler_pipe.cc: pipes for Cygwin. This file is part of Cygwin. From e32d1510da0f943dc4631bce3d49d85d156f78bd Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Sat, 19 Jan 2019 20:53:38 +0100 Subject: [PATCH 114/475] Cygwin: timerfd: prepare for TFD_TIMER_CANCEL_ON_SET Also drop debugging sleep and make sure overrun count is positive. Signed-off-by: Corinna Vinschen --- winsup/cygwin/fhandler_timerfd.cc | 2 -- winsup/cygwin/timerfd.cc | 22 ++++++++++++++-------- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/winsup/cygwin/fhandler_timerfd.cc b/winsup/cygwin/fhandler_timerfd.cc index 8d3085692..33829edac 100644 --- a/winsup/cygwin/fhandler_timerfd.cc +++ b/winsup/cygwin/fhandler_timerfd.cc @@ -322,8 +322,6 @@ extern "C" int timerfd_settime (int fd_in, int flags, const struct itimerspec *value, struct itimerspec *ovalue) { - /* TODO: There's no easy way to implement TFD_TIMER_CANCEL_ON_SET, - but we should at least accept the flag. */ if ((flags & ~(TFD_TIMER_ABSTIME | TFD_TIMER_CANCEL_ON_SET)) != 0) { set_errno (EINVAL); diff --git a/winsup/cygwin/timerfd.cc b/winsup/cygwin/timerfd.cc index 145f3a665..ae26004a4 100644 --- a/winsup/cygwin/timerfd.cc +++ b/winsup/cygwin/timerfd.cc @@ -36,6 +36,7 @@ timerfd_tracker::thread_func () } /* Inner loop: Timer expired? If not, wait for it. */ + /* TODO: TFD_TIMER_CANCEL_ON_SET */ HANDLE expired[3] = { tfd_shared->timer (), tfd_shared->disarm_evt (), cancel_evt }; @@ -359,16 +360,21 @@ repeat: { ret = read_and_reset_overrun_count (); leave_critical_section (); - if (ret) - break; - /* A 0 overrun count indicates another read was quicker. - Continue as if we didn't catch the expiry. */ - if (!nonblocking) + switch (ret) { - Sleep (100L); - goto repeat; + case -1: /* TFD_TIMER_CANCEL_ON_SET */ + ret = -ECANCELED; + break; + case 0: /* Another read was quicker. */ + if (!nonblocking) + goto repeat; + ret = -EAGAIN; + break; + default: /* Return (positive) overrun count. */ + if (ret < 0) + ret = INT64_MAX; + break; } - ret = -EAGAIN; } break; case WAIT_OBJECT_0 + 1: /* signal */ From 597285ca58770f3c9495aa91fbf24129b01cf426 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Sun, 20 Jan 2019 22:18:17 +0100 Subject: [PATCH 115/475] Cygwin: timerfd: fix read(2) running wild - On systems with inexact realtime clock, the current timestamp may be fractionally smaller than the desired timestamp. This breaks the computation for incrementing overrun_count so overrun_count may end up as 0. Expiring the timer with an overrun_count of 0 is a no-go. Make sure we always increment overrun_count by at least one after timer expiry. - Do not expire the timer when another process deletes its timer_tracker. This, too, may result in a 0 overrun_count. Signed-off-by: Corinna Vinschen --- winsup/cygwin/timerfd.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/winsup/cygwin/timerfd.cc b/winsup/cygwin/timerfd.cc index ae26004a4..dbb63e676 100644 --- a/winsup/cygwin/timerfd.cc +++ b/winsup/cygwin/timerfd.cc @@ -69,6 +69,9 @@ timerfd_tracker::thread_func () LONG64 now = get_clock_now (); LONG64 ts = get_exp_ts (); + /* Make concessions for unexact realtime clock */ + if (ts > now) + ts = now - 1; increment_overrun_count ((now - ts + get_interval () - 1) / get_interval ()); /* Set exp_ts to current timestamp. Make sure exp_ts ends up @@ -251,7 +254,6 @@ timerfd_shared::dtor () { return false; } - timer_expired (); disarm_timer (); NtClose (_timer); NtClose (_arm_evt); From 693c98c5e2f9d674eb28952be3e105fba7ea06ad Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Sun, 20 Jan 2019 22:19:27 +0100 Subject: [PATCH 116/475] Cygwin: timerfd: Fix entering critical section Getting an abandonded mutex is just as well and must be handled. Signed-off-by: Corinna Vinschen --- winsup/cygwin/timerfd.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/winsup/cygwin/timerfd.h b/winsup/cygwin/timerfd.h index 6c42d91f4..711738283 100644 --- a/winsup/cygwin/timerfd.h +++ b/winsup/cygwin/timerfd.h @@ -59,7 +59,8 @@ class timerfd_shared /* write access methods */ bool enter_cs () { - return WaitForSingleObject (_access_mtx, INFINITE) == WAIT_OBJECT_0; + return (WaitForSingleObject (_access_mtx, INFINITE) & ~WAIT_ABANDONED_0) + == WAIT_OBJECT_0; } void leave_cs () { From 95bc4240ed3f593cd7d3740db86d0a2ceabbf660 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Sun, 20 Jan 2019 22:46:44 +0100 Subject: [PATCH 117/475] Cygwin: timerfd: convert expiry timestamp to LONG64 Turns out we never need it as LARGE_INTEGER. Signed-off-by: Corinna Vinschen --- winsup/cygwin/timerfd.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/winsup/cygwin/timerfd.h b/winsup/cygwin/timerfd.h index 711738283..543fad1d2 100644 --- a/winsup/cygwin/timerfd.h +++ b/winsup/cygwin/timerfd.h @@ -26,7 +26,7 @@ class timerfd_shared clockid_t _clockid; /* clockid */ struct itimerspec _time_spec; /* original incoming itimerspec */ - LARGE_INTEGER _exp_ts; /* start timestamp or next expire timestamp + LONG64 _exp_ts; /* start timestamp or next expire timestamp in 100ns */ LONG64 _interval; /* timer interval in 100ns */ LONG64 _overrun_count; /* expiry counter */ @@ -71,7 +71,7 @@ class timerfd_shared { ResetEvent (_arm_evt); memset (&_time_spec, 0, sizeof _time_spec); - _exp_ts.QuadPart = 0; + _exp_ts = 0; _interval = 0; _flags = 0; NtCancelTimer (timer (), NULL); @@ -79,7 +79,7 @@ class timerfd_shared return 0; } void timer_expired () { SetEvent (_expired_evt); } - void set_exp_ts (LONG64 ts) { _exp_ts.QuadPart = ts; } + void set_exp_ts (LONG64 ts) { _exp_ts = ts; } friend class timerfd_tracker; }; @@ -120,7 +120,7 @@ class timerfd_tracker /* cygheap! */ { return tfd_shared->time_spec ().it_interval; } LONG64 get_clock_now () const { return tfd_shared->get_clock_now (); } - LONG64 get_exp_ts () const { return tfd_shared->_exp_ts.QuadPart; } + LONG64 get_exp_ts () const { return tfd_shared->_exp_ts; } LONG64 get_interval () const { return tfd_shared->_interval; } void set_exp_ts (LONG64 ts) const { tfd_shared->set_exp_ts (ts); } From 2993057a94fa0f3954c327d8430943c7f71642ba Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Sun, 20 Jan 2019 22:47:52 +0100 Subject: [PATCH 118/475] Cygwin: timerfd: implement TFD_TIMER_CANCEL_ON_SET Signed-off-by: Corinna Vinschen --- winsup/cygwin/autoload.cc | 2 + winsup/cygwin/timerfd.cc | 90 +++++++++++++++++++++++++++++++++++++-- winsup/cygwin/timerfd.h | 28 ++++++++---- 3 files changed, 109 insertions(+), 11 deletions(-) diff --git a/winsup/cygwin/autoload.cc b/winsup/cygwin/autoload.cc index 7978287cb..b4dc77339 100644 --- a/winsup/cygwin/autoload.cc +++ b/winsup/cygwin/autoload.cc @@ -663,6 +663,7 @@ LoadDLLfunc (CreateDesktopW, 24, user32) LoadDLLfunc (CreateWindowExW, 48, user32) LoadDLLfunc (CreateWindowStationW, 16, user32) LoadDLLfunc (DefWindowProcW, 16, user32) +LoadDLLfunc (DestroyWindow, 4, user32) LoadDLLfunc (DispatchMessageW, 4, user32) LoadDLLfunc (EmptyClipboard, 0, user32) LoadDLLfunc (EnumWindows, 8, user32) @@ -690,6 +691,7 @@ LoadDLLfunc (SetClipboardData, 8, user32) LoadDLLfunc (SetParent, 8, user32) LoadDLLfunc (SetProcessWindowStation, 4, user32) LoadDLLfunc (SetThreadDesktop, 4, user32) +LoadDLLfunc (UnregisterClassW, 8, user32) LoadDLLfuncEx (CreateEnvironmentBlock, 12, userenv, 1) LoadDLLfuncEx2 (CreateProfile, 16, userenv, 1, 1) diff --git a/winsup/cygwin/timerfd.cc b/winsup/cygwin/timerfd.cc index dbb63e676..cebb002ed 100644 --- a/winsup/cygwin/timerfd.cc +++ b/winsup/cygwin/timerfd.cc @@ -16,6 +16,70 @@ details. */ #include #include "timerfd.h" +#define TFD_CANCEL_FLAGS (TFD_TIMER_ABSTIME | TFD_TIMER_CANCEL_ON_SET) + +/* Unfortunately MsgWaitForMultipleObjectsEx does not receive WM_TIMECHANGED + messages without a window defined in this process. Create a hidden window + for that purpose. */ + +void +timerfd_tracker::create_timechange_window () +{ + WNDCLASSW wclass = { 0 }; + WCHAR cname[NAME_MAX]; + + __small_swprintf (cname, L"Cygwin.timerfd.%u", winpid); + wclass.lpfnWndProc = DefWindowProcW; + wclass.hInstance = GetModuleHandle (NULL); + wclass.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1); + wclass.lpszClassName = cname; + atom = RegisterClassW (&wclass); + if (!atom) + debug_printf ("RegisterClass %E"); + else + { + window = CreateWindowExW (0, cname, cname, WS_POPUP, 0, 0, 0, 0, + NULL, NULL, NULL, NULL); + if (!window) + debug_printf ("RegisterClass %E"); + } +} + +void +timerfd_tracker::delete_timechange_window () +{ + if (window) + DestroyWindow (window); + if (atom) + UnregisterClassW ((LPWSTR) (uintptr_t) atom, GetModuleHandle (NULL)); +} + +void +timerfd_tracker::handle_timechange_window () +{ + MSG msg; + + if (PeekMessageW(&msg, NULL, 0, 0, PM_REMOVE) && msg.message != WM_QUIT) + { + DispatchMessageW(&msg); + if (msg.message == WM_TIMECHANGE + && get_clockid () == CLOCK_REALTIME + && (flags () & TFD_CANCEL_FLAGS) == TFD_CANCEL_FLAGS + && enter_critical_section ()) + { + /* make sure to handle each WM_TIMECHANGE only once! */ + if (msg.time != tc_time ()) + { + set_overrun_count (-1LL); + disarm_timer (); + timer_expired (); + set_tc_time (msg.time); + } + leave_critical_section (); + } + } +} + DWORD timerfd_tracker::thread_func () { @@ -23,14 +87,19 @@ timerfd_tracker::thread_func () HANDLE armed[2] = { tfd_shared->arm_evt (), cancel_evt }; + create_timechange_window (); while (1) { - switch (WaitForMultipleObjects (2, armed, FALSE, INFINITE)) + switch (MsgWaitForMultipleObjectsEx (2, armed, INFINITE, QS_POSTMESSAGE, + MWMO_INPUTAVAILABLE)) { case WAIT_OBJECT_0: break; case WAIT_OBJECT_0 + 1: goto canceled; + case WAIT_OBJECT_0 + 2: + handle_timechange_window (); + continue; default: continue; } @@ -40,9 +109,12 @@ timerfd_tracker::thread_func () HANDLE expired[3] = { tfd_shared->timer (), tfd_shared->disarm_evt (), cancel_evt }; + while (1) { - switch (WaitForMultipleObjects (3, expired, FALSE, INFINITE)) + switch (MsgWaitForMultipleObjectsEx (3, expired, INFINITE, + QS_POSTMESSAGE, + MWMO_INPUTAVAILABLE)) { case WAIT_OBJECT_0: break; @@ -50,12 +122,23 @@ timerfd_tracker::thread_func () goto disarmed; case WAIT_OBJECT_0 + 2: goto canceled; + case WAIT_OBJECT_0 + 3: + handle_timechange_window (); + continue; default: continue; } if (!enter_critical_section ()) continue; + /* Make sure we haven't been abandoned and/or disarmed + in the meantime */ + if (overrun_count () == -1LL + || IsEventSignalled (tfd_shared->disarm_evt ())) + { + leave_critical_section (); + goto disarmed; + } /* One-shot timer? */ if (!get_interval ()) { @@ -93,7 +176,7 @@ timerfd_tracker::thread_func () NtSetTimer (tfd_shared->timer (), &DueTime, NULL, NULL, Resume, 0, NULL); } - } + } /* Arm the expiry object */ timer_expired (); leave_critical_section (); @@ -103,6 +186,7 @@ disarmed: } canceled: + delete_timechange_window (); _my_tls._ctinfo->auto_release (); /* automatically return the cygthread to the cygthread pool */ return 0; } diff --git a/winsup/cygwin/timerfd.h b/winsup/cygwin/timerfd.h index 543fad1d2..cebd1d9eb 100644 --- a/winsup/cygwin/timerfd.h +++ b/winsup/cygwin/timerfd.h @@ -31,6 +31,7 @@ class timerfd_shared LONG64 _interval; /* timer interval in 100ns */ LONG64 _overrun_count; /* expiry counter */ int _flags; /* settime flags */ + DWORD _tc_time; /* timestamp of the last WM_TIMECHANGE msg */ int create (clockid_t); bool dtor (); @@ -43,7 +44,8 @@ class timerfd_shared LONG64 get_clock_now () const { return get_clock (_clockid)->n100secs (); } struct itimerspec &time_spec () { return _time_spec; } int flags () const { return _flags; } - LONG64 overrun_count () const { return _overrun_count; } + + /* write access methods */ void increment_overrun_count (LONG64 add) { InterlockedAdd64 (&_overrun_count, add); } void set_overrun_count (LONG64 newval) @@ -55,8 +57,6 @@ class timerfd_shared ResetEvent (_expired_evt); return ret; } - - /* write access methods */ bool enter_cs () { return (WaitForSingleObject (_access_mtx, INFINITE) & ~WAIT_ABANDONED_0) @@ -73,7 +73,7 @@ class timerfd_shared memset (&_time_spec, 0, sizeof _time_spec); _exp_ts = 0; _interval = 0; - _flags = 0; + /* _flags = 0; DON'T DO THAT. Required for TFD_TIMER_CANCEL_ON_SET */ NtCancelTimer (timer (), NULL); SetEvent (_disarm_evt); return 0; @@ -86,8 +86,6 @@ class timerfd_shared class timerfd_tracker /* cygheap! */ { - DWORD winpid; /* This is used @ fork/exec time to know if - this tracker already has been fixed up. */ HANDLE tfd_shared_hdl; /* handle auf shared mem */ timerfd_shared *tfd_shared; /* pointer auf shared mem, needs NtMapViewOfSection in each new process. */ @@ -96,6 +94,14 @@ class timerfd_tracker /* cygheap! */ HANDLE sync_thr; /* cygthread sync object. */ LONG local_instance_count; /* each open fd increments this. If 0 -> cancel thread. */ + DWORD winpid; /* This is used @ fork/exec time to know if + this tracker already has been fixed up. */ + HWND window; /* window handle */ + ATOM atom; /* window class */ + + void create_timechange_window (); + void delete_timechange_window (); + void handle_timechange_window (); bool dtor (); @@ -107,9 +113,10 @@ class timerfd_tracker /* cygheap! */ int disarm_timer () const { return tfd_shared->disarm_timer (); } void timer_expired () const { tfd_shared->timer_expired (); } + LONG64 overrun_count () const { return tfd_shared->_overrun_count; } void increment_overrun_count (LONG64 add) const { tfd_shared->increment_overrun_count (add); } - void set_overrun_count (uint64_t ov_cnt) const + void set_overrun_count (LONG64 ov_cnt) const { tfd_shared->set_overrun_count ((LONG64) ov_cnt); } LONG64 read_and_reset_overrun_count () const { return tfd_shared->read_and_reset_overrun_count (); } @@ -119,9 +126,13 @@ class timerfd_tracker /* cygheap! */ struct timespec it_interval () const { return tfd_shared->time_spec ().it_interval; } + clock_t get_clockid () const { return tfd_shared->_clockid; } LONG64 get_clock_now () const { return tfd_shared->get_clock_now (); } LONG64 get_exp_ts () const { return tfd_shared->_exp_ts; } LONG64 get_interval () const { return tfd_shared->_interval; } + int flags () const { return tfd_shared->flags (); } + DWORD tc_time () const { return tfd_shared->_tc_time; } + void set_tc_time (DWORD new_time) { tfd_shared->_tc_time = new_time; } void set_exp_ts (LONG64 ts) const { tfd_shared->set_exp_ts (ts); } @@ -129,7 +140,8 @@ class timerfd_tracker /* cygheap! */ void *operator new (size_t, void *p) __attribute__ ((nothrow)) {return p;} timerfd_tracker () : tfd_shared_hdl (NULL), tfd_shared (NULL), cancel_evt (NULL), - sync_thr (NULL), local_instance_count (1) {} + sync_thr (NULL), local_instance_count (1), winpid (0), window (NULL), + atom (0) {} int create (clockid_t); int gettime (struct itimerspec *); int settime (int, const struct itimerspec *, struct itimerspec *); From 02de9ac61e84c40b18f71e7d8be15f90bb01411e Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Mon, 21 Jan 2019 00:14:09 +0100 Subject: [PATCH 119/475] Cygwin: timerfd: fill out it_interval on timerfd_gettime Might not be such a bad idea, after all... Signed-off-by: Corinna Vinschen --- winsup/cygwin/timerfd.cc | 1 + winsup/cygwin/timerfd.h | 1 + 2 files changed, 2 insertions(+) diff --git a/winsup/cygwin/timerfd.cc b/winsup/cygwin/timerfd.cc index cebb002ed..4f04efd13 100644 --- a/winsup/cygwin/timerfd.cc +++ b/winsup/cygwin/timerfd.cc @@ -495,6 +495,7 @@ timerfd_tracker::gettime (struct itimerspec *curr_value) next_relative_exp -= curr_value->it_value.tv_sec * NS100PERSEC; curr_value->it_value.tv_nsec = next_relative_exp * (NSPERSEC / NS100PERSEC); + curr_value->it_interval = time_spec ().it_interval; leave_critical_section (); ret = 0; } diff --git a/winsup/cygwin/timerfd.h b/winsup/cygwin/timerfd.h index cebd1d9eb..e314579b0 100644 --- a/winsup/cygwin/timerfd.h +++ b/winsup/cygwin/timerfd.h @@ -128,6 +128,7 @@ class timerfd_tracker /* cygheap! */ clock_t get_clockid () const { return tfd_shared->_clockid; } LONG64 get_clock_now () const { return tfd_shared->get_clock_now (); } + struct itimerspec &time_spec () { return tfd_shared->time_spec (); } LONG64 get_exp_ts () const { return tfd_shared->_exp_ts; } LONG64 get_interval () const { return tfd_shared->_interval; } int flags () const { return tfd_shared->flags (); } From a3268ac392241830cf6c91abe663f252c407cf8c Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Mon, 21 Jan 2019 00:14:51 +0100 Subject: [PATCH 120/475] Cygwin: timerfd: Handle gettime error in settime Signed-off-by: Corinna Vinschen --- winsup/cygwin/timerfd.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/winsup/cygwin/timerfd.cc b/winsup/cygwin/timerfd.cc index 4f04efd13..e5c17fb4e 100644 --- a/winsup/cygwin/timerfd.cc +++ b/winsup/cygwin/timerfd.cc @@ -590,8 +590,8 @@ timerfd_tracker::settime (int flags, const struct itimerspec *new_value, ret = -EBADF; __leave; } - if (old_value) - gettime (old_value); + if (old_value && (ret = gettime (old_value)) < 0) + __leave; if (new_value->it_value.tv_sec == 0 && new_value->it_value.tv_nsec == 0) ret = disarm_timer (); else From 6ed50a68a133e7e0c0d10e328bce94f98944dbe5 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Mon, 21 Jan 2019 10:05:13 +0100 Subject: [PATCH 121/475] Cygwin: timerfd: settime: fix computing DueTime on non-realtime clocks Non-CLOCK_REALTIME counters always use a relative DueTime in NtSetTimer. However, relative DueTime has to be negative, but the code Signed-off-by: Corinna Vinschen --- winsup/cygwin/timerfd.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/winsup/cygwin/timerfd.cc b/winsup/cygwin/timerfd.cc index e5c17fb4e..64836b021 100644 --- a/winsup/cygwin/timerfd.cc +++ b/winsup/cygwin/timerfd.cc @@ -532,7 +532,7 @@ timerfd_shared::arm_timer (int flags, const struct itimerspec *new_value) DueTime.QuadPart = ts + FACTOR; else /* non-REALTIME clocks require relative DueTime. */ { - DueTime.QuadPart = ts - get_clock_now (); + DueTime.QuadPart = get_clock_now () - ts; /* If the timestamp was earlier than now, compute number of overruns and offset DueTime to expire immediately. */ if (DueTime.QuadPart >= 0) From ea99e9fdda42141ef1c2273943a33d3191d72844 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Mon, 21 Jan 2019 11:14:16 +0100 Subject: [PATCH 122/475] Cygwin: timerfd: fix overrun computation - Drop erroneous initial computation of overrun count in settime for absolute non-realtime clocks. It's repeated in thread_func and thus counted twice. - Fix overrun computation for timestamp offsets being a multiple of the timer interval. The timestamp has to be corrected after the first offset, otherwise the correction loop counts the intervals again. Signed-off-by: Corinna Vinschen --- winsup/cygwin/timerfd.cc | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/winsup/cygwin/timerfd.cc b/winsup/cygwin/timerfd.cc index 64836b021..0a042415d 100644 --- a/winsup/cygwin/timerfd.cc +++ b/winsup/cygwin/timerfd.cc @@ -155,13 +155,18 @@ timerfd_tracker::thread_func () /* Make concessions for unexact realtime clock */ if (ts > now) ts = now - 1; - increment_overrun_count ((now - ts + get_interval () - 1) - / get_interval ()); + LONG64 ov_cnt = (now - ts + get_interval () - 1) + / get_interval (); + increment_overrun_count (ov_cnt); + ts += get_interval () * ov_cnt; /* Set exp_ts to current timestamp. Make sure exp_ts ends up bigger than "now" and fix overrun count as required */ - while ((ts += get_interval ()) <= (now = get_clock_now ())) - increment_overrun_count ((now - ts + get_interval () - 1) - / get_interval ()); + while (ts <= (now = get_clock_now ())) + { + increment_overrun_count ((now - ts + get_interval () - 1) + / get_interval ()); + ts += get_interval (); + } set_exp_ts (ts); /* NtSetTimer allows periods of up to 24 days only. If the time is longer, we set the timer up as one-shot timer for each @@ -536,11 +541,7 @@ timerfd_shared::arm_timer (int flags, const struct itimerspec *new_value) /* If the timestamp was earlier than now, compute number of overruns and offset DueTime to expire immediately. */ if (DueTime.QuadPart >= 0) - { - LONG64 num_intervals = DueTime.QuadPart / _interval; - increment_overrun_count (num_intervals); - DueTime.QuadPart = -1LL; - } + DueTime.QuadPart = -1LL; } } else From 528f4d49384e1c3ad95d3a6913bf681ef714d51f Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Mon, 21 Jan 2019 12:26:51 +0100 Subject: [PATCH 123/475] Cygwin: timerfd: rename overrun_count to expiration_count The value returned by reading from a timerfd is not an overrun count in the same sense as for posix timers, it's an expiry counter. Reflect that in the name. Signed-off-by: Corinna Vinschen --- winsup/cygwin/fhandler_timerfd.cc | 8 ++++---- winsup/cygwin/timerfd.cc | 34 +++++++++++++++---------------- winsup/cygwin/timerfd.h | 28 ++++++++++++------------- 3 files changed, 35 insertions(+), 35 deletions(-) diff --git a/winsup/cygwin/fhandler_timerfd.cc b/winsup/cygwin/fhandler_timerfd.cc index 33829edac..8a6c4b559 100644 --- a/winsup/cygwin/fhandler_timerfd.cc +++ b/winsup/cygwin/fhandler_timerfd.cc @@ -218,7 +218,7 @@ int fhandler_timerfd::ioctl (unsigned int cmd, void *p) { int ret = -1; - uint64_t ov_cnt; + uint64_t exp_cnt; switch (cmd) { @@ -227,13 +227,13 @@ fhandler_timerfd::ioctl (unsigned int cmd, void *p) { timerfd_tracker *tfd = (timerfd_tracker *) timerid; - ov_cnt = *(uint64_t *) p; - if (!ov_cnt) + exp_cnt = *(uint64_t *) p; + if (!exp_cnt) { set_errno (EINVAL); break; } - tfd->ioctl_set_ticks (ov_cnt); + tfd->ioctl_set_ticks (exp_cnt); ret = 0; } __except (EFAULT) {} diff --git a/winsup/cygwin/timerfd.cc b/winsup/cygwin/timerfd.cc index 0a042415d..08fff312c 100644 --- a/winsup/cygwin/timerfd.cc +++ b/winsup/cygwin/timerfd.cc @@ -70,7 +70,7 @@ timerfd_tracker::handle_timechange_window () /* make sure to handle each WM_TIMECHANGE only once! */ if (msg.time != tc_time ()) { - set_overrun_count (-1LL); + set_expiration_count (-1LL); disarm_timer (); timer_expired (); set_tc_time (msg.time); @@ -133,7 +133,7 @@ timerfd_tracker::thread_func () continue; /* Make sure we haven't been abandoned and/or disarmed in the meantime */ - if (overrun_count () == -1LL + if (expiration_count () == -1LL || IsEventSignalled (tfd_shared->disarm_evt ())) { leave_critical_section (); @@ -142,29 +142,29 @@ timerfd_tracker::thread_func () /* One-shot timer? */ if (!get_interval ()) { - /* Set overrun count, disarm timer */ - increment_overrun_count (1); + /* Set expiration count, disarm timer */ + increment_expiration_count (1); disarm_timer (); } else { - /* Compute overrun count. */ + /* Compute expiration count. */ LONG64 now = get_clock_now (); LONG64 ts = get_exp_ts (); + LONG64 exp_cnt; /* Make concessions for unexact realtime clock */ if (ts > now) ts = now - 1; - LONG64 ov_cnt = (now - ts + get_interval () - 1) - / get_interval (); - increment_overrun_count (ov_cnt); - ts += get_interval () * ov_cnt; + exp_cnt = (now - ts + get_interval () - 1) / get_interval (); + increment_expiration_count (exp_cnt); + ts += get_interval () * exp_cnt; /* Set exp_ts to current timestamp. Make sure exp_ts ends up - bigger than "now" and fix overrun count as required */ + bigger than "now" and fix expiration count as required */ while (ts <= (now = get_clock_now ())) { - increment_overrun_count ((now - ts + get_interval () - 1) - / get_interval ()); + increment_expiration_count ((now - ts + get_interval () - 1) + / get_interval ()); ts += get_interval (); } set_exp_ts (ts); @@ -395,9 +395,9 @@ timerfd_tracker::close () } void -timerfd_tracker::ioctl_set_ticks (uint64_t ov_cnt) +timerfd_tracker::ioctl_set_ticks (uint64_t exp_cnt) { - set_overrun_count (ov_cnt); + set_expiration_count (exp_cnt); timer_expired (); } @@ -449,7 +449,7 @@ repeat: ret = -EIO; else { - ret = read_and_reset_overrun_count (); + ret = read_and_reset_expiration_count (); leave_critical_section (); switch (ret) { @@ -461,7 +461,7 @@ repeat: goto repeat; ret = -EAGAIN; break; - default: /* Return (positive) overrun count. */ + default: /* Return (positive) expiration count. */ if (ret < 0) ret = INT64_MAX; break; @@ -539,7 +539,7 @@ timerfd_shared::arm_timer (int flags, const struct itimerspec *new_value) { DueTime.QuadPart = get_clock_now () - ts; /* If the timestamp was earlier than now, compute number - of overruns and offset DueTime to expire immediately. */ + of expirations and offset DueTime to expire immediately. */ if (DueTime.QuadPart >= 0) DueTime.QuadPart = -1LL; } diff --git a/winsup/cygwin/timerfd.h b/winsup/cygwin/timerfd.h index e314579b0..1f9f76268 100644 --- a/winsup/cygwin/timerfd.h +++ b/winsup/cygwin/timerfd.h @@ -29,7 +29,7 @@ class timerfd_shared LONG64 _exp_ts; /* start timestamp or next expire timestamp in 100ns */ LONG64 _interval; /* timer interval in 100ns */ - LONG64 _overrun_count; /* expiry counter */ + LONG64 _expiration_count; /* expiry counter */ int _flags; /* settime flags */ DWORD _tc_time; /* timestamp of the last WM_TIMECHANGE msg */ @@ -46,13 +46,13 @@ class timerfd_shared int flags () const { return _flags; } /* write access methods */ - void increment_overrun_count (LONG64 add) - { InterlockedAdd64 (&_overrun_count, add); } - void set_overrun_count (LONG64 newval) - { InterlockedExchange64 (&_overrun_count, newval); } - LONG64 read_and_reset_overrun_count () + void increment_expiration_count (LONG64 add) + { InterlockedAdd64 (&_expiration_count, add); } + void set_expiration_count (LONG64 newval) + { InterlockedExchange64 (&_expiration_count, newval); } + LONG64 read_and_reset_expiration_count () { - LONG64 ret = InterlockedExchange64 (&_overrun_count, 0); + LONG64 ret = InterlockedExchange64 (&_expiration_count, 0); if (ret) ResetEvent (_expired_evt); return ret; @@ -113,13 +113,13 @@ class timerfd_tracker /* cygheap! */ int disarm_timer () const { return tfd_shared->disarm_timer (); } void timer_expired () const { tfd_shared->timer_expired (); } - LONG64 overrun_count () const { return tfd_shared->_overrun_count; } - void increment_overrun_count (LONG64 add) const - { tfd_shared->increment_overrun_count (add); } - void set_overrun_count (LONG64 ov_cnt) const - { tfd_shared->set_overrun_count ((LONG64) ov_cnt); } - LONG64 read_and_reset_overrun_count () const - { return tfd_shared->read_and_reset_overrun_count (); } + LONG64 expiration_count () const { return tfd_shared->_expiration_count; } + void increment_expiration_count (LONG64 add) const + { tfd_shared->increment_expiration_count (add); } + void set_expiration_count (LONG64 exp_cnt) const + { tfd_shared->set_expiration_count ((LONG64) exp_cnt); } + LONG64 read_and_reset_expiration_count () const + { return tfd_shared->read_and_reset_expiration_count (); } struct timespec it_value () const { return tfd_shared->time_spec ().it_value; } From 289b7c09c8bca6c84edfddf77c11b530bda95016 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Mon, 21 Jan 2019 12:41:00 +0100 Subject: [PATCH 124/475] Cygwin: timerfd: move ioctl error handling into timerfd_tracker Signed-off-by: Corinna Vinschen --- winsup/cygwin/fhandler_timerfd.cc | 62 +++++++++++++++---------------- winsup/cygwin/timerfd.cc | 11 +++++- winsup/cygwin/timerfd.h | 2 +- 3 files changed, 39 insertions(+), 36 deletions(-) diff --git a/winsup/cygwin/fhandler_timerfd.cc b/winsup/cygwin/fhandler_timerfd.cc index 8a6c4b559..2a0521708 100644 --- a/winsup/cygwin/fhandler_timerfd.cc +++ b/winsup/cygwin/fhandler_timerfd.cc @@ -187,6 +187,35 @@ fhandler_timerfd::dup (fhandler_base *child, int flags) return ret; } +int +fhandler_timerfd::ioctl (unsigned int cmd, void *p) +{ + int ret = -1; + uint64_t exp_cnt; + + switch (cmd) + { + case TFD_IOC_SET_TICKS: + __try + { + timerfd_tracker *tfd = (timerfd_tracker *) timerid; + + exp_cnt = *(uint64_t *) p; + ret = tfd->ioctl_set_ticks (exp_cnt); + if (ret < 0) + set_errno (-ret); + } + __except (EFAULT) {} + __endtry + break; + default: + ret = fhandler_base::ioctl (cmd, p); + break; + } + syscall_printf ("%d = ioctl_timerfd(%x, %p)", ret, cmd, p); + return ret; +} + void fhandler_timerfd::fixup_after_fork (HANDLE) { @@ -214,39 +243,6 @@ fhandler_timerfd::fixup_after_exec () __endtry } -int -fhandler_timerfd::ioctl (unsigned int cmd, void *p) -{ - int ret = -1; - uint64_t exp_cnt; - - switch (cmd) - { - case TFD_IOC_SET_TICKS: - __try - { - timerfd_tracker *tfd = (timerfd_tracker *) timerid; - - exp_cnt = *(uint64_t *) p; - if (!exp_cnt) - { - set_errno (EINVAL); - break; - } - tfd->ioctl_set_ticks (exp_cnt); - ret = 0; - } - __except (EFAULT) {} - __endtry - break; - default: - ret = fhandler_base::ioctl (cmd, p); - break; - } - syscall_printf ("%d = ioctl_timerfd(%x, %p)", ret, cmd, p); - return ret; -} - fhandler_timerfd::~fhandler_timerfd () { __try diff --git a/winsup/cygwin/timerfd.cc b/winsup/cygwin/timerfd.cc index 08fff312c..a03749a60 100644 --- a/winsup/cygwin/timerfd.cc +++ b/winsup/cygwin/timerfd.cc @@ -394,11 +394,18 @@ timerfd_tracker::close () InterlockedDecrement (&tfd_shared->instance_count); } -void -timerfd_tracker::ioctl_set_ticks (uint64_t exp_cnt) +int +timerfd_tracker::ioctl_set_ticks (uint64_t new_exp_cnt) { + LONG64 exp_cnt = (LONG64) new_exp_cnt; + if (exp_cnt == 0 || exp_cnt == -1LL) + return -EINVAL; + if (!enter_critical_section ()) + return -EBADF; set_expiration_count (exp_cnt); timer_expired (); + leave_critical_section (); + return 0; } void diff --git a/winsup/cygwin/timerfd.h b/winsup/cygwin/timerfd.h index 1f9f76268..66bf78424 100644 --- a/winsup/cygwin/timerfd.h +++ b/winsup/cygwin/timerfd.h @@ -148,7 +148,7 @@ class timerfd_tracker /* cygheap! */ int settime (int, const struct itimerspec *, struct itimerspec *); static void dtor (timerfd_tracker *); void close (); - void ioctl_set_ticks (uint64_t); + int ioctl_set_ticks (uint64_t); void fixup_after_fork_exec (bool); void fixup_after_fork () { fixup_after_fork_exec (false); } void fixup_after_exec () { fixup_after_fork_exec (true); } From 5b23a8e83112548d4c06e2f4b46aa20bd38d26d5 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Mon, 21 Jan 2019 22:52:39 +0100 Subject: [PATCH 125/475] Cygwin: timerfd: fix gettime - split into to __try/__except blocks to make sure leave_critical_section is always called when required. - Actually fill time_spec in settime so it_interval is returned correctly. - Return all 0 if timer is disarmed. Signed-off-by: Corinna Vinschen --- winsup/cygwin/timerfd.cc | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/winsup/cygwin/timerfd.cc b/winsup/cygwin/timerfd.cc index a03749a60..295716f46 100644 --- a/winsup/cygwin/timerfd.cc +++ b/winsup/cygwin/timerfd.cc @@ -502,13 +502,26 @@ timerfd_tracker::gettime (struct itimerspec *curr_value) ret = -EBADF; __leave; } - LONG64 next_relative_exp = get_exp_ts () - get_clock_now (); - curr_value->it_value.tv_sec = next_relative_exp / NS100PERSEC; - next_relative_exp -= curr_value->it_value.tv_sec * NS100PERSEC; - curr_value->it_value.tv_nsec = next_relative_exp - * (NSPERSEC / NS100PERSEC); - curr_value->it_interval = time_spec ().it_interval; - leave_critical_section (); + } + __except (NO_ERROR) + { + return -EFAULT; + } + __endtry + + __try + { + if (IsEventSignalled (tfd_shared->disarm_evt ())) + *curr_value = time_spec (); + else + { + LONG64 next_relative_exp = get_exp_ts () - get_clock_now (); + curr_value->it_value.tv_sec = next_relative_exp / NS100PERSEC; + next_relative_exp -= curr_value->it_value.tv_sec * NS100PERSEC; + curr_value->it_value.tv_nsec = next_relative_exp + * (NSPERSEC / NS100PERSEC); + curr_value->it_interval = time_spec ().it_interval; + } ret = 0; } __except (NO_ERROR) @@ -516,6 +529,7 @@ timerfd_tracker::gettime (struct itimerspec *curr_value) ret = -EFAULT; } __endtry + leave_critical_section (); return ret; } @@ -559,6 +573,7 @@ timerfd_shared::arm_timer (int flags, const struct itimerspec *new_value) ts += get_clock_now (); } set_exp_ts (ts); + time_spec () = *new_value; /* TODO: CLOCK_REALTIME_ALARM / CLOCK_BOOTTIME_ALARM Note: Advanced Power Settings -> Sleep -> Allow Wake Timers since W10 1709 */ From a75bd958b4a64182645984babedad3c2babb8401 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Mon, 21 Jan 2019 22:54:26 +0100 Subject: [PATCH 126/475] Cygwin: timerfd: reset expiry counter in settime As on Linux, reset the expiry counter when the timer gets rearmed. Signed-off-by: Corinna Vinschen --- winsup/cygwin/timerfd.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/winsup/cygwin/timerfd.cc b/winsup/cygwin/timerfd.cc index 295716f46..e865c0c15 100644 --- a/winsup/cygwin/timerfd.cc +++ b/winsup/cygwin/timerfd.cc @@ -574,6 +574,7 @@ timerfd_shared::arm_timer (int flags, const struct itimerspec *new_value) } set_exp_ts (ts); time_spec () = *new_value; + read_and_reset_expiration_count (); /* TODO: CLOCK_REALTIME_ALARM / CLOCK_BOOTTIME_ALARM Note: Advanced Power Settings -> Sleep -> Allow Wake Timers since W10 1709 */ From 4c50dc94c38cca718a7dc8a4f1dd6f2e5b1c4cfb Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Tue, 22 Jan 2019 15:06:51 +0100 Subject: [PATCH 127/475] Cygwin: timerfd: another overrun computation fix and drop useless variable - When correcting the next expiration timestamp, the number of expirations gets computed correctly, just the expiration timestamp itself is then only incremented by a single interval, rather than the just computed expired intervals. Fix that. - drop the local clock variable in timerfd_tracker::create. It doesn't serve any purpose. Signed-off-by: Corinna Vinschen --- winsup/cygwin/timerfd.cc | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/winsup/cygwin/timerfd.cc b/winsup/cygwin/timerfd.cc index e865c0c15..87074fd6f 100644 --- a/winsup/cygwin/timerfd.cc +++ b/winsup/cygwin/timerfd.cc @@ -163,9 +163,9 @@ timerfd_tracker::thread_func () bigger than "now" and fix expiration count as required */ while (ts <= (now = get_clock_now ())) { - increment_expiration_count ((now - ts + get_interval () - 1) - / get_interval ()); - ts += get_interval (); + exp_cnt = (now - ts + get_interval () - 1) / get_interval (); + increment_expiration_count (exp_cnt); + ts += get_interval () * exp_cnt; } set_exp_ts (ts); /* NtSetTimer allows periods of up to 24 days only. If the time @@ -271,7 +271,6 @@ int timerfd_tracker::create (clockid_t clock_id) { int ret; - clk_t *clock; NTSTATUS status; OBJECT_ATTRIBUTES attr; @@ -281,8 +280,7 @@ timerfd_tracker::create (clockid_t clock_id) LARGE_INTEGER sectionsize = { QuadPart: PAGE_SIZE }; /* Valid clock? */ - clock = get_clock (clock_id); - if (!clock) + if (!get_clock (clock_id)) { ret = -EINVAL; goto err; From 229ea3f23c01543f98f4446bd9092dbf60c983cc Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Tue, 22 Jan 2019 15:23:05 +0100 Subject: [PATCH 128/475] Cygwin: posix timers: reimplement using OS timer - Rename files timer.* to posix_timer.*. - Reimplement using an OS timer rather than a handcrafted wait loop. - Use a Slim R/W Lock for synchronization. - Drop timer chaining. It doesn't server a purpose since all timers are local only. - Rename ttstart to itimer_tracker to better reflect its purpose. It's not the anchor for a timer chain anymore anyway. - Drop fixup_timers_after_fork. Everything is process-local, nothing gets inherited. - Rename timer_tracker::disarm_event to disarm_overrun_event for better readability. Signed-off-by: Corinna Vinschen --- winsup/cygwin/Makefile.in | 2 +- winsup/cygwin/cygheap_malloc.h | 3 +- winsup/cygwin/exceptions.cc | 8 +- winsup/cygwin/fork.cc | 2 - winsup/cygwin/{timer.cc => posix_timer.cc} | 494 +++++++++++---------- winsup/cygwin/{timer.h => posix_timer.h} | 33 +- winsup/cygwin/signal.cc | 4 +- 7 files changed, 298 insertions(+), 248 deletions(-) rename winsup/cygwin/{timer.cc => posix_timer.cc} (50%) rename winsup/cygwin/{timer.h => posix_timer.h} (58%) diff --git a/winsup/cygwin/Makefile.in b/winsup/cygwin/Makefile.in index 374272f4c..32c02b87b 100644 --- a/winsup/cygwin/Makefile.in +++ b/winsup/cygwin/Makefile.in @@ -354,6 +354,7 @@ DLL_OFILES:= \ pinfo.o \ poll.o \ posix_ipc.o \ + posix_timer.o \ pseudo-reloc.o \ pthread.o \ quotactl.o \ @@ -395,7 +396,6 @@ DLL_OFILES:= \ syslog.o \ termios.o \ thread.o \ - timer.o \ timerfd.o \ times.o \ tls_pbuf.o \ diff --git a/winsup/cygwin/cygheap_malloc.h b/winsup/cygwin/cygheap_malloc.h index 74f0bb619..cd545c35d 100644 --- a/winsup/cygwin/cygheap_malloc.h +++ b/winsup/cygwin/cygheap_malloc.h @@ -34,7 +34,8 @@ enum cygheap_types HEAP_2_DLL, HEAP_MMAP, HEAP_2_MAX = 200, - HEAP_3_FHANDLER + HEAP_3_FHANDLER, + HEAP_3_TIMER }; extern "C" { diff --git a/winsup/cygwin/exceptions.cc b/winsup/cygwin/exceptions.cc index 205ad850e..491eedbe4 100644 --- a/winsup/cygwin/exceptions.cc +++ b/winsup/cygwin/exceptions.cc @@ -27,7 +27,7 @@ details. */ #include "child_info.h" #include "ntdll.h" #include "exception.h" -#include "timer.h" +#include "posix_timer.h" /* Definitions for code simplification */ #ifdef __x86_64__ @@ -1483,7 +1483,7 @@ sigpacket::process () if (handler == SIG_IGN) { if (si.si_code == SI_TIMER) - ((timer_tracker *) si.si_tid)->disarm_event (); + ((timer_tracker *) si.si_tid)->disarm_overrun_event (); sigproc_printf ("signal %d ignored", si.si_signo); goto done; } @@ -1508,7 +1508,7 @@ sigpacket::process () || si.si_signo == SIGURG) { if (si.si_code == SI_TIMER) - ((timer_tracker *) si.si_tid)->disarm_event (); + ((timer_tracker *) si.si_tid)->disarm_overrun_event (); sigproc_printf ("signal %d default is currently ignore", si.si_signo); goto done; } @@ -1637,7 +1637,7 @@ _cygtls::call_signal_handler () { timer_tracker *tt = (timer_tracker *) infodata.si_tid; - infodata.si_overrun = tt->disarm_event (); + infodata.si_overrun = tt->disarm_overrun_event (); } /* Save information locally on stack to pass to handler. */ diff --git a/winsup/cygwin/fork.cc b/winsup/cygwin/fork.cc index 5cfdd9559..6813446cf 100644 --- a/winsup/cygwin/fork.cc +++ b/winsup/cygwin/fork.cc @@ -22,7 +22,6 @@ details. */ #include "tls_pbuf.h" #include "dll_init.h" #include "cygmalloc.h" -#include "timer.h" #include "ntdll.h" #define NPIDS_HELD 4 @@ -196,7 +195,6 @@ frok::child (volatile char * volatile here) ForceCloseHandle1 (fork_info->forker_finished, forker_finished); pthread::atforkchild (); - fixup_timers_after_fork (); cygbench ("fork-child"); ld_preload (); fixup_hooks_after_fork (); diff --git a/winsup/cygwin/timer.cc b/winsup/cygwin/posix_timer.cc similarity index 50% rename from winsup/cygwin/timer.cc rename to winsup/cygwin/posix_timer.cc index e24edd5e9..d4f2575f1 100644 --- a/winsup/cygwin/timer.cc +++ b/winsup/cygwin/posix_timer.cc @@ -14,65 +14,37 @@ details. */ #include "fhandler.h" #include "dtable.h" #include "cygheap.h" -#include "timer.h" +#include "posix_timer.h" #include -#define EVENT_DISARMED 0 -#define EVENT_ARMED -1 -#define EVENT_LOCK 1 +#define OVR_EVENT_DISARMED 0 +#define OVR_EVENT_ARMED 1 -/* Must not be NO_COPY to avoid memory leak after fork. */ -timer_tracker ttstart (CLOCK_REALTIME, NULL); - -class lock_timer_tracker -{ - static muto protect; -public: - lock_timer_tracker (); - ~lock_timer_tracker (); -}; - -muto NO_COPY lock_timer_tracker::protect; - -lock_timer_tracker::lock_timer_tracker () -{ - protect.init ("timer_protect")->acquire (); -} - -lock_timer_tracker::~lock_timer_tracker () -{ - protect.release (); -} +timer_tracker NO_COPY itimer_tracker (CLOCK_REALTIME, NULL); bool timer_tracker::cancel () { - if (!hcancel) - return false; + DWORD res; - SetEvent (hcancel); - DWORD res = WaitForSingleObject (syncthread, INFINITE); - if (res != WAIT_OBJECT_0) - system_printf ("WFSO returned unexpected value %u, %E", res); + if (!cancel_evt) + return false; + SetEvent (cancel_evt); + if (sync_thr) + { + res = WaitForSingleObject (sync_thr, INFINITE); + if (res != WAIT_OBJECT_0) + system_printf ("WFSO returned unexpected value %u, %E", res); + } return true; } -timer_tracker::~timer_tracker () -{ - if (cancel ()) - { - CloseHandle (hcancel); -#ifdef DEBUGGING - hcancel = NULL; -#endif - } - if (syncthread) - CloseHandle (syncthread); - magic = 0; -} - timer_tracker::timer_tracker (clockid_t c, const sigevent *e) +: magic (TT_MAGIC), clock_id (c), timer (NULL), cancel_evt (NULL), + sync_thr (NULL), interval (0), exp_ts (0), overrun_event_running (0), + overrun_count_curr (0), overrun_count (0) { + srwlock = SRWLOCK_INIT; if (e != NULL) evp = *e; else @@ -81,18 +53,17 @@ timer_tracker::timer_tracker (clockid_t c, const sigevent *e) evp.sigev_signo = SIGALRM; evp.sigev_value.sival_ptr = this; } - clock_id = c; - magic = TT_MAGIC; - hcancel = NULL; - event_running = EVENT_DISARMED; - overrun_count_curr = 0; - overrun_count = 0; - if (this != &ttstart) - { - lock_timer_tracker here; - next = ttstart.next; - ttstart.next = this; - } +} + +timer_tracker::~timer_tracker () +{ + AcquireSRWLockExclusive (&srwlock); + cancel (); + NtClose (cancel_evt); + NtClose (sync_thr); + NtClose (timer); + magic = 0; + ReleaseSRWLockExclusive (&srwlock); } static inline int64_t @@ -105,29 +76,26 @@ timespec_to_us (const timespec& ts) } /* Returns 0 if arming successful, -1 if a signal is already queued. - If so, it also increments overrun_count. */ + If so, it also increments overrun_count. Only call under lock! */ LONG -timer_tracker::arm_event () +timer_tracker::arm_overrun_event () { LONG ret; - while ((ret = InterlockedCompareExchange (&event_running, EVENT_ARMED, - EVENT_DISARMED)) == EVENT_LOCK) - yield (); - if (ret == EVENT_ARMED) - InterlockedIncrement64 (&overrun_count); + ret = InterlockedExchange (&overrun_event_running, OVR_EVENT_ARMED); + if (ret == OVR_EVENT_ARMED) + ret = InterlockedIncrement64 (&overrun_count); return ret; } LONG -timer_tracker::disarm_event () +timer_tracker::disarm_overrun_event () { LONG ret; - while ((ret = InterlockedCompareExchange (&event_running, EVENT_LOCK, - EVENT_ARMED)) == EVENT_LOCK) - yield (); - if (ret == EVENT_ARMED) + AcquireSRWLockExclusive (&srwlock); + ret = InterlockedExchange (&overrun_event_running, OVR_EVENT_DISARMED); + if (ret == OVR_EVENT_ARMED) { LONG64 ov_cnt; @@ -138,8 +106,8 @@ timer_tracker::disarm_event () overrun_count_curr = ov_cnt; ret = overrun_count_curr; InterlockedExchange64 (&overrun_count, 0); - InterlockedExchange (&event_running, EVENT_DISARMED); } + ReleaseSRWLockExclusive (&srwlock); return ret; } @@ -151,57 +119,69 @@ notify_thread_wrapper (void *arg) void * (*notify_func) (void *) = (void * (*) (void *)) evt->sigev_notify_function; - tt->disarm_event (); + tt->disarm_overrun_event (); return notify_func (evt->sigev_value.sival_ptr); } DWORD timer_tracker::thread_func () { - int64_t now; - int64_t cur_sleepto_us = sleepto_us; + HANDLE w4[2] = { timer, cancel_evt }; + + debug_printf ("%p timer armed", this); while (1) { - int64_t sleep_us; - LONG sleep_ms; - /* Account for delays in starting thread - and sending the signal */ - now = get_clock (clock_id)->usecs (); - sleep_us = cur_sleepto_us - now; - if (sleep_us > 0) + switch (WaitForMultipleObjects (2, w4, FALSE, INFINITE)) { - sleepto_us = cur_sleepto_us; - sleep_ms = (sleep_us + (USPERSEC / MSPERSEC) - 1) - / (USPERSEC / MSPERSEC); - } - else - { - int64_t num_intervals = (now - cur_sleepto_us) / interval_us; - InterlockedAdd64 (&overrun_count, num_intervals); - cur_sleepto_us += num_intervals * interval_us; - sleepto_us = cur_sleepto_us; - sleep_ms = 0; - } - - debug_printf ("%p waiting for %u ms", this, sleep_ms); - switch (WaitForSingleObject (hcancel, sleep_ms)) - { - case WAIT_TIMEOUT: - debug_printf ("timed out"); - break; case WAIT_OBJECT_0: - debug_printf ("%p cancelled", this); + debug_printf ("%p timer expired", this); + break; + case WAIT_OBJECT_0 + 1: + debug_printf ("%p timer disarmed, %E", this); goto out; default: debug_printf ("%p wait failed, %E", this); + continue; + } + AcquireSRWLockExclusive (&srwlock); + /* Make sure we haven't been abandoned and/or disarmed in the meantime */ + if (exp_ts == 0 && interval == 0) + { + ReleaseSRWLockExclusive (&srwlock); goto out; } + if (interval) + { + /* Compute expiration count. */ + LONG64 now = get_clock_now (); + LONG64 ts = get_exp_ts (); + LONG64 exp_cnt; + /* Make concessions for unexact realtime clock */ + if (ts > now) + ts = now - 1; + exp_cnt = (now - ts) / interval; + InterlockedAdd64 (&overrun_count, exp_cnt); + ts += interval * exp_cnt; + set_exp_ts (ts); + /* NtSetTimer allows periods of up to 24 days only. If the time + is longer, we set the timer up as one-shot timer for each + interval. Restart timer here with new due time. */ + if (interval > INT_MAX * (NS100PERSEC / MSPERSEC)) + { + /* TODO: CLOCK_REALTIME_ALARM / CLOCK_BOOTTIME_ALARM + See comment in arm_timer */ + BOOL Resume = FALSE; + LARGE_INTEGER DueTime = { QuadPart: -interval }; + + NtSetTimer (timer, &DueTime, NULL, NULL, Resume, 0, NULL); + } + } switch (evp.sigev_notify) { case SIGEV_SIGNAL: { - if (arm_event ()) + if (arm_overrun_event ()) { debug_printf ("%p timer signal already queued", this); break; @@ -217,7 +197,7 @@ timer_tracker::thread_func () } case SIGEV_THREAD: { - if (arm_event ()) + if (arm_overrun_event ()) { debug_printf ("%p timer thread already queued", this); break; @@ -243,10 +223,16 @@ timer_tracker::thread_func () break; } } - if (!interval_us) - break; - - cur_sleepto_us = sleepto_us + interval_us; + /* one-shot timer? */ + if (!interval) + { + memset (&time_spec, 0, sizeof time_spec); + exp_ts = 0; + overrun_event_running = OVR_EVENT_DISARMED; + ReleaseSRWLockExclusive (&srwlock); + goto out; + } + ReleaseSRWLockExclusive (&srwlock); debug_printf ("looping"); } @@ -262,58 +248,166 @@ timer_thread (VOID *x) return tt->thread_func (); } -static inline bool -timespec_bad (const timespec& t) +int +timer_tracker::gettime (itimerspec *curr_value, bool lock) { - if (t.tv_nsec < 0 || t.tv_nsec >= NSPERSEC || t.tv_sec < 0) + if (lock) { - set_errno (EINVAL); - return true; + AcquireSRWLockExclusive (&srwlock); + if (!is_timer_tracker ()) + { + ReleaseSRWLockExclusive (&srwlock); + return -EINVAL; + } } - return false; + if (!cancel_evt) + memset (curr_value, 0, sizeof (*curr_value)); + else + { + LONG64 next_relative_exp = get_exp_ts () - get_clock_now (); + curr_value->it_value.tv_sec = next_relative_exp / NS100PERSEC; + next_relative_exp -= curr_value->it_value.tv_sec * NS100PERSEC; + curr_value->it_value.tv_nsec = next_relative_exp + * (NSPERSEC / NS100PERSEC); + curr_value->it_interval = time_spec.it_interval; + } + if (lock) + ReleaseSRWLockExclusive (&srwlock); + return 0; } int -timer_tracker::settime (int in_flags, const itimerspec *value, itimerspec *ovalue) +timer_tracker::settime (int flags, const itimerspec *new_value, + itimerspec *old_value) { int ret = -1; __try { - if (!value) + if (!new_value || !valid_timespec (new_value->it_value) + || !valid_timespec (new_value->it_interval)) { - set_errno (EINVAL); + ret = -EINVAL; __leave; } - if (timespec_bad (value->it_value) || timespec_bad (value->it_interval)) - __leave; + AcquireSRWLockExclusive (&srwlock); + if (!is_timer_tracker ()) + { + ReleaseSRWLockExclusive (&srwlock); + ret = -EINVAL; + __leave; + } - lock_timer_tracker here; - cancel (); + if (old_value) + gettime (old_value, false); - if (ovalue) - gettime (ovalue); - - if (!value->it_value.tv_sec && !value->it_value.tv_nsec) - interval_us = sleepto_us = 0; + if (!new_value->it_value.tv_sec && !new_value->it_value.tv_nsec) + { + cancel (); + memset (&time_spec, 0, sizeof time_spec); + interval = 0; + exp_ts = 0; + } else { - interval_us = timespec_to_us (value->it_interval); - sleepto_us = timespec_to_us (value->it_value); - if (!(in_flags & TIMER_ABSTIME)) - sleepto_us += get_clock (clock_id)->usecs (); - it_interval = value->it_interval; - if (!hcancel) - hcancel = CreateEvent (&sec_none_nih, TRUE, FALSE, NULL); + LONG64 ts; + LARGE_INTEGER DueTime; + BOOLEAN Resume; + LONG Period; + NTSTATUS status; + + if (!timer) + { + OBJECT_ATTRIBUTES attr; + + InitializeObjectAttributes (&attr, NULL, 0, NULL, + sec_none_nih.lpSecurityDescriptor); + status = NtCreateEvent (&cancel_evt, EVENT_ALL_ACCESS, &attr, + NotificationEvent, FALSE); + if (!NT_SUCCESS (status)) + { + ret = -geterrno_from_nt_status (status); + __leave; + } + status = NtCreateEvent (&sync_thr, EVENT_ALL_ACCESS, &attr, + NotificationEvent, FALSE); + if (!NT_SUCCESS (status)) + { + NtClose (cancel_evt); + cancel_evt = NULL; + ret = -geterrno_from_nt_status (status); + __leave; + } + status = NtCreateTimer (&timer, TIMER_ALL_ACCESS, &attr, + SynchronizationTimer); + if (!NT_SUCCESS (status)) + { + NtClose (cancel_evt); + NtClose (sync_thr); + cancel_evt = sync_thr = NULL; + ret = -geterrno_from_nt_status (status); + __leave; + } + } + ResetEvent (cancel_evt); + ResetEvent (sync_thr); + NtCancelTimer (timer, NULL); + /* Convert incoming itimerspec into 100ns interval and timestamp */ + interval = new_value->it_interval.tv_sec * NS100PERSEC + + (new_value->it_interval.tv_nsec + + (NSPERSEC / NS100PERSEC) - 1) + / (NSPERSEC / NS100PERSEC); + ts = new_value->it_value.tv_sec * NS100PERSEC + + (new_value->it_value.tv_nsec + (NSPERSEC / NS100PERSEC) - 1) + / (NSPERSEC / NS100PERSEC); + if (flags & TIMER_ABSTIME) + { + if (clock_id == CLOCK_REALTIME) + DueTime.QuadPart = ts + FACTOR; + else /* non-REALTIME clocks require relative DueTime. */ + { + DueTime.QuadPart = get_clock_now () - ts; + /* If the timestamp was earlier than now, compute number + of expirations and offset DueTime to expire immediately. */ + if (DueTime.QuadPart >= 0) + DueTime.QuadPart = -1LL; + } + } else - ResetEvent (hcancel); - if (!syncthread) - syncthread = CreateEvent (&sec_none_nih, TRUE, FALSE, NULL); + { + /* Keep relative timestamps relative for the timer, but store the + expiry timestamp absolute for the timer thread. */ + DueTime.QuadPart = -ts; + ts += get_clock_now (); + } + set_exp_ts (ts); + time_spec = *new_value; + overrun_count_curr = 0; + overrun_count = 0; + overrun_event_running = OVR_EVENT_DISARMED; + /* TODO: CLOCK_REALTIME_ALARM / CLOCK_BOOTTIME_ALARM + Note: Advanced Power Settings -> Sleep -> Allow Wake Timers + since W10 1709 */ + Resume = FALSE; + if (interval > INT_MAX * (NS100PERSEC / MSPERSEC)) + Period = 0; else - ResetEvent (syncthread); - new cygthread (timer_thread, this, "itimer", syncthread); + Period = (interval + (NS100PERSEC / MSPERSEC) - 1) + / (NS100PERSEC / MSPERSEC); + status = NtSetTimer (timer, &DueTime, NULL, NULL, Resume, Period, + NULL); + if (!NT_SUCCESS (status)) + { + memset (&time_spec, 0, sizeof time_spec); + interval = 0; + exp_ts = 0; + ret = -geterrno_from_nt_status (status); + __leave; + } + new cygthread (timer_thread, this, "itimer", sync_thr); } + ReleaseSRWLockExclusive (&srwlock); ret = 0; } __except (EFAULT) {} @@ -321,78 +415,12 @@ timer_tracker::settime (int in_flags, const itimerspec *value, itimerspec *ovalu return ret; } -void -timer_tracker::gettime (itimerspec *ovalue) -{ - if (!hcancel) - memset (ovalue, 0, sizeof (*ovalue)); - else - { - ovalue->it_interval = it_interval; - int64_t now = get_clock (clock_id)->usecs (); - int64_t left_us = sleepto_us - now; - if (left_us < 0) - left_us = 0; - ovalue->it_value.tv_sec = left_us / USPERSEC; - ovalue->it_value.tv_nsec = (left_us % USPERSEC) * (NSPERSEC/USPERSEC); - } -} - -int -timer_tracker::clean_and_unhook () -{ - for (timer_tracker *tt = &ttstart; tt->next != NULL; tt = tt->next) - if (tt->next == this) - { - tt->next = this->next; - return 0; - } - return -1; -} - -void -timer_tracker::fixup_after_fork () -{ - ttstart.hcancel = ttstart.syncthread = NULL; - ttstart.event_running = EVENT_DISARMED; - ttstart.overrun_count_curr = 0; - ttstart.overrun_count = 0; - for (timer_tracker *tt = &ttstart; tt->next != NULL; /* nothing */) - { - timer_tracker *deleteme = tt->next; - tt->next = deleteme->next; - deleteme->hcancel = deleteme->syncthread = NULL; - delete deleteme; - } -} - -void -fixup_timers_after_fork () -{ - timer_tracker::fixup_after_fork (); -} - -extern "C" int -timer_gettime (timer_t timerid, struct itimerspec *ovalue) -{ - int ret = -1; - - __try - { - timer_tracker *tt = (timer_tracker *) timerid; - if (!tt->is_timer_tracker ()) - { - set_errno (EINVAL); - return -1; - } - - tt->gettime (ovalue); - ret = 0; - } - __except (EFAULT) {} - __endtry - return ret; -} +/* The timers are stored on the cygheap. */ +#define cnew(name, ...) \ + ({ \ + void* ptr = (void*) ccalloc (HEAP_3_TIMER, 1, sizeof (name)); \ + ptr ? new (ptr) name (__VA_ARGS__) : NULL; \ + }) extern "C" int timer_create (clockid_t clock_id, struct sigevent *__restrict evp, @@ -414,7 +442,7 @@ timer_create (clockid_t clock_id, struct sigevent *__restrict evp, return -1; } - *timerid = (timer_t) new timer_tracker (clock_id, evp); + *timerid = (timer_t) cnew (timer_tracker, clock_id, evp); ret = 0; } __except (EFAULT) {} @@ -422,6 +450,29 @@ timer_create (clockid_t clock_id, struct sigevent *__restrict evp, return ret; } +extern "C" int +timer_gettime (timer_t timerid, struct itimerspec *ovalue) +{ + int ret = -1; + + __try + { + timer_tracker *tt = (timer_tracker *) timerid; + if (!tt->is_timer_tracker ()) + { + set_errno (EINVAL); + return -1; + } + + ret = tt->gettime (ovalue, true); + if (ret < 0) + set_errno (-ret); + } + __except (EFAULT) {} + __endtry + return ret; +} + extern "C" int timer_settime (timer_t timerid, int flags, const struct itimerspec *__restrict value, @@ -438,6 +489,8 @@ timer_settime (timer_t timerid, int flags, __leave; } ret = tt->settime (flags, value, ovalue); + if (ret < 0) + set_errno (-ret); } __except (EFAULT) {} __endtry @@ -476,20 +529,12 @@ timer_delete (timer_t timerid) __try { timer_tracker *in_tt = (timer_tracker *) timerid; - if (!in_tt->is_timer_tracker ()) + if (!in_tt->is_timer_tracker () || in_tt == &itimer_tracker) { set_errno (EINVAL); __leave; } - - lock_timer_tracker here; - if (in_tt->clean_and_unhook () == 0) - { - delete in_tt; - ret = 0; - } - else - set_errno (EINVAL); + delete in_tt; } __except (EFAULT) {} __endtry @@ -513,7 +558,8 @@ setitimer (int which, const struct itimerval *__restrict value, spec_value.it_interval.tv_nsec = value->it_interval.tv_usec * 1000; spec_value.it_value.tv_sec = value->it_value.tv_sec; spec_value.it_value.tv_nsec = value->it_value.tv_usec * 1000; - ret = timer_settime ((timer_t) &ttstart, 0, &spec_value, &spec_ovalue); + ret = timer_settime ((timer_t) &itimer_tracker, 0, + &spec_value, &spec_ovalue); if (ret) ret = -1; else if (ovalue) @@ -541,7 +587,7 @@ getitimer (int which, struct itimerval *ovalue) __try { struct itimerspec spec_ovalue; - ret = timer_gettime ((timer_t) &ttstart, &spec_ovalue); + ret = timer_gettime ((timer_t) &itimer_tracker, &spec_ovalue); if (!ret) { ovalue->it_interval.tv_sec = spec_ovalue.it_interval.tv_sec; @@ -567,7 +613,7 @@ alarm (unsigned int seconds) if (seconds > (CLOCK_DELAY_MAX / 1000 - 1)) seconds = (CLOCK_DELAY_MAX / 1000 - 1); newt.it_value.tv_sec = seconds; - timer_settime ((timer_t) &ttstart, 0, &newt, &oldt); + timer_settime ((timer_t) &itimer_tracker, 0, &newt, &oldt); int ret = oldt.it_value.tv_sec + (oldt.it_value.tv_nsec > 0); syscall_printf ("%d = alarm(%u)", ret, seconds); return ret; @@ -589,7 +635,7 @@ ualarm (useconds_t value, useconds_t interval) timer.it_interval.tv_sec = interval / USPERSEC; timer.it_interval.tv_nsec = (interval % USPERSEC) * (NSPERSEC/USPERSEC); } - timer_settime ((timer_t) &ttstart, 0, &timer, &otimer); + timer_settime ((timer_t) &itimer_tracker, 0, &timer, &otimer); useconds_t ret = otimer.it_value.tv_sec * USPERSEC + (otimer.it_value.tv_nsec + (NSPERSEC/USPERSEC) - 1) / (NSPERSEC/USPERSEC); diff --git a/winsup/cygwin/timer.h b/winsup/cygwin/posix_timer.h similarity index 58% rename from winsup/cygwin/timer.h rename to winsup/cygwin/posix_timer.h index dd5b165c7..04a383fd6 100644 --- a/winsup/cygwin/timer.h +++ b/winsup/cygwin/posix_timer.h @@ -13,38 +13,43 @@ details. */ class timer_tracker { unsigned magic; - timer_tracker *next; - + SRWLOCK srwlock; clockid_t clock_id; sigevent evp; - timespec it_interval; - HANDLE hcancel; - HANDLE syncthread; - int64_t interval_us; - int64_t sleepto_us; - LONG event_running; + struct itimerspec time_spec; + HANDLE timer; + HANDLE cancel_evt; + HANDLE sync_thr; + LONG64 interval; + LONG64 exp_ts; + LONG overrun_event_running; LONG overrun_count_curr; LONG64 overrun_count; bool cancel (); public: + void *operator new (size_t, void *p) __attribute__ ((nothrow)) {return p;} + void operator delete (void *p) { cfree (p); } timer_tracker (clockid_t, const sigevent *); ~timer_tracker (); inline bool is_timer_tracker () const { return magic == TT_MAGIC; } inline sigevent_t *sigevt () { return &evp; } inline int getoverrun () const { return overrun_count_curr; } - void gettime (itimerspec *); + LONG64 get_clock_now () const { return get_clock (clock_id)->n100secs (); } + LONG64 get_exp_ts () const { return exp_ts; } + LONG64 get_interval () const { return interval; } + void set_exp_ts (LONG64 ts) { exp_ts = ts; } + + LONG arm_overrun_event (); + LONG disarm_overrun_event (); + + int gettime (itimerspec *, bool); int settime (int, const itimerspec *, itimerspec *); - int clean_and_unhook (); - LONG arm_event (); - LONG disarm_event (); DWORD thread_func (); static void fixup_after_fork (); }; -extern void fixup_timers_after_fork (); - #endif /* __TIMER_H__ */ diff --git a/winsup/cygwin/signal.cc b/winsup/cygwin/signal.cc index fdde26058..abefedd7b 100644 --- a/winsup/cygwin/signal.cc +++ b/winsup/cygwin/signal.cc @@ -21,7 +21,7 @@ details. */ #include "dtable.h" #include "cygheap.h" #include "cygwait.h" -#include "timer.h" +#include "posix_timer.h" #define _SA_NORESTART 0x8000 @@ -619,7 +619,7 @@ sigwait_common (const sigset_t *set, siginfo_t *info, PLARGE_INTEGER waittime) { timer_tracker *tt = (timer_tracker *) _my_tls.infodata.si_tid; - _my_tls.infodata.si_overrun = tt->disarm_event (); + _my_tls.infodata.si_overrun = tt->disarm_overrun_event (); } if (info) *info = _my_tls.infodata; From 13ea67a3c63990f203abc1d20a5a1f81e3ec163f Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Tue, 22 Jan 2019 15:39:39 +0100 Subject: [PATCH 129/475] time.h: Add CLOCK_REALTIME_ALARM/CLOCK_BOOTTIME_ALARM Slightly reshuffle and add comment Signed-off-by: Corinna Vinschen --- newlib/libc/include/time.h | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/newlib/libc/include/time.h b/newlib/libc/include/time.h index bd35d0e02..d69d19969 100644 --- a/newlib/libc/include/time.h +++ b/newlib/libc/include/time.h @@ -249,6 +249,11 @@ extern "C" { /* thread shall not have a CPU-time clock */ /* accessible. */ +/* Flag indicating time is "absolute" with respect to the clock + associated with a time. Value 4 is historic. */ + +#define TIMER_ABSTIME 4 + /* Manifest Constants, P1003.1b-1993, p. 262 */ #if __GNU_VISIBLE @@ -257,11 +262,6 @@ extern "C" { #define CLOCK_REALTIME ((clockid_t) 1) -/* Flag indicating time is "absolute" with respect to the clock - associated with a time. */ - -#define TIMER_ABSTIME 4 - /* Manifest Constants, P1003.4b/D8, p. 55 */ #if defined(_POSIX_CPUTIME) @@ -287,11 +287,13 @@ extern "C" { #if defined(_POSIX_MONOTONIC_CLOCK) /* The identifier for the system-wide monotonic clock, which is defined - * as a clock whose value cannot be set via clock_settime() and which - * cannot have backward clock jumps. */ + * as a clock whose value cannot be set via clock_settime() and which + * cannot have backward clock jumps. */ #define CLOCK_MONOTONIC ((clockid_t) 4) +#endif + #if __GNU_VISIBLE #define CLOCK_MONOTONIC_RAW ((clockid_t) 5) @@ -300,7 +302,9 @@ extern "C" { #define CLOCK_BOOTTIME ((clockid_t) 7) -#endif +#define CLOCK_REALTIME_ALARM ((clockid_t) 8) + +#define CLOCK_BOOTTIME_ALARM ((clockid_t) 9) #endif From 1daece586130467b632f7011395c514b6d8811f8 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Tue, 22 Jan 2019 15:42:07 +0100 Subject: [PATCH 130/475] Cygwin: clocks: Add CLOCK_REALTIME_ALARM/CLOCK_BOOTTIME_ALARM clocks Signed-off-by: Corinna Vinschen --- winsup/cygwin/clock.cc | 4 ++++ winsup/cygwin/clock.h | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/winsup/cygwin/clock.cc b/winsup/cygwin/clock.cc index 18d628884..9c0b787ba 100644 --- a/winsup/cygwin/clock.cc +++ b/winsup/cygwin/clock.cc @@ -274,6 +274,8 @@ static clk_monotonic_t clk_monotonic; static clk_monotonic_t clk_monotonic_raw; /* same as clk_monotonic */ static clk_monotonic_coarse_t clk_monotonic_coarse; static clk_boottime_t clk_boottime; +static clk_realtime_t clk_realtime_alarm; /* same as clk_realtime */ +static clk_boottime_t clk_boottime_alarm; /* same as clk_boottime_t */ clk_t *cyg_clock[MAX_CLOCKS] = { @@ -285,6 +287,8 @@ clk_t *cyg_clock[MAX_CLOCKS] = &clk_monotonic_raw, &clk_monotonic_coarse, &clk_boottime, + &clk_realtime_alarm, + &clk_boottime_alarm, }; clk_t * diff --git a/winsup/cygwin/clock.h b/winsup/cygwin/clock.h index 538b4b284..7323299df 100644 --- a/winsup/cygwin/clock.h +++ b/winsup/cygwin/clock.h @@ -12,7 +12,7 @@ details. */ #include /* Must be a power of 2. */ -#define MAX_CLOCKS (8) +#define MAX_CLOCKS (16) /* Conversions for per-process and per-thread clocks */ #define CLOCKID(cid) \ From 013e2bd9ecf85a8e7c94459aae17ad6d03bbcc31 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Tue, 22 Jan 2019 15:45:58 +0100 Subject: [PATCH 131/475] Cygwin: posix timers: Add support for CLOCK_REALTIME_ALARM/CLOCK_BOOTTIME_ALARM Signed-off-by: Corinna Vinschen --- winsup/cygwin/posix_timer.cc | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/winsup/cygwin/posix_timer.cc b/winsup/cygwin/posix_timer.cc index d4f2575f1..8651c226c 100644 --- a/winsup/cygwin/posix_timer.cc +++ b/winsup/cygwin/posix_timer.cc @@ -169,9 +169,8 @@ timer_tracker::thread_func () interval. Restart timer here with new due time. */ if (interval > INT_MAX * (NS100PERSEC / MSPERSEC)) { - /* TODO: CLOCK_REALTIME_ALARM / CLOCK_BOOTTIME_ALARM - See comment in arm_timer */ - BOOL Resume = FALSE; + BOOLEAN Resume = (clock_id == CLOCK_REALTIME_ALARM + || clock_id == CLOCK_BOOTTIME_ALARM); LARGE_INTEGER DueTime = { QuadPart: -interval }; NtSetTimer (timer, &DueTime, NULL, NULL, Resume, 0, NULL); @@ -386,10 +385,10 @@ timer_tracker::settime (int flags, const itimerspec *new_value, overrun_count_curr = 0; overrun_count = 0; overrun_event_running = OVR_EVENT_DISARMED; - /* TODO: CLOCK_REALTIME_ALARM / CLOCK_BOOTTIME_ALARM - Note: Advanced Power Settings -> Sleep -> Allow Wake Timers - since W10 1709 */ - Resume = FALSE; + /* Note: Advanced Power Settings -> Sleep -> Allow Wake Timers + since W10 1709 */ + Resume = (clock_id == CLOCK_REALTIME_ALARM + || clock_id == CLOCK_BOOTTIME_ALARM); if (interval > INT_MAX * (NS100PERSEC / MSPERSEC)) Period = 0; else From 6c44af8179f71a4355659008e1a58c793171e17d Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Tue, 22 Jan 2019 15:46:17 +0100 Subject: [PATCH 132/475] Cygwin: timerfd: Add support for CLOCK_REALTIME_ALARM/CLOCK_BOOTTIME_ALARM Signed-off-by: Corinna Vinschen --- winsup/cygwin/release/2.12.0 | 3 ++- winsup/cygwin/timerfd.cc | 11 +++++------ winsup/doc/new-features.xml | 3 ++- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/winsup/cygwin/release/2.12.0 b/winsup/cygwin/release/2.12.0 index 80d0c6fba..ba911ee54 100644 --- a/winsup/cygwin/release/2.12.0 +++ b/winsup/cygwin/release/2.12.0 @@ -2,7 +2,8 @@ What's new: ----------- - Support for CLOCK_REALTIME_COARSE, CLOCK_MONOTONIC_COARSE, - CLOCK_MONOTONIC_RAW, CLOCK_BOOTTIME clocks. + CLOCK_MONOTONIC_RAW, CLOCK_BOOTTIME, CLOCK_REALTIME_ALARM, + CLOCK_BOOTTIME_ALARM clocks. - Support for case sensitive directories. mkdir(2) automatically creates directories within the Cygwin installation dir as case diff --git a/winsup/cygwin/timerfd.cc b/winsup/cygwin/timerfd.cc index 87074fd6f..dc404883e 100644 --- a/winsup/cygwin/timerfd.cc +++ b/winsup/cygwin/timerfd.cc @@ -173,9 +173,8 @@ timerfd_tracker::thread_func () interval. Restart timer here with new due time. */ if (get_interval () > INT_MAX * (NS100PERSEC / MSPERSEC)) { - /* TODO: CLOCK_REALTIME_ALARM / CLOCK_BOOTTIME_ALARM - See comment in arm_timer */ - BOOL Resume = FALSE; + BOOLEAN Resume = (get_clockid () == CLOCK_REALTIME_ALARM + || get_clockid () == CLOCK_BOOTTIME_ALARM); LARGE_INTEGER DueTime = { QuadPart: -get_interval () }; NtSetTimer (tfd_shared->timer (), &DueTime, NULL, NULL, @@ -573,10 +572,10 @@ timerfd_shared::arm_timer (int flags, const struct itimerspec *new_value) set_exp_ts (ts); time_spec () = *new_value; read_and_reset_expiration_count (); - /* TODO: CLOCK_REALTIME_ALARM / CLOCK_BOOTTIME_ALARM - Note: Advanced Power Settings -> Sleep -> Allow Wake Timers + /* Note: Advanced Power Settings -> Sleep -> Allow Wake Timers since W10 1709 */ - Resume = FALSE; + Resume = (_clockid == CLOCK_REALTIME_ALARM + || _clockid == CLOCK_BOOTTIME_ALARM); if (_interval > INT_MAX * (NS100PERSEC / MSPERSEC)) Period = 0; else diff --git a/winsup/doc/new-features.xml b/winsup/doc/new-features.xml index 2c4b3e43f..a1799d08b 100644 --- a/winsup/doc/new-features.xml +++ b/winsup/doc/new-features.xml @@ -10,7 +10,8 @@ Support for CLOCK_REALTIME_COARSE, CLOCK_MONOTONIC_COARSE, -CLOCK_MONOTONIC_RAW, CLOCK_BOOTTIME clocks. +CLOCK_MONOTONIC_RAW, CLOCK_BOOTTIME, CLOCK_REALTIME_ALARM, +CLOCK_BOOTTIME_ALARM clocks. From 83c51fffe6bad36a7143c30946ac5445f9ca4c56 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Tue, 22 Jan 2019 16:22:45 +0100 Subject: [PATCH 133/475] Cygwin: posix timers: allocate timer_tracker on system heap. Allocating on the cygheap would copy information of the tracker into the child process. A forked child knows the timer id and could simply still access the (free'd but still valid) timer_tracker on the heap, which is dangerous and very certainly doesn't reflect POSIX semantics. Signed-off-by: Corinna Vinschen --- winsup/cygwin/cygheap_malloc.h | 3 +-- winsup/cygwin/posix_timer.cc | 5 +++-- winsup/cygwin/posix_timer.h | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/winsup/cygwin/cygheap_malloc.h b/winsup/cygwin/cygheap_malloc.h index cd545c35d..74f0bb619 100644 --- a/winsup/cygwin/cygheap_malloc.h +++ b/winsup/cygwin/cygheap_malloc.h @@ -34,8 +34,7 @@ enum cygheap_types HEAP_2_DLL, HEAP_MMAP, HEAP_2_MAX = 200, - HEAP_3_FHANDLER, - HEAP_3_TIMER + HEAP_3_FHANDLER }; extern "C" { diff --git a/winsup/cygwin/posix_timer.cc b/winsup/cygwin/posix_timer.cc index 8651c226c..e969dcc78 100644 --- a/winsup/cygwin/posix_timer.cc +++ b/winsup/cygwin/posix_timer.cc @@ -414,10 +414,11 @@ timer_tracker::settime (int flags, const itimerspec *new_value, return ret; } -/* The timers are stored on the cygheap. */ +/* The timers are stored on the system heap in order to avoid accidental + leaking of timer ids into the child process. */ #define cnew(name, ...) \ ({ \ - void* ptr = (void*) ccalloc (HEAP_3_TIMER, 1, sizeof (name)); \ + void* ptr = (void*) HeapAlloc (GetProcessHeap (), 0, sizeof (name)); \ ptr ? new (ptr) name (__VA_ARGS__) : NULL; \ }) diff --git a/winsup/cygwin/posix_timer.h b/winsup/cygwin/posix_timer.h index 04a383fd6..f69a179c3 100644 --- a/winsup/cygwin/posix_timer.h +++ b/winsup/cygwin/posix_timer.h @@ -30,7 +30,7 @@ class timer_tracker public: void *operator new (size_t, void *p) __attribute__ ((nothrow)) {return p;} - void operator delete (void *p) { cfree (p); } + void operator delete (void *p) { HeapFree (GetProcessHeap (), 0, p); } timer_tracker (clockid_t, const sigevent *); ~timer_tracker (); inline bool is_timer_tracker () const { return magic == TT_MAGIC; } From de0ec284a3aeb31601383c507904ddaf755854f6 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Tue, 22 Jan 2019 16:37:15 +0100 Subject: [PATCH 134/475] Cygwin: posix timers: fix error handling in public API Signed-off-by: Corinna Vinschen --- winsup/cygwin/posix_timer.cc | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/winsup/cygwin/posix_timer.cc b/winsup/cygwin/posix_timer.cc index e969dcc78..5f569b6de 100644 --- a/winsup/cygwin/posix_timer.cc +++ b/winsup/cygwin/posix_timer.cc @@ -433,17 +433,20 @@ timer_create (clockid_t clock_id, struct sigevent *__restrict evp, if (CLOCKID_IS_PROCESS (clock_id) || CLOCKID_IS_THREAD (clock_id)) { set_errno (ENOTSUP); - return -1; + __leave; } if (clock_id >= MAX_CLOCKS) { set_errno (EINVAL); - return -1; + __leave; } *timerid = (timer_t) cnew (timer_tracker, clock_id, evp); - ret = 0; + if (!*timerid) + __seterrno (); + else + ret = 0; } __except (EFAULT) {} __endtry @@ -461,12 +464,15 @@ timer_gettime (timer_t timerid, struct itimerspec *ovalue) if (!tt->is_timer_tracker ()) { set_errno (EINVAL); - return -1; + __leave; } ret = tt->gettime (ovalue, true); if (ret < 0) - set_errno (-ret); + { + set_errno (-ret); + ret = -1; + } } __except (EFAULT) {} __endtry @@ -490,7 +496,10 @@ timer_settime (timer_t timerid, int flags, } ret = tt->settime (flags, value, ovalue); if (ret < 0) - set_errno (-ret); + { + set_errno (-ret); + ret = -1; + } } __except (EFAULT) {} __endtry From 1f10a00ba717b22b154205508e60af0dcb641ed3 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Tue, 22 Jan 2019 18:20:18 +0100 Subject: [PATCH 135/475] Cygwin: posix timers: fix overrun count always being 1 too big Combine with a bit of cleanup: - Drop overrun_event_running in favor of overrun_count being -1. - Fix include guard in posix_timer.h. - Drop ununsed function timespec_to_us. - Don't use Interlocked functions without need. Signed-off-by: Corinna Vinschen --- winsup/cygwin/posix_timer.cc | 49 +++++++++++++----------------------- winsup/cygwin/posix_timer.h | 9 +++---- 2 files changed, 21 insertions(+), 37 deletions(-) diff --git a/winsup/cygwin/posix_timer.cc b/winsup/cygwin/posix_timer.cc index 5f569b6de..a76ba0694 100644 --- a/winsup/cygwin/posix_timer.cc +++ b/winsup/cygwin/posix_timer.cc @@ -17,8 +17,7 @@ details. */ #include "posix_timer.h" #include -#define OVR_EVENT_DISARMED 0 -#define OVR_EVENT_ARMED 1 +#define OVR_DISARMED -1LL timer_tracker NO_COPY itimer_tracker (CLOCK_REALTIME, NULL); @@ -34,15 +33,15 @@ timer_tracker::cancel () { res = WaitForSingleObject (sync_thr, INFINITE); if (res != WAIT_OBJECT_0) - system_printf ("WFSO returned unexpected value %u, %E", res); + debug_printf ("WFSO returned unexpected value %u, %E", res); } return true; } timer_tracker::timer_tracker (clockid_t c, const sigevent *e) : magic (TT_MAGIC), clock_id (c), timer (NULL), cancel_evt (NULL), - sync_thr (NULL), interval (0), exp_ts (0), overrun_event_running (0), - overrun_count_curr (0), overrun_count (0) + sync_thr (NULL), interval (0), exp_ts (0), overrun_count_curr (0), + overrun_count (OVR_DISARMED) { srwlock = SRWLOCK_INIT; if (e != NULL) @@ -66,25 +65,14 @@ timer_tracker::~timer_tracker () ReleaseSRWLockExclusive (&srwlock); } -static inline int64_t -timespec_to_us (const timespec& ts) -{ - int64_t res = ts.tv_sec; - res *= USPERSEC; - res += (ts.tv_nsec + (NSPERSEC/USPERSEC) - 1) / (NSPERSEC/USPERSEC); - return res; -} - /* Returns 0 if arming successful, -1 if a signal is already queued. If so, it also increments overrun_count. Only call under lock! */ -LONG -timer_tracker::arm_overrun_event () +bool +timer_tracker::arm_overrun_event (LONG64 exp_cnt) { - LONG ret; + bool ret = (overrun_count != OVR_DISARMED); - ret = InterlockedExchange (&overrun_event_running, OVR_EVENT_ARMED); - if (ret == OVR_EVENT_ARMED) - ret = InterlockedIncrement64 (&overrun_count); + overrun_count += exp_cnt; return ret; } @@ -94,18 +82,17 @@ timer_tracker::disarm_overrun_event () LONG ret; AcquireSRWLockExclusive (&srwlock); - ret = InterlockedExchange (&overrun_event_running, OVR_EVENT_DISARMED); - if (ret == OVR_EVENT_ARMED) + if (overrun_count != OVR_DISARMED) { LONG64 ov_cnt; - InterlockedExchange64 (&ov_cnt, overrun_count); + ov_cnt = overrun_count; if (ov_cnt > DELAYTIMER_MAX || ov_cnt < 0) overrun_count_curr = DELAYTIMER_MAX; else overrun_count_curr = ov_cnt; ret = overrun_count_curr; - InterlockedExchange64 (&overrun_count, 0); + overrun_count = OVR_DISARMED; } ReleaseSRWLockExclusive (&srwlock); return ret; @@ -150,18 +137,17 @@ timer_tracker::thread_func () ReleaseSRWLockExclusive (&srwlock); goto out; } + LONG64 exp_cnt = 0; if (interval) { /* Compute expiration count. */ LONG64 now = get_clock_now (); LONG64 ts = get_exp_ts (); - LONG64 exp_cnt; /* Make concessions for unexact realtime clock */ if (ts > now) ts = now - 1; - exp_cnt = (now - ts) / interval; - InterlockedAdd64 (&overrun_count, exp_cnt); + exp_cnt = (now - ts + interval - 1) / interval; ts += interval * exp_cnt; set_exp_ts (ts); /* NtSetTimer allows periods of up to 24 days only. If the time @@ -180,7 +166,7 @@ timer_tracker::thread_func () { case SIGEV_SIGNAL: { - if (arm_overrun_event ()) + if (arm_overrun_event (exp_cnt)) { debug_printf ("%p timer signal already queued", this); break; @@ -196,7 +182,7 @@ timer_tracker::thread_func () } case SIGEV_THREAD: { - if (arm_overrun_event ()) + if (arm_overrun_event (exp_cnt)) { debug_printf ("%p timer thread already queued", this); break; @@ -227,7 +213,7 @@ timer_tracker::thread_func () { memset (&time_spec, 0, sizeof time_spec); exp_ts = 0; - overrun_event_running = OVR_EVENT_DISARMED; + overrun_count = OVR_DISARMED; ReleaseSRWLockExclusive (&srwlock); goto out; } @@ -383,8 +369,7 @@ timer_tracker::settime (int flags, const itimerspec *new_value, set_exp_ts (ts); time_spec = *new_value; overrun_count_curr = 0; - overrun_count = 0; - overrun_event_running = OVR_EVENT_DISARMED; + overrun_count = OVR_DISARMED; /* Note: Advanced Power Settings -> Sleep -> Allow Wake Timers since W10 1709 */ Resume = (clock_id == CLOCK_REALTIME_ALARM diff --git a/winsup/cygwin/posix_timer.h b/winsup/cygwin/posix_timer.h index f69a179c3..e1cfe84c7 100644 --- a/winsup/cygwin/posix_timer.h +++ b/winsup/cygwin/posix_timer.h @@ -6,8 +6,8 @@ This software is a copyrighted work licensed under the terms of the Cygwin license. Please consult the file "CYGWIN_LICENSE" for details. */ -#ifndef __TIMER_H__ -#define __TIMER_H__ +#ifndef __POSIX_TIMER_H__ +#define __POSIX_TIMER_H__ #define TT_MAGIC 0x513e4a1c class timer_tracker @@ -22,7 +22,6 @@ class timer_tracker HANDLE sync_thr; LONG64 interval; LONG64 exp_ts; - LONG overrun_event_running; LONG overrun_count_curr; LONG64 overrun_count; @@ -42,7 +41,7 @@ class timer_tracker LONG64 get_interval () const { return interval; } void set_exp_ts (LONG64 ts) { exp_ts = ts; } - LONG arm_overrun_event (); + bool arm_overrun_event (LONG64); LONG disarm_overrun_event (); int gettime (itimerspec *, bool); @@ -52,4 +51,4 @@ class timer_tracker static void fixup_after_fork (); }; -#endif /* __TIMER_H__ */ +#endif /* __POSIX_TIMER_H__ */ From b14a879d85b171960df789ac8ba2332004f838e0 Mon Sep 17 00:00:00 2001 From: Jozef Lawrynowicz Date: Thu, 6 Dec 2018 16:14:01 +0000 Subject: [PATCH 136/475] Remove matherr, and SVID and X/Open math library configurations Default math library configuration is now IEEE --- newlib/libc/include/math.h | 39 -- newlib/libc/machine/necv70/necv70.tex | 2 +- newlib/libc/saber | 1 - newlib/libm/common/Makefile.am | 4 +- newlib/libm/common/Makefile.in | 43 +- newlib/libm/common/fdlibm.h | 3 - newlib/libm/common/hypotl.c | 30 +- newlib/libm/common/s_exp10.c | 3 - newlib/libm/common/s_lib_ver.c | 4 +- newlib/libm/common/s_log2.c | 7 +- newlib/libm/common/s_matherr.c | 118 ----- newlib/libm/common/s_pow10.c | 3 - newlib/libm/complex/Makefile.in | 1 - newlib/libm/libm.texinfo | 18 +- newlib/libm/math/k_standard.c | 609 ++++--------------------- newlib/libm/math/math.tex | 58 +-- newlib/libm/math/w_acos.c | 28 +- newlib/libm/math/w_acosh.c | 25 +- newlib/libm/math/w_asin.c | 30 +- newlib/libm/math/w_atan2.c | 2 - newlib/libm/math/w_atanh.c | 37 +- newlib/libm/math/w_cosh.c | 22 +- newlib/libm/math/w_exp.c | 37 +- newlib/libm/math/w_exp2.c | 3 - newlib/libm/math/w_fmod.c | 24 +- newlib/libm/math/w_gamma.c | 36 +- newlib/libm/math/w_hypot.c | 22 +- newlib/libm/math/w_j0.c | 50 +- newlib/libm/math/w_j1.c | 50 +- newlib/libm/math/w_jn.c | 53 +-- newlib/libm/math/w_lgamma.c | 39 +- newlib/libm/math/w_log.c | 35 +- newlib/libm/math/w_log10.c | 35 +- newlib/libm/math/w_pow.c | 120 +---- newlib/libm/math/w_remainder.c | 17 +- newlib/libm/math/w_scalb.c | 35 +- newlib/libm/math/w_sinh.c | 21 +- newlib/libm/math/w_sqrt.c | 21 +- newlib/libm/math/wf_acos.c | 18 +- newlib/libm/math/wf_acosh.c | 20 +- newlib/libm/math/wf_asin.c | 18 +- newlib/libm/math/wf_atanh.c | 38 +- newlib/libm/math/wf_cosh.c | 21 +- newlib/libm/math/wf_exp.c | 34 +- newlib/libm/math/wf_fmod.c | 22 +- newlib/libm/math/wf_gamma.c | 35 +- newlib/libm/math/wf_hypot.c | 20 +- newlib/libm/math/wf_j0.c | 50 +- newlib/libm/math/wf_j1.c | 52 +-- newlib/libm/math/wf_jn.c | 55 +-- newlib/libm/math/wf_lgamma.c | 33 +- newlib/libm/math/wf_log.c | 32 +- newlib/libm/math/wf_log10.c | 36 +- newlib/libm/math/wf_pow.c | 136 +----- newlib/libm/math/wf_remainder.c | 21 +- newlib/libm/math/wf_scalb.c | 37 +- newlib/libm/math/wf_sinh.c | 19 +- newlib/libm/math/wf_sqrt.c | 23 +- newlib/libm/math/wr_gamma.c | 35 +- newlib/libm/math/wr_lgamma.c | 36 +- newlib/libm/math/wrf_gamma.c | 32 +- newlib/libm/math/wrf_lgamma.c | 33 +- newlib/libm/mathfp/e_acosh.c | 9 +- newlib/libm/mathfp/e_atanh.c | 3 - newlib/libm/mathfp/e_hypot.c | 2 - newlib/libm/mathfp/er_lgamma.c | 2 - newlib/libm/mathfp/s_acos.c | 9 +- newlib/libm/mathfp/s_atan2.c | 2 - newlib/libm/mathfp/s_cosh.c | 3 - newlib/libm/mathfp/s_fmod.c | 2 - newlib/libm/mathfp/s_logarithm.c | 3 +- newlib/libm/mathfp/s_pow.c | 2 - newlib/libm/mathfp/w_jn.c | 53 +-- newlib/libm/mathfp/wf_jn.c | 55 +-- newlib/libm/test/math.c | 17 +- winsup/cygwin/common.din | 1 - winsup/cygwin/i686.din | 1 - winsup/cygwin/include/cygwin/version.h | 3 +- winsup/cygwin/math/acosh.def.h | 4 +- winsup/cygwin/math/complex_internal.h | 31 -- winsup/cygwin/math/cos.def.h | 4 +- winsup/cygwin/math/exp.def.h | 6 +- winsup/cygwin/math/expm1.def.h | 2 +- winsup/cygwin/math/log.def.h | 4 +- winsup/cygwin/math/pow.def.h | 8 +- winsup/cygwin/math/powi.def.h | 2 +- winsup/cygwin/math/sin.def.h | 4 +- winsup/cygwin/math/sqrt.def.h | 2 +- winsup/cygwin/release/2.12.0 | 3 + winsup/doc/new-features.xml | 5 + 90 files changed, 433 insertions(+), 2350 deletions(-) delete mode 100644 newlib/libm/common/s_matherr.c diff --git a/newlib/libc/include/math.h b/newlib/libc/include/math.h index 893a5d064..1efc5b92c 100644 --- a/newlib/libc/include/math.h +++ b/newlib/libc/include/math.h @@ -568,41 +568,6 @@ extern int *__signgam (void); #define __signgam_r(ptr) _REENT_SIGNGAM(ptr) #endif /* __MISC_VISIBLE || __XSI_VISIBLE */ -#if __SVID_VISIBLE -/* The exception structure passed to the matherr routine. */ -/* We have a problem when using C++ since `exception' is a reserved - name in C++. */ -#ifdef __cplusplus -struct __exception -#else -struct exception -#endif -{ - int type; - char *name; - double arg1; - double arg2; - double retval; - int err; -}; - -#ifdef __cplusplus -extern int matherr (struct __exception *e); -#else -extern int matherr (struct exception *e); -#endif - -/* Values for the type field of struct exception. */ - -#define DOMAIN 1 -#define SING 2 -#define OVERFLOW 3 -#define UNDERFLOW 4 -#define TLOSS 5 -#define PLOSS 6 - -#endif /* __SVID_VISIBLE */ - /* Useful constants. */ #if __BSD_VISIBLE || __XSI_VISIBLE @@ -642,8 +607,6 @@ extern int matherr (struct exception *e); enum __fdlibm_version { __fdlibm_ieee = -1, - __fdlibm_svid, - __fdlibm_xopen, __fdlibm_posix }; @@ -653,8 +616,6 @@ enum __fdlibm_version extern __IMPORT _LIB_VERSION_TYPE _LIB_VERSION; #define _IEEE_ __fdlibm_ieee -#define _SVID_ __fdlibm_svid -#define _XOPEN_ __fdlibm_xopen #define _POSIX_ __fdlibm_posix #endif /* __BSD_VISIBLE */ diff --git a/newlib/libc/machine/necv70/necv70.tex b/newlib/libc/machine/necv70/necv70.tex index 9c1530411..c7858c2dc 100644 --- a/newlib/libc/machine/necv70/necv70.tex +++ b/newlib/libc/machine/necv70/necv70.tex @@ -35,7 +35,7 @@ double x; The library has an entry @code{fast_sin} which uses the machine instruction @code{fsin.l} to perform the operation. Note that the -built-in instructions cannot call @code{matherr} or set @code{errno} +built-in instructions cannot set @code{errno} in the same way that the C coded functions do. Refer to a V70 instruction manual to see how errors are generated and handled. diff --git a/newlib/libc/saber b/newlib/libc/saber index 4f16f976e..154eddf41 100644 --- a/newlib/libc/saber +++ b/newlib/libc/saber @@ -173,7 +173,6 @@ load math/log10.c load math/log1p.c load math/log2.c load math/log__L.c -load math/matherr.c load math/modf.c load math/pow.c load math/scalb.c diff --git a/newlib/libm/common/Makefile.am b/newlib/libm/common/Makefile.am index b0856715b..1eef0236a 100644 --- a/newlib/libm/common/Makefile.am +++ b/newlib/libm/common/Makefile.am @@ -8,7 +8,7 @@ src = s_finite.c s_copysign.c s_modf.c s_scalbn.c \ s_cbrt.c s_exp10.c s_expm1.c s_ilogb.c \ s_infinity.c s_isinf.c s_isinfd.c s_isnan.c s_isnand.c \ s_log1p.c s_nan.c s_nextafter.c s_pow10.c \ - s_rint.c s_logb.c s_log2.c s_matherr.c s_lib_ver.c \ + s_rint.c s_logb.c s_log2.c s_lib_ver.c \ s_fdim.c s_fma.c s_fmax.c s_fmin.c s_fpclassify.c \ s_lrint.c s_llrint.c \ s_lround.c s_llround.c s_nearbyint.c s_remquo.c s_round.c s_scalbln.c \ @@ -62,7 +62,7 @@ endif # USE_LIBTOOL include $(srcdir)/../../Makefile.shared CHEWOUT_FILES = s_cbrt.def s_copysign.def s_exp10.def s_expm1.def s_ilogb.def \ - s_infinity.def s_isnan.def s_log1p.def s_matherr.def s_modf.def \ + s_infinity.def s_isnan.def s_log1p.def s_modf.def \ s_nan.def s_nextafter.def s_pow10.def s_scalbn.def \ s_fdim.def s_fma.def s_fmax.def s_fmin.def \ s_logb.def s_log2.def s_lrint.def s_lround.def s_nearbyint.def \ diff --git a/newlib/libm/common/Makefile.in b/newlib/libm/common/Makefile.in index a777a3466..2caf7dd6c 100644 --- a/newlib/libm/common/Makefile.in +++ b/newlib/libm/common/Makefile.in @@ -85,20 +85,19 @@ am__objects_1 = lib_a-s_finite.$(OBJEXT) lib_a-s_copysign.$(OBJEXT) \ lib_a-s_nan.$(OBJEXT) lib_a-s_nextafter.$(OBJEXT) \ lib_a-s_pow10.$(OBJEXT) lib_a-s_rint.$(OBJEXT) \ lib_a-s_logb.$(OBJEXT) lib_a-s_log2.$(OBJEXT) \ - lib_a-s_matherr.$(OBJEXT) lib_a-s_lib_ver.$(OBJEXT) \ - lib_a-s_fdim.$(OBJEXT) lib_a-s_fma.$(OBJEXT) \ - lib_a-s_fmax.$(OBJEXT) lib_a-s_fmin.$(OBJEXT) \ - lib_a-s_fpclassify.$(OBJEXT) lib_a-s_lrint.$(OBJEXT) \ - lib_a-s_llrint.$(OBJEXT) lib_a-s_lround.$(OBJEXT) \ - lib_a-s_llround.$(OBJEXT) lib_a-s_nearbyint.$(OBJEXT) \ - lib_a-s_remquo.$(OBJEXT) lib_a-s_round.$(OBJEXT) \ - lib_a-s_scalbln.$(OBJEXT) lib_a-s_signbit.$(OBJEXT) \ - lib_a-s_trunc.$(OBJEXT) lib_a-exp.$(OBJEXT) \ - lib_a-exp2.$(OBJEXT) lib_a-exp_data.$(OBJEXT) \ - lib_a-math_err.$(OBJEXT) lib_a-log.$(OBJEXT) \ - lib_a-log_data.$(OBJEXT) lib_a-log2.$(OBJEXT) \ - lib_a-log2_data.$(OBJEXT) lib_a-pow.$(OBJEXT) \ - lib_a-pow_log_data.$(OBJEXT) + lib_a-s_lib_ver.$(OBJEXT) lib_a-s_fdim.$(OBJEXT) \ + lib_a-s_fma.$(OBJEXT) lib_a-s_fmax.$(OBJEXT) \ + lib_a-s_fmin.$(OBJEXT) lib_a-s_fpclassify.$(OBJEXT) \ + lib_a-s_lrint.$(OBJEXT) lib_a-s_llrint.$(OBJEXT) \ + lib_a-s_lround.$(OBJEXT) lib_a-s_llround.$(OBJEXT) \ + lib_a-s_nearbyint.$(OBJEXT) lib_a-s_remquo.$(OBJEXT) \ + lib_a-s_round.$(OBJEXT) lib_a-s_scalbln.$(OBJEXT) \ + lib_a-s_signbit.$(OBJEXT) lib_a-s_trunc.$(OBJEXT) \ + lib_a-exp.$(OBJEXT) lib_a-exp2.$(OBJEXT) \ + lib_a-exp_data.$(OBJEXT) lib_a-math_err.$(OBJEXT) \ + lib_a-log.$(OBJEXT) lib_a-log_data.$(OBJEXT) \ + lib_a-log2.$(OBJEXT) lib_a-log2_data.$(OBJEXT) \ + lib_a-pow.$(OBJEXT) lib_a-pow_log_data.$(OBJEXT) am__objects_2 = lib_a-sf_finite.$(OBJEXT) lib_a-sf_copysign.$(OBJEXT) \ lib_a-sf_modf.$(OBJEXT) lib_a-sf_scalbn.$(OBJEXT) \ lib_a-sf_cbrt.$(OBJEXT) lib_a-sf_exp10.$(OBJEXT) \ @@ -164,9 +163,9 @@ am__objects_5 = s_finite.lo s_copysign.lo s_modf.lo s_scalbn.lo \ s_cbrt.lo s_exp10.lo s_expm1.lo s_ilogb.lo s_infinity.lo \ s_isinf.lo s_isinfd.lo s_isnan.lo s_isnand.lo s_log1p.lo \ s_nan.lo s_nextafter.lo s_pow10.lo s_rint.lo s_logb.lo \ - s_log2.lo s_matherr.lo s_lib_ver.lo s_fdim.lo s_fma.lo \ - s_fmax.lo s_fmin.lo s_fpclassify.lo s_lrint.lo s_llrint.lo \ - s_lround.lo s_llround.lo s_nearbyint.lo s_remquo.lo s_round.lo \ + s_log2.lo s_lib_ver.lo s_fdim.lo s_fma.lo s_fmax.lo s_fmin.lo \ + s_fpclassify.lo s_lrint.lo s_llrint.lo s_lround.lo \ + s_llround.lo s_nearbyint.lo s_remquo.lo s_round.lo \ s_scalbln.lo s_signbit.lo s_trunc.lo exp.lo exp2.lo \ exp_data.lo math_err.lo log.lo log_data.lo log2.lo \ log2_data.lo pow.lo pow_log_data.lo @@ -355,7 +354,7 @@ src = s_finite.c s_copysign.c s_modf.c s_scalbn.c \ s_cbrt.c s_exp10.c s_expm1.c s_ilogb.c \ s_infinity.c s_isinf.c s_isinfd.c s_isnan.c s_isnand.c \ s_log1p.c s_nan.c s_nextafter.c s_pow10.c \ - s_rint.c s_logb.c s_log2.c s_matherr.c s_lib_ver.c \ + s_rint.c s_logb.c s_log2.c s_lib_ver.c \ s_fdim.c s_fma.c s_fmax.c s_fmin.c s_fpclassify.c \ s_lrint.c s_llrint.c \ s_lround.c s_llround.c s_nearbyint.c s_remquo.c s_round.c s_scalbln.c \ @@ -406,7 +405,7 @@ DOCBOOK_OUT_FILES = $(CHEWOUT_FILES:.def=.xml) DOCBOOK_CHAPTERS = $(CHAPTERS:.tex=.xml) CLEANFILES = $(CHEWOUT_FILES) $(DOCBOOK_OUT_FILES) CHEWOUT_FILES = s_cbrt.def s_copysign.def s_exp10.def s_expm1.def s_ilogb.def \ - s_infinity.def s_isnan.def s_log1p.def s_matherr.def s_modf.def \ + s_infinity.def s_isnan.def s_log1p.def s_modf.def \ s_nan.def s_nextafter.def s_pow10.def s_scalbn.def \ s_fdim.def s_fma.def s_fmax.def s_fmin.def \ s_logb.def s_log2.def s_lrint.def s_lround.def s_nearbyint.def \ @@ -603,12 +602,6 @@ lib_a-s_log2.o: s_log2.c lib_a-s_log2.obj: s_log2.c $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-s_log2.obj `if test -f 's_log2.c'; then $(CYGPATH_W) 's_log2.c'; else $(CYGPATH_W) '$(srcdir)/s_log2.c'; fi` -lib_a-s_matherr.o: s_matherr.c - $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-s_matherr.o `test -f 's_matherr.c' || echo '$(srcdir)/'`s_matherr.c - -lib_a-s_matherr.obj: s_matherr.c - $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-s_matherr.obj `if test -f 's_matherr.c'; then $(CYGPATH_W) 's_matherr.c'; else $(CYGPATH_W) '$(srcdir)/s_matherr.c'; fi` - lib_a-s_lib_ver.o: s_lib_ver.c $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-s_lib_ver.o `test -f 's_lib_ver.c' || echo '$(srcdir)/'`s_lib_ver.c diff --git a/newlib/libm/common/fdlibm.h b/newlib/libm/common/fdlibm.h index 2155f5194..8dfff243d 100644 --- a/newlib/libm/common/fdlibm.h +++ b/newlib/libm/common/fdlibm.h @@ -16,9 +16,6 @@ #include #include -/* REDHAT LOCAL: Default to XOPEN_MODE. */ -#define _XOPEN_MODE - /* Most routines need to check whether a float is finite, infinite, or not a number, and many need to know whether the result of an operation will overflow. These conditions depend on whether the largest exponent is diff --git a/newlib/libm/common/hypotl.c b/newlib/libm/common/hypotl.c index cf67ccf58..a0dcdc3c1 100644 --- a/newlib/libm/common/hypotl.c +++ b/newlib/libm/common/hypotl.c @@ -52,36 +52,14 @@ hypotl (long double x, long double y) if ((! finitel (z)) && finitel (x) && finitel (y)) { /* hypot (finite, finite) overflow. */ - struct exception exc; - - exc.type = OVERFLOW; - exc.name = "hypotl"; - exc.err = 0; - exc.arg1 = x; - exc.arg2 = y; - - if (_LIB_VERSION == _SVID_) - exc.retval = HUGE; - else - { #ifndef HUGE_VAL #define HUGE_VAL inf - double inf = 0.0; + double inf = 0.0; - SET_HIGH_WORD (inf, 0x7ff00000); /* Set inf to infinite. */ + SET_HIGH_WORD (inf, 0x7ff00000); /* Set inf to infinite. */ #endif - exc.retval = HUGE_VAL; - } - - if (_LIB_VERSION == _POSIX_) - errno = ERANGE; - else if (! matherr (& exc)) - errno = ERANGE; - - if (exc.err != 0) - errno = exc.err; - - return (long double) exc.retval; + errno = ERANGE; + return (long double) HUGE_VAL; } return z; diff --git a/newlib/libm/common/s_exp10.c b/newlib/libm/common/s_exp10.c index 08fa5ff16..6bd027f59 100644 --- a/newlib/libm/common/s_exp10.c +++ b/newlib/libm/common/s_exp10.c @@ -34,9 +34,6 @@ DESCRIPTION $10^x$ @end tex - You can use the (non-ANSI) function <> to specify - error handling for these functions. - RETURNS On success, <> and <> return the calculated value. If the result underflows, the returned value is <<0>>. If the diff --git a/newlib/libm/common/s_lib_ver.c b/newlib/libm/common/s_lib_ver.c index 15c8b4166..8da03b79a 100644 --- a/newlib/libm/common/s_lib_ver.c +++ b/newlib/libm/common/s_lib_ver.c @@ -24,10 +24,10 @@ _LIB_VERSION_TYPE _LIB_VERSION = _POSIX_; #else #ifdef _XOPEN_MODE -_LIB_VERSION_TYPE _LIB_VERSION = _XOPEN_; +#error _XOPEN_MODE is unsupported #else #ifdef _SVID3_MODE -_LIB_VERSION_TYPE _LIB_VERSION = _SVID_; +#error _SVID3_MODE is unsupported #else /* default _IEEE_MODE */ _LIB_VERSION_TYPE _LIB_VERSION = _IEEE_; #endif diff --git a/newlib/libm/common/s_log2.c b/newlib/libm/common/s_log2.c index 0b1ec1d63..724148c57 100644 --- a/newlib/libm/common/s_log2.c +++ b/newlib/libm/common/s_log2.c @@ -38,10 +38,6 @@ macros defined in math.h: . #define log2f(x) (logf (x) / (float) _M_LN2) To use the functions instead, just undefine the macros first. -You can use the (non-ANSI) function <> to specify error -handling for these functions, indirectly through the respective <> -function. - RETURNS The <> functions return @ifnottex @@ -54,8 +50,7 @@ on success. When <[x]> is zero, the returned value is <<-HUGE_VAL>> and <> is set to <>. When <[x]> is negative, the returned value is NaN (not a number) and -<> is set to <>. You can control the error behavior via -<>. +<> is set to <>. PORTABILITY C99, POSIX, System V Interface Definition (Issue 6). diff --git a/newlib/libm/common/s_matherr.c b/newlib/libm/common/s_matherr.c deleted file mode 100644 index 00d2caa38..000000000 --- a/newlib/libm/common/s_matherr.c +++ /dev/null @@ -1,118 +0,0 @@ - -/* @(#)s_matherr.c 5.1 93/09/24 */ -/* - * ==================================================== - * 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. - * ==================================================== - */ - -/* - -FUNCTION - <>---modifiable math error handler - -INDEX - matherr - -SYNOPSIS - #include - int matherr(struct exception *<[e]>); - -DESCRIPTION -<> is called whenever a math library function generates an error. -You can replace <> by your own subroutine to customize -error treatment. The customized <> must return 0 if -it fails to resolve the error, and non-zero if the error is resolved. - -When <> returns a nonzero value, no error message is printed -and the value of <> is not modified. You can accomplish either -or both of these things in your own <> using the information -passed in the structure <<*<[e]>>>. - -This is the <> structure (defined in `<>'): -. struct exception { -. int type; -. char *name; -. double arg1, arg2, retval; -. int err; -. }; - -The members of the exception structure have the following meanings: -o+ -o type -The type of mathematical error that occured; macros encoding error -types are also defined in `<>'. - -o name -a pointer to a null-terminated string holding the -name of the math library function where the error occurred. - -o arg1, arg2 -The arguments which caused the error. - -o retval -The error return value (what the calling function will return). - -o err -If set to be non-zero, this is the new value assigned to <>. -o- - -The error types defined in `<>' represent possible mathematical -errors as follows: - -o+ -o DOMAIN -An argument was not in the domain of the function; e.g. <>. - -o SING -The requested calculation would result in a singularity; e.g. <> - -o OVERFLOW -A calculation would produce a result too large to represent; e.g. -<>. - -o UNDERFLOW -A calculation would produce a result too small to represent; e.g. -<>. - -o TLOSS -Total loss of precision. The result would have no significant digits; -e.g. <>. - -o PLOSS -Partial loss of precision. -o- - - -RETURNS -The library definition for <> returns <<0>> in all cases. - -You can change the calling function's result from a customized <> -by modifying <retval>>, which propagates backs to the caller. - -If <> returns <<0>> (indicating that it was not able to resolve -the error) the caller sets <> to an appropriate value, and prints -an error message. - -PORTABILITY -<> is not ANSI C. -*/ - -#include "fdlibm.h" - -#ifdef __STDC__ - int matherr(struct exception *x) -#else - int matherr(x) - struct exception *x; -#endif -{ - int n=0; - if(x->arg1!=x->arg1) return 0; - return n; -} diff --git a/newlib/libm/common/s_pow10.c b/newlib/libm/common/s_pow10.c index 46645c71b..a9e7284d9 100644 --- a/newlib/libm/common/s_pow10.c +++ b/newlib/libm/common/s_pow10.c @@ -34,9 +34,6 @@ DESCRIPTION $10^x$ @end tex - You can use the (non-ANSI) function <> to specify - error handling for these functions. - RETURNS On success, <> and <> return the calculated value. If the result underflows, the returned value is <<0>>. If the diff --git a/newlib/libm/complex/Makefile.in b/newlib/libm/complex/Makefile.in index f8128997a..20b3b17f2 100644 --- a/newlib/libm/complex/Makefile.in +++ b/newlib/libm/complex/Makefile.in @@ -271,7 +271,6 @@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ -runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ diff --git a/newlib/libm/libm.texinfo b/newlib/libm/libm.texinfo index f55ad72d9..a579a1743 100644 --- a/newlib/libm/libm.texinfo +++ b/newlib/libm/libm.texinfo @@ -107,23 +107,13 @@ into another language, under the above conditions for modified versions. @cindex reentrancy @cindex @code{matherr} and reentrancy When a libm function detects an exceptional case, @code{errno} may be -set, the @code{matherr} function may be called, and a error message -may be written to the standard error stream. This behavior may not -be reentrant. +set. @c The exact behavior depends on the currently selected error handling -@c mode (IEEE, POSIX, X/Open, or SVID). +@c mode (IEEE or POSIX). -With reentrant C libraries like the Red Hat newlib C library, @code{errno} is -a macro which expands to the per-thread error value. This makes it thread -safe. - -When the user provides his own @code{matherr} function it must be -reentrant for the math library as a whole to be reentrant. - -In normal debugged programs, there are usually no math subroutine -errors---and therefore no assignments to @code{errno} and no @code{matherr} -calls; in that situation, the math functions behave reentrantly. +@code{errno} is a macro which expands to the per-thread error value. +This makes it thread safe, and therefore reentrant. @node Long Double Functions @chapter The long double function support of @code{libm} diff --git a/newlib/libm/math/k_standard.c b/newlib/libm/math/k_standard.c index 0d72f1a53..91fd6c33f 100644 --- a/newlib/libm/math/k_standard.c +++ b/newlib/libm/math/k_standard.c @@ -31,7 +31,7 @@ static double zero = 0.0; /* used as const */ #endif /* - * Standard conformance (non-IEEE) on exception cases. + * POSIX Standard conformance on exception cases. * Mapping: * 1 -- acos(|x|>1) * 2 -- asin(|x|>1) @@ -85,7 +85,7 @@ static double zero = 0.0; /* used as const */ double x,y; int type; #endif { - struct exception exc; + double retval = 0.0; #ifndef HUGE_VAL /* this is the only routine that uses HUGE_VAL */ #define HUGE_VAL inf double inf = 0.0; @@ -96,689 +96,264 @@ static double zero = 0.0; /* used as const */ #ifdef _USE_WRITE /* (void) fflush(_stdout_r(p)); */ #endif - exc.arg1 = x; - exc.arg2 = y; - exc.err = 0; switch(type) { case 1: case 101: /* acos(|x|>1) */ - exc.type = DOMAIN; - exc.name = type < 100 ? "acos" : "acosf"; - exc.retval = zero; - if (_LIB_VERSION == _POSIX_) - errno = EDOM; - else if (!matherr(&exc)) { - /* if(_LIB_VERSION == _SVID_) { - (void) WRITE2("acos: DOMAIN error\n", 19); - } */ - errno = EDOM; - } + retval = zero; + errno = EDOM; break; case 2: case 102: /* asin(|x|>1) */ - exc.type = DOMAIN; - exc.name = type < 100 ? "asin" : "asinf"; - exc.retval = zero; - if(_LIB_VERSION == _POSIX_) - errno = EDOM; - else if (!matherr(&exc)) { - /* if(_LIB_VERSION == _SVID_) { - (void) WRITE2("asin: DOMAIN error\n", 19); - } */ - errno = EDOM; - } + retval = zero; + errno = EDOM; break; case 3: case 103: /* atan2(+-0,+-0) */ - exc.arg1 = y; - exc.arg2 = x; - exc.type = DOMAIN; - exc.name = type < 100 ? "atan2" : "atan2f"; - exc.retval = zero; - if(_LIB_VERSION == _POSIX_) - errno = EDOM; - else if (!matherr(&exc)) { - /* if(_LIB_VERSION == _SVID_) { - (void) WRITE2("atan2: DOMAIN error\n", 20); - } */ - errno = EDOM; - } + retval = zero; + errno = EDOM; break; case 4: case 104: /* hypot(finite,finite) overflow */ - exc.type = OVERFLOW; - exc.name = type < 100 ? "hypot" : "hypotf"; - if (_LIB_VERSION == _SVID_) - exc.retval = HUGE; - else - exc.retval = HUGE_VAL; - if (_LIB_VERSION == _POSIX_) - errno = ERANGE; - else if (!matherr(&exc)) { - errno = ERANGE; - } + retval = HUGE_VAL; + errno = ERANGE; break; case 5: case 105: /* cosh(finite) overflow */ - exc.type = OVERFLOW; - exc.name = type < 100 ? "cosh" : "coshf"; - if (_LIB_VERSION == _SVID_) - exc.retval = HUGE; - else - exc.retval = HUGE_VAL; - if (_LIB_VERSION == _POSIX_) - errno = ERANGE; - else if (!matherr(&exc)) { - errno = ERANGE; - } + retval = HUGE_VAL; + errno = ERANGE; break; case 6: case 106: /* exp(finite) overflow */ - exc.type = OVERFLOW; - exc.name = type < 100 ? "exp" : "expf"; - if (_LIB_VERSION == _SVID_) - exc.retval = HUGE; - else - exc.retval = HUGE_VAL; - if (_LIB_VERSION == _POSIX_) - errno = ERANGE; - else if (!matherr(&exc)) { - errno = ERANGE; - } + retval = HUGE_VAL; + errno = ERANGE; break; case 7: case 107: /* exp(finite) underflow */ - exc.type = UNDERFLOW; - exc.name = type < 100 ? "exp" : "expf"; - exc.retval = zero; - if (_LIB_VERSION == _POSIX_) - errno = ERANGE; - else if (!matherr(&exc)) { - errno = ERANGE; - } + retval = zero; + errno = ERANGE; break; case 8: case 108: /* y0(0) = -inf */ - exc.type = DOMAIN; /* should be SING for IEEE */ - exc.name = type < 100 ? "y0" : "y0f"; - if (_LIB_VERSION == _SVID_) - exc.retval = -HUGE; - else - exc.retval = -HUGE_VAL; - if (_LIB_VERSION == _POSIX_) - errno = EDOM; - else if (!matherr(&exc)) { - /* if (_LIB_VERSION == _SVID_) { - (void) WRITE2("y0: DOMAIN error\n", 17); - } */ - errno = EDOM; - } + retval = -HUGE_VAL; + errno = EDOM; break; case 9: case 109: /* y0(x<0) = NaN */ - exc.type = DOMAIN; - exc.name = type < 100 ? "y0" : "y0f"; - if (_LIB_VERSION == _SVID_) - exc.retval = -HUGE; - else - exc.retval = -HUGE_VAL; - if (_LIB_VERSION == _POSIX_) - errno = EDOM; - else if (!matherr(&exc)) { - /*if (_LIB_VERSION == _SVID_) { - (void) WRITE2("y0: DOMAIN error\n", 17); - } */ - errno = EDOM; - } + retval = -HUGE_VAL; + errno = EDOM; break; case 10: case 110: /* y1(0) = -inf */ - exc.type = DOMAIN; /* should be SING for IEEE */ - exc.name = type < 100 ? "y1" : "y1f"; - if (_LIB_VERSION == _SVID_) - exc.retval = -HUGE; - else - exc.retval = -HUGE_VAL; - if (_LIB_VERSION == _POSIX_) - errno = EDOM; - else if (!matherr(&exc)) { - /* if (_LIB_VERSION == _SVID_) { - (void) WRITE2("y1: DOMAIN error\n", 17); - } */ - errno = EDOM; - } + retval = -HUGE_VAL; + errno = EDOM; break; case 11: case 111: /* y1(x<0) = NaN */ - exc.type = DOMAIN; - exc.name = type < 100 ? "y1" : "y1f"; - if (_LIB_VERSION == _SVID_) - exc.retval = -HUGE; - else - exc.retval = -HUGE_VAL; - if (_LIB_VERSION == _POSIX_) - errno = EDOM; - else if (!matherr(&exc)) { - /* if (_LIB_VERSION == _SVID_) { - (void) WRITE2("y1: DOMAIN error\n", 17); - } */ - errno = EDOM; - } + retval = -HUGE_VAL; + errno = EDOM; break; case 12: case 112: /* yn(n,0) = -inf */ - exc.type = DOMAIN; /* should be SING for IEEE */ - exc.name = type < 100 ? "yn" : "ynf"; - if (_LIB_VERSION == _SVID_) - exc.retval = -HUGE; - else - exc.retval = -HUGE_VAL; - if (_LIB_VERSION == _POSIX_) - errno = EDOM; - else if (!matherr(&exc)) { - /* if (_LIB_VERSION == _SVID_) { - (void) WRITE2("yn: DOMAIN error\n", 17); - } */ - errno = EDOM; - } + retval = -HUGE_VAL; + errno = EDOM; break; case 13: case 113: /* yn(x<0) = NaN */ - exc.type = DOMAIN; - exc.name = type < 100 ? "yn" : "ynf"; - if (_LIB_VERSION == _SVID_) - exc.retval = -HUGE; - else - exc.retval = -HUGE_VAL; - if (_LIB_VERSION == _POSIX_) - errno = EDOM; - else if (!matherr(&exc)) { - /* if (_LIB_VERSION == _SVID_) { - (void) WRITE2("yn: DOMAIN error\n", 17); - } */ - errno = EDOM; - } + retval = -HUGE_VAL; + errno = EDOM; break; case 14: case 114: /* lgamma(finite) overflow */ - exc.type = OVERFLOW; - exc.name = type < 100 ? "lgamma" : "lgammaf"; - if (_LIB_VERSION == _SVID_) - exc.retval = HUGE; - else - exc.retval = HUGE_VAL; - if (_LIB_VERSION == _POSIX_) - errno = ERANGE; - else if (!matherr(&exc)) { - errno = ERANGE; - } + retval = HUGE_VAL; + errno = ERANGE; break; case 15: case 115: /* lgamma(-integer) or lgamma(0) */ - exc.type = SING; - exc.name = type < 100 ? "lgamma" : "lgammaf"; - if (_LIB_VERSION == _SVID_) - exc.retval = HUGE; - else - exc.retval = HUGE_VAL; - if (_LIB_VERSION == _POSIX_) - errno = EDOM; - else if (!matherr(&exc)) { - /* if (_LIB_VERSION == _SVID_) { - (void) WRITE2("lgamma: SING error\n", 19); - } */ - errno = EDOM; - } + retval = HUGE_VAL; + errno = EDOM; break; case 16: case 116: /* log(0) */ - exc.type = SING; - exc.name = type < 100 ? "log" : "logf"; - if (_LIB_VERSION == _SVID_) - exc.retval = -HUGE; - else - exc.retval = -HUGE_VAL; - if (_LIB_VERSION == _POSIX_) - errno = ERANGE; - else if (!matherr(&exc)) { - /* if (_LIB_VERSION == _SVID_) { - (void) WRITE2("log: SING error\n", 16); - } */ - errno = EDOM; - } + retval = -HUGE_VAL; + errno = EDOM; break; case 17: case 117: /* log(x<0) */ - exc.type = DOMAIN; - exc.name = type < 100 ? "log" : "logf"; - if (_LIB_VERSION == _SVID_) - exc.retval = -HUGE; - else - exc.retval = -HUGE_VAL; - if (_LIB_VERSION == _POSIX_) - errno = EDOM; - else if (!matherr(&exc)) { - /* if (_LIB_VERSION == _SVID_) { - (void) WRITE2("log: DOMAIN error\n", 18); - } */ - errno = EDOM; - } + retval = -HUGE_VAL; + errno = EDOM; break; case 18: case 118: /* log10(0) */ - exc.type = SING; - exc.name = type < 100 ? "log10" : "log10f"; - if (_LIB_VERSION == _SVID_) - exc.retval = -HUGE; - else - exc.retval = -HUGE_VAL; - if (_LIB_VERSION == _POSIX_) - errno = ERANGE; - else if (!matherr(&exc)) { - /* if (_LIB_VERSION == _SVID_) { - (void) WRITE2("log10: SING error\n", 18); - } */ - errno = EDOM; - } + retval = -HUGE_VAL; + errno = EDOM; break; case 19: case 119: /* log10(x<0) */ - exc.type = DOMAIN; - exc.name = type < 100 ? "log10" : "log10f"; - if (_LIB_VERSION == _SVID_) - exc.retval = -HUGE; - else - exc.retval = -HUGE_VAL; - if (_LIB_VERSION == _POSIX_) - errno = EDOM; - else if (!matherr(&exc)) { - /* if (_LIB_VERSION == _SVID_) { - (void) WRITE2("log10: DOMAIN error\n", 20); - } */ - errno = EDOM; - } + retval = -HUGE_VAL; + errno = EDOM; break; case 20: case 120: /* pow(0.0,0.0) */ - /* error only if _LIB_VERSION == _SVID_ */ - exc.type = DOMAIN; - exc.name = type < 100 ? "pow" : "powf"; - exc.retval = zero; - if (_LIB_VERSION != _SVID_) exc.retval = 1.0; - else if (!matherr(&exc)) { - /* (void) WRITE2("pow(0,0): DOMAIN error\n", 23); */ - errno = EDOM; - } + /* Not an error. */ + retval = 1.0; break; case 21: case 121: /* pow(x,y) overflow */ - exc.type = OVERFLOW; - exc.name = type < 100 ? "pow" : "powf"; - if (_LIB_VERSION == _SVID_) { - exc.retval = HUGE; - y *= 0.5; - if(xzero) ? HUGE : -HUGE); - else - exc.retval = ( (x>zero) ? HUGE_VAL : -HUGE_VAL); - if (_LIB_VERSION == _POSIX_) - errno = ERANGE; - else if (!matherr(&exc)) { - errno = ERANGE; - } + retval = ( (x>zero) ? HUGE_VAL : -HUGE_VAL); + errno = ERANGE; break; case 26: case 126: /* sqrt(x<0) */ - exc.type = DOMAIN; - exc.name = type < 100 ? "sqrt" : "sqrtf"; - if (_LIB_VERSION == _SVID_) - exc.retval = zero; - else - exc.retval = zero/zero; - if (_LIB_VERSION == _POSIX_) - errno = EDOM; - else if (!matherr(&exc)) { - /* if (_LIB_VERSION == _SVID_) { - (void) WRITE2("sqrt: DOMAIN error\n", 19); - } */ - errno = EDOM; - } + retval = zero/zero; + errno = EDOM; break; case 27: case 127: - /* fmod(x,0) */ - exc.type = DOMAIN; - exc.name = type < 100 ? "fmod" : "fmodf"; - if (_LIB_VERSION == _SVID_) - exc.retval = x; - else - exc.retval = zero/zero; - if (_LIB_VERSION == _POSIX_) - errno = EDOM; - else if (!matherr(&exc)) { - /* if (_LIB_VERSION == _SVID_) { - (void) WRITE2("fmod: DOMAIN error\n", 20); - } */ - errno = EDOM; - } + /* fmod(x,0) */ + retval = zero/zero; + errno = EDOM; break; case 28: case 128: /* remainder(x,0) */ - exc.type = DOMAIN; - exc.name = type < 100 ? "remainder" : "remainderf"; - exc.retval = zero/zero; - if (_LIB_VERSION == _POSIX_) - errno = EDOM; - else if (!matherr(&exc)) { - /* if (_LIB_VERSION == _SVID_) { - (void) WRITE2("remainder: DOMAIN error\n", 24); - } */ - errno = EDOM; - } + retval = zero/zero; + errno = EDOM; break; case 29: case 129: /* acosh(x<1) */ - exc.type = DOMAIN; - exc.name = type < 100 ? "acosh" : "acoshf"; - exc.retval = zero/zero; - if (_LIB_VERSION == _POSIX_) - errno = EDOM; - else if (!matherr(&exc)) { - /* if (_LIB_VERSION == _SVID_) { - (void) WRITE2("acosh: DOMAIN error\n", 20); - } */ - errno = EDOM; - } + retval = zero/zero; + errno = EDOM; break; case 30: case 130: /* atanh(|x|>1) */ - exc.type = DOMAIN; - exc.name = type < 100 ? "atanh" : "atanhf"; - exc.retval = zero/zero; - if (_LIB_VERSION == _POSIX_) - errno = EDOM; - else if (!matherr(&exc)) { - /* if (_LIB_VERSION == _SVID_) { - (void) WRITE2("atanh: DOMAIN error\n", 20); - } */ - errno = EDOM; - } + retval = zero/zero; + errno = EDOM; break; case 31: case 131: /* atanh(|x|=1) */ - exc.type = SING; - exc.name = type < 100 ? "atanh" : "atanhf"; - exc.retval = x/zero; /* sign(x)*inf */ - if (_LIB_VERSION == _POSIX_) - errno = EDOM; - else if (!matherr(&exc)) { - /* if (_LIB_VERSION == _SVID_) { - (void) WRITE2("atanh: SING error\n", 18); - } */ - errno = EDOM; - } + retval = x/zero; /* sign(x)*inf */ + errno = EDOM; break; case 32: case 132: - /* scalb overflow; SVID also returns +-HUGE_VAL */ - exc.type = OVERFLOW; - exc.name = type < 100 ? "scalb" : "scalbf"; - exc.retval = x > zero ? HUGE_VAL : -HUGE_VAL; - if (_LIB_VERSION == _POSIX_) - errno = ERANGE; - else if (!matherr(&exc)) { - errno = ERANGE; - } + /* scalb overflow */ + retval = x > zero ? HUGE_VAL : -HUGE_VAL; + errno = ERANGE; break; case 33: case 133: /* scalb underflow */ - exc.type = UNDERFLOW; - exc.name = type < 100 ? "scalb" : "scalbf"; - exc.retval = copysign(zero,x); - if (_LIB_VERSION == _POSIX_) - errno = ERANGE; - else if (!matherr(&exc)) { - errno = ERANGE; - } + retval = copysign(zero,x); + errno = ERANGE; break; case 34: case 134: /* j0(|x|>X_TLOSS) */ - exc.type = TLOSS; - exc.name = type < 100 ? "j0" : "j0f"; - exc.retval = zero; - if (_LIB_VERSION == _POSIX_) - errno = ERANGE; - else if (!matherr(&exc)) { - /* if (_LIB_VERSION == _SVID_) { - (void) WRITE2(exc.name, 2); - (void) WRITE2(": TLOSS error\n", 14); - } */ - errno = ERANGE; - } + retval = zero; + errno = ERANGE; break; case 35: case 135: /* y0(x>X_TLOSS) */ - exc.type = TLOSS; - exc.name = type < 100 ? "y0" : "y0f"; - exc.retval = zero; - if (_LIB_VERSION == _POSIX_) - errno = ERANGE; - else if (!matherr(&exc)) { - /* if (_LIB_VERSION == _SVID_) { - (void) WRITE2(exc.name, 2); - (void) WRITE2(": TLOSS error\n", 14); - } */ - errno = ERANGE; - } + retval = zero; + errno = ERANGE; break; case 36: case 136: /* j1(|x|>X_TLOSS) */ - exc.type = TLOSS; - exc.name = type < 100 ? "j1" : "j1f"; - exc.retval = zero; - if (_LIB_VERSION == _POSIX_) - errno = ERANGE; - else if (!matherr(&exc)) { - /* if (_LIB_VERSION == _SVID_) { - (void) WRITE2(exc.name, 2); - (void) WRITE2(": TLOSS error\n", 14); - } */ - errno = ERANGE; - } + retval = zero; + errno = ERANGE; break; case 37: case 137: /* y1(x>X_TLOSS) */ - exc.type = TLOSS; - exc.name = type < 100 ? "y1" : "y1f"; - exc.retval = zero; - if (_LIB_VERSION == _POSIX_) - errno = ERANGE; - else if (!matherr(&exc)) { - /* if (_LIB_VERSION == _SVID_) { - (void) WRITE2(exc.name, 2); - (void) WRITE2(": TLOSS error\n", 14); - } */ - errno = ERANGE; - } + retval = zero; + errno = ERANGE; break; case 38: case 138: /* jn(|x|>X_TLOSS) */ - exc.type = TLOSS; - exc.name = type < 100 ? "jn" : "jnf"; - exc.retval = zero; - if (_LIB_VERSION == _POSIX_) - errno = ERANGE; - else if (!matherr(&exc)) { - /* if (_LIB_VERSION == _SVID_) { - (void) WRITE2(exc.name, 2); - (void) WRITE2(": TLOSS error\n", 14); - } */ - errno = ERANGE; - } + retval = zero; + errno = ERANGE; break; case 39: case 139: /* yn(x>X_TLOSS) */ - exc.type = TLOSS; - exc.name = type < 100 ? "yn" : "ynf"; - exc.retval = zero; - if (_LIB_VERSION == _POSIX_) - errno = ERANGE; - else if (!matherr(&exc)) { - /* if (_LIB_VERSION == _SVID_) { - (void) WRITE2(exc.name, 2); - (void) WRITE2(": TLOSS error\n", 14); - } */ - errno = ERANGE; - } + retval = zero; + errno = ERANGE; break; case 40: case 140: /* gamma(finite) overflow */ - exc.type = OVERFLOW; - exc.name = type < 100 ? "gamma" : "gammaf"; - if (_LIB_VERSION == _SVID_) - exc.retval = HUGE; - else - exc.retval = HUGE_VAL; - if (_LIB_VERSION == _POSIX_) - errno = ERANGE; - else if (!matherr(&exc)) { - errno = ERANGE; - } + retval = HUGE_VAL; + errno = ERANGE; break; case 41: case 141: /* gamma(-integer) or gamma(0) */ - exc.type = SING; - exc.name = type < 100 ? "gamma" : "gammaf"; - if (_LIB_VERSION == _SVID_) - exc.retval = HUGE; - else - exc.retval = HUGE_VAL; - if (_LIB_VERSION == _POSIX_) - errno = EDOM; - else if (!matherr(&exc)) { - /* if (_LIB_VERSION == _SVID_) { - (void) WRITE2("gamma: SING error\n", 18); - } */ - errno = EDOM; - } + retval = HUGE_VAL; + errno = EDOM; break; case 42: case 142: /* pow(NaN,0.0) */ - /* error only if _LIB_VERSION == _SVID_ & _XOPEN_ */ - exc.type = DOMAIN; - exc.name = type < 100 ? "pow" : "powf"; - exc.retval = x; - if (_LIB_VERSION == _IEEE_ || - _LIB_VERSION == _POSIX_) exc.retval = 1.0; - else if (!matherr(&exc)) { - errno = EDOM; - } + /* Not an error. */ + retval = 1.0; break; } - if (exc.err != 0) - errno = exc.err; - return exc.retval; + return retval; } diff --git a/newlib/libm/math/math.tex b/newlib/libm/math/math.tex index a6f931b3e..92b384f63 100644 --- a/newlib/libm/math/math.tex +++ b/newlib/libm/math/math.tex @@ -3,33 +3,15 @@ This chapter groups a wide variety of mathematical functions. The corresponding definitions and declarations are in @file{math.h}. -Two definitions from @file{math.h} are of particular interest. +The definition of HUGE_VAL from @file{math.h} is of particular interest. @enumerate @item The representation of infinity as a @code{double} is defined as @code{HUGE_VAL}; this number is returned on overflow by many functions. The macro @code{HUGE_VALF} is a corresponding value for @code{float}. - -@item -The structure @code{exception} is used when you write customized error -handlers for the mathematical functions. You can customize error -handling for most of these functions by defining your own version of -@code{matherr}; see the section on @code{matherr} for details. @end enumerate -@cindex system calls -@cindex support subroutines -@cindex stubs -@cindex OS stubs -Since the error handling code calls @code{fputs}, the mathematical -subroutines require stubs or minimal implementations for the same list -of OS subroutines as @code{fputs}: @code{close}, @code{fstat}, -@code{isatty}, @code{lseek}, @code{read}, @code{sbrk}, @code{write}. -@xref{syscalls,,System Calls, libc.info, The Red Hat newlib C Library}, -for a discussion and for sample minimal implementations of these support -subroutines. - Alternative declarations of the mathematical functions, which exploit specific machine capabilities to operate faster---but generally have less error checking and may reflect additional limitations on some @@ -76,7 +58,6 @@ machines---are available when you include @file{fastmath.h} instead of * logb:: Get exponent * lrint:: Round to integer * lround:: Round to integer, away from zero (lround, llround) -* matherr:: Modifiable math error handler * modf:: Split fractional and integer parts * nan:: Floating Not a Number * nearbyint:: Round to integer @@ -101,40 +82,23 @@ machines---are available when you include @file{fastmath.h} instead of @node version @section Error Handling -There are four different versions of the math library routines: IEEE, -POSIX, X/Open, or SVID. The version may be selected at runtime by +There are two different versions of the math library routines: IEEE +and POSIX. The version may be selected at runtime by setting the global variable @code{_LIB_VERSION}, defined in @file{math.h}. It may be set to one of the following constants defined -in @file{math.h}: @code{_IEEE_}, @code{_POSIX_}, @code{_XOPEN_}, or -@code{_SVID_}. The @code{_LIB_VERSION} variable is not specific to any +in @file{math.h}: @code{_IEEE_} or @code{_POSIX_}. +The @code{_LIB_VERSION} variable is not specific to any thread, and changing it will affect all threads. -The versions of the library differ only in how errors are handled. +The versions of the library differ only in the setting of @code{errno}. -In IEEE mode, the @code{matherr} function is never called, no warning -messages are printed, and @code{errno} is never set. +In IEEE mode, @code{errno} is never set. -In POSIX mode, @code{errno} is set correctly, but the @code{matherr} -function is never called and no warning messages are printed. +In POSIX mode, @code{errno} is set correctly. -In X/Open mode, @code{errno} is set correctly, and @code{matherr} is -called, but warning message are not printed. +The library is set to IEEE mode by default. -In SVID mode, functions which overflow return 3.40282346638528860e+38, -the maximum single-precision floating-point value, rather than infinity. -Also, @code{errno} is set correctly, @code{matherr} is called, and, if -@code{matherr} returns 0, warning messages are printed for some errors. -For example, by default @samp{log(-1.0)} writes this message on standard -error output: - -@example -log: DOMAIN error -@end example - -The library is set to X/Open mode by default. - -The aforementioned error reporting is the supported Newlib libm error -handling method. However, the majority of the functions are written +The majority of the floating-point math functions are written so as to produce the floating-point exceptions (e.g. "invalid", "divide-by-zero") as required by the C and POSIX standards, for floating-point implementations that support them. Newlib does not provide @@ -241,8 +205,6 @@ registered trademark of The IEEE. @page @include common/s_lround.def @page -@include common/s_matherr.def -@page @include common/s_modf.def @page @include common/s_nan.def diff --git a/newlib/libm/math/w_acos.c b/newlib/libm/math/w_acos.c index eb3e20111..c0a86a97d 100644 --- a/newlib/libm/math/w_acos.c +++ b/newlib/libm/math/w_acos.c @@ -42,16 +42,12 @@ RETURNS @end tex If <[x]> is not between @minus{}1 and 1, the returned value is NaN - (not a number) the global variable <> is set to <>, and a - <> message is sent as standard error output. - - You can modify error handling for these functions using <>. - + (not a number), and the global variable <> is set to <>. QUICKREF - ansi svid posix rentrant - acos y,y,y,m - acosf n,n,n,m + ansi posix rentrant + acos y,y,m + acosf n,n,m MATHREF acos, [-1,1], acos(arg),,, @@ -83,24 +79,12 @@ MATHREF return __ieee754_acos(x); #else double z; - struct exception exc; z = __ieee754_acos(x); if(_LIB_VERSION == _IEEE_ || isnan(x)) return z; if(fabs(x)>1.0) { /* acos(|x|>1) */ - exc.type = DOMAIN; - exc.name = "acos"; - exc.err = 0; - exc.arg1 = exc.arg2 = x; - exc.retval = nan(""); - if (_LIB_VERSION == _POSIX_) - errno = EDOM; - else if (!matherr(&exc)) { - errno = EDOM; - } - if (exc.err != 0) - errno = exc.err; - return exc.retval; + errno = EDOM; + return nan(""); } else return z; #endif diff --git a/newlib/libm/math/w_acosh.c b/newlib/libm/math/w_acosh.c index ac15bb1bd..74382663c 100644 --- a/newlib/libm/math/w_acosh.c +++ b/newlib/libm/math/w_acosh.c @@ -44,18 +44,15 @@ RETURNS <> and <> return the calculated value. If <[x]> less than 1, the return value is NaN and <> is set to <>. -You can change the error-handling behavior with the non-ANSI -<> function. - PORTABILITY Neither <> nor <> are ANSI C. They are not recommended for portable programs. QUICKREF - ansi svid posix rentrant - acos n,n,n,m - acosf n,n,n,m + ansi posix rentrant + acos n,n,m + acosf n,n,m MATHREF acosh, NAN, arg,DOMAIN,EDOM @@ -89,24 +86,12 @@ MATHREF return __ieee754_acosh(x); #else double z; - struct exception exc; z = __ieee754_acosh(x); if(_LIB_VERSION == _IEEE_ || isnan(x)) return z; if(x<1.0) { /* acosh(x<1) */ - exc.type = DOMAIN; - exc.name = "acosh"; - exc.err = 0; - exc.arg1 = exc.arg2 = x; - exc.retval = 0.0/0.0; - if (_LIB_VERSION == _POSIX_) - errno = EDOM; - else if (!matherr(&exc)) { - errno = EDOM; - } - if (exc.err != 0) - errno = exc.err; - return exc.retval; + errno = EDOM; + return 0.0/0.0; } else return z; #endif diff --git a/newlib/libm/math/w_asin.c b/newlib/libm/math/w_asin.c index 9964d75b0..a94b0d550 100644 --- a/newlib/libm/math/w_asin.c +++ b/newlib/libm/math/w_asin.c @@ -34,8 +34,6 @@ Arguments to <> must be in the range @minus{}1 to 1. <> is identical to <>, other than taking and returning floats. -You can modify error handling for these routines using <>. - RETURNS @ifnottex <> returns values in radians, in the range of -pi/2 to pi/2. @@ -45,15 +43,13 @@ RETURNS @end tex If <[x]> is not in the range @minus{}1 to 1, <> and <> -return NaN (not a number), set the global variable <> to -<>, and issue a <> message. - -You can change this error treatment using <>. +return NaN (not a number), and the global variable <> is set to +<>. QUICKREF - ansi svid posix rentrant - asin y,y,y,m - asinf n,n,n,m + ansi posix rentrant + asin y,y,m + asinf n,n,m MATHREF asin, -1<=arg<=1, asin(arg),,, @@ -87,24 +83,12 @@ MATHREF return __ieee754_asin(x); #else double z; - struct exception exc; z = __ieee754_asin(x); if(_LIB_VERSION == _IEEE_ || isnan(x)) return z; if(fabs(x)>1.0) { /* asin(|x|>1) */ - exc.type = DOMAIN; - exc.name = "asin"; - exc.err = 0; - exc.arg1 = exc.arg2 = x; - exc.retval = nan(""); - if(_LIB_VERSION == _POSIX_) - errno = EDOM; - else if (!matherr(&exc)) { - errno = EDOM; - } - if (exc.err != 0) - errno = exc.err; - return exc.retval; + errno = EDOM; + return nan(""); } else return z; #endif diff --git a/newlib/libm/math/w_atan2.c b/newlib/libm/math/w_atan2.c index bcf9506bf..4b2bb6a94 100644 --- a/newlib/libm/math/w_atan2.c +++ b/newlib/libm/math/w_atan2.c @@ -50,8 +50,6 @@ RETURNS $-\pi$ to $\pi$. @end tex -You can modify error handling for these functions using <>. - PORTABILITY <> is ANSI C. <> is an extension. diff --git a/newlib/libm/math/w_atanh.c b/newlib/libm/math/w_atanh.c index a87e23cc4..3376aeff7 100644 --- a/newlib/libm/math/w_atanh.c +++ b/newlib/libm/math/w_atanh.c @@ -54,9 +54,6 @@ RETURNS is 1, the global <> is set to <>; and the result is infinity with the same sign as <>. A <> is reported. - You can modify the error handling for these routines using - <>. - PORTABILITY Neither <> nor <> are ANSI C. @@ -87,39 +84,19 @@ QUICKREF return __ieee754_atanh(x); #else double z,y; - struct exception exc; z = __ieee754_atanh(x); if(_LIB_VERSION == _IEEE_ || isnan(x)) return z; y = fabs(x); if(y>=1.0) { if(y>1.0) { - /* atanh(|x|>1) */ - exc.type = DOMAIN; - exc.name = "atanh"; - exc.err = 0; - exc.arg1 = exc.arg2 = x; - exc.retval = 0.0/0.0; - if (_LIB_VERSION == _POSIX_) - errno = EDOM; - else if (!matherr(&exc)) { - errno = EDOM; - } + /* atanh(|x|>1) */ + errno = EDOM; + return 0.0/0.0; } else { - /* atanh(|x|=1) */ - exc.type = SING; - exc.name = "atanh"; - exc.err = 0; - exc.arg1 = exc.arg2 = x; - exc.retval = x/0.0; /* sign(x)*inf */ - if (_LIB_VERSION == _POSIX_) - errno = EDOM; - else if (!matherr(&exc)) { - errno = EDOM; - } - } - if (exc.err != 0) - errno = exc.err; - return exc.retval; + /* atanh(|x|=1) */ + errno = EDOM; + return x/0.0; /* sign(x)*inf */ + } } else return z; #endif diff --git a/newlib/libm/math/w_cosh.c b/newlib/libm/math/w_cosh.c index e5b08df00..a26442178 100644 --- a/newlib/libm/math/w_cosh.c +++ b/newlib/libm/math/w_cosh.c @@ -41,9 +41,6 @@ RETURNS an overflow, <> returns the value <> with the appropriate sign, and the global value <> is set to <>. - You can modify error handling for these functions using the - function <>. - PORTABILITY <> is ANSI. <> is an extension. @@ -73,7 +70,6 @@ QUICKREF return __ieee754_cosh(x); #else double z; - struct exception exc; z = __ieee754_cosh(x); if(_LIB_VERSION == _IEEE_ || isnan(x)) return z; if(fabs(x)>7.10475860073943863426e+02) { @@ -84,22 +80,8 @@ QUICKREF SET_HIGH_WORD(inf,0x7ff00000); /* set inf to infinite */ #endif - exc.type = OVERFLOW; - exc.name = "cosh"; - exc.err = 0; - exc.arg1 = exc.arg2 = x; - if (_LIB_VERSION == _SVID_) - exc.retval = HUGE; - else - exc.retval = HUGE_VAL; - if (_LIB_VERSION == _POSIX_) - errno = ERANGE; - else if (!matherr(&exc)) { - errno = ERANGE; - } - if (exc.err != 0) - errno = exc.err; - return exc.retval; + errno = ERANGE; + return HUGE_VAL; } else return z; #endif diff --git a/newlib/libm/math/w_exp.c b/newlib/libm/math/w_exp.c index 0c4467712..3da6d7702 100644 --- a/newlib/libm/math/w_exp.c +++ b/newlib/libm/math/w_exp.c @@ -34,9 +34,6 @@ DESCRIPTION @end tex is the base of the natural system of logarithms, approximately 2.71828). - You can use the (non-ANSI) function <> to specify - error handling for these functions. - RETURNS On success, <> and <> return the calculated value. If the result underflows, the returned value is <<0>>. If the @@ -77,7 +74,6 @@ u_threshold= -7.45133219101941108420e+02; /* 0xc0874910, 0xD52D3051 */ return __ieee754_exp(x); #else double z; - struct exception exc; z = __ieee754_exp(x); if(_LIB_VERSION == _IEEE_) return z; if(finite(x)) { @@ -89,37 +85,12 @@ u_threshold= -7.45133219101941108420e+02; /* 0xc0874910, 0xD52D3051 */ SET_HIGH_WORD(inf,0x7ff00000); /* set inf to infinite */ #endif - exc.type = OVERFLOW; - exc.name = "exp"; - exc.err = 0; - exc.arg1 = exc.arg2 = x; - if (_LIB_VERSION == _SVID_) - exc.retval = HUGE; - else - exc.retval = HUGE_VAL; - if (_LIB_VERSION == _POSIX_) - errno = ERANGE; - else if (!matherr(&exc)) { - errno = ERANGE; - } - if (exc.err != 0) - errno = exc.err; - return exc.retval; + errno = ERANGE; + return HUGE_VAL; } else if(x> to specify - error handling for these functions. - RETURNS On success, <> and <> return the calculated value. If the result underflows, the returned value is <<0>>. If the diff --git a/newlib/libm/math/w_fmod.c b/newlib/libm/math/w_fmod.c index df11dc34c..678800053 100644 --- a/newlib/libm/math/w_fmod.c +++ b/newlib/libm/math/w_fmod.c @@ -43,8 +43,6 @@ magnitude of <[y]>. <,0)>> returns NaN, and sets <> to <>. -You can modify error treatment for these functions using <>. - PORTABILITY <> is ANSI C. <> is an extension. */ @@ -69,28 +67,12 @@ PORTABILITY return __ieee754_fmod(x,y); #else double z; - struct exception exc; z = __ieee754_fmod(x,y); if(_LIB_VERSION == _IEEE_ ||isnan(y)||isnan(x)) return z; if(y==0.0) { - /* fmod(x,0) */ - exc.type = DOMAIN; - exc.name = "fmod"; - exc.arg1 = x; - exc.arg2 = y; - exc.err = 0; - if (_LIB_VERSION == _SVID_) - exc.retval = x; - else - exc.retval = 0.0/0.0; - if (_LIB_VERSION == _POSIX_) - errno = EDOM; - else if (!matherr(&exc)) { - errno = EDOM; - } - if (exc.err != 0) - errno = exc.err; - return exc.retval; + /* fmod(x,0) */ + errno = EDOM; + return 0.0/0.0; } else return z; #endif diff --git a/newlib/libm/math/w_gamma.c b/newlib/libm/math/w_gamma.c index a1f50b593..6de114a86 100644 --- a/newlib/libm/math/w_gamma.c +++ b/newlib/libm/math/w_gamma.c @@ -121,14 +121,12 @@ When <[x]> is a nonpositive integer, <> returns <> and <> is set to <>. If the result overflows, <> returns <> and <> is set to <>. -You can modify this error treatment using <>. - PORTABILITY Neither <> nor <> is ANSI C. It is better not to use either of these; use <> or <> instead.@* <>, <>, <>, and <> are nominally C standard -in terms of the base return values, although the <> error-handling -is not standard, nor is the <[signgam]> global for <>. +in terms of the base return values, although the <[signgam]> global for +<> is not standard. */ /* double gamma(double x) @@ -154,7 +152,6 @@ is not standard, nor is the <[signgam]> global for <>. return __ieee754_gamma_r(x,&(_REENT_SIGNGAM(_REENT))); #else double y; - struct exception exc; y = __ieee754_gamma_r(x,&(_REENT_SIGNGAM(_REENT))); if(_LIB_VERSION == _IEEE_) return y; if(!finite(y)&&finite(x)) { @@ -164,33 +161,14 @@ is not standard, nor is the <[signgam]> global for <>. SET_HIGH_WORD(inf,0x7ff00000); /* set inf to infinite */ #endif - exc.name = "gamma"; - exc.err = 0; - exc.arg1 = exc.arg2 = x; - if (_LIB_VERSION == _SVID_) - exc.retval = HUGE; - else - exc.retval = HUGE_VAL; if(floor(x)==x&&x<=0.0) { /* gamma(-integer) or gamma(0) */ - exc.type = SING; - if (_LIB_VERSION == _POSIX_) - errno = EDOM; - else if (!matherr(&exc)) { - errno = EDOM; - } - } else { + errno = EDOM; + } else { /* gamma(finite) overflow */ - exc.type = OVERFLOW; - if (_LIB_VERSION == _POSIX_) - errno = ERANGE; - else if (!matherr(&exc)) { - errno = ERANGE; - } - } - if (exc.err != 0) - errno = exc.err; - return exc.retval; + errno = ERANGE; + } + return HUGE_VAL; } else return y; #endif diff --git a/newlib/libm/math/w_hypot.c b/newlib/libm/math/w_hypot.c index 533702277..441fc20cb 100644 --- a/newlib/libm/math/w_hypot.c +++ b/newlib/libm/math/w_hypot.c @@ -41,8 +41,6 @@ RETURNS <> returns <> and sets <> to <>. - You can change the error treatment with <>. - PORTABILITY <> and <> are not ANSI C. */ @@ -66,7 +64,6 @@ PORTABILITY return __ieee754_hypot(x,y); #else double z; - struct exception exc; z = __ieee754_hypot(x,y); if(_LIB_VERSION == _IEEE_) return z; if((!finite(z))&&finite(x)&&finite(y)) { @@ -77,23 +74,8 @@ PORTABILITY SET_HIGH_WORD(inf,0x7ff00000); /* set inf to infinite */ #endif - exc.type = OVERFLOW; - exc.name = "hypot"; - exc.err = 0; - exc.arg1 = x; - exc.arg2 = y; - if (_LIB_VERSION == _SVID_) - exc.retval = HUGE; - else - exc.retval = HUGE_VAL; - if (_LIB_VERSION == _POSIX_) - errno = ERANGE; - else if (!matherr(&exc)) { - errno = ERANGE; - } - if (exc.err != 0) - errno = exc.err; - return exc.retval; + errno = ERANGE; + return HUGE_VAL; } else return z; #endif diff --git a/newlib/libm/math/w_j0.c b/newlib/libm/math/w_j0.c index ab05dbdeb..59d17e8b8 100644 --- a/newlib/libm/math/w_j0.c +++ b/newlib/libm/math/w_j0.c @@ -104,24 +104,12 @@ None of the Bessel functions are in ANSI C. #ifdef _IEEE_LIBM return __ieee754_j0(x); #else - struct exception exc; double z = __ieee754_j0(x); if(_LIB_VERSION == _IEEE_ || isnan(x)) return z; if(fabs(x)>X_TLOSS) { /* j0(|x|>X_TLOSS) */ - exc.type = TLOSS; - exc.name = "j0"; - exc.err = 0; - exc.arg1 = exc.arg2 = x; - exc.retval = 0.0; - if (_LIB_VERSION == _POSIX_) - errno = ERANGE; - else if (!matherr(&exc)) { - errno = ERANGE; - } - if (exc.err != 0) - errno = exc.err; - return exc.retval; + errno = ERANGE; + return 0.0; } else return z; #endif @@ -138,7 +126,6 @@ None of the Bessel functions are in ANSI C. return __ieee754_y0(x); #else double z; - struct exception exc; z = __ieee754_y0(x); if(_LIB_VERSION == _IEEE_ || isnan(x) ) return z; if(x <= 0.0){ @@ -149,38 +136,13 @@ None of the Bessel functions are in ANSI C. SET_HIGH_WORD(inf,0x7ff00000); /* set inf to infinite */ #endif /* y0(0) = -inf or y0(x<0) = NaN */ - exc.type = DOMAIN; /* should be SING for IEEE y0(0) */ - exc.name = "y0"; - exc.err = 0; - exc.arg1 = exc.arg2 = x; - if (_LIB_VERSION == _SVID_) - exc.retval = -HUGE; - else - exc.retval = -HUGE_VAL; - if (_LIB_VERSION == _POSIX_) - errno = EDOM; - else if (!matherr(&exc)) { - errno = EDOM; - } - if (exc.err != 0) - errno = exc.err; - return exc.retval; + errno = EDOM; + return -HUGE_VAL; } if(x>X_TLOSS) { /* y0(x>X_TLOSS) */ - exc.type = TLOSS; - exc.name = "y0"; - exc.err = 0; - exc.arg1 = exc.arg2 = x; - exc.retval = 0.0; - if (_LIB_VERSION == _POSIX_) - errno = ERANGE; - else if (!matherr(&exc)) { - errno = ERANGE; - } - if (exc.err != 0) - errno = exc.err; - return exc.retval; + errno = ERANGE; + return 0.0; } else return z; #endif diff --git a/newlib/libm/math/w_j1.c b/newlib/libm/math/w_j1.c index ba7df1566..127324aad 100644 --- a/newlib/libm/math/w_j1.c +++ b/newlib/libm/math/w_j1.c @@ -31,24 +31,12 @@ return __ieee754_j1(x); #else double z; - struct exception exc; z = __ieee754_j1(x); if(_LIB_VERSION == _IEEE_ || isnan(x) ) return z; if(fabs(x)>X_TLOSS) { /* j1(|x|>X_TLOSS) */ - exc.type = TLOSS; - exc.name = "j1"; - exc.err = 0; - exc.arg1 = exc.arg2 = x; - exc.retval = 0.0; - if (_LIB_VERSION == _POSIX_) - errno = ERANGE; - else if (!matherr(&exc)) { - errno = ERANGE; - } - if (exc.err != 0) - errno = exc.err; - return exc.retval; + errno = ERANGE; + return 0.0; } else return z; #endif @@ -65,7 +53,6 @@ return __ieee754_y1(x); #else double z; - struct exception exc; z = __ieee754_y1(x); if(_LIB_VERSION == _IEEE_ || isnan(x) ) return z; if(x <= 0.0){ @@ -76,38 +63,13 @@ SET_HIGH_WORD(inf,0x7ff00000); /* set inf to infinite */ #endif /* y1(0) = -inf or y1(x<0) = NaN */ - exc.type = DOMAIN; /* should be SING for IEEE */ - exc.name = "y1"; - exc.err = 0; - exc.arg1 = exc.arg2 = x; - if (_LIB_VERSION == _SVID_) - exc.retval = -HUGE; - else - exc.retval = -HUGE_VAL; - if (_LIB_VERSION == _POSIX_) - errno = EDOM; - else if (!matherr(&exc)) { - errno = EDOM; - } - if (exc.err != 0) - errno = exc.err; - return exc.retval; + errno = EDOM; + return -HUGE_VAL; } if(x>X_TLOSS) { /* y1(x>X_TLOSS) */ - exc.type = TLOSS; - exc.name = "y1"; - exc.err = 0; - exc.arg1 = exc.arg2 = x; - exc.retval = 0.0; - if (_LIB_VERSION == _POSIX_) - errno = ERANGE; - else if (!matherr(&exc)) { - errno = ERANGE; - } - if (exc.err != 0) - errno = exc.err; - return exc.retval; + errno = ERANGE; + return 0.0; } else return z; #endif diff --git a/newlib/libm/math/w_jn.c b/newlib/libm/math/w_jn.c index 6cadc9a01..0482fa95a 100644 --- a/newlib/libm/math/w_jn.c +++ b/newlib/libm/math/w_jn.c @@ -53,25 +53,12 @@ return __ieee754_jn(n,x); #else double z; - struct exception exc; z = __ieee754_jn(n,x); if(_LIB_VERSION == _IEEE_ || isnan(x) ) return z; if(fabs(x)>X_TLOSS) { /* jn(|x|>X_TLOSS) */ - exc.type = TLOSS; - exc.name = "jn"; - exc.err = 0; - exc.arg1 = n; - exc.arg2 = x; - exc.retval = 0.0; - if (_LIB_VERSION == _POSIX_) - errno = ERANGE; - else if (!matherr(&exc)) { - errno = ERANGE; - } - if (exc.err != 0) - errno = exc.err; - return exc.retval; + errno = ERANGE; + return 0.0; } else return z; #endif @@ -88,7 +75,6 @@ return __ieee754_yn(n,x); #else double z; - struct exception exc; z = __ieee754_yn(n,x); if(_LIB_VERSION == _IEEE_ || isnan(x) ) return z; if(x <= 0.0){ @@ -99,40 +85,13 @@ SET_HIGH_WORD(inf,0x7ff00000); /* set inf to infinite */ #endif - exc.type = DOMAIN; /* should be SING for IEEE */ - exc.name = "yn"; - exc.err = 0; - exc.arg1 = n; - exc.arg2 = x; - if (_LIB_VERSION == _SVID_) - exc.retval = -HUGE; - else - exc.retval = -HUGE_VAL; - if (_LIB_VERSION == _POSIX_) - errno = EDOM; - else if (!matherr(&exc)) { - errno = EDOM; - } - if (exc.err != 0) - errno = exc.err; - return exc.retval; + errno = EDOM; + return -HUGE_VAL; } if(x>X_TLOSS) { /* yn(x>X_TLOSS) */ - exc.type = TLOSS; - exc.name = "yn"; - exc.err = 0; - exc.arg1 = n; - exc.arg2 = x; - exc.retval = 0.0; - if (_LIB_VERSION == _POSIX_) - errno = ERANGE; - else if (!matherr(&exc)) { - errno = ERANGE; - } - if (exc.err != 0) - errno = exc.err; - return exc.retval; + errno = ERANGE; + return 0.0; } else return z; #endif diff --git a/newlib/libm/math/w_lgamma.c b/newlib/libm/math/w_lgamma.c index e56e47767..f848f1c95 100644 --- a/newlib/libm/math/w_lgamma.c +++ b/newlib/libm/math/w_lgamma.c @@ -35,7 +35,6 @@ return __ieee754_lgamma_r(x,&(_REENT_SIGNGAM(_REENT))); #else double y; - struct exception exc; y = __ieee754_lgamma_r(x,&(_REENT_SIGNGAM(_REENT))); if(_LIB_VERSION == _IEEE_) return y; if(!finite(y)&&finite(x)) { @@ -45,36 +44,14 @@ SET_HIGH_WORD(inf,0x7ff00000); /* set inf to infinite */ #endif - exc.name = "lgamma"; - exc.err = 0; - exc.arg1 = x; - exc.arg2 = x; - if (_LIB_VERSION == _SVID_) - exc.retval = HUGE; - else - exc.retval = HUGE_VAL; - if(floor(x)==x&&x<=0.0) { - /* lgamma(-integer) */ - exc.type = SING; - if (_LIB_VERSION == _POSIX_) - errno = EDOM; - else if (!matherr(&exc)) { - errno = EDOM; - } - - } else { - /* lgamma(finite) overflow */ - exc.type = OVERFLOW; - if (_LIB_VERSION == _POSIX_) - errno = ERANGE; - else if (!matherr(&exc)) { - errno = ERANGE; - } - } - if (exc.err != 0) - errno = exc.err; - return exc.retval; - } else + if(floor(x)==x&&x<=0.0) + /* lgamma(-integer) */ + errno = EDOM; + else + /* lgamma(finite) overflow */ + errno = ERANGE; + return HUGE_VAL; + } else return y; #endif } diff --git a/newlib/libm/math/w_log.c b/newlib/libm/math/w_log.c index 5f66d26ad..37afcac3c 100644 --- a/newlib/libm/math/w_log.c +++ b/newlib/libm/math/w_log.c @@ -30,15 +30,11 @@ Return the natural logarithm of <[x]>, that is, its logarithm base e (where e is the base of the natural system of logarithms, 2.71828@dots{}). <> and <> are identical save for the return and argument types. -You can use the (non-ANSI) function <> to specify error -handling for these functions. - RETURNS Normally, returns the calculated value. When <[x]> is zero, the returned value is <<-HUGE_VAL>> and <> is set to <>. When <[x]> is negative, the returned value is NaN (not a number) and -<> is set to <>. You can control the error behavior via -<>. +<> is set to <>. PORTABILITY <> is ANSI. <> is an extension. @@ -65,7 +61,6 @@ PORTABILITY return __ieee754_log(x); #else double z; - struct exception exc; z = __ieee754_log(x); if(_LIB_VERSION == _IEEE_ || isnan(x) || x > 0.0) return z; #ifndef HUGE_VAL @@ -74,35 +69,15 @@ PORTABILITY SET_HIGH_WORD(inf,0x7ff00000); /* set inf to infinite */ #endif - exc.name = "log"; - exc.err = 0; - exc.arg1 = x; - exc.arg2 = x; - if (_LIB_VERSION == _SVID_) - exc.retval = -HUGE; - else - exc.retval = -HUGE_VAL; if(x==0.0) { /* log(0) */ - exc.type = SING; - if (_LIB_VERSION == _POSIX_) - errno = ERANGE; - else if (!matherr(&exc)) { - errno = ERANGE; - } + errno = ERANGE; + return -HUGE_VAL; } else { /* log(x<0) */ - exc.type = DOMAIN; - if (_LIB_VERSION == _POSIX_) - errno = EDOM; - else if (!matherr(&exc)) { - errno = EDOM; - } - exc.retval = nan(""); + errno = EDOM; + return nan(""); } - if (exc.err != 0) - errno = exc.err; - return exc.retval; #endif } diff --git a/newlib/libm/math/w_log10.c b/newlib/libm/math/w_log10.c index 3b436d539..69ef5f92c 100644 --- a/newlib/libm/math/w_log10.c +++ b/newlib/libm/math/w_log10.c @@ -61,7 +61,6 @@ PORTABILITY return __ieee754_log10(x); #else double z; - struct exception exc; z = __ieee754_log10(x); if(_LIB_VERSION == _IEEE_ || isnan(x)) return z; if(x<=0.0) { @@ -71,35 +70,15 @@ PORTABILITY SET_HIGH_WORD(inf,0x7ff00000); /* set inf to infinite */ #endif - exc.name = "log10"; - exc.err = 0; - exc.arg1 = x; - exc.arg2 = x; - if (_LIB_VERSION == _SVID_) - exc.retval = -HUGE; - else - exc.retval = -HUGE_VAL; if(x==0.0) { - /* log10(0) */ - exc.type = SING; - if (_LIB_VERSION == _POSIX_) - errno = ERANGE; - else if (!matherr(&exc)) { - errno = ERANGE; - } + /* log10(0) */ + errno = ERANGE; + return -HUGE_VAL; } else { - /* log10(x<0) */ - exc.type = DOMAIN; - if (_LIB_VERSION == _POSIX_) - errno = EDOM; - else if (!matherr(&exc)) { - errno = EDOM; - } - exc.retval = nan(""); - } - if (exc.err != 0) - errno = exc.err; - return exc.retval; + /* log10(x<0) */ + errno = EDOM; + return nan(""); + } } else return z; #endif diff --git a/newlib/libm/math/w_pow.c b/newlib/libm/math/w_pow.c index 9d1e396a5..e9ac37051 100644 --- a/newlib/libm/math/w_pow.c +++ b/newlib/libm/math/w_pow.c @@ -42,8 +42,6 @@ RETURNS is set to <>. If <[x]> and <[y]> are both 0, then <> and <> return <<1>>. - You can modify error handling for these functions using <>. - PORTABILITY <> is ANSI C. <> is an extension. */ @@ -74,134 +72,48 @@ PORTABILITY SET_HIGH_WORD(inf,0x7ff00000); /* set inf to infinite */ #endif - struct exception exc; z=__ieee754_pow(x,y); if(_LIB_VERSION == _IEEE_|| isnan(y)) return z; if(isnan(x)) { if(y==0.0) { /* pow(NaN,0.0) */ - /* error only if _LIB_VERSION == _SVID_ & _XOPEN_ */ - exc.type = DOMAIN; - exc.name = "pow"; - exc.err = 0; - exc.arg1 = x; - exc.arg2 = y; - exc.retval = 1.0; - if (_LIB_VERSION == _IEEE_ || - _LIB_VERSION == _POSIX_) exc.retval = 1.0; - else if (!matherr(&exc)) { - errno = EDOM; - } - if (exc.err != 0) - errno = exc.err; - return exc.retval; + /* Not an error. */ + return 1.0; } else return z; } if(x==0.0){ if(y==0.0) { /* pow(0.0,0.0) */ - /* error only if _LIB_VERSION == _SVID_ */ - exc.type = DOMAIN; - exc.name = "pow"; - exc.err = 0; - exc.arg1 = x; - exc.arg2 = y; - exc.retval = 0.0; - if (_LIB_VERSION != _SVID_) exc.retval = 1.0; - else if (!matherr(&exc)) { - errno = EDOM; - } - if (exc.err != 0) - errno = exc.err; - return exc.retval; + /* Not an error. */ + return 1.0; } - if(finite(y)&&y<0.0) { + if(finite(y)&&y<0.0) { /* 0**neg */ - exc.type = DOMAIN; - exc.name = "pow"; - exc.err = 0; - exc.arg1 = x; - exc.arg2 = y; - if (_LIB_VERSION == _SVID_) - exc.retval = 0.0; - else - exc.retval = -HUGE_VAL; - if (_LIB_VERSION == _POSIX_) - errno = EDOM; - else if (!matherr(&exc)) { - errno = EDOM; - } - if (exc.err != 0) - errno = exc.err; - return exc.retval; - } + errno = EDOM; + return -HUGE_VAL; + } return z; } if(!finite(z)) { if(finite(x)&&finite(y)) { if(isnan(z)) { /* neg**non-integral */ - exc.type = DOMAIN; - exc.name = "pow"; - exc.err = 0; - exc.arg1 = x; - exc.arg2 = y; - if (_LIB_VERSION == _SVID_) - exc.retval = 0.0; - else - exc.retval = 0.0/0.0; /* X/Open allow NaN */ - if (_LIB_VERSION == _POSIX_) - errno = EDOM; - else if (!matherr(&exc)) { - errno = EDOM; - } - if (exc.err != 0) - errno = exc.err; - return exc.retval; + errno = EDOM; + return 0.0/0.0; } else { /* pow(x,y) overflow */ - exc.type = OVERFLOW; - exc.name = "pow"; - exc.err = 0; - exc.arg1 = x; - exc.arg2 = y; - if (_LIB_VERSION == _SVID_) { - exc.retval = HUGE; - y *= 0.5; - if(x<0.0&&rint(y)!=y) exc.retval = -HUGE; - } else { - exc.retval = HUGE_VAL; - y *= 0.5; - if(x<0.0&&rint(y)!=y) exc.retval = -HUGE_VAL; - } - if (_LIB_VERSION == _POSIX_) - errno = ERANGE; - else if (!matherr(&exc)) { - errno = ERANGE; - } - if (exc.err != 0) - errno = exc.err; - return exc.retval; + errno = ERANGE; + if(x<0.0&&rint(y)!=y) + return -HUGE_VAL; + return HUGE_VAL; } } } if(z==0.0&&finite(x)&&finite(y)) { /* pow(x,y) underflow */ - exc.type = UNDERFLOW; - exc.name = "pow"; - exc.err = 0; - exc.arg1 = x; - exc.arg2 = y; - exc.retval = 0.0; - if (_LIB_VERSION == _POSIX_) - errno = ERANGE; - else if (!matherr(&exc)) { - errno = ERANGE; - } - if (exc.err != 0) - errno = exc.err; - return exc.retval; + errno = ERANGE; + return 0.0; } return z; #endif diff --git a/newlib/libm/math/w_remainder.c b/newlib/libm/math/w_remainder.c index 5b13390f9..468e38a42 100644 --- a/newlib/libm/math/w_remainder.c +++ b/newlib/libm/math/w_remainder.c @@ -57,25 +57,12 @@ PORTABILITY return __ieee754_remainder(x,y); #else double z; - struct exception exc; z = __ieee754_remainder(x,y); if(_LIB_VERSION == _IEEE_ || isnan(y)) return z; if(y==0.0) { /* remainder(x,0) */ - exc.type = DOMAIN; - exc.name = "remainder"; - exc.err = 0; - exc.arg1 = x; - exc.arg2 = y; - exc.retval = 0.0/0.0; - if (_LIB_VERSION == _POSIX_) - errno = EDOM; - else if (!matherr(&exc)) { - errno = EDOM; - } - if (exc.err != 0) - errno = exc.err; - return exc.retval; + errno = EDOM; + return 0.0/0.0; } else return z; #endif diff --git a/newlib/libm/math/w_scalb.c b/newlib/libm/math/w_scalb.c index c32496892..77fb2af53 100644 --- a/newlib/libm/math/w_scalb.c +++ b/newlib/libm/math/w_scalb.c @@ -47,42 +47,17 @@ SET_HIGH_WORD(inf,0x7ff00000); /* set inf to infinite */ #endif - struct exception exc; z = __ieee754_scalb(x,fn); if(_LIB_VERSION == _IEEE_) return z; if(!(finite(z)||isnan(z))&&finite(x)) { - /* scalb overflow; SVID also returns +-HUGE_VAL */ - exc.type = OVERFLOW; - exc.name = "scalb"; - exc.err = 0; - exc.arg1 = x; - exc.arg2 = fn; - exc.retval = x > 0.0 ? HUGE_VAL : -HUGE_VAL; - if (_LIB_VERSION == _POSIX_) - errno = ERANGE; - else if (!matherr(&exc)) { - errno = ERANGE; - } - if (exc.err != 0) - errno = exc.err; - return exc.retval; + /* scalb overflow */ + errno = ERANGE; + return (x > 0.0 ? HUGE_VAL : -HUGE_VAL); } if(z==0.0&&z!=x) { /* scalb underflow */ - exc.type = UNDERFLOW; - exc.name = "scalb"; - exc.err = 0; - exc.arg1 = x; - exc.arg2 = fn; - exc.retval = copysign(0.0,x); - if (_LIB_VERSION == _POSIX_) - errno = ERANGE; - else if (!matherr(&exc)) { - errno = ERANGE; - } - if (exc.err != 0) - errno = exc.err; - return exc.retval; + errno = ERANGE; + return copysign(0.0,x); } #ifndef _SCALB_INT if(!finite(fn)) errno = ERANGE; diff --git a/newlib/libm/math/w_sinh.c b/newlib/libm/math/w_sinh.c index 340a7112d..0e97e5455 100644 --- a/newlib/libm/math/w_sinh.c +++ b/newlib/libm/math/w_sinh.c @@ -46,8 +46,6 @@ RETURNS appropriate sign, and sets the global value <> to <>. - You can modify error handling for these functions with <>. - PORTABILITY <> is ANSI C. <> is an extension. @@ -77,7 +75,6 @@ QUICKREF return __ieee754_sinh(x); #else double z; - struct exception exc; z = __ieee754_sinh(x); if(_LIB_VERSION == _IEEE_) return z; if(!finite(z)&&finite(x)) { @@ -88,22 +85,8 @@ QUICKREF SET_HIGH_WORD(inf,0x7ff00000); /* set inf to infinite */ #endif - exc.type = OVERFLOW; - exc.name = "sinh"; - exc.err = 0; - exc.arg1 = exc.arg2 = x; - if (_LIB_VERSION == _SVID_) - exc.retval = ( (x>0.0) ? HUGE : -HUGE); - else - exc.retval = ( (x>0.0) ? HUGE_VAL : -HUGE_VAL); - if (_LIB_VERSION == _POSIX_) - errno = ERANGE; - else if (!matherr(&exc)) { - errno = ERANGE; - } - if (exc.err != 0) - errno = exc.err; - return exc.retval; + errno = ERANGE; + return ((x>0.0) ? HUGE_VAL : -HUGE_VAL); } else return z; #endif diff --git a/newlib/libm/math/w_sqrt.c b/newlib/libm/math/w_sqrt.c index 61d42fcec..36e9ad76b 100644 --- a/newlib/libm/math/w_sqrt.c +++ b/newlib/libm/math/w_sqrt.c @@ -27,8 +27,6 @@ SYNOPSIS DESCRIPTION <> computes the positive square root of the argument. - You can modify error handling for this function with - <>. RETURNS On success, the square root is returned. If <[x]> is real and @@ -59,27 +57,12 @@ PORTABILITY #ifdef _IEEE_LIBM return __ieee754_sqrt(x); #else - struct exception exc; double z; z = __ieee754_sqrt(x); if(_LIB_VERSION == _IEEE_ || isnan(x)) return z; if(x<0.0) { - exc.type = DOMAIN; - exc.name = "sqrt"; - exc.err = 0; - exc.arg1 = exc.arg2 = x; - if (_LIB_VERSION == _SVID_) - exc.retval = 0.0; - else - exc.retval = 0.0/0.0; - if (_LIB_VERSION == _POSIX_) - errno = EDOM; - else if (!matherr(&exc)) { - errno = EDOM; - } - if (exc.err != 0) - errno = exc.err; - return exc.retval; + errno = EDOM; + return 0.0/0.0; } else return z; #endif diff --git a/newlib/libm/math/wf_acos.c b/newlib/libm/math/wf_acos.c index 8154c795e..15d869980 100644 --- a/newlib/libm/math/wf_acos.c +++ b/newlib/libm/math/wf_acos.c @@ -26,24 +26,12 @@ return __ieee754_acosf(x); #else float z; - struct exception exc; z = __ieee754_acosf(x); if(_LIB_VERSION == _IEEE_ || isnan(x)) return z; - if(fabsf(x)>(float)1.0) { + if(fabsf(x)>1.0f) { /* acosf(|x|>1) */ - exc.type = DOMAIN; - exc.name = "acosf"; - exc.err = 0; - exc.arg1 = exc.arg2 = (double)x; - exc.retval = nan(""); - if (_LIB_VERSION == _POSIX_) - errno = EDOM; - else if (!matherr(&exc)) { - errno = EDOM; - } - if (exc.err != 0) - errno = exc.err; - return (float)exc.retval; + errno = EDOM; + return (float) nan(""); } else return z; #endif diff --git a/newlib/libm/math/wf_acosh.c b/newlib/libm/math/wf_acosh.c index fc8ec3a0a..6a8000fee 100644 --- a/newlib/libm/math/wf_acosh.c +++ b/newlib/libm/math/wf_acosh.c @@ -32,24 +32,12 @@ return __ieee754_acoshf(x); #else float z; - struct exception exc; z = __ieee754_acoshf(x); if(_LIB_VERSION == _IEEE_ || isnan(x)) return z; - if(x<(float)1.0) { - /* acoshf(x<1) */ - exc.type = DOMAIN; - exc.name = "acoshf"; - exc.err = 0; - exc.arg1 = exc.arg2 = (double)x; - exc.retval = 0.0/0.0; - if (_LIB_VERSION == _POSIX_) - errno = EDOM; - else if (!matherr(&exc)) { - errno = EDOM; - } - if (exc.err != 0) - errno = exc.err; - return (float)exc.retval; + if(x<1.0f) { + /* acoshf(x<1) */ + errno = EDOM; + return 0.0f/0.0f; } else return z; #endif diff --git a/newlib/libm/math/wf_asin.c b/newlib/libm/math/wf_asin.c index 385de5499..2f9ffaf6e 100644 --- a/newlib/libm/math/wf_asin.c +++ b/newlib/libm/math/wf_asin.c @@ -33,24 +33,12 @@ return __ieee754_asinf(x); #else float z; - struct exception exc; z = __ieee754_asinf(x); if(_LIB_VERSION == _IEEE_ || isnan(x)) return z; - if(fabsf(x)>(float)1.0) { + if(fabsf(x)>1.0f) { /* asinf(|x|>1) */ - exc.type = DOMAIN; - exc.name = "asinf"; - exc.err = 0; - exc.arg1 = exc.arg2 = (double)x; - exc.retval = nan(""); - if(_LIB_VERSION == _POSIX_) - errno = EDOM; - else if (!matherr(&exc)) { - errno = EDOM; - } - if (exc.err != 0) - errno = exc.err; - return (float)exc.retval; + errno = EDOM; + return (float)nan(""); } else return z; #endif diff --git a/newlib/libm/math/wf_atanh.c b/newlib/libm/math/wf_atanh.c index 565630411..31e049006 100644 --- a/newlib/libm/math/wf_atanh.c +++ b/newlib/libm/math/wf_atanh.c @@ -30,39 +30,19 @@ return __ieee754_atanhf(x); #else float z,y; - struct exception exc; z = __ieee754_atanhf(x); if(_LIB_VERSION == _IEEE_ || isnan(x)) return z; y = fabsf(x); - if(y>=(float)1.0) { - if(y>(float)1.0) { - /* atanhf(|x|>1) */ - exc.type = DOMAIN; - exc.name = "atanhf"; - exc.err = 0; - exc.arg1 = exc.arg2 = (double)x; - exc.retval = 0.0/0.0; - if (_LIB_VERSION == _POSIX_) - errno = EDOM; - else if (!matherr(&exc)) { - errno = EDOM; - } + if(y>=1.0f) { + if(y>1.0f) { + /* atanhf(|x|>1) */ + errno = EDOM; + return 0.0f/0.0f; } else { - /* atanhf(|x|=1) */ - exc.type = SING; - exc.name = "atanhf"; - exc.err = 0; - exc.arg1 = exc.arg2 = (double)x; - exc.retval = x/0.0; /* sign(x)*inf */ - if (_LIB_VERSION == _POSIX_) - errno = EDOM; - else if (!matherr(&exc)) { - errno = EDOM; - } - } - if (exc.err != 0) - errno = exc.err; - return (float)exc.retval; + /* atanhf(|x|=1) */ + errno = EDOM; + return x/0.0f; /* sign(x)*inf */ + } } else return z; #endif diff --git a/newlib/libm/math/wf_cosh.c b/newlib/libm/math/wf_cosh.c index 02eb12472..1b507b09b 100644 --- a/newlib/libm/math/wf_cosh.c +++ b/newlib/libm/math/wf_cosh.c @@ -31,10 +31,9 @@ return __ieee754_coshf(x); #else float z; - struct exception exc; z = __ieee754_coshf(x); if(_LIB_VERSION == _IEEE_ || isnan(x)) return z; - if(fabsf(x)>(float)8.9415985107e+01) { + if(fabsf(x)>8.9415985107e+01f) { /* coshf(finite) overflow */ #ifndef HUGE_VAL #define HUGE_VAL inf @@ -42,22 +41,8 @@ SET_HIGH_WORD(inf,0x7ff00000); /* set inf to infinite */ #endif - exc.type = OVERFLOW; - exc.name = "coshf"; - exc.err = 0; - exc.arg1 = exc.arg2 = (double)x; - if (_LIB_VERSION == _SVID_) - exc.retval = HUGE; - else - exc.retval = HUGE_VAL; - if (_LIB_VERSION == _POSIX_) - errno = ERANGE; - else if (!matherr(&exc)) { - errno = ERANGE; - } - if (exc.err != 0) - errno = exc.err; - return (float)exc.retval; + errno = ERANGE; + return (float)HUGE_VAL; } else return z; #endif diff --git a/newlib/libm/math/wf_exp.c b/newlib/libm/math/wf_exp.c index f16af1d1b..af1800eeb 100644 --- a/newlib/libm/math/wf_exp.c +++ b/newlib/libm/math/wf_exp.c @@ -40,7 +40,6 @@ u_threshold= -1.0397208405e+02; /* 0xc2cff1b5 */ return __ieee754_expf(x); #else float z; - struct exception exc; z = __ieee754_expf(x); if(_LIB_VERSION == _IEEE_) return z; if(finitef(x)) { @@ -52,37 +51,12 @@ u_threshold= -1.0397208405e+02; /* 0xc2cff1b5 */ SET_HIGH_WORD(inf,0x7ff00000); /* set inf to infinite */ #endif - exc.type = OVERFLOW; - exc.name = "expf"; - exc.err = 0; - exc.arg1 = exc.arg2 = (double)x; - if (_LIB_VERSION == _SVID_) - exc.retval = HUGE; - else - exc.retval = HUGE_VAL; - if (_LIB_VERSION == _POSIX_) - errno = ERANGE; - else if (!matherr(&exc)) { - errno = ERANGE; - } - if (exc.err != 0) - errno = exc.err; - return exc.retval; + errno = ERANGE; + return HUGE_VAL; } else if(x(float)X_TLOSS) { /* j0f(|x|>X_TLOSS) */ - exc.type = TLOSS; - exc.name = "j0f"; - exc.err = 0; - exc.arg1 = exc.arg2 = (double)x; - exc.retval = 0.0; - if (_LIB_VERSION == _POSIX_) - errno = ERANGE; - else if (!matherr(&exc)) { - errno = ERANGE; - } - if (exc.err != 0) - errno = exc.err; - return (float)exc.retval; + errno = ERANGE; + return 0.0f; } else return z; #endif @@ -64,7 +52,6 @@ return __ieee754_y0f(x); #else float z; - struct exception exc; z = __ieee754_y0f(x); if(_LIB_VERSION == _IEEE_ || isnan(x) ) return z; if(x <= (float)0.0){ @@ -75,38 +62,13 @@ SET_HIGH_WORD(inf,0x7ff00000); /* set inf to infinite */ #endif /* y0f(0) = -inf or y0f(x<0) = NaN */ - exc.type = DOMAIN; /* should be SING for IEEE y0f(0) */ - exc.name = "y0f"; - exc.err = 0; - exc.arg1 = exc.arg2 = (double)x; - if (_LIB_VERSION == _SVID_) - exc.retval = -HUGE; - else - exc.retval = -HUGE_VAL; - if (_LIB_VERSION == _POSIX_) - errno = EDOM; - else if (!matherr(&exc)) { - errno = EDOM; - } - if (exc.err != 0) - errno = exc.err; - return (float)exc.retval; + errno = EDOM; + return (float)-HUGE_VAL; } if(x>(float)X_TLOSS) { /* y0f(x>X_TLOSS) */ - exc.type = TLOSS; - exc.name = "y0f"; - exc.err = 0; - exc.arg1 = exc.arg2 = (double)x; - exc.retval = 0.0; - if (_LIB_VERSION == _POSIX_) - errno = ERANGE; - else if (!matherr(&exc)) { - errno = ERANGE; - } - if (exc.err != 0) - errno = exc.err; - return (float)exc.retval; + errno = ERANGE; + return 0.0f; } else return z; #endif diff --git a/newlib/libm/math/wf_j1.c b/newlib/libm/math/wf_j1.c index b91962881..01c9999c6 100644 --- a/newlib/libm/math/wf_j1.c +++ b/newlib/libm/math/wf_j1.c @@ -32,24 +32,12 @@ return __ieee754_j1f(x); #else float z; - struct exception exc; z = __ieee754_j1f(x); if(_LIB_VERSION == _IEEE_ || isnan(x) ) return z; if(fabsf(x)>(float)X_TLOSS) { /* j1f(|x|>X_TLOSS) */ - exc.type = TLOSS; - exc.name = "j1f"; - exc.err = 0; - exc.arg1 = exc.arg2 = (double)x; - exc.retval = 0.0; - if (_LIB_VERSION == _POSIX_) - errno = ERANGE; - else if (!matherr(&exc)) { - errno = ERANGE; - } - if (exc.err != 0) - errno = exc.err; - return exc.retval; + errno = ERANGE; + return 0.0f; } else return z; #endif @@ -66,10 +54,9 @@ return __ieee754_y1f(x); #else float z; - struct exception exc; z = __ieee754_y1f(x); if(_LIB_VERSION == _IEEE_ || isnan(x) ) return z; - if(x <= (float)0.0){ + if(x <= 0.0f){ /* y1f(0) = -inf or y1f(x<0) = NaN */ #ifndef HUGE_VAL #define HUGE_VAL inf @@ -77,38 +64,13 @@ SET_HIGH_WORD(inf,0x7ff00000); /* set inf to infinite */ #endif - exc.type = DOMAIN; /* should be SING for IEEE */ - exc.name = "y1f"; - exc.err = 0; - exc.arg1 = exc.arg2 = (double)x; - if (_LIB_VERSION == _SVID_) - exc.retval = -HUGE; - else - exc.retval = -HUGE_VAL; - if (_LIB_VERSION == _POSIX_) - errno = EDOM; - else if (!matherr(&exc)) { - errno = EDOM; - } - if (exc.err != 0) - errno = exc.err; - return (float)exc.retval; + errno = EDOM; + return (float)-HUGE_VAL; } if(x>(float)X_TLOSS) { /* y1f(x>X_TLOSS) */ - exc.type = TLOSS; - exc.name = "y1f"; - exc.err = 0; - exc.arg1 = exc.arg2 = (double)x; - exc.retval = 0.0; - if (_LIB_VERSION == _POSIX_) - errno = ERANGE; - else if (!matherr(&exc)) { - errno = ERANGE; - } - if (exc.err != 0) - errno = exc.err; - return (float)exc.retval; + errno = ERANGE; + return 0.0f; } else return z; #endif diff --git a/newlib/libm/math/wf_jn.c b/newlib/libm/math/wf_jn.c index 837b6b703..b41837273 100644 --- a/newlib/libm/math/wf_jn.c +++ b/newlib/libm/math/wf_jn.c @@ -28,25 +28,12 @@ return __ieee754_jnf(n,x); #else float z; - struct exception exc; z = __ieee754_jnf(n,x); if(_LIB_VERSION == _IEEE_ || isnan(x) ) return z; if(fabsf(x)>(float)X_TLOSS) { /* jnf(|x|>X_TLOSS) */ - exc.type = TLOSS; - exc.name = "jnf"; - exc.err = 0; - exc.arg1 = (double)n; - exc.arg2 = (double)x; - exc.retval = 0.0; - if (_LIB_VERSION == _POSIX_) - errno = ERANGE; - else if (!matherr(&exc)) { - errno = ERANGE; - } - if (exc.err != 0) - errno = exc.err; - return exc.retval; + errno = ERANGE; + return 0.0f; } else return z; #endif @@ -63,10 +50,9 @@ return __ieee754_ynf(n,x); #else float z; - struct exception exc; z = __ieee754_ynf(n,x); if(_LIB_VERSION == _IEEE_ || isnan(x) ) return z; - if(x <= (float)0.0){ + if(x <= 0.0f){ /* ynf(n,0) = -inf or ynf(x<0) = NaN */ #ifndef HUGE_VAL #define HUGE_VAL inf @@ -74,40 +60,13 @@ SET_HIGH_WORD(inf,0x7ff00000); /* set inf to infinite */ #endif - exc.type = DOMAIN; /* should be SING for IEEE */ - exc.name = "ynf"; - exc.err = 0; - exc.arg1 = (double)n; - exc.arg2 = (double)x; - if (_LIB_VERSION == _SVID_) - exc.retval = -HUGE; - else - exc.retval = -HUGE_VAL; - if (_LIB_VERSION == _POSIX_) - errno = EDOM; - else if (!matherr(&exc)) { - errno = EDOM; - } - if (exc.err != 0) - errno = exc.err; - return (float)exc.retval; + errno = EDOM; + return (float)-HUGE_VAL; } if(x>(float)X_TLOSS) { /* ynf(x>X_TLOSS) */ - exc.type = TLOSS; - exc.name = "ynf"; - exc.err = 0; - exc.arg1 = (double)n; - exc.arg2 = (double)x; - exc.retval = 0.0; - if (_LIB_VERSION == _POSIX_) - errno = ERANGE; - else if (!matherr(&exc)) { - errno = ERANGE; - } - if (exc.err != 0) - errno = exc.err; - return (float)exc.retval; + errno = ERANGE; + return 0.0f; } else return z; #endif diff --git a/newlib/libm/math/wf_lgamma.c b/newlib/libm/math/wf_lgamma.c index f1bf0c019..574111e36 100644 --- a/newlib/libm/math/wf_lgamma.c +++ b/newlib/libm/math/wf_lgamma.c @@ -29,7 +29,6 @@ return __ieee754_lgammaf_r(x,&(_REENT_SIGNGAM(_REENT))); #else float y; - struct exception exc; y = __ieee754_lgammaf_r(x,&(_REENT_SIGNGAM(_REENT))); if(_LIB_VERSION == _IEEE_) return y; if(!finitef(y)&&finitef(x)) { @@ -39,34 +38,14 @@ SET_HIGH_WORD(inf,0x7ff00000); /* set inf to infinite */ #endif - exc.name = "lgammaf"; - exc.err = 0; - exc.arg1 = exc.arg2 = (double)x; - if (_LIB_VERSION == _SVID_) - exc.retval = HUGE; - else - exc.retval = HUGE_VAL; - if(floorf(x)==x&&x<=(float)0.0) { + if(floorf(x)==x&&x<=0.0f) { /* lgammaf(-integer) */ - exc.type = SING; - if (_LIB_VERSION == _POSIX_) - errno = EDOM; - else if (!matherr(&exc)) { - errno = EDOM; - } - - } else { + errno = EDOM; + } else { /* lgammaf(finite) overflow */ - exc.type = OVERFLOW; - if (_LIB_VERSION == _POSIX_) - errno = ERANGE; - else if (!matherr(&exc)) { - errno = ERANGE; - } - } - if (exc.err != 0) - errno = exc.err; - return (float)exc.retval; + errno = ERANGE; + } + return (float)HUGE_VAL; } else return y; #endif diff --git a/newlib/libm/math/wf_log.c b/newlib/libm/math/wf_log.c index 07be8d63c..24e6eeb80 100644 --- a/newlib/libm/math/wf_log.c +++ b/newlib/libm/math/wf_log.c @@ -32,43 +32,23 @@ return __ieee754_logf(x); #else float z; - struct exception exc; z = __ieee754_logf(x); - if(_LIB_VERSION == _IEEE_ || isnan(x) || x > (float)0.0) return z; + if(_LIB_VERSION == _IEEE_ || isnan(x) || x > 0.0f) return z; #ifndef HUGE_VAL #define HUGE_VAL inf double inf = 0.0; SET_HIGH_WORD(inf,0x7ff00000); /* set inf to infinite */ #endif - exc.name = "logf"; - exc.err = 0; - exc.arg1 = exc.arg2 = (double)x; - if (_LIB_VERSION == _SVID_) - exc.retval = -HUGE; - else - exc.retval = -HUGE_VAL; - if(x==(float)0.0) { + if(x==0.0f) { /* logf(0) */ - exc.type = SING; - if (_LIB_VERSION == _POSIX_) - errno = ERANGE; - else if (!matherr(&exc)) { - errno = ERANGE; - } + errno = ERANGE; + return (float)-HUGE_VAL; } else { /* logf(x<0) */ - exc.type = DOMAIN; - if (_LIB_VERSION == _POSIX_) - errno = EDOM; - else if (!matherr(&exc)) { - errno = EDOM; - } - exc.retval = nan(""); + errno = EDOM; + return nan(""); } - if (exc.err != 0) - errno = exc.err; - return (float)exc.retval; #endif } diff --git a/newlib/libm/math/wf_log10.c b/newlib/libm/math/wf_log10.c index 11c595637..3560c5c0e 100644 --- a/newlib/libm/math/wf_log10.c +++ b/newlib/libm/math/wf_log10.c @@ -31,44 +31,24 @@ return __ieee754_log10f(x); #else float z; - struct exception exc; z = __ieee754_log10f(x); if(_LIB_VERSION == _IEEE_ || isnan(x)) return z; - if(x<=(float)0.0) { + if(x<=0.0f) { #ifndef HUGE_VAL #define HUGE_VAL inf double inf = 0.0; SET_HIGH_WORD(inf,0x7ff00000); /* set inf to infinite */ #endif - exc.name = "log10f"; - exc.err = 0; - exc.arg1 = exc.arg2 = (double)x; - if (_LIB_VERSION == _SVID_) - exc.retval = -HUGE; - else - exc.retval = -HUGE_VAL; - if(x==(float)0.0) { - /* log10f(0) */ - exc.type = SING; - if (_LIB_VERSION == _POSIX_) - errno = ERANGE; - else if (!matherr(&exc)) { - errno = ERANGE; - } + if(x==0.0f) { + /* log10f(0) */ + errno = ERANGE; + return (float)-HUGE_VAL; } else { - /* log10f(x<0) */ - exc.type = DOMAIN; - if (_LIB_VERSION == _POSIX_) - errno = EDOM; - else if (!matherr(&exc)) { - errno = EDOM; - } - exc.retval = nan(""); + /* log10f(x<0) */ + errno = EDOM; + return nan(""); } - if (exc.err != 0) - errno = exc.err; - return (float)exc.retval; } else return z; #endif diff --git a/newlib/libm/math/wf_pow.c b/newlib/libm/math/wf_pow.c index f753b5226..2288977e9 100644 --- a/newlib/libm/math/wf_pow.c +++ b/newlib/libm/math/wf_pow.c @@ -32,136 +32,50 @@ return __ieee754_powf(x,y); #else float z; - struct exception exc; z=__ieee754_powf(x,y); if(_LIB_VERSION == _IEEE_|| isnan(y)) return z; if(isnan(x)) { - if(y==(float)0.0) { + if(y==0.0f) { /* powf(NaN,0.0) */ - /* error only if _LIB_VERSION == _SVID_ & _XOPEN_ */ - exc.type = DOMAIN; - exc.name = "powf"; - exc.err = 0; - exc.arg1 = (double)x; - exc.arg2 = (double)y; - exc.retval = 1.0; - if (_LIB_VERSION == _IEEE_ || - _LIB_VERSION == _POSIX_) exc.retval = 1.0; - else if (!matherr(&exc)) { - errno = EDOM; - } - if (exc.err != 0) - errno = exc.err; - return (float)exc.retval; + /* Not an error. */ + return 1.0f; } else return z; } - if(x==(float)0.0){ - if(y==(float)0.0) { + if(x==0.0f){ + if(y==0.0f) { /* powf(0.0,0.0) */ - /* error only if _LIB_VERSION == _SVID_ */ - exc.type = DOMAIN; - exc.name = "powf"; - exc.err = 0; - exc.arg1 = (double)x; - exc.arg2 = (double)y; - exc.retval = 0.0; - if (_LIB_VERSION != _SVID_) exc.retval = 1.0; - else if (!matherr(&exc)) { - errno = EDOM; - } - if (exc.err != 0) - errno = exc.err; - return (float)exc.retval; + /* Not an error. */ + return 1.0f; } - if(finitef(y)&&y<(float)0.0) { + if(finitef(y)&&y<0.0f) { /* 0**neg */ - exc.type = DOMAIN; - exc.name = "powf"; - exc.err = 0; - exc.arg1 = (double)x; - exc.arg2 = (double)y; - if (_LIB_VERSION == _SVID_) - exc.retval = 0.0; - else - exc.retval = -HUGE_VAL; - if (_LIB_VERSION == _POSIX_) - errno = EDOM; - else if (!matherr(&exc)) { - errno = EDOM; - } - if (exc.err != 0) - errno = exc.err; - return (float)exc.retval; - } + errno = EDOM; + return (float)-HUGE_VAL; + } return z; } if(!finitef(z)) { if(finitef(x)&&finitef(y)) { - if(isnan(z)) { + if(isnan(z)) { /* neg**non-integral */ - exc.type = DOMAIN; - exc.name = "powf"; - exc.err = 0; - exc.arg1 = (double)x; - exc.arg2 = (double)y; - if (_LIB_VERSION == _SVID_) - exc.retval = 0.0; - else - /* Use a float divide, to avoid a soft-float double - divide call on single-float only targets. */ - exc.retval = (0.0f/0.0f); /* X/Open allow NaN */ - if (_LIB_VERSION == _POSIX_) - errno = EDOM; - else if (!matherr(&exc)) { - errno = EDOM; - } - if (exc.err != 0) - errno = exc.err; - return (float)exc.retval; - } else { + errno = EDOM; + /* Use a float divide, to avoid a soft-float double + divide call on single-float only targets. */ + return 0.0f/0.0f; + } else { /* powf(x,y) overflow */ - exc.type = OVERFLOW; - exc.name = "powf"; - exc.err = 0; - exc.arg1 = (double)x; - exc.arg2 = (double)y; - if (_LIB_VERSION == _SVID_) { - exc.retval = HUGE; - y *= 0.5; - if(x<0.0f&&rintf(y)!=y) exc.retval = -HUGE; - } else { - exc.retval = HUGE_VAL; - y *= 0.5; - if(x<0.0f&&rintf(y)!=y) exc.retval = -HUGE_VAL; - } - if (_LIB_VERSION == _POSIX_) - errno = ERANGE; - else if (!matherr(&exc)) { - errno = ERANGE; - } - if (exc.err != 0) - errno = exc.err; - return (float)exc.retval; - } + errno = ERANGE; + if(x<0.0f&&rintf(y)!=y) + return (float)-HUGE_VAL; + return (float)HUGE_VAL; + } } } - if(z==(float)0.0&&finitef(x)&&finitef(y)) { + if(z==0.0f&&finitef(x)&&finitef(y)) { /* powf(x,y) underflow */ - exc.type = UNDERFLOW; - exc.name = "powf"; - exc.err = 0; - exc.arg1 = (double)x; - exc.arg2 = (double)y; - exc.retval = 0.0; - if (_LIB_VERSION == _POSIX_) - errno = ERANGE; - else if (!matherr(&exc)) { - errno = ERANGE; - } - if (exc.err != 0) - errno = exc.err; - return (float)exc.retval; + errno = ERANGE; + return 0.0f; } return z; #endif diff --git a/newlib/libm/math/wf_remainder.c b/newlib/libm/math/wf_remainder.c index f38c23785..463d1bc32 100644 --- a/newlib/libm/math/wf_remainder.c +++ b/newlib/libm/math/wf_remainder.c @@ -31,25 +31,12 @@ return __ieee754_remainderf(x,y); #else float z; - struct exception exc; z = __ieee754_remainderf(x,y); if(_LIB_VERSION == _IEEE_ || isnan(y)) return z; - if(y==(float)0.0) { - /* remainderf(x,0) */ - exc.type = DOMAIN; - exc.name = "remainderf"; - exc.err = 0; - exc.arg1 = (double)x; - exc.arg2 = (double)y; - exc.retval = 0.0/0.0; - if (_LIB_VERSION == _POSIX_) - errno = EDOM; - else if (!matherr(&exc)) { - errno = EDOM; - } - if (exc.err != 0) - errno = exc.err; - return (float)exc.retval; + if(y==0.0f) { + /* remainderf(x,0) */ + errno = EDOM; + return 0.0f/0.0f; } else return z; #endif diff --git a/newlib/libm/math/wf_scalb.c b/newlib/libm/math/wf_scalb.c index d2c3cd2aa..acdf8a80d 100644 --- a/newlib/libm/math/wf_scalb.c +++ b/newlib/libm/math/wf_scalb.c @@ -47,42 +47,17 @@ SET_HIGH_WORD(inf,0x7ff00000); /* set inf to infinite */ #endif - struct exception exc; z = __ieee754_scalbf(x,fn); if(_LIB_VERSION == _IEEE_) return z; if(!(finitef(z)||isnan(z))&&finitef(x)) { - /* scalbf overflow; SVID also returns +-HUGE_VAL */ - exc.type = OVERFLOW; - exc.name = "scalbf"; - exc.err = 0; - exc.arg1 = (double)x; - exc.arg2 = (double)fn; - exc.retval = x > 0.0 ? HUGE_VAL : -HUGE_VAL; - if (_LIB_VERSION == _POSIX_) - errno = ERANGE; - else if (!matherr(&exc)) { - errno = ERANGE; - } - if (exc.err != 0) - errno = exc.err; - return exc.retval; + /* scalbf overflow; */ + errno = ERANGE; + return (x > 0.0 ? HUGE_VAL : -HUGE_VAL); } - if(z==(float)0.0&&z!=x) { + if(z==0.0f&&z!=x) { /* scalbf underflow */ - exc.type = UNDERFLOW; - exc.name = "scalbf"; - exc.err = 0; - exc.arg1 = (double)x; - exc.arg2 = (double)fn; - exc.retval = copysign(0.0,x); - if (_LIB_VERSION == _POSIX_) - errno = ERANGE; - else if (!matherr(&exc)) { - errno = ERANGE; - } - if (exc.err != 0) - errno = exc.err; - return exc.retval; + errno = ERANGE; + return copysign(0.0,x); } #ifndef _SCALB_INT if(!finitef(fn)) errno = ERANGE; diff --git a/newlib/libm/math/wf_sinh.c b/newlib/libm/math/wf_sinh.c index 80c7a8e6e..f7d5a9665 100644 --- a/newlib/libm/math/wf_sinh.c +++ b/newlib/libm/math/wf_sinh.c @@ -31,7 +31,6 @@ return __ieee754_sinhf(x); #else float z; - struct exception exc; z = __ieee754_sinhf(x); if(_LIB_VERSION == _IEEE_) return z; if(!finitef(z)&&finitef(x)) { @@ -42,22 +41,8 @@ SET_HIGH_WORD(inf,0x7ff00000); /* set inf to infinite */ #endif - exc.type = OVERFLOW; - exc.name = "sinhf"; - exc.err = 0; - exc.arg1 = exc.arg2 = (double)x; - if (_LIB_VERSION == _SVID_) - exc.retval = ( (x>0.0) ? HUGE : -HUGE); - else - exc.retval = ( (x>0.0) ? HUGE_VAL : -HUGE_VAL); - if (_LIB_VERSION == _POSIX_) - errno = ERANGE; - else if (!matherr(&exc)) { - errno = ERANGE; - } - if (exc.err != 0) - errno = exc.err; - return (float)exc.retval; + errno = ERANGE; + return ( (x>0.0f) ? HUGE_VAL : -HUGE_VAL); } else return z; #endif diff --git a/newlib/libm/math/wf_sqrt.c b/newlib/libm/math/wf_sqrt.c index 4536ba0ac..4107511ae 100644 --- a/newlib/libm/math/wf_sqrt.c +++ b/newlib/libm/math/wf_sqrt.c @@ -31,27 +31,12 @@ return __ieee754_sqrtf(x); #else float z; - struct exception exc; z = __ieee754_sqrtf(x); if(_LIB_VERSION == _IEEE_ || isnan(x)) return z; - if(x<(float)0.0) { - /* sqrtf(negative) */ - exc.type = DOMAIN; - exc.name = "sqrtf"; - exc.err = 0; - exc.arg1 = exc.arg2 = (double)x; - if (_LIB_VERSION == _SVID_) - exc.retval = 0.0; - else - exc.retval = 0.0/0.0; - if (_LIB_VERSION == _POSIX_) - errno = EDOM; - else if (!matherr(&exc)) { - errno = EDOM; - } - if (exc.err != 0) - errno = exc.err; - return (float)exc.retval; + if(x<0.0f) { + /* sqrtf(negative) */ + errno = EDOM; + return 0.0f/0.0f; } else return z; #endif diff --git a/newlib/libm/math/wr_gamma.c b/newlib/libm/math/wr_gamma.c index 0092ed02c..f07908c8a 100644 --- a/newlib/libm/math/wr_gamma.c +++ b/newlib/libm/math/wr_gamma.c @@ -31,7 +31,6 @@ return __ieee754_gamma_r(x,signgamp); #else double y; - struct exception exc; y = __ieee754_gamma_r(x,signgamp); if(_LIB_VERSION == _IEEE_) return y; if(!finite(y)&&finite(x)) { @@ -41,33 +40,13 @@ SET_HIGH_WORD(inf,0x7ff00000); /* set inf to infinite */ #endif - exc.name = "gamma"; - exc.err = 0; - exc.arg1 = exc.arg2 = (double)x; - if (_LIB_VERSION == _SVID_) - exc.retval = HUGE; - else - exc.retval = HUGE_VAL; - if(floor(x)==x&&x<=0.0) { - /* gamma(-integer) or gamma(0) */ - exc.type = SING; - if (_LIB_VERSION == _POSIX_) - errno = EDOM; - else if (!matherr(&exc)) { - errno = EDOM; - } - } else { - /* gamma(finite) overflow */ - exc.type = OVERFLOW; - if (_LIB_VERSION == _POSIX_) - errno = ERANGE; - else if (!matherr(&exc)) { - errno = ERANGE; - } - } - if (exc.err != 0) - errno = exc.err; - return exc.retval; + if(floor(x)==x&&x<=0.0) + /* gamma(-integer) or gamma(0) */ + errno = EDOM; + else + /* gamma(finite) overflow */ + errno = ERANGE; + return HUGE_VAL; } else return y; #endif diff --git a/newlib/libm/math/wr_lgamma.c b/newlib/libm/math/wr_lgamma.c index c59c1cce9..8a32a59b8 100644 --- a/newlib/libm/math/wr_lgamma.c +++ b/newlib/libm/math/wr_lgamma.c @@ -31,7 +31,6 @@ return __ieee754_lgamma_r(x,signgamp); #else double y; - struct exception exc; y = __ieee754_lgamma_r(x,signgamp); if(_LIB_VERSION == _IEEE_) return y; if(!finite(y)&&finite(x)) { @@ -41,34 +40,13 @@ SET_HIGH_WORD(inf,0x7ff00000); /* set inf to infinite */ #endif - exc.name = "lgamma"; - exc.err = 0; - exc.arg1 = exc.arg2 = (double)x; - if (_LIB_VERSION == _SVID_) - exc.retval = HUGE; - else - exc.retval = HUGE_VAL; - if(floor(x)==x&&x<=0.0) { - /* lgamma(-integer) */ - exc.type = SING; - if (_LIB_VERSION == _POSIX_) - errno = EDOM; - else if (!matherr(&exc)) { - errno = EDOM; - } - - } else { - /* lgamma(finite) overflow */ - exc.type = OVERFLOW; - if (_LIB_VERSION == _POSIX_) - errno = ERANGE; - else if (!matherr(&exc)) { - errno = ERANGE; - } - } - if (exc.err != 0) - errno = exc.err; - return exc.retval; + if(floor(x)==x&&x<=0.0) + /* lgamma(-integer) */ + errno = EDOM; + else + /* lgamma(finite) overflow */ + errno = ERANGE; + return HUGE_VAL; } else return y; #endif diff --git a/newlib/libm/math/wrf_gamma.c b/newlib/libm/math/wrf_gamma.c index ae285f564..625ea4772 100644 --- a/newlib/libm/math/wrf_gamma.c +++ b/newlib/libm/math/wrf_gamma.c @@ -31,7 +31,6 @@ return __ieee754_gammaf_r(x,signgamp); #else float y; - struct exception exc; y = __ieee754_gammaf_r(x,signgamp); if(_LIB_VERSION == _IEEE_) return y; if(!finitef(y)&&finitef(x)) { @@ -41,33 +40,14 @@ SET_HIGH_WORD(inf,0x7ff00000); /* set inf to infinite */ #endif - exc.name = "gammaf"; - exc.err = 0; - exc.arg1 = exc.arg2 = (double)x; - if (_LIB_VERSION == _SVID_) - exc.retval = HUGE; - else - exc.retval = HUGE_VAL; - if(floorf(x)==x&&x<=(float)0.0) { + if(floorf(x)==x&&x<=0.0f) { /* gammaf(-integer) or gamma(0) */ - exc.type = SING; - if (_LIB_VERSION == _POSIX_) - errno = EDOM; - else if (!matherr(&exc)) { - errno = EDOM; - } - } else { + errno = EDOM; + } else { /* gammaf(finite) overflow */ - exc.type = OVERFLOW; - if (_LIB_VERSION == _POSIX_) - errno = ERANGE; - else if (!matherr(&exc)) { - errno = ERANGE; - } - } - if (exc.err != 0) - errno = exc.err; - return (float)exc.retval; + errno = ERANGE; + } + return (float)HUGE_VAL; } else return y; #endif diff --git a/newlib/libm/math/wrf_lgamma.c b/newlib/libm/math/wrf_lgamma.c index 73985e271..e91bffb38 100644 --- a/newlib/libm/math/wrf_lgamma.c +++ b/newlib/libm/math/wrf_lgamma.c @@ -31,7 +31,6 @@ return __ieee754_lgammaf_r(x,signgamp); #else float y; - struct exception exc; y = __ieee754_lgammaf_r(x,signgamp); if(_LIB_VERSION == _IEEE_) return y; if(!finitef(y)&&finitef(x)) { @@ -41,34 +40,14 @@ SET_HIGH_WORD(inf,0x7ff00000); /* set inf to infinite */ #endif - exc.name = "lgammaf"; - exc.err = 0; - exc.arg1 = exc.arg2 = (double)x; - if (_LIB_VERSION == _SVID_) - exc.retval = HUGE; - else - exc.retval = HUGE_VAL; - if(floorf(x)==x&&x<=(float)0.0) { + if(floorf(x)==x&&x<=0.0f) { /* lgammaf(-integer) or lgamma(0) */ - exc.type = SING; - if (_LIB_VERSION == _POSIX_) - errno = EDOM; - else if (!matherr(&exc)) { - errno = EDOM; - } - - } else { + errno = EDOM; + } else { /* lgammaf(finite) overflow */ - exc.type = OVERFLOW; - if (_LIB_VERSION == _POSIX_) - errno = ERANGE; - else if (!matherr(&exc)) { - errno = ERANGE; - } - } - if (exc.err != 0) - errno = exc.err; - return (float)exc.retval; + errno = ERANGE; + } + return (float)HUGE_VAL; } else return y; #endif diff --git a/newlib/libm/mathfp/e_acosh.c b/newlib/libm/mathfp/e_acosh.c index 0ad0f0611..1146b1d87 100644 --- a/newlib/libm/mathfp/e_acosh.c +++ b/newlib/libm/mathfp/e_acosh.c @@ -33,18 +33,15 @@ RETURNS <> and <> return the calculated value. If <[x]> less than 1, the return value is NaN and <> is set to <>. -You can change the error-handling behavior with the non-ANSI -<> function. - PORTABILITY Neither <> nor <> are ANSI C. They are not recommended for portable programs. QUICKREF - ansi svid posix rentrant - acos n,n,n,m - acosf n,n,n,m + ansi posix rentrant + acos n,n,m + acosf n,n,m MATHREF acosh, NAN, arg,DOMAIN,EDOM diff --git a/newlib/libm/mathfp/e_atanh.c b/newlib/libm/mathfp/e_atanh.c index 072c44607..d56d50216 100644 --- a/newlib/libm/mathfp/e_atanh.c +++ b/newlib/libm/mathfp/e_atanh.c @@ -55,9 +55,6 @@ RETURNS is 1, the global <> is set to <>; and the result is infinity with the same sign as <>. A <> is reported. - You can modify the error handling for these routines using - <>. - PORTABILITY Neither <> nor <> are ANSI C. diff --git a/newlib/libm/mathfp/e_hypot.c b/newlib/libm/mathfp/e_hypot.c index 1a59afcde..2729eeb6c 100644 --- a/newlib/libm/mathfp/e_hypot.c +++ b/newlib/libm/mathfp/e_hypot.c @@ -41,8 +41,6 @@ RETURNS <> returns <> and sets <> to <>. - You can change the error treatment with <>. - PORTABILITY <> and <> are not ANSI C. */ diff --git a/newlib/libm/mathfp/er_lgamma.c b/newlib/libm/mathfp/er_lgamma.c index 915dac7d0..cb0f2c257 100644 --- a/newlib/libm/mathfp/er_lgamma.c +++ b/newlib/libm/mathfp/er_lgamma.c @@ -97,8 +97,6 @@ When <[x]> is a nonpositive integer, <> returns <> and <> is set to <>. If the result overflows, <> returns <> and <> is set to <>. -You can modify this error treatment using <>. - PORTABILITY Neither <> nor <> is ANSI C. */ diff --git a/newlib/libm/mathfp/s_acos.c b/newlib/libm/mathfp/s_acos.c index d0318e1c7..d43b45c6c 100644 --- a/newlib/libm/mathfp/s_acos.c +++ b/newlib/libm/mathfp/s_acos.c @@ -37,13 +37,10 @@ o $\pi$. (not a number) the global variable <> is set to <>, and a <> message is sent as standard error output. - You can modify error handling for these functions using <>. - - QUICKREF - ansi svid posix rentrant - acos y,y,y,m - acosf n,n,n,m + ansi posix rentrant + acos y,y,m + acosf n,n,m MATHREF acos, [-1,1], acos(arg),,, diff --git a/newlib/libm/mathfp/s_atan2.c b/newlib/libm/mathfp/s_atan2.c index 395253905..d8ba3a2b1 100644 --- a/newlib/libm/mathfp/s_atan2.c +++ b/newlib/libm/mathfp/s_atan2.c @@ -41,8 +41,6 @@ $-\pi$ to $\pi$. If both <[x]> and <[y]> are 0.0, <> causes a <> error. -You can modify error handling for these functions using <>. - PORTABILITY <> is ANSI C. <> is an extension. diff --git a/newlib/libm/mathfp/s_cosh.c b/newlib/libm/mathfp/s_cosh.c index bfe665069..9d6f8d1ce 100644 --- a/newlib/libm/mathfp/s_cosh.c +++ b/newlib/libm/mathfp/s_cosh.c @@ -31,9 +31,6 @@ RETURNS an overflow, <> returns the value <> with the appropriate sign, and the global value <> is set to <>. - You can modify error handling for these functions using the - function <>. - PORTABILITY <> is ANSI. <> is an extension. diff --git a/newlib/libm/mathfp/s_fmod.c b/newlib/libm/mathfp/s_fmod.c index d878f009c..4197ea832 100644 --- a/newlib/libm/mathfp/s_fmod.c +++ b/newlib/libm/mathfp/s_fmod.c @@ -43,8 +43,6 @@ magnitude of <[y]>. <,0)>> returns NaN, and sets <> to <>. -You can modify error treatment for these functions using <>. - PORTABILITY <> is ANSI C. <> is an extension. */ diff --git a/newlib/libm/mathfp/s_logarithm.c b/newlib/libm/mathfp/s_logarithm.c index e8c24200a..b9ec63751 100644 --- a/newlib/libm/mathfp/s_logarithm.c +++ b/newlib/libm/mathfp/s_logarithm.c @@ -38,8 +38,7 @@ RETURNS Normally, returns the calculated value. When <[x]> is zero, the returned value is <<-HUGE_VAL>> and <> is set to <>. When <[x]> is negative, the returned value is <<-HUGE_VAL>> and -<> is set to <>. You can control the error behavior via -<>. +<> is set to <>. PORTABILITY <> is ANSI. <> is an extension. diff --git a/newlib/libm/mathfp/s_pow.c b/newlib/libm/mathfp/s_pow.c index 5866dcd06..4754cf08a 100644 --- a/newlib/libm/mathfp/s_pow.c +++ b/newlib/libm/mathfp/s_pow.c @@ -31,8 +31,6 @@ RETURNS is set to <>. If <[x]> and <[y]> are both 0, then <> and <> return <<1>>. - You can modify error handling for these functions using <>. - PORTABILITY <> is ANSI C. <> is an extension. */ diff --git a/newlib/libm/mathfp/w_jn.c b/newlib/libm/mathfp/w_jn.c index 71ea4a095..15b941218 100644 --- a/newlib/libm/mathfp/w_jn.c +++ b/newlib/libm/mathfp/w_jn.c @@ -127,25 +127,12 @@ None of the Bessel functions are in ANSI C. return jn(n,x); #else double z; - struct exception exc; z = jn(n,x); if(_LIB_VERSION == _IEEE_ || isnan(x) ) return z; if(fabs(x)>X_TLOSS) { /* jn(|x|>X_TLOSS) */ - exc.type = TLOSS; - exc.name = "jn"; - exc.err = 0; - exc.arg1 = n; - exc.arg2 = x; - exc.retval = 0.0; - if (_LIB_VERSION == _POSIX_) - errno = ERANGE; - else if (!matherr(&exc)) { - errno = ERANGE; - } - if (exc.err != 0) - errno = exc.err; - return exc.retval; + errno = ERANGE; + return 0.0; } else return z; #endif @@ -162,7 +149,6 @@ None of the Bessel functions are in ANSI C. return yn(n,x); #else double z; - struct exception exc; z = yn(n,x); if(_LIB_VERSION == _IEEE_ || isnan(x) ) return z; if(x <= 0.0){ @@ -173,40 +159,13 @@ None of the Bessel functions are in ANSI C. SET_HIGH_WORD(inf,0x7ff00000); /* set inf to infinite */ #endif - exc.type = DOMAIN; /* should be SING for IEEE */ - exc.name = "yn"; - exc.err = 0; - exc.arg1 = n; - exc.arg2 = x; - if (_LIB_VERSION == _SVID_) - exc.retval = -HUGE; - else - exc.retval = -HUGE_VAL; - if (_LIB_VERSION == _POSIX_) - errno = EDOM; - else if (!matherr(&exc)) { - errno = EDOM; - } - if (exc.err != 0) - errno = exc.err; - return exc.retval; + errno = EDOM; + return -HUGE_VAL; } if(x>X_TLOSS) { /* yn(x>X_TLOSS) */ - exc.type = TLOSS; - exc.name = "yn"; - exc.err = 0; - exc.arg1 = n; - exc.arg2 = x; - exc.retval = 0.0; - if (_LIB_VERSION == _POSIX_) - errno = ERANGE; - else if (!matherr(&exc)) { - errno = ERANGE; - } - if (exc.err != 0) - errno = exc.err; - return exc.retval; + errno = ERANGE; + return 0.0; } else return z; #endif diff --git a/newlib/libm/mathfp/wf_jn.c b/newlib/libm/mathfp/wf_jn.c index ebc886de9..526027441 100644 --- a/newlib/libm/mathfp/wf_jn.c +++ b/newlib/libm/mathfp/wf_jn.c @@ -28,25 +28,12 @@ return jnf(n,x); #else float z; - struct exception exc; z = jnf(n,x); if(_LIB_VERSION == _IEEE_ || isnanf(x) ) return z; if(fabsf(x)>(float)X_TLOSS) { /* jnf(|x|>X_TLOSS) */ - exc.type = TLOSS; - exc.name = "jnf"; - exc.err = 0; - exc.arg1 = (double)n; - exc.arg2 = (double)x; - exc.retval = 0.0; - if (_LIB_VERSION == _POSIX_) - errno = ERANGE; - else if (!matherr(&exc)) { - errno = ERANGE; - } - if (exc.err != 0) - errno = exc.err; - return exc.retval; + errno = ERANGE; + return 0.0f; } else return z; #endif @@ -63,10 +50,9 @@ return ynf(n,x); #else float z; - struct exception exc; z = ynf(n,x); if(_LIB_VERSION == _IEEE_ || isnanf(x) ) return z; - if(x <= (float)0.0){ + if(x <= 0.0f){ /* ynf(n,0) = -inf or ynf(x<0) = NaN */ #ifndef HUGE_VAL #define HUGE_VAL inf @@ -74,40 +60,13 @@ SET_HIGH_WORD(inf,0x7ff00000); /* set inf to infinite */ #endif - exc.type = DOMAIN; /* should be SING for IEEE */ - exc.name = "ynf"; - exc.err = 0; - exc.arg1 = (double)n; - exc.arg2 = (double)x; - if (_LIB_VERSION == _SVID_) - exc.retval = -HUGE; - else - exc.retval = -HUGE_VAL; - if (_LIB_VERSION == _POSIX_) - errno = EDOM; - else if (!matherr(&exc)) { - errno = EDOM; - } - if (exc.err != 0) - errno = exc.err; - return (float)exc.retval; + errno = EDOM; + return (float)-HUGE_VAL; } if(x>(float)X_TLOSS) { /* ynf(x>X_TLOSS) */ - exc.type = TLOSS; - exc.name = "ynf"; - exc.err = 0; - exc.arg1 = (double)n; - exc.arg2 = (double)x; - exc.retval = 0.0; - if (_LIB_VERSION == _POSIX_) - errno = ERANGE; - else if (!matherr(&exc)) { - errno = ERANGE; - } - if (exc.err != 0) - errno = exc.err; - return (float)exc.retval; + errno = ERANGE; + return 0.0f; } else return z; #endif diff --git a/newlib/libm/test/math.c b/newlib/libm/test/math.c index 0a6389a01..cd8441cc5 100644 --- a/newlib/libm/test/math.c +++ b/newlib/libm/test/math.c @@ -33,22 +33,6 @@ char *mname; int verbose; -/* To test exceptions - we trap them all and return a known value */ -int -matherr (struct exception *e) -{ - if (traperror) - { - merror = e->type + 12; - mname = e->name; - e->retval = mretval; - errno = merror + 24; - return 1; - } - return 0; -} - - void translate_to (FILE *file, double r) { @@ -90,6 +74,7 @@ ffcheck (double is, #if 0 if (p->qs[0].merror != merror) { + /* Beware, matherr doesn't exist anymore. */ printf("testing %s_vec.c:%d, matherr wrong: %d %d\n", name, p->line, merror, p->qs[0].merror); } diff --git a/winsup/cygwin/common.din b/winsup/cygwin/common.din index 384cf0b15..ca819c63e 100644 --- a/winsup/cygwin/common.din +++ b/winsup/cygwin/common.din @@ -907,7 +907,6 @@ malloc_stats SIGFE malloc_trim SIGFE malloc_usable_size SIGFE mallopt SIGFE -matherr NOSIGFE mblen NOSIGFE mbrlen NOSIGFE mbrtowc NOSIGFE diff --git a/winsup/cygwin/i686.din b/winsup/cygwin/i686.din index 934243bbc..174e73dd0 100644 --- a/winsup/cygwin/i686.din +++ b/winsup/cygwin/i686.din @@ -366,7 +366,6 @@ _lseek64 = lseek64 SIGFE _lstat = lstat SIGFE _lstat64 = lstat64 SIGFE _malloc = malloc SIGFE -_matherr = matherr NOSIGFE _mblen = mblen NOSIGFE _mbstowcs = mbstowcs NOSIGFE _mbtowc = mbtowc NOSIGFE diff --git a/winsup/cygwin/include/cygwin/version.h b/winsup/cygwin/include/cygwin/version.h index d6dcbea0e..c3e971ed8 100644 --- a/winsup/cygwin/include/cygwin/version.h +++ b/winsup/cygwin/include/cygwin/version.h @@ -504,12 +504,13 @@ details. */ 331: Add timer_getoverrun, DELAYTIMER_MAX. 332: Add signalfd. 333: Add timerfd_create, timerfd_gettime, timerfd_settime. + 334: Remove matherr. Note that we forgot to bump the api for ualarm, strtoll, strtoull, sigaltstack, sethostname. */ #define CYGWIN_VERSION_API_MAJOR 0 -#define CYGWIN_VERSION_API_MINOR 333 +#define CYGWIN_VERSION_API_MINOR 334 /* There is also a compatibity version number associated with the shared memory regions. It is incremented when incompatible changes are made to the shared diff --git a/winsup/cygwin/math/acosh.def.h b/winsup/cygwin/math/acosh.def.h index c039bd8eb..1fc5deb14 100644 --- a/winsup/cygwin/math/acosh.def.h +++ b/winsup/cygwin/math/acosh.def.h @@ -52,12 +52,12 @@ __FLT_ABI(acosh) (__FLT_TYPE x) int x_class = fpclassify (x); if (x_class == FP_NAN || x < __FLT_CST(1.0)) { - __FLT_RPT_DOMAIN ("acosh", x, 0.0, __FLT_NAN); + errno = EDOM; return __FLT_NAN; } else if (x_class == FP_INFINITE) { - __FLT_RPT_DOMAIN ("acosh", x, 0.0, __FLT_NAN); + errno = EDOM; return __FLT_NAN; } diff --git a/winsup/cygwin/math/complex_internal.h b/winsup/cygwin/math/complex_internal.h index b230b15b8..83b17b0f5 100644 --- a/winsup/cygwin/math/complex_internal.h +++ b/winsup/cygwin/math/complex_internal.h @@ -120,34 +120,3 @@ #else # error "Unknown complex number type" #endif - -#define __FLT_RPT_DOMAIN(NAME, ARG1, ARG2, RSLT) \ - errno = EDOM, \ - __mingw_raise_matherr (_DOMAIN, __FLT_REPORT(NAME), (double) (ARG1), \ - (double) (ARG2), (double) (RSLT)) -#define __FLT_RPT_ERANGE(NAME, ARG1, ARG2, RSLT, OVL) \ - errno = ERANGE, \ - __mingw_raise_matherr (((OVL) ? _OVERFLOW : _UNDERFLOW), \ - __FLT_REPORT(NAME), (double) (ARG1), \ - (double) (ARG2), (double) (RSLT)) - -#ifdef __CYGWIN__ -inline void __attribute__ ((always_inline)) -__mingw_raise_matherr (int typ, const char *name, double a1, double a2, - double rslt) -{ - if (_LIB_VERSION != _POSIX_) - { - struct exception ex; - ex.type = typ; - ex.name = (char*)name; - ex.arg1 = a1; - ex.arg2 = a2; - ex.retval = rslt; - matherr(&ex); - } -} -#define _DOMAIN DOMAIN -#define _OVERFLOW OVERFLOW -#define _UNDERFLOW UNDERFLOW -#endif diff --git a/winsup/cygwin/math/cos.def.h b/winsup/cygwin/math/cos.def.h index 1058d031f..cbb226e49 100644 --- a/winsup/cygwin/math/cos.def.h +++ b/winsup/cygwin/math/cos.def.h @@ -53,12 +53,12 @@ __FLT_ABI(cos) (__FLT_TYPE x) int x_class = fpclassify (x); if (x_class == FP_NAN) { - __FLT_RPT_DOMAIN ("cos", x, 0.0, x); + errno = EDOM; return x; } else if (x_class == FP_INFINITE) { - __FLT_RPT_DOMAIN ("cos", x, 0.0, __FLT_NAN); + errno = EDOM; return __FLT_NAN; } return (__FLT_TYPE) __cosl_internal ((long double) x); diff --git a/winsup/cygwin/math/exp.def.h b/winsup/cygwin/math/exp.def.h index 2419ef6d1..678e7c1ee 100644 --- a/winsup/cygwin/math/exp.def.h +++ b/winsup/cygwin/math/exp.def.h @@ -109,13 +109,13 @@ __FLT_ABI(exp) (__FLT_TYPE x) int x_class = fpclassify (x); if (x_class == FP_NAN) { - __FLT_RPT_DOMAIN ("exp", x, 0.0, x); + errno = EDOM; return x; } else if (x_class == FP_INFINITE) { __FLT_TYPE r = (signbit (x) ? __FLT_CST (0.0) : __FLT_HUGE_VAL); - __FLT_RPT_ERANGE ("exp", x, 0.0, r, signbit (x)); + errno = ERANGE; return r; } else if (x_class == FP_ZERO) @@ -124,7 +124,7 @@ __FLT_ABI(exp) (__FLT_TYPE x) } else if (x > __FLT_MAXLOG) { - __FLT_RPT_ERANGE ("exp", x, 0.0, __FLT_HUGE_VAL, 1); + errno = ERANGE; return __FLT_HUGE_VAL; } else if (x < __FLT_MINLOG) diff --git a/winsup/cygwin/math/expm1.def.h b/winsup/cygwin/math/expm1.def.h index 5a2b6f498..64fe42860 100644 --- a/winsup/cygwin/math/expm1.def.h +++ b/winsup/cygwin/math/expm1.def.h @@ -51,7 +51,7 @@ __FLT_ABI(expm1) (__FLT_TYPE x) int x_class = fpclassify (x); if (x_class == FP_NAN) { - __FLT_RPT_DOMAIN ("expm1", x, 0.0, x); + errno = EDOM; return x; } else if (x_class == FP_INFINITE) diff --git a/winsup/cygwin/math/log.def.h b/winsup/cygwin/math/log.def.h index 94a77007f..2ba7421a2 100644 --- a/winsup/cygwin/math/log.def.h +++ b/winsup/cygwin/math/log.def.h @@ -53,12 +53,12 @@ __FLT_ABI(log) (__FLT_TYPE x) int x_class = fpclassify (x); if (x_class == FP_ZERO) { - __FLT_RPT_ERANGE ("log", x, 0.0, -__FLT_HUGE_VAL, 1); + errno = ERANGE; return -__FLT_HUGE_VAL; } else if (signbit (x)) { - __FLT_RPT_DOMAIN ("log", x, 0.0, __FLT_NAN); + errno = EDOM; return __FLT_NAN; } else if (x_class == FP_INFINITE) diff --git a/winsup/cygwin/math/pow.def.h b/winsup/cygwin/math/pow.def.h index a5513c1f9..e1538d9fa 100644 --- a/winsup/cygwin/math/pow.def.h +++ b/winsup/cygwin/math/pow.def.h @@ -122,7 +122,7 @@ __FLT_ABI(pow) (__FLT_TYPE x, __FLT_TYPE y) else if (x_class == FP_NAN || y_class == FP_NAN) { rslt = (signbit(x) ? -__FLT_NAN : __FLT_NAN); - __FLT_RPT_DOMAIN ("pow", x, y, rslt); + errno = EDOM; return rslt; } else if (x_class == FP_ZERO) @@ -133,7 +133,7 @@ __FLT_ABI(pow) (__FLT_TYPE x, __FLT_TYPE y) if (signbit(x) && internal_modf (y, &d) != 0.0) { return signbit (y) ? (1.0 / -x) : __FLT_CST (0.0); - /*__FLT_RPT_DOMAIN ("pow", x, y, -__FLT_NAN); + /*errno = EDOM; return -__FLT_NAN; */ } odd_y = (internal_modf (__FLT_ABI (ldexp) (y, -1), &d) != 0.0) ? 1 : 0; @@ -167,7 +167,7 @@ __FLT_ABI(pow) (__FLT_TYPE x, __FLT_TYPE y) if (signbit(x) && internal_modf (y, &d) != 0.0) { return signbit(y) ? 1.0 / -x : -x; - /*__FLT_RPT_DOMAIN ("pow", x, y, -__FLT_NAN); + /*errno = EDOM; return -__FLT_NAN;*/ } odd_y = (internal_modf (__FLT_ABI (ldexp) (y, -1), &d) != 0.0) ? 1 : 0; @@ -195,7 +195,7 @@ __FLT_ABI(pow) (__FLT_TYPE x, __FLT_TYPE y) { if (signbit (x)) { - __FLT_RPT_DOMAIN ("pow", x, y, -__FLT_NAN); + errno = EDOM; return -__FLT_NAN; } if (y == __FLT_CST(0.5)) diff --git a/winsup/cygwin/math/powi.def.h b/winsup/cygwin/math/powi.def.h index f7fa860a6..e3840e757 100644 --- a/winsup/cygwin/math/powi.def.h +++ b/winsup/cygwin/math/powi.def.h @@ -83,7 +83,7 @@ __FLT_ABI(__powi) (__FLT_TYPE x, int y) else if (x_class == FP_NAN) { rslt = (signbit(x) ? -__FLT_NAN : __FLT_NAN); - __FLT_RPT_DOMAIN ("__powi", x, (__FLT_TYPE) y, rslt); + errno = EDOM; return rslt; } else if (x_class == FP_ZERO) diff --git a/winsup/cygwin/math/sin.def.h b/winsup/cygwin/math/sin.def.h index c9b3b0499..dfb1cb49f 100644 --- a/winsup/cygwin/math/sin.def.h +++ b/winsup/cygwin/math/sin.def.h @@ -53,12 +53,12 @@ __FLT_ABI(sin) (__FLT_TYPE x) int x_class = fpclassify (x); if (x_class == FP_NAN) { - __FLT_RPT_DOMAIN ("sin", x, 0.0, x); + errno = EDOM; return x; } else if (x_class == FP_INFINITE) { - __FLT_RPT_DOMAIN ("sin", x, 0.0, __FLT_NAN); + errno = EDOM; return __FLT_NAN; } return (__FLT_TYPE) __sinl_internal ((long double) x); diff --git a/winsup/cygwin/math/sqrt.def.h b/winsup/cygwin/math/sqrt.def.h index 2690d1d9f..ee858a785 100644 --- a/winsup/cygwin/math/sqrt.def.h +++ b/winsup/cygwin/math/sqrt.def.h @@ -73,7 +73,7 @@ __FLT_ABI (sqrt) (__FLT_TYPE x) if (x_class == FP_ZERO) return __FLT_CST (-0.0); - __FLT_RPT_DOMAIN ("sqrt", x, 0.0, x); + errno = EDOM; return x; } else if (x_class == FP_ZERO) diff --git a/winsup/cygwin/release/2.12.0 b/winsup/cygwin/release/2.12.0 index ba911ee54..af74b099e 100644 --- a/winsup/cygwin/release/2.12.0 +++ b/winsup/cygwin/release/2.12.0 @@ -53,6 +53,9 @@ What changed: - Wctype functions updated to Unicode 11.0. +- Remove matherr, and SVID and X/Open math library configurations. + Default math library configuration is now IEEE. + Bug Fixes --------- diff --git a/winsup/doc/new-features.xml b/winsup/doc/new-features.xml index a1799d08b..59db9c98a 100644 --- a/winsup/doc/new-features.xml +++ b/winsup/doc/new-features.xml @@ -86,6 +86,11 @@ to free the parent directory. Wctype functions updated to Unicode 11.0. + +Remove matherr, and SVID and X/Open math library configurations. +Default math library configuration is now IEEE. + + From 7db203304ef12ac1b351b4890b0a4d5f61ad2c0c Mon Sep 17 00:00:00 2001 From: Jozef Lawrynowicz Date: Tue, 22 Jan 2019 10:38:37 +0000 Subject: [PATCH 137/475] Remove HUGE_VAL definition from libm math functions This patch removes the definitions of HUGE_VAL from some of the float math functions. HUGE_VAL is defined in newlib/libc/include/math.h, so it is not necessary to have a further definition in the math functions. --- newlib/libm/common/hypotl.c | 6 ------ newlib/libm/math/k_standard.c | 6 ------ newlib/libm/math/w_cosh.c | 6 ------ newlib/libm/math/w_exp.c | 6 ------ newlib/libm/math/w_gamma.c | 6 ------ newlib/libm/math/w_hypot.c | 6 ------ newlib/libm/math/w_j0.c | 6 ------ newlib/libm/math/w_j1.c | 6 ------ newlib/libm/math/w_jn.c | 6 ------ newlib/libm/math/w_lgamma.c | 6 ------ newlib/libm/math/w_log.c | 6 ------ newlib/libm/math/w_log10.c | 6 ------ newlib/libm/math/w_pow.c | 6 ------ newlib/libm/math/w_scalb.c | 6 ------ newlib/libm/math/w_sinh.c | 6 ------ newlib/libm/math/wf_cosh.c | 6 ------ newlib/libm/math/wf_exp.c | 6 ------ newlib/libm/math/wf_gamma.c | 6 ------ newlib/libm/math/wf_hypot.c | 6 ------ newlib/libm/math/wf_j0.c | 6 ------ newlib/libm/math/wf_j1.c | 6 ------ newlib/libm/math/wf_jn.c | 6 ------ newlib/libm/math/wf_lgamma.c | 6 ------ newlib/libm/math/wf_log.c | 6 ------ newlib/libm/math/wf_log10.c | 6 ------ newlib/libm/math/wf_scalb.c | 6 ------ newlib/libm/math/wf_sinh.c | 6 ------ newlib/libm/math/wr_gamma.c | 6 ------ newlib/libm/math/wr_lgamma.c | 6 ------ newlib/libm/math/wrf_gamma.c | 6 ------ newlib/libm/math/wrf_lgamma.c | 6 ------ 31 files changed, 186 deletions(-) diff --git a/newlib/libm/common/hypotl.c b/newlib/libm/common/hypotl.c index a0dcdc3c1..fb51adee4 100644 --- a/newlib/libm/common/hypotl.c +++ b/newlib/libm/common/hypotl.c @@ -52,12 +52,6 @@ hypotl (long double x, long double y) if ((! finitel (z)) && finitel (x) && finitel (y)) { /* hypot (finite, finite) overflow. */ -#ifndef HUGE_VAL -#define HUGE_VAL inf - double inf = 0.0; - - SET_HIGH_WORD (inf, 0x7ff00000); /* Set inf to infinite. */ -#endif errno = ERANGE; return (long double) HUGE_VAL; } diff --git a/newlib/libm/math/k_standard.c b/newlib/libm/math/k_standard.c index 91fd6c33f..906412ba7 100644 --- a/newlib/libm/math/k_standard.c +++ b/newlib/libm/math/k_standard.c @@ -86,12 +86,6 @@ static double zero = 0.0; /* used as const */ #endif { double retval = 0.0; -#ifndef HUGE_VAL /* this is the only routine that uses HUGE_VAL */ -#define HUGE_VAL inf - double inf = 0.0; - - SET_HIGH_WORD(inf,0x7ff00000); /* set inf to infinite */ -#endif #ifdef _USE_WRITE /* (void) fflush(_stdout_r(p)); */ diff --git a/newlib/libm/math/w_cosh.c b/newlib/libm/math/w_cosh.c index a26442178..5021e28a1 100644 --- a/newlib/libm/math/w_cosh.c +++ b/newlib/libm/math/w_cosh.c @@ -74,12 +74,6 @@ QUICKREF if(_LIB_VERSION == _IEEE_ || isnan(x)) return z; if(fabs(x)>7.10475860073943863426e+02) { /* cosh(finite) overflow */ -#ifndef HUGE_VAL -#define HUGE_VAL inf - double inf = 0.0; - - SET_HIGH_WORD(inf,0x7ff00000); /* set inf to infinite */ -#endif errno = ERANGE; return HUGE_VAL; } else diff --git a/newlib/libm/math/w_exp.c b/newlib/libm/math/w_exp.c index 3da6d7702..66c3f5c74 100644 --- a/newlib/libm/math/w_exp.c +++ b/newlib/libm/math/w_exp.c @@ -79,12 +79,6 @@ u_threshold= -7.45133219101941108420e+02; /* 0xc0874910, 0xD52D3051 */ if(finite(x)) { if(x>o_threshold) { /* exp(finite) overflow */ -#ifndef HUGE_VAL -#define HUGE_VAL inf - double inf = 0.0; - - SET_HIGH_WORD(inf,0x7ff00000); /* set inf to infinite */ -#endif errno = ERANGE; return HUGE_VAL; } else if(x global for y = __ieee754_gamma_r(x,&(_REENT_SIGNGAM(_REENT))); if(_LIB_VERSION == _IEEE_) return y; if(!finite(y)&&finite(x)) { -#ifndef HUGE_VAL -#define HUGE_VAL inf - double inf = 0.0; - - SET_HIGH_WORD(inf,0x7ff00000); /* set inf to infinite */ -#endif if(floor(x)==x&&x<=0.0) { /* gamma(-integer) or gamma(0) */ errno = EDOM; diff --git a/newlib/libm/math/w_hypot.c b/newlib/libm/math/w_hypot.c index 441fc20cb..48b47881e 100644 --- a/newlib/libm/math/w_hypot.c +++ b/newlib/libm/math/w_hypot.c @@ -68,12 +68,6 @@ PORTABILITY if(_LIB_VERSION == _IEEE_) return z; if((!finite(z))&&finite(x)&&finite(y)) { /* hypot(finite,finite) overflow */ -#ifndef HUGE_VAL -#define HUGE_VAL inf - double inf = 0.0; - - SET_HIGH_WORD(inf,0x7ff00000); /* set inf to infinite */ -#endif errno = ERANGE; return HUGE_VAL; } else diff --git a/newlib/libm/math/w_j0.c b/newlib/libm/math/w_j0.c index 59d17e8b8..b537ef406 100644 --- a/newlib/libm/math/w_j0.c +++ b/newlib/libm/math/w_j0.c @@ -129,12 +129,6 @@ None of the Bessel functions are in ANSI C. z = __ieee754_y0(x); if(_LIB_VERSION == _IEEE_ || isnan(x) ) return z; if(x <= 0.0){ -#ifndef HUGE_VAL -#define HUGE_VAL inf - double inf = 0.0; - - SET_HIGH_WORD(inf,0x7ff00000); /* set inf to infinite */ -#endif /* y0(0) = -inf or y0(x<0) = NaN */ errno = EDOM; return -HUGE_VAL; diff --git a/newlib/libm/math/w_j1.c b/newlib/libm/math/w_j1.c index 127324aad..6f25fea27 100644 --- a/newlib/libm/math/w_j1.c +++ b/newlib/libm/math/w_j1.c @@ -56,12 +56,6 @@ z = __ieee754_y1(x); if(_LIB_VERSION == _IEEE_ || isnan(x) ) return z; if(x <= 0.0){ -#ifndef HUGE_VAL -#define HUGE_VAL inf - double inf = 0.0; - - SET_HIGH_WORD(inf,0x7ff00000); /* set inf to infinite */ -#endif /* y1(0) = -inf or y1(x<0) = NaN */ errno = EDOM; return -HUGE_VAL; diff --git a/newlib/libm/math/w_jn.c b/newlib/libm/math/w_jn.c index 0482fa95a..28a9abc07 100644 --- a/newlib/libm/math/w_jn.c +++ b/newlib/libm/math/w_jn.c @@ -79,12 +79,6 @@ if(_LIB_VERSION == _IEEE_ || isnan(x) ) return z; if(x <= 0.0){ /* yn(n,0) = -inf or yn(x<0) = NaN */ -#ifndef HUGE_VAL -#define HUGE_VAL inf - double inf = 0.0; - - SET_HIGH_WORD(inf,0x7ff00000); /* set inf to infinite */ -#endif errno = EDOM; return -HUGE_VAL; } diff --git a/newlib/libm/math/w_lgamma.c b/newlib/libm/math/w_lgamma.c index f848f1c95..25d12c9c7 100644 --- a/newlib/libm/math/w_lgamma.c +++ b/newlib/libm/math/w_lgamma.c @@ -38,12 +38,6 @@ y = __ieee754_lgamma_r(x,&(_REENT_SIGNGAM(_REENT))); if(_LIB_VERSION == _IEEE_) return y; if(!finite(y)&&finite(x)) { -#ifndef HUGE_VAL -#define HUGE_VAL inf - double inf = 0.0; - - SET_HIGH_WORD(inf,0x7ff00000); /* set inf to infinite */ -#endif if(floor(x)==x&&x<=0.0) /* lgamma(-integer) */ errno = EDOM; diff --git a/newlib/libm/math/w_log.c b/newlib/libm/math/w_log.c index 37afcac3c..2a6c980e0 100644 --- a/newlib/libm/math/w_log.c +++ b/newlib/libm/math/w_log.c @@ -63,12 +63,6 @@ PORTABILITY double z; z = __ieee754_log(x); if(_LIB_VERSION == _IEEE_ || isnan(x) || x > 0.0) return z; -#ifndef HUGE_VAL -#define HUGE_VAL inf - double inf = 0.0; - - SET_HIGH_WORD(inf,0x7ff00000); /* set inf to infinite */ -#endif if(x==0.0) { /* log(0) */ errno = ERANGE; diff --git a/newlib/libm/math/w_log10.c b/newlib/libm/math/w_log10.c index 69ef5f92c..a9112f86f 100644 --- a/newlib/libm/math/w_log10.c +++ b/newlib/libm/math/w_log10.c @@ -64,12 +64,6 @@ PORTABILITY z = __ieee754_log10(x); if(_LIB_VERSION == _IEEE_ || isnan(x)) return z; if(x<=0.0) { -#ifndef HUGE_VAL -#define HUGE_VAL inf - double inf = 0.0; - - SET_HIGH_WORD(inf,0x7ff00000); /* set inf to infinite */ -#endif if(x==0.0) { /* log10(0) */ errno = ERANGE; diff --git a/newlib/libm/math/w_pow.c b/newlib/libm/math/w_pow.c index e9ac37051..6e953360a 100644 --- a/newlib/libm/math/w_pow.c +++ b/newlib/libm/math/w_pow.c @@ -66,12 +66,6 @@ PORTABILITY return __ieee754_pow(x,y); #else double z; -#ifndef HUGE_VAL -#define HUGE_VAL inf - double inf = 0.0; - - SET_HIGH_WORD(inf,0x7ff00000); /* set inf to infinite */ -#endif z=__ieee754_pow(x,y); if(_LIB_VERSION == _IEEE_|| isnan(y)) return z; if(isnan(x)) { diff --git a/newlib/libm/math/w_scalb.c b/newlib/libm/math/w_scalb.c index 77fb2af53..14f54a7e8 100644 --- a/newlib/libm/math/w_scalb.c +++ b/newlib/libm/math/w_scalb.c @@ -41,12 +41,6 @@ return __ieee754_scalb(x,fn); #else double z; -#ifndef HUGE_VAL -#define HUGE_VAL inf - double inf = 0.0; - - SET_HIGH_WORD(inf,0x7ff00000); /* set inf to infinite */ -#endif z = __ieee754_scalb(x,fn); if(_LIB_VERSION == _IEEE_) return z; if(!(finite(z)||isnan(z))&&finite(x)) { diff --git a/newlib/libm/math/w_sinh.c b/newlib/libm/math/w_sinh.c index 0e97e5455..9d7833a2c 100644 --- a/newlib/libm/math/w_sinh.c +++ b/newlib/libm/math/w_sinh.c @@ -79,12 +79,6 @@ QUICKREF if(_LIB_VERSION == _IEEE_) return z; if(!finite(z)&&finite(x)) { /* sinh(finite) overflow */ -#ifndef HUGE_VAL -#define HUGE_VAL inf - double inf = 0.0; - - SET_HIGH_WORD(inf,0x7ff00000); /* set inf to infinite */ -#endif errno = ERANGE; return ((x>0.0) ? HUGE_VAL : -HUGE_VAL); } else diff --git a/newlib/libm/math/wf_cosh.c b/newlib/libm/math/wf_cosh.c index 1b507b09b..e0fd1c492 100644 --- a/newlib/libm/math/wf_cosh.c +++ b/newlib/libm/math/wf_cosh.c @@ -35,12 +35,6 @@ if(_LIB_VERSION == _IEEE_ || isnan(x)) return z; if(fabsf(x)>8.9415985107e+01f) { /* coshf(finite) overflow */ -#ifndef HUGE_VAL -#define HUGE_VAL inf - double inf = 0.0; - - SET_HIGH_WORD(inf,0x7ff00000); /* set inf to infinite */ -#endif errno = ERANGE; return (float)HUGE_VAL; } else diff --git a/newlib/libm/math/wf_exp.c b/newlib/libm/math/wf_exp.c index af1800eeb..73177bc25 100644 --- a/newlib/libm/math/wf_exp.c +++ b/newlib/libm/math/wf_exp.c @@ -45,12 +45,6 @@ u_threshold= -1.0397208405e+02; /* 0xc2cff1b5 */ if(finitef(x)) { if(x>o_threshold) { /* expf(finite) overflow */ -#ifndef HUGE_VAL -#define HUGE_VAL inf - double inf = 0.0; - - SET_HIGH_WORD(inf,0x7ff00000); /* set inf to infinite */ -#endif errno = ERANGE; return HUGE_VAL; } else if(x 0.0f) return z; -#ifndef HUGE_VAL -#define HUGE_VAL inf - double inf = 0.0; - - SET_HIGH_WORD(inf,0x7ff00000); /* set inf to infinite */ -#endif if(x==0.0f) { /* logf(0) */ errno = ERANGE; diff --git a/newlib/libm/math/wf_log10.c b/newlib/libm/math/wf_log10.c index 3560c5c0e..a61120d24 100644 --- a/newlib/libm/math/wf_log10.c +++ b/newlib/libm/math/wf_log10.c @@ -34,12 +34,6 @@ z = __ieee754_log10f(x); if(_LIB_VERSION == _IEEE_ || isnan(x)) return z; if(x<=0.0f) { -#ifndef HUGE_VAL -#define HUGE_VAL inf - double inf = 0.0; - - SET_HIGH_WORD(inf,0x7ff00000); /* set inf to infinite */ -#endif if(x==0.0f) { /* log10f(0) */ errno = ERANGE; diff --git a/newlib/libm/math/wf_scalb.c b/newlib/libm/math/wf_scalb.c index acdf8a80d..b57e2e684 100644 --- a/newlib/libm/math/wf_scalb.c +++ b/newlib/libm/math/wf_scalb.c @@ -41,12 +41,6 @@ return __ieee754_scalbf(x,fn); #else float z; -#ifndef HUGE_VAL -#define HUGE_VAL inf - double inf = 0.0; - - SET_HIGH_WORD(inf,0x7ff00000); /* set inf to infinite */ -#endif z = __ieee754_scalbf(x,fn); if(_LIB_VERSION == _IEEE_) return z; if(!(finitef(z)||isnan(z))&&finitef(x)) { diff --git a/newlib/libm/math/wf_sinh.c b/newlib/libm/math/wf_sinh.c index f7d5a9665..9149d19f3 100644 --- a/newlib/libm/math/wf_sinh.c +++ b/newlib/libm/math/wf_sinh.c @@ -35,12 +35,6 @@ if(_LIB_VERSION == _IEEE_) return z; if(!finitef(z)&&finitef(x)) { /* sinhf(finite) overflow */ -#ifndef HUGE_VAL -#define HUGE_VAL inf - double inf = 0.0; - - SET_HIGH_WORD(inf,0x7ff00000); /* set inf to infinite */ -#endif errno = ERANGE; return ( (x>0.0f) ? HUGE_VAL : -HUGE_VAL); } else diff --git a/newlib/libm/math/wr_gamma.c b/newlib/libm/math/wr_gamma.c index f07908c8a..9dda12b5a 100644 --- a/newlib/libm/math/wr_gamma.c +++ b/newlib/libm/math/wr_gamma.c @@ -34,12 +34,6 @@ y = __ieee754_gamma_r(x,signgamp); if(_LIB_VERSION == _IEEE_) return y; if(!finite(y)&&finite(x)) { -#ifndef HUGE_VAL -#define HUGE_VAL inf - double inf = 0.0; - - SET_HIGH_WORD(inf,0x7ff00000); /* set inf to infinite */ -#endif if(floor(x)==x&&x<=0.0) /* gamma(-integer) or gamma(0) */ errno = EDOM; diff --git a/newlib/libm/math/wr_lgamma.c b/newlib/libm/math/wr_lgamma.c index 8a32a59b8..d961db58d 100644 --- a/newlib/libm/math/wr_lgamma.c +++ b/newlib/libm/math/wr_lgamma.c @@ -34,12 +34,6 @@ y = __ieee754_lgamma_r(x,signgamp); if(_LIB_VERSION == _IEEE_) return y; if(!finite(y)&&finite(x)) { -#ifndef HUGE_VAL -#define HUGE_VAL inf - double inf = 0.0; - - SET_HIGH_WORD(inf,0x7ff00000); /* set inf to infinite */ -#endif if(floor(x)==x&&x<=0.0) /* lgamma(-integer) */ errno = EDOM; diff --git a/newlib/libm/math/wrf_gamma.c b/newlib/libm/math/wrf_gamma.c index 625ea4772..b03919bfd 100644 --- a/newlib/libm/math/wrf_gamma.c +++ b/newlib/libm/math/wrf_gamma.c @@ -34,12 +34,6 @@ y = __ieee754_gammaf_r(x,signgamp); if(_LIB_VERSION == _IEEE_) return y; if(!finitef(y)&&finitef(x)) { -#ifndef HUGE_VAL -#define HUGE_VAL inf - double inf = 0.0; - - SET_HIGH_WORD(inf,0x7ff00000); /* set inf to infinite */ -#endif if(floorf(x)==x&&x<=0.0f) { /* gammaf(-integer) or gamma(0) */ errno = EDOM; diff --git a/newlib/libm/math/wrf_lgamma.c b/newlib/libm/math/wrf_lgamma.c index e91bffb38..f12c0dff1 100644 --- a/newlib/libm/math/wrf_lgamma.c +++ b/newlib/libm/math/wrf_lgamma.c @@ -34,12 +34,6 @@ y = __ieee754_lgammaf_r(x,signgamp); if(_LIB_VERSION == _IEEE_) return y; if(!finitef(y)&&finitef(x)) { -#ifndef HUGE_VAL -#define HUGE_VAL inf - double inf = 0.0; - - SET_HIGH_WORD(inf,0x7ff00000); /* set inf to infinite */ -#endif if(floorf(x)==x&&x<=0.0f) { /* lgammaf(-integer) or lgamma(0) */ errno = EDOM; From d451d9ec78854766fe4b95795de7bdfa099f8524 Mon Sep 17 00:00:00 2001 From: Jozef Lawrynowicz Date: Tue, 22 Jan 2019 10:39:38 +0000 Subject: [PATCH 138/475] Use HUGE_VALF instead of HUGE_VAL in single-precision float libm math functions This patch replaces instances of "(float).*HUGE_VAL" with a direct usage of HUGE_VALF, which is also defined in math.h. --- newlib/libm/math/wf_cosh.c | 2 +- newlib/libm/math/wf_exp.c | 2 +- newlib/libm/math/wf_gamma.c | 2 +- newlib/libm/math/wf_hypot.c | 2 +- newlib/libm/math/wf_j0.c | 2 +- newlib/libm/math/wf_j1.c | 2 +- newlib/libm/math/wf_jn.c | 2 +- newlib/libm/math/wf_lgamma.c | 2 +- newlib/libm/math/wf_log.c | 2 +- newlib/libm/math/wf_log10.c | 2 +- newlib/libm/math/wf_pow.c | 6 +++--- newlib/libm/math/wf_scalb.c | 2 +- newlib/libm/math/wf_sinh.c | 2 +- newlib/libm/math/wr_gamma.c | 2 +- newlib/libm/math/wrf_gamma.c | 2 +- newlib/libm/math/wrf_lgamma.c | 2 +- 16 files changed, 18 insertions(+), 18 deletions(-) diff --git a/newlib/libm/math/wf_cosh.c b/newlib/libm/math/wf_cosh.c index e0fd1c492..976009914 100644 --- a/newlib/libm/math/wf_cosh.c +++ b/newlib/libm/math/wf_cosh.c @@ -36,7 +36,7 @@ if(fabsf(x)>8.9415985107e+01f) { /* coshf(finite) overflow */ errno = ERANGE; - return (float)HUGE_VAL; + return HUGE_VALF; } else return z; #endif diff --git a/newlib/libm/math/wf_exp.c b/newlib/libm/math/wf_exp.c index 73177bc25..38cacd95a 100644 --- a/newlib/libm/math/wf_exp.c +++ b/newlib/libm/math/wf_exp.c @@ -46,7 +46,7 @@ u_threshold= -1.0397208405e+02; /* 0xc2cff1b5 */ if(x>o_threshold) { /* expf(finite) overflow */ errno = ERANGE; - return HUGE_VAL; + return HUGE_VALF; } else if(x(float)X_TLOSS) { /* y0f(x>X_TLOSS) */ diff --git a/newlib/libm/math/wf_j1.c b/newlib/libm/math/wf_j1.c index 41d6c49c5..e178273c5 100644 --- a/newlib/libm/math/wf_j1.c +++ b/newlib/libm/math/wf_j1.c @@ -59,7 +59,7 @@ if(x <= 0.0f){ /* y1f(0) = -inf or y1f(x<0) = NaN */ errno = EDOM; - return (float)-HUGE_VAL; + return -HUGE_VALF; } if(x>(float)X_TLOSS) { /* y1f(x>X_TLOSS) */ diff --git a/newlib/libm/math/wf_jn.c b/newlib/libm/math/wf_jn.c index 450c81589..3e4632ead 100644 --- a/newlib/libm/math/wf_jn.c +++ b/newlib/libm/math/wf_jn.c @@ -55,7 +55,7 @@ if(x <= 0.0f){ /* ynf(n,0) = -inf or ynf(x<0) = NaN */ errno = EDOM; - return (float)-HUGE_VAL; + return -HUGE_VALF; } if(x>(float)X_TLOSS) { /* ynf(x>X_TLOSS) */ diff --git a/newlib/libm/math/wf_lgamma.c b/newlib/libm/math/wf_lgamma.c index 1ecd264fa..c644072e4 100644 --- a/newlib/libm/math/wf_lgamma.c +++ b/newlib/libm/math/wf_lgamma.c @@ -39,7 +39,7 @@ /* lgammaf(finite) overflow */ errno = ERANGE; } - return (float)HUGE_VAL; + return HUGE_VALF; } else return y; #endif diff --git a/newlib/libm/math/wf_log.c b/newlib/libm/math/wf_log.c index 2f6ac772b..93d1d213e 100644 --- a/newlib/libm/math/wf_log.c +++ b/newlib/libm/math/wf_log.c @@ -37,7 +37,7 @@ if(x==0.0f) { /* logf(0) */ errno = ERANGE; - return (float)-HUGE_VAL; + return -HUGE_VALF; } else { /* logf(x<0) */ errno = EDOM; diff --git a/newlib/libm/math/wf_log10.c b/newlib/libm/math/wf_log10.c index a61120d24..c9f8ecb57 100644 --- a/newlib/libm/math/wf_log10.c +++ b/newlib/libm/math/wf_log10.c @@ -37,7 +37,7 @@ if(x==0.0f) { /* log10f(0) */ errno = ERANGE; - return (float)-HUGE_VAL; + return -HUGE_VALF; } else { /* log10f(x<0) */ errno = EDOM; diff --git a/newlib/libm/math/wf_pow.c b/newlib/libm/math/wf_pow.c index 2288977e9..73648b83f 100644 --- a/newlib/libm/math/wf_pow.c +++ b/newlib/libm/math/wf_pow.c @@ -51,7 +51,7 @@ if(finitef(y)&&y<0.0f) { /* 0**neg */ errno = EDOM; - return (float)-HUGE_VAL; + return -HUGE_VALF; } return z; } @@ -67,8 +67,8 @@ /* powf(x,y) overflow */ errno = ERANGE; if(x<0.0f&&rintf(y)!=y) - return (float)-HUGE_VAL; - return (float)HUGE_VAL; + return -HUGE_VALF; + return HUGE_VALF; } } } diff --git a/newlib/libm/math/wf_scalb.c b/newlib/libm/math/wf_scalb.c index b57e2e684..e87dc37dd 100644 --- a/newlib/libm/math/wf_scalb.c +++ b/newlib/libm/math/wf_scalb.c @@ -46,7 +46,7 @@ if(!(finitef(z)||isnan(z))&&finitef(x)) { /* scalbf overflow; */ errno = ERANGE; - return (x > 0.0 ? HUGE_VAL : -HUGE_VAL); + return (x > 0.0 ? HUGE_VALF : -HUGE_VALF); } if(z==0.0f&&z!=x) { /* scalbf underflow */ diff --git a/newlib/libm/math/wf_sinh.c b/newlib/libm/math/wf_sinh.c index 9149d19f3..2f2c605ef 100644 --- a/newlib/libm/math/wf_sinh.c +++ b/newlib/libm/math/wf_sinh.c @@ -36,7 +36,7 @@ if(!finitef(z)&&finitef(x)) { /* sinhf(finite) overflow */ errno = ERANGE; - return ( (x>0.0f) ? HUGE_VAL : -HUGE_VAL); + return ( (x>0.0f) ? HUGE_VALF : -HUGE_VALF); } else return z; #endif diff --git a/newlib/libm/math/wr_gamma.c b/newlib/libm/math/wr_gamma.c index 9dda12b5a..c4c2a829e 100644 --- a/newlib/libm/math/wr_gamma.c +++ b/newlib/libm/math/wr_gamma.c @@ -40,7 +40,7 @@ else /* gamma(finite) overflow */ errno = ERANGE; - return HUGE_VAL; + return HUGE_VALF; } else return y; #endif diff --git a/newlib/libm/math/wrf_gamma.c b/newlib/libm/math/wrf_gamma.c index b03919bfd..d43c7f03d 100644 --- a/newlib/libm/math/wrf_gamma.c +++ b/newlib/libm/math/wrf_gamma.c @@ -41,7 +41,7 @@ /* gammaf(finite) overflow */ errno = ERANGE; } - return (float)HUGE_VAL; + return HUGE_VALF; } else return y; #endif diff --git a/newlib/libm/math/wrf_lgamma.c b/newlib/libm/math/wrf_lgamma.c index f12c0dff1..2785b87e5 100644 --- a/newlib/libm/math/wrf_lgamma.c +++ b/newlib/libm/math/wrf_lgamma.c @@ -41,7 +41,7 @@ /* lgammaf(finite) overflow */ errno = ERANGE; } - return (float)HUGE_VAL; + return HUGE_VALF; } else return y; #endif From b644774b8f796d58ff9ac71af2c6aa0fa1cbcaf9 Mon Sep 17 00:00:00 2001 From: Jozef Lawrynowicz Date: Tue, 22 Jan 2019 10:40:18 +0000 Subject: [PATCH 139/475] Use nanf() instead of nan() in single-precision float libm math functions This patch reduces code size for a few single-precision float math functions, by using nanf() instead of nan() where required. --- newlib/libm/math/wf_acos.c | 2 +- newlib/libm/math/wf_asin.c | 2 +- newlib/libm/math/wf_log.c | 2 +- newlib/libm/math/wf_log10.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/newlib/libm/math/wf_acos.c b/newlib/libm/math/wf_acos.c index 15d869980..c24912de5 100644 --- a/newlib/libm/math/wf_acos.c +++ b/newlib/libm/math/wf_acos.c @@ -31,7 +31,7 @@ if(fabsf(x)>1.0f) { /* acosf(|x|>1) */ errno = EDOM; - return (float) nan(""); + return nanf(""); } else return z; #endif diff --git a/newlib/libm/math/wf_asin.c b/newlib/libm/math/wf_asin.c index 2f9ffaf6e..c9f15e352 100644 --- a/newlib/libm/math/wf_asin.c +++ b/newlib/libm/math/wf_asin.c @@ -38,7 +38,7 @@ if(fabsf(x)>1.0f) { /* asinf(|x|>1) */ errno = EDOM; - return (float)nan(""); + return nanf(""); } else return z; #endif diff --git a/newlib/libm/math/wf_log.c b/newlib/libm/math/wf_log.c index 93d1d213e..97f4a7f1a 100644 --- a/newlib/libm/math/wf_log.c +++ b/newlib/libm/math/wf_log.c @@ -41,7 +41,7 @@ } else { /* logf(x<0) */ errno = EDOM; - return nan(""); + return nanf(""); } #endif } diff --git a/newlib/libm/math/wf_log10.c b/newlib/libm/math/wf_log10.c index c9f8ecb57..529ed6514 100644 --- a/newlib/libm/math/wf_log10.c +++ b/newlib/libm/math/wf_log10.c @@ -41,7 +41,7 @@ } else { /* log10f(x<0) */ errno = EDOM; - return nan(""); + return nanf(""); } } else return z; From b79b0c2bae128c4a48ba4f0c890b3424ddc6c4cd Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Wed, 23 Jan 2019 21:39:19 +0100 Subject: [PATCH 140/475] Cygwin: cygthread: set thread name before calling thread func When reusing a cygthread, the stub method fails to set the thread name to the new name. The name is only set when actually creating the thread. Fix that by moving the SetThreadName call right in front of the thread function call. Signed-off-by: Corinna Vinschen --- winsup/cygwin/cygthread.cc | 4 ++-- winsup/cygwin/release/2.12.0 | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/winsup/cygwin/cygthread.cc b/winsup/cygwin/cygthread.cc index 4404e4a19..66a317934 100644 --- a/winsup/cygwin/cygthread.cc +++ b/winsup/cygwin/cygthread.cc @@ -87,6 +87,7 @@ cygthread::stub (VOID *arg) #endif else { + SetThreadName (info->id, info->__name); info->callfunc (false); HANDLE notify = info->notify_detached; @@ -128,6 +129,7 @@ cygthread::simplestub (VOID *arg) _my_tls._ctinfo = info; info->stack_ptr = &arg; HANDLE notify = info->notify_detached; + SetThreadName (info->id, info->__name); info->callfunc (true); if (notify) SetEvent (notify); @@ -213,8 +215,6 @@ cygthread::create () this, 0, &id); if (!htobe) api_fatal ("CreateThread failed for %s - %p<%y>, %E", __name, h, id); - else - SetThreadName (GetThreadId (htobe), __name); thread_printf ("created name '%s', thread %p, id %y", __name, h, id); #ifdef DEBUGGING terminated = false; diff --git a/winsup/cygwin/release/2.12.0 b/winsup/cygwin/release/2.12.0 index af74b099e..c847b91c0 100644 --- a/winsup/cygwin/release/2.12.0 +++ b/winsup/cygwin/release/2.12.0 @@ -77,3 +77,5 @@ Bug Fixes - Fix WEOF handling in wctype functions. Addresses: https://cygwin.com/ml/cygwin/2018-12/msg00173.html + +- Fix thread names in GDB when cygthreads get reused. From 04e3dc112884313b79ff346651d6219e85aba7fd Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Thu, 24 Jan 2019 11:39:43 +0100 Subject: [PATCH 141/475] Cygwin: version: Use UTC timestamp as build time Signed-off-by: Corinna Vinschen --- winsup/cygwin/mkvers.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/winsup/cygwin/mkvers.sh b/winsup/cygwin/mkvers.sh index 6309c84b1..b2db73cc7 100755 --- a/winsup/cygwin/mkvers.sh +++ b/winsup/cygwin/mkvers.sh @@ -58,7 +58,7 @@ parse_preproc_flags $CC # # Load the current date so we can work on individual fields # -set -$- $(date +"%m %d %Y %H:%M") +set -$- $(date -u +"%m %d %Y %H:%M") m=$1 d=$2 y=$3 hhmm=$4 # # Set date into YYYY-MM-DD HH:MM:SS format From c6171b9fde818b058b710c5e146bdecd963b7e9e Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Thu, 24 Jan 2019 14:01:59 +0100 Subject: [PATCH 142/475] Cygwin: gethostname: fix fetching hostname from non-winsock function If gethostname() fails we call GetComputerNameEx with ComputerNameDnsFullyQualified. This is wrong, gethostname should return the hostname only, not the FQDN. Fix this by calling GetComputerNameEx with ComputerNameDnsHostname. Signed-off-by: Corinna Vinschen --- winsup/cygwin/net.cc | 2 +- winsup/cygwin/release/2.12.0 | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/winsup/cygwin/net.cc b/winsup/cygwin/net.cc index cfd29d191..2af71f7e5 100644 --- a/winsup/cygwin/net.cc +++ b/winsup/cygwin/net.cc @@ -718,7 +718,7 @@ cygwin_gethostname (char *name, size_t len) { DWORD local_len = len; - if (!GetComputerNameExA (ComputerNameDnsFullyQualified, name, + if (!GetComputerNameExA (ComputerNameDnsHostname, name, &local_len)) { if (GetLastError () == ERROR_MORE_DATA) diff --git a/winsup/cygwin/release/2.12.0 b/winsup/cygwin/release/2.12.0 index c847b91c0..5835952ee 100644 --- a/winsup/cygwin/release/2.12.0 +++ b/winsup/cygwin/release/2.12.0 @@ -79,3 +79,5 @@ Bug Fixes Addresses: https://cygwin.com/ml/cygwin/2018-12/msg00173.html - Fix thread names in GDB when cygthreads get reused. + +- Fix return value of gethostname in a border case. From 2166f7dc0d9ae212d9f663241501f6fd17b71e50 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Thu, 24 Jan 2019 14:22:09 +0100 Subject: [PATCH 143/475] Cygwin: net: unify gethostname/getdomainname Use info from same source (GetNetworkParams). Also move getdomainname near gethostname in source. Signed-off-by: Corinna Vinschen --- winsup/cygwin/net.cc | 77 +++++++++++++++++++++----------------------- 1 file changed, 36 insertions(+), 41 deletions(-) diff --git a/winsup/cygwin/net.cc b/winsup/cygwin/net.cc index 2af71f7e5..cd296d19d 100644 --- a/winsup/cygwin/net.cc +++ b/winsup/cygwin/net.cc @@ -710,30 +710,24 @@ cygwin_getservbyport (int port, const char *proto) extern "C" int cygwin_gethostname (char *name, size_t len) { - int res = -1; - __try { - if (gethostname (name, len)) - { - DWORD local_len = len; + PFIXED_INFO info = NULL; + ULONG size = 0; - if (!GetComputerNameExA (ComputerNameDnsHostname, name, - &local_len)) - { - if (GetLastError () == ERROR_MORE_DATA) - set_errno (ENAMETOOLONG); - else - set_winsock_errno (); - __leave; - } + if (GetNetworkParams(info, &size) == ERROR_BUFFER_OVERFLOW + && (info = (PFIXED_INFO) alloca(size)) + && GetNetworkParams(info, &size) == ERROR_SUCCESS) + { + strncpy(name, info->HostName, len); + debug_printf ("gethostname %s", name); + return 0; } - debug_printf ("name %s", name); - res = 0; + __seterrno (); } - __except (EFAULT) {} + __except (EFAULT) __endtry - return res; + return -1; } extern "C" int @@ -750,6 +744,30 @@ sethostname (const char *name, size_t len) return 0; } +/* getdomainname: 4.4BSD */ +extern "C" int +getdomainname (char *domain, size_t len) +{ + __try + { + PFIXED_INFO info = NULL; + ULONG size = 0; + + if (GetNetworkParams(info, &size) == ERROR_BUFFER_OVERFLOW + && (info = (PFIXED_INFO) alloca(size)) + && GetNetworkParams(info, &size) == ERROR_SUCCESS) + { + strncpy(domain, info->DomainName, len); + debug_printf ("gethostname %s", domain); + return 0; + } + __seterrno (); + } + __except (EFAULT) + __endtry + return -1; +} + /* exported as gethostbyname: POSIX.1-2001 */ extern "C" struct hostent * cygwin_gethostbyname (const char *name) @@ -1406,29 +1424,6 @@ cygwin_send (int fd, const void *buf, size_t len, int flags) return res; } -/* getdomainname: 4.4BSD */ -extern "C" int -getdomainname (char *domain, size_t len) -{ - __try - { - PFIXED_INFO info = NULL; - ULONG size = 0; - - if (GetNetworkParams(info, &size) == ERROR_BUFFER_OVERFLOW - && (info = (PFIXED_INFO) alloca(size)) - && GetNetworkParams(info, &size) == ERROR_SUCCESS) - { - strncpy(domain, info->DomainName, len); - return 0; - } - __seterrno (); - } - __except (EFAULT) - __endtry - return -1; -} - /* Fill out an ifconf struct. */ struct gaa_wa { From 2c12a2c32a6fe43f8a74e2792ad15c65116c6e2c Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Thu, 24 Jan 2019 16:22:49 +0100 Subject: [PATCH 144/475] Cygwin: seteuid: refuse changing uid to disabled or locked out user So far seteuid could change uid to any existing account, given sufficient permissions of the caller. This is kind of bad since it disallows admins to refuse login to disabled or locked out accounts. Add check for the account's UF_ACCOUNTDISABLE or UF_LOCKOUT flags and don't let the user in, if one of the flags is set. Signed-off-by: Corinna Vinschen --- winsup/cygwin/release/2.12.0 | 3 +++ winsup/cygwin/sec_auth.cc | 15 +++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/winsup/cygwin/release/2.12.0 b/winsup/cygwin/release/2.12.0 index 5835952ee..c2abc9329 100644 --- a/winsup/cygwin/release/2.12.0 +++ b/winsup/cygwin/release/2.12.0 @@ -81,3 +81,6 @@ Bug Fixes - Fix thread names in GDB when cygthreads get reused. - Fix return value of gethostname in a border case. + +- Disallow seteuid on disabled or locked out accounts. + Addresses: https://cygwin.com/ml/cygwin/2019-01/msg00197.html diff --git a/winsup/cygwin/sec_auth.cc b/winsup/cygwin/sec_auth.cc index d4c2701da..8fdfa3a86 100644 --- a/winsup/cygwin/sec_auth.cc +++ b/winsup/cygwin/sec_auth.cc @@ -553,6 +553,21 @@ get_server_groups (cygsidlist &grp_list, PSID usersid) && sid_sub_auth (usersid, 0) == SECURITY_NT_NON_UNIQUE && get_logon_server (domain, server, DS_IS_FLAT_NAME)) { + NET_API_STATUS napi_stat; + USER_INFO_1 *ui1; + bool allow_user = false; + + napi_stat = NetUserGetInfo (server, user, 1, (LPBYTE *) &ui1); + if (napi_stat == NERR_Success) + allow_user = !(ui1->usri1_flags & (UF_ACCOUNTDISABLE | UF_LOCKOUT)); + if (ui1) + NetApiBufferFree (ui1); + if (!allow_user) + { + debug_printf ("User denied: %W\\%W", domain, user); + set_errno (EACCES); + return false; + } get_user_groups (server, grp_list, user, domain); get_user_local_groups (server, domain, grp_list, user); } From 02373d8bec71abcd46421f0ce952ad4e8cfc1422 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Thu, 24 Jan 2019 21:19:40 +0100 Subject: [PATCH 145/475] Cygwin: seteuid: work with password-less user switch as well The previous patch failed with password-less auth because in that case the return code from get_server_groups wasn't tested. Fix that. Also make sure that get_server_groups does not check if the account is disabled or locked out when just fetching the group list for initgroups or getgrouplist. Signed-off-by: Corinna Vinschen --- winsup/cygwin/grp.cc | 2 +- winsup/cygwin/sec_auth.cc | 50 ++++++++++++++++++++++++--------------- winsup/cygwin/security.h | 8 ++++++- 3 files changed, 39 insertions(+), 21 deletions(-) diff --git a/winsup/cygwin/grp.cc b/winsup/cygwin/grp.cc index ca35a4bf4..a126bffe1 100644 --- a/winsup/cygwin/grp.cc +++ b/winsup/cygwin/grp.cc @@ -738,7 +738,7 @@ get_groups (const char *user, gid_t gid, cygsidlist &gsids) struct group *grp = internal_getgrgid (gid, &cldap); cygsid usersid, grpsid; if (usersid.getfrompw (pw)) - get_server_groups (gsids, usersid); + get_server_groups (gsids, usersid, NO_CHK_DISABLED); if (gid != ILLEGAL_GID && grpsid.getfromgr (grp)) gsids += grpsid; cygheap->user.reimpersonate (); diff --git a/winsup/cygwin/sec_auth.cc b/winsup/cygwin/sec_auth.cc index 8fdfa3a86..af927636e 100644 --- a/winsup/cygwin/sec_auth.cc +++ b/winsup/cygwin/sec_auth.cc @@ -523,7 +523,8 @@ get_token_group_sidlist (cygsidlist &grp_list, PTOKEN_GROUPS my_grps) } bool -get_server_groups (cygsidlist &grp_list, PSID usersid) +get_server_groups (cygsidlist &grp_list, PSID usersid, + acct_disabled_chk_t check_account_disabled) { WCHAR user[UNLEN + 1]; WCHAR domain[MAX_DOMAIN_NAME_LEN + 1]; @@ -553,20 +554,23 @@ get_server_groups (cygsidlist &grp_list, PSID usersid) && sid_sub_auth (usersid, 0) == SECURITY_NT_NON_UNIQUE && get_logon_server (domain, server, DS_IS_FLAT_NAME)) { - NET_API_STATUS napi_stat; - USER_INFO_1 *ui1; - bool allow_user = false; - - napi_stat = NetUserGetInfo (server, user, 1, (LPBYTE *) &ui1); - if (napi_stat == NERR_Success) - allow_user = !(ui1->usri1_flags & (UF_ACCOUNTDISABLE | UF_LOCKOUT)); - if (ui1) - NetApiBufferFree (ui1); - if (!allow_user) + if (check_account_disabled == CHK_DISABLED) { - debug_printf ("User denied: %W\\%W", domain, user); - set_errno (EACCES); - return false; + NET_API_STATUS napi_stat; + USER_INFO_1 *ui1; + bool allow_user = false; + + napi_stat = NetUserGetInfo (server, user, 1, (LPBYTE *) &ui1); + if (napi_stat == NERR_Success) + allow_user = !(ui1->usri1_flags & (UF_ACCOUNTDISABLE | UF_LOCKOUT)); + if (ui1) + NetApiBufferFree (ui1); + if (!allow_user) + { + debug_printf ("User denied: %W\\%W", domain, user); + set_errno (EACCES); + return false; + } } get_user_groups (server, grp_list, user, domain); get_user_local_groups (server, domain, grp_list, user); @@ -582,7 +586,7 @@ get_initgroups_sidlist (cygsidlist &grp_list, PSID usersid, PSID pgrpsid, grp_list *= well_known_authenticated_users_sid; if (well_known_system_sid != usersid) get_token_group_sidlist (grp_list, my_grps); - if (!get_server_groups (grp_list, usersid)) + if (!get_server_groups (grp_list, usersid, CHK_DISABLED)) return false; /* special_pgrp true if pgrpsid is not in normal groups */ @@ -590,17 +594,19 @@ get_initgroups_sidlist (cygsidlist &grp_list, PSID usersid, PSID pgrpsid, return true; } -static void +static bool get_setgroups_sidlist (cygsidlist &tmp_list, PSID usersid, PTOKEN_GROUPS my_grps, user_groups &groups) { tmp_list *= well_known_world_sid; tmp_list *= well_known_authenticated_users_sid; get_token_group_sidlist (tmp_list, my_grps); - get_server_groups (tmp_list, usersid); + if (!get_server_groups (tmp_list, usersid, CHK_DISABLED)) + return false; for (int gidx = 0; gidx < groups.sgsids.count (); gidx++) tmp_list += groups.sgsids.sids[gidx]; tmp_list += groups.pgsid; + return true; } /* Fixed size TOKEN_PRIVILEGES list to reflect privileges given to the @@ -953,7 +959,10 @@ create_token (cygsid &usersid, user_groups &new_groups) /* Create list of groups, the user is member in. */ if (new_groups.issetgroups ()) - get_setgroups_sidlist (tmp_gsids, usersid, my_tok_gsids, new_groups); + { + if (!get_setgroups_sidlist (tmp_gsids, usersid, my_tok_gsids, new_groups)) + goto out; + } else if (!get_initgroups_sidlist (tmp_gsids, usersid, new_groups.pgsid, my_tok_gsids)) goto out; @@ -1089,7 +1098,10 @@ lsaauth (cygsid &usersid, user_groups &new_groups) /* Create list of groups, the user is member in. */ if (new_groups.issetgroups ()) - get_setgroups_sidlist (tmp_gsids, usersid, NULL, new_groups); + { + if (!get_setgroups_sidlist (tmp_gsids, usersid, NULL, new_groups)) + goto out; + } else if (!get_initgroups_sidlist (tmp_gsids, usersid, new_groups.pgsid, NULL)) goto out; diff --git a/winsup/cygwin/security.h b/winsup/cygwin/security.h index 2f9d0ad4d..5104bb7d2 100644 --- a/winsup/cygwin/security.h +++ b/winsup/cygwin/security.h @@ -482,7 +482,13 @@ HANDLE lsaprivkeyauth (struct passwd *pw); /* Verify an existing token */ bool verify_token (HANDLE token, cygsid &usersid, user_groups &groups, bool *pintern = NULL); /* Get groups of a user */ -bool get_server_groups (cygsidlist &grp_list, PSID usersid); +enum acct_disabled_chk_t { + NO_CHK_DISABLED = 0, + CHK_DISABLED = 1 +}; + +bool get_server_groups (cygsidlist &grp_list, PSID usersid, + acct_disabled_chk_t check_account_disabled); /* Extract U-domain\user field from passwd entry. */ void extract_nt_dom_user (const struct passwd *pw, PWCHAR domain, PWCHAR user); From c524a915a55f4f7a88e706f0311195ac19d382cf Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Fri, 25 Jan 2019 20:01:11 +0100 Subject: [PATCH 146/475] Cygwin: lsaauth: Drop outdated test for loading Secur32.dll Signed-off-by: Corinna Vinschen --- winsup/cygwin/sec_auth.cc | 6 ------ 1 file changed, 6 deletions(-) diff --git a/winsup/cygwin/sec_auth.cc b/winsup/cygwin/sec_auth.cc index af927636e..1d07e374f 100644 --- a/winsup/cygwin/sec_auth.cc +++ b/winsup/cygwin/sec_auth.cc @@ -1061,7 +1061,6 @@ lsaauth (cygsid &usersid, user_groups &new_groups) /* Register as logon process. */ RtlInitAnsiString (&name, "Cygwin"); - SetLastError (0); status = LsaRegisterLogonProcess (&name, &lsa_hdl, &sec_mode); if (status != STATUS_SUCCESS) { @@ -1069,11 +1068,6 @@ lsaauth (cygsid &usersid, user_groups &new_groups) __seterrno_from_nt_status (status); goto out; } - else if (GetLastError () == ERROR_PROC_NOT_FOUND) - { - debug_printf ("Couldn't load Secur32.dll"); - goto out; - } /* Get handle to our own LSA package. */ RtlInitAnsiString (&name, CYG_LSA_PKGNAME); status = LsaLookupAuthenticationPackage (lsa_hdl, &name, &package_id); From 3a1ed0ef7060bb9ebf18ac3c00a5cb2860b225d1 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Fri, 25 Jan 2019 20:02:03 +0100 Subject: [PATCH 147/475] Cygwin: syscalls.cc: fix formatting Signed-off-by: Corinna Vinschen --- winsup/cygwin/syscalls.cc | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc index 04035a9ab..289f4626f 100644 --- a/winsup/cygwin/syscalls.cc +++ b/winsup/cygwin/syscalls.cc @@ -371,7 +371,7 @@ try_to_bin (path_conv &pc, HANDLE &fh, ACCESS_MASK access, ULONG flags) if (!NT_SUCCESS (status)) { debug_printf ("NtOpenFile (%S) failed, status = %y", - &recycler, status); + &recycler, status); goto out; } /* Correct the rootdir HANDLE in pfri after reopening the dir. */ @@ -394,7 +394,7 @@ try_to_bin (path_conv &pc, HANDLE &fh, ACCESS_MASK access, ULONG flags) if (!NT_SUCCESS (status)) { debug_printf ("NtCreateFile (%S) failed, status = %y", - &recycler, status); + &recycler, status); goto out; } /* If we opened the recycler (in contrast to creating it) and our @@ -1842,7 +1842,6 @@ fhandler_base::stat_fixup (struct stat *buf) buf->st_ino = FH_TTY; else buf->st_ino = get_device (); - } /* For /dev-based devices, st_dev must be set to the device number of /dev, not it's own device major/minor numbers. What we do here to speed up @@ -2436,7 +2435,7 @@ rename2 (const char *oldpath, const char *newpath, unsigned int at2flags) else if (oldpc.is_binary () && !old_explicit_suffix && oldpc.known_suffix () && !nt_path_has_executable_suffix - (newpc.get_nt_native_path ())) + (newpc.get_nt_native_path ())) /* Never append .exe suffix if oldpath had .exe suffix given explicitely, or if oldpath wasn't already a .exe file, or if the destination filename has one of the blessed executable @@ -2477,7 +2476,7 @@ rename2 (const char *oldpath, const char *newpath, unsigned int at2flags) if (!old_explicit_suffix && oldpc.known_suffix () && !newpc.is_binary () && !nt_path_has_executable_suffix - (newpc.get_nt_native_path ())) + (newpc.get_nt_native_path ())) { rename_append_suffix (new2pc, newpath, nlen, ".exe"); removepc = &newpc; From 0e3fd33321414e03466370bca048b4c4b6f91ba0 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Fri, 25 Jan 2019 19:58:21 +0100 Subject: [PATCH 148/475] Cygwin: create_token: Return NULL, not INVALID_HANDLE_VALUE Signed-off-by: Corinna Vinschen --- winsup/cygwin/sec_auth.cc | 5 +++-- winsup/cygwin/syscalls.cc | 5 ++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/winsup/cygwin/sec_auth.cc b/winsup/cygwin/sec_auth.cc index 1d07e374f..54053dfb5 100644 --- a/winsup/cygwin/sec_auth.cc +++ b/winsup/cygwin/sec_auth.cc @@ -907,8 +907,8 @@ create_token (cygsid &usersid, user_groups &new_groups) source.SourceIdentifier.HighPart = 0; source.SourceIdentifier.LowPart = 0x0101; - HANDLE token = INVALID_HANDLE_VALUE; - HANDLE primary_token = INVALID_HANDLE_VALUE; + HANDLE token = NULL; + HANDLE primary_token = NULL; tmp_pathbuf tp; PTOKEN_GROUPS my_tok_gsids = NULL; @@ -1010,6 +1010,7 @@ create_token (cygsid &usersid, user_groups &new_groups) { __seterrno (); debug_printf ("DuplicateTokenEx %E"); + primary_token = NULL; } } diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc index 289f4626f..978bd424e 100644 --- a/winsup/cygwin/syscalls.cc +++ b/winsup/cygwin/syscalls.cc @@ -3546,10 +3546,9 @@ seteuid32 (uid_t uid) if (!(new_token = lsaauth (usersid, groups))) { debug_printf ("lsaauth failed, try create_token."); - new_token = create_token (usersid, groups); - if (new_token == INVALID_HANDLE_VALUE) + if (!(new_token = create_token (usersid, groups))) { - debug_printf ("create_token failed, bail out of here"); + debug_printf ("create_token failed, bail out"); cygheap->user.reimpersonate (); return -1; } From 6ffcc50f192b75971b88d5e5bdffdeec945153a8 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Sat, 26 Jan 2019 18:26:56 +0100 Subject: [PATCH 149/475] Cygwin: netdb.h: fix __GNU_VISIBLE tests Signed-off-by: Corinna Vinschen --- winsup/cygwin/include/netdb.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/winsup/cygwin/include/netdb.h b/winsup/cygwin/include/netdb.h index 91e91720d..30fb06334 100644 --- a/winsup/cygwin/include/netdb.h +++ b/winsup/cygwin/include/netdb.h @@ -167,7 +167,7 @@ extern __declspec(dllimport) int h_errno; #define AI_ADDRCONFIG 0x400 /* Only return address types available on this host. */ #define AI_V4MAPPED 0x800 /* IPv4 mapped addresses are acceptable. */ -#ifdef __GNU_VISIBLE +#if __GNU_VISIBLE /* Glibc extensions. We use numerical values taken by winsock-specific extensions. */ #define AI_IDN 0x4000 /* Encode IDN input from current local to @@ -186,7 +186,7 @@ extern __declspec(dllimport) int h_errno; #define NI_NAMEREQD 0x4 /* Not being able to resolve is an error. */ #define NI_NUMERICSERV 0x8 /* Return port number, rather than name. */ #define NI_DGRAM 0x10 /* Lookup datagram (UDP) service. */ -#ifdef __GNU_VISIBLE +#if __GNU_VISIBLE /* Glibc extensions. We use numerical values taken by winsock-specific extensions. */ #define NI_IDN 0x4000 /* Decode name from punycode to IDN in @@ -215,7 +215,7 @@ extern __declspec(dllimport) int h_errno; #define EAI_BADHINTS 12 /* Invalid value for hints */ #define EAI_PROTOCOL 13 /* Resolved protocol is unknown */ #define EAI_OVERFLOW 14 /* An argument buffer overflowed */ -#ifdef __GNU_VISIBLE +#if __GNU_VISIBLE /* Glibc extensions. */ #define EAI_IDN_ENCODE 15 /* Parameter string not correctly encoded */ #endif From 84230b71c64765ad0e34faffdfe6d1c58477a84d Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Thu, 24 Jan 2019 12:01:01 +0100 Subject: [PATCH 150/475] Cygwin: uname: Raise size of utsname fields and revamp uname(2) output New format: sysname: CYGWIN_NT-${osversion}-${os_build_number}[-WOW64] nodename: `gethostname` release: ${cygwin_version}-${API minor}.${arch}[.snap] version: YYYY-MM-DD HH:MM UTC machine: ${arch} _GNU_SOURCE: domainname: `getdomainname` !_GNU_SOURCE: __domainname: `getdomainname` Signed-off-by: Corinna Vinschen --- winsup/cygwin/Makefile.in | 1 + winsup/cygwin/common.din | 1 + winsup/cygwin/include/cygwin/version.h | 3 +- winsup/cygwin/include/sys/utsname.h | 17 +++++-- winsup/cygwin/release/2.12.0 | 2 + winsup/cygwin/uname.cc | 70 +++++++++++++++++++++++++- winsup/cygwin/wincap.h | 1 + winsup/doc/new-features.xml | 4 ++ 8 files changed, 92 insertions(+), 7 deletions(-) diff --git a/winsup/cygwin/Makefile.in b/winsup/cygwin/Makefile.in index 32c02b87b..ecdabb003 100644 --- a/winsup/cygwin/Makefile.in +++ b/winsup/cygwin/Makefile.in @@ -440,6 +440,7 @@ GMON_OFILES:=gmon.o mcount.o profil.o mcountFunc.o NEW_FUNCTIONS:=$(addprefix --replace=,\ atexit= \ timezone= \ + uname=uname_x \ __xdrrec_getrec= \ __xdrrec_setnonblock= \ xdr_array= \ diff --git a/winsup/cygwin/common.din b/winsup/cygwin/common.din index ca819c63e..f620d8183 100644 --- a/winsup/cygwin/common.din +++ b/winsup/cygwin/common.din @@ -1522,6 +1522,7 @@ ualarm SIGFE umask NOSIGFE umount SIGFE uname SIGFE +uname_x SIGFE ungetc SIGFE ungetwc SIGFE unlink SIGFE diff --git a/winsup/cygwin/include/cygwin/version.h b/winsup/cygwin/include/cygwin/version.h index c3e971ed8..478d080f5 100644 --- a/winsup/cygwin/include/cygwin/version.h +++ b/winsup/cygwin/include/cygwin/version.h @@ -505,12 +505,13 @@ details. */ 332: Add signalfd. 333: Add timerfd_create, timerfd_gettime, timerfd_settime. 334: Remove matherr. + 335: Change size of utsname, change uname output. Note that we forgot to bump the api for ualarm, strtoll, strtoull, sigaltstack, sethostname. */ #define CYGWIN_VERSION_API_MAJOR 0 -#define CYGWIN_VERSION_API_MINOR 334 +#define CYGWIN_VERSION_API_MINOR 335 /* There is also a compatibity version number associated with the shared memory regions. It is incremented when incompatible changes are made to the shared diff --git a/winsup/cygwin/include/sys/utsname.h b/winsup/cygwin/include/sys/utsname.h index e9dd019df..d6b3be96f 100644 --- a/winsup/cygwin/include/sys/utsname.h +++ b/winsup/cygwin/include/sys/utsname.h @@ -13,13 +13,20 @@ details. */ extern "C" { #endif +#define _UTSNAME_LENGTH 65 + struct utsname { - char sysname[20]; - char nodename[20]; - char release[20]; - char version[20]; - char machine[20]; + char sysname[_UTSNAME_LENGTH]; + char nodename[_UTSNAME_LENGTH]; + char release[_UTSNAME_LENGTH]; + char version[_UTSNAME_LENGTH]; + char machine[_UTSNAME_LENGTH]; +#if __GNU_VISIBLE + char domainname[_UTSNAME_LENGTH]; +#else + char __domainname[_UTSNAME_LENGTH]; +#endif }; int uname (struct utsname *); diff --git a/winsup/cygwin/release/2.12.0 b/winsup/cygwin/release/2.12.0 index c2abc9329..19e05565a 100644 --- a/winsup/cygwin/release/2.12.0 +++ b/winsup/cygwin/release/2.12.0 @@ -56,6 +56,8 @@ What changed: - Remove matherr, and SVID and X/Open math library configurations. Default math library configuration is now IEEE. +- Improve uname(2) for newly built applications. + Bug Fixes --------- diff --git a/winsup/cygwin/uname.cc b/winsup/cygwin/uname.cc index 778ca5738..306cdee4a 100644 --- a/winsup/cygwin/uname.cc +++ b/winsup/cygwin/uname.cc @@ -10,15 +10,83 @@ details. */ #include "winsup.h" #include +#include #include "cygwin_version.h" #include "cygtls.h" extern "C" int cygwin_gethostname (char *__name, size_t __len); +extern "C" int getdomainname (char *__name, size_t __len); /* uname: POSIX 4.4.1.1 */ + +/* New entrypoint for applications since API 335 */ extern "C" int -uname (struct utsname *name) +uname_x (struct utsname *name) { + __try + { + char buf[NI_MAXHOST + 1]; + char *snp = strstr (cygwin_version.dll_build_date, "SNP"); + + memset (name, 0, sizeof (*name)); + /* sysname */ + __small_sprintf (name->sysname, "CYGWIN_%s-%u%s", + wincap.osname (), wincap.build_number (), + wincap.is_wow64 () ? "-WOW64" : ""); + /* nodename */ + memset (buf, 0, sizeof buf); + cygwin_gethostname (buf, sizeof buf - 1); + strncat (name->nodename, buf, sizeof (name->nodename) - 1); + /* release */ + __small_sprintf (name->release, "%d.%d.%d-%d.", + cygwin_version.dll_major / 1000, + cygwin_version.dll_major % 1000, + cygwin_version.dll_minor, + cygwin_version.api_minor); + /* version */ + stpcpy (name->version, cygwin_version.dll_build_date); + if (snp) + name->version[snp - cygwin_version.dll_build_date] = '\0'; + strcat (name->version, " UTC"); + /* machine */ + switch (wincap.cpu_arch ()) + { + case PROCESSOR_ARCHITECTURE_INTEL: + strcat (name->release, strcpy (name->machine, "i686")); + break; + case PROCESSOR_ARCHITECTURE_AMD64: + strcat (name->release, strcpy (name->machine, "x86_64")); + break; + default: + strcpy (name->machine, "unknown"); + break; + } + if (snp) + strcat (name->release, ".snap"); + /* domainame */ + memset (buf, 0, sizeof buf); + getdomainname (buf, sizeof buf - 1); + strncat (name->domainname, buf, sizeof (name->domainname) - 1); + } + __except (EFAULT) { return -1; } + __endtry + return 0; +} + +/* Old entrypoint for applications up to API 334 */ +struct old_utsname +{ + char sysname[20]; + char nodename[20]; + char release[20]; + char version[20]; + char machine[20]; +}; + +extern "C" int +uname (struct utsname *in_name) +{ + struct old_utsname *name = (struct old_utsname *) in_name; __try { char *snp = strstr (cygwin_version.dll_build_date, "SNP"); diff --git a/winsup/cygwin/wincap.h b/winsup/cygwin/wincap.h index d89fd71b4..f8846f91d 100644 --- a/winsup/cygwin/wincap.h +++ b/winsup/cygwin/wincap.h @@ -59,6 +59,7 @@ public: const size_t allocation_granularity () const { return (size_t) system_info.dwAllocationGranularity; } const char *osname () const { return osnam; } + const DWORD build_number () const { return version.dwBuildNumber; } const bool is_wow64 () const { return !!wow64; } #define IMPLEMENT(cap) cap() const { return ((wincaps *) this->caps)->cap; } diff --git a/winsup/doc/new-features.xml b/winsup/doc/new-features.xml index 59db9c98a..ae5088d27 100644 --- a/winsup/doc/new-features.xml +++ b/winsup/doc/new-features.xml @@ -91,6 +91,10 @@ Remove matherr, and SVID and X/Open math library configurations. Default math library configuration is now IEEE. + +Improve uname(2) for newly built applications. + + From 0fb497165f8545470624012315aeaf37333c1ea2 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Sat, 26 Jan 2019 18:33:41 +0100 Subject: [PATCH 151/475] Cygwin: seteuid: use Kerberos/MsV1_0 S4U authentication by default - This simple and official method replaces cyglsa and "create token" methods. No network share access, same as before. - lsaauth and create_token are disabled now. If problems crop up, they can be easily reactivated. If no problems crop up, they can be removed in a while, together with the lsaauth subdir. - Bump Cygwin version to 3.0. Signed-off-by: Corinna Vinschen --- winsup/cygwin/autoload.cc | 1 + winsup/cygwin/include/cygwin/version.h | 2 +- winsup/cygwin/release/{2.12.0 => 3.0} | 3 + winsup/cygwin/sec_auth.cc | 265 ++++++++++++++++++++++++- winsup/cygwin/security.h | 2 + winsup/cygwin/syscalls.cc | 26 ++- winsup/doc/new-features.xml | 13 +- winsup/doc/ntsec.xml | 118 +++++------ 8 files changed, 352 insertions(+), 78 deletions(-) rename winsup/cygwin/release/{2.12.0 => 3.0} (95%) diff --git a/winsup/cygwin/autoload.cc b/winsup/cygwin/autoload.cc index b4dc77339..73367dfd8 100644 --- a/winsup/cygwin/autoload.cc +++ b/winsup/cygwin/autoload.cc @@ -647,6 +647,7 @@ LoadDLLfunc (LsaFreeReturnBuffer, 4, secur32) LoadDLLfunc (LsaLogonUser, 56, secur32) LoadDLLfunc (LsaLookupAuthenticationPackage, 12, secur32) LoadDLLfunc (LsaRegisterLogonProcess, 12, secur32) +LoadDLLfunc (TranslateNameW, 20, secur32) LoadDLLfunc (SHGetDesktopFolder, 4, shell32) diff --git a/winsup/cygwin/include/cygwin/version.h b/winsup/cygwin/include/cygwin/version.h index 478d080f5..b5ba93f5a 100644 --- a/winsup/cygwin/include/cygwin/version.h +++ b/winsup/cygwin/include/cygwin/version.h @@ -10,7 +10,7 @@ details. */ the Cygwin shared library". This version is used to track important changes to the DLL and is mainly informative in nature. */ -#define CYGWIN_VERSION_DLL_MAJOR 2012 +#define CYGWIN_VERSION_DLL_MAJOR 3000 #define CYGWIN_VERSION_DLL_MINOR 0 /* Major numbers before CYGWIN_VERSION_DLL_EPOCH are incompatible. */ diff --git a/winsup/cygwin/release/2.12.0 b/winsup/cygwin/release/3.0 similarity index 95% rename from winsup/cygwin/release/2.12.0 rename to winsup/cygwin/release/3.0 index 19e05565a..79affdb27 100644 --- a/winsup/cygwin/release/2.12.0 +++ b/winsup/cygwin/release/3.0 @@ -58,6 +58,9 @@ What changed: - Improve uname(2) for newly built applications. +- Kerberos/MSV1_0 S4U authentication replaces two old methods: + Creating a token from scratch and Cygwin LSA authentication package. + Bug Fixes --------- diff --git a/winsup/cygwin/sec_auth.cc b/winsup/cygwin/sec_auth.cc index 54053dfb5..21cb0727f 100644 --- a/winsup/cygwin/sec_auth.cc +++ b/winsup/cygwin/sec_auth.cc @@ -24,6 +24,8 @@ details. */ #include #include #include +#define SECURITY_WIN32 +#include #include "cyglsa.h" #include "cygserver_setpwd.h" #include @@ -872,6 +874,32 @@ verify_token (HANDLE token, cygsid &usersid, user_groups &groups, bool *pintern) || groups.pgsid == usersid; } +const char * +account_restriction (NTSTATUS status) +{ + const char *type; + + switch (status) + { + case STATUS_INVALID_LOGON_HOURS: + type = "Logon outside allowed hours"; + break; + case STATUS_INVALID_WORKSTATION: + type = "Logon at this machine not allowed"; + break; + case STATUS_PASSWORD_EXPIRED: + type = "Password expired"; + break; + case STATUS_ACCOUNT_DISABLED: + type = "Account disabled"; + break; + default: + type = "Unknown"; + break; + } + return type; +} + HANDLE create_token (cygsid &usersid, user_groups &new_groups) { @@ -1229,7 +1257,11 @@ lsaauth (cygsid &usersid, user_groups &new_groups) &sub_status); if (status != STATUS_SUCCESS) { - debug_printf ("LsaLogonUser: %y (sub-status %y)", status, sub_status); + if (status == STATUS_ACCOUNT_RESTRICTION) + debug_printf ("Cygwin LSA Auth LsaLogonUser failed: %y (%s)", + status, account_restriction (sub_status)); + else + debug_printf ("Cygwin LSA Auth LsaLogonUser failed: %y", status); __seterrno_from_nt_status (status); goto out; } @@ -1338,3 +1370,234 @@ out: pop_self_privilege (); return token; } + +/* The following code is inspired by the generate_s4u_user_token + and lookup_principal_name functions from + https://github.com/PowerShell/openssh-portable + + Thanks guys! For courtesy here's the original copyright disclaimer: */ + +/* +* Author: Manoj Ampalam +* Utilities to generate user tokens +* +* Author: Bryan Berns +* Updated s4u, logon, and profile loading routines to use +* normalized login names. +* +* Copyright (c) 2015 Microsoft Corp. +* All rights reserved +* +* Microsoft openssh win32 port +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* +* 1. Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* 2. Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* +* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +/* In Mingw-w64, MsV1_0S4ULogon and MSV1_0_S4U_LOGON are only defined + in ddk/ntifs.h. We can't inlcude this. */ + +#define MsV1_0S4ULogon ((MSV1_0_LOGON_SUBMIT_TYPE) 12) + +typedef struct _MSV1_0_S4U_LOGON +{ + MSV1_0_LOGON_SUBMIT_TYPE MessageType; + ULONG Flags; + UNICODE_STRING UserPrincipalName; + UNICODE_STRING DomainName; +} MSV1_0_S4U_LOGON, *PMSV1_0_S4U_LOGON; + +HANDLE +s4uauth (struct passwd *pw) +{ + LSA_STRING name; + HANDLE lsa_hdl = NULL; + LSA_OPERATIONAL_MODE sec_mode; + NTSTATUS status, sub_status; + WCHAR domain[MAX_DOMAIN_NAME_LEN + 1]; + WCHAR user[UNLEN + 1]; + bool try_kerb_auth; + ULONG package_id, size; + struct { + LSA_STRING str; + CHAR buf[16]; + } origin; + + tmp_pathbuf tp; + PVOID authinf = NULL; + ULONG authinf_size; + TOKEN_SOURCE ts; + PKERB_INTERACTIVE_PROFILE profile = NULL; + LUID luid; + QUOTA_LIMITS quota; + HANDLE token = NULL; + + push_self_privilege (SE_TCB_PRIVILEGE, true); + + /* Register as logon process. */ + RtlInitAnsiString (&name, "Cygwin"); + status = LsaRegisterLogonProcess (&name, &lsa_hdl, &sec_mode); + if (status != STATUS_SUCCESS) + { + debug_printf ("LsaRegisterLogonProcess: %y", status); + __seterrno_from_nt_status (status); + goto out; + } + + /* Fetch user and domain name and check if this is a domain user. + If so, try Kerberos first. */ + extract_nt_dom_user (pw, domain, user); + try_kerb_auth = cygheap->dom.member_machine () + && wcscasecmp (domain, cygheap->dom.account_flat_name ()); + RtlInitAnsiString (&name, try_kerb_auth ? MICROSOFT_KERBEROS_NAME_A + : MSV1_0_PACKAGE_NAME); + status = LsaLookupAuthenticationPackage (lsa_hdl, &name, &package_id); + if (status != STATUS_SUCCESS) + { + debug_printf ("LsaLookupAuthenticationPackage: %y", status); + __seterrno_from_nt_status (status); + goto out; + } + /* Create origin. */ + stpcpy (origin.buf, "Cygwin"); + RtlInitAnsiString (&origin.str, origin.buf); + + if (try_kerb_auth) + { + PWCHAR sam_name = tp.w_get (); + PWCHAR upn_name = tp.w_get (); + size = NT_MAX_PATH; + KERB_S4U_LOGON *s4u_logon; + USHORT name_len; + + wcpcpy (wcpcpy (wcpcpy (sam_name, domain), L"\\"), user); + if (TranslateNameW (sam_name, NameSamCompatible, NameUserPrincipal, + upn_name, &size) == 0) + { + PWCHAR translated_name = tp.w_get (); + PWCHAR p; + + debug_printf ("TranslateNameW(%W, NameUserPrincipal) %E", sam_name); + size = NT_MAX_PATH; + if (TranslateNameW (sam_name, NameSamCompatible, NameCanonical, + translated_name, &size) == 0) + { + debug_printf ("TranslateNameW(%W, NameCanonical) %E", sam_name); + debug_printf ("Fallback to MsV1_0 auth"); + goto msv1_0_auth; /* Fall through to MSV1_0 authentication */ + } + p = wcschr (translated_name, L'/'); + if (p) + *p = '\0'; + wcpcpy (wcpcpy (wcpcpy (upn_name, user), L"@"), translated_name); + } + + name_len = wcslen (upn_name) * sizeof (WCHAR); + authinf_size = sizeof (KERB_S4U_LOGON) + name_len; + authinf = tp.c_get (); + RtlSecureZeroMemory (authinf, authinf_size); + s4u_logon = (KERB_S4U_LOGON *) authinf; + s4u_logon->MessageType = KerbS4ULogon; + s4u_logon->Flags = 0; + /* Append user to login info */ + RtlInitEmptyUnicodeString (&s4u_logon->ClientUpn, + (PWCHAR) (s4u_logon + 1), + name_len); + RtlAppendUnicodeToString (&s4u_logon->ClientUpn, upn_name); + debug_printf ("ClientUpn: <%S>", &s4u_logon->ClientUpn); + /* Create token source. */ + memcpy (ts.SourceName, "Cygwin.1", 8); + ts.SourceIdentifier.HighPart = 0; + ts.SourceIdentifier.LowPart = 0x0105; + status = LsaLogonUser (lsa_hdl, (PLSA_STRING) &origin, Network, + package_id, authinf, authinf_size, NULL, + &ts, (PVOID *) &profile, &size, + &luid, &token, "a, &sub_status); + switch (status) + { + case STATUS_SUCCESS: + goto out; + /* These failures are fatal */ + case STATUS_QUOTA_EXCEEDED: + case STATUS_LOGON_FAILURE: + debug_printf ("Kerberos S4U LsaLogonUser failed: %y", status); + goto out; + case STATUS_ACCOUNT_RESTRICTION: + debug_printf ("Kerberos S4U LsaLogonUser failed: %y (%s)", + status, account_restriction (sub_status)); + goto out; + default: + break; + } + debug_printf ("Kerberos S4U LsaLogonUser failed: %y, try MsV1_0", status); + /* Fall through to MSV1_0 authentication */ + } + +msv1_0_auth: + MSV1_0_S4U_LOGON *s4u_logon; + USHORT user_len, domain_len; + + user_len = wcslen (user) * sizeof (WCHAR); + domain_len = wcslen (domain) * sizeof (WCHAR); /* Local machine */ + authinf_size = sizeof (MSV1_0_S4U_LOGON) + user_len + domain_len; + if (!authinf) + authinf = tp.c_get (); + RtlSecureZeroMemory (authinf, authinf_size); + s4u_logon = (MSV1_0_S4U_LOGON *) authinf; + s4u_logon->MessageType = MsV1_0S4ULogon; + s4u_logon->Flags = 0; + /* Append user and domain to login info */ + RtlInitEmptyUnicodeString (&s4u_logon->UserPrincipalName, + (PWCHAR) (s4u_logon + 1), + user_len); + RtlInitEmptyUnicodeString (&s4u_logon->DomainName, + (PWCHAR) ((PBYTE) (s4u_logon + 1) + user_len), + domain_len); + RtlAppendUnicodeToString (&s4u_logon->UserPrincipalName, user); + RtlAppendUnicodeToString (&s4u_logon->DomainName, domain); + debug_printf ("DomainName: <%S> UserPrincipalName: <%S>", + &s4u_logon->DomainName, &s4u_logon->UserPrincipalName); + /* Create token source. */ + memcpy (ts.SourceName, "Cygwin.1", 8); + ts.SourceIdentifier.HighPart = 0; + ts.SourceIdentifier.LowPart = 0x0106; + if ((status = LsaLogonUser (lsa_hdl, (PLSA_STRING) &origin, Network, + package_id, authinf, authinf_size, NULL, + &ts, (PVOID *) &profile, &size, + &luid, &token, "a, &sub_status)) + != STATUS_SUCCESS) + { + if (status == STATUS_ACCOUNT_RESTRICTION) + debug_printf ("MSV1_0 S4U LsaLogonUser failed: %y (%s)", + status, account_restriction (sub_status)); + else + debug_printf ("MSV1_0 S4U LsaLogonUser failed: %y", status); + } + +out: + if (lsa_hdl) + LsaDeregisterLogonProcess (lsa_hdl); + if (profile) + LsaFreeReturnBuffer (profile); + + pop_self_privilege (); + return token; +} diff --git a/winsup/cygwin/security.h b/winsup/cygwin/security.h index 5104bb7d2..70912b4fc 100644 --- a/winsup/cygwin/security.h +++ b/winsup/cygwin/security.h @@ -479,6 +479,8 @@ HANDLE create_token (cygsid &usersid, user_groups &groups); HANDLE lsaauth (cygsid &, user_groups &); /* LSA private key storage authentication, same as when using service logons. */ HANDLE lsaprivkeyauth (struct passwd *pw); +/* Kerberos or MsV1 S4U logon. */ +HANDLE s4uauth (struct passwd *pw); /* Verify an existing token */ bool verify_token (HANDLE token, cygsid &usersid, user_groups &groups, bool *pintern = NULL); /* Get groups of a user */ diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc index 978bd424e..8a995e8fb 100644 --- a/winsup/cygwin/syscalls.cc +++ b/winsup/cygwin/syscalls.cc @@ -3494,7 +3494,7 @@ seteuid32 (uid_t uid) order, the setgroups group list is still active when calling seteuid and verify_token treats the original token of the privileged user as insufficient. This in turn results in creating a new user token for - the privileged user instead of using the orignal token. This can have + the privileged user instead of using the original token. This can have unfortunate side effects. The created token has different group memberships, different user rights, and misses possible network credentials. @@ -3542,17 +3542,31 @@ seteuid32 (uid_t uid) } if (!new_token) { +#if 1 + debug_printf ("lsaprivkeyauth failed, try s4uauth."); + if (!(new_token = s4uauth (pw_new))) + { + debug_printf ("s4uauth failed, bail out"); + cygheap->user.reimpersonate (); + return -1; + } +#else debug_printf ("lsaprivkeyauth failed, try lsaauth."); if (!(new_token = lsaauth (usersid, groups))) { - debug_printf ("lsaauth failed, try create_token."); - if (!(new_token = create_token (usersid, groups))) + debug_printf ("lsaauth failed, try s4uauth."); + if (!(new_token = s4uauth (pw_new))) { - debug_printf ("create_token failed, bail out"); - cygheap->user.reimpersonate (); - return -1; + debug_printf ("s4uauth failed, try create_token."); + if (!(new_token = create_token (usersid, groups))) + { + debug_printf ("create_token failed, bail out"); + cygheap->user.reimpersonate (); + return -1; + } } } +#endif } /* Keep at most one internal token */ diff --git a/winsup/doc/new-features.xml b/winsup/doc/new-features.xml index ae5088d27..d620d1c2c 100644 --- a/winsup/doc/new-features.xml +++ b/winsup/doc/new-features.xml @@ -4,7 +4,7 @@ What's new and what changed in Cygwin -What's new and what changed in 2.12 +What's new and what changed in 3.0 @@ -86,15 +86,20 @@ to free the parent directory. Wctype functions updated to Unicode 11.0. - + Remove matherr, and SVID and X/Open math library configurations. Default math library configuration is now IEEE. - - + + Improve uname(2) for newly built applications. + +Kerberos/MSV1_0 S4U authentication replaces two old methods: +Creating a token from scratch and Cygwin LSA authentication package. + + diff --git a/winsup/doc/ntsec.xml b/winsup/doc/ntsec.xml index 03293591b..e8419c5bc 100644 --- a/winsup/doc/ntsec.xml +++ b/winsup/doc/ntsec.xml @@ -2326,35 +2326,56 @@ example: -Switching the user context without password, Method 1: Create a token from scratch +Switching the user context without password, Method 1: Kerberos/MsV1_0 S4U authentication An unfortunate aspect of the implementation of set(e)uid is the fact that the calling process -requires the password of the user to which to switch. Applications such as +requires the password of the user to switch to. Applications such as sshd wishing to switch the user context after a successful public key authentication, or the cron application which, again, wants to switch the user without any authentication are stuck here. But there are other ways to get new user tokens. -One way is just to create a user token from scratch. This is -accomplished by using an (officially undocumented) function on the NT -function level. The NT function level is used to implement the Win32 -level, and, as such is closer to the kernel than the Win32 level. The -function of interest, NtCreateToken, allows you to -specify user, groups, permissions and almost everything you need to -create a user token, without the need to specify the user password. The -only restriction for using this function is that the calling process -needs the "Create a token object" user right, which only the SYSTEM user -account has by default, and which is considered the most dangerous right -a user can have on Windows systems. +Starting with Cygwin 3.0, Cygwin tries to create a token by using +Windows S4U authentication by default. For a quick +description, see +this blog posting. Cygwin versions prior +to 3.0 tried to creat a user token from scratch using an officially +undocumented function NtCreateToken which +is now disabled. -That sounds good. We just start the servers which have to switch -the user context (sshd, inetd, -cron, ...) as Windows services under the SYSTEM -(or LocalSystem in the GUI) account and everything just works. -Unfortunately that's too simple. Using NtCreateToken -has a few drawbacks. +So we just start the servers which have to switch the user context +(sshd, inetd, cron, +...) as Windows services under the SYSTEM (or LocalSystem in the GUI) +account and everything just works. Unfortunately that's too simple. +Using S4U has a drawback. +Annoyingly, you don't have the usual comfortable access +to network shares. The reason is that the token has been created +without knowing the password. The password are your credentials +necessary for network access. Thus, if you logon with a password, the +password is stored hidden as "token credentials" within the access token +and used as default logon to access network resources. Since these +credentials are missing from the token created with S4U +or NtCreateToken, you only can access network shares +from the new user's process tree by using explicit authentication, on +the command line for instance: + + +bash$ net use '\\server\share' /user:DOMAIN\my_user my_users_password + + +Note that, on some systems, you can't even define a drive letter +to access the share, and under some circumstances the drive letter you +choose collides with a drive letter already used in another session. +Therefore it's better to get used to accessing these shares using the UNC +path as in + + +bash$ grep foo //server/share/foofile + + + -Switching the user context without password, Method 3: With password +Switching the user context without password, Method 2: With password -Ok, so we have solved almost any problem, except for the network -access problem. Not being able to access network shares without -having to specify a cleartext password on the command line or in a -script is a harsh problem for automated logons for testing purposes -and similar stuff. +Not being able to access network shares without having to specify +a cleartext password on the command line or in a script is a harsh problem +for automated logons for testing purposes and similar stuff. Fortunately there is a solution, but it has its own drawbacks. But, first things first, how does it work? The title of this section @@ -2512,13 +2504,7 @@ as normal, non-privileged user as well. hidden, obfuscated registry area. Only SYSTEM has access to this area for listing purposes, so, even as an administrator, you can't examine this area with regedit. Right? No. Every administrator can start -regedit as SYSTEM user: - - -bash$ date -Tue Dec 2 16:28:03 CET 2008 -bash$ at 16:29 /interactive regedit.exe - +regedit as SYSTEM user, the Internet is your friend here. Additionally, if an administrator knows under which name the private key is stored (which is well-known since the algorithms @@ -2539,12 +2525,12 @@ safely use this method. Switching the user context, how does it all fit together? -Now we learned about four different ways to switch the user +Now we learned about three different ways to switch the user context using the set(e)uid system call, but how does set(e)uid really work? Which method does it use now? -The answer is, all four of them. So here's a brief overview +The answer is, all three of them. So here's a brief overview what set(e)uid does under the hood: @@ -2575,17 +2561,17 @@ private registry area, either under a Cygwin key, or under a SFU key. If so, use this to call LogonUser. If this succeeds, we use the resulting token for the user context switch. - + -Last chance, try to use the NtCreateToken call -to create a token. If that works, use this token. +Otherwise, use the default S4U authentication +to create a token. From 69cc7a068656b5c6ef07ca079a213f801e02e650 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Sun, 27 Jan 2019 13:15:15 +0100 Subject: [PATCH 152/475] Cygwin: fork: restrict parent handle perms and drop handle after use Signed-off-by: Corinna Vinschen --- winsup/cygwin/dcrt0.cc | 3 ++- winsup/cygwin/fork.cc | 2 ++ winsup/cygwin/sigproc.cc | 5 +++-- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/winsup/cygwin/dcrt0.cc b/winsup/cygwin/dcrt0.cc index af5eaaca7..cf2a08eb1 100644 --- a/winsup/cygwin/dcrt0.cc +++ b/winsup/cygwin/dcrt0.cc @@ -637,7 +637,8 @@ child_info_fork::handle_fork () bool child_info_spawn::get_parent_handle () { - parent = OpenProcess (PROCESS_VM_READ, false, parent_winpid); + parent = OpenProcess (PROCESS_QUERY_LIMITED_INFORMATION, FALSE, + parent_winpid); moreinfo->myself_pinfo = NULL; return !!parent; } diff --git a/winsup/cygwin/fork.cc b/winsup/cygwin/fork.cc index 6813446cf..d8c4ac459 100644 --- a/winsup/cygwin/fork.cc +++ b/winsup/cygwin/fork.cc @@ -203,6 +203,8 @@ frok::child (volatile char * volatile here) rd_proc_pipe that would be an invalid handle. In the case of wr_proc_pipe it would be == my_wr_proc_pipe. Both would be bad. */ ch.rd_proc_pipe = ch.wr_proc_pipe = NULL; + CloseHandle (hParent); + hParent = NULL; cygwin_finished_initializing = true; return 0; } diff --git a/winsup/cygwin/sigproc.cc b/winsup/cygwin/sigproc.cc index 92fa5ea3d..45e948251 100644 --- a/winsup/cygwin/sigproc.cc +++ b/winsup/cygwin/sigproc.cc @@ -814,8 +814,9 @@ child_info::child_info (unsigned in_cb, child_info_types chtype, allow the child to duplicate handles from the parent to itself. */ parent = NULL; if (!DuplicateHandle (GetCurrentProcess (), GetCurrentProcess (), - GetCurrentProcess (), &parent, 0, true, - DUPLICATE_SAME_ACCESS)) + GetCurrentProcess (), &parent, + PROCESS_DUP_HANDLE | PROCESS_VM_READ + | PROCESS_QUERY_LIMITED_INFORMATION, TRUE, 0)) system_printf ("couldn't create handle to myself for child, %E"); } From 3b21333172e57f56fa44ce63a10c368289701062 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Sun, 27 Jan 2019 22:42:41 +0100 Subject: [PATCH 153/475] Cygwin: spawn: revert incorrect restriction of permissions Signed-off-by: Corinna Vinschen --- winsup/cygwin/dcrt0.cc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/winsup/cygwin/dcrt0.cc b/winsup/cygwin/dcrt0.cc index cf2a08eb1..6b564dced 100644 --- a/winsup/cygwin/dcrt0.cc +++ b/winsup/cygwin/dcrt0.cc @@ -637,8 +637,7 @@ child_info_fork::handle_fork () bool child_info_spawn::get_parent_handle () { - parent = OpenProcess (PROCESS_QUERY_LIMITED_INFORMATION, FALSE, - parent_winpid); + parent = OpenProcess (PROCESS_VM_READ, FALSE, parent_winpid); moreinfo->myself_pinfo = NULL; return !!parent; } From 2741dd055010546c25223e6a4d0dc6aedc4b6607 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Sun, 27 Jan 2019 13:32:44 +0100 Subject: [PATCH 154/475] Cygwin: seteuid: disable unused funcs and lsaauth subdir If S4U proves to be usable alone, remove this code entirely. Signed-off-by: Corinna Vinschen --- winsup/configure | 4 ++-- winsup/configure.ac | 2 +- winsup/cygwin/sec_auth.cc | 8 ++++++++ 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/winsup/configure b/winsup/configure index 23b3a7b78..a66c34585 100755 --- a/winsup/configure +++ b/winsup/configure @@ -682,7 +682,7 @@ CXXFLAGS CCC CPP' ac_subdirs_all='cygwin cygserver doc -utils lsaauth' +utils' # Initialize some variables set by options. ac_init_help= @@ -3452,7 +3452,7 @@ export CXX subdirs="$subdirs cygwin cygserver doc" if test "x$with_cross_bootstrap" != "xyes"; then - subdirs="$subdirs utils lsaauth" + subdirs="$subdirs utils" fi diff --git a/winsup/configure.ac b/winsup/configure.ac index b975dfc1a..131dc79ee 100644 --- a/winsup/configure.ac +++ b/winsup/configure.ac @@ -36,7 +36,7 @@ AC_CYGWIN_INCLUDES AC_CONFIG_SUBDIRS(cygwin cygserver doc) if test "x$with_cross_bootstrap" != "xyes"; then - AC_CONFIG_SUBDIRS([utils lsaauth]) + AC_CONFIG_SUBDIRS([utils]) fi INSTALL_LICENSE="install-license" diff --git a/winsup/cygwin/sec_auth.cc b/winsup/cygwin/sec_auth.cc index 21cb0727f..d66a2a5d8 100644 --- a/winsup/cygwin/sec_auth.cc +++ b/winsup/cygwin/sec_auth.cc @@ -488,6 +488,7 @@ sid_in_token_groups (PTOKEN_GROUPS grps, cygpsid sid) return false; } +#if 0 && S4U_RUNS_FINE static void get_token_group_sidlist (cygsidlist &grp_list, PTOKEN_GROUPS my_grps) { @@ -523,6 +524,7 @@ get_token_group_sidlist (cygsidlist &grp_list, PTOKEN_GROUPS my_grps) grp_list *= well_known_users_sid; } } +#endif bool get_server_groups (cygsidlist &grp_list, PSID usersid, @@ -556,6 +558,7 @@ get_server_groups (cygsidlist &grp_list, PSID usersid, && sid_sub_auth (usersid, 0) == SECURITY_NT_NON_UNIQUE && get_logon_server (domain, server, DS_IS_FLAT_NAME)) { +#if 0 && S4U_RUNS_FINE if (check_account_disabled == CHK_DISABLED) { NET_API_STATUS napi_stat; @@ -574,12 +577,14 @@ get_server_groups (cygsidlist &grp_list, PSID usersid, return false; } } +#endif get_user_groups (server, grp_list, user, domain); get_user_local_groups (server, domain, grp_list, user); } return true; } +#if 0 && S4U_RUNS_FINE static bool get_initgroups_sidlist (cygsidlist &grp_list, PSID usersid, PSID pgrpsid, PTOKEN_GROUPS my_grps) @@ -757,6 +762,7 @@ get_priv_list (LSA_HANDLE lsa, cygsid &usersid, cygsidlist &grp_list, } return privs; } +#endif /* Accept a token if - the requested usersid matches the TokenUser and @@ -900,6 +906,7 @@ account_restriction (NTSTATUS status) return type; } +#if 0 && S4U_RUNS_FINE HANDLE create_token (cygsid &usersid, user_groups &new_groups) { @@ -1293,6 +1300,7 @@ out: debug_printf ("%p = lsaauth ()", user_token); return user_token; } +#endif #define SFU_LSA_KEY_SUFFIX L"_microsoft_sfu_utility" From e148aa62a79619b102c394029d170d22198542ea Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Mon, 28 Jan 2019 10:23:59 +0100 Subject: [PATCH 155/475] Cygwin: procfd: improve debug output Signed-off-by: Corinna Vinschen --- winsup/cygwin/fhandler.cc | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/winsup/cygwin/fhandler.cc b/winsup/cygwin/fhandler.cc index 9643373b0..07a048208 100644 --- a/winsup/cygwin/fhandler.cc +++ b/winsup/cygwin/fhandler.cc @@ -547,7 +547,8 @@ fhandler_base::open (int flags, mode_t mode) PFILE_FULL_EA_INFORMATION p = NULL; ULONG plen = 0; - syscall_printf ("(%S, %y)", pc.get_nt_native_path (), flags); + syscall_printf ("(%S, %y)%s", pc.get_nt_native_path (), flags, + get_handle () ? " by handle" : ""); if (flags & O_PATH) query_open (query_read_attributes); @@ -559,6 +560,8 @@ fhandler_base::open (int flags, mode_t mode) pc.init_reopen_attr (attr, get_handle ()); if (!(flags & O_CLOEXEC)) attr.Attributes |= OBJ_INHERIT; + if (pc.has_buggy_reopen ()) + debug_printf ("Reopen by handle requested but FS doesn't support it"); } else pc.get_object_attr (attr, *sec_none_cloexec (flags)); @@ -693,7 +696,7 @@ fhandler_base::open (int flags, mode_t mode) status = NtCreateFile (&fh, access, &attr, &io, NULL, file_attributes, shared, create_disposition, options, p, plen); - /* Pre-W10, we can't open a file by handle with delete disposition + /* Pre-W10, we can't reopen a file by handle with delete disposition set, so we have to lie our ass off. */ if (get_handle () && status == STATUS_DELETE_PENDING) { From c86b2f549bd099fdb56834d28a8103e8b9814e32 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Tue, 29 Jan 2019 17:33:59 +0100 Subject: [PATCH 156/475] Cygwin: Makefile.in: Improve dependency for version info The version info only depends on the object files. This results in the version info not being rebuild immediately if a source file is changed. Rather, the version info is only rebuilt on the next make run. Fix that by making the version info build rule dependent on the source files. Signed-off-by: Corinna Vinschen --- winsup/cygwin/Makefile.in | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/winsup/cygwin/Makefile.in b/winsup/cygwin/Makefile.in index ecdabb003..4dc849b4a 100644 --- a/winsup/cygwin/Makefile.in +++ b/winsup/cygwin/Makefile.in @@ -761,7 +761,12 @@ libssp.a: ${LIB_NAME} $(newlib_build)/libc/ssp/lib.a ${EXTRALIBS}: lib%.a: %.o $(AR) cru $@ $? -winver.o: mkvers.sh include/cygwin/version.h winver.rc $(DLL_OFILES) +# Every time we touch a source file, the version info has to be rebuilt +# to maintain a correct build date, especially in uname release output +find_src_files = $(wildcard $(dir)/*.[chS]) $(wildcard $(dir)/*.cc) +src_files := $(foreach dir,$(VPATH),$(find_src_files)) + +winver.o: mkvers.sh include/cygwin/version.h winver.rc $(src_files) @echo "Making version.cc and winver.o";\ /bin/sh ${word 1,$^} ${word 2,$^} ${word 3,$^} $(WINDRES) ${CFLAGS} $(addprefix -I,${CCWRAP_SYSTEM_HEADERS} ${CCWRAP_DIRAFTER_HEADERS}) From 5a0f2c00aa019de73a6077ca3017b594c43184a4 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Tue, 29 Jan 2019 16:26:45 +0100 Subject: [PATCH 157/475] Cygwin: fork/exec: fix child process permissions - Exec'ed/spawned processes don't need PROCESS_DUP_HANDLE. Remove that permission from the parent handle. - PROCESS_QUERY_LIMITED_INFORMATION doesn't work for Windows 7 if the process is started as a service. Add PROCESS_QUERY_INFORMATION for pre-Windows 8 in that case. Signed-off-by: Corinna Vinschen --- winsup/cygwin/security.h | 1 + winsup/cygwin/sigproc.cc | 20 ++++++++++++++++---- winsup/cygwin/uinfo.cc | 14 ++++++++++---- winsup/cygwin/wincap.cc | 9 +++++++++ winsup/cygwin/wincap.h | 2 ++ 5 files changed, 38 insertions(+), 8 deletions(-) diff --git a/winsup/cygwin/security.h b/winsup/cygwin/security.h index 70912b4fc..ec68171a3 100644 --- a/winsup/cygwin/security.h +++ b/winsup/cygwin/security.h @@ -17,6 +17,7 @@ details. */ /* UID/GID */ void uinfo_init (); +bool check_token_membership (HANDLE, PSID); bool check_token_membership (PSID); #define ILLEGAL_UID ((uid_t)-1) diff --git a/winsup/cygwin/sigproc.cc b/winsup/cygwin/sigproc.cc index 45e948251..42eeb304d 100644 --- a/winsup/cygwin/sigproc.cc +++ b/winsup/cygwin/sigproc.cc @@ -811,12 +811,24 @@ child_info::child_info (unsigned in_cb, child_info_types chtype, } sigproc_printf ("subproc_ready %p", subproc_ready); /* Create an inheritable handle to pass to the child process. This will - allow the child to duplicate handles from the parent to itself. */ + allow the child to copy cygheap etc. from the parent to itself. If + we're forking, we also need handle duplicate access. */ parent = NULL; + DWORD perms = PROCESS_QUERY_LIMITED_INFORMATION | PROCESS_VM_READ; + if (type == _CH_FORK) + { + perms |= PROCESS_DUP_HANDLE; + /* For some reason fork on Windows 7 requires PROCESS_QUERY_INFORMATION + rather than just PROCESS_QUERY_LIMITED_INFORMATION when started as a + service. */ + if (wincap.needs_query_information () + && (cygheap->user.saved_sid () == well_known_system_sid + || check_token_membership (hProcToken, well_known_service_sid))) + perms |= PROCESS_QUERY_INFORMATION; + } + if (!DuplicateHandle (GetCurrentProcess (), GetCurrentProcess (), - GetCurrentProcess (), &parent, - PROCESS_DUP_HANDLE | PROCESS_VM_READ - | PROCESS_QUERY_LIMITED_INFORMATION, TRUE, 0)) + GetCurrentProcess (), &parent, perms, TRUE, 0)) system_printf ("couldn't create handle to myself for child, %E"); } diff --git a/winsup/cygwin/uinfo.cc b/winsup/cygwin/uinfo.cc index 8dcf731de..00a2b5abb 100644 --- a/winsup/cygwin/uinfo.cc +++ b/winsup/cygwin/uinfo.cc @@ -118,16 +118,13 @@ cygheap_user::init () This needs careful checking should we use check_token_membership in other circumstances. */ bool -check_token_membership (PSID sid) +check_token_membership (HANDLE tok, PSID sid) { NTSTATUS status; ULONG size; tmp_pathbuf tp; PTOKEN_GROUPS groups = (PTOKEN_GROUPS) tp.w_get (); - /* If impersonated, use impersonation token. */ - HANDLE tok = cygheap->user.issetuid () ? cygheap->user.primary_token () - : hProcToken; status = NtQueryInformationToken (tok, TokenGroups, groups, 2 * NT_MAX_PATH, &size); if (!NT_SUCCESS (status)) @@ -142,6 +139,15 @@ check_token_membership (PSID sid) return false; } +bool +check_token_membership (PSID sid) +{ + /* If impersonated, use impersonation token. */ + HANDLE tok = cygheap->user.issetuid () ? cygheap->user.primary_token () + : hProcToken; + return check_token_membership (tok, sid); +} + static void internal_getlogin (cygheap_user &user) { diff --git a/winsup/cygwin/wincap.cc b/winsup/cygwin/wincap.cc index 4c1c7b401..132265c6a 100644 --- a/winsup/cygwin/wincap.cc +++ b/winsup/cygwin/wincap.cc @@ -23,6 +23,7 @@ wincaps wincap_vista __attribute__((section (".cygwin_dll_common"), shared)) = { { is_server:false, needs_count_in_si_lpres2:true, + needs_query_information:true, has_gaa_largeaddress_bug:true, has_broken_alloc_console:false, has_console_logon_sid:false, @@ -46,6 +47,7 @@ wincaps wincap_7 __attribute__((section (".cygwin_dll_common"), shared)) = { { is_server:false, needs_count_in_si_lpres2:false, + needs_query_information:true, has_gaa_largeaddress_bug:true, has_broken_alloc_console:true, has_console_logon_sid:true, @@ -69,6 +71,7 @@ wincaps wincap_8 __attribute__((section (".cygwin_dll_common"), shared)) = { { is_server:false, needs_count_in_si_lpres2:false, + needs_query_information:false, has_gaa_largeaddress_bug:false, has_broken_alloc_console:true, has_console_logon_sid:true, @@ -92,6 +95,7 @@ wincaps wincap_10_1507 __attribute__((section (".cygwin_dll_common"), shared)) { is_server:false, needs_count_in_si_lpres2:false, + needs_query_information:false, has_gaa_largeaddress_bug:false, has_broken_alloc_console:true, has_console_logon_sid:true, @@ -115,6 +119,7 @@ wincaps wincap_10_1511 __attribute__((section (".cygwin_dll_common"), shared)) = { is_server:false, needs_count_in_si_lpres2:false, + needs_query_information:false, has_gaa_largeaddress_bug:false, has_broken_alloc_console:true, has_console_logon_sid:true, @@ -138,6 +143,7 @@ wincaps wincap_10_1703 __attribute__((section (".cygwin_dll_common"), shared)) = { is_server:false, needs_count_in_si_lpres2:false, + needs_query_information:false, has_gaa_largeaddress_bug:false, has_broken_alloc_console:true, has_console_logon_sid:true, @@ -161,6 +167,7 @@ wincaps wincap_10_1709 __attribute__((section (".cygwin_dll_common"), shared)) = { is_server:false, needs_count_in_si_lpres2:false, + needs_query_information:false, has_gaa_largeaddress_bug:false, has_broken_alloc_console:true, has_console_logon_sid:true, @@ -184,6 +191,7 @@ wincaps wincap_10_1803 __attribute__((section (".cygwin_dll_common"), shared)) = { is_server:false, needs_count_in_si_lpres2:false, + needs_query_information:false, has_gaa_largeaddress_bug:false, has_broken_alloc_console:true, has_console_logon_sid:true, @@ -207,6 +215,7 @@ wincaps wincap_10_1809 __attribute__((section (".cygwin_dll_common"), shared)) = { is_server:false, needs_count_in_si_lpres2:false, + needs_query_information:false, has_gaa_largeaddress_bug:false, has_broken_alloc_console:true, has_console_logon_sid:true, diff --git a/winsup/cygwin/wincap.h b/winsup/cygwin/wincap.h index f8846f91d..75b7a9f0a 100644 --- a/winsup/cygwin/wincap.h +++ b/winsup/cygwin/wincap.h @@ -17,6 +17,7 @@ struct wincaps struct __attribute__ ((aligned (8))) { unsigned is_server : 1; unsigned needs_count_in_si_lpres2 : 1; + unsigned needs_query_information : 1; unsigned has_gaa_largeaddress_bug : 1; unsigned has_broken_alloc_console : 1; unsigned has_console_logon_sid : 1; @@ -70,6 +71,7 @@ public: } bool IMPLEMENT (is_server) bool IMPLEMENT (needs_count_in_si_lpres2) + bool IMPLEMENT (needs_query_information) bool IMPLEMENT (has_gaa_largeaddress_bug) bool IMPLEMENT (has_broken_alloc_console) bool IMPLEMENT (has_console_logon_sid) From 4d738e0f62403c3f1b082abf927aab00056230c5 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Tue, 29 Jan 2019 20:37:00 +0100 Subject: [PATCH 158/475] Cygwin: execve: reduce parent handle to non-inheritable SYNCHRONIZE Keeping an inheritable handle open results in that handle being spilled over into grandchild processes, which is not desired. Duplicate original parent handle into a non-inheritable one with minimal SYNCHRONIZE permissions and close the original handle. Signed-off-by: Corinna Vinschen --- winsup/cygwin/dcrt0.cc | 30 +++++++++++++++++++++++------- winsup/cygwin/sigproc.cc | 3 ++- 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/winsup/cygwin/dcrt0.cc b/winsup/cygwin/dcrt0.cc index 6b564dced..463df3128 100644 --- a/winsup/cygwin/dcrt0.cc +++ b/winsup/cygwin/dcrt0.cc @@ -685,14 +685,30 @@ child_info_spawn::handle_spawn () ready (true); - /* Keep pointer to parent open if we've execed so that pid will not be reused. - Otherwise, we no longer need this handle so close it. - Need to do this after debug_fixup_after_fork_exec or DEBUGGING handling of - handles might get confused. */ - if (type != _CH_EXEC && child_proc_info->parent) + if (child_proc_info->parent) { - CloseHandle (child_proc_info->parent); - child_proc_info->parent = NULL; + if (type == _CH_EXEC) + { + /* Keep pointer to parent open if we've execed so that pid will not be + reused. Try to Urther reduce permissions. */ + HANDLE new_parent; + + if (DuplicateHandle (GetCurrentProcess (), child_proc_info->parent, + GetCurrentProcess (), &new_parent, + SYNCHRONIZE, FALSE, 0)) + { + CloseHandle (child_proc_info->parent); + child_proc_info->parent = new_parent; + } + } + else + { + /* Otherwise, we no longer need this handle so close it. Need to do + this after debug_fixup_after_fork_exec or DEBUGGING handling of + handles might get confused. */ + CloseHandle (child_proc_info->parent); + child_proc_info->parent = NULL; + } } signal_fixup_after_exec (); diff --git a/winsup/cygwin/sigproc.cc b/winsup/cygwin/sigproc.cc index 42eeb304d..080fe58df 100644 --- a/winsup/cygwin/sigproc.cc +++ b/winsup/cygwin/sigproc.cc @@ -814,7 +814,8 @@ child_info::child_info (unsigned in_cb, child_info_types chtype, allow the child to copy cygheap etc. from the parent to itself. If we're forking, we also need handle duplicate access. */ parent = NULL; - DWORD perms = PROCESS_QUERY_LIMITED_INFORMATION | PROCESS_VM_READ; + DWORD perms = PROCESS_QUERY_LIMITED_INFORMATION | PROCESS_VM_READ + | SYNCHRONIZE; if (type == _CH_FORK) { perms |= PROCESS_DUP_HANDLE; From a52396bd079a22be539df4d63d42425413e0a51c Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Wed, 30 Jan 2019 11:36:45 +0100 Subject: [PATCH 159/475] Cygwin: raise: change to call pthread_kill POSIX requires that raise(3) is equivalent to pthread_kill(pthread_self(), sig); in multi-threaded applications. Our raise just called kill(sig). Fix that. Signed-off-by: Corinna Vinschen --- winsup/cygwin/release/3.0 | 3 +++ winsup/cygwin/signal.cc | 5 ++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/winsup/cygwin/release/3.0 b/winsup/cygwin/release/3.0 index 79affdb27..49edb3870 100644 --- a/winsup/cygwin/release/3.0 +++ b/winsup/cygwin/release/3.0 @@ -89,3 +89,6 @@ Bug Fixes - Disallow seteuid on disabled or locked out accounts. Addresses: https://cygwin.com/ml/cygwin/2019-01/msg00197.html + +- Fix raise to work as required by POSIX. + (Partially) addresses: https://cygwin.com/ml/cygwin/2019-01/msg00149.html diff --git a/winsup/cygwin/signal.cc b/winsup/cygwin/signal.cc index abefedd7b..9c51ec129 100644 --- a/winsup/cygwin/signal.cc +++ b/winsup/cygwin/signal.cc @@ -300,7 +300,10 @@ _pinfo::kill (siginfo_t& si) extern "C" int raise (int sig) { - return kill (myself->pid, sig); + pthread *thread = _my_tls.tid; + if (!thread) + return kill (myself->pid, sig); + return pthread_kill (thread, sig); } static int From ef8ce3077f55d5a105b39f605b877da50ab80aa7 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Wed, 30 Jan 2019 12:18:03 +0100 Subject: [PATCH 160/475] Cygwin: fork: fix child process permissions, take 2 VirtualQueryEx, called by fixup_mmaps_after_fork, requires PROCESS_QUERY_INFORMATION permissions per MSDN. However, testing shows that PROCESS_QUERY_LIMITED_INFORMATION is sufficient when running the same code on Windows 8.1 or Windows 10. Fix the code to give the forked child always PROCESS_QUERY_INFORMATION perms on Windows Vista/7 and respective server releases. Revert now unneeded patch to check_token_membership as well. Signed-off-by: Corinna Vinschen --- winsup/cygwin/security.h | 1 - winsup/cygwin/sigproc.cc | 10 ++++------ winsup/cygwin/uinfo.cc | 14 ++++---------- 3 files changed, 8 insertions(+), 17 deletions(-) diff --git a/winsup/cygwin/security.h b/winsup/cygwin/security.h index ec68171a3..70912b4fc 100644 --- a/winsup/cygwin/security.h +++ b/winsup/cygwin/security.h @@ -17,7 +17,6 @@ details. */ /* UID/GID */ void uinfo_init (); -bool check_token_membership (HANDLE, PSID); bool check_token_membership (PSID); #define ILLEGAL_UID ((uid_t)-1) diff --git a/winsup/cygwin/sigproc.cc b/winsup/cygwin/sigproc.cc index 080fe58df..a830bff79 100644 --- a/winsup/cygwin/sigproc.cc +++ b/winsup/cygwin/sigproc.cc @@ -819,12 +819,10 @@ child_info::child_info (unsigned in_cb, child_info_types chtype, if (type == _CH_FORK) { perms |= PROCESS_DUP_HANDLE; - /* For some reason fork on Windows 7 requires PROCESS_QUERY_INFORMATION - rather than just PROCESS_QUERY_LIMITED_INFORMATION when started as a - service. */ - if (wincap.needs_query_information () - && (cygheap->user.saved_sid () == well_known_system_sid - || check_token_membership (hProcToken, well_known_service_sid))) + /* VirtualQueryEx is documented to require PROCESS_QUERY_INFORMATION. + That's true for Windows 7, but PROCESS_QUERY_LIMITED_INFORMATION + appears to be sufficient on Windows 8 and later. */ + if (wincap.needs_query_information ()) perms |= PROCESS_QUERY_INFORMATION; } diff --git a/winsup/cygwin/uinfo.cc b/winsup/cygwin/uinfo.cc index 00a2b5abb..8dcf731de 100644 --- a/winsup/cygwin/uinfo.cc +++ b/winsup/cygwin/uinfo.cc @@ -118,13 +118,16 @@ cygheap_user::init () This needs careful checking should we use check_token_membership in other circumstances. */ bool -check_token_membership (HANDLE tok, PSID sid) +check_token_membership (PSID sid) { NTSTATUS status; ULONG size; tmp_pathbuf tp; PTOKEN_GROUPS groups = (PTOKEN_GROUPS) tp.w_get (); + /* If impersonated, use impersonation token. */ + HANDLE tok = cygheap->user.issetuid () ? cygheap->user.primary_token () + : hProcToken; status = NtQueryInformationToken (tok, TokenGroups, groups, 2 * NT_MAX_PATH, &size); if (!NT_SUCCESS (status)) @@ -139,15 +142,6 @@ check_token_membership (HANDLE tok, PSID sid) return false; } -bool -check_token_membership (PSID sid) -{ - /* If impersonated, use impersonation token. */ - HANDLE tok = cygheap->user.issetuid () ? cygheap->user.primary_token () - : hProcToken; - return check_token_membership (tok, sid); -} - static void internal_getlogin (cygheap_user &user) { From ba3e20894d068d34186e485563cc1ab2819e8f5f Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Wed, 30 Jan 2019 16:16:25 +0100 Subject: [PATCH 161/475] Cygwin: document W10 1803 per-directory case-sensitivity behaviour Signed-off-by: Corinna Vinschen --- winsup/doc/specialnames.xml | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/winsup/doc/specialnames.xml b/winsup/doc/specialnames.xml index bc4b0440d..f27836032 100644 --- a/winsup/doc/specialnames.xml +++ b/winsup/doc/specialnames.xml @@ -215,6 +215,39 @@ Read on for more information. + +Case sensitive directories + +Windows 10 1803 introduced a new feature: NTFS directories can be marked +as case-sensitive, independently of the obcaseinsensitive +registry key discussed in the previous section. This new per-directory +case-sensitivity requires setting a flag in the NTFS filesystem header which +is, unfortunately, undocumented. The result is that you have to activate +Windows Subsystem for Linux (WSL), a +feature available via Programs and Features -> +Turn Windows features on or off. You only have to activate +WSL, you don't have to install any actual Linux. After +turning WSL on and performing the compulsory reboot, +case-sensitive directories are activated. + +With WSL activated and starting with Cygwin 3.0, +Cygwin's mkdir system call will automatically create all +directories below the Cygwin installation directory as case-sensitive. +Directories created outside the Cygwin installation tree will be left +alone. However, you can use Cygwin's new tool +with the -C option to control case-sensitivity of +directories on NTFS filesystems. + +Please keep in mind that switching off +case-sensitivity on a directory has a condition attached to it: If +the directory contains two files which only differ in case (e. g., +foo and FOO), Windows +refuses to convert the dir back to case-insensitive. First you have +to fix the filename collision, i. e., you have to rename one of these +files. + + + POSIX devices While there is no need to create a POSIX /dev directory, the directory is automatically created as part of a Cygwin From 9a5abcc896bde48ae72fd62fe43a2307663d8ad5 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Wed, 30 Jan 2019 20:05:39 +0100 Subject: [PATCH 162/475] Cygwin: x86_64: pthreads: Install exception handler after switching stack After creating a pthread, the stack gets moved to the desired memory location. While the 32 bit thread wrapper copies the exception handler information to the new stack (so we have at least *some* exception handler present), the x86_64 code didn't perform any exception handler magic. Fix that. Signed-off-by: Corinna Vinschen --- winsup/cygwin/thread.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/winsup/cygwin/thread.cc b/winsup/cygwin/thread.cc index c7b7e5157..f353dd497 100644 --- a/winsup/cygwin/thread.cc +++ b/winsup/cygwin/thread.cc @@ -30,6 +30,7 @@ details. */ #include "cygheap.h" #include "ntdll.h" #include "cygwait.h" +#include "exception.h" extern "C" void __fp_lock_all (); extern "C" void __fp_unlock_all (); @@ -1990,6 +1991,7 @@ pthread_spinlock::unlock () DWORD WINAPI pthread::thread_init_wrapper (void *arg) { + exception protect; pthread *thread = (pthread *) arg; /* This *must* be set prior to calling set_tls_self_pointer or there is a race with the signal processing code which may miss the signal mask From 24629e97011a2c7863380cddfb00936c70db26c0 Mon Sep 17 00:00:00 2001 From: pfg Date: Mon, 20 Nov 2017 19:49:47 +0000 Subject: [PATCH 163/475] General further adoption of SPDX licensing ID tags. Mainly focus on files that use BSD 3-Clause license. The Software Package Data Exchange (SPDX) group provides a specification to make it easier for automated tools to detect and summarize well known opensource licenses. We are gradually adopting the specification, noting that the tags are considered only advisory and do not, in any way, superceed or replace the license texts. Special thanks to Wind River for providing access to "The Duke of Highlander" tool: an older (2014) run over FreeBSD tree was useful as a starting point. --- newlib/libc/posix/scandir.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/newlib/libc/posix/scandir.c b/newlib/libc/posix/scandir.c index d95cff378..57b96827e 100644 --- a/newlib/libc/posix/scandir.c +++ b/newlib/libc/posix/scandir.c @@ -1,6 +1,8 @@ #ifndef HAVE_OPENDIR /* + * SPDX-License-Identifier: BSD-3-Clause + * * Copyright (c) 1983 Regents of the University of California. * All rights reserved. * From 62fb0614c6ceb06152ca347420baf9fba8821cd5 Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Thu, 31 Jan 2019 11:42:29 +0100 Subject: [PATCH 164/475] scandir: Update copyright notice from FreeBSD Signed-off-by: Sebastian Huber --- newlib/libc/posix/scandir.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/newlib/libc/posix/scandir.c b/newlib/libc/posix/scandir.c index 57b96827e..20c1d6d4d 100644 --- a/newlib/libc/posix/scandir.c +++ b/newlib/libc/posix/scandir.c @@ -1,10 +1,10 @@ #ifndef HAVE_OPENDIR -/* +/*- * SPDX-License-Identifier: BSD-3-Clause * - * Copyright (c) 1983 Regents of the University of California. - * All rights reserved. + * Copyright (c) 1983, 1993 + * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions From b46ef7699f2ba34da07edef28efa3e1f5f86e068 Mon Sep 17 00:00:00 2001 From: imp Date: Tue, 28 Feb 2017 23:42:47 +0000 Subject: [PATCH 165/475] Renumber copyright clause 4 Renumber cluase 4 to 3, per what everybody else did when BSD granted them permission to remove clause 3. My insistance on keeping the same numbering for legal reasons is too pedantic, so give up on that point. Submitted by: Jan Schaumann Pull Request: https://github.com/freebsd/freebsd/pull/96 --- newlib/libc/posix/scandir.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/newlib/libc/posix/scandir.c b/newlib/libc/posix/scandir.c index 20c1d6d4d..2f00d3d92 100644 --- a/newlib/libc/posix/scandir.c +++ b/newlib/libc/posix/scandir.c @@ -14,7 +14,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * From 0e7db0c356c0c47e34bd2cac1d3b83386540a7f7 Mon Sep 17 00:00:00 2001 From: jhb Date: Tue, 3 Jul 2018 17:31:45 +0000 Subject: [PATCH 166/475] Clean up the vcs ID strings in libc's gen/ directory. - Move CSRG IDs into __SCCSID(). - When a file has been copied, consistently use 'From: ' for strings referencing the version of the source file copied from in the license block comment. - Some of the 'From:' tags were using $FreeBSD$ that was being expanded on each checkout. Fix those to hardcode the FreeBSD tag from the file that was copied at the time of the copy. - When multiple strings are present list them in "chronological" order, so CSRG (__SCCSID) before FreeBSD (__FBSDID). If a file came from OtherBSD and contains a CSRG ID from the OtherBSD file, use the order CSRG -> OtherBSD -> FreeBSD. Reviewed by: imp Differential Revision: https://reviews.freebsd.org/D15831 --- newlib/libc/posix/scandir.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/newlib/libc/posix/scandir.c b/newlib/libc/posix/scandir.c index 2f00d3d92..97a16cf7b 100644 --- a/newlib/libc/posix/scandir.c +++ b/newlib/libc/posix/scandir.c @@ -31,9 +31,8 @@ * SUCH DAMAGE. */ -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)scandir.c 5.10 (Berkeley) 2/23/91"; -#endif /* LIBC_SCCS and not lint */ +#include +__SCCSID("@(#)scandir.c 8.3 (Berkeley) 1/2/94"); /* * Scan the directory dirname calling select to make a list of selected From d785551a46a786ed08db6b5efd2e1032d513f234 Mon Sep 17 00:00:00 2001 From: obrien Date: Fri, 1 Feb 2002 01:32:19 +0000 Subject: [PATCH 167/475] Remove __P and convert to ANSI prototypes. * Fix SCM ID's. --- newlib/libc/posix/scandir.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/newlib/libc/posix/scandir.c b/newlib/libc/posix/scandir.c index 97a16cf7b..95be97708 100644 --- a/newlib/libc/posix/scandir.c +++ b/newlib/libc/posix/scandir.c @@ -33,6 +33,7 @@ #include __SCCSID("@(#)scandir.c 8.3 (Berkeley) 1/2/94"); +__FBSDID("$FreeBSD$"); /* * Scan the directory dirname calling select to make a list of selected @@ -64,15 +65,11 @@ __SCCSID("@(#)scandir.c 8.3 (Berkeley) 1/2/94"); (offsetof (struct dirent, d_name) + ((strlen((dp)->d_name)+1 + 3) &~ 3)) #endif -#ifndef __P -#define __P(args) () -#endif int -scandir (const char *dirname, - struct dirent ***namelist, - int (*select) __P((const struct dirent *)), - int (*dcomp) __P((const struct dirent **, const struct dirent **))) +scandir(const char *dirname, struct dirent ***namelist, + int (*select)(const struct dirent *), int (*dcomp)(const struct dirent **, + const struct dirent **)) { register struct dirent *d, *p, **names; register size_t nitems; From 2d3c2f4697481dc6df76528c9addabd4c80d3652 Mon Sep 17 00:00:00 2001 From: das Date: Sun, 16 Mar 2008 19:08:53 +0000 Subject: [PATCH 168/475] scandir(3) previously used st_size to obtain an initial estimate of the array length needed to store all the directory entries. Although BSD has historically guaranteed that st_size is the size of the directory file, POSIX does not, and more to the point, some recent filesystems such as ZFS use st_size to mean something else. The fix is to not stat the directory at all, set the initial array size to 32 entries, and realloc it in powers of 2 if that proves insufficient. PR: 113668 --- newlib/libc/posix/scandir.c | 90 ++++++++++++++----------------------- 1 file changed, 34 insertions(+), 56 deletions(-) diff --git a/newlib/libc/posix/scandir.c b/newlib/libc/posix/scandir.c index 95be97708..56de1b9e1 100644 --- a/newlib/libc/posix/scandir.c +++ b/newlib/libc/posix/scandir.c @@ -42,8 +42,6 @@ __FBSDID("$FreeBSD$"); * struct dirent (through namelist). Returns -1 if there were any errors. */ -#include -#include #include #include #include @@ -71,41 +69,22 @@ scandir(const char *dirname, struct dirent ***namelist, int (*select)(const struct dirent *), int (*dcomp)(const struct dirent **, const struct dirent **)) { - register struct dirent *d, *p, **names; - register size_t nitems; - struct stat stb; - long arraysz; + register struct dirent *d, *p, **names = NULL; + register size_t arraysz, numitems; DIR *dirp; - int successful = 0; - int rc = 0; - - dirp = NULL; - names = NULL; if ((dirp = opendir(dirname)) == NULL) return(-1); #ifdef HAVE_DD_LOCK __lock_acquire_recursive(dirp->dd_lock); #endif - if (fstat(dirp->dd_fd, &stb) < 0) - goto cleanup; - /* - * If there were no directory entries, then bail. - */ - if (stb.st_size == 0) - goto cleanup; - - /* - * estimate the array size by taking the size of the directory file - * and dividing it by a multiple of the minimum size entry. - */ - arraysz = (stb.st_size / 24); + numitems = 0; + arraysz = 32; /* initial estimate of the array size */ names = (struct dirent **)malloc(arraysz * sizeof(struct dirent *)); if (names == NULL) - goto cleanup; + goto fail; - nitems = 0; while ((d = readdir(dirp)) != NULL) { if (select != NULL && !(*select)(d)) continue; /* just selected names */ @@ -114,7 +93,7 @@ scandir(const char *dirname, struct dirent ***namelist, */ p = (struct dirent *)malloc(DIRSIZ(d)); if (p == NULL) - goto cleanup; + goto fail; p->d_ino = d->d_ino; p->d_reclen = d->d_reclen; #ifdef _DIRENT_HAVE_D_NAMLEN @@ -127,39 +106,38 @@ scandir(const char *dirname, struct dirent ***namelist, * Check to make sure the array has space left and * realloc the maximum size. */ - if (++nitems >= arraysz) { - if (fstat(dirp->dd_fd, &stb) < 0) - goto cleanup; - arraysz = stb.st_size / 12; - names = (struct dirent **)reallocf((char *)names, - arraysz * sizeof(struct dirent *)); - if (names == NULL) - goto cleanup; - } - names[nitems-1] = p; - } - successful = 1; -cleanup: - closedir(dirp); - if (successful) { - if (nitems && dcomp != NULL) - qsort(names, nitems, sizeof(struct dirent *), (void *)dcomp); - *namelist = names; - rc = nitems; - } else { /* We were unsuccessful, clean up storage and return -1. */ - if ( names ) { - int i; - for (i=0; i < nitems; i++ ) - free( names[i] ); - free( names ); - } - rc = -1; - } + if (numitems >= arraysz) { + struct dirent **names2; + names2 = reallocarray(names, arraysz, + 2 * sizeof(struct dirent *)); + if (names2 == NULL) { + free(p); + goto fail; + } + names = names2; + arraysz *= 2; + } + names[numitems++] = p; + } + closedir(dirp); + if (numitems && dcomp != NULL) + qsort(names, numitems, sizeof(struct dirent *), (void *)dcomp); + *namelist = names; #ifdef HAVE_DD_LOCK __lock_release_recursive(dirp->dd_lock); #endif - return(rc); + return (numitems); + +fail: + while (numitems > 0) + free(names[--numitems]); + free(names); + closedir(dirp); +#ifdef HAVE_DD_LOCK + __lock_release_recursive(dirp->dd_lock); +#endif + return (-1); } /* From 67613cbbd87b5b3c5b10209e6272fc8ec6405b26 Mon Sep 17 00:00:00 2001 From: ache Date: Mon, 18 Jan 2010 10:17:51 +0000 Subject: [PATCH 169/475] a) Use strcoll() in opendir() and alphasort() as POSIX 2008 requires. It also matches now how our 'ls' works for years. b) Remove comment expressed 2 fears: 1) One just simple describe how strcoll() works in _any_ context, not for directories only. Are we plan to remove strcoll() from everything just because it is little more complex than strcmp()? I doubt, and directories give nothing different here. Moreover, strcoll() used in 'ls' for years and nobody complaints yet. 2) Plain wrong statement about undefined strcoll() behaviour. strcoll() always gives predictable results, falling back to strcmp() on any trouble, see strcoll(3). No objections from -current list discussion. --- newlib/libc/posix/scandir.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/newlib/libc/posix/scandir.c b/newlib/libc/posix/scandir.c index 56de1b9e1..c39d9a4c4 100644 --- a/newlib/libc/posix/scandir.c +++ b/newlib/libc/posix/scandir.c @@ -142,12 +142,13 @@ fail: /* * Alphabetic order comparison routine for those who want it. + * POSIX 2008 requires that alphasort() uses strcoll(). */ int -alphasort (const struct dirent **d1, - const struct dirent **d2) +alphasort(const struct dirent **d1, const struct dirent **d2) { - return(strcmp((*d1)->d_name, (*d2)->d_name)); + + return (strcoll((*d1)->d_name, (*d2)->d_name)); } #endif /* ! HAVE_OPENDIR */ From 3e24fbf6f0e4915efbbd98702e4801bcf9ebf89a Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Thu, 31 Jan 2019 11:48:12 +0100 Subject: [PATCH 170/475] scandir: Add support for struct dirent::d_type Signed-off-by: Sebastian Huber --- newlib/libc/posix/scandir.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/newlib/libc/posix/scandir.c b/newlib/libc/posix/scandir.c index c39d9a4c4..7fd008910 100644 --- a/newlib/libc/posix/scandir.c +++ b/newlib/libc/posix/scandir.c @@ -33,7 +33,7 @@ #include __SCCSID("@(#)scandir.c 8.3 (Berkeley) 1/2/94"); -__FBSDID("$FreeBSD$"); +__FBSDID("$FreeBSD: head/lib/libc/gen/scandir.c 335898 2018-07-03 17:31:45Z jhb $"); /* * Scan the directory dirname calling select to make a list of selected @@ -95,6 +95,9 @@ scandir(const char *dirname, struct dirent ***namelist, if (p == NULL) goto fail; p->d_ino = d->d_ino; +#ifdef DT_UNKNOWN + p->d_type = d->d_type; +#endif p->d_reclen = d->d_reclen; #ifdef _DIRENT_HAVE_D_NAMLEN p->d_namlen = d->d_namlen; From 351b57527d700b19c87ef3c341f67808351c4b83 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Wed, 30 Jan 2019 22:21:46 +0100 Subject: [PATCH 171/475] Cygwin: Add pthread exception handling patch to release notes Signed-off-by: Corinna Vinschen --- winsup/cygwin/release/3.0 | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/winsup/cygwin/release/3.0 b/winsup/cygwin/release/3.0 index 49edb3870..f4433c320 100644 --- a/winsup/cygwin/release/3.0 +++ b/winsup/cygwin/release/3.0 @@ -91,4 +91,7 @@ Bug Fixes Addresses: https://cygwin.com/ml/cygwin/2019-01/msg00197.html - Fix raise to work as required by POSIX. - (Partially) addresses: https://cygwin.com/ml/cygwin/2019-01/msg00149.html + Addresses: https://cygwin.com/ml/cygwin/2019-01/msg00149.html + +- Fix exception handling in pthreads. + Addresses: https://cygwin.com/ml/cygwin/2019-01/msg00149.html From 210bd56aa26d8d6f88e6c4566981cdb7835b80b9 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Fri, 1 Feb 2019 13:18:15 +0100 Subject: [PATCH 172/475] Cygwin: /proc: don't exit prematurely from /proc/PID/status If a process is just exiting, requesting memory info may fail with STATUS_PROCESS_IS_TERMINATING. Right now the code just bails out if fetching mem info fails. However, the rest of the info is still valuable for procps, so just carry on. Signed-off-by: Corinna Vinschen --- winsup/cygwin/fhandler_process.cc | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/winsup/cygwin/fhandler_process.cc b/winsup/cygwin/fhandler_process.cc index 24ef7d00c..29b8c5934 100644 --- a/winsup/cygwin/fhandler_process.cc +++ b/winsup/cygwin/fhandler_process.cc @@ -1212,9 +1212,8 @@ format_process_status (void *data, char *&destbuf) state_str = "stopped"; break; } - if (!get_mem_values (p->dwProcessId, vmsize, vmrss, vmtext, vmdata, - vmlib, vmshare)) - return 0; + get_mem_values (p->dwProcessId, vmsize, vmrss, vmtext, vmdata, + vmlib, vmshare); /* The real uid value for *this* process is stored at cygheap->user.real_uid but we can't get at the real uid value for any other process, so just fake it as p->uid. Similar for p->gid. */ From c0b9f600f9ce6753545f4df7967cffe1bb867488 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Fri, 1 Feb 2019 13:36:27 +0100 Subject: [PATCH 173/475] Cygwin: remove outdated vfork doc Signed-off-by: Corinna Vinschen --- winsup/cygwin/how-vfork-works.txt | 36 ------------------------------- 1 file changed, 36 deletions(-) delete mode 100644 winsup/cygwin/how-vfork-works.txt diff --git a/winsup/cygwin/how-vfork-works.txt b/winsup/cygwin/how-vfork-works.txt deleted file mode 100644 index 59fe5f52e..000000000 --- a/winsup/cygwin/how-vfork-works.txt +++ /dev/null @@ -1,36 +0,0 @@ -(THIS DESCRIPTION IS OUT-OF-DATE) - -How does vfork work? - -When a program calls vfork, cygwin attempts to short circuit its -normal, expensive fork mechanism. - -Vfork is mainly smoke and mirrors. A call to vfork contines to execute -in the current process but first it returns a pid of 0 so that process -will execute code intended for the child in a UNIX system. Before -returning the zero, vfork makes a copy of the current fd table so that -closing an fd in the "child" will not affect the "parent". - -Some of this info is stored in a per-thread structure but vfork is not -really thread-safe since it also stores the fd "backup" table in the -global fd table. - -The process continues to execute until it hits some type of exec call. -The exec call is essentially translated into a spawn NO_WAIT call and -the new process is started via this mechanism. After execing, the -"child" process no longer should exist, so the spawn code longjmps back -to the original vfork call. The previously opened fds are closed and -the parent's fd table is restored. vfork() then returns the pid of the -just-spawned process. - -Meanwhile, the just-spawned child notices that it has been spawned as -the result of a vfork and closes the extra file handles. - -This all relies on the fact that the child in a vfork call can affect -just about everything in the parent except for the parent's fds. -The assumption is that a vfork is always just used as a method for -starting a program. - -The assumption is also that all of this is much faster than the -slow method that cygwin uses to implement fork(). - From b5e1003722cb14235c4f166be72c09acdffc62ea Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Thu, 31 Jan 2019 21:19:03 +0100 Subject: [PATCH 174/475] Cygwin: processes: use dedicated Cygwin PID rather than Windows PID Using the Windows PID as Cygwin PID has a few drawbacks: - the PIDs on Windows get reused quickly. Some POSIX applications choke on that, so we need extra code to avoid too quick PID reuse. - The code to avoid PID reuse keeps parent process handles and (depending on a build option) child processes open unnecessarily. - After an execve, the process has a split personality: Its Windows PID is a new PID, while its Cygwin PID is the PID of the execve caller process. This requires to keep two procinfo shared sections open, the second just to redirect process info requests to the first, correct one. This patch changes the way Cygwin PIDs are generated: - Cygwin PIDs are generated independently of the Windows PID, in a way expected by POSIX processes. The PIDs are created incrementally in the range between 2 and 65535, round-robin. - On startup of the first Cygwin process, choose a semi-random start PID for the first process in the lower PID range to make the PIDs slightly unpredictable. This may not be necessary but it seems kind of inviting to know that the first Cygwin process always starts with PID 2. - Every process not only creates the shared procinfo section, but also a symlink in the NT namespace, symlinking the Windows PID to the Cygwin PID. This drops the need for the extra procinfo section after execve. - Don't keep other process handles around unnecessarily. - Simplify the code creating/opening the shared procinfo section and make a clear distinction between interfaces getting a Cygwin PID and interfaces getting a Windows PID. Signed-off-by: Corinna Vinschen --- winsup/cygwin/dcrt0.cc | 27 +--- winsup/cygwin/fork.cc | 33 ---- winsup/cygwin/include/cygwin/version.h | 3 +- winsup/cygwin/include/sys/cygwin.h | 3 +- winsup/cygwin/pinfo.cc | 212 +++++++++++++++---------- winsup/cygwin/pinfo.h | 22 ++- winsup/cygwin/release/3.0 | 3 + winsup/cygwin/shared.cc | 5 + winsup/cygwin/shared_info.h | 3 +- winsup/cygwin/spawn.cc | 2 +- winsup/doc/new-features.xml | 5 + 11 files changed, 162 insertions(+), 156 deletions(-) diff --git a/winsup/cygwin/dcrt0.cc b/winsup/cygwin/dcrt0.cc index 463df3128..5cdf01c6f 100644 --- a/winsup/cygwin/dcrt0.cc +++ b/winsup/cygwin/dcrt0.cc @@ -687,28 +687,11 @@ child_info_spawn::handle_spawn () if (child_proc_info->parent) { - if (type == _CH_EXEC) - { - /* Keep pointer to parent open if we've execed so that pid will not be - reused. Try to Urther reduce permissions. */ - HANDLE new_parent; - - if (DuplicateHandle (GetCurrentProcess (), child_proc_info->parent, - GetCurrentProcess (), &new_parent, - SYNCHRONIZE, FALSE, 0)) - { - CloseHandle (child_proc_info->parent); - child_proc_info->parent = new_parent; - } - } - else - { - /* Otherwise, we no longer need this handle so close it. Need to do - this after debug_fixup_after_fork_exec or DEBUGGING handling of - handles might get confused. */ - CloseHandle (child_proc_info->parent); - child_proc_info->parent = NULL; - } + /* We no longer need this handle so close it. Need to do + this after debug_fixup_after_fork_exec or DEBUGGING handling of + handles might get confused. */ + CloseHandle (child_proc_info->parent); + child_proc_info->parent = NULL; } signal_fixup_after_exec (); diff --git a/winsup/cygwin/fork.cc b/winsup/cygwin/fork.cc index d8c4ac459..c083f7a02 100644 --- a/winsup/cygwin/fork.cc +++ b/winsup/cygwin/fork.cc @@ -209,35 +209,6 @@ frok::child (volatile char * volatile here) return 0; } -#define NO_SLOW_PID_REUSE -#ifndef NO_SLOW_PID_REUSE -static void -slow_pid_reuse (HANDLE h) -{ - static NO_COPY HANDLE last_fork_procs[NPIDS_HELD]; - static NO_COPY unsigned nfork_procs; - - if (nfork_procs >= (sizeof (last_fork_procs) / sizeof (last_fork_procs [0]))) - nfork_procs = 0; - /* Keep a list of handles to child processes sitting around to prevent - Windows from reusing the same pid n times in a row. Having the same pids - close in succesion confuses bash. Keeping a handle open will stop - windows from reusing the same pid. */ - if (last_fork_procs[nfork_procs]) - ForceCloseHandle1 (last_fork_procs[nfork_procs], fork_stupidity); - if (DuplicateHandle (GetCurrentProcess (), h, - GetCurrentProcess (), &last_fork_procs[nfork_procs], - 0, FALSE, DUPLICATE_SAME_ACCESS)) - ProtectHandle1 (last_fork_procs[nfork_procs], fork_stupidity); - else - { - last_fork_procs[nfork_procs] = NULL; - system_printf ("couldn't create last_fork_proc, %E"); - } - nfork_procs++; -} -#endif - int __stdcall frok::parent (volatile char * volatile stack_here) { @@ -437,10 +408,6 @@ frok::parent (volatile char * volatile stack_here) goto cleanup; } -#ifndef NO_SLOW_PID_REUSE - slow_pid_reuse (hchild); -#endif - /* CHILD IS STOPPED */ debug_printf ("child is alive (but stopped)"); diff --git a/winsup/cygwin/include/cygwin/version.h b/winsup/cygwin/include/cygwin/version.h index b5ba93f5a..8926d49ae 100644 --- a/winsup/cygwin/include/cygwin/version.h +++ b/winsup/cygwin/include/cygwin/version.h @@ -506,12 +506,13 @@ details. */ 333: Add timerfd_create, timerfd_gettime, timerfd_settime. 334: Remove matherr. 335: Change size of utsname, change uname output. + 336: New Cygwin PID algorithm (yeah, not really an API change) Note that we forgot to bump the api for ualarm, strtoll, strtoull, sigaltstack, sethostname. */ #define CYGWIN_VERSION_API_MAJOR 0 -#define CYGWIN_VERSION_API_MINOR 335 +#define CYGWIN_VERSION_API_MINOR 336 /* There is also a compatibity version number associated with the shared memory regions. It is incremented when incompatible changes are made to the shared diff --git a/winsup/cygwin/include/sys/cygwin.h b/winsup/cygwin/include/sys/cygwin.h index c5da87c65..480d8ea06 100644 --- a/winsup/cygwin/include/sys/cygwin.h +++ b/winsup/cygwin/include/sys/cygwin.h @@ -269,8 +269,7 @@ enum PID_INITIALIZING = 0x00800, /* Set until ready to receive signals. */ PID_NEW = 0x01000, /* Available. */ PID_ALLPIDS = 0x02000, /* used by pinfo scanner */ - PID_EXECED = 0x04000, /* redirect to original pid info block */ - PID_NOREDIR = 0x08000, /* don't redirect if execed */ + PID_PROCINFO = 0x08000, /* caller just asks for process info */ PID_EXITED = 0x40000000, /* Free entry. */ PID_REAPED = 0x80000000 /* Reaped */ }; diff --git a/winsup/cygwin/pinfo.cc b/winsup/cygwin/pinfo.cc index 90dfd2b7c..98168c76a 100644 --- a/winsup/cygwin/pinfo.cc +++ b/winsup/cygwin/pinfo.cc @@ -58,8 +58,7 @@ pinfo::thisproc (HANDLE h) DWORD flags = PID_IN_USE | PID_ACTIVE; if (!h) { - h = INVALID_HANDLE_VALUE; - cygheap->pid = cygwin_pid (myself_initial.pid); + cygheap->pid = create_cygwin_pid (); flags |= PID_NEW; } @@ -68,16 +67,10 @@ pinfo::thisproc (HANDLE h) procinfo->dwProcessId = myself_initial.pid; procinfo->sendsig = myself_initial.sendsig; wcscpy (procinfo->progname, myself_initial.progname); + create_winpid_symlink (procinfo->pid, procinfo->dwProcessId); + procinfo->exec_sendsig = NULL; + procinfo->exec_dwProcessId = 0; debug_printf ("myself dwProcessId %u", procinfo->dwProcessId); - if (h != INVALID_HANDLE_VALUE) - { - /* here if execed */ - static pinfo NO_COPY myself_identity; - myself_identity.init (cygwin_pid (procinfo->dwProcessId), PID_EXECED, NULL); - procinfo->exec_sendsig = NULL; - procinfo->exec_dwProcessId = 0; - myself_identity->ppid = procinfo->pid; - } } /* Initialize the process table entry for the current task. @@ -109,7 +102,8 @@ pinfo_init (char **envp, int envc) myself->process_state |= PID_ACTIVE; myself->process_state &= ~(PID_INITIALIZING | PID_EXITED | PID_REAPED); myself.preserve (); - debug_printf ("pid %d, pgid %d, process_state %y", myself->pid, myself->pgid, myself->process_state); + debug_printf ("pid %d, pgid %d, process_state %y", + myself->pid, myself->pgid, myself->process_state); } DWORD @@ -152,7 +146,7 @@ pinfo::status_exit (DWORD x) reason (but note, the environment *in* CMD is broken and shortened). This occurs at a point where there's no return to the exec'ing parent process, so we have to find some way to inform the user what happened. - + FIXME: For now, just return with SIGBUS set. Maybe it's better to add a lengthy small_printf instead. */ x = SIGBUS; @@ -229,6 +223,106 @@ pinfo::exit (DWORD n) } # undef self +/* Return next free Cygwin PID between 2 and 65535, round-robin. Each new + PID is checked that it doesn't collide with an existing PID. For that, + just check if the "cygpid.PID" section exists. */ +pid_t +create_cygwin_pid () +{ + pid_t pid = 0; + WCHAR sym_name[24]; + UNICODE_STRING sym_str; + OBJECT_ATTRIBUTES attr; + HANDLE sym_hdl; + NTSTATUS status; + + do + { + do + { + pid = ((uint32_t) InterlockedIncrement (&cygwin_shared->pid_src)) + % 65536; + } + while (pid < 2); + __small_swprintf (sym_name, L"cygpid.%u", pid); + RtlInitUnicodeString (&sym_str, sym_name); + InitializeObjectAttributes (&attr, &sym_str, OBJ_CASE_INSENSITIVE, + get_shared_parent_dir (), NULL); + /* We just want to know if the section (and thus the process) still + exists. Instead of actually opening the section, try to open + it as symlink. NtOpenSymbolicLinkObject will always returns an + error: + - STATUS_OBJECT_NAME_NOT_FOUND if the section doesn't exist, + so the slot is free and we can use this pid. + - STATUS_OBJECT_TYPE_MISMATCH if the section exists, so we have + to skip this pid and loop to try the next one. + As side-effect we never have to close the section handle and thus + we don't influence the lifetime of the section. */ + status = NtOpenSymbolicLinkObject (&sym_hdl, SYMBOLIC_LINK_QUERY, &attr); + } + while (status == STATUS_OBJECT_TYPE_MISMATCH); + return pid; +} + +/* Convert Windows WINPID into Cygwin PID. Utilize the "winpid.WINPID" + symlinks created for each process. The symlink contains the Cygwin + PID as target. Return 0 if no "winpid.WINPID" symlink exists for + this WINPID. */ +pid_t +cygwin_pid (DWORD dwProcessId) +{ + WCHAR sym_name[24]; + WCHAR pid_name[12]; + UNICODE_STRING sym_str; + UNICODE_STRING pid_str; + OBJECT_ATTRIBUTES attr; + HANDLE sym_hdl; + NTSTATUS status; + + __small_swprintf (sym_name, L"winpid.%u", dwProcessId); + RtlInitUnicodeString (&sym_str, sym_name); + InitializeObjectAttributes (&attr, &sym_str, OBJ_CASE_INSENSITIVE, + get_shared_parent_dir (), NULL); + status = NtOpenSymbolicLinkObject (&sym_hdl, SYMBOLIC_LINK_QUERY, &attr); + if (!NT_SUCCESS (status)) + return 0; + RtlInitEmptyUnicodeString (&pid_str, pid_name, + sizeof pid_name - sizeof (WCHAR)); + status = NtQuerySymbolicLinkObject (sym_hdl, &pid_str, NULL); + NtClose (sym_hdl); + if (!NT_SUCCESS (status)) + { + system_printf ("NtOpenSymbolicLinkObject: %y, PID %u, ret 0", + status, dwProcessId); + return 0; + } + pid_str.Buffer[pid_str.Length / sizeof (WCHAR)] = L'\0'; + pid_t ret = (pid_t) wcstoul (pid_str.Buffer, NULL, 10); + return ret; +} + +/* Create "winpid.WINPID" symlinks with the Cygwin PID of that process as + target. This is used to find the Cygwin PID for a given Windows WINPID. */ +inline void +pinfo::create_winpid_symlink (pid_t cygpid, DWORD winpid) +{ + WCHAR sym_name[24]; + WCHAR pid_name[24]; + UNICODE_STRING sym_str; + UNICODE_STRING pid_str; + OBJECT_ATTRIBUTES attr; + + __small_swprintf (sym_name, L"winpid.%u", + procinfo->dwProcessId ?: myself_initial.pid); + RtlInitUnicodeString (&sym_str, sym_name); + __small_swprintf (pid_name, L"%u", procinfo->pid); + RtlInitUnicodeString (&pid_str, pid_name); + InitializeObjectAttributes (&attr, &sym_str, OBJ_CASE_INSENSITIVE, + get_shared_parent_dir (), NULL); + NtCreateSymbolicLinkObject (&winpid_hdl, SYMBOLIC_LINK_ALL_ACCESS, + &attr, &pid_str); +} + inline void pinfo::_pinfo_release () { @@ -252,20 +346,18 @@ pinfo::init (pid_t n, DWORD flag, HANDLE h0) { shared_locations shloc; h = NULL; - if (myself && !(flag & PID_EXECED) - && (n == myself->pid || (DWORD) n == myself->dwProcessId)) + if (myself && n == myself->pid) { procinfo = myself; destroy = 0; return; } - int createit = flag & (PID_IN_USE | PID_EXECED); + int createit = (flag & PID_IN_USE); DWORD access = FILE_MAP_READ - | (flag & (PID_IN_USE | PID_EXECED | PID_MAP_RW) - ? FILE_MAP_WRITE : 0); + | (flag & (PID_IN_USE | PID_MAP_RW) ? FILE_MAP_WRITE : 0); if (!h0 || myself.h) - shloc = (flag & (PID_IN_USE | PID_EXECED)) ? SH_JUSTCREATE : SH_JUSTOPEN; + shloc = (flag & PID_IN_USE) ? SH_JUSTCREATE : SH_JUSTOPEN; else { shloc = SH_MYSELF; @@ -281,14 +373,8 @@ pinfo::init (pid_t n, DWORD flag, HANDLE h0) for (int i = 0; i < 20; i++) { - DWORD mapsize; - if (flag & PID_EXECED) - mapsize = PINFO_REDIR_SIZE; - else - mapsize = sizeof (_pinfo); - - procinfo = (_pinfo *) open_shared (L"cygpid", n, h0, mapsize, &shloc, - sec_attribs, access); + procinfo = (_pinfo *) open_shared (L"cygpid", n, h0, sizeof (_pinfo), + &shloc, sec_attribs, access); if (!h0) { if (createit) @@ -311,33 +397,10 @@ pinfo::init (pid_t n, DWORD flag, HANDLE h0) bool created = shloc != SH_JUSTOPEN; - /* Detect situation where a transitional memory block is being retrieved. - If the block has been allocated with PINFO_REDIR_SIZE but not yet - updated with a PID_EXECED state then we'll retry. */ - if (!created && !(flag & PID_NEW) && !procinfo->ppid) - { - /* Fetching process info for /proc or ps? just ignore this one. */ - if (flag & PID_NOREDIR) - break; - /* FIXME: Do we ever hit this case? And if so, in what situation? */ - system_printf ("This shouldn't happen:\n" - " me: (%d, %d, %d, %W)\n" - " pid %d\n" - " process_state %y\n" - " cygstarted %d\n" - " dwProcessId %d\n" - " name %W", - myself->pid, myself->dwProcessId, myself->cygstarted, - myself->progname, - procinfo->pid, procinfo->process_state, - procinfo->cygstarted, procinfo->dwProcessId, - procinfo->progname); - /* If not populated, wait 2 seconds for procinfo to become populated. - Would like to wait with finer granularity but that is not easily - doable. */ - for (int i = 0; i < 200 && !procinfo->ppid; i++) - Sleep (10); - } + /* Just fetching info for ps or /proc, don't do anything rash. */ + if (!created && !(flag & PID_NEW) && !procinfo->ppid + && (flag & PID_PROCINFO)) + break; if (!created && createit && (procinfo->process_state & PID_REAPED)) { @@ -346,32 +409,18 @@ pinfo::init (pid_t n, DWORD flag, HANDLE h0) shared memory */ } - if ((procinfo->process_state & PID_REAPED) - || ((procinfo->process_state & PID_INITIALIZING) && (flag & PID_NOREDIR) - && cygwin_pid (procinfo->dwProcessId) != procinfo->pid)) + if (procinfo->process_state & PID_REAPED) { set_errno (ESRCH); break; } - if (procinfo->process_state & PID_EXECED) - { - pid_t realpid = procinfo->pid; - debug_printf ("execed process windows pid %u, cygwin pid %d", n, realpid); - if (realpid == n) - api_fatal ("retrieval of execed process info for pid %d failed due to recursion.", n); - - n = realpid; - CloseHandle (h0); - h0 = NULL; - goto loop; - } - /* In certain pathological cases, it is possible for the shared memory region to exist for a while after a process has exited. This should only be a brief occurrence, so rather than introduce some kind of locking mechanism, just loop. */ - if (!created && createit && (procinfo->process_state & (PID_EXITED | PID_REAPED))) + if (!created && createit + && (procinfo->process_state & (PID_EXITED | PID_REAPED))) { debug_printf ("looping because pid %d, procinfo->pid %d, " "procinfo->dwProcessid %u has PID_EXITED|PID_REAPED set", @@ -381,15 +430,8 @@ pinfo::init (pid_t n, DWORD flag, HANDLE h0) if (flag & PID_NEW) procinfo->start_time = time (NULL); - if (!created) - /* nothing */; - else if (!(flag & PID_EXECED)) + if (created) procinfo->pid = n; - else - { - procinfo->process_state |= PID_IN_USE | PID_EXECED; - procinfo->pid = myself->pid; - } h = h0; /* Success! */ break; @@ -529,7 +571,7 @@ _pinfo::set_ctty (fhandler_termios *fh, int flags) bool __reg1 _pinfo::exists () { - return process_state && !(process_state & (PID_EXITED | PID_REAPED | PID_EXECED)); + return process_state && !(process_state & (PID_EXITED | PID_REAPED)); } bool @@ -1279,6 +1321,8 @@ void pinfo::release () { _pinfo_release (); + if (winpid_hdl) + NtClose (winpid_hdl); HANDLE close_h; if (rd_proc_pipe) { @@ -1389,7 +1433,7 @@ winpids::add (DWORD& nelem, bool winpid, DWORD pid) make a copy of the shared memory area when it exists (it may not). */ perform_copy = onreturn ? make_copy : true; - p.init (cygpid, PID_NOREDIR | pinfo_access, NULL); + p.init (cygpid, PID_PROCINFO | pinfo_access, NULL); } /* If we're just looking for winpids then don't do any special cygwin "stuff* */ @@ -1403,9 +1447,9 @@ winpids::add (DWORD& nelem, bool winpid, DWORD pid) that it isn't a cygwin process. */ if (!p) { - if (!pinfo_access) + if (!pinfo_access || !cygpid) return; - p.init (cygpid, PID_NOREDIR, NULL); + p.init (cygpid, PID_PROCINFO, NULL); if (!p) return; } @@ -1491,7 +1535,7 @@ winpids::enum_processes (bool winpid) { restart = FALSE; f.dbi.ObjectName.Buffer[f.dbi.ObjectName.Length / sizeof (WCHAR)] = L'\0'; - if (wcsncmp (f.dbi.ObjectName.Buffer, L"cygpid.", 7) == 0) + if (wcsncmp (f.dbi.ObjectName.Buffer, L"winpid.", 7) == 0) { DWORD pid = wcstoul (f.dbi.ObjectName.Buffer + 7, NULL, 10); add (nelem, false, pid); diff --git a/winsup/cygwin/pinfo.h b/winsup/cygwin/pinfo.h index c4881c7f8..81e10d3d5 100644 --- a/winsup/cygwin/pinfo.h +++ b/winsup/cygwin/pinfo.h @@ -53,8 +53,6 @@ public: DWORD exitcode; /* set when process exits */ -#define PINFO_REDIR_SIZE ((char *) &myself.procinfo->exitcode - (char *) myself.procinfo) - /* > 0 if started by a cygwin process */ DWORD cygstarted; @@ -147,22 +145,25 @@ public: class pinfo: public pinfo_minimal { bool destroy; + HANDLE winpid_hdl; _pinfo *procinfo; public: bool waiter_ready; class cygthread *wait_thread; void __reg3 init (pid_t, DWORD, HANDLE); - pinfo (_pinfo *x = NULL): pinfo_minimal (), destroy (false), procinfo (x), - waiter_ready (false), wait_thread (NULL) {} - pinfo (pid_t n, DWORD flag = 0): pinfo_minimal (), destroy (false), - procinfo (NULL), waiter_ready (false), - wait_thread (NULL) + pinfo (_pinfo *x = NULL) + : pinfo_minimal (), destroy (false), winpid_hdl (NULL), procinfo (x), + waiter_ready (false), wait_thread (NULL) {} + pinfo (pid_t n, DWORD flag = 0) + : pinfo_minimal (), destroy (false), winpid_hdl (NULL), procinfo (NULL), + waiter_ready (false), wait_thread (NULL) { init (n, flag, NULL); } pinfo (HANDLE, pinfo_minimal&, pid_t); void __reg2 thisproc (HANDLE); + void create_winpid_symlink (pid_t, DWORD); inline void _pinfo_release (); void release (); bool __reg1 wait (); @@ -239,11 +240,8 @@ public: void release (); }; -extern __inline pid_t -cygwin_pid (pid_t pid) -{ - return pid; -} +pid_t create_cygwin_pid (); +pid_t cygwin_pid (DWORD); void __stdcall pinfo_init (char **, int); extern pinfo myself; diff --git a/winsup/cygwin/release/3.0 b/winsup/cygwin/release/3.0 index f4433c320..907405a05 100644 --- a/winsup/cygwin/release/3.0 +++ b/winsup/cygwin/release/3.0 @@ -61,6 +61,9 @@ What changed: - Kerberos/MSV1_0 S4U authentication replaces two old methods: Creating a token from scratch and Cygwin LSA authentication package. +- Cygwin PIDs have been decoupled from Windows PID. Cygwin PIDs are + now incrementally dealt in the range from 2 up to 65535, POSIX-like. + Bug Fixes --------- diff --git a/winsup/cygwin/shared.cc b/winsup/cygwin/shared.cc index dd16f1466..e87f2f960 100644 --- a/winsup/cygwin/shared.cc +++ b/winsup/cygwin/shared.cc @@ -323,12 +323,17 @@ shared_info::initialize () spinlock sversion (version, CURR_SHARED_MAGIC); if (!sversion) { + LUID luid; + cb = sizeof (*this); get_session_parent_dir (); /* Create session dir if first process. */ init_obcaseinsensitive (); /* Initialize obcaseinsensitive */ tty.init (); /* Initialize tty table */ mt.initialize (); /* Initialize shared tape information */ loadavg.initialize (); /* Initialize loadavg information */ + NtAllocateLocallyUniqueId (&luid);/* Initialize pid_src to a low */ + InterlockedExchange (&pid_src, /* random value to make start pid */ + luid.LowPart % 2048);/* less predictably */ /* Defer debug output printing the installation root and installation key up to this point. Debug output except for system_printf requires the global shared memory to exist. */ diff --git a/winsup/cygwin/shared_info.h b/winsup/cygwin/shared_info.h index f331a3ab3..1a5648b24 100644 --- a/winsup/cygwin/shared_info.h +++ b/winsup/cygwin/shared_info.h @@ -33,7 +33,7 @@ public: /* Data accessible to all tasks */ -#define CURR_SHARED_MAGIC 0x9b1c0f25U +#define CURR_SHARED_MAGIC 0x6758de88U #define USER_VERSION 1 @@ -50,6 +50,7 @@ class shared_info DWORD obcaseinsensitive; mtinfo mt; loadavginfo loadavg; + LONG pid_src; void initialize (); void init_obcaseinsensitive (); diff --git a/winsup/cygwin/spawn.cc b/winsup/cygwin/spawn.cc index 37db52608..58e2696a1 100644 --- a/winsup/cygwin/spawn.cc +++ b/winsup/cygwin/spawn.cc @@ -709,7 +709,7 @@ child_info_spawn::worker (const char *prog_arg, const char *const *argv, ::cygheap->fdtab.fixup_before_exec (pi.dwProcessId); if (mode != _P_OVERLAY) - cygpid = cygwin_pid (pi.dwProcessId); + cygpid = create_cygwin_pid (); else cygpid = myself->pid; diff --git a/winsup/doc/new-features.xml b/winsup/doc/new-features.xml index d620d1c2c..4bbf5fbd0 100644 --- a/winsup/doc/new-features.xml +++ b/winsup/doc/new-features.xml @@ -100,6 +100,11 @@ Kerberos/MSV1_0 S4U authentication replaces two old methods: Creating a token from scratch and Cygwin LSA authentication package. + +Cygwin PIDs have been decoupled from Windows PID. Cygwin PIDs are now +incrementally dealt in the range from 2 up to 65535, POSIX-like. + + From 231ad6941f9ade7bde67d27929da5a776ebd9457 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Sat, 2 Feb 2019 11:13:17 +0100 Subject: [PATCH 175/475] Cygwin: Makefile.in: Fix another dependency problem in version info Signed-off-by: Corinna Vinschen --- winsup/cygwin/Makefile.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/winsup/cygwin/Makefile.in b/winsup/cygwin/Makefile.in index 4dc849b4a..f94edb916 100644 --- a/winsup/cygwin/Makefile.in +++ b/winsup/cygwin/Makefile.in @@ -770,7 +770,7 @@ winver.o: mkvers.sh include/cygwin/version.h winver.rc $(src_files) @echo "Making version.cc and winver.o";\ /bin/sh ${word 1,$^} ${word 2,$^} ${word 3,$^} $(WINDRES) ${CFLAGS} $(addprefix -I,${CCWRAP_SYSTEM_HEADERS} ${CCWRAP_DIRAFTER_HEADERS}) -version.cc: winver.o +version.o: winver.o Makefile: ${srcdir}/Makefile.in /bin/sh ./config.status From 448cf5aa4b429d5a9cebf92a0da4ab4b5b6d23fe Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Sat, 2 Feb 2019 12:23:39 +0100 Subject: [PATCH 176/475] Cygwin: processes: fix handling of native Windows processes Since commit b5e1003722cb14235c4f166be72c09acdffc62ea, native Windows processes not started by Cygwin processes don't have a Cygwin PID anymore. This breaks ps -W and kill -f . Introduce MAX_PID (65536 for now). Cygwin processes as well as native Windows processes started from a Cygwin process get a PID < MAX_PID. All other native Windows processes get a faked Cygwin PID >= MAX_PID. Signed-off-by: Corinna Vinschen --- winsup/cygwin/external.cc | 12 ++++++++---- winsup/cygwin/pinfo.cc | 2 +- winsup/cygwin/pinfo.h | 2 ++ 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/winsup/cygwin/external.cc b/winsup/cygwin/external.cc index 3a9130efd..ae30695a1 100644 --- a/winsup/cygwin/external.cc +++ b/winsup/cygwin/external.cc @@ -63,19 +63,23 @@ fillout_pinfo (pid_t pid, int winpid) _pinfo *p = pids[i]; i++; + /* Native Windows process not started from Cygwin have no procinfo + attached. They don't have a real Cygwin PID either. We fake a + Cygwin PID beyond MAX_PID. */ if (!p) { - if (!nextpid && thispid != (DWORD) pid) + if (!nextpid && thispid + MAX_PID != (DWORD) pid) continue; - ep.pid = cygwin_pid (thispid); + ep.pid = thispid + MAX_PID; ep.dwProcessId = thispid; ep.process_state = PID_IN_USE; ep.ctty = -1; break; } - else if (nextpid || p->pid == pid || (winpid && thispid == (DWORD) pid)) + else if (nextpid || p->pid == pid) { - ep.ctty = (p->ctty < 0 || iscons_dev (p->ctty)) ? p->ctty : device::minor (p->ctty); + ep.ctty = (p->ctty < 0 || iscons_dev (p->ctty)) + ? p->ctty : device::minor (p->ctty); ep.pid = p->pid; ep.ppid = p->ppid; ep.dwProcessId = p->dwProcessId; diff --git a/winsup/cygwin/pinfo.cc b/winsup/cygwin/pinfo.cc index 98168c76a..c9025774f 100644 --- a/winsup/cygwin/pinfo.cc +++ b/winsup/cygwin/pinfo.cc @@ -241,7 +241,7 @@ create_cygwin_pid () do { pid = ((uint32_t) InterlockedIncrement (&cygwin_shared->pid_src)) - % 65536; + % MAX_PID; } while (pid < 2); __small_swprintf (sym_name, L"cygpid.%u", pid); diff --git a/winsup/cygwin/pinfo.h b/winsup/cygwin/pinfo.h index 81e10d3d5..a1e5afe23 100644 --- a/winsup/cygwin/pinfo.h +++ b/winsup/cygwin/pinfo.h @@ -211,6 +211,8 @@ private: DWORD status_exit (DWORD); }; +#define MAX_PID 65536 + #define ISSTATE(p, f) (!!((p)->process_state & f)) #define NOTSTATE(p, f) (!((p)->process_state & f)) From 8de660271fe75a6993f1c9888d24b824bb7f999d Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Sat, 2 Feb 2019 15:00:39 +0100 Subject: [PATCH 177/475] Cygwin: kill(1): disallow killing process using raw Windows PID This may end up killing the wrong process. Only allow Cygwin PID. Slightly clean up code: Remove outdated W95 considerations. Fix a bug in commandline argument processing. Signed-off-by: Corinna Vinschen --- winsup/utils/kill.cc | 41 ++++++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 19 deletions(-) diff --git a/winsup/utils/kill.cc b/winsup/utils/kill.cc index c6adaa281..19c19d089 100644 --- a/winsup/utils/kill.cc +++ b/winsup/utils/kill.cc @@ -152,29 +152,31 @@ get_debug_priv (void) } static void __stdcall -forcekill (int pid, int sig, int wait) +forcekill (pid_t pid, int sig, int wait) { - // try to acquire SeDebugPrivilege + /* try to acquire SeDebugPrivilege */ get_debug_priv(); external_pinfo *p = NULL; - /* cygwin_internal misinterprets negative pids (Win9x pids) */ - if (pid > 0) - p = (external_pinfo *) cygwin_internal (CW_GETPINFO_FULL, pid); - DWORD dwpid = p ? p->dwProcessId : (DWORD) pid; - HANDLE h = OpenProcess (PROCESS_TERMINATE, FALSE, (DWORD) dwpid); + p = (external_pinfo *) cygwin_internal (CW_GETPINFO_FULL, pid); + if (!p) + { + fprintf (stderr, "%s: %d: No such process\n", prog_name, pid); + return; + } + DWORD dwpid = p->dwProcessId; + HANDLE h = OpenProcess (PROCESS_TERMINATE, FALSE, dwpid); if (!h) { if (!wait || GetLastError () != ERROR_INVALID_PARAMETER) - fprintf (stderr, "%s: couldn't open pid %u\n", - prog_name, (unsigned) dwpid); + fprintf (stderr, "%s: couldn't open pid %u\n", prog_name, dwpid); return; } if (!wait || WaitForSingleObject (h, 200) != WAIT_OBJECT_0) if (sig && !TerminateProcess (h, sig << 8) && WaitForSingleObject (h, 200) != WAIT_OBJECT_0) fprintf (stderr, "%s: couldn't kill pid %u, %u\n", - prog_name, (unsigned) dwpid, (unsigned int) GetLastError ()); + prog_name, dwpid, GetLastError ()); CloseHandle (h); } @@ -232,11 +234,8 @@ main (int argc, char **argv) print_version (); break; case '?': - if (gotasig) - { - --optind; - goto out; - } + if (gotasig) /* this is a negative pid, go ahead */ + goto out; optreset = 1; optind = 1 + av - argv; gotasig = *av + 1; @@ -252,18 +251,22 @@ out: test_for_unknown_sig (sig, gotasig); argv += optind; + if (*argv == 0) + { + fprintf (stderr, "%s: not enough arguments\n", prog_name); + return 1; + } while (*argv != NULL) { if (!pid) pid = strtoll (*argv, &p, 10); - if (*p != '\0' - || (!force && (pid < INT_MIN || pid > INT_MAX)) - || (force && (pid <= 0 || pid > UINT_MAX))) + /* INT_MIN <= pid <= INT_MAX. -f only takes positive pids. */ + if (*p != '\0' || pid < (force ? 1 : INT_MIN) || pid > INT_MAX) { fprintf (stderr, "%s: illegal pid: %s\n", prog_name, *argv); ret = 1; } - else if (pid <= INT_MAX && kill ((pid_t) pid, sig) == 0) + else if (kill ((pid_t) pid, sig) == 0) { if (force) forcekill ((pid_t) pid, sig, 1); From 2cd6829619290e12095eaeed21aa1a431116d71a Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Sat, 2 Feb 2019 15:10:13 +0100 Subject: [PATCH 178/475] Cygwin: Makefile.in: Fix previous version info generation fix Commit 231ad6941f9ade7bde67d27929da5a776ebd9457 looks good... as long as you never build Cygwin from scratch. Signed-off-by: Corinna Vinschen --- winsup/cygwin/Makefile.in | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/winsup/cygwin/Makefile.in b/winsup/cygwin/Makefile.in index f94edb916..c14eea32d 100644 --- a/winsup/cygwin/Makefile.in +++ b/winsup/cygwin/Makefile.in @@ -766,11 +766,12 @@ ${EXTRALIBS}: lib%.a: %.o find_src_files = $(wildcard $(dir)/*.[chS]) $(wildcard $(dir)/*.cc) src_files := $(foreach dir,$(VPATH),$(find_src_files)) -winver.o: mkvers.sh include/cygwin/version.h winver.rc $(src_files) +# mkvers.sh creates version.cc in the first place, winver.o always +# second, so version.cc is always older than winver.o +version.cc: mkvers.sh include/cygwin/version.h winver.rc $(src_files) @echo "Making version.cc and winver.o";\ /bin/sh ${word 1,$^} ${word 2,$^} ${word 3,$^} $(WINDRES) ${CFLAGS} $(addprefix -I,${CCWRAP_SYSTEM_HEADERS} ${CCWRAP_DIRAFTER_HEADERS}) - -version.o: winver.o +$(VERSION_OFILES): version.cc Makefile: ${srcdir}/Makefile.in /bin/sh ./config.status From f5c2d4db5be575ce5cb87f5727c981901639f74d Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Sat, 2 Feb 2019 15:32:28 +0100 Subject: [PATCH 179/475] Cygwin: kill(1): revert casts required for 32 bit to avoid spurious warnings Signed-off-by: Corinna Vinschen --- winsup/utils/kill.cc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/winsup/utils/kill.cc b/winsup/utils/kill.cc index 19c19d089..e34923ac0 100644 --- a/winsup/utils/kill.cc +++ b/winsup/utils/kill.cc @@ -169,14 +169,15 @@ forcekill (pid_t pid, int sig, int wait) if (!h) { if (!wait || GetLastError () != ERROR_INVALID_PARAMETER) - fprintf (stderr, "%s: couldn't open pid %u\n", prog_name, dwpid); + fprintf (stderr, "%s: couldn't open pid %u\n", + prog_name, (unsigned int) dwpid); return; } if (!wait || WaitForSingleObject (h, 200) != WAIT_OBJECT_0) if (sig && !TerminateProcess (h, sig << 8) && WaitForSingleObject (h, 200) != WAIT_OBJECT_0) fprintf (stderr, "%s: couldn't kill pid %u, %u\n", - prog_name, dwpid, GetLastError ()); + prog_name, (unsigned int) dwpid, (unsigned int) GetLastError ()); CloseHandle (h); } From d6cf2b781f4e14f81442ee5aaeaea9f6da73199b Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Sat, 2 Feb 2019 18:11:42 +0100 Subject: [PATCH 180/475] Cygwin: pinfo: simplify create_winpid_symlink The arguments are not used anyway, so drop them. When called, procinfo->dwProcessId is already set right, so we don't have to access myself_initial. Signed-off-by: Corinna Vinschen --- winsup/cygwin/pinfo.cc | 9 ++++----- winsup/cygwin/pinfo.h | 2 +- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/winsup/cygwin/pinfo.cc b/winsup/cygwin/pinfo.cc index c9025774f..b2bfb2b63 100644 --- a/winsup/cygwin/pinfo.cc +++ b/winsup/cygwin/pinfo.cc @@ -67,7 +67,7 @@ pinfo::thisproc (HANDLE h) procinfo->dwProcessId = myself_initial.pid; procinfo->sendsig = myself_initial.sendsig; wcscpy (procinfo->progname, myself_initial.progname); - create_winpid_symlink (procinfo->pid, procinfo->dwProcessId); + create_winpid_symlink (); procinfo->exec_sendsig = NULL; procinfo->exec_dwProcessId = 0; debug_printf ("myself dwProcessId %u", procinfo->dwProcessId); @@ -303,8 +303,8 @@ cygwin_pid (DWORD dwProcessId) /* Create "winpid.WINPID" symlinks with the Cygwin PID of that process as target. This is used to find the Cygwin PID for a given Windows WINPID. */ -inline void -pinfo::create_winpid_symlink (pid_t cygpid, DWORD winpid) +void +pinfo::create_winpid_symlink () { WCHAR sym_name[24]; WCHAR pid_name[24]; @@ -312,8 +312,7 @@ pinfo::create_winpid_symlink (pid_t cygpid, DWORD winpid) UNICODE_STRING pid_str; OBJECT_ATTRIBUTES attr; - __small_swprintf (sym_name, L"winpid.%u", - procinfo->dwProcessId ?: myself_initial.pid); + __small_swprintf (sym_name, L"winpid.%u", procinfo->dwProcessId); RtlInitUnicodeString (&sym_str, sym_name); __small_swprintf (pid_name, L"%u", procinfo->pid); RtlInitUnicodeString (&pid_str, pid_name); diff --git a/winsup/cygwin/pinfo.h b/winsup/cygwin/pinfo.h index a1e5afe23..38a34f327 100644 --- a/winsup/cygwin/pinfo.h +++ b/winsup/cygwin/pinfo.h @@ -163,7 +163,7 @@ public: } pinfo (HANDLE, pinfo_minimal&, pid_t); void __reg2 thisproc (HANDLE); - void create_winpid_symlink (pid_t, DWORD); + void create_winpid_symlink (); inline void _pinfo_release (); void release (); bool __reg1 wait (); From 3a3934252c2cb390b3970edb4898f452ea2f641a Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Sat, 2 Feb 2019 20:01:41 +0100 Subject: [PATCH 181/475] Cygwin: spawn: create and maintain winpid symlinks - If the execve'ed process is a non-Cygwin process, we have to create the matching winpid symlink and remove the old one ourselves. - If we spawn a child, the winpid symlink has to be maintained by the child process, otherwise it disappears if the parent process exits. Signed-off-by: Corinna Vinschen --- winsup/cygwin/pinfo.h | 1 + winsup/cygwin/spawn.cc | 30 +++++++++++++++++++++++++----- 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/winsup/cygwin/pinfo.h b/winsup/cygwin/pinfo.h index 38a34f327..8cf1bba2e 100644 --- a/winsup/cygwin/pinfo.h +++ b/winsup/cygwin/pinfo.h @@ -204,6 +204,7 @@ public: } #endif HANDLE shared_handle () {return h;} + HANDLE shared_winpid_handle () {return winpid_hdl;} void set_acl (); friend class _pinfo; friend class winpids; diff --git a/winsup/cygwin/spawn.cc b/winsup/cygwin/spawn.cc index 58e2696a1..d969c66ea 100644 --- a/winsup/cygwin/spawn.cc +++ b/winsup/cygwin/spawn.cc @@ -725,6 +725,16 @@ child_info_spawn::worker (const char *prog_arg, const char *const *argv, myself->dwProcessId = pi.dwProcessId; strace.execing = 1; myself.hProcess = hExeced = pi.hProcess; + if (!real_path.iscygexec ()) + { + /* If the child process is not a Cygwin process, we have to + create a new winpid symlink and drop the old one on + behalf of the child process not being able to do this + by itself. */ + HANDLE old_winpid_hdl = myself.shared_winpid_handle (); + myself.create_winpid_symlink (); + NtClose (old_winpid_hdl); + } real_path.get_wide_win32_path (myself->progname); // FIXME: race? sigproc_printf ("new process name %W", myself->progname); if (!iscygwin ()) @@ -748,13 +758,23 @@ child_info_spawn::worker (const char *prog_arg, const char *const *argv, child.hProcess = pi.hProcess; real_path.get_wide_win32_path (child->progname); - /* FIXME: This introduces an unreferenced, open handle into the child. - The purpose is to keep the pid shared memory open so that all of - the fields filled out by child.remember do not disappear and so - there is not a brief period during which the pid is not available. - However, we should try to find another way to do this eventually. */ + /* This introduces an unreferenced, open handle into the child. + The purpose is to keep the pid shared memory open so that all + of the fields filled out by child.remember do not disappear + and so there is not a brief period during which the pid is + not available. */ DuplicateHandle (GetCurrentProcess (), child.shared_handle (), pi.hProcess, NULL, 0, 0, DUPLICATE_SAME_ACCESS); + if (!real_path.iscygexec ()) + { + /* If the child process is not a Cygwin process, we have to + create a new winpid symlink and induce it into the child + process as well to keep it over the lifetime of the child. */ + child.create_winpid_symlink (); + DuplicateHandle (GetCurrentProcess (), + child.shared_winpid_handle (), + pi.hProcess, NULL, 0, 0, DUPLICATE_SAME_ACCESS); + } child->start_time = time (NULL); /* Register child's starting time. */ child->nice = myself->nice; postfork (child); From 658f9390032ad2f4a70fb2550480ec8ca58a530a Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Sat, 2 Feb 2019 21:02:00 +0100 Subject: [PATCH 182/475] Cygwin: kill(1): introduce a -W option Allow to kill processes using Windows PIDs on the command line. Signed-off-by: Corinna Vinschen --- winsup/cygwin/external.cc | 9 +++++ winsup/cygwin/include/sys/cygwin.h | 2 ++ winsup/doc/utils.xml | 10 +++++- winsup/utils/kill.cc | 58 ++++++++++++++++++++---------- 4 files changed, 59 insertions(+), 20 deletions(-) diff --git a/winsup/cygwin/external.cc b/winsup/cygwin/external.cc index ae30695a1..fbb901f3a 100644 --- a/winsup/cygwin/external.cc +++ b/winsup/cygwin/external.cc @@ -322,6 +322,15 @@ cygwin_internal (cygwin_getinfo_types t, ...) res = p ? p->dwProcessId : 0; } break; + + case CW_WINPID_TO_CYGWIN_PID: + { + DWORD winpid = va_arg (arg, DWORD); + pid_t pid = cygwin_pid (winpid); + res = pid ?: winpid + MAX_PID; + } + break; + case CW_EXTRACT_DOMAIN_AND_USER: { WCHAR nt_domain[MAX_DOMAIN_NAME_LEN + 1]; diff --git a/winsup/cygwin/include/sys/cygwin.h b/winsup/cygwin/include/sys/cygwin.h index 480d8ea06..afc193fb7 100644 --- a/winsup/cygwin/include/sys/cygwin.h +++ b/winsup/cygwin/include/sys/cygwin.h @@ -158,6 +158,7 @@ typedef enum CW_GETNSS_GRP_SRC, CW_EXCEPTION_RECORD_FROM_SIGINFO_T, CW_CYGHEAP_PROFTHR_ALL, + CW_WINPID_TO_CYGWIN_PID, } cygwin_getinfo_types; #define CW_LOCK_PINFO CW_LOCK_PINFO @@ -220,6 +221,7 @@ typedef enum #define CW_GETNSS_GRP_SRC CW_GETNSS_GRP_SRC #define CW_EXCEPTION_RECORD_FROM_SIGINFO_T CW_EXCEPTION_RECORD_FROM_SIGINFO_T #define CW_CYGHEAP_PROFTHR_ALL CW_CYGHEAP_PROFTHR_ALL +#define CW_WINPID_TO_CYGWIN_PID CW_WINPID_TO_CYGWIN_PID /* Token type for CW_SET_EXTERNAL_TOKEN */ enum diff --git a/winsup/doc/utils.xml b/winsup/doc/utils.xml index 17b564da4..0909d1173 100644 --- a/winsup/doc/utils.xml +++ b/winsup/doc/utils.xml @@ -692,6 +692,8 @@ kill -l [signal] -f, --force force, using win32 interface if necessary -l, --list print a list of signal names -s, --signal send signal (use kill --list for a list) + -W, --winpid specified pids are windows PIDs, not Cygwin PIDs + (use with extrem caution!) -h, --help output usage information and exit -V, --version output version information and exit @@ -717,7 +719,13 @@ $ /bin/kill --version which should give the Cygwin kill version number and copyright information. - Unless you specific the -f option, the "pid" + The -f option uses Windows functions to + terminate processes forcefully. Use -f to + terminate native Windows processes not started by Cygwin processes. + -f can also be useful to terminate Cygwin processes + not answering to SIGKILL. + + Unless you specific the -W option, the "pid" values used by kill are the Cygwin pids, not the Windows pids. To get a list of running programs and their Cygwin pids, use the Cygwin ps program. ps -W diff --git a/winsup/utils/kill.cc b/winsup/utils/kill.cc index e34923ac0..7905c4ea7 100644 --- a/winsup/utils/kill.cc +++ b/winsup/utils/kill.cc @@ -26,17 +26,18 @@ static struct option longopts[] = {"list", optional_argument, NULL, 'l'}, {"force", no_argument, NULL, 'f'}, {"signal", required_argument, NULL, 's'}, + {"winpid", no_argument, NULL, 'W'}, {"version", no_argument, NULL, 'V'}, {NULL, 0, NULL, 0} }; -static char opts[] = "hl::fs:V"; +static char opts[] = "hl::fs:WV"; static void usage (FILE *where = stderr) { fprintf (where , "" - "Usage: %1$s [-f] [-signal] [-s signal] pid1 [pid2 ...]\n" + "Usage: %1$s [-fW] [-signal] [-s signal] pid1 [pid2 ...]\n" " %1$s -l [signal]\n" "\n" "Send signals to processes\n" @@ -44,6 +45,8 @@ usage (FILE *where = stderr) " -f, --force force, using win32 interface if necessary\n" " -l, --list print a list of signal names\n" " -s, --signal send signal (use %1$s --list for a list)\n" + " -W, --winpid specified pids are windows PIDs, not Cygwin PIDs\n" + " (use with extrem caution!)\n" " -h, --help output usage information and exit\n" " -V, --version output version information and exit\n" "\n", prog_name); @@ -152,19 +155,28 @@ get_debug_priv (void) } static void __stdcall -forcekill (pid_t pid, int sig, int wait) +forcekill (pid_t pid, DWORD winpid, int sig, int wait) { + DWORD dwpid; + /* try to acquire SeDebugPrivilege */ get_debug_priv(); - external_pinfo *p = NULL; - p = (external_pinfo *) cygwin_internal (CW_GETPINFO_FULL, pid); - if (!p) + if (!winpid) { - fprintf (stderr, "%s: %d: No such process\n", prog_name, pid); - return; + external_pinfo *p = (external_pinfo *) + cygwin_internal (CW_GETPINFO_FULL, pid); + if (!p) + { + fprintf (stderr, "%s: %d: No such process\n", prog_name, pid); + return; + } + dwpid = p->dwProcessId; } - DWORD dwpid = p->dwProcessId; + else + /* pid is used for printing only after this point */ + pid = dwpid = winpid; + HANDLE h = OpenProcess (PROCESS_TERMINATE, FALSE, dwpid); if (!h) { @@ -186,6 +198,7 @@ main (int argc, char **argv) { int sig = SIGTERM; int force = 0; + int winpids = 0; int ret = 0; char *gotasig = NULL; @@ -197,7 +210,6 @@ main (int argc, char **argv) opterr = 0; char *p; - long long int pid = 0; for (;;) { @@ -228,6 +240,9 @@ main (int argc, char **argv) case 'f': force = 1; break; + case 'W': + winpids = 1; + break; case 'h': usage (stdout); break; @@ -257,32 +272,37 @@ out: fprintf (stderr, "%s: not enough arguments\n", prog_name); return 1; } - while (*argv != NULL) + for (long long int pid = 0; *argv != NULL; argv++) { - if (!pid) - pid = strtoll (*argv, &p, 10); + DWORD dwpid = 0; + + pid = strtoll (*argv, &p, 10); /* INT_MIN <= pid <= INT_MAX. -f only takes positive pids. */ if (*p != '\0' || pid < (force ? 1 : INT_MIN) || pid > INT_MAX) { fprintf (stderr, "%s: illegal pid: %s\n", prog_name, *argv); ret = 1; + continue; } - else if (kill ((pid_t) pid, sig) == 0) + if (winpids) + { + dwpid = pid; + pid = (pid_t) cygwin_internal (CW_WINPID_TO_CYGWIN_PID, dwpid); + } + if (kill ((pid_t) pid, sig) == 0) { if (force) - forcekill ((pid_t) pid, sig, 1); + forcekill ((pid_t) pid, dwpid, sig, 1); } else if (force) - forcekill ((pid_t) pid, sig, 0); + forcekill ((pid_t) pid, dwpid, sig, 0); else { char buf[1000]; - sprintf (buf, "%s: %lld", prog_name, pid); + sprintf (buf, "%s: %lld", prog_name, dwpid ?: pid); perror (buf); ret = 1; } - argv++; - pid = 0; } return ret; } From d5d9aac75907798e664bc12aeb7e1ab0c16b0875 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Sat, 2 Feb 2019 21:13:37 +0100 Subject: [PATCH 183/475] Cygwin: tweak Cygwin PID change release note Signed-off-by: Corinna Vinschen --- winsup/cygwin/release/3.0 | 2 ++ winsup/doc/new-features.xml | 2 ++ 2 files changed, 4 insertions(+) diff --git a/winsup/cygwin/release/3.0 b/winsup/cygwin/release/3.0 index 907405a05..4cd422a56 100644 --- a/winsup/cygwin/release/3.0 +++ b/winsup/cygwin/release/3.0 @@ -63,6 +63,8 @@ What changed: - Cygwin PIDs have been decoupled from Windows PID. Cygwin PIDs are now incrementally dealt in the range from 2 up to 65535, POSIX-like. + Native Windows processes not started by Cygwin processes are mapped + into the range beyond 65535. Bug Fixes diff --git a/winsup/doc/new-features.xml b/winsup/doc/new-features.xml index 4bbf5fbd0..6801e3eeb 100644 --- a/winsup/doc/new-features.xml +++ b/winsup/doc/new-features.xml @@ -103,6 +103,8 @@ Creating a token from scratch and Cygwin LSA authentication package. Cygwin PIDs have been decoupled from Windows PID. Cygwin PIDs are now incrementally dealt in the range from 2 up to 65535, POSIX-like. +Native Windows processes not started by Cygwin processes are mapped +into the range beyond 65535. From 49ea15ef17fda59cc279a59141c9b78cd9b9a3c1 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Sat, 2 Feb 2019 21:15:50 +0100 Subject: [PATCH 184/475] Cygwin: fix typo Signed-off-by: Corinna Vinschen --- winsup/doc/utils.xml | 2 +- winsup/utils/kill.cc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/winsup/doc/utils.xml b/winsup/doc/utils.xml index 0909d1173..043ed7358 100644 --- a/winsup/doc/utils.xml +++ b/winsup/doc/utils.xml @@ -693,7 +693,7 @@ kill -l [signal] -l, --list print a list of signal names -s, --signal send signal (use kill --list for a list) -W, --winpid specified pids are windows PIDs, not Cygwin PIDs - (use with extrem caution!) + (use with extreme caution!) -h, --help output usage information and exit -V, --version output version information and exit diff --git a/winsup/utils/kill.cc b/winsup/utils/kill.cc index 7905c4ea7..768ac44e7 100644 --- a/winsup/utils/kill.cc +++ b/winsup/utils/kill.cc @@ -46,7 +46,7 @@ usage (FILE *where = stderr) " -l, --list print a list of signal names\n" " -s, --signal send signal (use %1$s --list for a list)\n" " -W, --winpid specified pids are windows PIDs, not Cygwin PIDs\n" - " (use with extrem caution!)\n" + " (use with extreme caution!)\n" " -h, --help output usage information and exit\n" " -V, --version output version information and exit\n" "\n", prog_name); From 99cd3df6ec471d6cbdea62fb14ebbe1e5eec8ef8 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Mon, 4 Feb 2019 21:08:03 +0100 Subject: [PATCH 185/475] Cygwin: timerfd: drop outdated TODO comment Signed-off-by: Corinna Vinschen --- winsup/cygwin/timerfd.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/winsup/cygwin/timerfd.cc b/winsup/cygwin/timerfd.cc index dc404883e..7e6be72b2 100644 --- a/winsup/cygwin/timerfd.cc +++ b/winsup/cygwin/timerfd.cc @@ -105,7 +105,6 @@ timerfd_tracker::thread_func () } /* Inner loop: Timer expired? If not, wait for it. */ - /* TODO: TFD_TIMER_CANCEL_ON_SET */ HANDLE expired[3] = { tfd_shared->timer (), tfd_shared->disarm_evt (), cancel_evt }; From fb3e8bd88b06be6b5e748b99aa50968bb46653a1 Mon Sep 17 00:00:00 2001 From: Michael Haubenwallner Date: Tue, 5 Jun 2018 12:40:21 +0200 Subject: [PATCH 186/475] fork: remove cygpid.N sharedmem on fork failure When fork finally fails although both CreateProcess and creating the "cygpid.N" shared memory section succeeded, we have to release that shared memory section as well - before releasing the process handle. Otherways we leave an orphan "cygpid.N" shared memory section, and any subsequent cygwin process receiving the same PID fails to initialize. * fork.cc (frok::parent): Call child.allow_remove in cleanup code. --- winsup/cygwin/fork.cc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/winsup/cygwin/fork.cc b/winsup/cygwin/fork.cc index c083f7a02..6f0036433 100644 --- a/winsup/cygwin/fork.cc +++ b/winsup/cygwin/fork.cc @@ -499,13 +499,16 @@ frok::parent (volatile char * volatile stack_here) /* Common cleanup code for failure cases */ cleanup: + /* release procinfo before hProcess in destructor */ + child.allow_remove (); + if (fix_impersonation) cygheap->user.reimpersonate (); if (locked) __malloc_unlock (); /* Remember to de-allocate the fd table. */ - if (hchild && !child.hProcess) + if (hchild && !child.hProcess) /* no child.procinfo */ ForceCloseHandle1 (hchild, childhProc); if (forker_finished) ForceCloseHandle (forker_finished); From 7225a82c1a4e90bcea2a17da12a427d1e783de30 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Tue, 5 Feb 2019 12:52:13 +0100 Subject: [PATCH 187/475] Cygwin: fork: terminate child process unconditionally in error case Move TerminateProcess call into cleanup code to make sure child doesn't linger in some border cases. Signed-off-by: Corinna Vinschen --- winsup/cygwin/fork.cc | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/winsup/cygwin/fork.cc b/winsup/cygwin/fork.cc index 6f0036433..5f775249a 100644 --- a/winsup/cygwin/fork.cc +++ b/winsup/cygwin/fork.cc @@ -400,7 +400,6 @@ frok::parent (volatile char * volatile stack_here) we can't actually record the pid in the internal table. */ if (!child.remember (false)) { - TerminateProcess (hchild, 1); this_errno = EAGAIN; #ifdef DEBUGGING0 error ("child remember failed"); @@ -508,8 +507,12 @@ cleanup: __malloc_unlock (); /* Remember to de-allocate the fd table. */ - if (hchild && !child.hProcess) /* no child.procinfo */ - ForceCloseHandle1 (hchild, childhProc); + if (hchild) + { + TerminateProcess (hchild, 1); + if (!child.hProcess) /* no child.procinfo */ + ForceCloseHandle1 (hchild, childhProc); + } if (forker_finished) ForceCloseHandle (forker_finished); debug_printf ("returning -1"); From 1f6340aa8bd8cde79b45f66b4766bfb70b490a9b Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Tue, 5 Feb 2019 15:20:13 +0100 Subject: [PATCH 188/475] Cygwin: proc fd: pass along open mode when reopening file The reopen code neglected to pass along the requested open mode correctly. This may end up reopening the file with incorrect access mask, or duplicating the wrong pipe handle. Signed-off-by: Corinna Vinschen --- winsup/cygwin/fhandler.cc | 2 +- winsup/cygwin/fhandler.h | 4 ++-- winsup/cygwin/fhandler_process_fd.cc | 4 ++-- winsup/cygwin/syscalls.cc | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/winsup/cygwin/fhandler.cc b/winsup/cygwin/fhandler.cc index 07a048208..659435e0a 100644 --- a/winsup/cygwin/fhandler.cc +++ b/winsup/cygwin/fhandler.cc @@ -792,7 +792,7 @@ done: } fhandler_base * -fhandler_base::fd_reopen (int) +fhandler_base::fd_reopen (int, mode_t) { /* This is implemented in fhandler_process only. */ return NULL; diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h index 97804ed30..079385db8 100644 --- a/winsup/cygwin/fhandler.h +++ b/winsup/cygwin/fhandler.h @@ -331,7 +331,7 @@ class fhandler_base int open_with_arch (int, mode_t = 0); int open_null (int flags); virtual int open (int, mode_t); - virtual fhandler_base *fd_reopen (int); + virtual fhandler_base *fd_reopen (int, mode_t); virtual void open_setup (int flags); void set_unique_id (int64_t u) { unique_id = u; } void set_unique_id () { NtAllocateLocallyUniqueId ((PLUID) &unique_id); } @@ -2587,7 +2587,7 @@ class fhandler_process_fd : public fhandler_process fhandler_process_fd () : fhandler_process () {} fhandler_process_fd (void *) {} - virtual fhandler_base *fd_reopen (int); + virtual fhandler_base *fd_reopen (int, mode_t); int __reg2 fstat (struct stat *buf); virtual int __reg2 link (const char *); diff --git a/winsup/cygwin/fhandler_process_fd.cc b/winsup/cygwin/fhandler_process_fd.cc index a33fd7539..7d70ebe8d 100644 --- a/winsup/cygwin/fhandler_process_fd.cc +++ b/winsup/cygwin/fhandler_process_fd.cc @@ -97,7 +97,7 @@ fhandler_process_fd::fetch_fh (HANDLE &out_hdl, uint32_t flags) } fhandler_base * -fhandler_process_fd::fd_reopen (int flags) +fhandler_process_fd::fd_reopen (int flags, mode_t mode) { fhandler_base *fh; HANDLE hdl; @@ -106,7 +106,7 @@ fhandler_process_fd::fd_reopen (int flags) if (!fh) return NULL; fh->set_io_handle (hdl); - int ret = fh->open_with_arch (flags, 0); + int ret = fh->open_with_arch (flags, mode); CloseHandle (hdl); if (!ret) { diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc index 8a995e8fb..d1a1312b1 100644 --- a/winsup/cygwin/syscalls.cc +++ b/winsup/cygwin/syscalls.cc @@ -1507,7 +1507,7 @@ open (const char *unix_path, int flags, ...) if (fh->dev () == FH_PROCESSFD && fh->pc.follow_fd_symlink ()) { /* Reopen file by descriptor */ - fh_file = fh->fd_reopen (flags); + fh_file = fh->fd_reopen (flags, mode & 07777); if (!fh_file) __leave; delete fh; From b59f5795e69f5477b2be13e858dd1ee47e89b798 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Tue, 5 Feb 2019 15:20:50 +0100 Subject: [PATCH 189/475] Cygwin: proc fd: fix a copy/paste bug calling file_pathconv Signed-off-by: Corinna Vinschen --- winsup/cygwin/fhandler_process_fd.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/winsup/cygwin/fhandler_process_fd.cc b/winsup/cygwin/fhandler_process_fd.cc index 7d70ebe8d..4f326b69a 100644 --- a/winsup/cygwin/fhandler_process_fd.cc +++ b/winsup/cygwin/fhandler_process_fd.cc @@ -60,7 +60,7 @@ fhandler_process_fd::fetch_fh (HANDLE &out_hdl, uint32_t flags) return NULL; } size_t size; - void *buf = p->file_pathconv (fd, FFH_LINKAT, size); + void *buf = p->file_pathconv (fd, flags, size); if (size == 0) { set_errno (ENOENT); From 5628399c8470d3bbf6ca05b3d0f7f0366f1c16f8 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Tue, 5 Feb 2019 15:32:08 +0100 Subject: [PATCH 190/475] Cygwin: proc fd: fix handling of pipes, sockets, etc The symlink target of /proc/PID/fd files pointing to pipes and sockets are just artificial filenames referencing the object using some internal number. The pipe open code expects a path specifying process pid and the internal number so it access the right process and pipe. - Set the posix path of the pipe to the simple pipe name only, as it shows up in /proc/PID/fd. A /proc/self prefix is just as wrong as a /dev/fd prefix. - Revert thinko in fhandler_pipe::open expecting the name as /proc/self/fd/... In fact this should never happen. - Fix up the path before re-opening the pipe instead. Signed-off-by: Corinna Vinschen --- winsup/cygwin/fhandler_pipe.cc | 7 ++----- winsup/cygwin/fhandler_process_fd.cc | 11 +++++++++++ winsup/cygwin/syscalls.cc | 4 ++-- 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/winsup/cygwin/fhandler_pipe.cc b/winsup/cygwin/fhandler_pipe.cc index 3a70565de..31e73ceb0 100644 --- a/winsup/cygwin/fhandler_pipe.cc +++ b/winsup/cygwin/fhandler_pipe.cc @@ -73,11 +73,8 @@ fhandler_pipe::open (int flags, mode_t mode) bool inh; bool got_one = false; - if (sscanf (get_name (), "/proc/self/fd/pipe:[%llu]", - (long long *) &uniq_id) == 1) - pid = myself->pid; - else if (sscanf (get_name (), "/proc/%d/fd/pipe:[%llu]", - &pid, (long long *) &uniq_id) < 2) + if (sscanf (get_name (), "/proc/%d/fd/pipe:[%llu]", + &pid, (long long *) &uniq_id) < 2) { set_errno (ENOENT); return 0; diff --git a/winsup/cygwin/fhandler_process_fd.cc b/winsup/cygwin/fhandler_process_fd.cc index 4f326b69a..3bf8b74d8 100644 --- a/winsup/cygwin/fhandler_process_fd.cc +++ b/winsup/cygwin/fhandler_process_fd.cc @@ -13,6 +13,7 @@ details. */ #include "pinfo.h" #include "dtable.h" #include "cygheap.h" +#include "tls_pbuf.h" fhandler_base * fhandler_process_fd::fetch_fh (HANDLE &out_hdl, uint32_t flags) @@ -86,6 +87,16 @@ fhandler_process_fd::fetch_fh (HANDLE &out_hdl, uint32_t flags) CloseHandle (hdl); return NULL; } + /* relative path? This happens for special types like pipes and sockets. */ + if (*pc.get_posix () != '/') + { + tmp_pathbuf tp; + char *fullpath = tp.c_get (); + + stpcpy (stpncpy (fullpath, get_name (), path - get_name ()), + pc.get_posix ()); + pc.set_posix (fullpath); + } fhandler_base *fh = build_fh_pc (pc); if (!fh) { diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc index d1a1312b1..62b963844 100644 --- a/winsup/cygwin/syscalls.cc +++ b/winsup/cygwin/syscalls.cc @@ -5061,8 +5061,8 @@ pipe_worker (int filedes[2], unsigned int psize, int mode) { cygheap_fdnew fdin; cygheap_fdnew fdout (fdin, false); - char buf[sizeof ("/proc/self/fd/pipe:[9223372036854775807]")]; - __small_sprintf (buf, "/proc/self/fd/pipe:[%D]", fhs[0]->get_plain_ino ()); + char buf[sizeof ("pipe:[9223372036854775807]")]; + __small_sprintf (buf, "pipe:[%D]", fhs[0]->get_plain_ino ()); fhs[0]->pc.set_posix (buf); __small_sprintf (buf, "pipe:[%D]", fhs[1]->get_plain_ino ()); fhs[1]->pc.set_posix (buf); From 9fa22dba558f5e3efd0bb719049491edcd7b5e0b Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Wed, 6 Feb 2019 21:17:35 +0100 Subject: [PATCH 191/475] Cygwin: unlink: allow fallback from POSIX to default method Trying to delete in-use executables and DLLs using FILE_DISPOSITION_POSIX_SEMANTICS returns STATUS_CANNOT_DELETE. Fall back to the former method if that error occurs to allow unlinking these files. Signed-off-by: Corinna Vinschen --- winsup/cygwin/syscalls.cc | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc index 62b963844..593c2a4af 100644 --- a/winsup/cygwin/syscalls.cc +++ b/winsup/cygwin/syscalls.cc @@ -733,7 +733,11 @@ unlink_nt (path_conv &pc) if (pc.file_attributes () & FILE_ATTRIBUTE_READONLY) NtSetAttributesFile (fh, pc.file_attributes ()); NtClose (fh); - goto out; + /* Trying to delete in-use executables and DLLs using + FILE_DISPOSITION_POSIX_SEMANTICS returns STATUS_CANNOT_DELETE. + Fall back to the default method. */ + if (status != STATUS_CANNOT_DELETE) + goto out; } /* If the R/O attribute is set, we have to open the file with From 2678c4efe1195ffb49d92a899c10d4c9fa168eb0 Mon Sep 17 00:00:00 2001 From: Michael Haubenwallner Date: Wed, 7 Dec 2016 11:58:25 +0100 Subject: [PATCH 192/475] dll_list: Store dll file name as full NT path. Store loaded dll's file name as full NT path. * dll_init.h (struct dll): Rename member variable name to ntname. (struct dll_list): Declare private static member variable nt_max_path_buffer. Declare public static methods form_ntname, form_shortname. Define public static methods nt_max_path_buf, buffered_shortname. (dll_list::operator []): Use PCWCHAR rather than const PWCHAR. (dll_list::find_by_modname): Ditto. * dll_init.cc (in_load_after_fork): Define earlier in file. (struct dll_list): Rename member variable name to ntname. Define nt_max_path_buffer variable. Implement static methods form_ntname, form_shortname. (dll_list::operator []): Use PCWCHAR rather than const PWCHAR. (dll_list::find_by_modname): Ditto. (reserve_at): Ditto. (release_at): Ditto. (dll_list::alloc): Use nt_max_path_buf method instead of local buffer. Store module file name as full NT path, convert using the form_ntname static method. (dll_list::load_after_fork): Call load_after_fork_impl only when reload_on_fork is set. * fork.cc (frok::child): Call dlls.load_after_fork even without need to dynamically load dlls. (frok::parent): Move syscall_printf into the retry loop. --- winsup/cygwin/dll_init.cc | 208 ++++++++++++++++++++++++++++---------- winsup/cygwin/dll_init.h | 20 +++- winsup/cygwin/fork.cc | 28 +++-- 3 files changed, 187 insertions(+), 69 deletions(-) diff --git a/winsup/cygwin/dll_init.cc b/winsup/cygwin/dll_init.cc index 549e5cccd..f94c6698d 100644 --- a/winsup/cygwin/dll_init.cc +++ b/winsup/cygwin/dll_init.cc @@ -30,10 +30,129 @@ extern void __stdcall check_sanity_and_sync (per_process *); dll_list dlls; +WCHAR NO_COPY dll_list::nt_max_path_buffer[NT_MAX_PATH]; + muto dll_list::protect; static bool dll_global_dtors_recorded; +/* We need the in_load_after_fork flag so dll_dllcrt0_1 can decide at fork + time if this is a linked DLL or a dynamically loaded DLL. In either case, + both, cygwin_finished_initializing and in_forkee are true, so they are not + sufficient to discern the situation. */ +static bool NO_COPY in_load_after_fork; + +/* Into ntbuf with ntbufsize, prints name prefixed with "\\??\\" + or "\\??\\UNC" as necessary to form the native NT path name. + Returns the end of the resulting string in ntbuf. + Supports using (a substring of) ntbuf as name argument. */ +PWCHAR dll_list::form_ntname (PWCHAR ntbuf, size_t ntbufsize, PCWCHAR name) +{ + while (true) + { + /* avoid using path_conv here: cygheap might not be + initialized when started from non-cygwin process, + or still might be frozen in_forkee */ + if (name[0] == L'\0' || ntbufsize < 8) + break; + if (name[1] == L':') /* short Win32 drive letter path name */ + { + int winlen = min (ntbufsize - 5, wcslen (name)); + if (ntbuf + 4 != name) + memmove (ntbuf + 4, name, sizeof (*ntbuf) * winlen); + wcsncpy (ntbuf, L"\\??\\", 4); + ntbuf += 4 + winlen; + break; + } + if (!wcsncmp (name, L"\\\\?\\", 4)) /* long Win32 path name */ + { + int winlen = min (ntbufsize - 1, wcslen (name)); + if (ntbuf != name) + memmove (ntbuf, name, sizeof (*ntbuf) * winlen); + ntbuf[1] = L'?'; + ntbuf += winlen; + break; + } + if (!wcsncmp (name, L"\\\\", 2)) /* short Win32 UNC path name */ + { + name += 1; /* skip first backslash */ + int winlen = min (ntbufsize - 8, wcslen (name)); + if (ntbuf + 7 != name) + memmove (ntbuf + 7, name, sizeof (*ntbuf) * winlen); + wcsncpy (ntbuf, L"\\??\\UNC", 7); + ntbuf += 7 + winlen; + break; + } + if (!wcsncmp (name, L"\\??\\", 4)) /* already a long NT path name */ + { + int winlen = min (ntbufsize - 1, wcslen (name)); + if (ntbuf != name) + memmove (ntbuf, name, sizeof (*ntbuf) * winlen); + ntbuf += winlen; + break; + } + system_printf ("WARNING: invalid path name '%W'", name); + break; + } + if (ntbufsize) + *ntbuf = L'\0'; + return ntbuf; +} + +/* Into shortbuf with shortbufsize, prints name with "\\??\\" + or "\\??\\UNC" prefix removed/modified as necessary to form + the short Win32 path name. + Returns the end of the resulting string in shortbuf. + Supports using (a substring of) shortbuf as name argument. */ +PWCHAR +dll_list::form_shortname (PWCHAR shortbuf, size_t shortbufsize, PCWCHAR name) +{ + while (true) + { + /* avoid using path_conv here: cygheap might not be + initialized when started from non-cygwin process, + or still might be frozen in_forkee */ + if (name[0] == L'\0' || shortbufsize < 2) + break; + if (name[0] == L'\\' && + (name[1] == L'\\' || name[1] == L'?') && + name[2] == L'?' && + name[3] == L'\\') /* long Win32 or NT path name */ + name += 4; + if (name[1] == L':') /* short Win32 drive letter path name */ + { + int ntlen = min (shortbufsize - 1, wcslen (name)); + if (shortbuf != name) + memmove (shortbuf, name, sizeof (*shortbuf) * ntlen); + shortbuf += ntlen; + break; + } + if (!wcsncmp (name, L"UNC\\", 4)) /* UNC path name */ + { + name += 3; /* skip "UNC" */ + int winlen = min (shortbufsize - 2, wcslen (name)); + if (shortbuf + 1 != name) + memmove (shortbuf + 1, name, sizeof (*shortbuf) * winlen); + shortbuf[0] = L'\\'; + shortbuf += 1 + winlen; + break; + } + if (!wcsncmp (name, L"\\\\", 2)) /* already a short Win32 UNC path name */ + { + int winlen = min (shortbufsize - 1, wcslen (name)); + if (shortbuf != name) + memmove (shortbuf, name, sizeof (*shortbuf) * winlen); + shortbuf += winlen; + break; + } + system_printf ("WARNING: invalid path name '%W'", name); + break; + } + if (shortbufsize) + *shortbuf = L'\0'; + return shortbuf; +} + /* Run destructors for all DLLs on exit. */ void dll_global_dtors () @@ -148,11 +267,11 @@ dll::init () of dll_list::alloc, as well as the comment preceeding the definition of the in_load_after_fork bool later in the file. */ dll * -dll_list::operator[] (const PWCHAR name) +dll_list::operator[] (PCWCHAR ntname) { dll *d = &start; while ((d = d->next) != NULL) - if (!wcscasecmp (name, d->name)) + if (!wcscasecmp (ntname, d->ntname)) return d; return NULL; @@ -160,7 +279,7 @@ dll_list::operator[] (const PWCHAR name) /* Look for a dll based on the basename. */ dll * -dll_list::find_by_modname (const PWCHAR modname) +dll_list::find_by_modname (PCWCHAR modname) { dll *d = &start; while ((d = d->next) != NULL) @@ -177,58 +296,47 @@ dll * dll_list::alloc (HINSTANCE h, per_process *p, dll_type type) { /* Called under loader lock conditions so this function can't be called - multiple times in parallel. A static buffer is safe. */ - static WCHAR buf[NT_MAX_PATH]; - GetModuleFileNameW (h, buf, NT_MAX_PATH); - PWCHAR name = buf; - if (!wcsncmp (name, L"\\\\?\\", 4)) - { - name += 4; - if (!wcsncmp (name, L"UNC\\", 4)) - { - name += 2; - *name = L'\\'; - } - } - DWORD namelen = wcslen (name); - PWCHAR modname = wcsrchr (name, L'\\') + 1; + multiple times in parallel. The static buffer is safe. */ + PWCHAR ntname = nt_max_path_buf (); + GetModuleFileNameW (h, ntname, NT_MAX_PATH); + PWCHAR modname = form_ntname (ntname, NT_MAX_PATH, ntname); + while (modname > ntname && *(modname - 1) != L'\\') + --modname; guard (true); /* Already loaded? For linked DLLs, only compare the basenames. Linked DLLs are loaded using just the basename and the default DLL search path. The Windows loader picks up the first one it finds. */ - dll *d = (type == DLL_LINK) ? dlls.find_by_modname (modname) : dlls[name]; + dll *d = (type == DLL_LINK) ? dlls.find_by_modname (modname) : dlls[ntname]; if (d) { /* We only get here in the forkee. */ if (d->handle != h) fabort ("%W: Loaded to different address: parent(%p) != child(%p)", - name, d->handle, h); + ntname, d->handle, h); /* If this DLL has been linked against, and the full path differs, try to sanity check if this is the same DLL, just in another path. */ - else if (type == DLL_LINK && wcscasecmp (name, d->name) + else if (type == DLL_LINK && wcscasecmp (ntname, d->ntname) && (d->p.data_start != p->data_start || d->p.data_start != p->data_start || d->p.bss_start != p->bss_start || d->p.bss_end != p->bss_end || d->p.ctors != p->ctors || d->p.dtors != p->dtors)) - fabort ("\nLoaded different DLL with same basename in forked child,\n" + fabort ("\nLoaded different DLL with same basename in forked child,\n" "parent loaded: %W\n" " child loaded: %W\n" "The DLLs differ, so it's not safe to run the forked child.\n" "Make sure to remove the offending DLL before trying again.", - d->name, name); + d->ntname, ntname); d->p = p; } else { - d = (dll *) cmalloc (HEAP_2_DLL, - sizeof (*d) + (namelen * sizeof (*name))); /* Now we've allocated a block of information. Fill it in with the supplied info about this DLL. */ - wcscpy (d->name, name); - d->modname = d->name + (modname - name); + wcscpy (d->ntname, ntname); + d->modname = d->ntname + (modname - ntname); d->handle = h; d->count = 0; /* Reference counting performed in dlopen/dlclose. */ d->has_dtors = true; @@ -473,7 +581,7 @@ dll_list::init () to clobber the dll's target address range because it often overlaps. */ static PVOID -reserve_at (const PWCHAR name, PVOID here, PVOID dll_base, DWORD dll_size) +reserve_at (PCWCHAR name, PVOID here, PVOID dll_base, DWORD dll_size) { DWORD size; MEMORY_BASIC_INFORMATION mb; @@ -502,7 +610,7 @@ reserve_at (const PWCHAR name, PVOID here, PVOID dll_base, DWORD dll_size) /* Release the memory previously allocated by "reserve_at" above. */ static void -release_at (const PWCHAR name, PVOID here) +release_at (PCWCHAR name, PVOID here) { if (!VirtualFree (here, 0, MEM_RELEASE)) fabort ("couldn't release memory %p for '%W' alignment, %E\n", @@ -527,12 +635,6 @@ dll_list::reserve_space () d->modname, d->handle); } -/* We need the in_load_after_fork flag so dll_dllcrt0_1 can decide at fork - time if this is a linked DLL or a dynamically loaded DLL. In either case, - both, cygwin_finished_initializing and in_forkee are true, so they are not - sufficient to discern the situation. */ -static bool NO_COPY in_load_after_fork; - /* Reload DLLs after a fork. Iterates over the list of dynamically loaded DLLs and attempts to load them in the same place as they were loaded in the parent. */ @@ -543,7 +645,8 @@ dll_list::load_after_fork (HANDLE parent) // dll_list::reserve_space(); in_load_after_fork = true; - load_after_fork_impl (parent, dlls.istart (DLL_LOAD), 0); + if (reload_on_fork) + load_after_fork_impl (parent, dlls.istart (DLL_LOAD), 0); in_load_after_fork = false; } @@ -576,33 +679,34 @@ void dll_list::load_after_fork_impl (HANDLE parent, dll* d, int retries) dll's protective reservation from step 1 */ if (!retries && !VirtualFree (d->handle, 0, MEM_RELEASE)) - fabort ("unable to release protective reservation for %W (%p), %E", - d->modname, d->handle); + fabort ("unable to release protective reservation (%p) for %W, %E", + d->handle, d->ntname); - HMODULE h = LoadLibraryExW (d->name, NULL, DONT_RESOLVE_DLL_REFERENCES); + HMODULE h = LoadLibraryExW (buffered_shortname (d->ntname), + NULL, DONT_RESOLVE_DLL_REFERENCES); if (!h) - fabort ("unable to create interim mapping for %W, %E", d->name); + fabort ("unable to create interim mapping for %W, %E", d->ntname); if (h != d->handle) { sigproc_printf ("%W loaded in wrong place: %p != %p", - d->modname, h, d->handle); + d->ntname, h, d->handle); FreeLibrary (h); - PVOID reservation = reserve_at (d->modname, h, + PVOID reservation = reserve_at (d->ntname, h, d->handle, d->image_size); if (!reservation) fabort ("unable to block off %p to prevent %W from loading there", - h, d->modname); + h, d->ntname); if (retries < DLL_RETRY_MAX) load_after_fork_impl (parent, d, retries+1); else fabort ("unable to remap %W to same address as parent (%p) - try running rebaseall", - d->modname, d->handle); + d->ntname, d->handle); /* once the above returns all the dlls are mapped; release the reservation and continue unwinding */ sigproc_printf ("releasing blocked space at %p", reservation); - release_at (d->modname, reservation); + release_at (d->ntname, reservation); return; } } @@ -618,7 +722,7 @@ void dll_list::load_after_fork_impl (HANDLE parent, dll* d, int retries) { if (!VirtualFree (d->handle, 0, MEM_RELEASE)) fabort ("unable to release protective reservation for %W (%p), %E", - d->modname, d->handle); + d->ntname, d->handle); } else { @@ -626,17 +730,19 @@ void dll_list::load_after_fork_impl (HANDLE parent, dll* d, int retries) to ours or we wouldn't have gotten this far */ if (!FreeLibrary (d->handle)) fabort ("unable to unload interim mapping of %W, %E", - d->modname); + d->ntname); } - HMODULE h = LoadLibraryW (d->name); + /* cygwin1.dll - as linked dependency - may reuse the shortname + buffer, even in case of failure: don't reuse shortname later */ + HMODULE h = LoadLibraryW (buffered_shortname (d->ntname)); if (!h) - fabort ("unable to map %W, %E", d->name); + fabort ("unable to map %W, %E", d->ntname); if (h != d->handle) fabort ("unable to map %W to same address as parent: %p != %p", - d->modname, d->handle, h); + d->ntname, d->handle, h); /* Fix OS reference count. */ for (int cnt = 1; cnt < d->count; ++cnt) - LoadLibraryW (d->name); + LoadLibraryW (buffered_shortname (d->ntname)); } } diff --git a/winsup/cygwin/dll_init.h b/winsup/cygwin/dll_init.h index 862ad91b2..4897c420f 100644 --- a/winsup/cygwin/dll_init.h +++ b/winsup/cygwin/dll_init.h @@ -58,7 +58,7 @@ struct dll DWORD image_size; void* preferred_base; PWCHAR modname; - WCHAR name[1]; + WCHAR ntname[1]; /* must be the last data member */ void detach (); int init (); void run_dtors () @@ -79,11 +79,25 @@ class dll_list dll *hold; dll_type hold_type; static muto protect; + /* Use this buffer under loader lock conditions only. */ + static WCHAR NO_COPY nt_max_path_buffer[NT_MAX_PATH]; public: + static PWCHAR form_ntname (PWCHAR ntbuf, size_t bufsize, PCWCHAR name); + static PWCHAR form_shortname (PWCHAR shortbuf, size_t bufsize, PCWCHAR name); + static PWCHAR nt_max_path_buf () + { + return nt_max_path_buffer; + } + static PCWCHAR buffered_shortname (PCWCHAR name) + { + form_shortname (nt_max_path_buffer, NT_MAX_PATH, name); + return nt_max_path_buffer; + } + dll start; int loaded_dlls; int reload_on_fork; - dll *operator [] (const PWCHAR name); + dll *operator [] (PCWCHAR ntname); dll *alloc (HINSTANCE, per_process *, dll_type); dll *find (void *); void detach (void *); @@ -91,7 +105,7 @@ public: void load_after_fork (HANDLE); void reserve_space (); void load_after_fork_impl (HANDLE, dll* which, int retries); - dll *find_by_modname (const PWCHAR name); + dll *find_by_modname (PCWCHAR modname); void populate_deps (dll* d); void topsort (); void topsort_visit (dll* d, bool goto_tail); diff --git a/winsup/cygwin/fork.cc b/winsup/cygwin/fork.cc index 5f775249a..c78e5cf3b 100644 --- a/winsup/cygwin/fork.cc +++ b/winsup/cygwin/fork.cc @@ -175,21 +175,18 @@ frok::child (volatile char * volatile here) if (fixup_shms_after_fork ()) api_fatal ("recreate_shm areas after fork failed"); - /* If we haven't dynamically loaded any dlls, just signal - the parent. Otherwise, load all the dlls, tell the parent - that we're done, and wait for the parent to fill in the. - loaded dlls' data/bss. */ + /* load dynamic dlls, if any */ + dlls.load_after_fork (hParent); + + cygheap->fdtab.fixup_after_fork (hParent); + + /* If we haven't dynamically loaded any dlls, just signal the parent. + Otherwise, tell the parent that we've loaded all the dlls + and wait for the parent to fill in the loaded dlls' data/bss. */ if (!load_dlls) - { - cygheap->fdtab.fixup_after_fork (hParent); - sync_with_parent ("performed fork fixup", false); - } + sync_with_parent ("performed fork fixup", false); else - { - dlls.load_after_fork (hParent); - cygheap->fdtab.fixup_after_fork (hParent); - sync_with_parent ("loaded dlls", true); - } + sync_with_parent ("loaded dlls", true); init_console_handler (myself->ctty > 0); ForceCloseHandle1 (fork_info->forker_finished, forker_finished); @@ -303,8 +300,6 @@ frok::parent (volatile char * volatile stack_here) si.lpReserved2 = (LPBYTE) &ch; si.cbReserved2 = sizeof (ch); - syscall_printf ("CreateProcessW (%W, %W, 0, 0, 1, %y, 0, 0, %p, %p)", - myself->progname, myself->progname, c_flags, &si, &pi); bool locked = __malloc_lock (); /* Remove impersonation */ @@ -315,6 +310,9 @@ frok::parent (volatile char * volatile stack_here) while (1) { + syscall_printf ("CreateProcessW (%W, %W, 0, 0, 1, %y, 0, 0, %p, %p)", + myself->progname, myself->progname, c_flags, &si, &pi); + hchild = NULL; rc = CreateProcessW (myself->progname, /* image to run */ GetCommandLineW (), /* Take same space for command From dac0b6826bef8c637866c60d15ffd8461b361f50 Mon Sep 17 00:00:00 2001 From: Michael Haubenwallner Date: Wed, 7 Dec 2016 11:58:26 +0100 Subject: [PATCH 193/475] dll_list: Track main executable and cygwin1.dll. Even for the main executable and cygwin1.dll store the file name as full NT path. Create the child process using the main executable's file name converted from the full NT path stored before. * dll_init.cc (dll_list::alloc): Search for DLL_SELF type entry with module name like for DLL_LINK, use full NT path to search for DLL_LOAD type only. For DLL_SELF type do not indicate having a destructor to be called. (dll_list::find): Ignore DLL_SELF type entries. (dll_list::init): Ditto. Call track_self method. (dll_list::track_self): New. (dll_list::load_after_fork): Call track_self method. * dll_init.h (enum dll_type): Add DLL_SELF, for the main executable and cygwin1.dll. (struct dll_list): Declare private method track_self. Declare member variable main_executable. * fork.cc (frok::parent): Use ntname from dlls.main_executable to create child process, converted to short path using dll_list::buffered_shortname. --- winsup/cygwin/dll_init.cc | 26 ++++++++++++++++++++------ winsup/cygwin/dll_init.h | 4 ++++ winsup/cygwin/fork.cc | 15 ++++++++++++--- 3 files changed, 36 insertions(+), 9 deletions(-) diff --git a/winsup/cygwin/dll_init.cc b/winsup/cygwin/dll_init.cc index f94c6698d..2204533c6 100644 --- a/winsup/cygwin/dll_init.cc +++ b/winsup/cygwin/dll_init.cc @@ -306,8 +306,9 @@ dll_list::alloc (HINSTANCE h, per_process *p, dll_type type) guard (true); /* Already loaded? For linked DLLs, only compare the basenames. Linked DLLs are loaded using just the basename and the default DLL search path. - The Windows loader picks up the first one it finds. */ - dll *d = (type == DLL_LINK) ? dlls.find_by_modname (modname) : dlls[ntname]; + The Windows loader picks up the first one it finds. + This also applies to cygwin1.dll and the main-executable (DLL_SELF). */ + dll *d = (type != DLL_LOAD) ? dlls.find_by_modname (modname) : dlls[ntname]; if (d) { /* We only get here in the forkee. */ @@ -339,7 +340,8 @@ dll_list::alloc (HINSTANCE h, per_process *p, dll_type type) d->modname = d->ntname + (modname - ntname); d->handle = h; d->count = 0; /* Reference counting performed in dlopen/dlclose. */ - d->has_dtors = true; + /* DLL_SELF dtors (main-executable, cygwin1.dll) are run elsewhere */ + d->has_dtors = type != DLL_SELF; d->p = p; d->ndeps = 0; d->deps = NULL; @@ -526,7 +528,7 @@ dll_list::find (void *retaddr) dll *d = &start; while ((d = d->next)) - if (d->handle == h) + if (d->type != DLL_SELF && d->handle == h) break; return d; } @@ -566,11 +568,22 @@ dll_list::detach (void *retaddr) void dll_list::init () { + track_self (); + /* Walk the dll chain, initializing each dll */ dll *d = &start; dll_global_dtors_recorded = d->next != NULL; while ((d = d->next)) - d->init (); + if (d->type != DLL_SELF) /* linked and early loaded dlls */ + d->init (); +} + +void +dll_list::track_self () +{ + /* for cygwin1.dll and main-executable: maintain hardlinks only */ + alloc (cygwin_hmodule, user_data, DLL_SELF); + main_executable = alloc (GetModuleHandle (NULL), user_data, DLL_SELF); } #define A64K (64 * 1024) @@ -637,7 +650,7 @@ dll_list::reserve_space () /* Reload DLLs after a fork. Iterates over the list of dynamically loaded DLLs and attempts to load them in the same place as they were loaded in the - parent. */ + parent. Updates main-executable and cygwin1.dll tracking. */ void dll_list::load_after_fork (HANDLE parent) { @@ -647,6 +660,7 @@ dll_list::load_after_fork (HANDLE parent) in_load_after_fork = true; if (reload_on_fork) load_after_fork_impl (parent, dlls.istart (DLL_LOAD), 0); + track_self (); in_load_after_fork = false; } diff --git a/winsup/cygwin/dll_init.h b/winsup/cygwin/dll_init.h index 4897c420f..369fc5427 100644 --- a/winsup/cygwin/dll_init.h +++ b/winsup/cygwin/dll_init.h @@ -40,6 +40,7 @@ struct per_module typedef enum { DLL_NONE, + DLL_SELF, /* main-program.exe, cygwin1.dll */ DLL_LINK, DLL_LOAD, DLL_ANY @@ -75,6 +76,8 @@ struct dll class dll_list { + void track_self (); + dll *end; dll *hold; dll_type hold_type; @@ -94,6 +97,7 @@ public: return nt_max_path_buffer; } + dll *main_executable; dll start; int loaded_dlls; int reload_on_fork; diff --git a/winsup/cygwin/fork.cc b/winsup/cygwin/fork.cc index c78e5cf3b..adcd1d7ad 100644 --- a/winsup/cygwin/fork.cc +++ b/winsup/cygwin/fork.cc @@ -175,7 +175,7 @@ frok::child (volatile char * volatile here) if (fixup_shms_after_fork ()) api_fatal ("recreate_shm areas after fork failed"); - /* load dynamic dlls, if any */ + /* load dynamic dlls, if any, re-track main-executable and cygwin1.dll */ dlls.load_after_fork (hParent); cygheap->fdtab.fixup_after_fork (hParent); @@ -310,11 +310,20 @@ frok::parent (volatile char * volatile stack_here) while (1) { + PCWCHAR forking_progname = NULL; + if (dlls.main_executable) + forking_progname = dll_list::buffered_shortname + (dlls.main_executable->ntname); + if (!forking_progname || !*forking_progname) + forking_progname = myself->progname; + syscall_printf ("CreateProcessW (%W, %W, 0, 0, 1, %y, 0, 0, %p, %p)", - myself->progname, myself->progname, c_flags, &si, &pi); + forking_progname, myself->progname, c_flags, &si, &pi); hchild = NULL; - rc = CreateProcessW (myself->progname, /* image to run */ + /* cygwin1.dll may reuse the forking_progname buffer, even + in case of failure: don't reuse forking_progname later */ + rc = CreateProcessW (forking_progname, /* image to run */ GetCommandLineW (), /* Take same space for command line as in parent to make sure child stack is allocated From 8ddb1f60c8bd5a1e6c64b2e713480bc7bc386328 Mon Sep 17 00:00:00 2001 From: Michael Haubenwallner Date: Wed, 7 Dec 2016 11:58:27 +0100 Subject: [PATCH 194/475] forkables: Create forkable hardlinks, yet unused. In preparation to protect fork() against dll- and exe-updates, create hardlinks to the main executable and each loaded dll in subdirectories of /var/run/cygfork/, if that one exists on the NTFS file system. The directory names consist of the user sid, the main executable's NTFS IndexNumber, and the most recent LastWriteTime of all involved binaries (dlls and main executable). Next to the main.exe hardlink we create the empty file main.exe.local to enable dll redirection. The name of the mutex to synchronize hardlink creation/cleanup also is assembled from these directory names, to allow for synchronized cleanup of even orphaned hardlink directories. The hardlink to each dynamically loaded dll goes into another directory, named using the NTFS IndexNumber of the dll's original directory. * Makefile.in (DLL_OFILES): Add forkable.o. * dll_init.h (struct dll): Declare member variables fbi, fii, forkable_ntname. Declare methods nominate_forkable, create_forkable. (struct dll_list): Declare enum forkables_needs. Declare member variables forkables_dirx_size, forkables_dirx_ntname, forkables_mutex_name, forkables_mutex. Declare private methods forkable_ntnamesize, prepare_forkables_nomination, update_forkables_needs, update_forkables, create_forkables, denominate_forkables, close_mutex, try_remove_forkables, set_forkables_inheritance, request_forkables. Declare public static methods ntopenfile, read_fii, read_fbi. Declare public methods release_forkables, cleanup_forkables. Define public inline method setup_forkables. * dll_init.cc (dll_list::alloc): Allocate memory to hold the name of the hardlink in struct dll member forkable_ntname. Initialize struct dll members fbi, fii. (dll_list::load_after_fork): Call release_forkables method. * fork.cc: Rename public fork function to static dofork, add with_forkables as bool pointer parameter. Add new fork function calling dofork. (struct frok): Add bool pointer member with_forkables, add as constructor parameter. (frok::parent): Call dlls.setup_forkables before CreateProcessW, dlls.release_forkables afterwards. * pinfo.cc (pinfo::exit): Call dlls.cleanup_forkables. * syscalls.cc (_unlink_nt): Rename public unlink_nt function to static _unlink_nt, with 'shareable' as additional argument. (unlink_nt): New, wrap _unlink_nt for original behaviour. (unlink_nt_shareable): New, wrap _unlink_nt to keep a binary file still loadable while removing one of its hardlinks. * forkable.cc: New file. Implement static functions mkdirs, rmdirs, rmdirs_synchronized, stat_real_file_once, format_IndexNumber, rootname, sidname, exename, lwtimename. Define static array forkable_nameparts. (struct dll): Implement nominate_forkable, create_forkable. (struct dll_list): Implement static methods ntopenfile, read_fii, read_fbi. Implement forkable_ntnamesize, --- winsup/cygwin/Makefile.in | 1 + winsup/cygwin/dll_init.cc | 18 + winsup/cygwin/dll_init.h | 50 ++ winsup/cygwin/fork.cc | 21 +- winsup/cygwin/forkable.cc | 1095 +++++++++++++++++++++++++++++++++++++ winsup/cygwin/pinfo.cc | 3 + winsup/cygwin/syscalls.cc | 24 +- 7 files changed, 1207 insertions(+), 5 deletions(-) create mode 100644 winsup/cygwin/forkable.cc diff --git a/winsup/cygwin/Makefile.in b/winsup/cygwin/Makefile.in index c14eea32d..b687d922d 100644 --- a/winsup/cygwin/Makefile.in +++ b/winsup/cygwin/Makefile.in @@ -313,6 +313,7 @@ DLL_OFILES:= \ flock.o \ fnmatch.o \ fork.o \ + forkable.o \ fts.o \ ftw.o \ getentropy.o \ diff --git a/winsup/cygwin/dll_init.cc b/winsup/cygwin/dll_init.cc index 2204533c6..90b39408b 100644 --- a/winsup/cygwin/dll_init.cc +++ b/winsup/cygwin/dll_init.cc @@ -300,6 +300,7 @@ dll_list::alloc (HINSTANCE h, per_process *p, dll_type type) PWCHAR ntname = nt_max_path_buf (); GetModuleFileNameW (h, ntname, NT_MAX_PATH); PWCHAR modname = form_ntname (ntname, NT_MAX_PATH, ntname); + DWORD ntnamelen = modname - ntname; while (modname > ntname && *(modname - 1) != L'\\') --modname; @@ -334,6 +335,12 @@ dll_list::alloc (HINSTANCE h, per_process *p, dll_type type) } else { + size_t forkntsize = forkable_ntnamesize (type, ntname, modname); + + /* FIXME: Change this to new at some point. */ + d = (dll *) cmalloc (HEAP_2_DLL, sizeof (*d) + + ((ntnamelen + forkntsize) * sizeof (*ntname))); + /* Now we've allocated a block of information. Fill it in with the supplied info about this DLL. */ wcscpy (d->ntname, ntname); @@ -348,6 +355,15 @@ dll_list::alloc (HINSTANCE h, per_process *p, dll_type type) d->image_size = ((pefile*)h)->optional_hdr ()->SizeOfImage; d->preferred_base = (void*) ((pefile*)h)->optional_hdr()->ImageBase; d->type = type; + d->fbi.FileAttributes = INVALID_FILE_ATTRIBUTES; + d->fii.IndexNumber.QuadPart = -1LL; + if (!forkntsize) + d->forkable_ntname = NULL; + else + { + d->forkable_ntname = d->ntname + ntnamelen + 1; + *d->forkable_ntname = L'\0'; + } append (d); if (type == DLL_LOAD) loaded_dlls++; @@ -654,6 +670,8 @@ dll_list::reserve_space () void dll_list::load_after_fork (HANDLE parent) { + release_forkables (); + // moved to frok::child for performance reasons: // dll_list::reserve_space(); diff --git a/winsup/cygwin/dll_init.h b/winsup/cygwin/dll_init.h index 369fc5427..62739f729 100644 --- a/winsup/cygwin/dll_init.h +++ b/winsup/cygwin/dll_init.h @@ -59,9 +59,15 @@ struct dll DWORD image_size; void* preferred_base; PWCHAR modname; + FILE_BASIC_INFORMATION fbi; + FILE_INTERNAL_INFORMATION fii; + PWCHAR forkable_ntname; WCHAR ntname[1]; /* must be the last data member */ + void detach (); int init (); + void nominate_forkable (PCWCHAR); + bool create_forkable (); void run_dtors () { if (has_dtors) @@ -76,7 +82,32 @@ struct dll class dll_list { + /* forkables */ + enum + { + forkables_unknown, + forkables_impossible, + forkables_disabled, + forkables_needless, + forkables_needed, + forkables_created, + } + forkables_needs; + DWORD forkables_dirx_size; + PWCHAR forkables_dirx_ntname; + PWCHAR forkables_mutex_name; + HANDLE forkables_mutex; void track_self (); + size_t forkable_ntnamesize (dll_type, PCWCHAR fullntname, PCWCHAR modname); + void prepare_forkables_nomination (); + void update_forkables_needs (); + bool update_forkables (); + bool create_forkables (); + void denominate_forkables (); + bool close_mutex (); + void try_remove_forkables (PWCHAR dirbuf, size_t dirlen, size_t dirbufsize); + void set_forkables_inheritance (bool); + void request_forkables (); dll *end; dll *hold; @@ -85,6 +116,11 @@ class dll_list /* Use this buffer under loader lock conditions only. */ static WCHAR NO_COPY nt_max_path_buffer[NT_MAX_PATH]; public: + static HANDLE ntopenfile (PCWCHAR ntname, NTSTATUS *pstatus = NULL, + ULONG openopts = 0, ACCESS_MASK access = 0, + HANDLE rootDir = NULL); + static bool read_fii (HANDLE fh, PFILE_INTERNAL_INFORMATION pfii); + static bool read_fbi (HANDLE fh, PFILE_BASIC_INFORMATION pfbi); static PWCHAR form_ntname (PWCHAR ntbuf, size_t bufsize, PCWCHAR name); static PWCHAR form_shortname (PWCHAR shortbuf, size_t bufsize, PCWCHAR name); static PWCHAR nt_max_path_buf () @@ -115,6 +151,20 @@ public: void topsort_visit (dll* d, bool goto_tail); void append (dll* d); + void release_forkables (); + void cleanup_forkables (); + bool setup_forkables (bool with_forkables) + { + if (forkables_needs == forkables_impossible) + return true; /* short cut to not retry fork */ + /* Once used, always use forkables in current process chain. */ + if (forkables_needs != forkables_unknown) + with_forkables = true; + if (with_forkables) + request_forkables (); + return with_forkables; + } + dll *inext () { while ((hold = hold->next)) diff --git a/winsup/cygwin/fork.cc b/winsup/cygwin/fork.cc index adcd1d7ad..f929a85c0 100644 --- a/winsup/cygwin/fork.cc +++ b/winsup/cygwin/fork.cc @@ -30,8 +30,13 @@ details. */ /* FIXME: Once things stabilize, bump up to a few minutes. */ #define FORK_WAIT_TIMEOUT (300 * 1000) /* 300 seconds */ +static int dofork (bool *with_forkables); class frok { + frok (bool *forkables) + : with_forkables (forkables) + {} + bool *with_forkables; bool load_dlls; child_info_fork ch; const char *errmsg; @@ -41,7 +46,7 @@ class frok int __stdcall parent (volatile char * volatile here); int __stdcall child (volatile char * volatile here); bool error (const char *fmt, ...); - friend int fork (); + friend int dofork (bool *with_forkables); }; static void @@ -308,6 +313,8 @@ frok::parent (volatile char * volatile stack_here) ch.refresh_cygheap (); ch.prefork (); /* set up process tracking pipes. */ + *with_forkables = dlls.setup_forkables (*with_forkables); + while (1) { PCWCHAR forking_progname = NULL; @@ -344,6 +351,7 @@ frok::parent (volatile char * volatile stack_here) { this_errno = geterrno_from_win_error (); error ("CreateProcessW failed for '%W'", myself->progname); + dlls.release_forkables (); memset (&pi, 0, sizeof (pi)); goto cleanup; } @@ -357,6 +365,8 @@ frok::parent (volatile char * volatile stack_here) CloseHandle (pi.hThread); hchild = pi.hProcess; + dlls.release_forkables (); + /* Protect the handle but name it similarly to the way it will be called in subproc handling. */ ProtectHandle1 (hchild, childhProc); @@ -529,7 +539,14 @@ cleanup: extern "C" int fork () { - frok grouped; + bool with_forkables = true; + return dofork (&with_forkables); +} + +static int +dofork (bool *with_forkables) +{ + frok grouped (with_forkables); debug_printf ("entering"); grouped.load_dlls = 0; diff --git a/winsup/cygwin/forkable.cc b/winsup/cygwin/forkable.cc new file mode 100644 index 000000000..cc28f9f4f --- /dev/null +++ b/winsup/cygwin/forkable.cc @@ -0,0 +1,1095 @@ +/* forkable.cc + + Copyright 2015 Red Hat, Inc. + +This software is a copyrighted work licensed under the terms of the +Cygwin license. Please consult the file "CYGWIN_LICENSE" for +details. */ + +#include "winsup.h" +#include "cygerrno.h" +#include "perprocess.h" +#include "sync.h" +#include "dll_init.h" +#include "environ.h" +#include "security.h" +#include "path.h" +#include "fhandler.h" +#include "dtable.h" +#include "cygheap.h" +#include "pinfo.h" +#include "shared_info.h" +#include "child_info.h" +#include "cygtls.h" +#include "exception.h" +#include +#include +#include +#include + +/* Allow concurrent processes to use the same dll or exe + * via their hardlink while we delete our hardlink. */ +extern NTSTATUS unlink_nt_shareable (path_conv &pc); + +#define MUTEXSEP L"@" +#define PATHSEP L"\\" + +/* Create the lastsepcount directories found in ntdirname, where + counting is done along path separators (including trailing ones). + Returns true when these directories exist afterwards, false otherways. + The ntdirname is used for the path-splitting. */ +static bool +mkdirs (PWCHAR ntdirname, int lastsepcount) +{ + bool success = true; + int i = lastsepcount; + for (--i; i > 0; --i) + { + PWCHAR lastsep = wcsrchr (ntdirname, L'\\'); + if (!lastsep) + break; + *lastsep = L'\0'; + } + + for (++i; i <= lastsepcount; ++i) + { + if (success && (i == 0 || wcslen (wcsrchr (ntdirname, L'\\')) > 1)) + { + UNICODE_STRING dn; + RtlInitUnicodeString (&dn, ntdirname); + OBJECT_ATTRIBUTES oa; + InitializeObjectAttributes (&oa, &dn, 0, NULL, + sec_none_nih.lpSecurityDescriptor); + HANDLE dh = NULL; + NTSTATUS status; + IO_STATUS_BLOCK iosb; + status = NtCreateFile (&dh, GENERIC_READ | SYNCHRONIZE, + &oa, &iosb, NULL, FILE_ATTRIBUTE_NORMAL, + FILE_SHARE_READ | FILE_SHARE_WRITE, + FILE_CREATE, + FILE_DIRECTORY_FILE + | FILE_SYNCHRONOUS_IO_NONALERT, + NULL, 0); + if (NT_SUCCESS(status)) + NtClose (dh); + else if (status != STATUS_OBJECT_NAME_COLLISION) /* already exists */ + success = false; + debug_printf ("%y = NtCreateFile (%p, dir %W)", status, dh, ntdirname); + } + if (i < lastsepcount) + ntdirname[wcslen (ntdirname)] = L'\\'; /* restore original value */ + } + return success; +} + +/* Recursively remove the directory specified in ntmaxpathbuf, + using ntmaxpathbuf as the buffer to form subsequent filenames. */ +static void +rmdirs (WCHAR ntmaxpathbuf[NT_MAX_PATH]) +{ + PWCHAR basebuf = wcsrchr (ntmaxpathbuf, L'\\'); /* find last pathsep */ + if (basebuf && *(basebuf+1)) + basebuf += wcslen (basebuf); /* last pathsep is not trailing one */ + if (!basebuf) + basebuf = ntmaxpathbuf + wcslen (ntmaxpathbuf); + *basebuf = L'\0'; /* kill trailing pathsep, if any */ + + NTSTATUS status; + HANDLE hdir = dll_list::ntopenfile (ntmaxpathbuf, &status, + FILE_DIRECTORY_FILE | + FILE_DELETE_ON_CLOSE); + if (hdir == INVALID_HANDLE_VALUE) + return; + + *basebuf++ = L'\\'; /* (re-)add trailing pathsep */ + + struct { + FILE_DIRECTORY_INFORMATION fdi; + WCHAR buf[NAME_MAX]; + } fdibuf; + IO_STATUS_BLOCK iosb; + + while (NT_SUCCESS (status = NtQueryDirectoryFile (hdir, NULL, NULL, NULL, + &iosb, + &fdibuf, sizeof (fdibuf), + FileDirectoryInformation, + FALSE, NULL, FALSE))) + { + PFILE_DIRECTORY_INFORMATION pfdi = &fdibuf.fdi; + while (true) + { + int namelen = pfdi->FileNameLength / sizeof (WCHAR); + wcsncpy (basebuf, pfdi->FileName, namelen); + basebuf[namelen] = L'\0'; + + if (pfdi->FileAttributes & FILE_ATTRIBUTE_DIRECTORY) + { + if (wcscmp (basebuf, L".") && wcscmp (basebuf, L"..")) + rmdirs (ntmaxpathbuf); + } + else + { + UNICODE_STRING fn; + RtlInitUnicodeString (&fn, ntmaxpathbuf); + + path_conv pc (&fn); + unlink_nt_shareable (pc); /* move to bin */ + } + + if (!pfdi->NextEntryOffset) + break; + pfdi = (PFILE_DIRECTORY_INFORMATION)((caddr_t)pfdi + + pfdi->NextEntryOffset); + } + } + if (status != STATUS_NO_MORE_FILES) + debug_printf ("%y = NtQueryDirectoryFile (%p, io %y, info %d)", + status, hdir, iosb.Status, iosb.Information); + + CloseHandle (hdir); +} + +/* Get the NTFS file id for the real file behind the dll handle. + As we may open a wrong (or no) file while the dll is renamed, + we retry until we get the same file id a second time. + We use NtQueryVirtualMemory (MemorySectionName) for the current + file name, as GetModuleFileNameW () yields the as-loaded name. + While we have the file handle open, also read the attributes. + NOTE: Uses dll_list::nt_max_path_buf (). */ +static bool +stat_real_file_once (dll *d) +{ + if (d->fbi.FileAttributes != INVALID_FILE_ATTRIBUTES) + return true; + + tmp_pathbuf tp; + + HANDLE fhandle = INVALID_HANDLE_VALUE; + NTSTATUS status, fstatus; + PMEMORY_SECTION_NAME pmsi1; + MEMORY_SECTION_NAME msi2; + pmsi1 = (PMEMORY_SECTION_NAME) dll_list::nt_max_path_buf (); + RtlInitEmptyUnicodeString (&msi2.SectionFileName, tp.w_get (), 65535); + + /* Retry opening the real file name until that does not change any more. */ + status = NtQueryVirtualMemory (NtCurrentProcess (), d->handle, + MemorySectionName, pmsi1, 65536, NULL); + while (NT_SUCCESS (status) && + !RtlEqualUnicodeString (&msi2.SectionFileName, + &pmsi1->SectionFileName, FALSE)) + { + RtlCopyUnicodeString (&msi2.SectionFileName, &pmsi1->SectionFileName); + if (fhandle != INVALID_HANDLE_VALUE) + NtClose (fhandle); + pmsi1->SectionFileName.Buffer[pmsi1->SectionFileName.Length] = L'\0'; + fhandle = dll_list::ntopenfile (pmsi1->SectionFileName.Buffer, &fstatus); + status = NtQueryVirtualMemory (NtCurrentProcess (), d->handle, + MemorySectionName, pmsi1, 65536, NULL); + } + if (!NT_SUCCESS (status)) + system_printf ("WARNING: Unable (ntstatus %y) to query real file for %W", + status, d->ntname); + else if (fhandle == INVALID_HANDLE_VALUE) + system_printf ("WARNING: Unable (ntstatus %y) to open real file for %W", + fstatus, d->ntname); + if (fhandle == INVALID_HANDLE_VALUE) + return false; + + if (!dll_list::read_fii (fhandle, &d->fii) || + !dll_list::read_fbi (fhandle, &d->fbi)) + system_printf ("WARNING: Unable to read real file attributes for %W", + pmsi1->SectionFileName.Buffer); + + NtClose (fhandle); + return d->fbi.FileAttributes != INVALID_FILE_ATTRIBUTES; +} + +/* easy use of NtOpenFile */ +HANDLE +dll_list::ntopenfile (PCWCHAR ntname, NTSTATUS *pstatus, ULONG openopts, + ACCESS_MASK access, HANDLE rootDir) +{ + NTSTATUS status; + if (!pstatus) + pstatus = &status; + + UNICODE_STRING fn; + if (openopts & FILE_OPEN_BY_FILE_ID) + RtlInitCountedUnicodeString (&fn, ntname, 8); + else + RtlInitUnicodeString (&fn, ntname); + + OBJECT_ATTRIBUTES oa; + InitializeObjectAttributes (&oa, &fn, 0, rootDir, NULL); + + access |= FILE_READ_ATTRIBUTES; + if (openopts & FILE_DELETE_ON_CLOSE) + access |= DELETE; + if (openopts & FILE_DIRECTORY_FILE) + access |= FILE_LIST_DIRECTORY; + else + openopts |= FILE_NON_DIRECTORY_FILE; + + access |= SYNCHRONIZE; + openopts |= FILE_SYNCHRONOUS_IO_NONALERT; + + HANDLE fh = INVALID_HANDLE_VALUE; + ULONG share = FILE_SHARE_VALID_FLAGS; + IO_STATUS_BLOCK iosb; + *pstatus = NtOpenFile (&fh, access, &oa, &iosb, share, openopts); + if (openopts & FILE_OPEN_BY_FILE_ID) + debug_printf ("%y = NtOpenFile (%p, a %xh, sh %xh, o %xh, io %y, by id %llX)", + *pstatus, fh, access, share, openopts, iosb.Status, *(LONGLONG*)fn.Buffer); + else + debug_printf ("%y = NtOpenFile (%p, a %xh, sh %xh, o %xh, io %y, '%W')", + *pstatus, fh, access, share, openopts, iosb.Status, fn.Buffer); + + return NT_SUCCESS(*pstatus) ? fh : INVALID_HANDLE_VALUE; +} + +bool +dll_list::read_fii (HANDLE fh, PFILE_INTERNAL_INFORMATION pfii) +{ + pfii->IndexNumber.QuadPart = -1LL; + + NTSTATUS status; + IO_STATUS_BLOCK iosb; + status = NtQueryInformationFile (fh, &iosb, + pfii, sizeof (*pfii), + FileInternalInformation); + if (!NT_SUCCESS (status)) + { + system_printf ("WARNING: %y = NtQueryInformationFile (%p," + " InternalInfo, io.Status %y)", + status, fh, iosb.Status); + pfii->IndexNumber.QuadPart = -1LL; + return false; + } + return true; +} + +bool +dll_list::read_fbi (HANDLE fh, PFILE_BASIC_INFORMATION pfbi) +{ + pfbi->FileAttributes = INVALID_FILE_ATTRIBUTES; + pfbi->LastWriteTime.QuadPart = -1LL; + + NTSTATUS status; + IO_STATUS_BLOCK iosb; + status = NtQueryInformationFile (fh, &iosb, + pfbi, sizeof (*pfbi), + FileBasicInformation); + if (!NT_SUCCESS (status)) + { + system_printf ("WARNING: %y = NtQueryInformationFile (%p," + " BasicInfo, io.Status %y)", + status, fh, iosb.Status); + pfbi->FileAttributes = INVALID_FILE_ATTRIBUTES; + pfbi->LastWriteTime.QuadPart = -1LL; + return false; + } + return true; +} + +/* Into buf if not NULL, write the IndexNumber in pli. + Return the number of characters (that would be) written. */ +static int +format_IndexNumber (PWCHAR buf, ssize_t bufsize, LARGE_INTEGER const *pli) +{ + if (!buf) + return 16; + if (bufsize >= 0 && bufsize <= 16) + return 0; + return __small_swprintf (buf, L"%016X", pli->QuadPart); +} + +/* Into buf if not NULL, write the ntname of cygwin installation_root. + Return the number of characters (that would be) written. */ +static int +rootname (PWCHAR buf, ssize_t bufsize) +{ + UNICODE_STRING &cygroot = cygheap->installation_root; + if (!buf) + return 6 /* "\??\UN" */ + cygroot.Length / sizeof (WCHAR); + return dll_list::form_ntname (buf, bufsize, cygroot.Buffer) - buf; +} + +/* Into buf if not NULL, write the string representation of current user sid. + Return the number of characters (that would be) written. */ +static int +sidname (PWCHAR buf, ssize_t bufsize) +{ + if (!buf) + return 128; + if (bufsize >= 0 && bufsize <= 128) + return 0; + UNICODE_STRING sid; + WCHAR sidbuf[128+1]; + RtlInitEmptyUnicodeString (&sid, sidbuf, sizeof (sidbuf)); + RtlConvertSidToUnicodeString (&sid, cygheap->user.sid (), FALSE); + return wcpcpy (buf, sid.Buffer) - buf; +} + +/* Into buf if not NULL, write the IndexNumber of the main executable. + Return the number of characters (that would be) written. */ +static int +exename (PWCHAR buf, ssize_t bufsize) +{ + if (!buf) + return format_IndexNumber (NULL, bufsize, NULL); + dll *d = dlls.main_executable; + return format_IndexNumber (buf, bufsize, &d->fii.IndexNumber); +} + +/* Into buf if not NULL, write the newest dll's LastWriteTime. + Return the number of characters (that would be) written. */ +static int +lwtimename (PWCHAR buf, ssize_t bufsize) +{ + if (!buf) + return sizeof (LARGE_INTEGER) * 2; + if (bufsize >= 0 && bufsize <= (int)sizeof (LARGE_INTEGER) * 2) + return 0; + + LARGE_INTEGER newest = { 0 }; + /* Need by-handle-file-information for _all_ loaded dlls, + as most recent ctime forms the hardlinks directory. */ + dll *d = &dlls.start; + while ((d = d->next)) + { + /* LastWriteTime more properly tells the last file-content modification + time, because a newly created hardlink may have a different + CreationTime compared to the original file. */ + if (d->fbi.LastWriteTime.QuadPart > newest.QuadPart) + newest = d->fbi.LastWriteTime; + } + + return __small_swprintf (buf, L"%016X", newest); +} + +struct namepart { + PCWCHAR text; /* used when no pathfunc, description otherwise */ + int (*textfunc)(PWCHAR buf, ssize_t bufsize); + bool mutex_from_dir; /* on path-separators add mutex-separator */ + bool create_dir; +}; +/* mutex name is formed along dir names */ +static namepart NO_COPY_RO const +forkable_nameparts[] = { + /* text textfunc mutex_from_dir create */ + { L"", rootname, false, false, }, + { L"\\var\\run\\", NULL, false, false, }, + { L"cygfork", NULL, true, false, }, + { L"", sidname, true, true, }, + { L"", exename, false, false, }, + { MUTEXSEP, NULL, false, false, }, + { L"", lwtimename, true, true, }, + + { NULL, NULL }, +}; + +/* Nominate the hardlink to an individual DLL inside dirx_name, + that ends with the path separator (hence the "x" varname). + With NULL as dirx_name, never nominate the hardlink any more. + With "" as dirx_name, denominate the hardlink. */ +void +dll::nominate_forkable (PCWCHAR dirx_name) +{ + if (!dirx_name) + { + debug_printf ("type %d disable %W", type, ntname); + forkable_ntname = NULL; /* never create a hardlink for this dll */ + } + + if (!forkable_ntname) + return; + + PWCHAR next = wcpcpy (forkable_ntname, dirx_name); + + if (!*forkable_ntname) + return; /* denominate */ + + if (type < DLL_LOAD) + wcpcpy (next, modname); + else + { + /* Avoid lots of extra directories for loaded dll's: + * mangle full path into one single directory name, + * just keep original filename intact. The original + * filename is necessary to serve as linked + * dependencies of dynamically loaded dlls. */ + PWCHAR lastpathsep = wcsrchr (ntname, L'\\'); + if (!lastpathsep) + { + forkable_ntname = NULL; + return; + } + *lastpathsep = L'\0'; + HANDLE fh = dll_list::ntopenfile (ntname, NULL, FILE_DIRECTORY_FILE); + *lastpathsep = L'\\'; + + FILE_INTERNAL_INFORMATION fii = { 0 }; + if (fh != INVALID_HANDLE_VALUE) + { + dll_list::read_fii (fh, &fii); + NtClose (fh); + } + next += format_IndexNumber (next, -1, &fii.IndexNumber); + wcpcpy (next, lastpathsep); + } +} + +/* Create the nominated hardlink for one indivitual dll, + inside another subdirectory when dynamically loaded. */ +bool +dll::create_forkable () +{ + if (!forkable_ntname || !*forkable_ntname) + return true; /* disabled */ + + PWCHAR ntname = forkable_ntname; + + PWCHAR last = NULL; + bool success = true; + if (type >= DLL_LOAD) + { + last = wcsrchr (ntname, L'\\'); + if (!last) + return false; + *last = L'\0'; + success = mkdirs (ntname, 1); + *last = L'\\'; + if (!success) + return false; + } + + /* open device as parent handle for FILE_OPEN_BY_FILE_ID */ + PWCHAR devname = dll_list::nt_max_path_buf (); + PWCHAR n = ntname; + PWCHAR d = devname; + int pathseps = 0; + while (*n) + { + if (*d == L'\\' && ++pathseps > 4) + break; // "\\??\\UNC\\server\\share" + *d = *n++; + if (*d++ == L':') + break; // "\\??\\C:" + } + *d = L'\0'; + + HANDLE devhandle = dll_list::ntopenfile (devname); + if (devhandle == INVALID_HANDLE_VALUE) + return false; /* impossible */ + + HANDLE fh = dll_list::ntopenfile ((PCWCHAR)&fii.IndexNumber, NULL, + FILE_OPEN_BY_FILE_ID, + FILE_WRITE_ATTRIBUTES, + devhandle); + NtClose (devhandle); + if (fh == INVALID_HANDLE_VALUE) + return false; /* impossible */ + + int ntlen = wcslen (ntname); + int bufsize = sizeof (FILE_LINK_INFORMATION) + ntlen * sizeof (*ntname); + PFILE_LINK_INFORMATION pfli = (PFILE_LINK_INFORMATION) alloca (bufsize); + + wcscpy (pfli->FileName, ntname); + + pfli->FileNameLength = ntlen * sizeof (*ntname); + pfli->ReplaceIfExists = FALSE; /* allow concurrency */ + pfli->RootDirectory = NULL; + + IO_STATUS_BLOCK iosb; + NTSTATUS status = NtSetInformationFile (fh, &iosb, pfli, bufsize, + FileLinkInformation); + NtClose (fh); + debug_printf ("%y = NtSetInformationFile (%p, FileLink %W, iosb.Status %y)", + status, fh, pfli->FileName, iosb.Status); + if (NT_SUCCESS (status) || status == STATUS_OBJECT_NAME_COLLISION) + /* We've not found a performant way yet to protect fork against updates + to main executables and/or dlls that do not reside on the same NTFS + filesystem as the /var/run/cygfork/ directory. + But as long as the main executable can be hardlinked, dll redirection + works for any other hardlink-able dll, while non-hardlink-able dlls + are used from their original location. */ + return true; + + return false; +} + +/* return the number of characters necessary to store one forkable name */ +size_t +dll_list::forkable_ntnamesize (dll_type type, PCWCHAR fullntname, PCWCHAR modname) +{ + if (forkables_needs == forkables_impossible) + return 0; + + if (!forkables_dirx_size) + { + DWORD forkables_mutex_size = 0; + bool needsep = false; + for (namepart const *part = forkable_nameparts; part->text; ++part) + { + if (needsep) + { + forkables_dirx_size += wcslen (PATHSEP); + forkables_mutex_size += wcslen (MUTEXSEP); + } + needsep = part->mutex_from_dir; + int len = 0; + if (part->textfunc) + len = part->textfunc (NULL, 0); + else + len = wcslen (part->text); + forkables_dirx_size += len; + forkables_mutex_size += len; + } + /* trailing path sep */ + forkables_dirx_size += wcslen (PATHSEP); + /* trailing zeros */ + ++forkables_dirx_size; + ++forkables_mutex_size; + + /* allocate here, to avoid cygheap size changes during fork */ + forkables_dirx_ntname = (PWCHAR) cmalloc (HEAP_2_DLL, + (forkables_dirx_size + forkables_mutex_size) * + sizeof (*forkables_dirx_ntname)); + *forkables_dirx_ntname = L'\0'; + + forkables_mutex_name = forkables_dirx_ntname + forkables_dirx_size; + *forkables_mutex_name = L'\0'; + } + + size_t ret = forkables_dirx_size; + if (type >= DLL_LOAD) + ret += format_IndexNumber (NULL, -1, NULL) + 1; /* one more directory */ + return ret + wcslen (modname); +} + +/* Prepare top-level names necessary to nominate individual DLL hardlinks, + eventually releasing/removing previous forkable hardlinks. */ +void +dll_list::prepare_forkables_nomination () +{ + if (!forkables_dirx_ntname) + return; + + dll *d = &dlls.start; + while ((d = d->next)) + stat_real_file_once (d); /* uses nt_max_path_buf () */ + + PWCHAR pbuf = nt_max_path_buf (); + + bool needsep = false; + bool domutex = false; + namepart const *part; + for (part = forkable_nameparts; part->text; ++part) + { + if (part->mutex_from_dir) + domutex = true; /* mutex naming starts with first mutex_from_dir */ + if (!domutex) + continue; + if (needsep) + pbuf += __small_swprintf (pbuf, L"%W", MUTEXSEP); + needsep = part->mutex_from_dir; + if (part->textfunc) + pbuf += part->textfunc (pbuf, -1); + else + pbuf += __small_swprintf (pbuf, L"%W", part->text); + } + + if (!wcscmp (forkables_mutex_name, nt_max_path_buf ())) + return; /* nothing changed */ + + if (*forkables_mutex_name && + wcscmp (forkables_mutex_name, nt_max_path_buf ())) + { + /* The mutex name has changed since last fork and we either have + dlopen'ed a more recent or dlclose'd the most recent dll, + so we will not use the current forkable hardlinks any more. + Removing from the file system is done later, upon exit. */ + close_mutex (); + denominate_forkables (); + } + wcscpy (forkables_mutex_name, nt_max_path_buf ()); + + pbuf = forkables_dirx_ntname; + needsep = false; + for (namepart const *part = forkable_nameparts; part->text; ++part) + { + if (needsep) + pbuf += __small_swprintf (pbuf, L"%W", PATHSEP); + needsep = part->mutex_from_dir; + if (part->textfunc) + pbuf += part->textfunc (pbuf, -1); + else + pbuf += __small_swprintf (pbuf, L"%W", part->text); + } + pbuf += __small_swprintf (pbuf, L"%W", PATHSEP); + + debug_printf ("forkables dir %W", forkables_dirx_ntname); + debug_printf ("forkables mutex %W", forkables_mutex_name); +} + +/* Test if creating hardlinks is necessary. If creating hardlinks is possible + in general, each individual dll is tested if its previously created + hardlink (if any, or the original file) still is the same. + Testing is protected against hardlink removal by concurrent processes. */ +void +dll_list::update_forkables_needs () +{ + dll *d; + + if (forkables_needs == forkables_unknown) + { + /* check if filesystem of forkables dir is NTFS */ + PWCHAR pbuf = nt_max_path_buf (); + for (namepart const *part = forkable_nameparts; part->text; ++part) + { + if (part->mutex_from_dir) + break; /* leading non-mutex-naming dirs, must exist anyway */ + if (part->textfunc) + pbuf += part->textfunc (pbuf, -1); + else + pbuf += __small_swprintf (pbuf, L"%W", part->text); + } + + UNICODE_STRING fn; + RtlInitUnicodeString (&fn, nt_max_path_buf ()); + + fs_info fsi; + if (fsi.update (&fn, NULL) && +/* FIXME: !fsi.is_readonly () && */ + fsi.is_ntfs ()) + forkables_needs = forkables_disabled; /* check directory itself */ + else + { + debug_printf ("impossible, not on NTFS %W", fn.Buffer); + forkables_needs = forkables_impossible; + } + } + + if (forkables_needs == forkables_impossible) + return; /* we have not created any hardlink, nothing to clean up */ + + if (forkables_needs == forkables_disabled || + forkables_needs == forkables_needless || + forkables_needs == forkables_created) + { + /* (re-)check existence of forkables dir */ + PWCHAR pbuf = nt_max_path_buf (); + for (namepart const *part = forkable_nameparts; part->text; ++part) + { + if (part->textfunc) + pbuf += part->textfunc (pbuf, -1); + else + pbuf += __small_swprintf (pbuf, L"%W", part->text); + if (part->mutex_from_dir) + break; /* up to first mutex-naming dir */ + } + pbuf = nt_max_path_buf (); + + HANDLE dh = ntopenfile (pbuf, NULL, FILE_DIRECTORY_FILE); + if (dh != INVALID_HANDLE_VALUE) + { + NtClose (dh); + if (forkables_needs == forkables_disabled) + forkables_needs = forkables_needless; + } + else if (forkables_needs != forkables_disabled) + { + debug_printf ("disabled, disappearing %W", pbuf); + close_mutex (); + denominate_forkables (); + forkables_needs = forkables_disabled; + } + else + debug_printf ("disabled, missing %W", pbuf); + } + + if (forkables_needs == forkables_disabled) + return; + + if (forkables_needs == forkables_created) + { + /* already have created hardlinks in this process, ... */ + forkables_needs = forkables_needless; + d = &start; + while ((d = d->next) != NULL) + if (d->forkable_ntname && !*d->forkable_ntname) + { + /* ... but another dll was loaded since last fork */ + debug_printf ("needed, since last fork loaded %W", d->ntname); + forkables_needs = forkables_needed; + break; + } + } + + if (forkables_needs > forkables_needless) + return; /* no need to check anything else */ + + if (forkables_needs != forkables_needless) + { + /* paranoia */ + system_printf ("WARNING: invalid forkables_needs value %d", + forkables_needs); + return; + } + + forkables_needs = forkables_needed; +} + +/* Create the nominated forkable hardlinks and directories as necessary, + mutex-protected to avoid concurrent processes removing them. */ +bool +dll_list::update_forkables () +{ + /* existence of mutex indicates that we use these hardlinks */ + if (!forkables_mutex) + { + /* neither my parent nor myself did have need for hardlinks yet */ + forkables_mutex = CreateMutexW (&sec_none, FALSE, + forkables_mutex_name); + debug_printf ("%p = CreateMutexW (%W): %E", + forkables_mutex, forkables_mutex_name); + if (!forkables_mutex) + return false; + + /* Make sure another process does not rmdirs_synchronized () */ + debug_printf ("WFSO (%p, %W, inf)...", + forkables_mutex, forkables_mutex_name); + DWORD ret = WaitForSingleObject (forkables_mutex, INFINITE); + debug_printf ("%u = WFSO (%p, %W)", + ret, forkables_mutex, forkables_mutex_name); + switch (ret) + { + case WAIT_OBJECT_0: + case WAIT_ABANDONED: + break; + default: + system_printf ("cannot wait for mutex %W: %E", + forkables_mutex_name); + return false; + } + + BOOL bret = ReleaseMutex (forkables_mutex); + debug_printf ("%d = ReleaseMutex (%p, %W)", + bret, forkables_mutex, forkables_mutex_name); + } + + return create_forkables (); +} + +/* Create the nominated forkable hardlinks and directories as necessary, + as well as the .local file for dll-redirection. */ +bool +dll_list::create_forkables () +{ + bool success = true; + + int lastsepcount = 1; /* we have trailing pathsep */ + for (namepart const *part = forkable_nameparts; part->text; ++part) + if (part->create_dir) + ++lastsepcount; + + PWCHAR ntname = nt_max_path_buf (); + wcsncpy (ntname, forkables_dirx_ntname, NT_MAX_PATH); + + if (!mkdirs (ntname, lastsepcount)) + success = false; + + if (success) + { + /* create the DotLocal file as empty file */ + wcsncat (ntname, main_executable->modname, NT_MAX_PATH); + wcsncat (ntname, L".local", NT_MAX_PATH); + + UNICODE_STRING fn; + RtlInitUnicodeString (&fn, ntname); + + OBJECT_ATTRIBUTES oa; + InitializeObjectAttributes (&oa, &fn, 0, NULL, + sec_none_nih.lpSecurityDescriptor); + HANDLE hlocal = NULL; + NTSTATUS status; + IO_STATUS_BLOCK iosb; + status = NtCreateFile (&hlocal, GENERIC_WRITE | SYNCHRONIZE, + &oa, &iosb, NULL, FILE_ATTRIBUTE_NORMAL, + FILE_SHARE_READ | FILE_SHARE_WRITE, + FILE_CREATE, + FILE_NON_DIRECTORY_FILE + | FILE_SYNCHRONOUS_IO_NONALERT, + NULL, 0); + if (NT_SUCCESS (status)) + CloseHandle (hlocal); + else if (status != STATUS_OBJECT_NAME_COLLISION) /* already exists */ + success = false; + debug_printf ("%y = NtCreateFile (%p, %W)", status, hlocal, ntname); + } + + if (success) + { + dll *d = &start; + while ((d = d->next)) + if (!d->create_forkable ()) + d->nominate_forkable (NULL); /* never again */ + debug_printf ("hardlinks created"); + } + + return success; +} + +static void +rmdirs_synchronized (WCHAR ntbuf[NT_MAX_PATH], int depth, int maxdepth, + PFILE_DIRECTORY_INFORMATION pfdi, ULONG fdisize) +{ + if (depth == maxdepth) + { + debug_printf ("sync on %W", ntbuf); + /* calculate mutex name from path parts, using + full path name length to allocate mutex name buffer */ + WCHAR mutexname[wcslen (ntbuf)]; + mutexname[0] = L'\0'; + PWCHAR mutexnext = mutexname; + + /* mutex name is formed by dir names */ + int pathcount = 0; + for (namepart const *part = forkable_nameparts; part->text; ++part) + if (part->mutex_from_dir) + ++pathcount; + + PWCHAR pathseps[pathcount]; + + /* along the path separators split needed path parts */ + int i = pathcount; + while (--i >= 0) + if ((pathseps[i] = wcsrchr (ntbuf, L'\\'))) + *pathseps[i] = L'\0'; + else + return; /* something's wrong */ + + /* build the mutex name from dir names */ + for (i = 0; i < pathcount; ++i) + { + if (i > 0) + mutexnext = wcpcpy (mutexnext, MUTEXSEP); + mutexnext = wcpcpy (mutexnext, &pathseps[i][1]); + *pathseps[i] = L'\\'; /* restore full path */ + } + + HANDLE mutex = CreateMutexW (&sec_none_nih, TRUE, mutexname); + DWORD lasterror = GetLastError (); + debug_printf ("%p = CreateMutexW (%W): %E", mutex, mutexname); + if (mutex) + { + if (lasterror != ERROR_ALREADY_EXISTS) + { + debug_printf ("cleaning up for mutex %W", mutexname); + rmdirs (ntbuf); + } + BOOL bret = CloseHandle (mutex); + debug_printf ("%d = CloseHandle (%p, %W): %E", + bret, mutex, mutexname); + } + return; + } + + IO_STATUS_BLOCK iosb; + NTSTATUS status; + + HANDLE hdir = dll_list::ntopenfile (ntbuf, &status, + FILE_DIRECTORY_FILE | + (depth ? FILE_DELETE_ON_CLOSE : 0)); + if (hdir == INVALID_HANDLE_VALUE) + return; + + PWCHAR plast = ntbuf + wcslen (ntbuf); + while (NT_SUCCESS (status = NtQueryDirectoryFile (hdir, + NULL, NULL, NULL, &iosb, + pfdi, fdisize, + FileDirectoryInformation, + TRUE, NULL, FALSE))) + if (pfdi->FileAttributes & FILE_ATTRIBUTE_DIRECTORY) + { + int namelen = pfdi->FileNameLength / sizeof (WCHAR); + if (!wcsncmp (pfdi->FileName, L".", namelen) || + !wcsncmp (pfdi->FileName, L"..", namelen)) + continue; + *plast = L'\\'; + wcsncpy (plast+1, pfdi->FileName, namelen); + plast[1+namelen] = L'\0'; + rmdirs_synchronized (ntbuf, depth+1, maxdepth, pfdi, fdisize); + *plast = L'\0'; + } + if (status != STATUS_NO_MORE_FILES) + debug_printf ("%y = NtQueryDirectoryFile (%p, io %y, info %d)", + status, hdir, iosb.Status, iosb.Information); + CloseHandle (hdir); +} + +/* Try to lock the mutex handle with almost no timeout, then close the + mutex handle. Locking before closing is to get the mutex closing + promoted synchronously, otherways we might end up with no one + succeeding in create-with-lock, which is the precondition + to actually remove the hardlinks from the filesystem. */ +bool +dll_list::close_mutex () +{ + if (!forkables_mutex || !*forkables_mutex_name) + return false; + + HANDLE hmutex = forkables_mutex; + forkables_mutex = NULL; + + bool locked = false; + DWORD ret = WaitForSingleObject (hmutex, 1); + debug_printf ("%u = WFSO (%p, %W, 1)", + ret, hmutex, forkables_mutex_name); + switch (ret) + { + case WAIT_OBJECT_0: + case WAIT_ABANDONED: + locked = true; + break; + case WAIT_TIMEOUT: + break; + default: + system_printf ("error locking mutex %W: %E", forkables_mutex_name); + break; + } + BOOL bret = CloseHandle (hmutex); + debug_printf ("%d = CloseHandle (%p, %W): %E", + bret, hmutex, forkables_mutex_name); + return locked; +} + +/* Release the forkable hardlinks, and remove them if the + mutex can be create-locked after locked-closing. */ +void +dll_list::cleanup_forkables () +{ + if (!forkables_dirx_ntname) + return; + + bool locked = close_mutex (); + + /* Start the removal below with current forkables dir, + which is cleaned in denominate_forkables (). */ + PWCHAR buf = nt_max_path_buf (); + PWCHAR pathsep = wcpncpy (buf, forkables_dirx_ntname, NT_MAX_PATH); + buf[NT_MAX_PATH-1] = L'\0'; + + denominate_forkables (); + + if (!locked) + return; + + /* drop last path separator */ + while (--pathsep >= buf && *pathsep != L'\\'); + *pathsep = L'\0'; + + try_remove_forkables (buf, pathsep - buf, NT_MAX_PATH); +} + +void +dll_list::try_remove_forkables (PWCHAR dirbuf, size_t dirlen, size_t dirbufsize) +{ + /* Instead of just the current forkables, try to remove any forkables + found, to ensure some cleanup even in situations like power-loss. */ + PWCHAR end = dirbuf + wcslen (dirbuf); + int backcount = 0; + for (namepart const *part = forkable_nameparts; part->text; ++part) + if (part->create_dir) + { + /* drop one path separator per create_dir */ + while (--end >= dirbuf && *end != L'\\'); + if (end < dirbuf) + return; + *end = L'\0'; + ++backcount; + } + + /* reading one at a time to reduce stack pressure */ + struct { + FILE_DIRECTORY_INFORMATION fdi; + WCHAR buf[NAME_MAX]; + } fdibuf; + rmdirs_synchronized (dirbuf, 0, backcount, &fdibuf.fdi, sizeof (fdibuf)); +} + +void +dll_list::denominate_forkables () +{ + *forkables_dirx_ntname = L'\0'; + *forkables_mutex_name = L'\0'; + + dll *d = &start; + while ((d = d->next)) + d->nominate_forkable (forkables_dirx_ntname); +} + +/* Set or clear HANDLE_FLAG_INHERIT for all handles necessary + to maintain forkables-hardlinks. */ +void +dll_list::set_forkables_inheritance (bool inherit) +{ + DWORD mask = HANDLE_FLAG_INHERIT; + DWORD flags = inherit ? HANDLE_FLAG_INHERIT : 0; + + if (forkables_mutex) + SetHandleInformation (forkables_mutex, mask, flags); +} + +/* create the forkable hardlinks, if necessary */ +void +dll_list::request_forkables () +{ + if (!forkables_dirx_ntname) + return; + + /* Even on forkables_impossible, keep the number of open handles + stable across the fork, and close them when releasing only. */ + prepare_forkables_nomination (); + + update_forkables_needs (); + + set_forkables_inheritance (true); + + if (forkables_needs <= forkables_needless) + return; + + dll *d = &start; + while ((d = d->next)) + d->nominate_forkable (forkables_dirx_ntname); + + bool updated = update_forkables (); + + if (!updated) + forkables_needs = forkables_needless; + else + forkables_needs = forkables_created; +} + + +void +dll_list::release_forkables () +{ + if (!forkables_dirx_ntname) + return; + + set_forkables_inheritance (false); + + if (forkables_needs == forkables_impossible) + { + cleanup_forkables (); + + dll *d = &start; + while ((d = d->next)) + d->forkable_ntname = NULL; + + cfree (forkables_dirx_ntname); + forkables_dirx_ntname = NULL; + forkables_mutex_name = NULL; + } +} diff --git a/winsup/cygwin/pinfo.cc b/winsup/cygwin/pinfo.cc index b2bfb2b63..445bd35b2 100644 --- a/winsup/cygwin/pinfo.cc +++ b/winsup/cygwin/pinfo.cc @@ -25,6 +25,7 @@ details. */ #include "cygtls.h" #include "tls_pbuf.h" #include "child_info.h" +#include "dll_init.h" class pinfo_basic: public _pinfo { @@ -216,6 +217,8 @@ pinfo::exit (DWORD n) int exitcode = self->exitcode & 0xffff; if (!self->cygstarted) exitcode = ((exitcode & 0xff) << 8) | ((exitcode >> 8) & 0xff); + sigproc_printf ("Calling dlls.cleanup_forkables n %y, exitcode %y", n, exitcode); + dlls.cleanup_forkables (); sigproc_printf ("Calling ExitProcess n %y, exitcode %y", n, exitcode); if (!TerminateProcess (GetCurrentProcess (), exitcode)) system_printf ("TerminateProcess failed, %E"); diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc index 593c2a4af..387f4da32 100644 --- a/winsup/cygwin/syscalls.cc +++ b/winsup/cygwin/syscalls.cc @@ -670,8 +670,8 @@ check_dir_not_empty (HANDLE dir, path_conv &pc) return STATUS_SUCCESS; } -NTSTATUS -unlink_nt (path_conv &pc) +static NTSTATUS +_unlink_nt (path_conv &pc, bool shareable) { NTSTATUS status; HANDLE fh, fh_ro = NULL; @@ -797,6 +797,9 @@ retry_open: bin so that it actually disappears from its directory even though its in use. Otherwise, if opening doesn't fail, the file is not in use and we can go straight to setting the delete disposition flag. + However, while we have the file open with FILE_SHARE_DELETE, using + this file via another hardlink for anything other than DELETE by + concurrent processes fails. The 'shareable' argument is to prevent this. NOTE: The missing sharing modes FILE_SHARE_READ and FILE_SHARE_WRITE do NOT result in a STATUS_SHARING_VIOLATION, if another handle is @@ -806,7 +809,10 @@ retry_open: will succeed. So, apparently there is no reliable way to find out if a file is already open elsewhere for other purposes than reading and writing data. */ - status = NtOpenFile (&fh, access, &attr, &io, FILE_SHARE_DELETE, flags); + if (shareable) + status = STATUS_SHARING_VIOLATION; + else + status = NtOpenFile (&fh, access, &attr, &io, FILE_SHARE_DELETE, flags); /* STATUS_SHARING_VIOLATION is what we expect. STATUS_LOCK_NOT_GRANTED can be generated under not quite clear circumstances when trying to open a file on NFS with FILE_SHARE_DELETE only. This has been observed with @@ -1056,6 +1062,18 @@ out: return status; } +NTSTATUS +unlink_nt (path_conv &pc) +{ + return _unlink_nt (pc, false); +} + +NTSTATUS +unlink_nt_shareable (path_conv &pc) +{ + return _unlink_nt (pc, true); +} + extern "C" int unlink (const char *ourname) { From ece7282f329fd3616a9a1089aa0f0c26a5c01cc1 Mon Sep 17 00:00:00 2001 From: Michael Haubenwallner Date: Wed, 7 Dec 2016 11:58:28 +0100 Subject: [PATCH 195/475] forkables: On fork failure, retry with hardlinks. To support in-cygwin package managers, the fork() implementation must not rely on .exe and .dll files to stay in their original location, as the package manager's job is to replace these files. Instead, when the first fork try fails, and we have NTFS, we use hardlinks to the original binaries in /var/run/cygfork/ to create the child process during the second fork try, along the main.exe.local file to enable the "DotLocal Dll Redirection" feature for the dlls. The (probably few) users that need an update-safe fork manually have to create the /var/run/cygfork/ directory for now, using: mkdir --mode=a=rwxt /var/run/cygfork * child_info.h: Bump CURR_CHILD_INFO_MAGIC. (enum child_status): Add _CI_SILENTFAIL flag. (struct child_info): Add silentfail setter and getter. * winsup.h (child_copy): Add bool silentfail parameter. * cygheap.cc: Pass silentfail parameter to child_copy. * dcrt0.cc: Ditto. * dll_init.h (struct dll): Define public inline method forkedntname. (struct dll_list): Declare private method find_by_forkedntname. * dll_init.cc (struct dll_list): Implement find_by_forkedntname. (dll_list::alloc): Use find_by_forkedntname when in load after fork. (dll_list::load_after_fork_impl): Load dlls using dll::forkedntname. * fork.cc (frok::parent): Set silentfail child info flag. Pass silentfail parameter to child_copy. Use forkedntname of dlls.main_executable. (fork): When first dofork run failed and did not use forkables, run dofork again with_forkables set to true. (child_copy): Use debug_printf if silentfail is true, system_printf otherwise. --- winsup/cygwin/child_info.h | 13 ++++++++-- winsup/cygwin/cygheap.cc | 3 ++- winsup/cygwin/dcrt0.cc | 4 ++-- winsup/cygwin/dll_init.cc | 49 ++++++++++++++++++++++++++------------ winsup/cygwin/dll_init.h | 5 ++++ winsup/cygwin/fork.cc | 37 +++++++++++++++++++--------- winsup/cygwin/sigproc.cc | 5 +++- winsup/cygwin/winsup.h | 2 +- 8 files changed, 85 insertions(+), 33 deletions(-) diff --git a/winsup/cygwin/child_info.h b/winsup/cygwin/child_info.h index f7a144199..67264119e 100644 --- a/winsup/cygwin/child_info.h +++ b/winsup/cygwin/child_info.h @@ -21,7 +21,8 @@ enum child_status { _CI_STRACED = 0x01, _CI_ISCYGWIN = 0x02, - _CI_SAW_CTRL_C = 0x04 + _CI_SAW_CTRL_C = 0x04, + _CI_SILENTFAIL = 0x08 }; #define OPROC_MAGIC_MASK 0xff00ff00 @@ -36,7 +37,7 @@ enum child_status #define EXEC_MAGIC_SIZE sizeof(child_info) /* Change this value if you get a message indicating that it is out-of-sync. */ -#define CURR_CHILD_INFO_MAGIC 0xc96f5e9U +#define CURR_CHILD_INFO_MAGIC 0x3ee00652U #define NPROCS 256 @@ -82,6 +83,7 @@ public: bool isstraced () const {return !!(flag & _CI_STRACED);} bool iscygwin () const {return !!(flag & _CI_ISCYGWIN);} bool saw_ctrl_c () const {return !!(flag & _CI_SAW_CTRL_C);} + bool silentfail () const {return !!(flag & _CI_SILENTFAIL);} void prefork (bool = false); void cleanup (); void postfork (pinfo& child) @@ -91,6 +93,13 @@ public: child.set_rd_proc_pipe (rd_proc_pipe); rd_proc_pipe = NULL; } + void silentfail (bool f) + { + if (f) + flag |= _CI_SILENTFAIL; + else + flag &= ~_CI_SILENTFAIL; + } }; class mount_info; diff --git a/winsup/cygwin/cygheap.cc b/winsup/cygwin/cygheap.cc index 0e9741c7c..eb60cf279 100644 --- a/winsup/cygwin/cygheap.cc +++ b/winsup/cygwin/cygheap.cc @@ -78,7 +78,8 @@ cygheap_fixup_in_child (bool execed) { cygheap_max = cygheap = (init_cygheap *) _cygheap_start; _csbrk ((char *) child_proc_info->cygheap_max - (char *) cygheap); - child_copy (child_proc_info->parent, false, "cygheap", cygheap, cygheap_max, NULL); + child_copy (child_proc_info->parent, false, child_proc_info->silentfail (), + "cygheap", cygheap, cygheap_max, NULL); cygheap_init (); debug_fixup_after_fork_exec (); if (execed) diff --git a/winsup/cygwin/dcrt0.cc b/winsup/cygwin/dcrt0.cc index 5cdf01c6f..78506d43d 100644 --- a/winsup/cygwin/dcrt0.cc +++ b/winsup/cygwin/dcrt0.cc @@ -601,7 +601,7 @@ child_info_fork::handle_fork () myself->uid = cygheap->user.real_uid; myself->gid = cygheap->user.real_gid; - child_copy (parent, false, + child_copy (parent, false, silentfail (), "dll data", dll_data_start, dll_data_end, "dll bss", dll_bss_start, dll_bss_end, "user heap", cygheap->user_heap.base, cygheap->user_heap.ptr, @@ -625,7 +625,7 @@ child_info_fork::handle_fork () /* step 2 now that the dll has its heap filled in, we can fill in the user's data and bss since user_data is now filled out. */ - child_copy (parent, false, + child_copy (parent, false, silentfail (), "data", user_data->data_start, user_data->data_end, "bss", user_data->bss_start, user_data->bss_end, NULL); diff --git a/winsup/cygwin/dll_init.cc b/winsup/cygwin/dll_init.cc index 90b39408b..82b065608 100644 --- a/winsup/cygwin/dll_init.cc +++ b/winsup/cygwin/dll_init.cc @@ -289,6 +289,19 @@ dll_list::find_by_modname (PCWCHAR modname) return NULL; } +/* Look for a dll based on the ntname used + to dynamically reload in forked child. */ +dll * +dll_list::find_by_forkedntname (PCWCHAR ntname) +{ + dll *d = &start; + while ((d = d->next) != NULL) + if (!wcscasecmp (ntname, d->forkedntname ())) + return d; + + return NULL; +} + #define RETRIES 1000 /* Allocate space for a dll struct. */ @@ -308,8 +321,11 @@ dll_list::alloc (HINSTANCE h, per_process *p, dll_type type) /* Already loaded? For linked DLLs, only compare the basenames. Linked DLLs are loaded using just the basename and the default DLL search path. The Windows loader picks up the first one it finds. - This also applies to cygwin1.dll and the main-executable (DLL_SELF). */ - dll *d = (type != DLL_LOAD) ? dlls.find_by_modname (modname) : dlls[ntname]; + This also applies to cygwin1.dll and the main-executable (DLL_SELF). + When in_load_after_fork, dynamically loaded dll's are reloaded + using their parent's forkable_ntname, if available. */ + dll *d = (type != DLL_LOAD) ? dlls.find_by_modname (modname) : + in_load_after_fork ? dlls.find_by_forkedntname (ntname) : dlls[ntname]; if (d) { /* We only get here in the forkee. */ @@ -714,14 +730,16 @@ void dll_list::load_after_fork_impl (HANDLE parent, dll* d, int retries) fabort ("unable to release protective reservation (%p) for %W, %E", d->handle, d->ntname); - HMODULE h = LoadLibraryExW (buffered_shortname (d->ntname), + HMODULE h = LoadLibraryExW (buffered_shortname (d->forkedntname ()), NULL, DONT_RESOLVE_DLL_REFERENCES); if (!h) - fabort ("unable to create interim mapping for %W, %E", d->ntname); + fabort ("unable to create interim mapping for %W (using %W), %E", + d->ntname, buffered_shortname (d->forkedntname ())); if (h != d->handle) { - sigproc_printf ("%W loaded in wrong place: %p != %p", - d->ntname, h, d->handle); + sigproc_printf ("%W (using %W) loaded in wrong place: %p != %p", + d->ntname, buffered_shortname (d->forkedntname ()), + h, d->handle); FreeLibrary (h); PVOID reservation = reserve_at (d->ntname, h, d->handle, d->image_size); @@ -732,8 +750,8 @@ void dll_list::load_after_fork_impl (HANDLE parent, dll* d, int retries) if (retries < DLL_RETRY_MAX) load_after_fork_impl (parent, d, retries+1); else - fabort ("unable to remap %W to same address as parent (%p) - try running rebaseall", - d->ntname, d->handle); + fabort ("unable to remap %W (using %W) to same address as parent (%p) - try running rebaseall", + d->ntname, buffered_shortname (d->forkedntname ()), d->handle); /* once the above returns all the dlls are mapped; release the reservation and continue unwinding */ @@ -761,20 +779,21 @@ void dll_list::load_after_fork_impl (HANDLE parent, dll* d, int retries) /* Free the library using our parent's handle: it's identical to ours or we wouldn't have gotten this far */ if (!FreeLibrary (d->handle)) - fabort ("unable to unload interim mapping of %W, %E", - d->ntname); + fabort ("unable to unload interim mapping of %W (using %W), %E", + d->ntname, buffered_shortname (d->forkedntname ())); } /* cygwin1.dll - as linked dependency - may reuse the shortname buffer, even in case of failure: don't reuse shortname later */ - HMODULE h = LoadLibraryW (buffered_shortname (d->ntname)); + HMODULE h = LoadLibraryW (buffered_shortname (d->forkedntname ())); if (!h) - fabort ("unable to map %W, %E", d->ntname); + fabort ("unable to map %W (using %W), %E", + d->ntname, buffered_shortname (d->forkedntname ())); if (h != d->handle) - fabort ("unable to map %W to same address as parent: %p != %p", - d->ntname, d->handle, h); + fabort ("unable to map %W (using %W) to same address as parent: %p != %p", + d->ntname, buffered_shortname (d->forkedntname ()), d->handle, h); /* Fix OS reference count. */ for (int cnt = 1; cnt < d->count; ++cnt) - LoadLibraryW (buffered_shortname (d->ntname)); + LoadLibraryW (buffered_shortname (d->forkedntname ())); } } diff --git a/winsup/cygwin/dll_init.h b/winsup/cygwin/dll_init.h index 62739f729..45f71cb10 100644 --- a/winsup/cygwin/dll_init.h +++ b/winsup/cygwin/dll_init.h @@ -76,6 +76,10 @@ struct dll p.run_dtors (); } } + PWCHAR forkedntname () + { + return forkable_ntname && *forkable_ntname ? forkable_ntname : ntname; + } }; #define MAX_DLL_BEFORE_INIT 100 @@ -98,6 +102,7 @@ class dll_list PWCHAR forkables_mutex_name; HANDLE forkables_mutex; void track_self (); + dll *find_by_forkedntname (PCWCHAR ntname); size_t forkable_ntnamesize (dll_type, PCWCHAR fullntname, PCWCHAR modname); void prepare_forkables_nomination (); void update_forkables_needs (); diff --git a/winsup/cygwin/fork.cc b/winsup/cygwin/fork.cc index f929a85c0..530e423ad 100644 --- a/winsup/cygwin/fork.cc +++ b/winsup/cygwin/fork.cc @@ -315,12 +315,14 @@ frok::parent (volatile char * volatile stack_here) *with_forkables = dlls.setup_forkables (*with_forkables); + ch.silentfail (!*with_forkables); /* fail silently without forkables */ + while (1) { PCWCHAR forking_progname = NULL; if (dlls.main_executable) forking_progname = dll_list::buffered_shortname - (dlls.main_executable->ntname); + (dlls.main_executable->forkedntname ()); if (!forking_progname || !*forking_progname) forking_progname = myself->progname; @@ -444,7 +446,7 @@ frok::parent (volatile char * volatile stack_here) impure_beg = _impure_ptr; impure_end = _impure_ptr + 1; } - rc = child_copy (hchild, true, + rc = child_copy (hchild, true, !*with_forkables, "stack", stack_here, ch.stackbase, impure, impure_beg, impure_end, NULL); @@ -462,7 +464,7 @@ frok::parent (volatile char * volatile stack_here) for (dll *d = dlls.istart (DLL_LINK); d; d = dlls.inext ()) { debug_printf ("copying data/bss of a linked dll"); - if (!child_copy (hchild, true, + if (!child_copy (hchild, true, !*with_forkables, "linked dll data", d->p.data_start, d->p.data_end, "linked dll bss", d->p.bss_start, d->p.bss_end, NULL)) @@ -492,7 +494,7 @@ frok::parent (volatile char * volatile stack_here) for (dll *d = dlls.istart (DLL_LOAD); d; d = dlls.inext ()) { debug_printf ("copying data/bss for a loaded dll"); - if (!child_copy (hchild, true, + if (!child_copy (hchild, true, !*with_forkables, "loaded dll data", d->p.data_start, d->p.data_end, "loaded dll bss", d->p.bss_start, d->p.bss_end, NULL)) @@ -539,7 +541,13 @@ cleanup: extern "C" int fork () { - bool with_forkables = true; + bool with_forkables = false; /* do not force hardlinks on first try */ + int res = dofork (&with_forkables); + if (res >= 0) + return res; + if (with_forkables) + return res; /* no need for second try when already enabled */ + with_forkables = true; /* enable hardlinks for second try */ return dofork (&with_forkables); } @@ -613,6 +621,9 @@ dofork (bool *with_forkables) { if (!grouped.errmsg) syscall_printf ("fork failed - child pid %d, errno %d", grouped.child_pid, grouped.this_errno); + else if (grouped.ch.silentfail ()) + debug_printf ("child %d - %s, errno %d", grouped.child_pid, + grouped.errmsg, grouped.this_errno); else system_printf ("child %d - %s, errno %d", grouped.child_pid, grouped.errmsg, grouped.this_errno); @@ -640,10 +651,10 @@ vfork () /* Copy memory from one process to another. */ bool -child_copy (HANDLE hp, bool write, ...) +child_copy (HANDLE hp, bool write, bool silentfail, ...) { va_list args; - va_start (args, write); + va_start (args, silentfail); static const char *huh[] = {"read", "write"}; char *what; @@ -669,10 +680,14 @@ child_copy (HANDLE hp, bool write, ...) { if (!res) __seterrno (); - /* If this happens then there is a bug in our fork - implementation somewhere. */ - system_printf ("%s %s copy failed, %p..%p, done %lu, windows pid %u, %E", - what, huh[write], low, high, done, myself->dwProcessId); + if (silentfail) + debug_printf ("%s %s copy failed, %p..%p, done %lu, windows pid %u, %E", + what, huh[write], low, high, done, myself->dwProcessId); + else + /* If this happens then there is a bug in our fork + implementation somewhere. */ + system_printf ("%s %s copy failed, %p..%p, done %lu, windows pid %u, %E", + what, huh[write], low, high, done, myself->dwProcessId); goto err; } } diff --git a/winsup/cygwin/sigproc.cc b/winsup/cygwin/sigproc.cc index a830bff79..30dfaaa25 100644 --- a/winsup/cygwin/sigproc.cc +++ b/winsup/cygwin/sigproc.cc @@ -1101,7 +1101,10 @@ child_info_fork::abort (const char *fmt, ...) { va_list ap; va_start (ap, fmt); - strace_vprintf (SYSTEM, fmt, ap); + if (silentfail ()) + strace_vprintf (DEBUG, fmt, ap); + else + strace_vprintf (SYSTEM, fmt, ap); TerminateProcess (GetCurrentProcess (), EXITCODE_FORK_FAILED); } if (retry > 0) diff --git a/winsup/cygwin/winsup.h b/winsup/cygwin/winsup.h index 3a5f5d538..95ab41e6b 100644 --- a/winsup/cygwin/winsup.h +++ b/winsup/cygwin/winsup.h @@ -224,7 +224,7 @@ int __small_swprintf (PWCHAR dst, const WCHAR *fmt, ...); int __small_vswprintf (PWCHAR dst, const WCHAR *fmt, va_list ap); void multiple_cygwin_problem (const char *, uintptr_t, uintptr_t); -bool child_copy (HANDLE, bool, ...); +bool child_copy (HANDLE, bool, bool, ...); class path_conv; From 5a41aa6f4d5eb12a1fc2ef084d98f63d65f5fcc3 Mon Sep 17 00:00:00 2001 From: Michael Haubenwallner Date: Wed, 7 Dec 2016 11:58:29 +0100 Subject: [PATCH 196/475] forkables: Keep hardlinks disabled via shared mem. To avoid the need for each process to check the filesystem to detect that hardlink creation is impossible or disabled, cache this fact in shared memory. Removing cygfork directory while in use does disable hardlinks creation. To (re-)enable hardlinks creation, the cygfork directory has to exist before the first cygwin process does fork. * forkable.cc (dll_list::forkable_ntnamesize): Short cut forkables needs to impossible when disabled via shared memory. (dll_list::update_forkables_needs): When detecting hardlink creation as impossible (not on NTFS) while still (we are the first one checking) enabled via shared memory, disable the shared memory value. (dll_list::request_forkables): Disable the shared memory value when hardlinks creation became disabled, that is when the cygfork directory was removed. * include/cygwin/version.h: Bump CYGWIN_VERSION_SHARED_DATA 6. * shared_info.h (struct shared_info): Add member prefer_forkable_hardlinks. Update CURR_SHARED_MAGIC. * shared.cc (shared_info::initialize): Initialize prefer_forkable_hardlinks to 1 (Yes). --- winsup/cygwin/forkable.cc | 13 +++++++++++++ winsup/cygwin/include/cygwin/version.h | 2 +- winsup/cygwin/shared_info.h | 3 ++- 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/winsup/cygwin/forkable.cc b/winsup/cygwin/forkable.cc index cc28f9f4f..da45643ae 100644 --- a/winsup/cygwin/forkable.cc +++ b/winsup/cygwin/forkable.cc @@ -522,6 +522,11 @@ dll::create_forkable () size_t dll_list::forkable_ntnamesize (dll_type type, PCWCHAR fullntname, PCWCHAR modname) { + /* per process, this is the first forkables-method ever called */ + if (forkables_needs == forkables_unknown && + !cygwin_shared->prefer_forkable_hardlinks) + forkables_needs = forkables_impossible; /* short cut */ + if (forkables_needs == forkables_impossible) return 0; @@ -667,6 +672,7 @@ dll_list::update_forkables_needs () { debug_printf ("impossible, not on NTFS %W", fn.Buffer); forkables_needs = forkables_impossible; + cygwin_shared->prefer_forkable_hardlinks = 0; } } @@ -1056,6 +1062,13 @@ dll_list::request_forkables () set_forkables_inheritance (true); + if (forkables_needs == forkables_disabled) + { + /* we do not support (re-)enabling on the fly */ + forkables_needs = forkables_impossible; + cygwin_shared->prefer_forkable_hardlinks = 0; + } + if (forkables_needs <= forkables_needless) return; diff --git a/winsup/cygwin/include/cygwin/version.h b/winsup/cygwin/include/cygwin/version.h index 8926d49ae..f7ed351d3 100644 --- a/winsup/cygwin/include/cygwin/version.h +++ b/winsup/cygwin/include/cygwin/version.h @@ -518,7 +518,7 @@ details. */ regions. It is incremented when incompatible changes are made to the shared memory region *or* to any named shared mutexes, semaphores, etc. */ -#define CYGWIN_VERSION_SHARED_DATA 5 +#define CYGWIN_VERSION_SHARED_DATA 6 /* An identifier used in the names used to create shared objects. The full names include the CYGWIN_VERSION_SHARED_DATA version as well as this diff --git a/winsup/cygwin/shared_info.h b/winsup/cygwin/shared_info.h index 1a5648b24..8f0954f50 100644 --- a/winsup/cygwin/shared_info.h +++ b/winsup/cygwin/shared_info.h @@ -33,7 +33,7 @@ public: /* Data accessible to all tasks */ -#define CURR_SHARED_MAGIC 0x6758de88U +#define CURR_SHARED_MAGIC 0x3a6025edU #define USER_VERSION 1 @@ -51,6 +51,7 @@ class shared_info mtinfo mt; loadavginfo loadavg; LONG pid_src; + char prefer_forkable_hardlinks; /* single byte access always is atomic */ void initialize (); void init_obcaseinsensitive (); From 6dd415caf569aa49ea11d4ab0e837aa379c130b4 Mon Sep 17 00:00:00 2001 From: Michael Haubenwallner Date: Wed, 7 Dec 2016 11:58:30 +0100 Subject: [PATCH 197/475] forkables: Document hardlink creation at forktime. * faq-api.xml: Mention hardlink creation by fork. * highlights.xml: Describe hardlink creation. --- winsup/doc/faq-api.xml | 5 +++++ winsup/doc/highlights.xml | 41 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+) diff --git a/winsup/doc/faq-api.xml b/winsup/doc/faq-api.xml index 6abbbc4b6..a95dbdd31 100644 --- a/winsup/doc/faq-api.xml +++ b/winsup/doc/faq-api.xml @@ -155,6 +155,11 @@ child, releases the mutex the child is waiting on and returns from the fork call. Child wakes from blocking on mutex, recreates any mmapped areas passed to it via shared area and then returns from fork itself. +When the executable or any dll in use by the parent was renamed or +moved into the hidden recycle bin, fork retries with creating hardlinks +for the old executable and any dll into per-user subdirectories in the +/var/run/cygfork/ directory, when that one exists and resides on NTFS. + diff --git a/winsup/doc/highlights.xml b/winsup/doc/highlights.xml index ec9fcd674..25b227382 100644 --- a/winsup/doc/highlights.xml +++ b/winsup/doc/highlights.xml @@ -195,6 +195,47 @@ difficult to implement correctly. Currently, the Cygwin fork is a non-copy-on-write implementation similar to what was present in early flavors of UNIX. +As the child process is created as new process, both the main +executable and all the dlls loaded either statically or dynamically have +to be identical as to when the parent process has started or loaded a dll. +While Windows does not allow to remove binaries in use from the file +system, they still can be renamed or moved into the recycle bin, as +outlined for unlink(2) in . +To allow an existing process to fork, the original binary files need to be +available via their original file names, but they may reside in +different directories when using the DotLocal (.local) Dll Redirection feature. +Since NTFS does support hardlinks, when the fork fails we try again, but +create a private directory containing hardlinks to the original files as +well as the .local file now. The private directory for the hardlinks is +/var/run/cygfork/, which you have to create manually for now if you need to +protect fork against exe- and dll- updates on your Cygwin instance. As +hardlinks cannot be used across multiple NTFS file systems, please make sure +your exe- and dll- replacing operations operate on the same single NTFS file +system as your Cygwin instance and the /var/run/cygfork/ directory. + +We create one directory per user, application and application age, +and remove it when no more processes use that directory. To indicate +whether a directory still is in use, we define a mutex name similar to +the directory name. As mutexes are destroyed when no process holds a +handle open any more, we can clean up even after power loss or similar: +Both the parent and child process, at exit they lock the mutex with +almost no timeout and close it, to get the closure promoted synchronously. +If the lock succeeded before closing, directory cleanup is started: +For each directory found, the corresponding mutex is created with lock. +If that succeeds, the directory is removed, as it is unused now, and the +corresponding mutex handle is closed. + +Before fork, when about to create hardlinks for the first time, the +mutex is opened and locked with infinite timeout, to wait for the cleanup +that may run at the same time. Once locked, the mutex is unlocked +immediately, but the mutex handle stays open until exit, and the hardlinks +are created. It is fine for multiple processes to concurrently create +the same hardlinks, as the result really should be identical. Once the +mutex is open, we can create more hardlinks within this one directory +without the need to lock the mutex again. + The first thing that happens when a parent process forks a child process is that the parent initializes a space in the Cygwin process table for the child. It then creates a suspended From 8bbb3d3a23e4d3ab8e707168f1c6bd7b0e19f6df Mon Sep 17 00:00:00 2001 From: Michael Haubenwallner Date: Thu, 12 Jan 2017 10:03:52 +0100 Subject: [PATCH 198/475] forkables: use dynloaded dll's IndexNumber as dirname --- winsup/cygwin/forkable.cc | 33 ++++++++------------------------- 1 file changed, 8 insertions(+), 25 deletions(-) diff --git a/winsup/cygwin/forkable.cc b/winsup/cygwin/forkable.cc index da45643ae..c569b0f70 100644 --- a/winsup/cygwin/forkable.cc +++ b/winsup/cygwin/forkable.cc @@ -409,34 +409,17 @@ dll::nominate_forkable (PCWCHAR dirx_name) if (!*forkable_ntname) return; /* denominate */ - if (type < DLL_LOAD) - wcpcpy (next, modname); - else + if (type == DLL_LOAD) { - /* Avoid lots of extra directories for loaded dll's: - * mangle full path into one single directory name, - * just keep original filename intact. The original - * filename is necessary to serve as linked - * dependencies of dynamically loaded dlls. */ - PWCHAR lastpathsep = wcsrchr (ntname, L'\\'); - if (!lastpathsep) - { - forkable_ntname = NULL; - return; - } - *lastpathsep = L'\0'; - HANDLE fh = dll_list::ntopenfile (ntname, NULL, FILE_DIRECTORY_FILE); - *lastpathsep = L'\\'; - - FILE_INTERNAL_INFORMATION fii = { 0 }; - if (fh != INVALID_HANDLE_VALUE) - { - dll_list::read_fii (fh, &fii); - NtClose (fh); - } + /* Multiple dynamically loaded dlls can have identical basenames + * when loaded from different directories. But still the original + * basename may serve as linked dependency for another dynamically + * loaded dll. So we have to create a separate directory for the + * dynamically loaded dll - using the dll's IndexNumber as name. */ next += format_IndexNumber (next, -1, &fii.IndexNumber); - wcpcpy (next, lastpathsep); + next = wcpcpy (next, L"\\"); } + wcpcpy (next, modname); } /* Create the nominated hardlink for one indivitual dll, From 135577f708a07405d1cd80880430429a9beb1041 Mon Sep 17 00:00:00 2001 From: Michael Haubenwallner Date: Wed, 1 Mar 2017 10:19:37 +0100 Subject: [PATCH 199/475] forkables: simplify disabling via shm * Rename cygwin_shared->prefer_forkable_hardlinks to forkable_hardlink_support, with values 0 for Unknown, 1 for Supported, -1 for Unsupported. Upon first dll loaded ever, dll_list::forkable_ntnamesize checks the /var/run/cygfork directory to both exist and reside on NTFS, setting cygwin_shared->forkable_hardlink_support accordingly. * Replace enum forkables_needs by bool forkables_created: Set to True by request_forkables after creating forkable hardlinks. --- winsup/cygwin/dll_init.h | 21 +-- winsup/cygwin/forkable.cc | 185 ++++++++----------------- winsup/cygwin/include/cygwin/version.h | 2 +- winsup/cygwin/shared.cc | 1 + winsup/cygwin/shared_info.h | 4 +- 5 files changed, 65 insertions(+), 148 deletions(-) diff --git a/winsup/cygwin/dll_init.h b/winsup/cygwin/dll_init.h index 45f71cb10..5c4cc0b29 100644 --- a/winsup/cygwin/dll_init.h +++ b/winsup/cygwin/dll_init.h @@ -87,17 +87,9 @@ struct dll class dll_list { /* forkables */ - enum - { - forkables_unknown, - forkables_impossible, - forkables_disabled, - forkables_needless, - forkables_needed, - forkables_created, - } - forkables_needs; + bool forkables_supported (); DWORD forkables_dirx_size; + bool forkables_created; PWCHAR forkables_dirx_ntname; PWCHAR forkables_mutex_name; HANDLE forkables_mutex; @@ -160,10 +152,11 @@ public: void cleanup_forkables (); bool setup_forkables (bool with_forkables) { - if (forkables_needs == forkables_impossible) - return true; /* short cut to not retry fork */ - /* Once used, always use forkables in current process chain. */ - if (forkables_needs != forkables_unknown) + if (!forkables_supported ()) + return true; /* no need to retry fork */ + if (forkables_created) + /* Once created, use forkables in current + process chain on first fork try already. */ with_forkables = true; if (with_forkables) request_forkables (); diff --git a/winsup/cygwin/forkable.cc b/winsup/cygwin/forkable.cc index c569b0f70..05b228517 100644 --- a/winsup/cygwin/forkable.cc +++ b/winsup/cygwin/forkable.cc @@ -501,17 +501,56 @@ dll::create_forkable () return false; } +bool +dll_list::forkables_supported () +{ + return cygwin_shared->forkable_hardlink_support >= 0; +} + /* return the number of characters necessary to store one forkable name */ size_t dll_list::forkable_ntnamesize (dll_type type, PCWCHAR fullntname, PCWCHAR modname) { /* per process, this is the first forkables-method ever called */ - if (forkables_needs == forkables_unknown && - !cygwin_shared->prefer_forkable_hardlinks) - forkables_needs = forkables_impossible; /* short cut */ + if (cygwin_shared->forkable_hardlink_support == 0) /* Unknown */ + { + /* check existence of forkables dir */ + PWCHAR pbuf = nt_max_path_buf (); + for (namepart const *part = forkable_nameparts; part->text; ++part) + { + if (part->textfunc) + pbuf += part->textfunc (pbuf, -1); + else + pbuf += __small_swprintf (pbuf, L"%W", part->text); + if (part->mutex_from_dir) + break; /* up to first mutex-naming dir */ + } + pbuf = nt_max_path_buf (); - if (forkables_needs == forkables_impossible) - return 0; + UNICODE_STRING fn; + RtlInitUnicodeString (&fn, pbuf); + + HANDLE dh = INVALID_HANDLE_VALUE; + fs_info fsi; + if (fsi.update (&fn, NULL) && +/* FIXME: !fsi.is_readonly () && */ + fsi.is_ntfs ()) + dh = ntopenfile (pbuf, NULL, FILE_DIRECTORY_FILE); + if (dh != INVALID_HANDLE_VALUE) + { + cygwin_shared->forkable_hardlink_support = 1; /* Yes */ + NtClose (dh); + debug_printf ("enabled"); + } + else + { + cygwin_shared->forkable_hardlink_support = -1; /* No */ + debug_printf ("disabled, missing or not on NTFS %W", fn.Buffer); + } + } + + if (!forkables_supported ()) + return 0; if (!forkables_dirx_size) { @@ -560,9 +599,6 @@ dll_list::forkable_ntnamesize (dll_type type, PCWCHAR fullntname, PCWCHAR modnam void dll_list::prepare_forkables_nomination () { - if (!forkables_dirx_ntname) - return; - dll *d = &dlls.start; while ((d = d->next)) stat_real_file_once (d); /* uses nt_max_path_buf () */ @@ -627,106 +663,19 @@ dll_list::prepare_forkables_nomination () void dll_list::update_forkables_needs () { - dll *d; - - if (forkables_needs == forkables_unknown) - { - /* check if filesystem of forkables dir is NTFS */ - PWCHAR pbuf = nt_max_path_buf (); - for (namepart const *part = forkable_nameparts; part->text; ++part) - { - if (part->mutex_from_dir) - break; /* leading non-mutex-naming dirs, must exist anyway */ - if (part->textfunc) - pbuf += part->textfunc (pbuf, -1); - else - pbuf += __small_swprintf (pbuf, L"%W", part->text); - } - - UNICODE_STRING fn; - RtlInitUnicodeString (&fn, nt_max_path_buf ()); - - fs_info fsi; - if (fsi.update (&fn, NULL) && -/* FIXME: !fsi.is_readonly () && */ - fsi.is_ntfs ()) - forkables_needs = forkables_disabled; /* check directory itself */ - else - { - debug_printf ("impossible, not on NTFS %W", fn.Buffer); - forkables_needs = forkables_impossible; - cygwin_shared->prefer_forkable_hardlinks = 0; - } - } - - if (forkables_needs == forkables_impossible) - return; /* we have not created any hardlink, nothing to clean up */ - - if (forkables_needs == forkables_disabled || - forkables_needs == forkables_needless || - forkables_needs == forkables_created) - { - /* (re-)check existence of forkables dir */ - PWCHAR pbuf = nt_max_path_buf (); - for (namepart const *part = forkable_nameparts; part->text; ++part) - { - if (part->textfunc) - pbuf += part->textfunc (pbuf, -1); - else - pbuf += __small_swprintf (pbuf, L"%W", part->text); - if (part->mutex_from_dir) - break; /* up to first mutex-naming dir */ - } - pbuf = nt_max_path_buf (); - - HANDLE dh = ntopenfile (pbuf, NULL, FILE_DIRECTORY_FILE); - if (dh != INVALID_HANDLE_VALUE) - { - NtClose (dh); - if (forkables_needs == forkables_disabled) - forkables_needs = forkables_needless; - } - else if (forkables_needs != forkables_disabled) - { - debug_printf ("disabled, disappearing %W", pbuf); - close_mutex (); - denominate_forkables (); - forkables_needs = forkables_disabled; - } - else - debug_printf ("disabled, missing %W", pbuf); - } - - if (forkables_needs == forkables_disabled) - return; - - if (forkables_needs == forkables_created) + if (forkables_created) { /* already have created hardlinks in this process, ... */ - forkables_needs = forkables_needless; - d = &start; + dll *d = &start; while ((d = d->next) != NULL) if (d->forkable_ntname && !*d->forkable_ntname) { /* ... but another dll was loaded since last fork */ debug_printf ("needed, since last fork loaded %W", d->ntname); - forkables_needs = forkables_needed; + forkables_created = false; break; } } - - if (forkables_needs > forkables_needless) - return; /* no need to check anything else */ - - if (forkables_needs != forkables_needless) - { - /* paranoia */ - system_printf ("WARNING: invalid forkables_needs value %d", - forkables_needs); - return; - } - - forkables_needs = forkables_needed; } /* Create the nominated forkable hardlinks and directories as necessary, @@ -958,7 +907,7 @@ dll_list::close_mutex () void dll_list::cleanup_forkables () { - if (!forkables_dirx_ntname) + if (!forkables_supported ()) return; bool locked = close_mutex (); @@ -1034,58 +983,32 @@ dll_list::set_forkables_inheritance (bool inherit) void dll_list::request_forkables () { - if (!forkables_dirx_ntname) + if (!forkables_supported ()) return; - /* Even on forkables_impossible, keep the number of open handles - stable across the fork, and close them when releasing only. */ prepare_forkables_nomination (); update_forkables_needs (); set_forkables_inheritance (true); - if (forkables_needs == forkables_disabled) - { - /* we do not support (re-)enabling on the fly */ - forkables_needs = forkables_impossible; - cygwin_shared->prefer_forkable_hardlinks = 0; - } - - if (forkables_needs <= forkables_needless) - return; + if (forkables_created) + return; /* nothing new to create */ dll *d = &start; while ((d = d->next)) d->nominate_forkable (forkables_dirx_ntname); - bool updated = update_forkables (); - - if (!updated) - forkables_needs = forkables_needless; - else - forkables_needs = forkables_created; + if (update_forkables ()) + forkables_created = true; } void dll_list::release_forkables () { - if (!forkables_dirx_ntname) + if (!forkables_supported ()) return; set_forkables_inheritance (false); - - if (forkables_needs == forkables_impossible) - { - cleanup_forkables (); - - dll *d = &start; - while ((d = d->next)) - d->forkable_ntname = NULL; - - cfree (forkables_dirx_ntname); - forkables_dirx_ntname = NULL; - forkables_mutex_name = NULL; - } } diff --git a/winsup/cygwin/include/cygwin/version.h b/winsup/cygwin/include/cygwin/version.h index f7ed351d3..8926d49ae 100644 --- a/winsup/cygwin/include/cygwin/version.h +++ b/winsup/cygwin/include/cygwin/version.h @@ -518,7 +518,7 @@ details. */ regions. It is incremented when incompatible changes are made to the shared memory region *or* to any named shared mutexes, semaphores, etc. */ -#define CYGWIN_VERSION_SHARED_DATA 6 +#define CYGWIN_VERSION_SHARED_DATA 5 /* An identifier used in the names used to create shared objects. The full names include the CYGWIN_VERSION_SHARED_DATA version as well as this diff --git a/winsup/cygwin/shared.cc b/winsup/cygwin/shared.cc index e87f2f960..c939e0d0f 100644 --- a/winsup/cygwin/shared.cc +++ b/winsup/cygwin/shared.cc @@ -334,6 +334,7 @@ shared_info::initialize () NtAllocateLocallyUniqueId (&luid);/* Initialize pid_src to a low */ InterlockedExchange (&pid_src, /* random value to make start pid */ luid.LowPart % 2048);/* less predictably */ + forkable_hardlink_support = 0; /* 0: Unknown, 1: Yes, -1: No */ /* Defer debug output printing the installation root and installation key up to this point. Debug output except for system_printf requires the global shared memory to exist. */ diff --git a/winsup/cygwin/shared_info.h b/winsup/cygwin/shared_info.h index 8f0954f50..307306ce7 100644 --- a/winsup/cygwin/shared_info.h +++ b/winsup/cygwin/shared_info.h @@ -33,7 +33,7 @@ public: /* Data accessible to all tasks */ -#define CURR_SHARED_MAGIC 0x3a6025edU +#define CURR_SHARED_MAGIC 0xc590e67eU #define USER_VERSION 1 @@ -51,7 +51,7 @@ class shared_info mtinfo mt; loadavginfo loadavg; LONG pid_src; - char prefer_forkable_hardlinks; /* single byte access always is atomic */ + char forkable_hardlink_support; /* single byte access always is atomic */ void initialize (); void init_obcaseinsensitive (); From 22d68bada39c0b676af7525d5dae272fd688c1c6 Mon Sep 17 00:00:00 2001 From: Michael Haubenwallner Date: Thu, 2 Mar 2017 17:26:53 +0100 Subject: [PATCH 200/475] forkables: inline dll_list::forkables_supported And LONG fits better for shared_info member forkable_hardlink_support. --- winsup/cygwin/dlfcn.cc | 2 +- winsup/cygwin/dll_init.cc | 1 + winsup/cygwin/dll_init.h | 6 ++++-- winsup/cygwin/fork.cc | 1 + winsup/cygwin/forkable.cc | 8 +------- winsup/cygwin/shared_info.h | 4 ++-- 6 files changed, 10 insertions(+), 12 deletions(-) diff --git a/winsup/cygwin/dlfcn.cc b/winsup/cygwin/dlfcn.cc index 7ef7dfd32..c675a5785 100644 --- a/winsup/cygwin/dlfcn.cc +++ b/winsup/cygwin/dlfcn.cc @@ -15,13 +15,13 @@ details. */ #include "path.h" #include "fhandler.h" #include "dtable.h" -#include "dll_init.h" #include "cygheap.h" #include "perprocess.h" #include "cygtls.h" #include "tls_pbuf.h" #include "ntdll.h" #include "shared_info.h" +#include "dll_init.h" #include "pathfinder.h" /* Dumb allocator using memory from tmp_pathbuf.w_get (). diff --git a/winsup/cygwin/dll_init.cc b/winsup/cygwin/dll_init.cc index 82b065608..4baa48dc1 100644 --- a/winsup/cygwin/dll_init.cc +++ b/winsup/cygwin/dll_init.cc @@ -8,6 +8,7 @@ details. */ #include "cygerrno.h" #include "perprocess.h" #include "sync.h" +#include "shared_info.h" #include "dll_init.h" #include "environ.h" #include "security.h" diff --git a/winsup/cygwin/dll_init.h b/winsup/cygwin/dll_init.h index 5c4cc0b29..c4a133f01 100644 --- a/winsup/cygwin/dll_init.h +++ b/winsup/cygwin/dll_init.h @@ -86,8 +86,10 @@ struct dll class dll_list { - /* forkables */ - bool forkables_supported (); + bool forkables_supported () + { + return cygwin_shared->forkable_hardlink_support >= 0; + } DWORD forkables_dirx_size; bool forkables_created; PWCHAR forkables_dirx_ntname; diff --git a/winsup/cygwin/fork.cc b/winsup/cygwin/fork.cc index 530e423ad..7ae0404f4 100644 --- a/winsup/cygwin/fork.cc +++ b/winsup/cygwin/fork.cc @@ -20,6 +20,7 @@ details. */ #include "child_info.h" #include "cygtls.h" #include "tls_pbuf.h" +#include "shared_info.h" #include "dll_init.h" #include "cygmalloc.h" #include "ntdll.h" diff --git a/winsup/cygwin/forkable.cc b/winsup/cygwin/forkable.cc index 05b228517..1e02a8a44 100644 --- a/winsup/cygwin/forkable.cc +++ b/winsup/cygwin/forkable.cc @@ -10,7 +10,6 @@ details. */ #include "cygerrno.h" #include "perprocess.h" #include "sync.h" -#include "dll_init.h" #include "environ.h" #include "security.h" #include "path.h" @@ -19,6 +18,7 @@ details. */ #include "cygheap.h" #include "pinfo.h" #include "shared_info.h" +#include "dll_init.h" #include "child_info.h" #include "cygtls.h" #include "exception.h" @@ -501,12 +501,6 @@ dll::create_forkable () return false; } -bool -dll_list::forkables_supported () -{ - return cygwin_shared->forkable_hardlink_support >= 0; -} - /* return the number of characters necessary to store one forkable name */ size_t dll_list::forkable_ntnamesize (dll_type type, PCWCHAR fullntname, PCWCHAR modname) diff --git a/winsup/cygwin/shared_info.h b/winsup/cygwin/shared_info.h index 307306ce7..83a1fd187 100644 --- a/winsup/cygwin/shared_info.h +++ b/winsup/cygwin/shared_info.h @@ -33,7 +33,7 @@ public: /* Data accessible to all tasks */ -#define CURR_SHARED_MAGIC 0xc590e67eU +#define CURR_SHARED_MAGIC 0x9f33cc5dU #define USER_VERSION 1 @@ -51,7 +51,7 @@ class shared_info mtinfo mt; loadavginfo loadavg; LONG pid_src; - char forkable_hardlink_support; /* single byte access always is atomic */ + LONG forkable_hardlink_support; void initialize (); void init_obcaseinsensitive (); From 3956ddd9bf28c518e73faf74c812379de02c3881 Mon Sep 17 00:00:00 2001 From: Michael Haubenwallner Date: Fri, 10 Mar 2017 11:32:54 +0100 Subject: [PATCH 201/475] forkables: hardlink without WRITE_ATTRIBUTES first When the current process has renamed (to bin) a readonly dll, we get STATUS_TRANSACTION_NOT_ACTIVE for unknown reason when subsequently creating the forkable hardlink. A workaround is to open the original file with FILE_WRITE_ATTRIBUTES access, but that fails with permission denied for users not owning the original file. * forkable.cc (dll::create_forkable): Retry hardlink creation using the original file's handle opened with FILE_WRITE_ATTRIBUTES access when the first attempt fails with STATUS_TRANSACTION_NOT_ACTIVE. --- winsup/cygwin/forkable.cc | 72 ++++++++++++++++++++++++++------------- 1 file changed, 48 insertions(+), 24 deletions(-) diff --git a/winsup/cygwin/forkable.cc b/winsup/cygwin/forkable.cc index 1e02a8a44..1067eac85 100644 --- a/winsup/cygwin/forkable.cc +++ b/winsup/cygwin/forkable.cc @@ -423,7 +423,14 @@ dll::nominate_forkable (PCWCHAR dirx_name) } /* Create the nominated hardlink for one indivitual dll, - inside another subdirectory when dynamically loaded. */ + inside another subdirectory when dynamically loaded. + + We've not found a performant way yet to protect fork against + updates to main executables and/or dlls that do not reside on + the same NTFS filesystem as the /var/run/cygfork/ + directory. But as long as the main executable can be hardlinked, + dll redirection works for any other hardlink-able dll, while + non-hardlink-able dlls are used from their original location. */ bool dll::create_forkable () { @@ -465,14 +472,6 @@ dll::create_forkable () if (devhandle == INVALID_HANDLE_VALUE) return false; /* impossible */ - HANDLE fh = dll_list::ntopenfile ((PCWCHAR)&fii.IndexNumber, NULL, - FILE_OPEN_BY_FILE_ID, - FILE_WRITE_ATTRIBUTES, - devhandle); - NtClose (devhandle); - if (fh == INVALID_HANDLE_VALUE) - return false; /* impossible */ - int ntlen = wcslen (ntname); int bufsize = sizeof (FILE_LINK_INFORMATION) + ntlen * sizeof (*ntname); PFILE_LINK_INFORMATION pfli = (PFILE_LINK_INFORMATION) alloca (bufsize); @@ -483,22 +482,47 @@ dll::create_forkable () pfli->ReplaceIfExists = FALSE; /* allow concurrency */ pfli->RootDirectory = NULL; - IO_STATUS_BLOCK iosb; - NTSTATUS status = NtSetInformationFile (fh, &iosb, pfli, bufsize, - FileLinkInformation); - NtClose (fh); - debug_printf ("%y = NtSetInformationFile (%p, FileLink %W, iosb.Status %y)", - status, fh, pfli->FileName, iosb.Status); - if (NT_SUCCESS (status) || status == STATUS_OBJECT_NAME_COLLISION) - /* We've not found a performant way yet to protect fork against updates - to main executables and/or dlls that do not reside on the same NTFS - filesystem as the /var/run/cygfork/ directory. - But as long as the main executable can be hardlinked, dll redirection - works for any other hardlink-able dll, while non-hardlink-able dlls - are used from their original location. */ - return true; + /* When we get STATUS_TRANSACTION_NOT_ACTIVE from hardlink creation, + the current process has renamed the file while it had the readonly + attribute. The rename() function uses a transaction for combined + writeable+rename action if possible to provide atomicity. + Although the transaction is closed afterwards, creating a hardlink + for this file requires the FILE_WRITE_ATTRIBUTES access, for unknown + reason. On the other hand, always requesting FILE_WRITE_ATTRIBUTES + would fail for users that do not own the original file. */ + bool ret = false; + int access = 0; /* first attempt */ + while (true) + { + HANDLE fh = dll_list::ntopenfile ((PCWCHAR)&fii.IndexNumber, NULL, + FILE_OPEN_BY_FILE_ID, + access, + devhandle); + if (fh == INVALID_HANDLE_VALUE) + break; /* impossible */ - return false; + IO_STATUS_BLOCK iosb; + NTSTATUS status = NtSetInformationFile (fh, &iosb, pfli, bufsize, + FileLinkInformation); + NtClose (fh); + debug_printf ("%y = NtSetInformationFile (%p, FileLink %W, iosb.Status %y)", + status, fh, pfli->FileName, iosb.Status); + if (NT_SUCCESS (status) || status == STATUS_OBJECT_NAME_COLLISION) + { + ret = true; + break; + } + + if (status != STATUS_TRANSACTION_NOT_ACTIVE || + access == FILE_WRITE_ATTRIBUTES) + break; + + access = FILE_WRITE_ATTRIBUTES; /* second attempt */ + } + + NtClose (devhandle); + + return ret; } /* return the number of characters necessary to store one forkable name */ From 6d6a623e7d8eb9e521bdbd73a7eafdd482678cea Mon Sep 17 00:00:00 2001 From: Tamar Christina Date: Wed, 6 Feb 2019 11:27:12 +0000 Subject: [PATCH 202/475] AArch32: Add support for HLT to Mixed Mode models The Semihosting v2 protocol requires us to output the Armv8-a HLT instruction when in mixed mode (SEMIHOST_V2_MIXED_MODE), however it also requires this to be done for Armv7-a and earlier architectures. The HLT instruction is defined in the undefined encoding space for older architectures but simulators such as QEMU already trap on it [1] for all architectures and is a requirement for semihosting v2 [2]. Unfortunately the GAS restricts the use of HLT to Armv8-a which requires us to use the instruction encodings we want directly in crt0. This patch does this, I have not updated newlib/libc/* as that is quite out of date already. A proper sync is needed in order to get things back in sync. A different patch for this would be best. [1] https://github.com/qemu/qemu/commit/19a6e31c9d2701ef648b70ddcfc3bf64cec8c37e [2] https://developer.arm.com/docs/100863/latest/the-semihosting-interface --- libgloss/arm/crt0.S | 6 +++--- libgloss/arm/swi.h | 14 ++++++++++---- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/libgloss/arm/crt0.S b/libgloss/arm/crt0.S index 48f3d6b1d..c708f63d8 100644 --- a/libgloss/arm/crt0.S +++ b/libgloss/arm/crt0.S @@ -116,10 +116,10 @@ bkpt AngelSWI #elif defined(__thumb2__) /* We are in thumb mode for startup on armv7 architectures. */ - AngelSWIAsm AngelSWI + AngelSWIAsm (AngelSWI) #else /* We are always in ARM mode for startup on pre armv7 archs. */ - AngelSWIAsm AngelSWI_ARM + AngelSWIAsm (AngelSWI_ARM) #endif ldr r0, .LC0 /* point at values read */ @@ -297,7 +297,7 @@ __change_mode: #else movs r0, #AngelSWI_Reason_GetCmdLine ldr r1, .LC30 /* Space for command line */ - AngelSWIAsm AngelSWI + AngelSWIAsm (AngelSWI) ldr r1, .LC30 ldr r1, [r1] #endif diff --git a/libgloss/arm/swi.h b/libgloss/arm/swi.h index 67eb36b3f..8f50ee7d9 100644 --- a/libgloss/arm/swi.h +++ b/libgloss/arm/swi.h @@ -31,9 +31,9 @@ /* Now the SWI numbers and reason codes for RDI (Angel) monitors. */ #if defined (SEMIHOST_V2) && defined (SEMIHOST_V2_MIXED_MODE) - #define AngelSWI_ARM 0xF000 /* HLT A32. */ + #define AngelSWI_ARM 0xE10F0070 /* HLT #0xF000 A32. */ #ifdef __thumb__ - #define AngelSWI 0x3C /* HLT T32. */ + #define AngelSWI 0xBABC /* HLT #0x3c T32. */ #else /* __thumb__. */ #define AngelSWI AngelSWI_ARM #endif /* __thumb__. */ @@ -49,10 +49,16 @@ /* For thumb only architectures use the BKPT instruction instead of SWI. */ #ifdef THUMB_VXM #define AngelSWIInsn "bkpt" - #define AngelSWIAsm bkpt + #define AngelSWIAsm(IMM) bkpt IMM +#elif defined (SEMIHOST_V2) && defined (SEMIHOST_V2_MIXED_MODE) + /* This is actually encoding the HLT instruction, however we don't have + support for this in older assemblers. So we have to encode the + instruction manually. */ + #define AngelSWIInsn ".inst" + #define AngelSWIAsm(IMM) .inst IMM #else #define AngelSWIInsn "swi" - #define AngelSWIAsm swi + #define AngelSWIAsm(IMM) swi IMM #endif /* The reason codes: */ From 88605243a19bbc2b6b9be36b99f513140b972e38 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Fri, 8 Feb 2019 15:49:47 +0100 Subject: [PATCH 203/475] Cygwin: fix child getting another pid after spawnve When calling spawnve, in contrast to execve, the parent has to create the pid for the child. With the old technique this was simply the Windows pid, but now we have to inform the child about its new pid. Add a cygpid member to class child_info_spawn. Set it in child_info_spawn::worker, just prior to calling CreateProcess rather than afterwards. Overwrite cygheap->pid in child_info_spawn::handle_spawn before calling pinfo::thisproc. Make sure pinfo::thisproc knows the pid is already set by setting the handle argument to INVALID_HANDLE_VALUE. Also set procinfo->dwProcessId to myself_initial.dwProcessId instead of to myself_initial.pid for clarity. Signed-off-by: Corinna Vinschen --- winsup/cygwin/child_info.h | 1 + winsup/cygwin/dcrt0.cc | 7 ++++++- winsup/cygwin/pinfo.cc | 9 +++++++-- winsup/cygwin/spawn.cc | 8 ++------ 4 files changed, 16 insertions(+), 9 deletions(-) diff --git a/winsup/cygwin/child_info.h b/winsup/cygwin/child_info.h index 67264119e..847614ff2 100644 --- a/winsup/cygwin/child_info.h +++ b/winsup/cygwin/child_info.h @@ -144,6 +144,7 @@ class child_info_spawn: public child_info { HANDLE hExeced; HANDLE ev; + pid_t cygpid; public: cygheap_exec_info *moreinfo; int __stdin; diff --git a/winsup/cygwin/dcrt0.cc b/winsup/cygwin/dcrt0.cc index 78506d43d..11edcdf0d 100644 --- a/winsup/cygwin/dcrt0.cc +++ b/winsup/cygwin/dcrt0.cc @@ -652,11 +652,16 @@ child_info_spawn::handle_spawn () cygheap_fixup_in_child (true); memory_init (); } + + cygheap->pid = cygpid; + + /* Spawned process sets h to INVALID_HANDLE_VALUE to notify + pinfo::thisproc not to create another pid. */ if (!moreinfo->myself_pinfo || !DuplicateHandle (GetCurrentProcess (), moreinfo->myself_pinfo, GetCurrentProcess (), &h, 0, FALSE, DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE)) - h = NULL; + h = (type == _CH_SPAWN) ? INVALID_HANDLE_VALUE : NULL; /* Setup our write end of the process pipe. Clear the one in the structure. The destructor should never be called for this but, it can't hurt to be diff --git a/winsup/cygwin/pinfo.cc b/winsup/cygwin/pinfo.cc index 445bd35b2..064299e0c 100644 --- a/winsup/cygwin/pinfo.cc +++ b/winsup/cygwin/pinfo.cc @@ -35,7 +35,7 @@ public: pinfo_basic::pinfo_basic () { - pid = dwProcessId = GetCurrentProcessId (); + dwProcessId = GetCurrentProcessId (); PWCHAR pend = wcpncpy (progname, global_progname, sizeof (progname) / sizeof (WCHAR) - 1); *pend = L'\0'; @@ -57,15 +57,20 @@ pinfo::thisproc (HANDLE h) procinfo = NULL; DWORD flags = PID_IN_USE | PID_ACTIVE; + /* Forked process or process started from non-Cygwin parent needs a pid. */ if (!h) { cygheap->pid = create_cygwin_pid (); flags |= PID_NEW; } + /* spawnve'd process got pid in parent, cygheap->pid has been set in + child_info_spawn::handle_spawn. */ + else if (h == INVALID_HANDLE_VALUE) + h = NULL; init (cygheap->pid, flags, h); procinfo->process_state |= PID_IN_USE; - procinfo->dwProcessId = myself_initial.pid; + procinfo->dwProcessId = myself_initial.dwProcessId; procinfo->sendsig = myself_initial.sendsig; wcscpy (procinfo->progname, myself_initial.progname); create_winpid_symlink (); diff --git a/winsup/cygwin/spawn.cc b/winsup/cygwin/spawn.cc index d969c66ea..ebc34d105 100644 --- a/winsup/cygwin/spawn.cc +++ b/winsup/cygwin/spawn.cc @@ -258,7 +258,6 @@ child_info_spawn::worker (const char *prog_arg, const char *const *argv, int in__stdin, int in__stdout) { bool rc; - pid_t cygpid; int res = -1; /* Check if we have been called from exec{lv}p or spawn{lv}p and mask @@ -578,6 +577,8 @@ child_info_spawn::worker (const char *prog_arg, const char *const *argv, if (!real_path.iscygexec () && mode == _P_OVERLAY) myself->process_state |= PID_NOTCYGWIN; + cygpid = (mode != _P_OVERLAY) ? create_cygwin_pid () : myself->pid; + wchar_t wcmd[(size_t) cmd]; if (!::cygheap->user.issetuid () || (::cygheap->user.saved_uid == ::cygheap->user.real_uid @@ -708,11 +709,6 @@ child_info_spawn::worker (const char *prog_arg, const char *const *argv, if (::cygheap->fdtab.need_fixup_before ()) ::cygheap->fdtab.fixup_before_exec (pi.dwProcessId); - if (mode != _P_OVERLAY) - cygpid = create_cygwin_pid (); - else - cygpid = myself->pid; - /* Print the original program name here so the user can see that too. */ syscall_printf ("pid %d, prog_arg %s, cmd line %.9500s)", rc ? cygpid : (unsigned int) -1, prog_arg, (const char *) cmd); From 7816cf363689a65f6618a57a8190cea0e97efa40 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Fri, 8 Feb 2019 17:48:34 +0100 Subject: [PATCH 204/475] Cygwin: change CURR_CHILD_INFO_MAGIC according to previous patch Signed-off-by: Corinna Vinschen --- winsup/cygwin/child_info.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/winsup/cygwin/child_info.h b/winsup/cygwin/child_info.h index 847614ff2..2fa71ba69 100644 --- a/winsup/cygwin/child_info.h +++ b/winsup/cygwin/child_info.h @@ -37,7 +37,7 @@ enum child_status #define EXEC_MAGIC_SIZE sizeof(child_info) /* Change this value if you get a message indicating that it is out-of-sync. */ -#define CURR_CHILD_INFO_MAGIC 0x3ee00652U +#define CURR_CHILD_INFO_MAGIC 0xf4531879U #define NPROCS 256 From 0be0b8f0335ec0fad6188b3570dffeba4ec94fea Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Sat, 9 Feb 2019 15:36:02 +0100 Subject: [PATCH 205/475] Cygwin: execve: fix setting O_APPEND file offset for native child dtable::set_file_pointers_for_exec is called from child_info_spawn::worker to move the file position of O_APPEND files to EOF if the child is a native child. However, this only works correctly for the first O_APPEND file descriptor: - set_file_pointers_for_exec calls SetFilePointer. The higher 4 bytes of the desired file offset are given to SetFilePointer as pointer to a DWORD value. On return, SetFilePointer returns the higher 4 bytes of the new file position in this DWORD. - So for the second and subsequent descriptors the higher 4 byte of the file position depend on what the actual file position of the previous file has been set to: - If the file is > 2 Gigs, the high offset will not be 0 anymore. - If the desciptor points to a non-seekable file (i.e., a pipe or socket), SetFilePosition returns an error and sets the high position to -1. Fix this by calling SetFilePointerEx instead, which does not modify the incoming position value. Signed-off-by: Corinna Vinschen --- winsup/cygwin/dtable.cc | 5 +++-- winsup/cygwin/release/3.0 | 3 +++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/winsup/cygwin/dtable.cc b/winsup/cygwin/dtable.cc index 663f99b34..86e0c716d 100644 --- a/winsup/cygwin/dtable.cc +++ b/winsup/cygwin/dtable.cc @@ -857,12 +857,13 @@ dtable::set_file_pointers_for_exec () { /* This is not POSIX-compliant so the function is only called for non-Cygwin processes. */ - LONG off_high = 0; + LARGE_INTEGER eof = { QuadPart: 0 }; + lock (); fhandler_base *fh; for (size_t i = 0; i < size; i++) if ((fh = fds[i]) != NULL && fh->get_flags () & O_APPEND) - SetFilePointer (fh->get_handle (), 0, &off_high, FILE_END); + SetFilePointerEx (fh->get_handle (), eof, NULL, FILE_END); unlock (); } diff --git a/winsup/cygwin/release/3.0 b/winsup/cygwin/release/3.0 index 4cd422a56..da0fe0961 100644 --- a/winsup/cygwin/release/3.0 +++ b/winsup/cygwin/release/3.0 @@ -100,3 +100,6 @@ Bug Fixes - Fix exception handling in pthreads. Addresses: https://cygwin.com/ml/cygwin/2019-01/msg00149.html + +- Fix O_APPEND handling on files when calling non-Cygwin applications + Addresses: https://cygwin.com/ml/cygwin/2019-02/msg00081.html From 52d91f112ec2e5dd62edd200ca547bb11e52effa Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Sat, 9 Feb 2019 18:41:47 +0100 Subject: [PATCH 206/475] Cygwin: disk device: stop using SetFilePointer This is a really old and crappy API, as the previous commit shows. Use NtQueryInformationFile(FilePositionInformation) here instead. Signed-off-by: Corinna Vinschen --- winsup/cygwin/fhandler_floppy.cc | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/winsup/cygwin/fhandler_floppy.cc b/winsup/cygwin/fhandler_floppy.cc index cca00bab8..43139ac2c 100644 --- a/winsup/cygwin/fhandler_floppy.cc +++ b/winsup/cygwin/fhandler_floppy.cc @@ -384,9 +384,12 @@ fhandler_dev_floppy::dup (fhandler_base *child, int flags) inline off_t fhandler_dev_floppy::get_current_position () { - LARGE_INTEGER off = { QuadPart: 0LL }; - off.LowPart = SetFilePointer (get_handle (), 0, &off.HighPart, FILE_CURRENT); - return off.QuadPart; + IO_STATUS_BLOCK io; + FILE_POSITION_INFORMATION fpi = { { QuadPart : 0LL } }; + + NtQueryInformationFile (get_handle (), &io, &fpi, sizeof fpi, + FilePositionInformation); + return fpi.CurrentByteOffset.QuadPart; } void __reg3 From 1ba66fe8fa94b2148c12beae9948b0cdf6bf1ffa Mon Sep 17 00:00:00 2001 From: Tamar Christina Date: Fri, 8 Feb 2019 17:13:24 +0000 Subject: [PATCH 207/475] AArch32: Fix the build for M class semihosting The M class cores don't support Semihosting v2 mixed mode, but we were accidentally using the new immediates for it. My last patch changed the immediates which broke the build because doing a full multi-lib build including M architectures now results in an assembler error instead of silently doing the wrong thing. This fixes the issue by changing the defines around such that According to the specs any M class build uses the normal semihosting instructions. Regtested on arm-none-eabi and no issues, using a build with m class multilibs too. --- libgloss/arm/swi.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libgloss/arm/swi.h b/libgloss/arm/swi.h index 8f50ee7d9..267d164d2 100644 --- a/libgloss/arm/swi.h +++ b/libgloss/arm/swi.h @@ -30,7 +30,9 @@ /* Now the SWI numbers and reason codes for RDI (Angel) monitors. */ -#if defined (SEMIHOST_V2) && defined (SEMIHOST_V2_MIXED_MODE) +#if defined (SEMIHOST_V2) \ + && defined (SEMIHOST_V2_MIXED_MODE) \ + && !defined (THUMB_VXM) #define AngelSWI_ARM 0xE10F0070 /* HLT #0xF000 A32. */ #ifdef __thumb__ #define AngelSWI 0xBABC /* HLT #0x3c T32. */ From f6be530a23789124f4eb0bbab3b87a7b1335057a Mon Sep 17 00:00:00 2001 From: Michael Haubenwallner Date: Fri, 8 Feb 2019 15:38:56 +0100 Subject: [PATCH 208/475] Cygwin: forkables: update doc, add release notes --- winsup/cygwin/release/3.0 | 6 ++++++ winsup/doc/highlights.xml | 26 ++++++++++++++++---------- winsup/doc/new-features.xml | 7 +++++++ 3 files changed, 29 insertions(+), 10 deletions(-) diff --git a/winsup/cygwin/release/3.0 b/winsup/cygwin/release/3.0 index da0fe0961..da357558d 100644 --- a/winsup/cygwin/release/3.0 +++ b/winsup/cygwin/release/3.0 @@ -31,6 +31,12 @@ What's new: - New APIs: signalfd, timerfd_create, timerfd_gettime, timerfd_settime, timer_getoverrun. +- fork(2) now is able to recover from when an in-use executable/dll is + removed or replaced during process runtime. This feature is disabled by + default and limited to exes/dlls on the same NTFS partition as the Cygwin + installation. For more information and how to enable, please refer to + https://www.cygwin.com/cygwin-ug-net/highlights.html#ov-hi-process + What changed: ------------- diff --git a/winsup/doc/highlights.xml b/winsup/doc/highlights.xml index 25b227382..67e326cb4 100644 --- a/winsup/doc/highlights.xml +++ b/winsup/doc/highlights.xml @@ -202,21 +202,27 @@ While Windows does not allow to remove binaries in use from the file system, they still can be renamed or moved into the recycle bin, as outlined for unlink(2) in . To allow an existing process to fork, the original binary files need to be -available via their original file names, but they may reside in -different directories when using the DotLocal (.local) Dll Redirection feature. Since NTFS does support hardlinks, when the fork fails we try again, but create a private directory containing hardlinks to the original files as -well as the .local file now. The private directory for the hardlinks is -/var/run/cygfork/, which you have to create manually for now if you need to -protect fork against exe- and dll- updates on your Cygwin instance. As -hardlinks cannot be used across multiple NTFS file systems, please make sure -your exe- and dll- replacing operations operate on the same single NTFS file -system as your Cygwin instance and the /var/run/cygfork/ directory. +well as the .local file now. The base directory for the +private hardlink directory is /var/run/cygfork/, which +you have to create manually for now if you need to protect fork against +updates to executables and dlls on your Cygwin instance. As hardlinks +cannot be used across multiple NTFS file systems, please make sure your +executable and dll replacing operations operate on the same single NTFS file +system as your Cygwin instance and the /var/run/cygfork/ +directory. Note that this private hardlink directory also does help for +when a wrong dll is found in the parent process' current working directory. +To enable creating the hardlinks, you need to stop all currently running +Cygwin processes after creating this directory, once per Cygwin installation: +$ mkdir --mode=a=rwxt /var/run/cygfork -We create one directory per user, application and application age, -and remove it when no more processes use that directory. To indicate +We create one hardlink directory per user, application and application +age, and remove it when no more processes use that directory. To indicate whether a directory still is in use, we define a mutex name similar to the directory name. As mutexes are destroyed when no process holds a handle open any more, we can clean up even after power loss or similar: diff --git a/winsup/doc/new-features.xml b/winsup/doc/new-features.xml index 6801e3eeb..8fc0ac6fe 100644 --- a/winsup/doc/new-features.xml +++ b/winsup/doc/new-features.xml @@ -107,6 +107,13 @@ Native Windows processes not started by Cygwin processes are mapped into the range beyond 65535. + +fork(2) now is able to recover from when an in-use executable/dll is +removed or replaced during process runtime. This feature is disabled by +default and limited to exes/dlls on the same NTFS partition as the Cygwin +installation. For more information and how to enable, please refer to +. + From 43fa1aafa6cec04d85ca0c08a9a293ada9bd3aad Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Wed, 13 Feb 2019 11:10:41 +0100 Subject: [PATCH 209/475] Cygwin: uinfo.cc: fix formatting Signed-off-by: Corinna Vinschen --- winsup/cygwin/uinfo.cc | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/winsup/cygwin/uinfo.cc b/winsup/cygwin/uinfo.cc index 8dcf731de..22cae5e04 100644 --- a/winsup/cygwin/uinfo.cc +++ b/winsup/cygwin/uinfo.cc @@ -651,7 +651,7 @@ cygheap_pwdgrp::init () && strchr (" \t", c[sizeof(s)-1])) /* The /etc/nsswitch.conf file is read exactly once by the root process of a - process tree. We can't afford methodical changes during the lifetime of a + process tree. We can't afford methodical changes during the lifetime of a process tree. */ void cygheap_pwdgrp::nss_init_line (const char *line) @@ -778,7 +778,7 @@ cygheap_pwdgrp::nss_init_line (const char *line) *spc = L'\0'; } else - new_enums &= ~(ENUM_TDOMS | ENUM_TDOMS_ALL); + new_enums &= ~(ENUM_TDOMS | ENUM_TDOMS_ALL); } enums = new_enums; } @@ -896,7 +896,7 @@ fetch_windows_home (cyg_ldap *pldap, PUSER_INFO_3 ui, cygpsid &sid, WCHAR sidstr[128]; if (get_user_profile_directory (sid.string (sidstr), profile, MAX_PATH)) - home = (char *) cygwin_create_path (CCP_WIN_W_TO_POSIX, profile); + home = (char *) cygwin_create_path (CCP_WIN_W_TO_POSIX, profile); } return home; } @@ -950,9 +950,9 @@ fetch_from_path (cyg_ldap *pldap, PUSER_INFO_3 ui, cygpsid &sid, PCWSTR str, while (*str && w < we) { if (*str != L'%') - *w++ = *str++; + *w++ = *str++; else - { + { switch (*++str) { case L'u': @@ -1135,7 +1135,7 @@ cygheap_pwdgrp::get_shell (cyg_ldap *pldap, cygpsid &sid, PCWSTR dom, break; case NSS_SCHEME_PATH: shell = fetch_from_path (pldap, NULL, sid, shell_scheme[idx].attrib, - dom, dnsdomain, name, full_qualified); + dom, dnsdomain, name, full_qualified); break; case NSS_SCHEME_FREEATTR: if (pldap->fetch_ad_account (sid, false, dnsdomain)) @@ -1547,7 +1547,7 @@ pwdgrp::add_account_post_fetch (char *line, bool lock) void *ret = NULL; if (line) - { + { if (lock) pglock.init ("pglock")->acquire (); if (add_line (line)) @@ -1645,16 +1645,16 @@ pwdgrp::add_group_from_windows (fetch_acc_t &full_acc, cyg_ldap *pldap) /* Check if file exists and if it has been written to since last checked. If file has been changed, invalidate the current cache. - + If the file doesn't exist when this function is called the first time, by the first Cygwin process in a process tree, the file will never be visited again by any process in this process tree. This is important, because we cannot allow a change of UID/GID values for the lifetime of a process tree. - + If the file gets deleted or unreadable, the file cache will stay in place, but we won't try to read new accounts from the file. - + The return code indicates to the calling function if the file exists. */ bool pwdgrp::check_file () @@ -1961,7 +1961,7 @@ pwdgrp::fetch_account_from_windows (fetch_user_arg_t &arg, cyg_ldap *pldap) *wcpncpy (dom, arg.full_acc->dom->Buffer, arg.full_acc->dom->Length / sizeof (WCHAR)) = L'\0'; acc_type = arg.full_acc->acc_type; - ret = acc_type != SidTypeUnknown; + ret = acc_type != SidTypeUnknown; } break; case SID_arg: @@ -2280,13 +2280,13 @@ pwdgrp::fetch_account_from_windows (fetch_user_arg_t &arg, cyg_ldap *pldap) && (sid_sub_auth_count (sid) <= 3 || sid_id_auth (sid) == 11)) acc_type = SidTypeWellKnownGroup; switch ((int) acc_type) - { + { case SidTypeUser: if (is_group ()) { /* Don't allow users as group. While this is technically possible, it doesn't make sense in a POSIX scenario. - + Microsoft Accounts as well as AzureAD accounts have the primary group SID in their user token set to their own user SID. @@ -2467,7 +2467,7 @@ pwdgrp::fetch_account_from_windows (fetch_user_arg_t &arg, cyg_ldap *pldap) WCHAR server[INTERNET_MAX_HOST_NAME_LENGTH + 3]; NET_API_STATUS nas; PUSER_INFO_3 ui; - + if (!get_logon_server (cygheap->dom.primary_flat_name (), server, DS_IS_FLAT_NAME)) break; @@ -2636,7 +2636,7 @@ pwdgrp::fetch_account_from_windows (fetch_user_arg_t &arg, cyg_ldap *pldap) default: return NULL; } - } + } else if (sid_id_auth (sid) == 0 && sid_sub_auth (sid, 0) == 0xfffe) { /* Special case "nobody" for reproducible construction of a @@ -2683,7 +2683,7 @@ pwdgrp::fetch_account_from_windows (fetch_user_arg_t &arg, cyg_ldap *pldap) else if (sid_id_auth (sid) == 18) { /* Authentication assertion SIDs. - + Available when using a 2012R2 DC, but not supported by LookupAccountXXX on pre Windows 8/2012 machines */ uid = 0x11200 + sid_sub_auth_rid (sid); From 9a3cc77b2afc52a2faa5e4daeb59dfd4506c0693 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Wed, 13 Feb 2019 11:10:55 +0100 Subject: [PATCH 210/475] Cygwin: passwd/group: store account name case correct When looking up valid accounts by name, LookupAccountName returns a SID and a case-correct domain name. However, the name was input and LookupAccountName is case-insensitive, so the name is not necessarily written the same way as in SAM or AD. Fix that by doing a reverse lookup on the just fetched SID. This fetches the account name in the correct case. Override the incoming name with the case correct name from LookupAccountSid. Signed-off-by: Corinna Vinschen --- winsup/cygwin/release/3.0 | 4 ++++ winsup/cygwin/uinfo.cc | 10 ++++++++++ 2 files changed, 14 insertions(+) diff --git a/winsup/cygwin/release/3.0 b/winsup/cygwin/release/3.0 index da357558d..444e71a94 100644 --- a/winsup/cygwin/release/3.0 +++ b/winsup/cygwin/release/3.0 @@ -109,3 +109,7 @@ Bug Fixes - Fix O_APPEND handling on files when calling non-Cygwin applications Addresses: https://cygwin.com/ml/cygwin/2019-02/msg00081.html + +- Fix case correctness of passwd/group entries fetched via getpwnam + or getgrnam. + Addresses: https://cygwin.com/ml/cygwin/2019-02/msg00109.html diff --git a/winsup/cygwin/uinfo.cc b/winsup/cygwin/uinfo.cc index 22cae5e04..4a5fa3470 100644 --- a/winsup/cygwin/uinfo.cc +++ b/winsup/cygwin/uinfo.cc @@ -2046,6 +2046,16 @@ pwdgrp::fetch_account_from_windows (fetch_user_arg_t &arg, cyg_ldap *pldap) /* We can skip the backslash in the rest of this function. */ if (p) name = p + 1; + /* Reverse lookup name from sid to make sure the username in + our passwd/group data is written exactly as in the user DB. */ + nlen = UNLEN + 1; + dlen = DNLEN + 1; + ret = LookupAccountSidW (NULL, sid, name, &nlen, dom, &dlen, &acc_type); + if (!ret) + { + system_printf ("LookupAccountNameW (%W), %E", name); + return NULL; + } /* Last but not least, some validity checks on the name style. */ if (!fq_name) { From 507982af79847f44c763ff70db15104d78174b2e Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Wed, 13 Feb 2019 12:41:55 +0100 Subject: [PATCH 211/475] Cygwin: passwd/group: raise local name buffer size Make sure a domain+username fits into the local name buffer. The former buffer size didn't take adding a domain name to a really_really_long_user_name into account. Signed-off-by: Corinna Vinschen --- winsup/cygwin/uinfo.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/winsup/cygwin/uinfo.cc b/winsup/cygwin/uinfo.cc index 4a5fa3470..b70e384f3 100644 --- a/winsup/cygwin/uinfo.cc +++ b/winsup/cygwin/uinfo.cc @@ -1919,7 +1919,7 @@ char * pwdgrp::fetch_account_from_windows (fetch_user_arg_t &arg, cyg_ldap *pldap) { /* Used in LookupAccount calls. */ - WCHAR namebuf[UNLEN + 1], *name = namebuf; + WCHAR namebuf[DNLEN + 1 + UNLEN + 1], *name = namebuf; WCHAR dom[DNLEN + 1] = L""; cygsid csid; DWORD nlen = UNLEN + 1; From 09bbcf8788692f927b6c07c0ea812e7a5eff3b84 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Wed, 13 Feb 2019 12:42:56 +0100 Subject: [PATCH 212/475] Cygwin: passwd/group: rename get_group_name to get_account_name The function is the same for user and grou accounts. Signed-off-by: Corinna Vinschen --- winsup/cygwin/ldap.h | 3 +-- winsup/cygwin/uinfo.cc | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/winsup/cygwin/ldap.h b/winsup/cygwin/ldap.h index 993f5100c..4c2437a6f 100644 --- a/winsup/cygwin/ldap.h +++ b/winsup/cygwin/ldap.h @@ -60,8 +60,7 @@ public: /* User only */ gid_t get_primary_gid () { return get_num_attribute (L"primaryGroupID"); } gid_t get_unix_uid () { return get_num_attribute (L"uidNumber"); } - /* group only */ - PWCHAR get_group_name () + PWCHAR get_account_name () { return get_string_attribute (L"sAMAccountName"); } gid_t get_unix_gid () { return get_num_attribute (L"gidNumber"); } }; diff --git a/winsup/cygwin/uinfo.cc b/winsup/cygwin/uinfo.cc index b70e384f3..681a9f714 100644 --- a/winsup/cygwin/uinfo.cc +++ b/winsup/cygwin/uinfo.cc @@ -1980,7 +1980,7 @@ pwdgrp::fetch_account_from_windows (fetch_user_arg_t &arg, cyg_ldap *pldap) PWCHAR val; if (cldap->fetch_ad_account (sid, true) - && (val = cldap->get_group_name ())) + && (val = cldap->get_account_name ())) { wcpcpy (name, val); wcpcpy (dom, L"BUILTIN"); From 79c4e95fad48111d2b04b2be183324d630d9d1a3 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Wed, 13 Feb 2019 12:43:25 +0100 Subject: [PATCH 213/475] Cygwin: ldap.cc: fix formatting Signed-off-by: Corinna Vinschen --- winsup/cygwin/ldap.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/winsup/cygwin/ldap.cc b/winsup/cygwin/ldap.cc index 6ccf8998c..dcd4fc461 100644 --- a/winsup/cygwin/ldap.cc +++ b/winsup/cygwin/ldap.cc @@ -242,7 +242,7 @@ ULONG cyg_ldap::search_s (PWCHAR base, ULONG scope, PWCHAR filter, PWCHAR *attrs) { ULONG ret; - + if ((ret = ldap_search_sW (lh, base, scope, filter, attrs, 0, &msg)) != LDAP_SUCCESS) debug_printf ("ldap_search_sW(%W,%W) error 0x%02x", base, filter, ret); @@ -279,7 +279,7 @@ cyg_ldap::next_page_s () { ULONG total; ULONG ret; - + do { ret = ldap_get_next_page_s (lh, srch_id, NULL, CYG_LDAP_ENUM_PAGESIZE, @@ -337,7 +337,7 @@ cyg_ldap::open (PCWSTR domain) if (!(def_context = wcsdup (val[0]))) { debug_printf ("wcsdup(%W, %W) %d", domain, rootdse_attr[0], - get_errno ()); + get_errno ()); goto err; } ldap_value_freeW (val); From 4e34a39b5cdf4c3f889486b7460bea063e579d10 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Wed, 13 Feb 2019 13:16:15 +0100 Subject: [PATCH 214/475] Cygwin: passwd/group: store account name case correct, take 2 The solution from commit 9a3cc77b2afc52a2faa5e4daeb59dfd4506c0693 didn't work for foreign domain accounts. Rather than calling LookupAccountSid we now use the info when we fetch it anyway via LDAP or Net*GetInfo. Only in case of domain groups we have to add an LDAP call explicitly. Signed-off-by: Corinna Vinschen --- winsup/cygwin/uinfo.cc | 41 +++++++++++++++++++++++------------------ 1 file changed, 23 insertions(+), 18 deletions(-) diff --git a/winsup/cygwin/uinfo.cc b/winsup/cygwin/uinfo.cc index 681a9f714..53efc2117 100644 --- a/winsup/cygwin/uinfo.cc +++ b/winsup/cygwin/uinfo.cc @@ -1941,6 +1941,7 @@ pwdgrp::fetch_account_from_windows (fetch_user_arg_t &arg, cyg_ldap *pldap) char *gecos = NULL; /* Temporary stuff. */ PWCHAR p; + PWCHAR val; WCHAR sidstr[128]; ULONG posix_offset = 0; uint32_t id_val; @@ -1977,8 +1978,6 @@ pwdgrp::fetch_account_from_windows (fetch_user_arg_t &arg, cyg_ldap *pldap) can't be resolved, and if we're a domain member machine, ask a DC. Do *not* use LookupAccountSidW. It can take ages when called on a DC for some weird reason. Use LDAP instead. */ - PWCHAR val; - if (cldap->fetch_ad_account (sid, true) && (val = cldap->get_account_name ())) { @@ -2046,16 +2045,6 @@ pwdgrp::fetch_account_from_windows (fetch_user_arg_t &arg, cyg_ldap *pldap) /* We can skip the backslash in the rest of this function. */ if (p) name = p + 1; - /* Reverse lookup name from sid to make sure the username in - our passwd/group data is written exactly as in the user DB. */ - nlen = UNLEN + 1; - dlen = DNLEN + 1; - ret = LookupAccountSidW (NULL, sid, name, &nlen, dom, &dlen, &acc_type); - if (!ret) - { - system_printf ("LookupAccountNameW (%W), %E", name); - return NULL; - } /* Last but not least, some validity checks on the name style. */ if (!fq_name) { @@ -2438,18 +2427,28 @@ pwdgrp::fetch_account_from_windows (fetch_user_arg_t &arg, cyg_ldap *pldap) if (is_domain_account) { - /* Skip this when creating group entries and for non-users. */ + /* Overwrite group name to be sure case is same as in SAM */ + if (is_group() + && cldap->fetch_ad_account (sid, true, domain) + && (val = cldap->get_account_name ())) + wcscpy (name, val); + /* Skip the rest if creating group entries and for non-users. */ if (is_group() || acc_type != SidTypeUser) break; /* On AD machines, use LDAP to fetch domain account infos. */ if (cygheap->dom.primary_dns_name ()) { - /* For the current user we got the primary group from the - user token. For any other user we fetch it from AD. */ + /* For the current user we got correctly cased username and + the primary group via process token. For any other user + we fetch it from AD and overwrite it. */ if (!is_current_user - && cldap->fetch_ad_account (sid, false, domain) - && (id_val = cldap->get_primary_gid ()) != ILLEGAL_GID) - gid = posix_offset + id_val; + && cldap->fetch_ad_account (sid, false, domain)) + { + if ((val = cldap->get_account_name ())) + wcscpy (name, val); + if ((id_val = cldap->get_primary_gid ()) != ILLEGAL_GID) + gid = posix_offset + id_val; + } home = cygheap->pg.get_home (cldap, sid, dom, domain, name, fully_qualified_name); shell = cygheap->pg.get_shell (cldap, sid, dom, domain, @@ -2487,6 +2486,8 @@ pwdgrp::fetch_account_from_windows (fetch_user_arg_t &arg, cyg_ldap *pldap) debug_printf ("NetUserGetInfo(%W) %u", name, nas); break; } + /* Overwrite name to be sure case is same as in SAM */ + wcscpy (name, ui->usri3_name); gid = posix_offset + ui->usri3_primary_group_id; home = cygheap->pg.get_home (ui, sid, dom, name, fully_qualified_name); @@ -2513,6 +2514,8 @@ pwdgrp::fetch_account_from_windows (fetch_user_arg_t &arg, cyg_ldap *pldap) debug_printf ("NetUserGetInfo(%W) %u", name, nas); break; } + /* Overwrite name to be sure case is same as in SAM */ + wcscpy (name, ui->usri3_name); /* Fetch user attributes. */ home = cygheap->pg.get_home (ui, sid, dom, name, fully_qualified_name); @@ -2533,6 +2536,8 @@ pwdgrp::fetch_account_from_windows (fetch_user_arg_t &arg, cyg_ldap *pldap) debug_printf ("NetLocalGroupGetInfo(%W) %u", name, nas); break; } + /* Overwrite name to be sure case is same as in SAM */ + wcscpy (name, gi->lgrpi1_name); /* Fetch unix gid from comment field. */ uxid = fetch_from_description (gi->lgrpi1_comment, L"unix=\"", 6); From 538e7abc3697c4d482ad3017169fe9fa6cbb1bcf Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Sat, 16 Feb 2019 18:11:16 +0100 Subject: [PATCH 215/475] Cygwin: bump version to 3.0.1 Signed-off-by: Corinna Vinschen --- winsup/cygwin/include/cygwin/version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/winsup/cygwin/include/cygwin/version.h b/winsup/cygwin/include/cygwin/version.h index 8926d49ae..2f887f055 100644 --- a/winsup/cygwin/include/cygwin/version.h +++ b/winsup/cygwin/include/cygwin/version.h @@ -11,7 +11,7 @@ details. */ changes to the DLL and is mainly informative in nature. */ #define CYGWIN_VERSION_DLL_MAJOR 3000 -#define CYGWIN_VERSION_DLL_MINOR 0 +#define CYGWIN_VERSION_DLL_MINOR 1 /* Major numbers before CYGWIN_VERSION_DLL_EPOCH are incompatible. */ From 7c34811440be0bf1e749d9f075f54320c706cb4b Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Sat, 16 Feb 2019 18:36:21 +0100 Subject: [PATCH 216/475] Cygwin: passwd/group: allow specifying "." as local computername Convenience only. The resulting passwd/group antry is still fully qualified. Signed-off-by: Corinna Vinschen --- winsup/cygwin/uinfo.cc | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/winsup/cygwin/uinfo.cc b/winsup/cygwin/uinfo.cc index 53efc2117..47fe24725 100644 --- a/winsup/cygwin/uinfo.cc +++ b/winsup/cygwin/uinfo.cc @@ -2008,7 +2008,15 @@ pwdgrp::fetch_account_from_windows (fetch_user_arg_t &arg, cyg_ldap *pldap) if ((p = wcschr (name, cygheap->pg.nss_separator ()[0]))) { fq_name = true; - *p = L'\\'; + /* Convenience: Translate domain name "." to local machine. */ + if (p == name + 1 && name[0] == L'.') + { + p = wcpcpy (name, cygheap->dom.account_flat_name ()); + *p = L'\\'; + sys_mbstowcs (p + 1, UNLEN + 1, arg.name + 2); + } + else + *p = L'\\'; } sid = csid; ret = LookupAccountNameW (NULL, name, sid, &slen, dom, &dlen, &acc_type); From 7e671e75787777c9ab8a1144a10c1187b7ced984 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Sun, 17 Feb 2019 22:51:21 +0100 Subject: [PATCH 217/475] Cygwin: fork: add PROCESS_VM_OPERATION to child process permissions ...on parent process. This is required for successful mmap propagation. Signed-off-by: Corinna Vinschen --- winsup/cygwin/release/3.0.1 | 13 +++++++++++++ winsup/cygwin/sigproc.cc | 2 +- 2 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 winsup/cygwin/release/3.0.1 diff --git a/winsup/cygwin/release/3.0.1 b/winsup/cygwin/release/3.0.1 new file mode 100644 index 000000000..ae6e03ea6 --- /dev/null +++ b/winsup/cygwin/release/3.0.1 @@ -0,0 +1,13 @@ +What's new: +----------- + + +What changed: +------------- + + +Bug Fixes +--------- + +- Relax fork child permissions to avoid a potential fork failure. + Addresses: https://cygwin.com/ml/cygwin/2019-02/msg00234.html diff --git a/winsup/cygwin/sigproc.cc b/winsup/cygwin/sigproc.cc index 30dfaaa25..3b6492bb4 100644 --- a/winsup/cygwin/sigproc.cc +++ b/winsup/cygwin/sigproc.cc @@ -815,7 +815,7 @@ child_info::child_info (unsigned in_cb, child_info_types chtype, we're forking, we also need handle duplicate access. */ parent = NULL; DWORD perms = PROCESS_QUERY_LIMITED_INFORMATION | PROCESS_VM_READ - | SYNCHRONIZE; + | PROCESS_VM_OPERATION | SYNCHRONIZE; if (type == _CH_FORK) { perms |= PROCESS_DUP_HANDLE; From 5e6ce1cfb212a6dd71790933186275081cffe3c3 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Sun, 17 Feb 2019 22:59:36 +0100 Subject: [PATCH 218/475] Cygwin: utils: kill: revert erroneously removed optind correction When recognizing a negative pid, optind is off by one. The code correcting this has been erroneously removed by commit 8de660271fe75a6993f1c9888d24b824bb7f999d. Revert that. Signed-off-by: Corinna Vinschen --- winsup/cygwin/release/3.0.1 | 3 +++ winsup/utils/kill.cc | 5 ++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/winsup/cygwin/release/3.0.1 b/winsup/cygwin/release/3.0.1 index ae6e03ea6..fd6595b98 100644 --- a/winsup/cygwin/release/3.0.1 +++ b/winsup/cygwin/release/3.0.1 @@ -11,3 +11,6 @@ Bug Fixes - Relax fork child permissions to avoid a potential fork failure. Addresses: https://cygwin.com/ml/cygwin/2019-02/msg00234.html + +- Fix Command-line argument handling of kill(1) in terms of negative PID. + Addresses: report on IRC diff --git a/winsup/utils/kill.cc b/winsup/utils/kill.cc index 768ac44e7..a22d70253 100644 --- a/winsup/utils/kill.cc +++ b/winsup/utils/kill.cc @@ -251,7 +251,10 @@ main (int argc, char **argv) break; case '?': if (gotasig) /* this is a negative pid, go ahead */ - goto out; + { + --optind; + goto out; + } optreset = 1; optind = 1 + av - argv; gotasig = *av + 1; From f76c8519ac662e244ab4c1c14d9f809c08e384b4 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Mon, 18 Feb 2019 10:03:19 +0100 Subject: [PATCH 219/475] Cygwin: mount: remove unused method mount_info::set_flags_from_win32_path Signed-off-by: Corinna Vinschen --- winsup/cygwin/mount.cc | 15 --------------- winsup/cygwin/mount.h | 1 - 2 files changed, 16 deletions(-) diff --git a/winsup/cygwin/mount.cc b/winsup/cygwin/mount.cc index 146b2b6cd..ea8987516 100644 --- a/winsup/cygwin/mount.cc +++ b/winsup/cygwin/mount.cc @@ -987,21 +987,6 @@ out: return 0; } -/* Return flags associated with a mount point given the win32 path. */ - -unsigned -mount_info::set_flags_from_win32_path (const char *p) -{ - for (int i = 0; i < nmounts; i++) - { - mount_item &mi = mount[native_sorted[i]]; - if (path_prefix_p (mi.native_path, p, mi.native_pathlen, - mi.flags & MOUNT_NOPOSIX)) - return mi.flags; - } - return MOUNT_BINARY; -} - inline char * skip_ws (char *in) { diff --git a/winsup/cygwin/mount.h b/winsup/cygwin/mount.h index 86e1b19c1..122a679a8 100644 --- a/winsup/cygwin/mount.h +++ b/winsup/cygwin/mount.h @@ -189,7 +189,6 @@ class mount_info int add_item (const char *dev, const char *path, unsigned flags); int del_item (const char *path, unsigned flags); - unsigned set_flags_from_win32_path (const char *path); int conv_to_win32_path (const char *src_path, char *dst, device&, unsigned *flags = NULL); int conv_to_posix_path (PWCHAR src_path, char *posix_path, int ccp_flags); From 367c1ae16185e7a81aea5bcc2388e4a7a473c92e Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Mon, 18 Feb 2019 10:12:07 +0100 Subject: [PATCH 220/475] Cygwin: mount: define binary mount as default Commit c1023ee353705671aa9a8e4e1179022277add2aa changed the way path_conv::binmode() works. Rather than returning three states, O_BINARY, O_TEXT, 0, it only returned 2 states, O_BINARY, O_TEXT. Since mounts are only binary if they are explicitely mounted binary by setting the MOUNT_BINARY flag, textmode is default. This introduced a new bug. When inheriting stdio HANDLEs from native Windows processes, the fhandler and its path_conv are created from a device struct only. None of the path or mount flags get set this way. So the mount flags are 0 and path_conv::binmode() returned 0. After the path_conv::binmode() change it returned O_TEXT since, as explained above, the default mount mode is textmode. Rather than just enforcing binary mode for path_conv's created from device structs, this patch changes the default mount mode to binary: Replace MOUNT_BINARY flag with MOUNT_TEXT flag with opposite meaning. Drop all explicit setting of MOUNT_BINARY. Drop local set_flags function, it doesn't add any value. Signed-off-by: Corinna Vinschen --- winsup/cygwin/include/sys/mount.h | 2 +- winsup/cygwin/mount.cc | 45 +++++++++++++------------------ winsup/cygwin/path.h | 4 +-- winsup/cygwin/release/3.0.1 | 4 +++ 4 files changed, 24 insertions(+), 31 deletions(-) diff --git a/winsup/cygwin/include/sys/mount.h b/winsup/cygwin/include/sys/mount.h index 506158011..0c4e078bf 100644 --- a/winsup/cygwin/include/sys/mount.h +++ b/winsup/cygwin/include/sys/mount.h @@ -22,7 +22,7 @@ extern "C" { enum { - MOUNT_BINARY = _BIT ( 1), /* "binary" format read/writes */ + MOUNT_TEXT = _BIT ( 0), /* "binary" format read/writes */ MOUNT_SYSTEM = _BIT ( 3), /* mount point came from system table */ MOUNT_EXEC = _BIT ( 4), /* Any file in the mounted directory gets 'x' bit */ diff --git a/winsup/cygwin/mount.cc b/winsup/cygwin/mount.cc index ea8987516..e0349815d 100644 --- a/winsup/cygwin/mount.cc +++ b/winsup/cygwin/mount.cc @@ -473,13 +473,13 @@ mount_info::create_root_entry (const PWCHAR root) sys_wcstombs (native_root, PATH_MAX, root); assert (*native_root != '\0'); if (add_item (native_root, "/", - MOUNT_SYSTEM | MOUNT_BINARY | MOUNT_IMMUTABLE | MOUNT_AUTOMATIC) + MOUNT_SYSTEM | MOUNT_IMMUTABLE | MOUNT_AUTOMATIC) < 0) api_fatal ("add_item (\"%s\", \"/\", ...) failed, errno %d", native_root, errno); /* Create a default cygdrive entry. Note that this is a user entry. This allows to override it with mount, unless the sysadmin created a cygdrive entry in /etc/fstab. */ - cygdrive_flags = MOUNT_BINARY | MOUNT_NOPOSIX | MOUNT_CYGDRIVE; + cygdrive_flags = MOUNT_NOPOSIX | MOUNT_CYGDRIVE; strcpy (cygdrive, CYGWIN_INFO_CYGDRIVE_DEFAULT_PREFIX "/"); cygdrive_len = strlen (cygdrive); } @@ -508,32 +508,23 @@ mount_info::init (bool user_init) if (!got_usr_bin) { stpcpy (p, "\\bin"); - add_item (native, "/usr/bin", - MOUNT_SYSTEM | MOUNT_BINARY | MOUNT_AUTOMATIC); + add_item (native, "/usr/bin", MOUNT_SYSTEM | MOUNT_AUTOMATIC); } if (!got_usr_lib) { stpcpy (p, "\\lib"); - add_item (native, "/usr/lib", - MOUNT_SYSTEM | MOUNT_BINARY | MOUNT_AUTOMATIC); + add_item (native, "/usr/lib", MOUNT_SYSTEM | MOUNT_AUTOMATIC); } } } -static void -set_flags (unsigned *flags, unsigned val) -{ - *flags = val; - debug_printf ("flags: binary (%y)", *flags & MOUNT_BINARY); -} - int mount_item::build_win32 (char *dst, const char *src, unsigned *outflags, unsigned chroot_pathlen) { int n, err = 0; const char *real_native_path; int real_posix_pathlen; - set_flags (outflags, (unsigned) flags); + *outflags = flags; if (!cygheap->root.exists () || posix_pathlen != 1 || posix_path[0] != '/') { n = native_pathlen; @@ -604,7 +595,7 @@ mount_info::conv_to_win32_path (const char *src_path, char *dst, device& dev, /* See if this is a cygwin "device" */ if (win32_device_name (src_path, dst, dev)) { - *flags = MOUNT_BINARY; /* FIXME: Is this a sensible default for devices? */ + *flags = 0; rc = 0; goto out_no_chroot_check; } @@ -617,7 +608,7 @@ mount_info::conv_to_win32_path (const char *src_path, char *dst, device& dev, if (!strchr (src_path + 2, '/')) { dev = *netdrive_dev; - set_flags (flags, MOUNT_BINARY); + *flags = 0; } else { @@ -626,7 +617,7 @@ mount_info::conv_to_win32_path (const char *src_path, char *dst, device& dev, are rather (warning, poetic description ahead) windows into the native Win32 world. This also gives the user an elegant way to change the settings for those paths in a central place. */ - set_flags (flags, (unsigned) cygdrive_flags); + *flags = cygdrive_flags; } backslashify (src_path, dst, 0); /* Go through chroot check */ @@ -638,14 +629,14 @@ mount_info::conv_to_win32_path (const char *src_path, char *dst, device& dev, dev = fhandler_proc::get_proc_fhandler (src_path); if (dev == FH_NADA) return ENOENT; - set_flags (flags, MOUNT_BINARY); + *flags = 0; if (isprocsys_dev (dev)) { if (src_path[procsys_len]) backslashify (src_path + procsys_len, dst, 0); else /* Avoid empty NT path. */ stpcpy (dst, "\\"); - set_flags (flags, (unsigned) cygdrive_flags); + *flags = cygdrive_flags; } else strcpy (dst, src_path); @@ -666,7 +657,7 @@ mount_info::conv_to_win32_path (const char *src_path, char *dst, device& dev, } else if (cygdrive_win32_path (src_path, dst, unit)) { - set_flags (flags, (unsigned) cygdrive_flags); + *flags = cygdrive_flags; goto out; } else if (mount_table->cygdrive_len > 1) @@ -1024,7 +1015,7 @@ struct opt { {"acl", MOUNT_NOACL, 1}, {"auto", 0, 0}, - {"binary", MOUNT_BINARY, 0}, + {"binary", MOUNT_TEXT, 1}, {"bind", MOUNT_BIND, 0}, {"cygexec", MOUNT_CYGWIN_EXEC, 0}, {"dos", MOUNT_DOS, 0}, @@ -1038,7 +1029,7 @@ struct opt {"posix=0", MOUNT_NOPOSIX, 0}, {"posix=1", MOUNT_NOPOSIX, 1}, {"sparse", MOUNT_SPARSE, 0}, - {"text", MOUNT_BINARY, 1}, + {"text", MOUNT_TEXT, 0}, {"user", MOUNT_SYSTEM, 1} }; @@ -1140,7 +1131,7 @@ mount_info::from_fstab_line (char *line, bool user) return true; cend = find_ws (c); *cend = '\0'; - unsigned mount_flags = MOUNT_SYSTEM | MOUNT_BINARY; + unsigned mount_flags = MOUNT_SYSTEM; if (!strcmp (fs_type, "cygdrive")) mount_flags |= MOUNT_NOPOSIX; if (!strcmp (fs_type, "usertemp")) @@ -1157,7 +1148,7 @@ mount_info::from_fstab_line (char *line, bool user) int error = conv_to_win32_path (bound_path, native_path, dev, &flags); if (error || strlen (native_path) >= MAX_PATH) return true; - if ((mount_flags & ~MOUNT_SYSTEM) == (MOUNT_BIND | MOUNT_BINARY)) + if ((mount_flags & ~MOUNT_SYSTEM) == MOUNT_BIND) mount_flags = (MOUNT_BIND | flags) & ~(MOUNT_IMMUTABLE | MOUNT_AUTOMATIC); } @@ -1277,7 +1268,7 @@ mount_info::get_cygdrive_info (char *user, char *system, char *user_flags, path[cygdrive_len - 1] = '\0'; } if (flags) - strcpy (flags, (cygdrive_flags & MOUNT_BINARY) ? "binmode" : "textmode"); + strcpy (flags, (cygdrive_flags & MOUNT_TEXT) ? "textmode" : "binmode"); return 0; } @@ -1603,7 +1594,7 @@ fillout_mntent (const char *native_path, const char *posix_path, unsigned flags) binary or textmode, or exec. We don't print `silent' here; it's a magic internal thing. */ - if (!(flags & MOUNT_BINARY)) + if (flags & MOUNT_TEXT) strcpy (_my_tls.locals.mnt_opts, (char *) "text"); else strcpy (_my_tls.locals.mnt_opts, (char *) "binary"); @@ -1759,7 +1750,7 @@ mount (const char *win32_path, const char *posix_path, unsigned flags) dev, &conv_flags); if (error || strlen (w32_path) >= MAX_PATH) return true; - if ((flags & ~MOUNT_SYSTEM) == (MOUNT_BIND | MOUNT_BINARY)) + if ((flags & ~MOUNT_SYSTEM) == MOUNT_BIND) flags = (MOUNT_BIND | conv_flags) & ~(MOUNT_IMMUTABLE | MOUNT_AUTOMATIC); } diff --git a/winsup/cygwin/path.h b/winsup/cygwin/path.h index 2b885045d..0c94c6152 100644 --- a/winsup/cygwin/path.h +++ b/winsup/cygwin/path.h @@ -174,9 +174,7 @@ class path_conv int has_buggy_basic_info () const {return fs.has_buggy_basic_info ();} int binmode () const { - if (mount_flags & MOUNT_BINARY) - return O_BINARY; - return O_TEXT; + return (mount_flags & MOUNT_TEXT) ? O_TEXT : O_BINARY; } int issymlink () const {return path_flags & PATH_SYMLINK;} int is_lnk_symlink () const {return path_flags & PATH_LNK;} diff --git a/winsup/cygwin/release/3.0.1 b/winsup/cygwin/release/3.0.1 index fd6595b98..8c88f3c2a 100644 --- a/winsup/cygwin/release/3.0.1 +++ b/winsup/cygwin/release/3.0.1 @@ -14,3 +14,7 @@ Bug Fixes - Fix Command-line argument handling of kill(1) in terms of negative PID. Addresses: report on IRC + +- Fix an accidentally introduced O_TEXT handling of pipes inherited + from native Windows processes. + Addresses: https://cygwin.com/ml/cygwin/2019-02/msg00246.html From 9883959f083d13ce9991d2162fcf5fee1613478d Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Mon, 18 Feb 2019 10:13:35 +0100 Subject: [PATCH 221/475] Revert "Cygwin: passwd/group: allow specifying "." as local computername" This reverts commit 7c34811440be0bf1e749d9f075f54320c706cb4b. This potentially allows to circumvent OpenSSHs user/group name matching, unless the Admin knows to add every local user twice or to use patterns, e.g.: Match user MACHINE+user,.+user Match user *+user Signed-off-by: Corinna Vinschen --- winsup/cygwin/uinfo.cc | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/winsup/cygwin/uinfo.cc b/winsup/cygwin/uinfo.cc index 47fe24725..53efc2117 100644 --- a/winsup/cygwin/uinfo.cc +++ b/winsup/cygwin/uinfo.cc @@ -2008,15 +2008,7 @@ pwdgrp::fetch_account_from_windows (fetch_user_arg_t &arg, cyg_ldap *pldap) if ((p = wcschr (name, cygheap->pg.nss_separator ()[0]))) { fq_name = true; - /* Convenience: Translate domain name "." to local machine. */ - if (p == name + 1 && name[0] == L'.') - { - p = wcpcpy (name, cygheap->dom.account_flat_name ()); - *p = L'\\'; - sys_mbstowcs (p + 1, UNLEN + 1, arg.name + 2); - } - else - *p = L'\\'; + *p = L'\\'; } sid = csid; ret = LookupAccountNameW (NULL, name, sid, &slen, dom, &dlen, &acc_type); From 26e0b37ed06c78926f1e1ee1e589b214a3813432 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Mon, 18 Feb 2019 11:00:06 +0100 Subject: [PATCH 222/475] Cygwin: utils: MOUNT_BINARY -> MOUNT_TEXT Signed-off-by: Corinna Vinschen --- winsup/utils/mount.cc | 2 +- winsup/utils/path.cc | 15 +++++++-------- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/winsup/utils/mount.cc b/winsup/utils/mount.cc index 1d32755c9..bd267511d 100644 --- a/winsup/utils/mount.cc +++ b/winsup/utils/mount.cc @@ -256,7 +256,7 @@ int main (int argc, char **argv) { int i; - int flags = MOUNT_BINARY; + int flags = 0; char *options = strdup (""); enum do_what { diff --git a/winsup/utils/path.cc b/winsup/utils/path.cc index 1a14a8963..d8c208123 100644 --- a/winsup/utils/path.cc +++ b/winsup/utils/path.cc @@ -312,7 +312,7 @@ static struct opt { {"acl", MOUNT_NOACL, 1}, {"auto", 0, 0}, - {"binary", MOUNT_BINARY, 0}, + {"binary", MOUNT_TEXT, 1}, {"cygexec", MOUNT_CYGWIN_EXEC, 0}, {"dos", MOUNT_DOS, 0}, {"exec", MOUNT_EXEC, 0}, @@ -324,7 +324,7 @@ static struct opt {"override", MOUNT_OVERRIDE, 0}, {"posix=0", MOUNT_NOPOSIX, 0}, {"posix=1", MOUNT_NOPOSIX, 1}, - {"text", MOUNT_BINARY, 1}, + {"text", MOUNT_TEXT, 0}, {"user", MOUNT_SYSTEM, 1} }; @@ -487,27 +487,26 @@ from_fstab (bool user, PWCHAR path, PWCHAR path_end) *(native_path += 2) = '\\'; m->posix = strdup ("/"); m->native = strdup (native_path); - m->flags = MOUNT_SYSTEM | MOUNT_BINARY | MOUNT_IMMUTABLE - | MOUNT_AUTOMATIC; + m->flags = MOUNT_SYSTEM | MOUNT_IMMUTABLE | MOUNT_AUTOMATIC; ++m; /* Create default /usr/bin and /usr/lib entries. */ char *trail = strchr (native_path, '\0'); strcpy (trail, "\\bin"); m->posix = strdup ("/usr/bin"); m->native = strdup (native_path); - m->flags = MOUNT_SYSTEM | MOUNT_BINARY | MOUNT_AUTOMATIC; + m->flags = MOUNT_SYSTEM | MOUNT_AUTOMATIC; ++m; strcpy (trail, "\\lib"); m->posix = strdup ("/usr/lib"); m->native = strdup (native_path); - m->flags = MOUNT_SYSTEM | MOUNT_BINARY | MOUNT_AUTOMATIC; + m->flags = MOUNT_SYSTEM | MOUNT_AUTOMATIC; ++m; /* Create a default cygdrive entry. Note that this is a user entry. This allows to override it with mount, unless the sysadmin created a cygdrive entry in /etc/fstab. */ m->posix = strdup (CYGWIN_INFO_CYGDRIVE_DEFAULT_PREFIX); m->native = strdup ("cygdrive prefix"); - m->flags = MOUNT_BINARY | MOUNT_CYGDRIVE; + m->flags = MOUNT_CYGDRIVE; ++m; max_mount_entry = m - mount_table; } @@ -935,7 +934,7 @@ getmntent (FILE *) strcpy (mnt.mnt_type, (char *) ((m->flags & MOUNT_SYSTEM) ? "system" : "user")); - if (!(m->flags & MOUNT_BINARY)) + if (m->flags & MOUNT_TEXT) strcpy (mnt.mnt_opts, (char *) "text"); else strcpy (mnt.mnt_opts, (char *) "binary"); From 959077ac0a6d03630e1df7cfcc6bdc602c47c0b2 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Mon, 18 Feb 2019 11:04:38 +0100 Subject: [PATCH 223/475] CYgwin: bump API minor for MOUNT_BINARY -> MOUNT_TEXT change Signed-off-by: Corinna Vinschen --- winsup/cygwin/include/cygwin/version.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/winsup/cygwin/include/cygwin/version.h b/winsup/cygwin/include/cygwin/version.h index 2f887f055..2c55f4b79 100644 --- a/winsup/cygwin/include/cygwin/version.h +++ b/winsup/cygwin/include/cygwin/version.h @@ -507,12 +507,13 @@ details. */ 334: Remove matherr. 335: Change size of utsname, change uname output. 336: New Cygwin PID algorithm (yeah, not really an API change) + 337: MOUNT_BINARY -> MOUNT_TEXT Note that we forgot to bump the api for ualarm, strtoll, strtoull, sigaltstack, sethostname. */ #define CYGWIN_VERSION_API_MAJOR 0 -#define CYGWIN_VERSION_API_MINOR 336 +#define CYGWIN_VERSION_API_MINOR 337 /* There is also a compatibity version number associated with the shared memory regions. It is incremented when incompatible changes are made to the shared From a96d68c5bd88080406d4523236449cf43ecebf39 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Mon, 18 Feb 2019 17:59:56 +0100 Subject: [PATCH 224/475] Cygwin: s4uauth: make sure to fetch correct package id for domain accounts we try KerbS4ULogon first, MsV1_0S4ULogon second. But we only fetch the package id for the supporting authentication package (Kerberos/MsV1_0) once at the start. Duplicate LsaLookupAuthenticationPackage call and move into the Kerb/MsV1_0 branches so that it fetches the correct package id for the method we call next. Curious enough this worked before. Apparently both methods work with the MICROSOFT_KERBEROS_NAME_A package id. However, requesting and using the right authentication package id is the prudent thing to do. Signed-off-by: Corinna Vinschen --- winsup/cygwin/sec_auth.cc | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/winsup/cygwin/sec_auth.cc b/winsup/cygwin/sec_auth.cc index d66a2a5d8..6588e6781 100644 --- a/winsup/cygwin/sec_auth.cc +++ b/winsup/cygwin/sec_auth.cc @@ -1475,15 +1475,6 @@ s4uauth (struct passwd *pw) extract_nt_dom_user (pw, domain, user); try_kerb_auth = cygheap->dom.member_machine () && wcscasecmp (domain, cygheap->dom.account_flat_name ()); - RtlInitAnsiString (&name, try_kerb_auth ? MICROSOFT_KERBEROS_NAME_A - : MSV1_0_PACKAGE_NAME); - status = LsaLookupAuthenticationPackage (lsa_hdl, &name, &package_id); - if (status != STATUS_SUCCESS) - { - debug_printf ("LsaLookupAuthenticationPackage: %y", status); - __seterrno_from_nt_status (status); - goto out; - } /* Create origin. */ stpcpy (origin.buf, "Cygwin"); RtlInitAnsiString (&origin.str, origin.buf); @@ -1496,6 +1487,14 @@ s4uauth (struct passwd *pw) KERB_S4U_LOGON *s4u_logon; USHORT name_len; + RtlInitAnsiString (&name, MICROSOFT_KERBEROS_NAME_A); + status = LsaLookupAuthenticationPackage (lsa_hdl, &name, &package_id); + if (status != STATUS_SUCCESS) + { + debug_printf ("LsaLookupAuthenticationPackage: %y", status); + __seterrno_from_nt_status (status); + goto out; + } wcpcpy (wcpcpy (wcpcpy (sam_name, domain), L"\\"), user); if (TranslateNameW (sam_name, NameSamCompatible, NameUserPrincipal, upn_name, &size) == 0) @@ -1563,6 +1562,14 @@ msv1_0_auth: MSV1_0_S4U_LOGON *s4u_logon; USHORT user_len, domain_len; + RtlInitAnsiString (&name, MSV1_0_PACKAGE_NAME); + status = LsaLookupAuthenticationPackage (lsa_hdl, &name, &package_id); + if (status != STATUS_SUCCESS) + { + debug_printf ("LsaLookupAuthenticationPackage: %y", status); + __seterrno_from_nt_status (status); + goto out; + } user_len = wcslen (user) * sizeof (WCHAR); domain_len = wcslen (domain) * sizeof (WCHAR); /* Local machine */ authinf_size = sizeof (MSV1_0_S4U_LOGON) + user_len + domain_len; From e53373bbdb3b8b6d497e7c388138e3ba22fda902 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Mon, 18 Feb 2019 21:00:59 +0100 Subject: [PATCH 225/475] Cygwin: re-enable create_token for older systems Under WOW64 on 64 bit Windows 7, MsV1_0S4ULogon appears to be unimplemented, probably under Vista as well. Re-enable create_token method, to allow basic seteuid on W7 WOW64 and Vista as well. Signed-off-by: Corinna Vinschen --- winsup/cygwin/release/3.0.1 | 4 ++++ winsup/cygwin/sec_auth.cc | 11 +++-------- winsup/cygwin/security.h | 2 +- winsup/cygwin/syscalls.cc | 38 ++++++++++++++++++------------------- winsup/doc/ntsec.xml | 10 ++++++++++ 5 files changed, 36 insertions(+), 29 deletions(-) diff --git a/winsup/cygwin/release/3.0.1 b/winsup/cygwin/release/3.0.1 index 8c88f3c2a..1894c5c00 100644 --- a/winsup/cygwin/release/3.0.1 +++ b/winsup/cygwin/release/3.0.1 @@ -18,3 +18,7 @@ Bug Fixes - Fix an accidentally introduced O_TEXT handling of pipes inherited from native Windows processes. Addresses: https://cygwin.com/ml/cygwin/2019-02/msg00246.html + +- Re-enable creating user token from scratch in seteuid to allow + user context switch on old systems not supporting MsV1_0S4ULogon. + Addresses: https://cygwin.com/ml/cygwin/2019-02/msg00277.html diff --git a/winsup/cygwin/sec_auth.cc b/winsup/cygwin/sec_auth.cc index 6588e6781..316ae99d9 100644 --- a/winsup/cygwin/sec_auth.cc +++ b/winsup/cygwin/sec_auth.cc @@ -488,7 +488,6 @@ sid_in_token_groups (PTOKEN_GROUPS grps, cygpsid sid) return false; } -#if 0 && S4U_RUNS_FINE static void get_token_group_sidlist (cygsidlist &grp_list, PTOKEN_GROUPS my_grps) { @@ -524,7 +523,6 @@ get_token_group_sidlist (cygsidlist &grp_list, PTOKEN_GROUPS my_grps) grp_list *= well_known_users_sid; } } -#endif bool get_server_groups (cygsidlist &grp_list, PSID usersid, @@ -558,7 +556,6 @@ get_server_groups (cygsidlist &grp_list, PSID usersid, && sid_sub_auth (usersid, 0) == SECURITY_NT_NON_UNIQUE && get_logon_server (domain, server, DS_IS_FLAT_NAME)) { -#if 0 && S4U_RUNS_FINE if (check_account_disabled == CHK_DISABLED) { NET_API_STATUS napi_stat; @@ -577,14 +574,12 @@ get_server_groups (cygsidlist &grp_list, PSID usersid, return false; } } -#endif get_user_groups (server, grp_list, user, domain); get_user_local_groups (server, domain, grp_list, user); } return true; } -#if 0 && S4U_RUNS_FINE static bool get_initgroups_sidlist (cygsidlist &grp_list, PSID usersid, PSID pgrpsid, PTOKEN_GROUPS my_grps) @@ -762,7 +757,6 @@ get_priv_list (LSA_HANDLE lsa, cygsid &usersid, cygsidlist &grp_list, } return privs; } -#endif /* Accept a token if - the requested usersid matches the TokenUser and @@ -906,7 +900,6 @@ account_restriction (NTSTATUS status) return type; } -#if 0 && S4U_RUNS_FINE HANDLE create_token (cygsid &usersid, user_groups &new_groups) { @@ -1061,6 +1054,7 @@ out: return primary_token; } +#if 0 && S4U_RUNS_FINE HANDLE lsaauth (cygsid &usersid, user_groups &new_groups) { @@ -1434,7 +1428,7 @@ typedef struct _MSV1_0_S4U_LOGON } MSV1_0_S4U_LOGON, *PMSV1_0_S4U_LOGON; HANDLE -s4uauth (struct passwd *pw) +s4uauth (struct passwd *pw, NTSTATUS &ret_status) { LSA_STRING name; HANDLE lsa_hdl = NULL; @@ -1614,5 +1608,6 @@ out: LsaFreeReturnBuffer (profile); pop_self_privilege (); + ret_status = status; return token; } diff --git a/winsup/cygwin/security.h b/winsup/cygwin/security.h index 70912b4fc..cabb91d25 100644 --- a/winsup/cygwin/security.h +++ b/winsup/cygwin/security.h @@ -480,7 +480,7 @@ HANDLE lsaauth (cygsid &, user_groups &); /* LSA private key storage authentication, same as when using service logons. */ HANDLE lsaprivkeyauth (struct passwd *pw); /* Kerberos or MsV1 S4U logon. */ -HANDLE s4uauth (struct passwd *pw); +HANDLE s4uauth (struct passwd *pw, NTSTATUS &ret_status); /* Verify an existing token */ bool verify_token (HANDLE token, cygsid &usersid, user_groups &groups, bool *pintern = NULL); /* Get groups of a user */ diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc index 387f4da32..c3a92445e 100644 --- a/winsup/cygwin/syscalls.cc +++ b/winsup/cygwin/syscalls.cc @@ -3564,31 +3564,29 @@ seteuid32 (uid_t uid) } if (!new_token) { -#if 1 + NTSTATUS status; + debug_printf ("lsaprivkeyauth failed, try s4uauth."); - if (!(new_token = s4uauth (pw_new))) + if (!(new_token = s4uauth (pw_new, status))) { - debug_printf ("s4uauth failed, bail out"); - cygheap->user.reimpersonate (); - return -1; - } -#else - debug_printf ("lsaprivkeyauth failed, try lsaauth."); - if (!(new_token = lsaauth (usersid, groups))) - { - debug_printf ("lsaauth failed, try s4uauth."); - if (!(new_token = s4uauth (pw_new))) + if (status != STATUS_INVALID_PARAMETER) { - debug_printf ("s4uauth failed, try create_token."); - if (!(new_token = create_token (usersid, groups))) - { - debug_printf ("create_token failed, bail out"); - cygheap->user.reimpersonate (); - return -1; - } + debug_printf ("s4uauth failed, bail out"); + cygheap->user.reimpersonate (); + return -1; + } + /* If s4uauth fails with status code STATUS_INVALID_PARAMETER, + we're running on a system not implementing MsV1_0S4ULogon + (Windows 7 WOW64, Vista?). Fall back to create_token in + this single case only. */ + debug_printf ("s4uauth failed, try create_token."); + if (!(new_token = create_token (usersid, groups))) + { + debug_printf ("create_token failed, bail out"); + cygheap->user.reimpersonate (); + return -1; } } -#endif } /* Keep at most one internal token */ diff --git a/winsup/doc/ntsec.xml b/winsup/doc/ntsec.xml index e8419c5bc..528784568 100644 --- a/winsup/doc/ntsec.xml +++ b/winsup/doc/ntsec.xml @@ -2574,6 +2574,16 @@ use the returned token. to create a token. + +Older systems, like WOW64 under Windows 7 64 bit, don't support +S4U authentication for local machine accounts. On +these systems Cygwin falls back to an old and otherwise deprecated +method to create a user token from scratch. The underlying system call +is undocumented and has an unfortunate requirement: We have to create a +special account with dangerous permissions to perform this action. +Therefore this is only enabled on affected systems. + + If all of the above fails, our process has insufficient privileges to switch the user context at all, so set(e)uid From 30782f7de4936bbc4c2e666cbaf587039c895fd3 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Mon, 18 Feb 2019 21:45:34 +0100 Subject: [PATCH 226/475] Cygwin: s4uauth: convert token to primary token Up to Vista CreateProcessAsUser only worked with primary tokens, so convert S4U impersonation token to primary token. MSDN still documents it that way, but actually an impersonation token is sufficient since Windows 7. Signed-off-by: Corinna Vinschen --- winsup/cygwin/sec_auth.cc | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/winsup/cygwin/sec_auth.cc b/winsup/cygwin/sec_auth.cc index 316ae99d9..beff3278e 100644 --- a/winsup/cygwin/sec_auth.cc +++ b/winsup/cygwin/sec_auth.cc @@ -1556,6 +1556,8 @@ msv1_0_auth: MSV1_0_S4U_LOGON *s4u_logon; USHORT user_len, domain_len; + /* Per MSDN MsV1_0S4ULogon is not implemented on Vista, but surprisingly + it works. */ RtlInitAnsiString (&name, MSV1_0_PACKAGE_NAME); status = LsaLookupAuthenticationPackage (lsa_hdl, &name, &package_id); if (status != STATUS_SUCCESS) @@ -1607,6 +1609,30 @@ out: if (profile) LsaFreeReturnBuffer (profile); + if (token) + { + /* Convert to primary token. Strictly speaking this is only + required on Vista/2008. CreateProcessAsUser also takes + impersonation tokens since Windows 7. */ + HANDLE tmp_token; + + if (DuplicateTokenEx (token, MAXIMUM_ALLOWED, &sec_none, + SecurityImpersonation, TokenPrimary, &tmp_token)) + { + CloseHandle (token); + token = tmp_token; + } + else + { + __seterrno (); + debug_printf ("DuplicateTokenEx %E"); + /* Make sure not to allow create_token. */ + status = STATUS_INVALID_HANDLE; + CloseHandle (token); + token = NULL; + } + } + pop_self_privilege (); ret_status = status; return token; From 9d4a6534fb218f41ac916aa5dcdb0ce1b55dc245 Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Wed, 13 Feb 2019 13:42:57 +0100 Subject: [PATCH 227/475] Move RTEMS and XMK specific type definitions Signed-off-by: Sebastian Huber --- newlib/libc/include/machine/types.h | 6 ++++++ newlib/libc/include/sys/types.h | 16 ---------------- newlib/libc/sys/rtems/include/machine/types.h | 6 ++++++ 3 files changed, 12 insertions(+), 16 deletions(-) diff --git a/newlib/libc/include/machine/types.h b/newlib/libc/include/machine/types.h index a5a64e675..19d0e8560 100644 --- a/newlib/libc/include/machine/types.h +++ b/newlib/libc/include/machine/types.h @@ -5,3 +5,9 @@ #ifndef _SYS_TYPES_H #error "must be included via " #endif /* !_SYS_TYPES_H */ + +#if defined(__XMK__) && defined(___int64_t_defined) +typedef __uint64_t u_quad_t; +typedef __int64_t quad_t; +typedef quad_t * qaddr_t; +#endif diff --git a/newlib/libc/include/sys/types.h b/newlib/libc/include/sys/types.h index 65ff520c8..2685df654 100644 --- a/newlib/libc/include/sys/types.h +++ b/newlib/libc/include/sys/types.h @@ -39,22 +39,6 @@ typedef __uint64_t u_int64_t; typedef int register_t; #define __BIT_TYPES_DEFINED__ 1 -#if defined(__rtems__) || defined(__XMK__) -/* - * The following section is RTEMS specific and is needed to more - * closely match the types defined in the BSD sys/types.h. - * This is needed to let the RTEMS/BSD TCP/IP stack compile. - */ - -/* deprecated */ -#if ___int64_t_defined -typedef __uint64_t u_quad_t; -typedef __int64_t quad_t; -typedef quad_t * qaddr_t; -#endif - -#endif /* __rtems__ || __XMK__ */ - #ifndef __need_inttypes #define _SYS_TYPES_H diff --git a/newlib/libc/sys/rtems/include/machine/types.h b/newlib/libc/sys/rtems/include/machine/types.h index ab52e47ed..c550873d3 100644 --- a/newlib/libc/sys/rtems/include/machine/types.h +++ b/newlib/libc/sys/rtems/include/machine/types.h @@ -62,6 +62,12 @@ typedef __lwpid_t lwpid_t; /* Thread ID (a.k.a. LWP) */ #define _LWPID_T_DECLARED #endif +#if ___int64_t_defined +typedef __uint64_t u_quad_t; +typedef __int64_t quad_t; +typedef quad_t * qaddr_t; +#endif + #ifndef _RLIM_T_DECLARED typedef __rlim_t rlim_t; /* resource limit */ #define _RLIM_T_DECLARED From 6246ef794939693896a3f1921ec5bf44a172bb5a Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Mon, 18 Feb 2019 09:38:36 +0100 Subject: [PATCH 228/475] Fix comment in Signed-off-by: Sebastian Huber --- newlib/libc/include/sys/types.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/newlib/libc/include/sys/types.h b/newlib/libc/include/sys/types.h index 2685df654..e5bd0294f 100644 --- a/newlib/libc/include/sys/types.h +++ b/newlib/libc/include/sys/types.h @@ -85,7 +85,7 @@ typedef unsigned long u_long; #endif #define _BSDTYPES_DEFINED #endif -#endif /*__BSD_VISIBLE || __CYGWIN__ */ +#endif /* __MISC_VISIBLE */ #if __MISC_VISIBLE typedef unsigned short ushort; /* System V compatibility */ From 688e584efe44ba2ffd5640e857b8be3d1b1c6bfa Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Mon, 18 Feb 2019 09:39:02 +0100 Subject: [PATCH 229/475] Change register_t definition On 64-bit targets, the register_t type must be a 64-bit integer. Signed-off-by: Sebastian Huber --- newlib/libc/include/sys/types.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/newlib/libc/include/sys/types.h b/newlib/libc/include/sys/types.h index e5bd0294f..85f8ddb5f 100644 --- a/newlib/libc/include/sys/types.h +++ b/newlib/libc/include/sys/types.h @@ -36,7 +36,7 @@ typedef __uint32_t u_int32_t; #if ___int64_t_defined typedef __uint64_t u_int64_t; #endif -typedef int register_t; +typedef __intptr_t register_t; #define __BIT_TYPES_DEFINED__ 1 #ifndef __need_inttypes From 1d35a003fd0574dabdfda783f4b5a33ae512b058 Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Mon, 18 Feb 2019 09:41:13 +0100 Subject: [PATCH 230/475] Define u_register_t if __BSD_VISIBLE Add u_register_t definition for FreeBSD compatibility. Signed-off-by: Sebastian Huber --- newlib/libc/include/sys/types.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/newlib/libc/include/sys/types.h b/newlib/libc/include/sys/types.h index 85f8ddb5f..19e3de689 100644 --- a/newlib/libc/include/sys/types.h +++ b/newlib/libc/include/sys/types.h @@ -62,6 +62,8 @@ typedef __uint32_t in_addr_t; /* base type for internet address */ typedef __uint16_t in_port_t; #define _IN_PORT_T_DECLARED #endif + +typedef __uintptr_t u_register_t; #endif /* __BSD_VISIBLE */ #if __MISC_VISIBLE From dd415f1a8c0480303a38f8f4612430c201e967cc Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Tue, 19 Feb 2019 19:34:40 +0100 Subject: [PATCH 231/475] Cygwin: sys/mount.h: fix comment Signed-off-by: Corinna Vinschen --- winsup/cygwin/include/sys/mount.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/winsup/cygwin/include/sys/mount.h b/winsup/cygwin/include/sys/mount.h index 0c4e078bf..8221d1a77 100644 --- a/winsup/cygwin/include/sys/mount.h +++ b/winsup/cygwin/include/sys/mount.h @@ -22,7 +22,7 @@ extern "C" { enum { - MOUNT_TEXT = _BIT ( 0), /* "binary" format read/writes */ + MOUNT_TEXT = _BIT ( 0), /* "text" format read/writes */ MOUNT_SYSTEM = _BIT ( 3), /* mount point came from system table */ MOUNT_EXEC = _BIT ( 4), /* Any file in the mounted directory gets 'x' bit */ From 850705f92e3371bc0c56cee270327add84cd441a Mon Sep 17 00:00:00 2001 From: Yaakov Selkowitz Date: Mon, 18 Feb 2019 23:06:11 -0600 Subject: [PATCH 232/475] Cygwin: add secure_getenv Signed-off-by: Yaakov Selkowitz --- newlib/libc/include/stdlib.h | 3 +++ winsup/cygwin/common.din | 1 + winsup/cygwin/environ.cc | 10 ++++++++++ winsup/cygwin/include/cygwin/version.h | 3 ++- winsup/doc/posix.xml | 1 + 5 files changed, 17 insertions(+), 1 deletion(-) diff --git a/newlib/libc/include/stdlib.h b/newlib/libc/include/stdlib.h index 9773d3672..933d181e1 100644 --- a/newlib/libc/include/stdlib.h +++ b/newlib/libc/include/stdlib.h @@ -94,6 +94,9 @@ void exit (int __status) _ATTRIBUTE ((__noreturn__)); void free (void *) _NOTHROW; char * getenv (const char *__string); char * _getenv_r (struct _reent *, const char *__string); +#if __GNU_VISIBLE +char * secure_getenv (const char *__string); +#endif char * _findenv (const char *, int *); char * _findenv_r (struct _reent *, const char *, int *); #if __POSIX_VISIBLE >= 200809 diff --git a/winsup/cygwin/common.din b/winsup/cygwin/common.din index f620d8183..68b95d470 100644 --- a/winsup/cygwin/common.din +++ b/winsup/cygwin/common.din @@ -1255,6 +1255,7 @@ sched_rr_get_interval SIGFE sched_setparam SIGFE sched_setscheduler SIGFE sched_yield SIGFE +secure_getenv NOSIGFE seed48 NOSIGFE seekdir SIGFE select = cygwin_select SIGFE diff --git a/winsup/cygwin/environ.cc b/winsup/cygwin/environ.cc index 495c340a4..21f13734c 100644 --- a/winsup/cygwin/environ.cc +++ b/winsup/cygwin/environ.cc @@ -549,6 +549,16 @@ _getenv_r (struct _reent *, const char *name) return findenv_func (name, &offset); } +/* Like getenv, but returns NULL if effective and real UID/GIDs do not match */ +extern "C" char * +secure_getenv (const char *name) +{ + int offset; + if (cygheap->user.issetuid ()) + return NULL; + return findenv_func (name, &offset); +} + /* Return number of environment entries, including terminating NULL. */ static int __stdcall envsize (const char * const *in_envp) diff --git a/winsup/cygwin/include/cygwin/version.h b/winsup/cygwin/include/cygwin/version.h index 2c55f4b79..d865f299d 100644 --- a/winsup/cygwin/include/cygwin/version.h +++ b/winsup/cygwin/include/cygwin/version.h @@ -508,12 +508,13 @@ details. */ 335: Change size of utsname, change uname output. 336: New Cygwin PID algorithm (yeah, not really an API change) 337: MOUNT_BINARY -> MOUNT_TEXT + 338: Export secure_getenv. Note that we forgot to bump the api for ualarm, strtoll, strtoull, sigaltstack, sethostname. */ #define CYGWIN_VERSION_API_MAJOR 0 -#define CYGWIN_VERSION_API_MINOR 337 +#define CYGWIN_VERSION_API_MINOR 338 /* There is also a compatibity version number associated with the shared memory regions. It is incremented when incompatible changes are made to the shared diff --git a/winsup/doc/posix.xml b/winsup/doc/posix.xml index 8e9b1a511..0755beda0 100644 --- a/winsup/doc/posix.xml +++ b/winsup/doc/posix.xml @@ -1377,6 +1377,7 @@ also IEEE Std 1003.1-2008 (POSIX.1-2008). removexattr scandirat sched_getcpu + secure_getenv setxattr signalfd sincos From a62b29bfec6d8c6cf3f285b4c7a5edcf4abf33e1 Mon Sep 17 00:00:00 2001 From: Yaakov Selkowitz Date: Tue, 19 Feb 2019 14:34:18 -0600 Subject: [PATCH 233/475] Cygwin: document secure_getenv Signed-off-by: Yaakov Selkowitz --- winsup/cygwin/release/3.0.1 | 2 ++ winsup/doc/new-features.xml | 6 +++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/winsup/cygwin/release/3.0.1 b/winsup/cygwin/release/3.0.1 index 1894c5c00..467bf2379 100644 --- a/winsup/cygwin/release/3.0.1 +++ b/winsup/cygwin/release/3.0.1 @@ -1,6 +1,8 @@ What's new: ----------- +- New API: secure_getenv. + What changed: ------------- diff --git a/winsup/doc/new-features.xml b/winsup/doc/new-features.xml index 8fc0ac6fe..ab369abb6 100644 --- a/winsup/doc/new-features.xml +++ b/winsup/doc/new-features.xml @@ -43,7 +43,7 @@ Support Linux-specific open(2) flag O_PATH. -- Support Linux-specific linkat(2) flag AT_EMPTY_PATH. +Support Linux-specific linkat(2) flag AT_EMPTY_PATH. @@ -52,8 +52,8 @@ siginfo_t::si_overrun). -New APIs: signalfd, timerfd_create, timerfd_gettime, timerfd_settime, -timer_getoverrun. +New APIs: secure_getenv, signalfd, timerfd_create, timerfd_gettime, +timerfd_settime, timer_getoverrun. From 65c569f9fd7f0c6e7de395dd4e811a677650b7af Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Fri, 22 Feb 2019 00:13:06 +0100 Subject: [PATCH 234/475] Cygwin: bump version to 3.0.2 Signed-off-by: Corinna Vinschen --- winsup/cygwin/include/cygwin/version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/winsup/cygwin/include/cygwin/version.h b/winsup/cygwin/include/cygwin/version.h index d865f299d..97bc0aeda 100644 --- a/winsup/cygwin/include/cygwin/version.h +++ b/winsup/cygwin/include/cygwin/version.h @@ -11,7 +11,7 @@ details. */ changes to the DLL and is mainly informative in nature. */ #define CYGWIN_VERSION_DLL_MAJOR 3000 -#define CYGWIN_VERSION_DLL_MINOR 1 +#define CYGWIN_VERSION_DLL_MINOR 2 /* Major numbers before CYGWIN_VERSION_DLL_EPOCH are incompatible. */ From 14e22688535e3695a7f73a0c82f3535ce164ee67 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Fri, 22 Feb 2019 00:13:57 +0100 Subject: [PATCH 235/475] Cygwin: fetch local groups from local machine ...even for domain accounts, otherwise local group membership is ignored. Signed-off-by: Corinna Vinschen --- winsup/cygwin/sec_auth.cc | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/winsup/cygwin/sec_auth.cc b/winsup/cygwin/sec_auth.cc index beff3278e..4bbcb0e28 100644 --- a/winsup/cygwin/sec_auth.cc +++ b/winsup/cygwin/sec_auth.cc @@ -400,11 +400,18 @@ get_user_local_groups (PWCHAR logonserver, PWCHAR domain, DWORD cnt, tot; NET_API_STATUS ret; - ret = NetUserGetLocalGroups (logonserver, user, 0, LG_INCLUDE_INDIRECT, + /* We want to know the membership in local groups on the current machine. + Thus, don't ask the logonserver, ask the local machine. In contrast + to most other NetUser functions, NetUserGetLocalGroups accepts the + username in DOMAIN\user form. */ + WCHAR username[MAX_DOMAIN_NAME_LEN + UNLEN + 2]; + wcpcpy (wcpcpy (wcpcpy (username, domain), L"\\"), user); + ret = NetUserGetLocalGroups (NULL, username, 0, LG_INCLUDE_INDIRECT, (LPBYTE *) &buf, MAX_PREFERRED_LENGTH, &cnt, &tot); if (ret) { + debug_printf ("username: %W", username); __seterrno_from_win_error (ret); return false; } From 5fcbbf7ead615c116f8e08047093232b1325faf4 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Fri, 22 Feb 2019 21:52:22 +0100 Subject: [PATCH 236/475] stdio: drop unused O_TEXT handling on non-Cygwin Signed-off-by: Corinna Vinschen --- newlib/libc/stdio/flags.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/newlib/libc/stdio/flags.c b/newlib/libc/stdio/flags.c index 71fc1f60a..1aa86d36e 100644 --- a/newlib/libc/stdio/flags.c +++ b/newlib/libc/stdio/flags.c @@ -89,10 +89,6 @@ __sflags (struct _reent *ptr, break; } } -#if defined (O_TEXT) && !defined (__CYGWIN__) - if (!(m | O_BINARY)) - m |= O_TEXT; -#endif *optr = m | o; return ret; } From 18c203fb6ebef6e363bb8633fe1673bf2b728e02 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Fri, 22 Feb 2019 11:04:34 +0100 Subject: [PATCH 237/475] Cygwin: passwd/group: drop fetching case-correct group names from LDAP Commit 4e34a39b5cdf4c3f889486b7460bea063e579d10 made sure all user and group names are case-correct, but it introduced a hefty performance hit on starting the first Cygwin process. Adding an ldap call for each AD group in a user token takes its toll in bigger AD environments with lots of groups in a user token. Real-life example: 300 groups w/ roundtrip time to the LDAP server of 0.25 secs per call... Signed-off-by: Corinna Vinschen --- winsup/cygwin/uinfo.cc | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/winsup/cygwin/uinfo.cc b/winsup/cygwin/uinfo.cc index 53efc2117..bfcce00da 100644 --- a/winsup/cygwin/uinfo.cc +++ b/winsup/cygwin/uinfo.cc @@ -2427,12 +2427,7 @@ pwdgrp::fetch_account_from_windows (fetch_user_arg_t &arg, cyg_ldap *pldap) if (is_domain_account) { - /* Overwrite group name to be sure case is same as in SAM */ - if (is_group() - && cldap->fetch_ad_account (sid, true, domain) - && (val = cldap->get_account_name ())) - wcscpy (name, val); - /* Skip the rest if creating group entries and for non-users. */ + /* Skip this when creating group entries and for non-users. */ if (is_group() || acc_type != SidTypeUser) break; /* On AD machines, use LDAP to fetch domain account infos. */ From 82c2cf6abcb9050886f9a14e5b2b0ca8fee2fc16 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Fri, 22 Feb 2019 13:36:13 +0100 Subject: [PATCH 238/475] Cygwin: drop unused parameter from get_user_local_groups Signed-off-by: Corinna Vinschen --- winsup/cygwin/sec_auth.cc | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/winsup/cygwin/sec_auth.cc b/winsup/cygwin/sec_auth.cc index 4bbcb0e28..3a08671a5 100644 --- a/winsup/cygwin/sec_auth.cc +++ b/winsup/cygwin/sec_auth.cc @@ -393,8 +393,7 @@ get_user_groups (WCHAR *logonserver, cygsidlist &grp_list, } static bool -get_user_local_groups (PWCHAR logonserver, PWCHAR domain, - cygsidlist &grp_list, PWCHAR user) +get_user_local_groups (PWCHAR domain, cygsidlist &grp_list, PWCHAR user) { LPLOCALGROUP_INFO_0 buf; DWORD cnt, tot; @@ -582,7 +581,7 @@ get_server_groups (cygsidlist &grp_list, PSID usersid, } } get_user_groups (server, grp_list, user, domain); - get_user_local_groups (server, domain, grp_list, user); + get_user_local_groups (domain, grp_list, user); } return true; } From 105fbdebdd3c65f96c7a95e1d5c527ce5790ac5e Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Fri, 22 Feb 2019 18:27:38 +0100 Subject: [PATCH 239/475] Cygwin: s4uauth: allow to be called for identification only s4uath was only callable to create an impersonation token so far. Rework the function to allow creating an identification token for informational purposes even from untrusted processes. Take domainname and username instead of a passwd pointer to be more multi-purpose. Signed-off-by: Corinna Vinschen --- winsup/cygwin/autoload.cc | 1 + winsup/cygwin/sec_auth.cc | 34 ++++++++++++++++++++-------------- winsup/cygwin/security.h | 2 +- winsup/cygwin/syscalls.cc | 6 +++++- 4 files changed, 27 insertions(+), 16 deletions(-) diff --git a/winsup/cygwin/autoload.cc b/winsup/cygwin/autoload.cc index 73367dfd8..056fac7dc 100644 --- a/winsup/cygwin/autoload.cc +++ b/winsup/cygwin/autoload.cc @@ -642,6 +642,7 @@ LoadDLLfunc (NetUserGetLocalGroups, 32, netapi32) LoadDLLfunc (CoTaskMemFree, 4, ole32) +LoadDLLfunc (LsaConnectUntrusted, 4, secur32) LoadDLLfunc (LsaDeregisterLogonProcess, 4, secur32) LoadDLLfunc (LsaFreeReturnBuffer, 4, secur32) LoadDLLfunc (LsaLogonUser, 56, secur32) diff --git a/winsup/cygwin/sec_auth.cc b/winsup/cygwin/sec_auth.cc index 3a08671a5..54182dd6c 100644 --- a/winsup/cygwin/sec_auth.cc +++ b/winsup/cygwin/sec_auth.cc @@ -22,7 +22,6 @@ details. */ #include "tls_pbuf.h" #include #include -#include #include #define SECURITY_WIN32 #include @@ -1421,7 +1420,7 @@ out: */ /* In Mingw-w64, MsV1_0S4ULogon and MSV1_0_S4U_LOGON are only defined - in ddk/ntifs.h. We can't inlcude this. */ + in ddk/ntifs.h. We can't include this. */ #define MsV1_0S4ULogon ((MSV1_0_LOGON_SUBMIT_TYPE) 12) @@ -1433,15 +1432,18 @@ typedef struct _MSV1_0_S4U_LOGON UNICODE_STRING DomainName; } MSV1_0_S4U_LOGON, *PMSV1_0_S4U_LOGON; +/* Missing in Mingw-w64 */ +#define KERB_S4U_LOGON_FLAG_IDENTITY 0x08 + +/* If logon is true we need an impersonation token. Otherwise we just + need an identification token, e. g. to fetch the group list. */ HANDLE -s4uauth (struct passwd *pw, NTSTATUS &ret_status) +s4uauth (bool logon, PCWSTR domain, PCWSTR user, NTSTATUS &ret_status) { LSA_STRING name; HANDLE lsa_hdl = NULL; LSA_OPERATIONAL_MODE sec_mode; NTSTATUS status, sub_status; - WCHAR domain[MAX_DOMAIN_NAME_LEN + 1]; - WCHAR user[UNLEN + 1]; bool try_kerb_auth; ULONG package_id, size; struct { @@ -1460,19 +1462,23 @@ s4uauth (struct passwd *pw, NTSTATUS &ret_status) push_self_privilege (SE_TCB_PRIVILEGE, true); - /* Register as logon process. */ - RtlInitAnsiString (&name, "Cygwin"); - status = LsaRegisterLogonProcess (&name, &lsa_hdl, &sec_mode); + if (logon) + { + /* Register as logon process. */ + RtlInitAnsiString (&name, "Cygwin"); + status = LsaRegisterLogonProcess (&name, &lsa_hdl, &sec_mode); + } + else + status = LsaConnectUntrusted (&lsa_hdl); if (status != STATUS_SUCCESS) { - debug_printf ("LsaRegisterLogonProcess: %y", status); + debug_printf ("%s: %y", logon ? "LsaRegisterLogonProcess" + : "LsaConnectUntrusted", status); __seterrno_from_nt_status (status); goto out; } - /* Fetch user and domain name and check if this is a domain user. - If so, try Kerberos first. */ - extract_nt_dom_user (pw, domain, user); + /* Check if this is a domain user. If so, try Kerberos first. */ try_kerb_auth = cygheap->dom.member_machine () && wcscasecmp (domain, cygheap->dom.account_flat_name ()); /* Create origin. */ @@ -1523,7 +1529,7 @@ s4uauth (struct passwd *pw, NTSTATUS &ret_status) RtlSecureZeroMemory (authinf, authinf_size); s4u_logon = (KERB_S4U_LOGON *) authinf; s4u_logon->MessageType = KerbS4ULogon; - s4u_logon->Flags = 0; + s4u_logon->Flags = logon ? 0 : KERB_S4U_LOGON_FLAG_IDENTITY; /* Append user to login info */ RtlInitEmptyUnicodeString (&s4u_logon->ClientUpn, (PWCHAR) (s4u_logon + 1), @@ -1615,7 +1621,7 @@ out: if (profile) LsaFreeReturnBuffer (profile); - if (token) + if (token && logon) { /* Convert to primary token. Strictly speaking this is only required on Vista/2008. CreateProcessAsUser also takes diff --git a/winsup/cygwin/security.h b/winsup/cygwin/security.h index cabb91d25..483a527e7 100644 --- a/winsup/cygwin/security.h +++ b/winsup/cygwin/security.h @@ -480,7 +480,7 @@ HANDLE lsaauth (cygsid &, user_groups &); /* LSA private key storage authentication, same as when using service logons. */ HANDLE lsaprivkeyauth (struct passwd *pw); /* Kerberos or MsV1 S4U logon. */ -HANDLE s4uauth (struct passwd *pw, NTSTATUS &ret_status); +HANDLE s4uauth (bool logon, PCWSTR domain, PCWSTR user, NTSTATUS &ret_status); /* Verify an existing token */ bool verify_token (HANDLE token, cygsid &usersid, user_groups &groups, bool *pintern = NULL); /* Get groups of a user */ diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc index c3a92445e..f4e8bcf2c 100644 --- a/winsup/cygwin/syscalls.cc +++ b/winsup/cygwin/syscalls.cc @@ -37,6 +37,7 @@ details. */ #include #include #include +#include #include "ntdll.h" #undef fstat @@ -3565,9 +3566,12 @@ seteuid32 (uid_t uid) if (!new_token) { NTSTATUS status; + WCHAR domain[MAX_DOMAIN_NAME_LEN + 1]; + WCHAR user[UNLEN + 1]; debug_printf ("lsaprivkeyauth failed, try s4uauth."); - if (!(new_token = s4uauth (pw_new, status))) + extract_nt_dom_user (pw_new, domain, user); + if (!(new_token = s4uauth (true, domain, user, status))) { if (status != STATUS_INVALID_PARAMETER) { From 649911fb40e45bc9a1ad8a3c28d90eec78c9cb7f Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Fri, 22 Feb 2019 18:31:03 +0100 Subject: [PATCH 240/475] Cygwin: get_user_groups: fetch a user's group list from identification token NetUserGetGroups and NetUserGetLocalGroups sometimes take a lot of time (up to more than 2 mins) for no apparent reason. Call s4uauth to generate an identification token for the user and fetch the group list from there. This is *much* faster. Keep the old code only for the sake of WOW64 on Vista and Windows 7, which don't implement MsV1_0S4ULogon. Signed-off-by: Corinna Vinschen --- winsup/cygwin/sec_auth.cc | 81 ++++++++++++++++++++++++++------------- winsup/cygwin/wincap.cc | 10 +++++ winsup/cygwin/wincap.h | 2 + 3 files changed, 66 insertions(+), 27 deletions(-) diff --git a/winsup/cygwin/sec_auth.cc b/winsup/cygwin/sec_auth.cc index 54182dd6c..459fe5420 100644 --- a/winsup/cygwin/sec_auth.cc +++ b/winsup/cygwin/sec_auth.cc @@ -535,7 +535,6 @@ get_server_groups (cygsidlist &grp_list, PSID usersid, { WCHAR user[UNLEN + 1]; WCHAR domain[MAX_DOMAIN_NAME_LEN + 1]; - WCHAR server[INTERNET_MAX_HOST_NAME_LENGTH + 3]; DWORD ulen = UNLEN + 1; DWORD dlen = MAX_DOMAIN_NAME_LEN + 1; SID_NAME_USE use; @@ -546,41 +545,73 @@ get_server_groups (cygsidlist &grp_list, PSID usersid, return true; } - grp_list *= well_known_world_sid; - grp_list *= well_known_authenticated_users_sid; - if (!LookupAccountSidW (NULL, usersid, user, &ulen, domain, &dlen, &use)) { __seterrno (); return false; } /* If the SID does NOT start with S-1-5-21, the domain is some builtin - domain. The search for a logon server and fetching group accounts - is moot. */ + domain. We don't fetch a group list then. */ if (sid_id_auth (usersid) == 5 /* SECURITY_NT_AUTHORITY */ - && sid_sub_auth (usersid, 0) == SECURITY_NT_NON_UNIQUE - && get_logon_server (domain, server, DS_IS_FLAT_NAME)) + && sid_sub_auth (usersid, 0) == SECURITY_NT_NON_UNIQUE) { - if (check_account_disabled == CHK_DISABLED) + if (wincap.no_msv1_0_s4u_logon_in_wow64 ()) { - NET_API_STATUS napi_stat; - USER_INFO_1 *ui1; - bool allow_user = false; + WCHAR server[INTERNET_MAX_HOST_NAME_LENGTH + 3]; - napi_stat = NetUserGetInfo (server, user, 1, (LPBYTE *) &ui1); - if (napi_stat == NERR_Success) - allow_user = !(ui1->usri1_flags & (UF_ACCOUNTDISABLE | UF_LOCKOUT)); - if (ui1) - NetApiBufferFree (ui1); - if (!allow_user) + if (!get_logon_server (domain, server, DS_IS_FLAT_NAME)) + return false; + if (check_account_disabled == CHK_DISABLED) { - debug_printf ("User denied: %W\\%W", domain, user); - set_errno (EACCES); - return false; + NET_API_STATUS napi_stat; + USER_INFO_1 *ui1; + bool allow_user = false; + + napi_stat = NetUserGetInfo (server, user, 1, (LPBYTE *) &ui1); + if (napi_stat == NERR_Success) + allow_user = !(ui1->usri1_flags & (UF_ACCOUNTDISABLE | UF_LOCKOUT)); + if (ui1) + NetApiBufferFree (ui1); + if (!allow_user) + { + debug_printf ("User denied: %W\\%W", domain, user); + set_errno (EACCES); + return false; + } } + grp_list *= well_known_world_sid; + grp_list *= well_known_authenticated_users_sid; + get_user_groups (server, grp_list, user, domain); + get_user_local_groups (domain, grp_list, user); + return true; } - get_user_groups (server, grp_list, user, domain); - get_user_local_groups (domain, grp_list, user); + + tmp_pathbuf tp; + HANDLE token; + NTSTATUS status; + PTOKEN_GROUPS groups; + ULONG size; + + token = s4uauth (false, domain, user, status); + if (!token) + return false; + + groups = (PTOKEN_GROUPS) tp.w_get (); + status = NtQueryInformationToken (token, TokenGroups, groups, + 2 * NT_MAX_PATH, &size); + if (NT_SUCCESS (status)) + for (DWORD pg = 0; pg < groups->GroupCount; ++pg) + { + if (groups->Groups[pg].Attributes & SE_GROUP_USE_FOR_DENY_ONLY) + continue; + cygpsid grpsid = groups->Groups[pg].Sid; + if (sid_id_auth (grpsid) == 5 /* SECURITY_NT_AUTHORITY */ + && sid_sub_auth (grpsid, 0) == SECURITY_NT_NON_UNIQUE) + grp_list += grpsid; + else + grp_list *= grpsid; + } + NtClose (token); } return true; } @@ -589,8 +620,6 @@ static bool get_initgroups_sidlist (cygsidlist &grp_list, PSID usersid, PSID pgrpsid, PTOKEN_GROUPS my_grps) { - grp_list *= well_known_world_sid; - grp_list *= well_known_authenticated_users_sid; if (well_known_system_sid != usersid) get_token_group_sidlist (grp_list, my_grps); if (!get_server_groups (grp_list, usersid, CHK_DISABLED)) @@ -605,8 +634,6 @@ static bool get_setgroups_sidlist (cygsidlist &tmp_list, PSID usersid, PTOKEN_GROUPS my_grps, user_groups &groups) { - tmp_list *= well_known_world_sid; - tmp_list *= well_known_authenticated_users_sid; get_token_group_sidlist (tmp_list, my_grps); if (!get_server_groups (tmp_list, usersid, CHK_DISABLED)) return false; diff --git a/winsup/cygwin/wincap.cc b/winsup/cygwin/wincap.cc index 132265c6a..7e381f420 100644 --- a/winsup/cygwin/wincap.cc +++ b/winsup/cygwin/wincap.cc @@ -39,6 +39,7 @@ wincaps wincap_vista __attribute__((section (".cygwin_dll_common"), shared)) = { has_posix_unlink_semantics:false, has_case_sensitive_dirs:false, has_posix_rename_semantics:false, + no_msv1_0_s4u_logon_in_wow64:true, }, }; @@ -63,6 +64,7 @@ wincaps wincap_7 __attribute__((section (".cygwin_dll_common"), shared)) = { has_posix_unlink_semantics:false, has_case_sensitive_dirs:false, has_posix_rename_semantics:false, + no_msv1_0_s4u_logon_in_wow64:true, }, }; @@ -87,6 +89,7 @@ wincaps wincap_8 __attribute__((section (".cygwin_dll_common"), shared)) = { has_posix_unlink_semantics:false, has_case_sensitive_dirs:false, has_posix_rename_semantics:false, + no_msv1_0_s4u_logon_in_wow64:false, }, }; @@ -111,6 +114,7 @@ wincaps wincap_10_1507 __attribute__((section (".cygwin_dll_common"), shared)) has_posix_unlink_semantics:false, has_case_sensitive_dirs:false, has_posix_rename_semantics:false, + no_msv1_0_s4u_logon_in_wow64:false, }, }; @@ -135,6 +139,7 @@ wincaps wincap_10_1511 __attribute__((section (".cygwin_dll_common"), shared)) = has_posix_unlink_semantics:false, has_case_sensitive_dirs:false, has_posix_rename_semantics:false, + no_msv1_0_s4u_logon_in_wow64:false, }, }; @@ -159,6 +164,7 @@ wincaps wincap_10_1703 __attribute__((section (".cygwin_dll_common"), shared)) = has_posix_unlink_semantics:false, has_case_sensitive_dirs:false, has_posix_rename_semantics:false, + no_msv1_0_s4u_logon_in_wow64:false, }, }; @@ -183,6 +189,7 @@ wincaps wincap_10_1709 __attribute__((section (".cygwin_dll_common"), shared)) = has_posix_unlink_semantics:true, has_case_sensitive_dirs:false, has_posix_rename_semantics:false, + no_msv1_0_s4u_logon_in_wow64:false, }, }; @@ -207,6 +214,7 @@ wincaps wincap_10_1803 __attribute__((section (".cygwin_dll_common"), shared)) = has_posix_unlink_semantics:true, has_case_sensitive_dirs:true, has_posix_rename_semantics:false, + no_msv1_0_s4u_logon_in_wow64:false, }, }; @@ -231,6 +239,7 @@ wincaps wincap_10_1809 __attribute__((section (".cygwin_dll_common"), shared)) = has_posix_unlink_semantics:true, has_case_sensitive_dirs:true, has_posix_rename_semantics:true, + no_msv1_0_s4u_logon_in_wow64:true, }, }; @@ -303,6 +312,7 @@ wincapc::init () ((wincaps *)caps)->needs_count_in_si_lpres2 = false; ((wincaps *)caps)->has_gaa_largeaddress_bug = false; ((wincaps *)caps)->has_broken_prefetchvm = false; + ((wincaps *)caps)->no_msv1_0_s4u_logon_in_wow64 = false; } __small_sprintf (osnam, "NT-%d.%d", version.dwMajorVersion, diff --git a/winsup/cygwin/wincap.h b/winsup/cygwin/wincap.h index 75b7a9f0a..0e83f6794 100644 --- a/winsup/cygwin/wincap.h +++ b/winsup/cygwin/wincap.h @@ -33,6 +33,7 @@ struct wincaps unsigned has_posix_unlink_semantics : 1; unsigned has_case_sensitive_dirs : 1; unsigned has_posix_rename_semantics : 1; + unsigned no_msv1_0_s4u_logon_in_wow64 : 1; }; }; @@ -87,6 +88,7 @@ public: bool IMPLEMENT (has_posix_unlink_semantics) bool IMPLEMENT (has_case_sensitive_dirs) bool IMPLEMENT (has_posix_rename_semantics) + bool IMPLEMENT (no_msv1_0_s4u_logon_in_wow64) void disable_case_sensitive_dirs () { From 322ab51659dbac7ff6b5a6aa5bfb3099a7e11681 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Sat, 23 Feb 2019 17:22:44 +0100 Subject: [PATCH 241/475] Cygwin: user profile: fetch roaming profile path via LDAP Commit 649911fb40e45bc9a1ad8a3c28d90eec78c9cb7f avoids the calls to NetUserGetGroups and NetUserGetLocalGroups since these can take a lot of time. The same problem potentially occurs when loading the user profile. The code fetches the roaming profile path calling NetUserGetInfo, which also can be rather slow. To avoid this problem, fetch the profile patch using LDAP. Also, don't bail out early if the user's registry hive already exists. This may result in outdated information. Signed-off-by: Corinna Vinschen --- winsup/cygwin/ldap.cc | 1 + winsup/cygwin/ldap.h | 2 ++ winsup/cygwin/sec_auth.cc | 66 ++++++++++++++++++++++++++------------- 3 files changed, 48 insertions(+), 21 deletions(-) diff --git a/winsup/cygwin/ldap.cc b/winsup/cygwin/ldap.cc index dcd4fc461..01e892f03 100644 --- a/winsup/cygwin/ldap.cc +++ b/winsup/cygwin/ldap.cc @@ -36,6 +36,7 @@ static const PCWSTR std_user_attr[] = L"objectSid", L"primaryGroupID", L"uidNumber", + L"profilePath", L"cygwinUnixUid", /* TODO */ /* windows scheme */ L"displayName", diff --git a/winsup/cygwin/ldap.h b/winsup/cygwin/ldap.h index 4c2437a6f..d51f18cbb 100644 --- a/winsup/cygwin/ldap.h +++ b/winsup/cygwin/ldap.h @@ -63,4 +63,6 @@ public: PWCHAR get_account_name () { return get_string_attribute (L"sAMAccountName"); } gid_t get_unix_gid () { return get_num_attribute (L"gidNumber"); } + PWCHAR get_profile_path () + { return get_string_attribute (L"profilePath"); } }; diff --git a/winsup/cygwin/sec_auth.cc b/winsup/cygwin/sec_auth.cc index 459fe5420..c96011d6d 100644 --- a/winsup/cygwin/sec_auth.cc +++ b/winsup/cygwin/sec_auth.cc @@ -231,23 +231,12 @@ load_user_profile (HANDLE token, struct passwd *pw, cygpsid &usersid) WCHAR domain[DNLEN + 1]; WCHAR username[UNLEN + 1]; WCHAR sid[128]; - HKEY hkey; WCHAR userpath[MAX_PATH]; PROFILEINFOW pi; - WCHAR server[INTERNET_MAX_HOST_NAME_LENGTH + 3]; - NET_API_STATUS nas = NERR_UserNotFound; - PUSER_INFO_3 ui; extract_nt_dom_user (pw, domain, username); usersid.string (sid); - debug_printf ("user: <%W> <%W>", username, sid); - /* Check if user hive is already loaded. */ - if (!RegOpenKeyExW (HKEY_USERS, sid, 0, KEY_READ, &hkey)) - { - debug_printf ("User registry hive for %W already exists", username); - RegCloseKey (hkey); - return NULL; - } + debug_printf ("user: <%W> <%W> <%W>", username, domain, sid); /* Check if the local profile dir has already been created. */ if (!get_user_profile_directory (sid, userpath, MAX_PATH)) { @@ -264,21 +253,56 @@ load_user_profile (HANDLE token, struct passwd *pw, cygpsid &usersid) pi.dwSize = sizeof pi; pi.dwFlags = PI_NOUI; pi.lpUserName = username; - /* Check if user has a roaming profile and fill in lpProfilePath, if so. */ - if (get_logon_server (domain, server, DS_IS_FLAT_NAME)) + /* Check if user has a roaming profile and fill in lpProfilePath, if so. + Call NetUserGetInfo only for local machine accounts, use LDAP otherwise. */ + if (!wcscasecmp (domain, cygheap->dom.account_flat_name ())) { - nas = NetUserGetInfo (server, username, 3, (PBYTE *) &ui); - if (NetUserGetInfo (server, username, 3, (PBYTE *) &ui) != NERR_Success) + NET_API_STATUS nas; + PUSER_INFO_3 ui; + + nas = NetUserGetInfo (NULL, username, 3, (PBYTE *) &ui); + if (nas != NERR_Success) debug_printf ("NetUserGetInfo, %u", nas); - else if (ui->usri3_profile && *ui->usri3_profile) - pi.lpProfilePath = ui->usri3_profile; + else + { + if (ui->usri3_profile && *ui->usri3_profile) + pi.lpProfilePath = ui->usri3_profile; + NetApiBufferFree (ui); + } + } + else + { + cyg_ldap cldap; + PWCHAR dnsdomain = NULL; + + if (!wcscasecmp (domain, cygheap->dom.primary_flat_name ())) + dnsdomain = wcsdup (cygheap->dom.primary_dns_name ()); + else + { + PDS_DOMAIN_TRUSTSW td = NULL; + + for (ULONG idx = 0; (td = cygheap->dom.trusted_domain (idx)); ++idx) + if (!wcscasecmp (domain, td->NetbiosDomainName)) + { + dnsdomain = wcsdup (td->DnsDomainName); + break; + } + } + if (cldap.fetch_ad_account (usersid, false, dnsdomain)) + { + PWCHAR val = cldap.get_profile_path (); + if (val && *val) + { + wcsncpy (userpath, val, MAX_PATH - 1); + userpath[MAX_PATH - 1] = L'\0'; + pi.lpProfilePath = userpath; + } + } + free (dnsdomain); } if (!LoadUserProfileW (token, &pi)) debug_printf ("LoadUserProfileW, %E"); - /* Free buffer created by NetUserGetInfo */ - if (nas == NERR_Success) - NetApiBufferFree (ui); return pi.hProfile; } From 13b1f9c0d1c6860be91523289c8a6ac6a87cb9db Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Sat, 23 Feb 2019 17:24:05 +0100 Subject: [PATCH 242/475] Cygwin: seteuid32: don't use INVALID_HANDLE_VALUE NULL is the natural state of an unused handle Signed-off-by: Corinna Vinschen --- winsup/cygwin/syscalls.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc index f4e8bcf2c..172b7c4f6 100644 --- a/winsup/cygwin/syscalls.cc +++ b/winsup/cygwin/syscalls.cc @@ -3479,7 +3479,7 @@ seteuid32 (uid_t uid) cygsid usersid; user_groups &groups = cygheap->user.groups; - HANDLE new_token = INVALID_HANDLE_VALUE; + HANDLE new_token = NULL; struct passwd * pw_new; bool token_is_internal, issamesid = false; @@ -3550,7 +3550,7 @@ seteuid32 (uid_t uid) /* If no impersonation token is available, try to authenticate using LSA private data stored password, LSA authentication using our own LSA module, or, as last chance, NtCreateToken. */ - if (new_token == INVALID_HANDLE_VALUE) + if (new_token == NULL) { new_token = lsaprivkeyauth (pw_new); if (new_token) From 9db6048c0fe7c35586f762ee2cdc1d0f92a041ea Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Sat, 23 Feb 2019 17:28:12 +0100 Subject: [PATCH 243/475] Cygwin: cygheap: better comment impersonation tokens Signed-off-by: Corinna Vinschen --- winsup/cygwin/cygheap.h | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/winsup/cygwin/cygheap.h b/winsup/cygwin/cygheap.h index be088b224..99d2e5389 100644 --- a/winsup/cygwin/cygheap.h +++ b/winsup/cygwin/cygheap.h @@ -101,12 +101,11 @@ public: gid_t real_gid; /* Ditto */ user_groups groups; /* Primary and supp SIDs */ - /* token is needed if set(e)uid should be called. It can be set by a call - to `set_impersonation_token()'. */ - HANDLE external_token; - HANDLE internal_token; - HANDLE curr_primary_token; - HANDLE curr_imp_token; + HANDLE external_token; /* token from set_impersonation_token call */ + HANDLE internal_token; /* password-less token fetched in seteuid32 */ + HANDLE curr_primary_token; /* Just a copy of external or internal token */ + HANDLE curr_imp_token; /* impersonation token derived from primary + token */ bool ext_token_is_restricted; /* external_token is restricted token */ bool curr_token_is_restricted; /* curr_primary_token is restricted token */ bool setuid_to_restricted; /* switch to restricted token by setuid () */ From 331653a215a054688308236e595bd0dfba08450f Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Sat, 23 Feb 2019 17:29:42 +0100 Subject: [PATCH 244/475] Cygwin: cygheap: drop unnecessary code closing curr_primary_token curr_primary_token is either NO_IMPERSONATION or the external_token or the internal_token, so it's never required to be closed by itself. Signed-off-by: Corinna Vinschen --- winsup/cygwin/cygheap.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/winsup/cygwin/cygheap.h b/winsup/cygwin/cygheap.h index 99d2e5389..8877cc358 100644 --- a/winsup/cygwin/cygheap.h +++ b/winsup/cygwin/cygheap.h @@ -177,10 +177,6 @@ public: { if (curr_imp_token != NO_IMPERSONATION) CloseHandle (curr_imp_token); - if (curr_primary_token != NO_IMPERSONATION - && curr_primary_token != external_token - && curr_primary_token != internal_token) - CloseHandle (curr_primary_token); if (external_token != NO_IMPERSONATION) CloseHandle (external_token); if (internal_token != NO_IMPERSONATION) From 71b8777a7140b79942d6e5079818cad2c3f5f07f Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Sat, 23 Feb 2019 17:30:44 +0100 Subject: [PATCH 245/475] Cygwin: user profile: Make an effort to unload unused user profiles Does this work? There's not much feedback given. TODO: We might want to try unloading the user profile at process exit as well, FWIW. Signed-off-by: Corinna Vinschen --- winsup/cygwin/autoload.cc | 1 + winsup/cygwin/cygheap.h | 3 +++ winsup/cygwin/sec_auth.cc | 6 ++++++ winsup/cygwin/security.h | 1 + winsup/cygwin/syscalls.cc | 15 ++++++++++++--- winsup/cygwin/uinfo.cc | 2 ++ 6 files changed, 25 insertions(+), 3 deletions(-) diff --git a/winsup/cygwin/autoload.cc b/winsup/cygwin/autoload.cc index 056fac7dc..c04e25c95 100644 --- a/winsup/cygwin/autoload.cc +++ b/winsup/cygwin/autoload.cc @@ -699,6 +699,7 @@ LoadDLLfuncEx (CreateEnvironmentBlock, 12, userenv, 1) LoadDLLfuncEx2 (CreateProfile, 16, userenv, 1, 1) LoadDLLfunc (DestroyEnvironmentBlock, 4, userenv) LoadDLLfunc (LoadUserProfileW, 8, userenv) +LoadDLLfunc (UnloadUserProfile, 8, userenv) LoadDLLfuncEx3 (waveInAddBuffer, 12, winmm, 1, 0, 1) LoadDLLfuncEx3 (waveInClose, 4, winmm, 1, 0, 1) diff --git a/winsup/cygwin/cygheap.h b/winsup/cygwin/cygheap.h index 8877cc358..5c5e3cd1e 100644 --- a/winsup/cygwin/cygheap.h +++ b/winsup/cygwin/cygheap.h @@ -106,6 +106,9 @@ public: HANDLE curr_primary_token; /* Just a copy of external or internal token */ HANDLE curr_imp_token; /* impersonation token derived from primary token */ + HANDLE imp_profile_token; /* Handle to the token used to load the + user profile in "imp_profile" */ + HANDLE imp_profile; /* Handle to the user profile */ bool ext_token_is_restricted; /* external_token is restricted token */ bool curr_token_is_restricted; /* curr_primary_token is restricted token */ bool setuid_to_restricted; /* switch to restricted token by setuid () */ diff --git a/winsup/cygwin/sec_auth.cc b/winsup/cygwin/sec_auth.cc index c96011d6d..59ee55339 100644 --- a/winsup/cygwin/sec_auth.cc +++ b/winsup/cygwin/sec_auth.cc @@ -306,6 +306,12 @@ load_user_profile (HANDLE token, struct passwd *pw, cygpsid &usersid) return pi.hProfile; } +bool +unload_user_profile (HANDLE token, HANDLE profile) +{ + return UnloadUserProfile (token, profile); +} + HANDLE lsa_open_policy (PWCHAR server, ACCESS_MASK access) { diff --git a/winsup/cygwin/security.h b/winsup/cygwin/security.h index 483a527e7..0ce7e8d7a 100644 --- a/winsup/cygwin/security.h +++ b/winsup/cygwin/security.h @@ -502,6 +502,7 @@ PWCHAR get_user_profile_directory (PCWSTR sidstr, PWCHAR path, SIZE_T path_len); /* Load user profile if it's not already loaded. */ HANDLE load_user_profile (HANDLE token, struct passwd *pw, cygpsid &sid); +bool unload_user_profile (HANDLE token, HANDLE profile); HANDLE lsa_open_policy (PWCHAR server, ACCESS_MASK access); void lsa_close_policy (HANDLE lsa); diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc index 172b7c4f6..b1039762d 100644 --- a/winsup/cygwin/syscalls.cc +++ b/winsup/cygwin/syscalls.cc @@ -3603,8 +3603,17 @@ seteuid32 (uid_t uid) { NTSTATUS status; - if (!request_restricted_uid_switch) - load_user_profile (new_token, pw_new, usersid); + if (!request_restricted_uid_switch + && new_token != cygheap->user.imp_profile_token) + { + if (cygheap->user.imp_profile_token && cygheap->user.imp_profile) + unload_user_profile (cygheap->user.imp_profile_token, + cygheap->user.imp_profile); + cygheap->user.imp_profile = load_user_profile (new_token, pw_new, + usersid); + if (cygheap->user.imp_profile) + cygheap->user.imp_profile_token = new_token; + } /* Try setting owner to same value as user. */ status = NtSetInformationToken (new_token, TokenOwner, @@ -3634,7 +3643,7 @@ seteuid32 (uid_t uid) issamesid = (usersid == cygheap->user.sid ()); cygheap->user.set_sid (usersid); cygheap->user.curr_primary_token = new_token == hProcToken ? NO_IMPERSONATION - : new_token; + : new_token; cygheap->user.curr_token_is_restricted = false; cygheap->user.setuid_to_restricted = false; if (cygheap->user.curr_imp_token != NO_IMPERSONATION) diff --git a/winsup/cygwin/uinfo.cc b/winsup/cygwin/uinfo.cc index bfcce00da..49614cb45 100644 --- a/winsup/cygwin/uinfo.cc +++ b/winsup/cygwin/uinfo.cc @@ -239,6 +239,8 @@ uinfo_init () cygheap->user.internal_token = NO_IMPERSONATION; cygheap->user.curr_primary_token = NO_IMPERSONATION; cygheap->user.curr_imp_token = NO_IMPERSONATION; + cygheap->user.imp_profile_token = NO_IMPERSONATION; + cygheap->user.imp_profile = NULL; cygheap->user.ext_token_is_restricted = false; cygheap->user.curr_token_is_restricted = false; cygheap->user.setuid_to_restricted = false; From 8eee25241e86fc596acde25c7c53723b75afee30 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Sat, 23 Feb 2019 20:46:48 +0100 Subject: [PATCH 246/475] Cygwin: user profile: add debug output to unload_user_profile Signed-off-by: Corinna Vinschen --- winsup/cygwin/sec_auth.cc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/winsup/cygwin/sec_auth.cc b/winsup/cygwin/sec_auth.cc index 59ee55339..a4e7458b3 100644 --- a/winsup/cygwin/sec_auth.cc +++ b/winsup/cygwin/sec_auth.cc @@ -309,7 +309,10 @@ load_user_profile (HANDLE token, struct passwd *pw, cygpsid &usersid) bool unload_user_profile (HANDLE token, HANDLE profile) { - return UnloadUserProfile (token, profile); + bool ret = UnloadUserProfile (token, profile); + if (!ret) + debug_printf ("UnloadUserProfile, %E"); + return ret; } HANDLE From dd3730ed9c1c78176f1aab1b429bb5a105d90a44 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Sat, 23 Feb 2019 20:48:59 +0100 Subject: [PATCH 247/475] Cygwin: seteuid: allow inheriting impersonation user profile handle The child process needs access to the handle to be able to unload it when switching user context. Signed-off-by: Corinna Vinschen --- winsup/cygwin/syscalls.cc | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc index b1039762d..a73af6748 100644 --- a/winsup/cygwin/syscalls.cc +++ b/winsup/cygwin/syscalls.cc @@ -3612,7 +3612,11 @@ seteuid32 (uid_t uid) cygheap->user.imp_profile = load_user_profile (new_token, pw_new, usersid); if (cygheap->user.imp_profile) - cygheap->user.imp_profile_token = new_token; + { + cygheap->user.imp_profile_token = new_token; + SetHandleInformation (cygheap->user.imp_profile, + HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT); + } } /* Try setting owner to same value as user. */ From bcb33dc4f0552e749dcb6c44e1ef7815b5db75a1 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Sat, 23 Feb 2019 21:06:12 +0100 Subject: [PATCH 248/475] Cywin: user profile: unload impersonation user profile on exit Signed-off-by: Corinna Vinschen --- winsup/cygwin/cygheap.h | 5 +++++ winsup/cygwin/pinfo.cc | 1 + 2 files changed, 6 insertions(+) diff --git a/winsup/cygwin/cygheap.h b/winsup/cygwin/cygheap.h index 5c5e3cd1e..4d9feb072 100644 --- a/winsup/cygwin/cygheap.h +++ b/winsup/cygwin/cygheap.h @@ -193,6 +193,11 @@ public: { return effec_cygsid.string (buf); } + void exit () + { + if (imp_profile_token && imp_profile) + unload_user_profile (imp_profile_token, imp_profile); + } const char __reg3 *test_uid (char *&, const char *, size_t); }; diff --git a/winsup/cygwin/pinfo.cc b/winsup/cygwin/pinfo.cc index 064299e0c..e29c00746 100644 --- a/winsup/cygwin/pinfo.cc +++ b/winsup/cygwin/pinfo.cc @@ -224,6 +224,7 @@ pinfo::exit (DWORD n) exitcode = ((exitcode & 0xff) << 8) | ((exitcode >> 8) & 0xff); sigproc_printf ("Calling dlls.cleanup_forkables n %y, exitcode %y", n, exitcode); dlls.cleanup_forkables (); + cygheap->user.exit (); sigproc_printf ("Calling ExitProcess n %y, exitcode %y", n, exitcode); if (!TerminateProcess (GetCurrentProcess (), exitcode)) system_printf ("TerminateProcess failed, %E"); From 0fb41d48aa3b0e8637a783961ffe4d67911fec50 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Sat, 23 Feb 2019 23:02:44 +0100 Subject: [PATCH 249/475] Cygwin: timerfd: fix select always returning immediately Signed-off-by: Corinna Vinschen --- winsup/cygwin/select.cc | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/winsup/cygwin/select.cc b/winsup/cygwin/select.cc index d6757e4ed..59325860d 100644 --- a/winsup/cygwin/select.cc +++ b/winsup/cygwin/select.cc @@ -1871,6 +1871,26 @@ fhandler_signalfd::select_except (select_stuff *stuff) return s; } +static int +peek_timerfd (select_record *me, bool) +{ + if (WaitForSingleObject (me->h, 0) == WAIT_OBJECT_0) + { + select_printf ("timerfd %d ready", me->fd); + me->read_ready = true; + return 1; + } + select_printf ("timerfd %d not ready", me->fd); + return 0; +} + +static int +verify_timerfd (select_record *me, fd_set *rfds, fd_set *wfds, + fd_set *efds) +{ + return peek_timerfd (me, true); +} + select_record * fhandler_timerfd::select_read (select_stuff *stuff) { @@ -1878,11 +1898,12 @@ fhandler_timerfd::select_read (select_stuff *stuff) if (!s->startup) { s->startup = no_startup; - s->verify = verify_ok; + s->verify = verify_timerfd; } s->h = get_timerfd_handle (); + s->peek = peek_timerfd; s->read_selected = true; - s->read_ready = true; + s->read_ready = false; return s; } From f3be186911ca2a4ab1c7482e405babdc0cbad839 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Sat, 23 Feb 2019 23:07:42 +0100 Subject: [PATCH 250/475] Cygwin: Add 3.0.2 release file Signed-off-by: Corinna Vinschen --- winsup/cygwin/release/3.0.2 | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 winsup/cygwin/release/3.0.2 diff --git a/winsup/cygwin/release/3.0.2 b/winsup/cygwin/release/3.0.2 new file mode 100644 index 000000000..0f3f4f741 --- /dev/null +++ b/winsup/cygwin/release/3.0.2 @@ -0,0 +1,20 @@ +What's new: +----------- + + +What changed: +------------- + + +Bug Fixes +--------- + +- Fix timerfd select always returning immediately. + Addresses: https://cygwin.com/ml/cygwin/2019-02/msg00364.html + +- Drop enforcing case-correct group names for AD accounts to avoid + excessively long startup times. + Addresses: https://cygwin.com/ml/cygwin/2019-02/msg00301.html + +- Fix and speed up evaluation of group membership in seteuid. + Addresses: Local testing. From aeaa051f3bd2dd74f664eeba87c9f2140e0b178e Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Sun, 24 Feb 2019 10:12:03 +0100 Subject: [PATCH 251/475] Cygwin: POSIX timers: Fix timer values returned for unarmed timer The "optimized" condition to recognize an unarmed timer was plain wrong. Replace it by checking the stored it_value against 0. Signed-off-by: Corinna Vinschen --- winsup/cygwin/posix_timer.cc | 2 +- winsup/cygwin/release/3.0.2 | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/winsup/cygwin/posix_timer.cc b/winsup/cygwin/posix_timer.cc index a76ba0694..0332cab92 100644 --- a/winsup/cygwin/posix_timer.cc +++ b/winsup/cygwin/posix_timer.cc @@ -245,7 +245,7 @@ timer_tracker::gettime (itimerspec *curr_value, bool lock) return -EINVAL; } } - if (!cancel_evt) + if (!time_spec.it_value.tv_sec && !time_spec.it_value.tv_nsec) memset (curr_value, 0, sizeof (*curr_value)); else { diff --git a/winsup/cygwin/release/3.0.2 b/winsup/cygwin/release/3.0.2 index 0f3f4f741..c1a18a903 100644 --- a/winsup/cygwin/release/3.0.2 +++ b/winsup/cygwin/release/3.0.2 @@ -18,3 +18,6 @@ Bug Fixes - Fix and speed up evaluation of group membership in seteuid. Addresses: Local testing. + +- Fix getitimer/timer_gettime values returned for unarmed timer. + Addresses: https://cygwin.com/ml/cygwin/2019-02/msg00395.html From a4e2eb6ba34b8cd3457e7f4074b1725874d6e2e9 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Sun, 24 Feb 2019 20:15:36 +0100 Subject: [PATCH 252/475] Cygwin: timerfd: fix shared memory allocation in fork/exec timerfd_tracker::fixup_after_fork_exec always tries to restore the shared timer region at the same address as in the parent. This is entirely unnecessary and wasn't intended, rather some kind of copy/paste thinko. Fix that. Print NtMapViewOfSection status code in api_fatal on failure for debugging. Signed-off-by: Corinna Vinschen --- winsup/cygwin/release/3.0.2 | 3 +++ winsup/cygwin/timerfd.cc | 14 ++++++++------ 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/winsup/cygwin/release/3.0.2 b/winsup/cygwin/release/3.0.2 index c1a18a903..e24fe4e7c 100644 --- a/winsup/cygwin/release/3.0.2 +++ b/winsup/cygwin/release/3.0.2 @@ -12,6 +12,9 @@ Bug Fixes - Fix timerfd select always returning immediately. Addresses: https://cygwin.com/ml/cygwin/2019-02/msg00364.html +- Fix fork/exec failing to restore timerfd share mem in child process. + Addresses: https://cygwin.com/ml/cygwin/2019-02/msg00400.html + - Drop enforcing case-correct group names for AD accounts to avoid excessively long startup times. Addresses: https://cygwin.com/ml/cygwin/2019-02/msg00301.html diff --git a/winsup/cygwin/timerfd.cc b/winsup/cygwin/timerfd.cc index 7e6be72b2..2823560e6 100644 --- a/winsup/cygwin/timerfd.cc +++ b/winsup/cygwin/timerfd.cc @@ -408,6 +408,7 @@ void timerfd_tracker::fixup_after_fork_exec (bool execing) { NTSTATUS status; + PVOID base_address = NULL; OBJECT_ATTRIBUTES attr; SIZE_T vsize = PAGE_SIZE; @@ -416,11 +417,12 @@ timerfd_tracker::fixup_after_fork_exec (bool execing) return; /* Recreate shared section mapping */ status = NtMapViewOfSection (tfd_shared_hdl, NtCurrentProcess (), - (void **) &tfd_shared, 0, PAGE_SIZE, NULL, - &vsize, ViewShare, MEM_TOP_DOWN, PAGE_READWRITE); + &base_address, 0, PAGE_SIZE, NULL, + &vsize, ViewShare, 0, PAGE_READWRITE); if (!NT_SUCCESS (status)) - api_fatal ("Can't recreate shared timerfd section during %s!", - execing ? "execve" : "fork"); + api_fatal ("Can't recreate shared timerfd section during %s, status %y!", + execing ? "execve" : "fork", status); + tfd_shared = (timerfd_shared *) base_address; /* Increment global instance count by the number of instances in this process */ InterlockedAdd (&tfd_shared->instance_count, local_instance_count); @@ -430,8 +432,8 @@ timerfd_tracker::fixup_after_fork_exec (bool execing) status = NtCreateEvent (&cancel_evt, EVENT_ALL_ACCESS, &attr, NotificationEvent, FALSE); if (!NT_SUCCESS (status)) - api_fatal ("Can't recreate timerfd cancel event during %s!", - execing ? "execve" : "fork"); + api_fatal ("Can't recreate timerfd cancel event during %s, status %y!", + execing ? "execve" : "fork", status); /* Set winpid so we don't run this twice */ winpid = GetCurrentProcessId (); new cygthread (timerfd_thread, this, "timerfd", sync_thr); From 98afd02be3a507ed09d77eb0cf9569480740edd8 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Mon, 25 Feb 2019 20:58:12 +0100 Subject: [PATCH 253/475] Cygwin: timerfd: rework implementation timerfd_tracker and timerfd_shared classes: - Just because handles are shared, we don't have to store them in shared memory. Move share handles into timerfd_tracker class. - Drop shared instance counter since it's not required anymore. timerfd_shared only stores the actual timer data. - Drop timerfd_shared::create, just set clock id. - Drop timerfd_shared::dtor, it's not required anymore. - Drop timerfd_tracker::close, just call dtor where required. - Rename timerfd_tracker::increment_instances to timerfd_tracker::dup. It's the only reason it exists... - timerfd_tracker::dtor now checks the non-shared pointers for NULL before attempting to close them. - timerfd_tracker::dtor handles decrementing the local instance count by itself. - Add a method timerfd_tracker::init_fixup_after_fork_exec to set non-shared pointers to NULL. Together with the dtor patches it fixes a problem with close_on_exec timerfd descriptors. - Fix a bug in handling the thread synchronization event. It's actually nice to create it before using it... - Drop using sec_none{_nih} in InitializeObjectAttributes. It's an unnecessary roundabout route just to get a NULL pointer. - Slightly rework timechange window handling. - Add more comments to explain what happens. fhandler_timerfd: - Drop cnew macro, it just hides what happens. - fhandler_timerfd::fixup_after_exec now calls timerfd_tracker::init_fixup_after_fork_exec first, so a subsequent call to timerfd_tracker::dtor only works on valid handles. - fhandler_timerfd::close directly calls timerfd_tracker::dtor now. - Drop dtor call in fhandler_timerfd destructor. Signed-off-by: Corinna Vinschen --- winsup/cygwin/fhandler.h | 2 +- winsup/cygwin/fhandler_timerfd.cc | 28 +-- winsup/cygwin/timerfd.cc | 296 +++++++++++++++--------------- winsup/cygwin/timerfd.h | 150 ++++++++------- 4 files changed, 226 insertions(+), 250 deletions(-) diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h index 079385db8..0da87e985 100644 --- a/winsup/cygwin/fhandler.h +++ b/winsup/cygwin/fhandler.h @@ -2682,7 +2682,7 @@ class fhandler_timerfd : public fhandler_base public: fhandler_timerfd (); fhandler_timerfd (void *) {} - ~fhandler_timerfd (); + ~fhandler_timerfd () {} fhandler_timerfd *is_timerfd () { return this; } diff --git a/winsup/cygwin/fhandler_timerfd.cc b/winsup/cygwin/fhandler_timerfd.cc index 2a0521708..e7e223296 100644 --- a/winsup/cygwin/fhandler_timerfd.cc +++ b/winsup/cygwin/fhandler_timerfd.cc @@ -30,21 +30,17 @@ fhandler_timerfd::get_proc_fd_name (char *buf) /* The timers connected to a descriptor are stored on the cygheap together with their fhandler. */ -#define cnew(name, ...) \ - ({ \ - void* ptr = (void*) ccalloc (HEAP_FHANDLER, 1, sizeof (name)); \ - ptr ? new (ptr) name (__VA_ARGS__) : NULL; \ - }) - int fhandler_timerfd::timerfd (clockid_t clock_id, int flags) { - timerfd_tracker *tfd = cnew (timerfd_tracker); + timerfd_tracker *tfd = (timerfd_tracker *) + ccalloc (HEAP_FHANDLER, 1, sizeof (timerfd_tracker)); if (!tfd) { set_errno (ENOMEM); return -1; } + new (tfd) timerfd_tracker (); int ret = tfd->create (clock_id); if (ret < 0) { @@ -178,7 +174,7 @@ fhandler_timerfd::dup (fhandler_base *child, int flags) __try { timerfd_tracker *tfd = (timerfd_tracker *) fhc->timerid; - tfd->increment_instances (); + tfd->dup (); ret = 0; } __except (EFAULT) {} @@ -234,8 +230,9 @@ fhandler_timerfd::fixup_after_exec () __try { timerfd_tracker *tfd = (timerfd_tracker *) timerid; + tfd->init_fixup_after_fork_exec (); if (close_on_exec ()) - tfd->decrement_instances (); + timerfd_tracker::dtor (tfd); else tfd->fixup_after_exec (); } @@ -243,17 +240,6 @@ fhandler_timerfd::fixup_after_exec () __endtry } -fhandler_timerfd::~fhandler_timerfd () -{ - __try - { - timerfd_tracker *tfd = (timerfd_tracker *) timerid; - timerfd_tracker::dtor (tfd); - } - __except (EFAULT) {} - __endtry -} - int fhandler_timerfd::close () { @@ -262,7 +248,7 @@ fhandler_timerfd::close () __try { timerfd_tracker *tfd = (timerfd_tracker *) timerid; - tfd->close (); + timerfd_tracker::dtor (tfd); ret = 0; } __except (EFAULT) {} diff --git a/winsup/cygwin/timerfd.cc b/winsup/cygwin/timerfd.cc index 2823560e6..418e71bf2 100644 --- a/winsup/cygwin/timerfd.cc +++ b/winsup/cygwin/timerfd.cc @@ -28,10 +28,9 @@ timerfd_tracker::create_timechange_window () WNDCLASSW wclass = { 0 }; WCHAR cname[NAME_MAX]; - __small_swprintf (cname, L"Cygwin.timerfd.%u", winpid); + __small_swprintf (cname, L"Cygwin.timerfd.%p", this); wclass.lpfnWndProc = DefWindowProcW; - wclass.hInstance = GetModuleHandle (NULL); - wclass.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1); + wclass.hInstance = user_data->hmodule; wclass.lpszClassName = cname; atom = RegisterClassW (&wclass); if (!atom) @@ -39,9 +38,9 @@ timerfd_tracker::create_timechange_window () else { window = CreateWindowExW (0, cname, cname, WS_POPUP, 0, 0, 0, 0, - NULL, NULL, NULL, NULL); + NULL, NULL, user_data->hmodule, NULL); if (!window) - debug_printf ("RegisterClass %E"); + debug_printf ("CreateWindowEx %E"); } } @@ -51,7 +50,7 @@ timerfd_tracker::delete_timechange_window () if (window) DestroyWindow (window); if (atom) - UnregisterClassW ((LPWSTR) (uintptr_t) atom, GetModuleHandle (NULL)); + UnregisterClassW ((LPWSTR) (uintptr_t) atom, user_data->hmodule); } void @@ -59,12 +58,13 @@ timerfd_tracker::handle_timechange_window () { MSG msg; - if (PeekMessageW(&msg, NULL, 0, 0, PM_REMOVE) && msg.message != WM_QUIT) + while (PeekMessageW (&msg, NULL, 0, 0, PM_REMOVE | PM_QS_POSTMESSAGE) + && msg.message != WM_QUIT) { - DispatchMessageW(&msg); + DispatchMessageW (&msg); if (msg.message == WM_TIMECHANGE && get_clockid () == CLOCK_REALTIME - && (flags () & TFD_CANCEL_FLAGS) == TFD_CANCEL_FLAGS + && (get_flags () & TFD_CANCEL_FLAGS) == TFD_CANCEL_FLAGS && enter_critical_section ()) { /* make sure to handle each WM_TIMECHANGE only once! */ @@ -84,7 +84,7 @@ DWORD timerfd_tracker::thread_func () { /* Outer loop: Is the timer armed? If not, wait for it. */ - HANDLE armed[2] = { tfd_shared->arm_evt (), + HANDLE armed[2] = { arm_evt (), cancel_evt }; create_timechange_window (); @@ -105,8 +105,8 @@ timerfd_tracker::thread_func () } /* Inner loop: Timer expired? If not, wait for it. */ - HANDLE expired[3] = { tfd_shared->timer (), - tfd_shared->disarm_evt (), + HANDLE expired[3] = { timer (), + disarm_evt (), cancel_evt }; while (1) @@ -133,7 +133,7 @@ timerfd_tracker::thread_func () /* Make sure we haven't been abandoned and/or disarmed in the meantime */ if (expiration_count () == -1LL - || IsEventSignalled (tfd_shared->disarm_evt ())) + || IsEventSignalled (disarm_evt ())) { leave_critical_section (); goto disarmed; @@ -176,8 +176,7 @@ timerfd_tracker::thread_func () || get_clockid () == CLOCK_BOOTTIME_ALARM); LARGE_INTEGER DueTime = { QuadPart: -get_interval () }; - NtSetTimer (tfd_shared->timer (), &DueTime, NULL, NULL, - Resume, 0, NULL); + NtSetTimer (timer (), &DueTime, NULL, NULL, Resume, 0, NULL); } } /* Arm the expiry object */ @@ -190,7 +189,8 @@ disarmed: canceled: delete_timechange_window (); - _my_tls._ctinfo->auto_release (); /* automatically return the cygthread to the cygthread pool */ + /* automatically return the cygthread to the cygthread pool */ + _my_tls._ctinfo->auto_release (); return 0; } @@ -202,21 +202,41 @@ timerfd_thread (VOID *arg) } int -timerfd_shared::create (clockid_t clock_id) +timerfd_tracker::create (clockid_t clock_id) { int ret; NTSTATUS status; OBJECT_ATTRIBUTES attr; - /* Create access mutex */ - InitializeObjectAttributes (&attr, NULL, OBJ_INHERIT, NULL, - sec_none.lpSecurityDescriptor); - status = NtCreateMutant (&_access_mtx, MUTEX_ALL_ACCESS, &attr, FALSE); + const ACCESS_MASK access = STANDARD_RIGHTS_REQUIRED + | SECTION_MAP_READ | SECTION_MAP_WRITE; + SIZE_T vsize = PAGE_SIZE; + LARGE_INTEGER sectionsize = { QuadPart: PAGE_SIZE }; + + /* Valid clock? */ + if (!get_clock (clock_id)) + { + ret = -EINVAL; + goto err; + } + + /* Create shared objects */ + InitializeObjectAttributes (&attr, NULL, OBJ_INHERIT, NULL, NULL); + /* Create shared section */ + status = NtCreateSection (&tfd_shared_hdl, access, &attr, §ionsize, + PAGE_READWRITE, SEC_COMMIT, NULL); if (!NT_SUCCESS (status)) { ret = -geterrno_from_nt_status (status); goto err; } + /* Create access mutex */ + status = NtCreateMutant (&_access_mtx, MUTEX_ALL_ACCESS, &attr, FALSE); + if (!NT_SUCCESS (status)) + { + ret = -geterrno_from_nt_status (status); + goto err_close_tfd_shared_hdl; + } /* Create "timer is armed" event, set to "Unsignaled" at creation time */ status = NtCreateEvent (&_arm_evt, EVENT_ALL_ACCESS, &attr, NotificationEvent, FALSE); @@ -249,10 +269,48 @@ timerfd_shared::create (clockid_t clock_id) ret = -geterrno_from_nt_status (status); goto err_close_timer; } - instance_count = 1; - _clockid = clock_id; + /* Create process-local cancel event for this processes timer thread + (has to be recreated after fork/exec)*/ + InitializeObjectAttributes (&attr, NULL, 0, NULL, NULL); + status = NtCreateEvent (&cancel_evt, EVENT_ALL_ACCESS, &attr, + NotificationEvent, FALSE); + if (!NT_SUCCESS (status)) + { + ret = -geterrno_from_nt_status (status); + goto err_close_expired_evt; + } + /* Create sync event for this processes timer thread */ + status = NtCreateEvent (&sync_thr, EVENT_ALL_ACCESS, &attr, + NotificationEvent, FALSE); + if (!NT_SUCCESS (status)) + { + ret = -geterrno_from_nt_status (status); + goto err_close_cancel_evt; + } + /* Create section mapping (has to be recreated after fork/exec) */ + tfd_shared = NULL; + status = NtMapViewOfSection (tfd_shared_hdl, NtCurrentProcess (), + (void **) &tfd_shared, 0, PAGE_SIZE, NULL, + &vsize, ViewShare, 0, PAGE_READWRITE); + if (!NT_SUCCESS (status)) + { + ret = -geterrno_from_nt_status (status); + goto err_close_sync_thr; + } + /* Initialize clock id */ + set_clockid (clock_id); + /* Set our winpid for fixup_after_fork_exec */ + winpid = GetCurrentProcessId (); + /* Start timerfd thread */ + new cygthread (timerfd_thread, this, "timerfd", sync_thr); return 0; +err_close_sync_thr: + NtClose (sync_thr); +err_close_cancel_evt: + NtClose (cancel_evt); +err_close_expired_evt: + NtClose (_expired_evt); err_close_timer: NtClose (_timer); err_close_disarm_evt: @@ -261,118 +319,43 @@ err_close_arm_evt: NtClose (_arm_evt); err_close_access_mtx: NtClose (_access_mtx); -err: - return ret; -} - -int -timerfd_tracker::create (clockid_t clock_id) -{ - int ret; - NTSTATUS status; - OBJECT_ATTRIBUTES attr; - - const ACCESS_MASK access = STANDARD_RIGHTS_REQUIRED - | SECTION_MAP_READ | SECTION_MAP_WRITE; - SIZE_T vsize = PAGE_SIZE; - LARGE_INTEGER sectionsize = { QuadPart: PAGE_SIZE }; - - /* Valid clock? */ - if (!get_clock (clock_id)) - { - ret = -EINVAL; - goto err; - } - /* Create shared section. */ - InitializeObjectAttributes (&attr, NULL, OBJ_INHERIT, NULL, - sec_none.lpSecurityDescriptor); - status = NtCreateSection (&tfd_shared_hdl, access, &attr, - §ionsize, PAGE_READWRITE, - SEC_COMMIT, NULL); - if (!NT_SUCCESS (status)) - { - ret = -geterrno_from_nt_status (status); - goto err; - } - /* Create section mapping (has to be repeated after fork/exec */ - status = NtMapViewOfSection (tfd_shared_hdl, NtCurrentProcess (), - (void **) &tfd_shared, 0, PAGE_SIZE, NULL, - &vsize, ViewShare, MEM_TOP_DOWN, PAGE_READWRITE); - if (!NT_SUCCESS (status)) - { - ret = -geterrno_from_nt_status (status); - goto err_close_tfd_shared_hdl; - } - /* Create cancel even for this processes timer thread */ - InitializeObjectAttributes (&attr, NULL, 0, NULL, - sec_none_nih.lpSecurityDescriptor); - status = NtCreateEvent (&cancel_evt, EVENT_ALL_ACCESS, &attr, - NotificationEvent, FALSE); - if (!NT_SUCCESS (status)) - { - ret = -geterrno_from_nt_status (status); - goto err_unmap_tfd_shared; - } - ret = tfd_shared->create (clock_id); - if (ret < 0) - goto err_close_cancel_evt; - winpid = GetCurrentProcessId (); - new cygthread (timerfd_thread, this, "timerfd", sync_thr); - return 0; - -err_close_cancel_evt: - NtClose (cancel_evt); -err_unmap_tfd_shared: - NtUnmapViewOfSection (NtCurrentProcess (), tfd_shared); err_close_tfd_shared_hdl: NtClose (tfd_shared_hdl); err: return ret; } -/* Return true if this was the last instance of a timerfd, session-wide, - false otherwise */ -bool -timerfd_shared::dtor () -{ - if (instance_count > 0) - { - return false; - } - disarm_timer (); - NtClose (_timer); - NtClose (_arm_evt); - NtClose (_disarm_evt); - NtClose (_expired_evt); - NtClose (_access_mtx); - return true; -} - -/* Return true if this was the last instance of a timerfd, session-wide, +/* Return true if this was the last instance of a timerfd, process-wide, false otherwise. Basically this is a destructor, but one which may notify the caller NOT to deleted the object. */ bool timerfd_tracker::dtor () { - if (enter_critical_section ()) + if (!enter_critical_section ()) + return false; + if (decrement_instances () > 0) { - if (local_instance_count > 0) - { - leave_critical_section (); - return false; - } - SetEvent (cancel_evt); - WaitForSingleObject (sync_thr, INFINITE); - if (tfd_shared->dtor ()) - { - NtUnmapViewOfSection (NtCurrentProcess (), tfd_shared); - NtClose (tfd_shared_hdl); - } - else - leave_critical_section (); + leave_critical_section (); + return false; } - NtClose (cancel_evt); - NtClose (sync_thr); + if (cancel_evt) + SetEvent (cancel_evt); + if (sync_thr) + { + WaitForSingleObject (sync_thr, INFINITE); + NtClose (sync_thr); + } + leave_critical_section (); + if (tfd_shared) + NtUnmapViewOfSection (NtCurrentProcess (), tfd_shared); + if (cancel_evt) + NtClose (cancel_evt); + NtClose (tfd_shared_hdl); + NtClose (_expired_evt); + NtClose (_timer); + NtClose (_disarm_evt); + NtClose (_arm_evt); + NtClose (_access_mtx); return true; } @@ -383,13 +366,6 @@ timerfd_tracker::dtor (timerfd_tracker *tfd) cfree (tfd); } -void -timerfd_tracker::close () -{ - InterlockedDecrement (&local_instance_count); - InterlockedDecrement (&tfd_shared->instance_count); -} - int timerfd_tracker::ioctl_set_ticks (uint64_t new_exp_cnt) { @@ -404,11 +380,22 @@ timerfd_tracker::ioctl_set_ticks (uint64_t new_exp_cnt) return 0; } +void +timerfd_tracker::init_fixup_after_fork_exec () +{ + /* Run this only if this is the first call, or all previous calls + came from close_on_exec descriptors */ + if (winpid == GetCurrentProcessId ()) + return; + tfd_shared = NULL; + cancel_evt = NULL; + sync_thr = NULL; +} + void timerfd_tracker::fixup_after_fork_exec (bool execing) { NTSTATUS status; - PVOID base_address = NULL; OBJECT_ATTRIBUTES attr; SIZE_T vsize = PAGE_SIZE; @@ -416,24 +403,27 @@ timerfd_tracker::fixup_after_fork_exec (bool execing) if (winpid == GetCurrentProcessId ()) return; /* Recreate shared section mapping */ + tfd_shared = NULL; status = NtMapViewOfSection (tfd_shared_hdl, NtCurrentProcess (), - &base_address, 0, PAGE_SIZE, NULL, + (PVOID *) &tfd_shared, 0, PAGE_SIZE, NULL, &vsize, ViewShare, 0, PAGE_READWRITE); if (!NT_SUCCESS (status)) api_fatal ("Can't recreate shared timerfd section during %s, status %y!", execing ? "execve" : "fork", status); - tfd_shared = (timerfd_shared *) base_address; - /* Increment global instance count by the number of instances in this - process */ - InterlockedAdd (&tfd_shared->instance_count, local_instance_count); - /* Create cancel even for this processes timer thread */ - InitializeObjectAttributes (&attr, NULL, 0, NULL, - sec_none_nih.lpSecurityDescriptor); + /* Create cancel event for this processes timer thread */ + InitializeObjectAttributes (&attr, NULL, 0, NULL, NULL); status = NtCreateEvent (&cancel_evt, EVENT_ALL_ACCESS, &attr, NotificationEvent, FALSE); if (!NT_SUCCESS (status)) api_fatal ("Can't recreate timerfd cancel event during %s, status %y!", execing ? "execve" : "fork", status); + /* Create sync event for this processes timer thread */ + InitializeObjectAttributes (&attr, NULL, 0, NULL, NULL); + status = NtCreateEvent (&sync_thr, EVENT_ALL_ACCESS, &attr, + NotificationEvent, FALSE); + if (!NT_SUCCESS (status)) + api_fatal ("Can't recreate timerfd sync event during %s, status %y!", + execing ? "execve" : "fork", status); /* Set winpid so we don't run this twice */ winpid = GetCurrentProcessId (); new cygthread (timerfd_thread, this, "timerfd", sync_thr); @@ -509,7 +499,7 @@ timerfd_tracker::gettime (struct itimerspec *curr_value) __try { - if (IsEventSignalled (tfd_shared->disarm_evt ())) + if (IsEventSignalled (disarm_evt ())) *curr_value = time_spec (); else { @@ -532,27 +522,28 @@ timerfd_tracker::gettime (struct itimerspec *curr_value) } int -timerfd_shared::arm_timer (int flags, const struct itimerspec *new_value) +timerfd_tracker::arm_timer (int flags, const struct itimerspec *new_value) { + LONG64 interval; LONG64 ts; NTSTATUS status; LARGE_INTEGER DueTime; BOOLEAN Resume; LONG Period; - ResetEvent (_disarm_evt); + ResetEvent (disarm_evt ()); /* Convert incoming itimerspec into 100ns interval and timestamp */ - _interval = new_value->it_interval.tv_sec * NS100PERSEC - + (new_value->it_interval.tv_nsec + (NSPERSEC / NS100PERSEC) - 1) - / (NSPERSEC / NS100PERSEC); + interval = new_value->it_interval.tv_sec * NS100PERSEC + + (new_value->it_interval.tv_nsec + (NSPERSEC / NS100PERSEC) - 1) + / (NSPERSEC / NS100PERSEC); ts = new_value->it_value.tv_sec * NS100PERSEC + (new_value->it_value.tv_nsec + (NSPERSEC / NS100PERSEC) - 1) / (NSPERSEC / NS100PERSEC); - _flags = flags; + set_flags (flags); if (flags & TFD_TIMER_ABSTIME) { - if (_clockid == CLOCK_REALTIME) + if (get_clockid () == CLOCK_REALTIME) DueTime.QuadPart = ts + FACTOR; else /* non-REALTIME clocks require relative DueTime. */ { @@ -570,17 +561,18 @@ timerfd_shared::arm_timer (int flags, const struct itimerspec *new_value) DueTime.QuadPart = -ts; ts += get_clock_now (); } - set_exp_ts (ts); time_spec () = *new_value; + set_exp_ts (ts); + set_interval (interval); read_and_reset_expiration_count (); /* Note: Advanced Power Settings -> Sleep -> Allow Wake Timers since W10 1709 */ - Resume = (_clockid == CLOCK_REALTIME_ALARM - || _clockid == CLOCK_BOOTTIME_ALARM); - if (_interval > INT_MAX * (NS100PERSEC / MSPERSEC)) + Resume = (get_clockid () == CLOCK_REALTIME_ALARM + || get_clockid () == CLOCK_BOOTTIME_ALARM); + if (interval > INT_MAX * (NS100PERSEC / MSPERSEC)) Period = 0; else - Period = (_interval + (NS100PERSEC / MSPERSEC) - 1) + Period = (interval + (NS100PERSEC / MSPERSEC) - 1) / (NS100PERSEC / MSPERSEC); status = NtSetTimer (timer (), &DueTime, NULL, NULL, Resume, Period, NULL); if (!NT_SUCCESS (status)) @@ -589,7 +581,7 @@ timerfd_shared::arm_timer (int flags, const struct itimerspec *new_value) return -geterrno_from_nt_status (status); } - SetEvent (_arm_evt); + SetEvent (arm_evt ()); return 0; } diff --git a/winsup/cygwin/timerfd.h b/winsup/cygwin/timerfd.h index 66bf78424..154be0847 100644 --- a/winsup/cygwin/timerfd.h +++ b/winsup/cygwin/timerfd.h @@ -14,16 +14,6 @@ details. */ class timerfd_shared { - HANDLE _access_mtx; /* controls access to shared data */ - HANDLE _arm_evt; /* settimer sets event when timer is armed, - unsets event when timer gets disarmed. */ - HANDLE _disarm_evt; /* settimer sets event when timer is armed, - unsets event when timer gets disarmed. */ - HANDLE _timer; /* SynchronizationTimer */ - HANDLE _expired_evt; /* Signal if timer expired, Unsignal on read. */ - LONG instance_count; /* each open fd increments this. - If 0 -> delete timerfd_shared */ - clockid_t _clockid; /* clockid */ struct itimerspec _time_spec; /* original incoming itimerspec */ LONG64 _exp_ts; /* start timestamp or next expire timestamp @@ -33,52 +23,29 @@ class timerfd_shared int _flags; /* settime flags */ DWORD _tc_time; /* timestamp of the last WM_TIMECHANGE msg */ - int create (clockid_t); - bool dtor (); - /* read access methods */ - HANDLE arm_evt () const { return _arm_evt; } - HANDLE disarm_evt () const { return _disarm_evt; } - HANDLE timer () const { return _timer; } - HANDLE expired_evt () const { return _expired_evt; } LONG64 get_clock_now () const { return get_clock (_clockid)->n100secs (); } struct itimerspec &time_spec () { return _time_spec; } - int flags () const { return _flags; } + int get_flags () const { return _flags; } + void set_flags (int nflags) { _flags = nflags; } /* write access methods */ + void set_clockid (clockid_t clock_id) { _clockid = clock_id; } void increment_expiration_count (LONG64 add) { InterlockedAdd64 (&_expiration_count, add); } void set_expiration_count (LONG64 newval) { InterlockedExchange64 (&_expiration_count, newval); } - LONG64 read_and_reset_expiration_count () - { - LONG64 ret = InterlockedExchange64 (&_expiration_count, 0); - if (ret) - ResetEvent (_expired_evt); - return ret; - } - bool enter_cs () - { - return (WaitForSingleObject (_access_mtx, INFINITE) & ~WAIT_ABANDONED_0) - == WAIT_OBJECT_0; - } - void leave_cs () - { - ReleaseMutex (_access_mtx); - } + LONG64 reset_expiration_count () + { return InterlockedExchange64 (&_expiration_count, 0); } int arm_timer (int, const struct itimerspec *); int disarm_timer () { - ResetEvent (_arm_evt); memset (&_time_spec, 0, sizeof _time_spec); _exp_ts = 0; _interval = 0; /* _flags = 0; DON'T DO THAT. Required for TFD_TIMER_CANCEL_ON_SET */ - NtCancelTimer (timer (), NULL); - SetEvent (_disarm_evt); return 0; } - void timer_expired () { SetEvent (_expired_evt); } void set_exp_ts (LONG64 ts) { _exp_ts = ts; } friend class timerfd_tracker; @@ -86,13 +53,22 @@ class timerfd_shared class timerfd_tracker /* cygheap! */ { - HANDLE tfd_shared_hdl; /* handle auf shared mem */ - timerfd_shared *tfd_shared; /* pointer auf shared mem, needs - NtMapViewOfSection in each new process. */ - + /* Shared handles */ + HANDLE tfd_shared_hdl; /* handle to shared mem */ + HANDLE _access_mtx; /* controls access to shared data */ + HANDLE _arm_evt; /* settimer sets event when timer is armed, + unsets event when timer gets disarmed. */ + HANDLE _disarm_evt; /* settimer sets event when timer is armed, + unsets event when timer gets disarmed. */ + HANDLE _timer; /* SynchronizationTimer */ + HANDLE _expired_evt; /* Signal if timer expired, Unsignal on read. */ + /* Process-local handles */ HANDLE cancel_evt; /* Signal thread to exit. */ HANDLE sync_thr; /* cygthread sync object. */ - LONG local_instance_count; /* each open fd increments this. + /* pointer to shared timerfd, misc */ + timerfd_shared *tfd_shared; /* pointer to shared mem, needs + NtMapViewOfSection in each new process. */ + LONG instance_count; /* each open fd increments this. If 0 -> cancel thread. */ DWORD winpid; /* This is used @ fork/exec time to know if this tracker already has been fixed up. */ @@ -105,69 +81,91 @@ class timerfd_tracker /* cygheap! */ bool dtor (); - bool enter_critical_section () const { return tfd_shared->enter_cs (); } - void leave_critical_section () const { tfd_shared->leave_cs (); } + bool enter_critical_section () + { + return (WaitForSingleObject (_access_mtx, INFINITE) & ~WAIT_ABANDONED_0) + == WAIT_OBJECT_0; + } + void leave_critical_section () + { + ReleaseMutex (_access_mtx); + } - int arm_timer (int flags, const struct itimerspec *new_value) const - { return tfd_shared->arm_timer (flags, new_value); } - int disarm_timer () const { return tfd_shared->disarm_timer (); } - void timer_expired () const { tfd_shared->timer_expired (); } + HANDLE arm_evt () const { return _arm_evt; } + HANDLE disarm_evt () const { return _disarm_evt; } + HANDLE timer () const { return _timer; } + HANDLE expired_evt () const { return _expired_evt; } + void timer_expired () { SetEvent (_expired_evt); } + int arm_timer (int flags, const struct itimerspec *new_value); + int disarm_timer () + { + ResetEvent (_arm_evt); + tfd_shared->disarm_timer (); + NtCancelTimer (timer (), NULL); + SetEvent (_disarm_evt); + return 0; + } + void timer_expired () const { timer_expired (); } LONG64 expiration_count () const { return tfd_shared->_expiration_count; } void increment_expiration_count (LONG64 add) const { tfd_shared->increment_expiration_count (add); } void set_expiration_count (LONG64 exp_cnt) const { tfd_shared->set_expiration_count ((LONG64) exp_cnt); } - LONG64 read_and_reset_expiration_count () const - { return tfd_shared->read_and_reset_expiration_count (); } + LONG64 read_and_reset_expiration_count () + { + LONG64 ret = tfd_shared->reset_expiration_count (); + if (ret) + ResetEvent (_expired_evt); + return ret; + } struct timespec it_value () const { return tfd_shared->time_spec ().it_value; } struct timespec it_interval () const { return tfd_shared->time_spec ().it_interval; } + void set_clockid (clockid_t clock_id) { tfd_shared->set_clockid (clock_id); } clock_t get_clockid () const { return tfd_shared->_clockid; } LONG64 get_clock_now () const { return tfd_shared->get_clock_now (); } struct itimerspec &time_spec () { return tfd_shared->time_spec (); } LONG64 get_exp_ts () const { return tfd_shared->_exp_ts; } LONG64 get_interval () const { return tfd_shared->_interval; } - int flags () const { return tfd_shared->flags (); } + void set_interval (LONG64 intv) { tfd_shared->_interval = intv; } + int get_flags () const { return tfd_shared->get_flags (); } + void set_flags (int nflags) { tfd_shared->set_flags (nflags); } DWORD tc_time () const { return tfd_shared->_tc_time; } void set_tc_time (DWORD new_time) { tfd_shared->_tc_time = new_time; } void set_exp_ts (LONG64 ts) const { tfd_shared->set_exp_ts (ts); } + LONG decrement_instances () { return InterlockedDecrement (&instance_count); } public: void *operator new (size_t, void *p) __attribute__ ((nothrow)) {return p;} timerfd_tracker () - : tfd_shared_hdl (NULL), tfd_shared (NULL), cancel_evt (NULL), - sync_thr (NULL), local_instance_count (1), winpid (0), window (NULL), - atom (0) {} + : tfd_shared_hdl (NULL), _access_mtx (NULL), _arm_evt (NULL), + _disarm_evt (NULL), cancel_evt (NULL), sync_thr (NULL), tfd_shared (NULL), + instance_count (1), winpid (0), window (NULL), atom (0) {} + + void init_fixup_after_fork_exec (); + void fixup_after_fork_exec (bool); + void fixup_after_fork () + { + init_fixup_after_fork_exec (); + fixup_after_fork_exec (false); + } + void fixup_after_exec () { fixup_after_fork_exec (true); } + + void dup () { InterlockedIncrement (&instance_count); } + HANDLE get_timerfd_handle () const { return expired_evt (); } + LONG64 wait (bool); + int ioctl_set_ticks (uint64_t); + int create (clockid_t); int gettime (struct itimerspec *); int settime (int, const struct itimerspec *, struct itimerspec *); - static void dtor (timerfd_tracker *); - void close (); - int ioctl_set_ticks (uint64_t); - void fixup_after_fork_exec (bool); - void fixup_after_fork () { fixup_after_fork_exec (false); } - void fixup_after_exec () { fixup_after_fork_exec (true); } - HANDLE get_timerfd_handle () const { return tfd_shared->expired_evt (); } - HANDLE get_disarm_evt () const { return tfd_shared->disarm_evt (); } - LONG64 wait (bool); - void increment_global_instances () - { InterlockedIncrement (&tfd_shared->instance_count); } - void increment_instances () - { - InterlockedIncrement (&tfd_shared->instance_count); - InterlockedIncrement (&local_instance_count); - } - void decrement_instances () - { - InterlockedDecrement (&tfd_shared->instance_count); - InterlockedDecrement (&local_instance_count); - } + static void dtor (timerfd_tracker *); DWORD thread_func (); }; From 3b3ba558e90e7ce07eb0b9a5939453d4b90bd5e5 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Mon, 25 Feb 2019 21:06:15 +0100 Subject: [PATCH 254/475] Cygwin: use NULL security descriptor in InitializeObjectAttributes Using sec_none{_nih} is just a roundabout way to specify a NULL SD. Signed-off-by: Corinna Vinschen --- winsup/cygwin/forkable.cc | 6 ++---- winsup/cygwin/mmap.cc | 3 +-- winsup/cygwin/posix_timer.cc | 3 +-- 3 files changed, 4 insertions(+), 8 deletions(-) diff --git a/winsup/cygwin/forkable.cc b/winsup/cygwin/forkable.cc index 1067eac85..d1b0f5723 100644 --- a/winsup/cygwin/forkable.cc +++ b/winsup/cygwin/forkable.cc @@ -58,8 +58,7 @@ mkdirs (PWCHAR ntdirname, int lastsepcount) UNICODE_STRING dn; RtlInitUnicodeString (&dn, ntdirname); OBJECT_ATTRIBUTES oa; - InitializeObjectAttributes (&oa, &dn, 0, NULL, - sec_none_nih.lpSecurityDescriptor); + InitializeObjectAttributes (&oa, &dn, 0, NULL, NULL); HANDLE dh = NULL; NTSTATUS status; IO_STATUS_BLOCK iosb; @@ -765,8 +764,7 @@ dll_list::create_forkables () RtlInitUnicodeString (&fn, ntname); OBJECT_ATTRIBUTES oa; - InitializeObjectAttributes (&oa, &fn, 0, NULL, - sec_none_nih.lpSecurityDescriptor); + InitializeObjectAttributes (&oa, &fn, 0, NULL, NULL); HANDLE hlocal = NULL; NTSTATUS status; IO_STATUS_BLOCK iosb; diff --git a/winsup/cygwin/mmap.cc b/winsup/cygwin/mmap.cc index f48790a8a..1d81d534f 100644 --- a/winsup/cygwin/mmap.cc +++ b/winsup/cygwin/mmap.cc @@ -145,8 +145,7 @@ CreateMapping (HANDLE fhdl, size_t len, off_t off, DWORD openflags, ULONG attributes = attached (prot) ? SEC_RESERVE : SEC_COMMIT; OBJECT_ATTRIBUTES oa; - InitializeObjectAttributes (&oa, NULL, OBJ_INHERIT, NULL, - sec_none.lpSecurityDescriptor); + InitializeObjectAttributes (&oa, NULL, OBJ_INHERIT, NULL, NULL); if (fhdl == INVALID_HANDLE_VALUE) { diff --git a/winsup/cygwin/posix_timer.cc b/winsup/cygwin/posix_timer.cc index 0332cab92..d9d4a9a18 100644 --- a/winsup/cygwin/posix_timer.cc +++ b/winsup/cygwin/posix_timer.cc @@ -306,8 +306,7 @@ timer_tracker::settime (int flags, const itimerspec *new_value, { OBJECT_ATTRIBUTES attr; - InitializeObjectAttributes (&attr, NULL, 0, NULL, - sec_none_nih.lpSecurityDescriptor); + InitializeObjectAttributes (&attr, NULL, 0, NULL, NULL); status = NtCreateEvent (&cancel_evt, EVENT_ALL_ACCESS, &attr, NotificationEvent, FALSE); if (!NT_SUCCESS (status)) From 5a483b6bcac263102df890c3172ecddf23fc9f53 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Tue, 26 Feb 2019 10:19:08 +0100 Subject: [PATCH 255/475] Cygwin: timerfd: reduce size of shared mem region to a single page The share section was created using the PAGE_SIZE constant, but PAGE_SIZE is 64K. Fix that by using wincap.page_size() instead, which returns the desired actual page size of 4K. Signed-off-by: Corinna Vinschen --- winsup/cygwin/timerfd.cc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/winsup/cygwin/timerfd.cc b/winsup/cygwin/timerfd.cc index 418e71bf2..b0d4db9de 100644 --- a/winsup/cygwin/timerfd.cc +++ b/winsup/cygwin/timerfd.cc @@ -210,8 +210,8 @@ timerfd_tracker::create (clockid_t clock_id) const ACCESS_MASK access = STANDARD_RIGHTS_REQUIRED | SECTION_MAP_READ | SECTION_MAP_WRITE; - SIZE_T vsize = PAGE_SIZE; - LARGE_INTEGER sectionsize = { QuadPart: PAGE_SIZE }; + SIZE_T vsize = wincap.page_size (); + LARGE_INTEGER sectionsize = { QuadPart: (LONGLONG) wincap.page_size () }; /* Valid clock? */ if (!get_clock (clock_id)) @@ -290,7 +290,7 @@ timerfd_tracker::create (clockid_t clock_id) /* Create section mapping (has to be recreated after fork/exec) */ tfd_shared = NULL; status = NtMapViewOfSection (tfd_shared_hdl, NtCurrentProcess (), - (void **) &tfd_shared, 0, PAGE_SIZE, NULL, + (void **) &tfd_shared, 0, vsize, NULL, &vsize, ViewShare, 0, PAGE_READWRITE); if (!NT_SUCCESS (status)) { @@ -397,7 +397,7 @@ timerfd_tracker::fixup_after_fork_exec (bool execing) { NTSTATUS status; OBJECT_ATTRIBUTES attr; - SIZE_T vsize = PAGE_SIZE; + SIZE_T vsize = wincap.page_size (); /* Run this only once per process */ if (winpid == GetCurrentProcessId ()) @@ -405,7 +405,7 @@ timerfd_tracker::fixup_after_fork_exec (bool execing) /* Recreate shared section mapping */ tfd_shared = NULL; status = NtMapViewOfSection (tfd_shared_hdl, NtCurrentProcess (), - (PVOID *) &tfd_shared, 0, PAGE_SIZE, NULL, + (PVOID *) &tfd_shared, 0, vsize, NULL, &vsize, ViewShare, 0, PAGE_READWRITE); if (!NT_SUCCESS (status)) api_fatal ("Can't recreate shared timerfd section during %s, status %y!", From 639645a2fd753f29ed9693b7c34f015c01de1741 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Tue, 26 Feb 2019 10:46:05 +0100 Subject: [PATCH 256/475] Cygwin: timerfd: add a sleep when being debugged A sleep is required on Windows 10 64 bit only before calling RegisterClassW in the timerfd thread, and only when running under strace. One of the child processes inheriting the timerfd descriptor will get a STATUS_FLOAT_INEXACT_RESULT exception inside of msvcrt.dll. It's apparently some timing problem. It occurs in 4 out of 5 runs under strace only. WOW64 and Windows 7 64 bit don't have this problem. Signed-off-by: Corinna Vinschen --- winsup/cygwin/timerfd.cc | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/winsup/cygwin/timerfd.cc b/winsup/cygwin/timerfd.cc index b0d4db9de..8e4c94e66 100644 --- a/winsup/cygwin/timerfd.cc +++ b/winsup/cygwin/timerfd.cc @@ -32,6 +32,15 @@ timerfd_tracker::create_timechange_window () wclass.lpfnWndProc = DefWindowProcW; wclass.hInstance = user_data->hmodule; wclass.lpszClassName = cname; + /* This sleep is required on Windows 10 64 bit only, and only when running + under strace. One of the child processes inheriting the timerfd + descriptor will get a STATUS_FLOAT_INEXACT_RESULT exception inside of + msvcrt.dll. While this is completely crazy in itself, it's apparently + some timing problem. It occurs in 4 out of 5 runs under strace only. + The sleep is required before calling RegisterClassW. Moving it before + CreateWindowExW does not work. What the heck? */ + if (being_debugged ()) + Sleep (1L); atom = RegisterClassW (&wclass); if (!atom) debug_printf ("RegisterClass %E"); From 495ae418919af8b4295e519ef18a002a68c04d8e Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Thu, 28 Feb 2019 16:55:39 +0100 Subject: [PATCH 257/475] Cygwin: wincap: fix copy/paste bug Signed-off-by: Corinna Vinschen --- winsup/cygwin/wincap.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/winsup/cygwin/wincap.cc b/winsup/cygwin/wincap.cc index 7e381f420..78cc41133 100644 --- a/winsup/cygwin/wincap.cc +++ b/winsup/cygwin/wincap.cc @@ -239,7 +239,7 @@ wincaps wincap_10_1809 __attribute__((section (".cygwin_dll_common"), shared)) = has_posix_unlink_semantics:true, has_case_sensitive_dirs:true, has_posix_rename_semantics:true, - no_msv1_0_s4u_logon_in_wow64:true, + no_msv1_0_s4u_logon_in_wow64:false, }, }; From 5d9ac1291d84d6a6f15efe082d91ae1bf5947ab1 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Thu, 28 Feb 2019 23:17:55 +0100 Subject: [PATCH 258/475] Cygwin: load_user_profile: chack if we got a valid, known domainname ...otherwise we may suffer a SEGV because dnsdomain is NULL. Signed-off-by: Corinna Vinschen --- winsup/cygwin/sec_auth.cc | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/winsup/cygwin/sec_auth.cc b/winsup/cygwin/sec_auth.cc index a4e7458b3..c1667f57c 100644 --- a/winsup/cygwin/sec_auth.cc +++ b/winsup/cygwin/sec_auth.cc @@ -288,17 +288,22 @@ load_user_profile (HANDLE token, struct passwd *pw, cygpsid &usersid) break; } } - if (cldap.fetch_ad_account (usersid, false, dnsdomain)) + if (dnsdomain) { - PWCHAR val = cldap.get_profile_path (); - if (val && *val) + if (cldap.fetch_ad_account (usersid, false, dnsdomain)) { - wcsncpy (userpath, val, MAX_PATH - 1); - userpath[MAX_PATH - 1] = L'\0'; - pi.lpProfilePath = userpath; + PWCHAR val = cldap.get_profile_path (); + if (val && *val) + { + wcsncpy (userpath, val, MAX_PATH - 1); + userpath[MAX_PATH - 1] = L'\0'; + pi.lpProfilePath = userpath; + } } + free (dnsdomain); } - free (dnsdomain); + else + debug_printf ("Unknown domain <%W>?", domain); } if (!LoadUserProfileW (token, &pi)) From 379598dd672d60b9f89d0b10d33b2f1859e7a024 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Fri, 1 Mar 2019 14:32:08 +0100 Subject: [PATCH 259/475] Cygwin: Disable creating case-sensitive folders by default Inspecting the content of case-sensitive directories on remote machines results in lots of errors like disappearing diretories and files, file not found, etc. This is not feasible as default behaviour Signed-off-by: Corinna Vinschen --- winsup/cygwin/fhandler_disk_file.cc | 7 +++++++ winsup/cygwin/release/3.0.2 | 8 ++++++++ winsup/doc/new-features.xml | 7 ++----- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/winsup/cygwin/fhandler_disk_file.cc b/winsup/cygwin/fhandler_disk_file.cc index 5a8463eff..193192762 100644 --- a/winsup/cygwin/fhandler_disk_file.cc +++ b/winsup/cygwin/fhandler_disk_file.cc @@ -1778,6 +1778,12 @@ fhandler_disk_file::mkdir (mode_t mode) pc.file_attributes (FILE_ATTRIBUTE_DIRECTORY); if (has_acls ()) set_created_file_access (dir, pc, mode & 07777); +#if 0 + /* FIXME: This default behaviour badly breaks interoperability. + Inspecting the content of case-sensitive directories + on remote machines results in lots of errors like + disappearing diretories and files, file not found, etc. */ + /* Starting with Windows 10 1803, try to create all dirs below the installation root as case-sensitive. If STATUS_NOT_SUPPORTED is returned, WSL isn't installed (unfortunately a requirement @@ -1808,6 +1814,7 @@ fhandler_disk_file::mkdir (mode_t mode) } } } +#endif NtClose (dir); res = 0; } diff --git a/winsup/cygwin/release/3.0.2 b/winsup/cygwin/release/3.0.2 index e24fe4e7c..d0a592b7c 100644 --- a/winsup/cygwin/release/3.0.2 +++ b/winsup/cygwin/release/3.0.2 @@ -5,6 +5,14 @@ What's new: What changed: ------------- +- Windows 10 1803 or later and WSL installed: + + Starting with 3.0.0, mkdir(2) automatically created directories within + the Cygwin installation dir as case sensitive. This badly breaks + interoperability with remote machines trying to access these dirs. + Therefore, disable this as default. You can still create case-sensitive + dirs via `chattr +C ...' + Bug Fixes --------- diff --git a/winsup/doc/new-features.xml b/winsup/doc/new-features.xml index ab369abb6..5bb410955 100644 --- a/winsup/doc/new-features.xml +++ b/winsup/doc/new-features.xml @@ -15,11 +15,8 @@ CLOCK_BOOTTIME_ALARM clocks. -Support for case sensitive directories. mkdir(2) automatically creates -directories within the Cygwin installation dir as case sensitive -now. - -This feature requires Windows 10 1803 or later and WSL installed! +Support for case sensitive directories via chattr(1). This feature requires +Windows 10 1803 or later and WSL installed. From f18a161cfff9ad32ca386b5bbb3d72c1047ff6b9 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Fri, 1 Mar 2019 16:04:51 +0100 Subject: [PATCH 260/475] Cygwin: s4uauth: drop fallback to MsV1_0 if Kerberos fails This never really worked. While at it, restructure code to do common stuff only in one spot. Improve debug output. Signed-off-by: Corinna Vinschen --- winsup/cygwin/sec_auth.cc | 168 +++++++++++++++++--------------------- 1 file changed, 77 insertions(+), 91 deletions(-) diff --git a/winsup/cygwin/sec_auth.cc b/winsup/cygwin/sec_auth.cc index c1667f57c..cb216a762 100644 --- a/winsup/cygwin/sec_auth.cc +++ b/winsup/cygwin/sec_auth.cc @@ -1509,7 +1509,7 @@ s4uauth (bool logon, PCWSTR domain, PCWSTR user, NTSTATUS &ret_status) HANDLE lsa_hdl = NULL; LSA_OPERATIONAL_MODE sec_mode; NTSTATUS status, sub_status; - bool try_kerb_auth; + bool kerberos_auth; ULONG package_id, size; struct { LSA_STRING str; @@ -1530,11 +1530,16 @@ s4uauth (bool logon, PCWSTR domain, PCWSTR user, NTSTATUS &ret_status) if (logon) { /* Register as logon process. */ + debug_printf ("Impersonation requested"); RtlInitAnsiString (&name, "Cygwin"); status = LsaRegisterLogonProcess (&name, &lsa_hdl, &sec_mode); } else - status = LsaConnectUntrusted (&lsa_hdl); + { + /* Connect untrusted to just create a identification token */ + debug_printf ("Identification requested"); + status = LsaConnectUntrusted (&lsa_hdl); + } if (status != STATUS_SUCCESS) { debug_printf ("%s: %y", logon ? "LsaRegisterLogonProcess" @@ -1543,14 +1548,34 @@ s4uauth (bool logon, PCWSTR domain, PCWSTR user, NTSTATUS &ret_status) goto out; } - /* Check if this is a domain user. If so, try Kerberos first. */ - try_kerb_auth = cygheap->dom.member_machine () - && wcscasecmp (domain, cygheap->dom.account_flat_name ()); + /* Check if this is a domain user. If so, use Kerberos. */ + kerberos_auth = cygheap->dom.member_machine () + && wcscasecmp (domain, cygheap->dom.account_flat_name ()); + debug_printf ("kerb %d, domain member %d, user domain <%W>, machine <%W>", + kerberos_auth, cygheap->dom.member_machine (), domain, + cygheap->dom.account_flat_name ()); + + /* Connect to authentication package. */ + RtlInitAnsiString (&name, kerberos_auth ? MICROSOFT_KERBEROS_NAME_A + : MSV1_0_PACKAGE_NAME); + status = LsaLookupAuthenticationPackage (lsa_hdl, &name, &package_id); + if (status != STATUS_SUCCESS) + { + debug_printf ("LsaLookupAuthenticationPackage: %y", status); + __seterrno_from_nt_status (status); + goto out; + } + /* Create origin. */ stpcpy (origin.buf, "Cygwin"); RtlInitAnsiString (&origin.str, origin.buf); - if (try_kerb_auth) + /* Create token source. */ + memcpy (ts.SourceName, "Cygwin.1", 8); + ts.SourceIdentifier.HighPart = 0; + ts.SourceIdentifier.LowPart = kerberos_auth ? 0x0105 : 0x0106; + + if (kerberos_auth) { PWCHAR sam_name = tp.w_get (); PWCHAR upn_name = tp.w_get (); @@ -1558,14 +1583,6 @@ s4uauth (bool logon, PCWSTR domain, PCWSTR user, NTSTATUS &ret_status) KERB_S4U_LOGON *s4u_logon; USHORT name_len; - RtlInitAnsiString (&name, MICROSOFT_KERBEROS_NAME_A); - status = LsaLookupAuthenticationPackage (lsa_hdl, &name, &package_id); - if (status != STATUS_SUCCESS) - { - debug_printf ("LsaLookupAuthenticationPackage: %y", status); - __seterrno_from_nt_status (status); - goto out; - } wcpcpy (wcpcpy (wcpcpy (sam_name, domain), L"\\"), user); if (TranslateNameW (sam_name, NameSamCompatible, NameUserPrincipal, upn_name, &size) == 0) @@ -1579,8 +1596,7 @@ s4uauth (bool logon, PCWSTR domain, PCWSTR user, NTSTATUS &ret_status) translated_name, &size) == 0) { debug_printf ("TranslateNameW(%W, NameCanonical) %E", sam_name); - debug_printf ("Fallback to MsV1_0 auth"); - goto msv1_0_auth; /* Fall through to MSV1_0 authentication */ + goto out; } p = wcschr (translated_name, L'/'); if (p) @@ -1600,84 +1616,54 @@ s4uauth (bool logon, PCWSTR domain, PCWSTR user, NTSTATUS &ret_status) (PWCHAR) (s4u_logon + 1), name_len); RtlAppendUnicodeToString (&s4u_logon->ClientUpn, upn_name); - debug_printf ("ClientUpn: <%S>", &s4u_logon->ClientUpn); - /* Create token source. */ - memcpy (ts.SourceName, "Cygwin.1", 8); - ts.SourceIdentifier.HighPart = 0; - ts.SourceIdentifier.LowPart = 0x0105; - status = LsaLogonUser (lsa_hdl, (PLSA_STRING) &origin, Network, - package_id, authinf, authinf_size, NULL, - &ts, (PVOID *) &profile, &size, - &luid, &token, "a, &sub_status); - switch (status) - { - case STATUS_SUCCESS: - goto out; - /* These failures are fatal */ - case STATUS_QUOTA_EXCEEDED: - case STATUS_LOGON_FAILURE: - debug_printf ("Kerberos S4U LsaLogonUser failed: %y", status); - goto out; - case STATUS_ACCOUNT_RESTRICTION: - debug_printf ("Kerberos S4U LsaLogonUser failed: %y (%s)", - status, account_restriction (sub_status)); - goto out; - default: - break; - } - debug_printf ("Kerberos S4U LsaLogonUser failed: %y, try MsV1_0", status); - /* Fall through to MSV1_0 authentication */ + debug_printf ("KerbS4ULogon: ClientUpn: <%S>", &s4u_logon->ClientUpn); + } + else + { + /* Per MSDN MsV1_0S4ULogon is not implemented on Vista, but surprisingly + it works. */ + MSV1_0_S4U_LOGON *s4u_logon; + USHORT user_len, domain_len; + + user_len = wcslen (user) * sizeof (WCHAR); + domain_len = wcslen (domain) * sizeof (WCHAR); /* Local machine */ + authinf_size = sizeof (MSV1_0_S4U_LOGON) + user_len + domain_len; + if (!authinf) + authinf = tp.c_get (); + RtlSecureZeroMemory (authinf, authinf_size); + s4u_logon = (MSV1_0_S4U_LOGON *) authinf; + s4u_logon->MessageType = MsV1_0S4ULogon; + s4u_logon->Flags = 0; + /* Append user and domain to login info */ + RtlInitEmptyUnicodeString (&s4u_logon->UserPrincipalName, + (PWCHAR) (s4u_logon + 1), + user_len); + RtlInitEmptyUnicodeString (&s4u_logon->DomainName, + (PWCHAR) ((PBYTE) (s4u_logon + 1) + user_len), + domain_len); + RtlAppendUnicodeToString (&s4u_logon->UserPrincipalName, user); + RtlAppendUnicodeToString (&s4u_logon->DomainName, domain); + debug_printf ("MsV1_0S4ULogon: DomainName: <%S> UserPrincipalName: <%S>", + &s4u_logon->DomainName, &s4u_logon->UserPrincipalName); } -msv1_0_auth: - MSV1_0_S4U_LOGON *s4u_logon; - USHORT user_len, domain_len; - - /* Per MSDN MsV1_0S4ULogon is not implemented on Vista, but surprisingly - it works. */ - RtlInitAnsiString (&name, MSV1_0_PACKAGE_NAME); - status = LsaLookupAuthenticationPackage (lsa_hdl, &name, &package_id); - if (status != STATUS_SUCCESS) + /* Try to logon. */ + status = LsaLogonUser (lsa_hdl, (PLSA_STRING) &origin, Network, package_id, + authinf, authinf_size, NULL, &ts, (PVOID *) &profile, + &size, &luid, &token, "a, &sub_status); + switch (status) { - debug_printf ("LsaLookupAuthenticationPackage: %y", status); - __seterrno_from_nt_status (status); - goto out; - } - user_len = wcslen (user) * sizeof (WCHAR); - domain_len = wcslen (domain) * sizeof (WCHAR); /* Local machine */ - authinf_size = sizeof (MSV1_0_S4U_LOGON) + user_len + domain_len; - if (!authinf) - authinf = tp.c_get (); - RtlSecureZeroMemory (authinf, authinf_size); - s4u_logon = (MSV1_0_S4U_LOGON *) authinf; - s4u_logon->MessageType = MsV1_0S4ULogon; - s4u_logon->Flags = 0; - /* Append user and domain to login info */ - RtlInitEmptyUnicodeString (&s4u_logon->UserPrincipalName, - (PWCHAR) (s4u_logon + 1), - user_len); - RtlInitEmptyUnicodeString (&s4u_logon->DomainName, - (PWCHAR) ((PBYTE) (s4u_logon + 1) + user_len), - domain_len); - RtlAppendUnicodeToString (&s4u_logon->UserPrincipalName, user); - RtlAppendUnicodeToString (&s4u_logon->DomainName, domain); - debug_printf ("DomainName: <%S> UserPrincipalName: <%S>", - &s4u_logon->DomainName, &s4u_logon->UserPrincipalName); - /* Create token source. */ - memcpy (ts.SourceName, "Cygwin.1", 8); - ts.SourceIdentifier.HighPart = 0; - ts.SourceIdentifier.LowPart = 0x0106; - if ((status = LsaLogonUser (lsa_hdl, (PLSA_STRING) &origin, Network, - package_id, authinf, authinf_size, NULL, - &ts, (PVOID *) &profile, &size, - &luid, &token, "a, &sub_status)) - != STATUS_SUCCESS) - { - if (status == STATUS_ACCOUNT_RESTRICTION) - debug_printf ("MSV1_0 S4U LsaLogonUser failed: %y (%s)", - status, account_restriction (sub_status)); - else - debug_printf ("MSV1_0 S4U LsaLogonUser failed: %y", status); + case STATUS_SUCCESS: + break; + case STATUS_ACCOUNT_RESTRICTION: + debug_printf ("%s S4U LsaLogonUser failed: %y (%s)", + kerberos_auth ? "Kerberos" : "MsV1_0", status, + account_restriction (sub_status)); + break; + default: + debug_printf ("%s S4U LsaLogonUser failed: %y", + kerberos_auth ? "Kerberos" : "MsV1_0", status); + break; } out: From 6aef5a46d7f22841e6a859103bb3f8acea060b84 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Fri, 1 Mar 2019 16:05:33 +0100 Subject: [PATCH 261/475] Cygwin: load_user_profile: temporarily extend debug output Signed-off-by: Corinna Vinschen --- winsup/cygwin/sec_auth.cc | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/winsup/cygwin/sec_auth.cc b/winsup/cygwin/sec_auth.cc index cb216a762..0b5e11238 100644 --- a/winsup/cygwin/sec_auth.cc +++ b/winsup/cygwin/sec_auth.cc @@ -255,6 +255,7 @@ load_user_profile (HANDLE token, struct passwd *pw, cygpsid &usersid) pi.lpUserName = username; /* Check if user has a roaming profile and fill in lpProfilePath, if so. Call NetUserGetInfo only for local machine accounts, use LDAP otherwise. */ + debug_printf ("machine <%W>", cygheap->dom.account_flat_name ()); if (!wcscasecmp (domain, cygheap->dom.account_flat_name ())) { NET_API_STATUS nas; @@ -275,6 +276,7 @@ load_user_profile (HANDLE token, struct passwd *pw, cygpsid &usersid) cyg_ldap cldap; PWCHAR dnsdomain = NULL; + debug_printf ("primary domain <%W>", cygheap->dom.primary_flat_name ()); if (!wcscasecmp (domain, cygheap->dom.primary_flat_name ())) dnsdomain = wcsdup (cygheap->dom.primary_dns_name ()); else @@ -282,11 +284,14 @@ load_user_profile (HANDLE token, struct passwd *pw, cygpsid &usersid) PDS_DOMAIN_TRUSTSW td = NULL; for (ULONG idx = 0; (td = cygheap->dom.trusted_domain (idx)); ++idx) - if (!wcscasecmp (domain, td->NetbiosDomainName)) - { - dnsdomain = wcsdup (td->DnsDomainName); - break; - } + { + debug_printf ("foreign domain <%W>", td->NetbiosDomainName); + if (!wcscasecmp (domain, td->NetbiosDomainName)) + { + dnsdomain = wcsdup (td->DnsDomainName); + break; + } + } } if (dnsdomain) { From 7ba9d12a72a722e0f20a80716dbeaf293e66a714 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Fri, 1 Mar 2019 21:04:02 +0100 Subject: [PATCH 262/475] Cygwin: load_user_profile: fix use-after-free issue In case of a local machine account login, pi.lpProfilePath points to the buffer returned by NetUserGetInfo, but NetApiBufferFree is called prior to calling LoadUserProfileW. Fix by copying over usri3_profile to the local userpath buffer, just as in the AD case. Signed-off-by: Corinna Vinschen --- winsup/cygwin/sec_auth.cc | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/winsup/cygwin/sec_auth.cc b/winsup/cygwin/sec_auth.cc index 0b5e11238..077b37ced 100644 --- a/winsup/cygwin/sec_auth.cc +++ b/winsup/cygwin/sec_auth.cc @@ -267,7 +267,11 @@ load_user_profile (HANDLE token, struct passwd *pw, cygpsid &usersid) else { if (ui->usri3_profile && *ui->usri3_profile) - pi.lpProfilePath = ui->usri3_profile; + { + wcsncpy (userpath, ui->usri3_profile, MAX_PATH - 1); + userpath[MAX_PATH - 1] = L'\0'; + pi.lpProfilePath = userpath; + } NetApiBufferFree (ui); } } From bffd21ad8047601e56d229e619bbcdb76096d975 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Fri, 1 Mar 2019 21:05:23 +0100 Subject: [PATCH 263/475] Cygwin: load_user_profile: use local pointer when appropriate dnsdomain does not have to be a copy of the domain, a pointer into cygheap is sufficient. Signed-off-by: Corinna Vinschen --- winsup/cygwin/sec_auth.cc | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/winsup/cygwin/sec_auth.cc b/winsup/cygwin/sec_auth.cc index 077b37ced..ee740facc 100644 --- a/winsup/cygwin/sec_auth.cc +++ b/winsup/cygwin/sec_auth.cc @@ -278,11 +278,11 @@ load_user_profile (HANDLE token, struct passwd *pw, cygpsid &usersid) else { cyg_ldap cldap; - PWCHAR dnsdomain = NULL; + PCWSTR dnsdomain = NULL; debug_printf ("primary domain <%W>", cygheap->dom.primary_flat_name ()); if (!wcscasecmp (domain, cygheap->dom.primary_flat_name ())) - dnsdomain = wcsdup (cygheap->dom.primary_dns_name ()); + dnsdomain = cygheap->dom.primary_dns_name (); else { PDS_DOMAIN_TRUSTSW td = NULL; @@ -292,7 +292,7 @@ load_user_profile (HANDLE token, struct passwd *pw, cygpsid &usersid) debug_printf ("foreign domain <%W>", td->NetbiosDomainName); if (!wcscasecmp (domain, td->NetbiosDomainName)) { - dnsdomain = wcsdup (td->DnsDomainName); + dnsdomain = td->DnsDomainName; break; } } @@ -309,7 +309,6 @@ load_user_profile (HANDLE token, struct passwd *pw, cygpsid &usersid) pi.lpProfilePath = userpath; } } - free (dnsdomain); } else debug_printf ("Unknown domain <%W>?", domain); From 166913fb23dd7ac0c63976a2f4e40a9e44ca41ca Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Fri, 1 Mar 2019 21:08:09 +0100 Subject: [PATCH 264/475] Cygwin: authentication: Always initialize domain info ...before calling any of its method. It's no safe bet that it's already initialized when calling s4uauth and adding it to load_user_profile certainly doesn't hurt. Signed-off-by: Corinna Vinschen --- winsup/cygwin/sec_auth.cc | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/winsup/cygwin/sec_auth.cc b/winsup/cygwin/sec_auth.cc index ee740facc..2f0480124 100644 --- a/winsup/cygwin/sec_auth.cc +++ b/winsup/cygwin/sec_auth.cc @@ -234,6 +234,10 @@ load_user_profile (HANDLE token, struct passwd *pw, cygpsid &usersid) WCHAR userpath[MAX_PATH]; PROFILEINFOW pi; + /* Initialize */ + if (!cygheap->dom.init ()) + return NULL; + extract_nt_dom_user (pw, domain, username); usersid.string (sid); debug_printf ("user: <%W> <%W> <%W>", username, domain, sid); @@ -1533,6 +1537,10 @@ s4uauth (bool logon, PCWSTR domain, PCWSTR user, NTSTATUS &ret_status) QUOTA_LIMITS quota; HANDLE token = NULL; + /* Initialize */ + if (!cygheap->dom.init ()) + return NULL; + push_self_privilege (SE_TCB_PRIVILEGE, true); if (logon) From 40958b0d867849199b38e2e2f04b3b9131a1e322 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Thu, 28 Feb 2019 15:05:13 +0100 Subject: [PATCH 265/475] Cygwin: fenv.h: Add feature test macros, fix values - feenableexcept,fedisableexcept, fegetexcept are GNU-only - fegetprec, fesetprec are Solaris, use __MISC_VISIBLE - _feinitialise is Cygwin-internal only - Replace self-named FP precision values to values from http://www.open-std.org/jtc1/sc22//WG14/www/docs/n752.htm as used by Solaris. - Change return value of fesetprec to adhere to the above document and Solaris. - Document fegetprec, fesetprec as Solaris functions, not as GNU functions Signed-off-by: Corinna Vinschen --- winsup/cygwin/fenv.cc | 26 ++++++++++++----- winsup/cygwin/include/fenv.h | 55 ++++++++++++++++++++---------------- winsup/doc/posix.xml | 4 +-- 3 files changed, 52 insertions(+), 33 deletions(-) diff --git a/winsup/cygwin/fenv.cc b/winsup/cygwin/fenv.cc index 3adc8a954..ebd93e8b4 100644 --- a/winsup/cygwin/fenv.cc +++ b/winsup/cygwin/fenv.cc @@ -391,18 +391,30 @@ fegetprec (void) return (cw & FE_CW_PREC_MASK) >> FE_CW_PREC_SHIFT; } -/* Changes the currently selected precision to prec. If prec does not - correspond to one of the supported rounding modes nothing is changed. - fesetprec returns zero if it changed the precision, or a nonzero value - if the mode is not supported. */ +/* http://www.open-std.org/jtc1/sc22//WG14/www/docs/n752.htm: + + The fesetprec function establishes the precision represented by its + argument prec. If the argument does not match a precision macro, the + precision is not changed. + + The fesetprec function returns a nonzero value if and only if the + argument matches a precision macro (that is, if and only if the requested + precision can be established). */ int fesetprec (int prec) { unsigned short cw; /* Will succeed for any valid value of the input parameter. */ - if (prec < FE_SINGLEPREC || prec > FE_EXTENDEDPREC) - return EINVAL; + switch (prec) + { + case FE_FLTPREC: + case FE_DBLPREC: + case FE_LDBLPREC: + break; + default: + return 0; + } /* Get control word. */ __asm__ volatile ("fnstcw %0" : "=m" (cw) : ); @@ -415,7 +427,7 @@ fesetprec (int prec) __asm__ volatile ("fldcw %0" :: "m" (cw)); /* Indicate success. */ - return 0; + return 1; } /* Set up the FPU and SSE environment at the start of execution. */ diff --git a/winsup/cygwin/include/fenv.h b/winsup/cygwin/include/fenv.h index 7ce3a9340..0f7e07445 100644 --- a/winsup/cygwin/include/fenv.h +++ b/winsup/cygwin/include/fenv.h @@ -106,11 +106,14 @@ typedef __uint32_t fexcept_t; #define FE_TOWARDZERO (3) #define FE_UPWARD (2) -/* Precision bit values. Not defined by Posix, but follow logically. */ -#define FE_SINGLEPREC (0) -#define FE_RESERVEDPREC (1) -#define FE_DOUBLEPREC (2) -#define FE_EXTENDEDPREC (3) +/* Only Solaris and QNX implement fegetprec/fesetprec. As Solaris, use the + values defined by http://www.open-std.org/jtc1/sc22//WG14/www/docs/n752.htm + QNX defines different values. */ +#if __MISC_VISIBLE +#define FE_FLTPREC (0) +#define FE_DBLPREC (2) +#define FE_LDBLPREC (3) +#endif /* The header shall define the following constant, which represents the default floating-point environment (that is, the one @@ -138,30 +141,34 @@ extern const fenv_t *_fe_nomask_env; /* The following shall be declared as functions and may also be defined as macros. Function prototypes shall be provided. */ -extern int feclearexcept (int excepts); -extern int fegetexceptflag (fexcept_t *flagp, int excepts); -extern int feraiseexcept (int excepts); -extern int fesetexceptflag (const fexcept_t *flagp, int excepts); -extern int fetestexcept (int excepts); +extern int feclearexcept (int __excepts); +extern int fegetexceptflag (fexcept_t *__flagp, int __excepts); +extern int feraiseexcept (int __excepts); +extern int fesetexceptflag (const fexcept_t *__flagp, int __excepts); +extern int fetestexcept (int __excepts); extern int fegetround (void); -extern int fesetround (int round); -extern int fegetenv (fenv_t *envp); -extern int feholdexcept (fenv_t *envp); -extern int fesetenv (const fenv_t *envp); -extern int feupdateenv (const fenv_t *envp); - -/* These are not defined in Posix, but make sense by obvious extension. */ -extern int fegetprec (void); -extern int fesetprec (int prec); - -/* This is Cygwin-custom, not from the standard, for use in the Cygwin CRT. */ -extern void _feinitialise (void); +extern int fesetround (int __round); +extern int fegetenv (fenv_t *__envp); +extern int feholdexcept (fenv_t *__envp); +extern int fesetenv (const fenv_t *__envp); +extern int feupdateenv (const fenv_t *__envp); +#if __GNU_VISIBLE /* These are GNU extensions defined in glibc. */ -extern int feenableexcept (int excepts); -extern int fedisableexcept (int excepts); +extern int feenableexcept (int __excepts); +extern int fedisableexcept (int __excepts); extern int fegetexcept (void); +#endif +#if __MISC_VISIBLE +extern int fegetprec (void); +extern int fesetprec (int __prec); +#endif + +#ifdef __INSIDE_CYGWIN__ +/* This is Cygwin-custom, not from the standard, for use in the Cygwin CRT. */ +extern void _feinitialise (); +#endif #ifdef __cplusplus } diff --git a/winsup/doc/posix.xml b/winsup/doc/posix.xml index 0755beda0..d49cf5591 100644 --- a/winsup/doc/posix.xml +++ b/winsup/doc/posix.xml @@ -1319,8 +1319,6 @@ also IEEE Std 1003.1-2008 (POSIX.1-2008). fedisableexcept feenableexcept fegetexcept - fegetprec - fesetprec ffsl ffsll fgets_unlocked @@ -1443,6 +1441,8 @@ also IEEE Std 1003.1-2008 (POSIX.1-2008). acltotext endmntent facl + fegetprec + fesetprec futimesat getmntent memalign From 6c86b85f4ea30662b16e22e1803cc18de2658f4f Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Sat, 2 Mar 2019 12:43:34 +0100 Subject: [PATCH 266/475] Cygwin: ldap: Fix overwriting domain when creating naming context cyg_ldap::fetch_ad_account creates a naming context from the incoming domain, if it's not NULL. The algorithm overwrites dots with \0 in domain while creating the naming context, but neglects to restore the dots. Fix that by never overwriting the incoming domain name. Signed-off-by: Corinna Vinschen --- winsup/cygwin/ldap.cc | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/winsup/cygwin/ldap.cc b/winsup/cygwin/ldap.cc index 01e892f03..3c9fd13a1 100644 --- a/winsup/cygwin/ldap.cc +++ b/winsup/cygwin/ldap.cc @@ -7,6 +7,10 @@ Cygwin license. Please consult the file "CYGWIN_LICENSE" for details. */ #include "winsup.h" +#include +#include +#include +#include #include "ldap.h" #include "cygerrno.h" #include "security.h" @@ -16,10 +20,7 @@ details. */ #include "cygheap.h" #include "registry.h" #include "pinfo.h" -#include "lm.h" -#include "dsgetdc.h" #include "tls_pbuf.h" -#include #define CYG_LDAP_ENUM_PAGESIZE 100 /* entries per page */ @@ -452,16 +453,15 @@ cyg_ldap::fetch_ad_account (PSID sid, bool group, PCWSTR domain) problems, we know what to do. */ base = tp.w_get (); PWCHAR b = base; - for (PWCHAR dotp = (PWCHAR) domain; dotp && *dotp; domain = dotp) + for (PCWSTR dotp = domain; dotp && *dotp; domain = dotp) { dotp = wcschr (domain, L'.'); - if (dotp) - *dotp++ = L'\0'; if (b > base) *b++ = L','; b = wcpcpy (b, L"DC="); - b = wcpcpy (b, domain); + b = dotp ? wcpncpy (b, domain, dotp++ - domain) : wcpcpy (b, domain); } + debug_printf ("naming context <%W>", base); } else { From 4abac6219346f3b3c06401d8100593c742b094b3 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Sat, 2 Mar 2019 12:47:54 +0100 Subject: [PATCH 267/475] Cygwin: load_user_profile: Don't give primary domain to ldap If the user domain is the primary domain, LDAP is supposed to use the default naming context. This is accomplished by setting domain name to NULL in the call to cyg_ldap::fetch_ad_account. Signed-off-by: Corinna Vinschen --- winsup/cygwin/sec_auth.cc | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/winsup/cygwin/sec_auth.cc b/winsup/cygwin/sec_auth.cc index 2f0480124..36874b63e 100644 --- a/winsup/cygwin/sec_auth.cc +++ b/winsup/cygwin/sec_auth.cc @@ -285,9 +285,7 @@ load_user_profile (HANDLE token, struct passwd *pw, cygpsid &usersid) PCWSTR dnsdomain = NULL; debug_printf ("primary domain <%W>", cygheap->dom.primary_flat_name ()); - if (!wcscasecmp (domain, cygheap->dom.primary_flat_name ())) - dnsdomain = cygheap->dom.primary_dns_name (); - else + if (wcscasecmp (domain, cygheap->dom.primary_flat_name ())) { PDS_DOMAIN_TRUSTSW td = NULL; @@ -301,21 +299,16 @@ load_user_profile (HANDLE token, struct passwd *pw, cygpsid &usersid) } } } - if (dnsdomain) + if (cldap.fetch_ad_account (usersid, false, dnsdomain)) { - if (cldap.fetch_ad_account (usersid, false, dnsdomain)) + PWCHAR val = cldap.get_profile_path (); + if (val && *val) { - PWCHAR val = cldap.get_profile_path (); - if (val && *val) - { - wcsncpy (userpath, val, MAX_PATH - 1); - userpath[MAX_PATH - 1] = L'\0'; - pi.lpProfilePath = userpath; - } + wcsncpy (userpath, val, MAX_PATH - 1); + userpath[MAX_PATH - 1] = L'\0'; + pi.lpProfilePath = userpath; } } - else - debug_printf ("Unknown domain <%W>?", domain); } if (!LoadUserProfileW (token, &pi)) From 38dde5f4c4c2e33dfe6dfb9d1bc593d13d85a290 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Sun, 3 Mar 2019 10:59:13 +0100 Subject: [PATCH 268/475] Cygwin: fork: fix child process permissions, take 3 Per MSDN VirtualQueryEx requires PROCESS_QUERY_INFORMATION. Testing showed that PROCESS_QUERY_LIMITED_INFORMATION is sufficient since Windows 8.1. The assumption that Windows 8 is the same as Windows 8 was not correct, it requires PROCESS_QUERY_INFORMATION as well. Fix that by splitting the Windows 8 wincaps into one for Windows 8 and one for Windows 8.1. Set needs_query_information for Windows 8. Signed-off-by: Corinna Vinschen --- winsup/cygwin/wincap.cc | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/winsup/cygwin/wincap.cc b/winsup/cygwin/wincap.cc index 78cc41133..5bc9c3778 100644 --- a/winsup/cygwin/wincap.cc +++ b/winsup/cygwin/wincap.cc @@ -69,6 +69,31 @@ wincaps wincap_7 __attribute__((section (".cygwin_dll_common"), shared)) = { }; wincaps wincap_8 __attribute__((section (".cygwin_dll_common"), shared)) = { + def_guard_pages:2, + { + is_server:false, + needs_count_in_si_lpres2:false, + needs_query_information:true, + has_gaa_largeaddress_bug:false, + has_broken_alloc_console:true, + has_console_logon_sid:true, + has_precise_system_time:true, + has_microsoft_accounts:true, + has_processor_groups:true, + has_broken_prefetchvm:false, + has_new_pebteb_region:false, + has_broken_whoami:false, + has_unprivileged_createsymlink:false, + has_unbiased_interrupt_time:true, + has_precise_interrupt_time:false, + has_posix_unlink_semantics:false, + has_case_sensitive_dirs:false, + has_posix_rename_semantics:false, + no_msv1_0_s4u_logon_in_wow64:false, + }, +}; + +wincaps wincap_8_1 __attribute__((section (".cygwin_dll_common"), shared)) = { def_guard_pages:2, { is_server:false, @@ -273,9 +298,11 @@ wincapc::init () caps = &wincap_7; break; case 2: - case 3: caps = &wincap_8; break; + case 3: + caps = &wincap_8_1; + break; default: caps = &wincap_10_1507; break; From c18f7d72dc5554b1e12f035fcf7d66be25ee3881 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Mon, 4 Mar 2019 14:03:32 +0100 Subject: [PATCH 269/475] Cygwin: doc: update case-sensitive dirs description Since we have to disable automatic case-sensitive mkdir again, change documentation accordingly. Signed-off-by: Corinna Vinschen --- winsup/doc/specialnames.xml | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/winsup/doc/specialnames.xml b/winsup/doc/specialnames.xml index f27836032..1120f86b1 100644 --- a/winsup/doc/specialnames.xml +++ b/winsup/doc/specialnames.xml @@ -230,13 +230,26 @@ feature available via Programs and Features -> turning WSL on and performing the compulsory reboot, case-sensitive directories are activated. -With WSL activated and starting with Cygwin 3.0, -Cygwin's mkdir system call will automatically create all +Of course, there's a drawback. While these case-sensitive directories +work like charm on the local machine, there are massive interoperability +problems when trying to access these directories from remote machines at +the time of writing this. We opened a bug report for that at +Microsoft's WSL issue tracker, +if you're interested in the details. + +If you want case-sensitivity and need interoperability with remote +machines, better stick to switching the kernel to case-sensitivity as +outlined in + +With WSL activated and starting with Cygwin 3.0.0, +Cygwin's mkdir system call automatically created all directories below the Cygwin installation directory as case-sensitive. -Directories created outside the Cygwin installation tree will be left -alone. However, you can use Cygwin's new tool -with the -C option to control case-sensitivity of -directories on NTFS filesystems. +With Cygwin 3.0.2, this feature had been disabled again for hopefully +obvious reasons. + +However, you can still use Cygwin's new + tool with the -C option +to control case-sensitivity of directories on NTFS filesystems. Please keep in mind that switching off case-sensitivity on a directory has a condition attached to it: If From fc5b248784f094c99bce02e6af580d3db5ebd93f Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Mon, 4 Mar 2019 14:14:15 +0100 Subject: [PATCH 270/475] Cygwin: update 3.0.2 release file Signed-off-by: Corinna Vinschen --- winsup/cygwin/release/3.0.2 | 3 +++ 1 file changed, 3 insertions(+) diff --git a/winsup/cygwin/release/3.0.2 b/winsup/cygwin/release/3.0.2 index d0a592b7c..7d3a03457 100644 --- a/winsup/cygwin/release/3.0.2 +++ b/winsup/cygwin/release/3.0.2 @@ -32,3 +32,6 @@ Bug Fixes - Fix getitimer/timer_gettime values returned for unarmed timer. Addresses: https://cygwin.com/ml/cygwin/2019-02/msg00395.html + +- Fix a fork issue with mmap on Windows 8 / Server 2012. + Addresses: https://cygwin.com/ml/cygwin/2019-03/msg00012.html From 5c4ce731ac08d6615ae759121ab7e9e824024808 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Mon, 4 Mar 2019 17:07:31 +0100 Subject: [PATCH 271/475] Cygwin: Revert attempting to unload user profile after use Revert "Cywin: user profile: unload impersonation user profile on exit" Revert "Cygwin: seteuid: allow inheriting impersonation user profile handle" Revert "Cygwin: user profile: add debug output to unload_user_profile" Revert "Cygwin: user profile: Make an effort to unload unused user profiles" This reverts commit bcb33dc4f0552e749dcb6c44e1ef7815b5db75a1. This reverts commit dd3730ed9c1c78176f1aab1b429bb5a105d90a44. This reverts commit 8eee25241e86fc596acde25c7c53723b75afee30. This reverts commit 71b8777a7140b79942d6e5079818cad2c3f5f07f. This patchset actually results in the following problem: - After a couple of ssh logon/logoff attempts, an interactive session of the same user loging in, is broken. Apparently UnloadUserProfile manages to unload the user's profile even while a parallel interactive session still uses the user's profile. Signed-off-by: Corinna Vinschen --- winsup/cygwin/autoload.cc | 1 - winsup/cygwin/cygheap.h | 8 -------- winsup/cygwin/pinfo.cc | 1 - winsup/cygwin/sec_auth.cc | 9 --------- winsup/cygwin/security.h | 1 - winsup/cygwin/syscalls.cc | 19 +++---------------- winsup/cygwin/uinfo.cc | 2 -- 7 files changed, 3 insertions(+), 38 deletions(-) diff --git a/winsup/cygwin/autoload.cc b/winsup/cygwin/autoload.cc index c04e25c95..056fac7dc 100644 --- a/winsup/cygwin/autoload.cc +++ b/winsup/cygwin/autoload.cc @@ -699,7 +699,6 @@ LoadDLLfuncEx (CreateEnvironmentBlock, 12, userenv, 1) LoadDLLfuncEx2 (CreateProfile, 16, userenv, 1, 1) LoadDLLfunc (DestroyEnvironmentBlock, 4, userenv) LoadDLLfunc (LoadUserProfileW, 8, userenv) -LoadDLLfunc (UnloadUserProfile, 8, userenv) LoadDLLfuncEx3 (waveInAddBuffer, 12, winmm, 1, 0, 1) LoadDLLfuncEx3 (waveInClose, 4, winmm, 1, 0, 1) diff --git a/winsup/cygwin/cygheap.h b/winsup/cygwin/cygheap.h index 4d9feb072..8877cc358 100644 --- a/winsup/cygwin/cygheap.h +++ b/winsup/cygwin/cygheap.h @@ -106,9 +106,6 @@ public: HANDLE curr_primary_token; /* Just a copy of external or internal token */ HANDLE curr_imp_token; /* impersonation token derived from primary token */ - HANDLE imp_profile_token; /* Handle to the token used to load the - user profile in "imp_profile" */ - HANDLE imp_profile; /* Handle to the user profile */ bool ext_token_is_restricted; /* external_token is restricted token */ bool curr_token_is_restricted; /* curr_primary_token is restricted token */ bool setuid_to_restricted; /* switch to restricted token by setuid () */ @@ -193,11 +190,6 @@ public: { return effec_cygsid.string (buf); } - void exit () - { - if (imp_profile_token && imp_profile) - unload_user_profile (imp_profile_token, imp_profile); - } const char __reg3 *test_uid (char *&, const char *, size_t); }; diff --git a/winsup/cygwin/pinfo.cc b/winsup/cygwin/pinfo.cc index e29c00746..064299e0c 100644 --- a/winsup/cygwin/pinfo.cc +++ b/winsup/cygwin/pinfo.cc @@ -224,7 +224,6 @@ pinfo::exit (DWORD n) exitcode = ((exitcode & 0xff) << 8) | ((exitcode >> 8) & 0xff); sigproc_printf ("Calling dlls.cleanup_forkables n %y, exitcode %y", n, exitcode); dlls.cleanup_forkables (); - cygheap->user.exit (); sigproc_printf ("Calling ExitProcess n %y, exitcode %y", n, exitcode); if (!TerminateProcess (GetCurrentProcess (), exitcode)) system_printf ("TerminateProcess failed, %E"); diff --git a/winsup/cygwin/sec_auth.cc b/winsup/cygwin/sec_auth.cc index 36874b63e..195d20ca9 100644 --- a/winsup/cygwin/sec_auth.cc +++ b/winsup/cygwin/sec_auth.cc @@ -316,15 +316,6 @@ load_user_profile (HANDLE token, struct passwd *pw, cygpsid &usersid) return pi.hProfile; } -bool -unload_user_profile (HANDLE token, HANDLE profile) -{ - bool ret = UnloadUserProfile (token, profile); - if (!ret) - debug_printf ("UnloadUserProfile, %E"); - return ret; -} - HANDLE lsa_open_policy (PWCHAR server, ACCESS_MASK access) { diff --git a/winsup/cygwin/security.h b/winsup/cygwin/security.h index 0ce7e8d7a..483a527e7 100644 --- a/winsup/cygwin/security.h +++ b/winsup/cygwin/security.h @@ -502,7 +502,6 @@ PWCHAR get_user_profile_directory (PCWSTR sidstr, PWCHAR path, SIZE_T path_len); /* Load user profile if it's not already loaded. */ HANDLE load_user_profile (HANDLE token, struct passwd *pw, cygpsid &sid); -bool unload_user_profile (HANDLE token, HANDLE profile); HANDLE lsa_open_policy (PWCHAR server, ACCESS_MASK access); void lsa_close_policy (HANDLE lsa); diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc index a73af6748..172b7c4f6 100644 --- a/winsup/cygwin/syscalls.cc +++ b/winsup/cygwin/syscalls.cc @@ -3603,21 +3603,8 @@ seteuid32 (uid_t uid) { NTSTATUS status; - if (!request_restricted_uid_switch - && new_token != cygheap->user.imp_profile_token) - { - if (cygheap->user.imp_profile_token && cygheap->user.imp_profile) - unload_user_profile (cygheap->user.imp_profile_token, - cygheap->user.imp_profile); - cygheap->user.imp_profile = load_user_profile (new_token, pw_new, - usersid); - if (cygheap->user.imp_profile) - { - cygheap->user.imp_profile_token = new_token; - SetHandleInformation (cygheap->user.imp_profile, - HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT); - } - } + if (!request_restricted_uid_switch) + load_user_profile (new_token, pw_new, usersid); /* Try setting owner to same value as user. */ status = NtSetInformationToken (new_token, TokenOwner, @@ -3647,7 +3634,7 @@ seteuid32 (uid_t uid) issamesid = (usersid == cygheap->user.sid ()); cygheap->user.set_sid (usersid); cygheap->user.curr_primary_token = new_token == hProcToken ? NO_IMPERSONATION - : new_token; + : new_token; cygheap->user.curr_token_is_restricted = false; cygheap->user.setuid_to_restricted = false; if (cygheap->user.curr_imp_token != NO_IMPERSONATION) diff --git a/winsup/cygwin/uinfo.cc b/winsup/cygwin/uinfo.cc index 49614cb45..bfcce00da 100644 --- a/winsup/cygwin/uinfo.cc +++ b/winsup/cygwin/uinfo.cc @@ -239,8 +239,6 @@ uinfo_init () cygheap->user.internal_token = NO_IMPERSONATION; cygheap->user.curr_primary_token = NO_IMPERSONATION; cygheap->user.curr_imp_token = NO_IMPERSONATION; - cygheap->user.imp_profile_token = NO_IMPERSONATION; - cygheap->user.imp_profile = NULL; cygheap->user.ext_token_is_restricted = false; cygheap->user.curr_token_is_restricted = false; cygheap->user.setuid_to_restricted = false; From ad492320839c18936c56d776240c9a5151d5d97b Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Mon, 4 Mar 2019 14:58:45 +0100 Subject: [PATCH 272/475] Revert "Cygwin: load_user_profile: temporarily extend debug output" This reverts commit 6aef5a46d7f22841e6a859103bb3f8acea060b84. --- winsup/cygwin/sec_auth.cc | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/winsup/cygwin/sec_auth.cc b/winsup/cygwin/sec_auth.cc index 195d20ca9..a76f4534b 100644 --- a/winsup/cygwin/sec_auth.cc +++ b/winsup/cygwin/sec_auth.cc @@ -259,7 +259,6 @@ load_user_profile (HANDLE token, struct passwd *pw, cygpsid &usersid) pi.lpUserName = username; /* Check if user has a roaming profile and fill in lpProfilePath, if so. Call NetUserGetInfo only for local machine accounts, use LDAP otherwise. */ - debug_printf ("machine <%W>", cygheap->dom.account_flat_name ()); if (!wcscasecmp (domain, cygheap->dom.account_flat_name ())) { NET_API_STATUS nas; @@ -284,20 +283,16 @@ load_user_profile (HANDLE token, struct passwd *pw, cygpsid &usersid) cyg_ldap cldap; PCWSTR dnsdomain = NULL; - debug_printf ("primary domain <%W>", cygheap->dom.primary_flat_name ()); if (wcscasecmp (domain, cygheap->dom.primary_flat_name ())) { PDS_DOMAIN_TRUSTSW td = NULL; for (ULONG idx = 0; (td = cygheap->dom.trusted_domain (idx)); ++idx) - { - debug_printf ("foreign domain <%W>", td->NetbiosDomainName); - if (!wcscasecmp (domain, td->NetbiosDomainName)) - { - dnsdomain = td->DnsDomainName; - break; - } - } + if (!wcscasecmp (domain, td->NetbiosDomainName)) + { + dnsdomain = td->DnsDomainName; + break; + } } if (cldap.fetch_ad_account (usersid, false, dnsdomain)) { From 8551226961429cc6810286b01ba4430f01c7d807 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Mon, 4 Mar 2019 20:30:37 +0100 Subject: [PATCH 273/475] Cygwin: seteuid: do not verify lsaprivkeyauth token We don't support setting groups via /etc/groups anymore. Also, the initgroups group list is created via S4U, so we have "Interactive" vs. "Network" token, an artificial and entirely irrelevant difference. So, "verifying" the lsaprivkeyauth token may lead to rejecting a prefectly valid token. Just remove the verify_token call. Signed-off-by: Corinna Vinschen --- winsup/cygwin/syscalls.cc | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc index 172b7c4f6..a914ae8a9 100644 --- a/winsup/cygwin/syscalls.cc +++ b/winsup/cygwin/syscalls.cc @@ -3552,18 +3552,7 @@ seteuid32 (uid_t uid) LSA module, or, as last chance, NtCreateToken. */ if (new_token == NULL) { - new_token = lsaprivkeyauth (pw_new); - if (new_token) - { - /* We have to verify this token since settings in /etc/group - might render it unusable im terms of group membership. */ - if (!verify_token (new_token, usersid, groups)) - { - CloseHandle (new_token); - new_token = NULL; - } - } - if (!new_token) + if (!(new_token = lsaprivkeyauth (pw_new))) { NTSTATUS status; WCHAR domain[MAX_DOMAIN_NAME_LEN + 1]; From 633278b877e0cb60956ce6da2f795f534ec9b5bc Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Tue, 5 Mar 2019 20:00:30 +0100 Subject: [PATCH 274/475] Cygwin: bump version to 3.0.3 Signed-off-by: Corinna Vinschen --- winsup/cygwin/include/cygwin/version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/winsup/cygwin/include/cygwin/version.h b/winsup/cygwin/include/cygwin/version.h index 97bc0aeda..2526e4e20 100644 --- a/winsup/cygwin/include/cygwin/version.h +++ b/winsup/cygwin/include/cygwin/version.h @@ -11,7 +11,7 @@ details. */ changes to the DLL and is mainly informative in nature. */ #define CYGWIN_VERSION_DLL_MAJOR 3000 -#define CYGWIN_VERSION_DLL_MINOR 2 +#define CYGWIN_VERSION_DLL_MINOR 3 /* Major numbers before CYGWIN_VERSION_DLL_EPOCH are incompatible. */ From 094a2a17ad1cd65909fa2eee648d049d8d69fc45 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Wed, 6 Mar 2019 22:17:32 +0100 Subject: [PATCH 275/475] Cygwin: posix timers: fix resource leak On setting the timer, the thread is accidentally only canceled when disarming the timer. This leaks one thread per timer_settimer call. Move the thread cancellation where it belongs. Signed-off-by: Corinna Vinschen --- winsup/cygwin/posix_timer.cc | 2 +- winsup/cygwin/release/3.0.3 | 13 +++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 winsup/cygwin/release/3.0.3 diff --git a/winsup/cygwin/posix_timer.cc b/winsup/cygwin/posix_timer.cc index d9d4a9a18..a140b00e9 100644 --- a/winsup/cygwin/posix_timer.cc +++ b/winsup/cygwin/posix_timer.cc @@ -287,9 +287,9 @@ timer_tracker::settime (int flags, const itimerspec *new_value, if (old_value) gettime (old_value, false); + cancel (); if (!new_value->it_value.tv_sec && !new_value->it_value.tv_nsec) { - cancel (); memset (&time_spec, 0, sizeof time_spec); interval = 0; exp_ts = 0; diff --git a/winsup/cygwin/release/3.0.3 b/winsup/cygwin/release/3.0.3 new file mode 100644 index 000000000..66ae63943 --- /dev/null +++ b/winsup/cygwin/release/3.0.3 @@ -0,0 +1,13 @@ +What's new: +----------- + + +What changed: +------------- + + +Bug Fixes +--------- + +- Fix a resource leak in posix timers. + Addresses: https://cygwin.com/ml/cygwin/2019-03/msg00120.html From 4ec5ffc198fcdcbea2dbca81a337900ac33b1fa7 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Fri, 8 Mar 2019 12:51:10 +0100 Subject: [PATCH 276/475] Cygwin: posix timers: fix a deadlock Canceling the timer thread runs under lock. The thread uses the same lock to guard its timer_tracker struct access. If the timing is bad, timer_settime or timer_delete grab the lock at the same time, the timer expires. In the end, cancel waits for the thread sync while the thread waits for ther lock to be released. Fix this by not waiting for the thread sync under lock. Signed-off-by: Corinna Vinschen --- winsup/cygwin/posix_timer.cc | 2 ++ winsup/cygwin/release/3.0.3 | 3 +++ 2 files changed, 5 insertions(+) diff --git a/winsup/cygwin/posix_timer.cc b/winsup/cygwin/posix_timer.cc index a140b00e9..c0d548fe9 100644 --- a/winsup/cygwin/posix_timer.cc +++ b/winsup/cygwin/posix_timer.cc @@ -31,7 +31,9 @@ timer_tracker::cancel () SetEvent (cancel_evt); if (sync_thr) { + ReleaseSRWLockExclusive (&srwlock); res = WaitForSingleObject (sync_thr, INFINITE); + AcquireSRWLockExclusive (&srwlock); if (res != WAIT_OBJECT_0) debug_printf ("WFSO returned unexpected value %u, %E", res); } diff --git a/winsup/cygwin/release/3.0.3 b/winsup/cygwin/release/3.0.3 index 66ae63943..b8c89cbe9 100644 --- a/winsup/cygwin/release/3.0.3 +++ b/winsup/cygwin/release/3.0.3 @@ -11,3 +11,6 @@ Bug Fixes - Fix a resource leak in posix timers. Addresses: https://cygwin.com/ml/cygwin/2019-03/msg00120.html + +- Fix a deadlock in posix timers + Addresses: https://cygwin.com/ml/cygwin/2019-03/msg00158.html From 7cbe4b59d6296ed29d2d674d15fcc6333fadf7ed Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Sat, 9 Mar 2019 20:13:50 +0100 Subject: [PATCH 277/475] Cygwin: bump version to 3.0.4 Signed-off-by: Corinna Vinschen --- winsup/cygwin/include/cygwin/version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/winsup/cygwin/include/cygwin/version.h b/winsup/cygwin/include/cygwin/version.h index 2526e4e20..da134be2d 100644 --- a/winsup/cygwin/include/cygwin/version.h +++ b/winsup/cygwin/include/cygwin/version.h @@ -11,7 +11,7 @@ details. */ changes to the DLL and is mainly informative in nature. */ #define CYGWIN_VERSION_DLL_MAJOR 3000 -#define CYGWIN_VERSION_DLL_MINOR 3 +#define CYGWIN_VERSION_DLL_MINOR 4 /* Major numbers before CYGWIN_VERSION_DLL_EPOCH are incompatible. */ From d9f934c9e9ec5588e6c616e9c63dd348995dafa8 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Mon, 11 Mar 2019 21:40:04 +0100 Subject: [PATCH 278/475] Cygwin: fix permissions of winpid symlinks The winpid symlinks got created with no query permissions, so only admins could see all Cygwin processes. Create symlinks so everyone has query permissions instead. Signed-off-by: Corinna Vinschen --- winsup/cygwin/pinfo.cc | 3 ++- winsup/cygwin/release/3.0.4 | 13 +++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) create mode 100644 winsup/cygwin/release/3.0.4 diff --git a/winsup/cygwin/pinfo.cc b/winsup/cygwin/pinfo.cc index 064299e0c..453861c81 100644 --- a/winsup/cygwin/pinfo.cc +++ b/winsup/cygwin/pinfo.cc @@ -325,7 +325,8 @@ pinfo::create_winpid_symlink () __small_swprintf (pid_name, L"%u", procinfo->pid); RtlInitUnicodeString (&pid_str, pid_name); InitializeObjectAttributes (&attr, &sym_str, OBJ_CASE_INSENSITIVE, - get_shared_parent_dir (), NULL); + get_shared_parent_dir (), + everyone_sd (SYMBOLIC_LINK_QUERY)); NtCreateSymbolicLinkObject (&winpid_hdl, SYMBOLIC_LINK_ALL_ACCESS, &attr, &pid_str); } diff --git a/winsup/cygwin/release/3.0.4 b/winsup/cygwin/release/3.0.4 new file mode 100644 index 000000000..c545f3e64 --- /dev/null +++ b/winsup/cygwin/release/3.0.4 @@ -0,0 +1,13 @@ +What's new: +----------- + + +What changed: +------------- + + +Bug Fixes +--------- + +- Fix access to process list + Addresses: https://cygwin.com/ml/cygwin/2019-03/msg00253.html From 048f28bfe4a86fde44759ccec34e8ac7de56eebe Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Tue, 12 Mar 2019 11:17:11 +0100 Subject: [PATCH 279/475] Cygwin: proc: return more useful cmdline Creating /proc//cmdline requires permissions to communicate with the target process via its signal pipe. If that fails, the output is "" which doesn't make sense most of the time. Rather, call format_process_exename in this case to get more useful process name info, albeit not the full cmdline. Signed-off-by: Corinna Vinschen --- winsup/cygwin/fhandler_process.cc | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/winsup/cygwin/fhandler_process.cc b/winsup/cygwin/fhandler_process.cc index 29b8c5934..06325caf1 100644 --- a/winsup/cygwin/fhandler_process.cc +++ b/winsup/cygwin/fhandler_process.cc @@ -519,12 +519,9 @@ format_process_cmdline (void *data, char *&destbuf) destbuf = NULL; } destbuf = p ? p->cmdline (fs) : NULL; - if (!destbuf || !*destbuf) - { - destbuf = cstrdup (""); - fs = strlen (destbuf) + 1; - } - return fs; + if (destbuf && *destbuf) + return fs; + return format_process_exename (data, destbuf); } static off_t From 4ce7e1bbaacf007197e348e4d11ec6258f508873 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Tue, 12 Mar 2019 11:20:42 +0100 Subject: [PATCH 280/475] Cygwin: proc: don't request PROCESS_VM_READ perms for stat The OpenProcess call to generate /proc//stat info requests PROCESS_VM_READ, but that's not required. Drop it. Signed-off-by: Corinna Vinschen --- winsup/cygwin/fhandler_process.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/winsup/cygwin/fhandler_process.cc b/winsup/cygwin/fhandler_process.cc index 06325caf1..576c5cbd0 100644 --- a/winsup/cygwin/fhandler_process.cc +++ b/winsup/cygwin/fhandler_process.cc @@ -1097,7 +1097,7 @@ format_process_stat (void *data, char *&destbuf) QUOTA_LIMITS ql; SYSTEM_TIMEOFDAY_INFORMATION stodi; SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION spt; - hProcess = OpenProcess (PROCESS_QUERY_LIMITED_INFORMATION | PROCESS_VM_READ, + hProcess = OpenProcess (PROCESS_QUERY_LIMITED_INFORMATION, FALSE, p->dwProcessId); if (hProcess == NULL) { From 57f1c81fb3e4a2581f5421350315755b07e509c8 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Tue, 12 Mar 2019 11:34:50 +0100 Subject: [PATCH 281/475] Cygwin: proc: let stat info always succeed There's no good reason to return blank if some of the info couldn't be collected. Drop useless call collecting SystemProcessorPerformanceInformation. Always return some valid start_time, even if we couldn't collect ProcessTimes. Signed-off-by: Corinna Vinschen --- winsup/cygwin/fhandler_process.cc | 70 +++++++++++++++++-------------- 1 file changed, 38 insertions(+), 32 deletions(-) diff --git a/winsup/cygwin/fhandler_process.cc b/winsup/cygwin/fhandler_process.cc index 576c5cbd0..31cd50700 100644 --- a/winsup/cygwin/fhandler_process.cc +++ b/winsup/cygwin/fhandler_process.cc @@ -1091,12 +1091,12 @@ format_process_stat (void *data, char *&destbuf) NTSTATUS status; HANDLE hProcess; - VM_COUNTERS vmc; - KERNEL_USER_TIMES put; - PROCESS_BASIC_INFORMATION pbi; - QUOTA_LIMITS ql; - SYSTEM_TIMEOFDAY_INFORMATION stodi; - SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION spt; + VM_COUNTERS vmc = { 0 }; + KERNEL_USER_TIMES put = { 0 }; + PROCESS_BASIC_INFORMATION pbi = { 0 }; + QUOTA_LIMITS ql = { 0 }; + SYSTEM_TIMEOFDAY_INFORMATION stodi = { 0 }; + hProcess = OpenProcess (PROCESS_QUERY_LIMITED_INFORMATION, FALSE, p->dwProcessId); if (hProcess == NULL) @@ -1104,38 +1104,44 @@ format_process_stat (void *data, char *&destbuf) DWORD error = GetLastError (); __seterrno_from_win_error (error); debug_printf ("OpenProcess: ret %u", error); - return 0; } - - status = NtQueryInformationProcess (hProcess, ProcessVmCounters, - (PVOID) &vmc, sizeof vmc, NULL); - if (NT_SUCCESS (status)) - status = NtQueryInformationProcess (hProcess, ProcessTimes, - (PVOID) &put, sizeof put, NULL); - if (NT_SUCCESS (status)) - status = NtQueryInformationProcess (hProcess, ProcessBasicInformation, - (PVOID) &pbi, sizeof pbi, NULL); - if (NT_SUCCESS (status)) - status = NtQueryInformationProcess (hProcess, ProcessQuotaLimits, - (PVOID) &ql, sizeof ql, NULL); - CloseHandle (hProcess); - if (NT_SUCCESS (status)) - status = NtQuerySystemInformation (SystemTimeOfDayInformation, - (PVOID) &stodi, sizeof stodi, NULL); - if (NT_SUCCESS (status)) - status = NtQuerySystemInformation (SystemProcessorPerformanceInformation, - (PVOID) &spt, sizeof spt, NULL); - if (!NT_SUCCESS (status)) + else { - __seterrno_from_nt_status (status); - debug_printf ("NtQueryInformationProcess: status %y, %E", status); - return 0; + status = NtQueryInformationProcess (hProcess, ProcessVmCounters, + (PVOID) &vmc, sizeof vmc, NULL); + if (!NT_SUCCESS (status)) + debug_printf ("NtQueryInformationProcess(ProcessVmCounters): status %y", + status); + status = NtQueryInformationProcess (hProcess, ProcessTimes, + (PVOID) &put, sizeof put, NULL); + if (!NT_SUCCESS (status)) + debug_printf ("NtQueryInformationProcess(ProcessTimes): status %y", + status); + status = NtQueryInformationProcess (hProcess, ProcessBasicInformation, + (PVOID) &pbi, sizeof pbi, NULL); + if (!NT_SUCCESS (status)) + debug_printf ("NtQueryInformationProcess(ProcessBasicInformation): " + "status %y", status); + status = NtQueryInformationProcess (hProcess, ProcessQuotaLimits, + (PVOID) &ql, sizeof ql, NULL); + if (!NT_SUCCESS (status)) + debug_printf ("NtQueryInformationProcess(ProcessQuotaLimits): " + "status %y", status); + CloseHandle (hProcess); } + status = NtQuerySystemInformation (SystemTimeOfDayInformation, + (PVOID) &stodi, sizeof stodi, NULL); + if (!NT_SUCCESS (status)) + debug_printf ("NtQuerySystemInformation(SystemTimeOfDayInformation): " + "status %y", status); fault_count = vmc.PageFaultCount; utime = put.UserTime.QuadPart * CLOCKS_PER_SEC / NS100PERSEC; stime = put.KernelTime.QuadPart * CLOCKS_PER_SEC / NS100PERSEC; - start_time = (put.CreateTime.QuadPart - stodi.BootTime.QuadPart) - * CLOCKS_PER_SEC / NS100PERSEC; + if (put.CreateTime.QuadPart) + start_time = (put.CreateTime.QuadPart - stodi.BootTime.QuadPart) + * CLOCKS_PER_SEC / NS100PERSEC; + else + start_time = (p->start_time - to_time_t (&stodi.BootTime)) * CLOCKS_PER_SEC; /* The BasePriority returned to a 32 bit process under WOW64 is apparently broken, for 32 and 64 bit target processes. 64 bit processes get the correct base priority, even for 32 bit processes. */ From 24f9cb015ea011b43f9c4b865c98b61be731487f Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Tue, 12 Mar 2019 11:41:35 +0100 Subject: [PATCH 282/475] Cygwin: fork/exec: Allow all users PROCESS_QUERY_LIMITED_INFORMATION Create process with standard rights, plus PROCESS_QUERY_LIMITED_INFORMATION for authenticated users. This allows to fetch basic process information and thus /proc//stat to succeed on foreign processes. While at it, fix formatting in CreateProcess calls. Signed-off-by: Corinna Vinschen --- winsup/cygwin/fork.cc | 17 ++++++++++++----- winsup/cygwin/spawn.cc | 30 ++++++++++++++++++------------ 2 files changed, 30 insertions(+), 17 deletions(-) diff --git a/winsup/cygwin/fork.cc b/winsup/cygwin/fork.cc index 7ae0404f4..74ee9acf4 100644 --- a/winsup/cygwin/fork.cc +++ b/winsup/cygwin/fork.cc @@ -318,6 +318,13 @@ frok::parent (volatile char * volatile stack_here) ch.silentfail (!*with_forkables); /* fail silently without forkables */ + tmp_pathbuf tp; + PSECURITY_ATTRIBUTES sa = (PSECURITY_ATTRIBUTES) tp.w_get (); + if (!sec_user_nih (sa, cygheap->user.saved_sid (), + well_known_authenticated_users_sid, + PROCESS_QUERY_LIMITED_INFORMATION)) + sa = &sec_none_nih; + while (1) { PCWCHAR forking_progname = NULL; @@ -339,12 +346,12 @@ frok::parent (volatile char * volatile stack_here) sure child stack is allocated in the same memory location as in parent. */ - &sec_none_nih, - &sec_none_nih, - TRUE, /* inherit handles from parent */ + sa, + sa, + TRUE, /* inherit handles */ c_flags, - NULL, /* environment filled in later */ - 0, /* use current drive/directory */ + NULL, /* environ filled in later */ + 0, /* use cwd */ &si, &pi); diff --git a/winsup/cygwin/spawn.cc b/winsup/cygwin/spawn.cc index ebc34d105..4e549f7d4 100644 --- a/winsup/cygwin/spawn.cc +++ b/winsup/cygwin/spawn.cc @@ -566,6 +566,12 @@ child_info_spawn::worker (const char *prog_arg, const char *const *argv, SetHandleInformation (my_wr_proc_pipe, HANDLE_FLAG_INHERIT, 0); parent_winpid = GetCurrentProcessId (); + PSECURITY_ATTRIBUTES sa = (PSECURITY_ATTRIBUTES) tp.w_get (); + if (!sec_user_nih (sa, cygheap->user.sid (), + well_known_authenticated_users_sid, + PROCESS_QUERY_LIMITED_INFORMATION)) + sa = &sec_none_nih; + loop: /* When ruid != euid we create the new process under the current original account and impersonate in child, this way maintaining the different @@ -586,13 +592,13 @@ child_info_spawn::worker (const char *prog_arg, const char *const *argv, && !::cygheap->user.groups.issetgroups () && !::cygheap->user.setuid_to_restricted)) { - rc = CreateProcessW (runpath, /* image name - with full path */ - cmd.wcs (wcmd),/* what was passed to exec */ - &sec_none_nih, /* process security attrs */ - &sec_none_nih, /* thread security attrs */ - TRUE, /* inherit handles from parent */ + rc = CreateProcessW (runpath, /* image name w/ full path */ + cmd.wcs (wcmd), /* what was passed to exec */ + sa, /* process security attrs */ + sa, /* thread security attrs */ + TRUE, /* inherit handles */ c_flags, - envblock, /* environment */ + envblock, /* environment */ NULL, &si, &pi); @@ -640,13 +646,13 @@ child_info_spawn::worker (const char *prog_arg, const char *const *argv, } rc = CreateProcessAsUserW (::cygheap->user.primary_token (), - runpath, /* image name - with full path */ - cmd.wcs (wcmd),/* what was passed to exec */ - &sec_none_nih, /* process security attrs */ - &sec_none_nih, /* thread security attrs */ - TRUE, /* inherit handles from parent */ + runpath, /* image name w/ full path */ + cmd.wcs (wcmd), /* what was passed to exec */ + sa, /* process security attrs */ + sa, /* thread security attrs */ + TRUE, /* inherit handles */ c_flags, - envblock, /* environment */ + envblock, /* environment */ NULL, &si, &pi); From 673a3daa84c33bf95833237e35791c773b25bcd5 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Tue, 12 Mar 2019 11:47:31 +0100 Subject: [PATCH 283/475] Cygwin: add /proc changes to release notes Signed-off-by: Corinna Vinschen --- winsup/cygwin/release/3.0.4 | 3 +++ winsup/doc/new-features.xml | 6 ++++++ 2 files changed, 9 insertions(+) diff --git a/winsup/cygwin/release/3.0.4 b/winsup/cygwin/release/3.0.4 index c545f3e64..e6632f461 100644 --- a/winsup/cygwin/release/3.0.4 +++ b/winsup/cygwin/release/3.0.4 @@ -5,6 +5,9 @@ What's new: What changed: ------------- +- Improve /proc//cmdline and /proc//stat handling to allow + all processes access to basic process information of foreign processes. + Bug Fixes --------- diff --git a/winsup/doc/new-features.xml b/winsup/doc/new-features.xml index 5bb410955..e14fbb1e8 100644 --- a/winsup/doc/new-features.xml +++ b/winsup/doc/new-features.xml @@ -111,6 +111,12 @@ default and limited to exes/dlls on the same NTFS partition as the Cygwin installation. For more information and how to enable, please refer to . + + +Improve /proc/<PID>/cmdline and /proc/<PID>/stat handling to allow +all processes access to basic process information of foreign processes. + + From de7f13aa9acec022ad1e4b3f929d4dc982ddf60b Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Tue, 12 Mar 2019 17:09:42 +0100 Subject: [PATCH 284/475] Cygwin: loadavg: improve debugging of load_init When logging in via ssh with an unprivileged account, PdhAddEnglishCounter returns with status 0x800007D0, PDH_CSTATUS_NO_MACHINE. We didn't find any workaround but the changes to improve debugging output may help in future. Using UNICODE instead of ANSI functions is a result of trying to fix this problem. Also drop the prototype workaround for PdhAddEnglishCounterA. It's not required anymore since Mingw-w64's pdh.h catched up. Signed-off-by: Corinna Vinschen --- winsup/cygwin/autoload.cc | 4 ++-- winsup/cygwin/loadavg.cc | 40 ++++++++++++++++++++++++--------------- 2 files changed, 27 insertions(+), 17 deletions(-) diff --git a/winsup/cygwin/autoload.cc b/winsup/cygwin/autoload.cc index 056fac7dc..c4d91611e 100644 --- a/winsup/cygwin/autoload.cc +++ b/winsup/cygwin/autoload.cc @@ -755,8 +755,8 @@ LoadDLLfunc (WSASocketW, 24, ws2_32) // LoadDLLfunc (WSAStartup, 8, ws2_32) LoadDLLfunc (WSAWaitForMultipleEvents, 20, ws2_32) -LoadDLLfunc (PdhAddEnglishCounterA, 16, pdh) +LoadDLLfunc (PdhAddEnglishCounterW, 16, pdh) LoadDLLfunc (PdhCollectQueryData, 4, pdh) LoadDLLfunc (PdhGetFormattedCounterValue, 16, pdh) -LoadDLLfunc (PdhOpenQueryA, 12, pdh) +LoadDLLfunc (PdhOpenQueryW, 12, pdh) } diff --git a/winsup/cygwin/loadavg.cc b/winsup/cygwin/loadavg.cc index bef80e13a..127591a2e 100644 --- a/winsup/cygwin/loadavg.cc +++ b/winsup/cygwin/loadavg.cc @@ -39,14 +39,7 @@ #include #include #include - -/* Prototype for PdhAddEnglishCounterA in pdh.h under _WIN32_WINNT >= 0x0600 is - missing WINAPI */ -#undef _WIN32_WINNT #include -extern "C" -PDH_FUNCTION PdhAddEnglishCounterA(PDH_HQUERY hQuery, LPCSTR szFullCounterPath, - DWORD_PTR dwUserData, PDH_HCOUNTER *phCounter); static PDH_HQUERY query; static PDH_HCOUNTER counter1; @@ -61,14 +54,31 @@ static bool load_init (void) if (!tried) { tried = true; - if (!((PdhOpenQueryA (NULL, 0, &query) == ERROR_SUCCESS) && - (PdhAddEnglishCounterA (query, "\\Processor(_Total)\\% Processor Time", - 0, &counter1) == ERROR_SUCCESS) && - (PdhAddEnglishCounterA (query, "\\System\\Processor Queue Length", - 0, &counter2) == ERROR_SUCCESS))) { - debug_printf("loadavg PDH initialization failed\n"); - return false; - } + PDH_STATUS status; + + status = PdhOpenQueryW (NULL, 0, &query); + if (status != STATUS_SUCCESS) + { + debug_printf ("PdhOpenQueryW, status %y", status); + return false; + } + status = PdhAddEnglishCounterW (query, + L"\\Processor(_Total)\\% Processor Time", + 0, &counter1); + if (status != STATUS_SUCCESS) + { + debug_printf ("PdhAddEnglishCounterW(time), status %y", status); + return false; + } + status = PdhAddEnglishCounterW (query, + L"\\System\\Processor Queue Length", + 0, &counter2); + + if (status != STATUS_SUCCESS) + { + debug_printf ("PdhAddEnglishCounterW(queue length), status %y", status); + return false; + } mutex = CreateMutex(&sec_all_nih, FALSE, "cyg.loadavg.mutex"); if (!mutex) { From a2693428b97b43fd2e39982bb9b7b7eb39e73141 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Tue, 12 Mar 2019 20:11:38 +0100 Subject: [PATCH 285/475] Cygwin: ntdll.h: Add SystemProcessIdInformation Add SystemProcessIdInformation to SYSTEM_INFORMATION_CLASS and define struct _SYSTEM_PROCESS_ID_INFORMATION. Signed-off-by: Corinna Vinschen --- winsup/cygwin/ntdll.h | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/winsup/cygwin/ntdll.h b/winsup/cygwin/ntdll.h index 872cb3170..b41b99b4b 100644 --- a/winsup/cygwin/ntdll.h +++ b/winsup/cygwin/ntdll.h @@ -582,6 +582,7 @@ typedef enum _SYSTEM_INFORMATION_CLASS SystemProcessorPerformanceInformation = 8, SystemHandleInformation = 16, SystemPagefileInformation = 18, + SystemProcessIdInformation = 0x58, /* There are a lot more of these... */ } SYSTEM_INFORMATION_CLASS; @@ -723,15 +724,6 @@ typedef struct _SYSTEM_PROCESS_INFORMATION SYSTEM_THREADS Threads[1]; } SYSTEM_PROCESS_INFORMATION, *PSYSTEM_PROCESS_INFORMATION; -typedef struct _IO_STATUS_BLOCK -{ - union { - NTSTATUS Status; - PVOID Pointer; - }; - ULONG_PTR Information; -} IO_STATUS_BLOCK, *PIO_STATUS_BLOCK; - typedef struct _SYSTEM_PERFORMANCE_INFORMATION { LARGE_INTEGER IdleTime; @@ -818,6 +810,12 @@ typedef struct _SYSTEM_TIMEOFDAY_INFORMATION BYTE Reserved1[20]; /* Per MSDN. Always 0. */ } SYSTEM_TIMEOFDAY_INFORMATION, *PSYSTEM_TIMEOFDAY_INFORMATION; +typedef struct _SYSTEM_PROCESS_ID_INFORMATION +{ + PVOID ProcessId; + UNICODE_STRING ImageName; +} SYSTEM_PROCESS_ID_INFORMATION, *PSYSTEM_PROCESS_ID_INFORMATION; + typedef enum _PROCESSINFOCLASS { ProcessBasicInformation = 0, @@ -1241,6 +1239,15 @@ typedef struct _FILE_MAILSLOT_SET_INFORMATION LARGE_INTEGER ReadTimeout; } FILE_MAILSLOT_SET_INFORMATION, *PFILE_MAILSLOT_SET_INFORMATION; +typedef struct _IO_STATUS_BLOCK +{ + union { + NTSTATUS Status; + PVOID Pointer; + }; + ULONG_PTR Information; +} IO_STATUS_BLOCK, *PIO_STATUS_BLOCK; + typedef VOID NTAPI (*PIO_APC_ROUTINE)(PVOID, PIO_STATUS_BLOCK, ULONG); typedef struct _EVENT_BASIC_INFORMATION From 37a046181e92cd358adabd154b630bf76fe0bf2c Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Tue, 12 Mar 2019 20:55:24 +0100 Subject: [PATCH 286/475] Cygwin: ps: show *all* processes in ps -W output There's a long-standing bug in ps -W. It only shows processes which ps can open with PROCESS_QUERY_LIMITED_INFORMATION permissions. However, that fails for a lot of system processes. Due to that, output is basically restricted to processes in the same session, as well as Cygwin processes... which isn't *quite* what ps -W was supposed to do. Basically we only need to open the process to fetch the image name. If that fails, utilize the undocumented SystemProcessIdInformation info class introduced with Windows Vista, which allows to fetch the image name by specifying the PID. Restructure the code a bit. Signed-off-by: Corinna Vinschen --- winsup/utils/ps.cc | 83 ++++++++++++++++++++++++++++------------------ 1 file changed, 51 insertions(+), 32 deletions(-) diff --git a/winsup/utils/ps.cc b/winsup/utils/ps.cc index ad46ab758..c655d74e5 100644 --- a/winsup/utils/ps.cc +++ b/winsup/utils/ps.cc @@ -26,7 +26,7 @@ details. */ /* Maximum possible path length under NT. There's no official define for that value. Note that PATH_MAX is only 4K. */ -#define NT_MAX_PATH 32768 +#define NT_MAX_PATH 32767 static char *prog_name; @@ -140,7 +140,13 @@ print_version () strrchr (__DATE__, ' ') + 1); } -char unicode_buf[sizeof (UNICODE_STRING) + NT_MAX_PATH]; +struct +{ + SYSTEM_PROCESS_ID_INFORMATION spii; + WCHAR buf[NT_MAX_PATH + 1]; +} ucbuf; + +char pname[NT_MAX_PATH + sizeof (" ") + 1]; int main (int argc, char *argv[]) @@ -158,7 +164,6 @@ main (int argc, char *argv[]) const char *ltitle = " PID PPID PGID WINPID TTY UID STIME COMMAND\n"; const char *lfmt = "%c %7d %7d %7d %10u %4s %8u %8s %s\n"; char ch; - PUNICODE_STRING uni = (PUNICODE_STRING) unicode_buf; void *drive_map = NULL; aflag = lflag = fflag = sflag = 0; @@ -288,7 +293,6 @@ main (int argc, char *argv[]) /* Maximum possible path length under NT. There's no official define for that value. */ - char pname[NT_MAX_PATH + sizeof (" ")]; if (p->ppid) { char *s; @@ -308,45 +312,60 @@ main (int argc, char *argv[]) h = OpenProcess (proc_access, FALSE, p->dwProcessId); if (!h) - continue; + { + ucbuf.spii.ProcessId = (PVOID) (ULONG_PTR) p->dwProcessId; + ucbuf.spii.ImageName.Length = 0; + ucbuf.spii.ImageName.MaximumLength = NT_MAX_PATH * sizeof (WCHAR); + ucbuf.spii.ImageName.Buffer = ucbuf.buf; + status = NtQuerySystemInformation (SystemProcessIdInformation, + &ucbuf.spii, sizeof ucbuf.spii, NULL); + if (NT_SUCCESS (status)) + { + if (ucbuf.spii.ImageName.Length) + ucbuf.spii.ImageName.Buffer[ucbuf.spii.ImageName.Length + / sizeof (WCHAR)] = L'\0'; + win32path = ucbuf.spii.ImageName.Buffer; + } + } /* We use NtQueryInformationProcess in the first place, because GetModuleFileNameEx does not work under WOW64 when trying to fetch module names of 64 bit processes. */ - if (!(proc_access & PROCESS_VM_READ)) + else if (!(proc_access & PROCESS_VM_READ)) { - status = NtQueryInformationProcess (h, ProcessImageFileName, uni, - sizeof unicode_buf, NULL); + status = NtQueryInformationProcess (h, ProcessImageFileName, + &ucbuf.spii.ImageName, + sizeof ucbuf - sizeof (PVOID), + NULL); if (NT_SUCCESS (status)) { - /* NtQueryInformationProcess returns a native NT device path. - Call CW_MAP_DRIVE_MAP to convert the path to an ordinary - Win32 path. The returned pointer is a pointer into the - incoming buffer given as third argument. It's expected - to be big enough, which we made sure by defining - unicode_buf to have enough space for a maximum sized - UNICODE_STRING. */ - if (uni->Length == 0) /* System process */ - win32path = (wchar_t *) L"System"; - else - { - uni->Buffer[uni->Length / sizeof (WCHAR)] = L'\0'; - win32path = (wchar_t *) cygwin_internal (CW_MAP_DRIVE_MAP, - drive_map, - uni->Buffer); - } + if (ucbuf.spii.ImageName.Length) + ucbuf.spii.ImageName.Buffer[ucbuf.spii.ImageName.Length / sizeof (WCHAR)] = L'\0'; + win32path = ucbuf.spii.ImageName.Buffer; } } - else if (GetModuleFileNameExW (h, NULL, (PWCHAR) unicode_buf, - NT_MAX_PATH)) - win32path = (wchar_t *) unicode_buf; + else if (GetModuleFileNameExW (h, NULL, ucbuf.buf, + NT_MAX_PATH + 1)) + win32path = ucbuf.buf; if (win32path) - wcstombs (pname, win32path, sizeof pname); + { + /* Call CW_MAP_DRIVE_MAP to convert native NT device paths to + an ordinary Win32 path. The returned pointer is a pointer + into the incoming buffer given as third argument. It's + expected to be big enough. */ + if (win32path[0] == L'\\') + win32path = (wchar_t *) cygwin_internal (CW_MAP_DRIVE_MAP, + drive_map, win32path); + wcstombs (pname, win32path, sizeof pname); + } else - strcpy (pname, "*** unknown ***"); + strcpy (pname, p->dwProcessId == 4 ? "System" : "*** unknown ***"); FILETIME ct, et, kt, ut; - if (GetProcessTimes (h, &ct, &et, &kt, &ut)) - p->start_time = to_time_t (&ct); - CloseHandle (h); + if (h) + { + if (GetProcessTimes (h, &ct, &et, &kt, &ut)) + p->start_time = to_time_t (&ct); + CloseHandle (h); + } } char uname[128]; From 1def2148d25fec8a150e5eac873d8ef4a0c71a50 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Tue, 12 Mar 2019 21:21:13 +0100 Subject: [PATCH 287/475] Cygwin: ps: simplify code Always use NtQuerySystemInformation(SystemProcessIdInformation). This drops two code paths calling NtQueryInformationProcess or GetModuleFileNameExW and only requires to open the process to fetch system time info. Signed-off-by: Corinna Vinschen --- winsup/utils/ps.cc | 65 +++++++++++++--------------------------------- 1 file changed, 18 insertions(+), 47 deletions(-) diff --git a/winsup/utils/ps.cc b/winsup/utils/ps.cc index c655d74e5..4fce3e0b3 100644 --- a/winsup/utils/ps.cc +++ b/winsup/utils/ps.cc @@ -155,7 +155,6 @@ main (int argc, char *argv[]) int aflag, lflag, fflag, sflag, proc_id; uid_t uid; bool found_proc_id = true; - DWORD proc_access = PROCESS_QUERY_LIMITED_INFORMATION; cygwin_getinfo_types query = CW_GETPINFO; const char *dtitle = " PID TTY STIME COMMAND\n"; const char *dfmt = "%7d%4s%10s %s\n"; @@ -257,12 +256,6 @@ main (int argc, char *argv[]) } drive_map = (void *) cygwin_internal (CW_ALLOC_DRIVE_MAP); - /* Check old Cygwin version. */ - if (drive_map == (void *) -1) - drive_map = NULL; - /* Allow fallback to GetModuleFileNameEx. */ - if (!drive_map) - proc_access = PROCESS_QUERY_INFORMATION | PROCESS_VM_READ; } for (int pid = 0; @@ -291,8 +284,6 @@ main (int argc, char *argv[]) else if (p->process_state & PID_TTYOU) status = 'O'; - /* Maximum possible path length under NT. There's no official define - for that value. */ if (p->ppid) { char *s; @@ -309,49 +300,27 @@ main (int argc, char *argv[]) HANDLE h; NTSTATUS status; wchar_t *win32path = NULL; + FILETIME ct, et, kt, ut; - h = OpenProcess (proc_access, FALSE, p->dwProcessId); - if (!h) + ucbuf.spii.ProcessId = (PVOID) (ULONG_PTR) p->dwProcessId; + ucbuf.spii.ImageName.Length = 0; + ucbuf.spii.ImageName.MaximumLength = NT_MAX_PATH * sizeof (WCHAR); + ucbuf.spii.ImageName.Buffer = ucbuf.buf; + status = NtQuerySystemInformation (SystemProcessIdInformation, + &ucbuf.spii, sizeof ucbuf.spii, + NULL); + if (NT_SUCCESS (status)) { - ucbuf.spii.ProcessId = (PVOID) (ULONG_PTR) p->dwProcessId; - ucbuf.spii.ImageName.Length = 0; - ucbuf.spii.ImageName.MaximumLength = NT_MAX_PATH * sizeof (WCHAR); - ucbuf.spii.ImageName.Buffer = ucbuf.buf; - status = NtQuerySystemInformation (SystemProcessIdInformation, - &ucbuf.spii, sizeof ucbuf.spii, NULL); - if (NT_SUCCESS (status)) - { - if (ucbuf.spii.ImageName.Length) - ucbuf.spii.ImageName.Buffer[ucbuf.spii.ImageName.Length - / sizeof (WCHAR)] = L'\0'; - win32path = ucbuf.spii.ImageName.Buffer; - } + if (ucbuf.spii.ImageName.Length) + ucbuf.spii.ImageName.Buffer[ucbuf.spii.ImageName.Length + / sizeof (WCHAR)] = L'\0'; + win32path = ucbuf.spii.ImageName.Buffer; } - /* We use NtQueryInformationProcess in the first place, because - GetModuleFileNameEx does not work under WOW64 when trying - to fetch module names of 64 bit processes. */ - else if (!(proc_access & PROCESS_VM_READ)) - { - status = NtQueryInformationProcess (h, ProcessImageFileName, - &ucbuf.spii.ImageName, - sizeof ucbuf - sizeof (PVOID), - NULL); - if (NT_SUCCESS (status)) - { - if (ucbuf.spii.ImageName.Length) - ucbuf.spii.ImageName.Buffer[ucbuf.spii.ImageName.Length / sizeof (WCHAR)] = L'\0'; - win32path = ucbuf.spii.ImageName.Buffer; - } - } - else if (GetModuleFileNameExW (h, NULL, ucbuf.buf, - NT_MAX_PATH + 1)) - win32path = ucbuf.buf; if (win32path) { /* Call CW_MAP_DRIVE_MAP to convert native NT device paths to - an ordinary Win32 path. The returned pointer is a pointer - into the incoming buffer given as third argument. It's - expected to be big enough. */ + an ordinary Win32 path. The returned pointer points into + the incoming buffer given as third argument. */ if (win32path[0] == L'\\') win32path = (wchar_t *) cygwin_internal (CW_MAP_DRIVE_MAP, drive_map, win32path); @@ -359,7 +328,9 @@ main (int argc, char *argv[]) } else strcpy (pname, p->dwProcessId == 4 ? "System" : "*** unknown ***"); - FILETIME ct, et, kt, ut; + + h = OpenProcess (PROCESS_QUERY_LIMITED_INFORMATION, FALSE, + p->dwProcessId); if (h) { if (GetProcessTimes (h, &ct, &et, &kt, &ut)) From 111b34bb1b1718e815ea95d19630cea4cab1ddf5 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Wed, 13 Mar 2019 11:26:58 +0100 Subject: [PATCH 288/475] Cygwin: proc: add missing LF to /proc//stat output Signed-off-by: Corinna Vinschen --- winsup/cygwin/fhandler_process.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/winsup/cygwin/fhandler_process.cc b/winsup/cygwin/fhandler_process.cc index 31cd50700..44410b223 100644 --- a/winsup/cygwin/fhandler_process.cc +++ b/winsup/cygwin/fhandler_process.cc @@ -1160,7 +1160,7 @@ format_process_stat (void *data, char *&destbuf) "%u %lu %lu %u %u %lu %lu " "%U %U %d %d %d %d " "%U %lu " - "%ld %lu", + "%ld %lu\n", p->pid, cmd, state, p->ppid, p->pgid, p->sid, p->ctty, -1, 0, fault_count, fault_count, 0, 0, utime, stime, From 004d8adfa27232067aa67c2eb9aba0d29a11b2fd Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Wed, 13 Mar 2019 12:06:48 +0100 Subject: [PATCH 289/475] Cygwin: acls: allow converting empty acl to text Signed-off-by: Corinna Vinschen --- winsup/cygwin/release/3.0.4 | 3 +++ winsup/cygwin/sec_acl.cc | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/winsup/cygwin/release/3.0.4 b/winsup/cygwin/release/3.0.4 index e6632f461..eeed28396 100644 --- a/winsup/cygwin/release/3.0.4 +++ b/winsup/cygwin/release/3.0.4 @@ -14,3 +14,6 @@ Bug Fixes - Fix access to process list Addresses: https://cygwin.com/ml/cygwin/2019-03/msg00253.html + +- Fix acl_to_text/acl_to_any_text returning EINVAL on empty acl + Addresses: https://cygwin.com/ml/cygwin/2019-03/msg00157.html diff --git a/winsup/cygwin/sec_acl.cc b/winsup/cygwin/sec_acl.cc index ce7910ed8..933bfa69d 100644 --- a/winsup/cygwin/sec_acl.cc +++ b/winsup/cygwin/sec_acl.cc @@ -1638,8 +1638,8 @@ char * __acltotext (aclent_t *aclbufp, int aclcnt, const char *prefix, char separator, int options) { - if (!aclbufp || aclcnt < 1 || aclcnt > MAX_ACL_ENTRIES - || aclsort32 (aclcnt, 0, aclbufp)) + if (!aclbufp || aclcnt < 0 || aclcnt > MAX_ACL_ENTRIES + || (aclcnt > 0 && aclsort32 (aclcnt, 0, aclbufp))) { set_errno (EINVAL); return NULL; From 1cff36cdd70eccbddc08432e721782b8a6e624ad Mon Sep 17 00:00:00 2001 From: Jeff Johnston Date: Thu, 14 Mar 2019 10:23:25 -0400 Subject: [PATCH 290/475] Add semihosting docs for nios2 and m68k Author: Sandra Loosemore Date: Wed Mar 13 20:22:16 2019 -0700 Add semihosting documentation for nios2 and m68k. QEMU maintainers have asked for a specification of the nios2 semihosting interface. Since it's essentially a copy of the m68k implementation, this patch adds a document for that target as well. --- libgloss/m68k/m68k-semi.txt | 214 ++++++++++++++++++++++++++++++++++ libgloss/nios2/nios2-semi.txt | 197 +++++++++++++++++++++++++++++++ 2 files changed, 411 insertions(+) create mode 100644 libgloss/m68k/m68k-semi.txt create mode 100644 libgloss/nios2/nios2-semi.txt diff --git a/libgloss/m68k/m68k-semi.txt b/libgloss/m68k/m68k-semi.txt new file mode 100644 index 000000000..50520c152 --- /dev/null +++ b/libgloss/m68k/m68k-semi.txt @@ -0,0 +1,214 @@ +Copyright (c) 2006 CodeSourcery Inc +Copyright (c) 2019 Mentor Graphics + +The authors hereby grant permission to use, copy, modify, distribute, +and license this software and its documentation for any purpose, provided +that existing copyright notices are retained in all copies and that this +notice is included verbatim in any distributions. No written agreement, +license, or royalty fee is required for any of the authorized uses. +Modifications to this software may be copyrighted by their authors +and need not follow the licensing terms described here, provided that +the new terms are clearly indicated on the first page of each file where +they apply. + + +m68k Semihosting Protocol +------------------------- + +The instruction used to trigger a semihosting request depends on the +m68k processor variant. On ColdFire, "halt" is used; on other processors +(which don't implement "halt"), "bkpt #0" may be used. + +Additionally, a special code sequence is used to distinguish +semihosting requests from other uses of the instruction used to +trigger it. The semihosting instruction is immediately preceded by a +"nop" aligned to a 4-byte boundary, and followed by an invalid sentinel +instruction 0x4e7bf000 ("movec %sp,0"). The debug agent handling the +semihosting request must adjust the program counter to skip over the +sentinel instruction before continuing execution. + +Registers d0 and d1 are used to pass parameters to the semihosting call. +d0 contains a request code. d1 is typically a pointer to a 4-longword +parameter block, except for the exit and simulator initialization operations +where it is an immediate integer value. + +The result of the operation is returned in the first word of the +parameter block. The second word is used to return an errno value, +encoded per the "Errno Values" section of the RSP documentation in the +GDB User Manual. + +The supported d0 request codes are: + +#define HOSTED_EXIT 0 + + Terminate program execution; send a 'W' stop reply to GDB. + + d1 contains the exit code, as an immediate integer rather than indirectly + in a parameter block. This semihosting request isn't expected to return. + +#define HOSTED_INIT_SIM 1 + + Do simulator initialization, such as allocation of memory for the + stack and heap. This semihosting request may be triggered from + startup code (crt0.S). + + On entry to the semihosting request, d1 contains the default initial + stack pointer as an immediate value, typically the high end of + memory defined by the linker script. If the simulator needs to + dynamically allocate memory for the stack, it should set both d1 and + sp (a7) to the new stack pointer value. + +#define HOSTED_OPEN 2 + + Open file; 'Fopen' GDB fileio request. + + d1 points to a parameter block containing: + [0] pointer to filename + [1] filename length + [2] open flags, encoded per the GDB RSP documentation + [3] mode, encoded per the GDB RSP documentation + + Return values in parameter block: + [0] file descriptor or -1 on error + [1] errno, encoded per the GDB RSP documentation + +#define HOSTED_CLOSE 3 + + Close file; 'Fclose' GDB fileio request. + + d1 points to a parameter block containing: + [0] file descriptor + + Return values in parameter block: + [0] return status + [1] errno, encoded per the GDB RSP documentation + +#define HOSTED_READ 4 + + Read from file; 'Fread' GDB fileio request. + + d1 points to a parameter block containing: + [0] file descriptor + [1] pointer to buffer + [2] buffer size + + Return values in parameter block: + [0] number of bytes read + [1] errno, encoded per the GDB RSP documentation + +#define HOSTED_WRITE 5 + + Write to file; 'Fwrite' GDB fileio request. + + d1 points to a parameter block containing: + [0] file descriptor + [1] pointer to buffer + [2] byte count + + Return values in parameter block: + [0] number of bytes written + [1] errno, encoded per the GDB RSP documentation + +#define HOSTED_LSEEK 6 + + File seek; 'Flseek' GDB fileio request. + + d1 points to a parameter block containing: + [0] file descriptor + [1] high word of 64-bit offset + [2] low word of 64-bit offset + [3] seek flag, encoded per the GDB RSP documentation + + Return values in parameter block: + [0] high word of 64-bit result + [1] low word of 64-bit result + [2] errno, encoded per the GDB RSP documentation + +#define HOSTED_RENAME 7 + + File rename; 'Frename' GDB fileio request. + + d1 points to a parameter block containing: + [0] oldname pointer + [1] oldname length + [2] newname pointer + [3] newname length + + Return values in parameter block: + [0] return status + [1] errno, encoded per the GDB RSP documentation + +#define HOSTED_UNLINK 8 + + File unlink/delete; 'Funlink' GDB fileio request. + + d1 points to a parameter block containing: + [0] filename pointer + [1] filename length + + Return values in parameter block: + [0] return status + [1] errno, encoded per the GDB RSP documentation + +#define HOSTED_STAT 9 + + File information; 'Fstat' GDB fileio request. + + d1 points to a parameter block containing: + [0] filename pointer + [1] filename length + [2] pointer to stat buf, using the structure definition in the GDB RSP + documentation + + Return values in parameter block: + [0] return status + [1] errno, encoded per the GDB RSP documentation + +#define HOSTED_FSTAT 10 + + File information; 'Ffstat' GDB fileio request. + + d1 points to a parameter block containing: + [0] file descriptor + [1] pointer to stat buf, using the structure definition in the GDB RSP + documentation + + Return values in parameter block: + [0] return status + [1] errno, encoded per the GDB RSP documentation + +#define HOSTED_GETTIMEOFDAY 11 + + Get current time; 'Fgettimeofday' GDB fileio request. + + d1 points to a parameter block containing: + [0] timeval pointer, using the structure definition in the GDB RSP + documentation + + Return values in parameter block: + [0] return status + [1] errno, encoded per the GDB RSP documentation + +#define HOSTED_ISATTY 12 + + Return true if the file descriptor is the GDB console; 'Fisatty' GDB fileio + request. + + d1 points to a parameter block containing: + [0] file descriptor + + Return values in parameter block: + [0] return status + [1] errno, encoded per the GDB RSP documentation + +#define HOSTED_SYSTEM 13 + + System call; 'Fsystem' GDB fileio request. + + d1 points to a parameter block containing: + [0] command pointer + [1] command length + + Return values in parameter block: + [0] return status + [1] errno, encoded per the GDB RSP documentation diff --git a/libgloss/nios2/nios2-semi.txt b/libgloss/nios2/nios2-semi.txt new file mode 100644 index 000000000..ded3a093c --- /dev/null +++ b/libgloss/nios2/nios2-semi.txt @@ -0,0 +1,197 @@ +Copyright (c) 2006 CodeSourcery Inc +Copyright (c) 2018, 2019 Mentor Graphics + +The authors hereby grant permission to use, copy, modify, distribute, +and license this software and its documentation for any purpose, provided +that existing copyright notices are retained in all copies and that this +notice is included verbatim in any distributions. No written agreement, +license, or royalty fee is required for any of the authorized uses. +Modifications to this software may be copyrighted by their authors +and need not follow the licensing terms described here, provided that +the new terms are clearly indicated on the first page of each file where +they apply. + + +Nios II Semihosting Protocol +---------------------------- + +The runtime (libgloss) indicates a semihosting request to the debug +agent by issuing a "break 1" instruction. r4 and r5 are used to pass +parameters per the normal C ABI on nios2. + +r4 contains a request code. r5 is typically a pointer to a 4-word +parameter block, except for the exit operation where it is an +immediate integer value. + +The result of the operation is returned in the first word of the +parameter block. The second word is used to return an errno value, +encoded per the "Errno Values" section of the RSP documentation in the +GDB User Manual. + +The supported r4 request codes are: + +#define HOSTED_EXIT 0 + + Terminate program execution; send a 'W' stop reply to GDB. + + r5 contains the exit code, as an immediate integer rather than indirectly + in a parameter block. This semihosting request isn't expected to return. + +#define HOSTED_INIT_SIM 1 + + Reserved/unimplemented. + +#define HOSTED_OPEN 2 + + Open file; 'Fopen' GDB fileio request. + + r5 points to a parameter block containing: + [0] pointer to filename + [1] filename length + [2] open flags, encoded per the GDB RSP documentation + [3] mode, encoded per the GDB RSP documentation + + Return values in parameter block: + [0] file descriptor or -1 on error + [1] errno, encoded per the GDB RSP documentation + +#define HOSTED_CLOSE 3 + + Close file; 'Fclose' GDB fileio request. + + r5 points to a parameter block containing: + [0] file descriptor + + Return values in parameter block: + [0] return status + [1] errno, encoded per the GDB RSP documentation + +#define HOSTED_READ 4 + + Read from file; 'Fread' GDB fileio request. + + r5 points to a parameter block containing: + [0] file descriptor + [1] pointer to buffer + [2] buffer size + + Return values in parameter block: + [0] number of bytes read + [1] errno, encoded per the GDB RSP documentation + +#define HOSTED_WRITE 5 + + Write to file; 'Fwrite' GDB fileio request. + + r5 points to a parameter block containing: + [0] file descriptor + [1] pointer to buffer + [2] byte count + + Return values in parameter block: + [0] number of bytes written + [1] errno, encoded per the GDB RSP documentation + +#define HOSTED_LSEEK 6 + + File seek; 'Flseek' GDB fileio request. + + r5 points to a parameter block containing: + [0] file descriptor + [1] high word of 64-bit offset + [2] low word of 64-bit offset + [3] seek flag, encoded per the GDB RSP documentation + + Return values in parameter block: + [0] high word of 64-bit result + [1] low word of 64-bit result + [2] errno, encoded per the GDB RSP documentation + +#define HOSTED_RENAME 7 + + File rename; 'Frename' GDB fileio request. + + r5 points to a parameter block containing: + [0] oldname pointer + [1] oldname length + [2] newname pointer + [3] newname length + + Return values in parameter block: + [0] return status + [1] errno, encoded per the GDB RSP documentation + +#define HOSTED_UNLINK 8 + + File unlink/delete; 'Funlink' GDB fileio request. + + r5 points to a parameter block containing: + [0] filename pointer + [1] filename length + + Return values in parameter block: + [0] return status + [1] errno, encoded per the GDB RSP documentation + +#define HOSTED_STAT 9 + + File information; 'Fstat' GDB fileio request. + + r5 points to a parameter block containing: + [0] filename pointer + [1] filename length + [2] pointer to stat buf, using the structure definition in the GDB RSP + documentation + + Return values in parameter block: + [0] return status + [1] errno, encoded per the GDB RSP documentation + +#define HOSTED_FSTAT 10 + + File information; 'Ffstat' GDB fileio request. + + r5 points to a parameter block containing: + [0] file descriptor + [1] pointer to stat buf, using the structure definition in the GDB RSP + documentation + + Return values in parameter block: + [0] return status + [1] errno, encoded per the GDB RSP documentation + +#define HOSTED_GETTIMEOFDAY 11 + + Get current time; 'Fgettimeofday' GDB fileio request. + + r5 points to a parameter block containing: + [0] timeval pointer, using the structure definition in the GDB RSP + documentation + + Return values in parameter block: + [0] return status + [1] errno, encoded per the GDB RSP documentation + +#define HOSTED_ISATTY 12 + + Return true if the file descriptor is the GDB console; 'Fisatty' GDB fileio + request. + + r5 points to a parameter block containing: + [0] file descriptor + + Return values in parameter block: + [0] return status + [1] errno, encoded per the GDB RSP documentation + +#define HOSTED_SYSTEM 13 + + System call; 'Fsystem' GDB fileio request. + + r5 points to a parameter block containing: + [0] command pointer + [1] command length + + Return values in parameter block: + [0] return status + [1] errno, encoded per the GDB RSP documentation From df960cb954aa6edbb320cf2b2cb8eb65a2b41a80 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Mon, 18 Mar 2019 11:29:00 +0100 Subject: [PATCH 291/475] Cygwin: bump version to 3.0.5 Signed-off-by: Corinna Vinschen --- winsup/cygwin/include/cygwin/version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/winsup/cygwin/include/cygwin/version.h b/winsup/cygwin/include/cygwin/version.h index da134be2d..0ce7e10da 100644 --- a/winsup/cygwin/include/cygwin/version.h +++ b/winsup/cygwin/include/cygwin/version.h @@ -11,7 +11,7 @@ details. */ changes to the DLL and is mainly informative in nature. */ #define CYGWIN_VERSION_DLL_MAJOR 3000 -#define CYGWIN_VERSION_DLL_MINOR 4 +#define CYGWIN_VERSION_DLL_MINOR 5 /* Major numbers before CYGWIN_VERSION_DLL_EPOCH are incompatible. */ From 38322b9bf64bcdee8025edbaacf93a6ba9559b5e Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Mon, 18 Mar 2019 11:34:00 +0100 Subject: [PATCH 292/475] Cygwin: proc: fix /proc/version output after uname change 3.0.0 changed uname but missed to align /proc/version which then used the old uname function on the new uname struct. Signed-off-by: Corinna Vinschen --- winsup/cygwin/fhandler_proc.cc | 4 +++- winsup/cygwin/release/3.0.5 | 13 +++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 winsup/cygwin/release/3.0.5 diff --git a/winsup/cygwin/fhandler_proc.cc b/winsup/cygwin/fhandler_proc.cc index cda2f72a2..a6a0b683c 100644 --- a/winsup/cygwin/fhandler_proc.cc +++ b/winsup/cygwin/fhandler_proc.cc @@ -405,6 +405,8 @@ fhandler_proc::fill_filebuf () return false; } +extern "C" int uname_x (struct utsname *); + static off_t format_proc_version (void *, char *&destbuf) { @@ -413,7 +415,7 @@ format_proc_version (void *, char *&destbuf) char *bufptr = buf; struct utsname uts_name; - uname (&uts_name); + uname_x (&uts_name); bufptr += __small_sprintf (bufptr, "%s version %s (%s@%s) (%s) %s\n", uts_name.sysname, uts_name.release, USERNAME, HOSTNAME, GCC_VERSION, uts_name.version); diff --git a/winsup/cygwin/release/3.0.5 b/winsup/cygwin/release/3.0.5 new file mode 100644 index 000000000..62c8cf5ca --- /dev/null +++ b/winsup/cygwin/release/3.0.5 @@ -0,0 +1,13 @@ +What's new: +----------- + + +What changed: +------------- + + +Bug Fixes +--------- + +- Fix /proc/version after uname change + Addresses: https://cygwin.com/ml/cygwin/2019-03/msg00467.html From 62c66a39bdcb64c74cdd001146b1d7e1e50c687d Mon Sep 17 00:00:00 2001 From: Andrew Stubbs Date: Mon, 18 Mar 2019 16:18:09 +0000 Subject: [PATCH 293/475] AMD GCN: Implement circular buffering. The GCN port outputs stdout and stderr via a shared-memory interface. Previously the buffer was limited to 1000 write operations, which was enough for testing purposes, but easy to exhaust. This patch implements a new circular buffering system allowing a greater amount of output. The interface must allow hundreds of hardware threads to output simultaneously. The new limit is UINT32_MAX write operations. Unfortunately, there's no way to tell if the host side has also been updated. This code will misbehave unless the gcn-run from GCC is also updated (although it's fine the other way around), but that patch has already been committed. OK? Andrew Stubbs Mentor Graphics / CodeSourcery --- newlib/libc/sys/amdgcn/write.c | 55 +++++++++++++++++++++++----------- 1 file changed, 38 insertions(+), 17 deletions(-) diff --git a/newlib/libc/sys/amdgcn/write.c b/newlib/libc/sys/amdgcn/write.c index ce5bd360c..9c0d2a968 100644 --- a/newlib/libc/sys/amdgcn/write.c +++ b/newlib/libc/sys/amdgcn/write.c @@ -26,10 +26,14 @@ The next_output counter must be atomically incremented for each print output. Only when the print data is fully written can the - "written" flag be set. */ + "written" flag be set. + + The buffer is circular; the host increments the consumed counter + and clears the written flag as it goes, opening up slots for reuse. + The counters always use absolute numbers. */ struct output { int return_value; - int next_output; + unsigned int next_output; struct printf_data { int written; char msg[128]; @@ -39,7 +43,8 @@ struct output { double dvalue; char text[128]; }; - } queue[1000]; + } queue[1024]; + unsigned int consumed; }; _READ_WRITE_RETURN_TYPE write (int fd, const void *buf, size_t count) @@ -55,33 +60,49 @@ _READ_WRITE_RETURN_TYPE write (int fd, const void *buf, size_t count) struct output *data = (struct output *)kernargs[2]; /* Each output slot allows 256 bytes, so reserve as many as we need. */ - int slot_count = ((count+1)/256)+1; - int index = __atomic_fetch_add (&data->next_output, slot_count, - __ATOMIC_ACQUIRE); + unsigned int slot_count = ((count+1)/256)+1; + unsigned int index = __atomic_fetch_add (&data->next_output, slot_count, + __ATOMIC_ACQUIRE); + + if ((unsigned int)(index + slot_count) < data->consumed) + { + /* Overflow. */ + errno = EFBIG; + return 0; + } + for (int c = count; - c >= 0 && index < 1000; + c >= 0; buf += 256, c -= 256, index++) { + unsigned int slot = index % 1024; + + /* Spinlock while the host catches up. */ + if (index >= 1024) + while (__atomic_load_n (&data->consumed, __ATOMIC_ACQUIRE) + <= (index - 1024)) + asm ("s_sleep 64"); + if (c < 128) { - memcpy (data->queue[index].msg, buf, c); - data->queue[index].msg[c] = '\0'; - data->queue[index].text[0] = '\0'; + memcpy (data->queue[slot].msg, buf, c); + data->queue[slot].msg[c] = '\0'; + data->queue[slot].text[0] = '\0'; } else if (c < 256) { - memcpy (data->queue[index].msg, buf, 128); - memcpy (data->queue[index].text, buf+128, c-128); - data->queue[index].text[c-128] = '\0'; + memcpy (data->queue[slot].msg, buf, 128); + memcpy (data->queue[slot].text, buf+128, c-128); + data->queue[slot].text[c-128] = '\0'; } else { - memcpy (data->queue[index].msg, buf, 128); - memcpy (data->queue[index].text, buf+128, 128); + memcpy (data->queue[slot].msg, buf, 128); + memcpy (data->queue[slot].text, buf+128, 128); } - data->queue[index].type = 3; /* Raw. */ - __atomic_store_n (&data->queue[index].written, 1, __ATOMIC_RELEASE); + data->queue[slot].type = 3; /* Raw. */ + __atomic_store_n (&data->queue[slot].written, 1, __ATOMIC_RELEASE); } return count; From 10900b98d177c6cf01d294fa187e9d13b053b80c Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Tue, 19 Mar 2019 20:56:11 +0100 Subject: [PATCH 294/475] Cygwin: wcsxfrm_l: Only byte swap if dest size is > 0 commit c0d7d3e1a2fa96db15613cbd68a68c96966bc402 removed the usage of the LCMAP_BYTEREV flag in the call to LCMapStringW to workaround a strange bug in LCMapStringW. This patch didn't take a userspace call of wcsxfrm{_l} with NULL buffer and 0 size to evaluate the required buffer size into account. This introduced a crash trying to byte swap the NULL buffer. This patch fixes that problem. Signed-off-by: Corinna Vinschen --- winsup/cygwin/nlsfuncs.cc | 21 ++++++++++++--------- winsup/cygwin/release/3.0.5 | 3 +++ 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/winsup/cygwin/nlsfuncs.cc b/winsup/cygwin/nlsfuncs.cc index 5bf7d22ac..455afb417 100644 --- a/winsup/cygwin/nlsfuncs.cc +++ b/winsup/cygwin/nlsfuncs.cc @@ -1204,15 +1204,18 @@ wcsxfrm_l (wchar_t *__restrict ws1, const wchar_t *__restrict ws2, size_t wsn, if (ret) { ret /= sizeof (wchar_t); - /* Byte swap the array ourselves here. */ - for (size_t idx = 0; idx < ret; ++idx) - ws1[idx] = __builtin_bswap16 (ws1[idx]); - /* LCMapStringW returns byte count including the terminating NUL char. - wcsxfrm is supposed to return length in wchar_t excluding the NUL. - Since the array is only single byte NUL-terminated yet, make sure - the result is wchar_t-NUL terminated. */ - if (ret < wsn) - ws1[ret] = L'\0'; + if (wsn) + { + /* Byte swap the array ourselves here. */ + for (size_t idx = 0; idx < ret; ++idx) + ws1[idx] = __builtin_bswap16 (ws1[idx]); + /* LCMapStringW returns byte count including the terminating NUL char. + wcsxfrm is supposed to return length in wchar_t excluding the NUL. + Since the array is only single byte NUL-terminated yet, make sure + the result is wchar_t-NUL terminated. */ + if (ret < wsn) + ws1[ret] = L'\0'; + } return ret; } if (GetLastError () != ERROR_INSUFFICIENT_BUFFER) diff --git a/winsup/cygwin/release/3.0.5 b/winsup/cygwin/release/3.0.5 index 62c8cf5ca..a52412cd2 100644 --- a/winsup/cygwin/release/3.0.5 +++ b/winsup/cygwin/release/3.0.5 @@ -11,3 +11,6 @@ Bug Fixes - Fix /proc/version after uname change Addresses: https://cygwin.com/ml/cygwin/2019-03/msg00467.html + +- Fix a crash in wcsxfrm_l if destination size is 0. + Addresses: https://cygwin.com/ml/cygwin/2019-03/msg00492.html From ae3370bb9d1bf1832b19cd6da005f4ec567c57e3 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Sat, 23 Mar 2019 17:50:00 +0100 Subject: [PATCH 295/475] Cygwin: strace: print windows and cygwin pid in event output strace only printed the Windows PID in event output so far. Especially now that Windows and Cygwin PID are decoupled, the strace user might like to see the Cygwin pid in event output as well. However, at process startup, the process might not have a Cygwin PID yet. To mitigate this, always print the Windows PID and only add the Cygwin pid if it exists. Signed-off-by: Corinna Vinschen --- winsup/cygwin/external.cc | 4 +++ winsup/cygwin/include/sys/cygwin.h | 2 ++ winsup/utils/strace.cc | 49 ++++++++++++++++++++++-------- 3 files changed, 42 insertions(+), 13 deletions(-) diff --git a/winsup/cygwin/external.cc b/winsup/cygwin/external.cc index fbb901f3a..94431bb52 100644 --- a/winsup/cygwin/external.cc +++ b/winsup/cygwin/external.cc @@ -331,6 +331,10 @@ cygwin_internal (cygwin_getinfo_types t, ...) } break; + case CW_MAX_CYGWIN_PID: + res = MAX_PID; + break; + case CW_EXTRACT_DOMAIN_AND_USER: { WCHAR nt_domain[MAX_DOMAIN_NAME_LEN + 1]; diff --git a/winsup/cygwin/include/sys/cygwin.h b/winsup/cygwin/include/sys/cygwin.h index afc193fb7..fc91d04ac 100644 --- a/winsup/cygwin/include/sys/cygwin.h +++ b/winsup/cygwin/include/sys/cygwin.h @@ -159,6 +159,7 @@ typedef enum CW_EXCEPTION_RECORD_FROM_SIGINFO_T, CW_CYGHEAP_PROFTHR_ALL, CW_WINPID_TO_CYGWIN_PID, + CW_MAX_CYGWIN_PID, } cygwin_getinfo_types; #define CW_LOCK_PINFO CW_LOCK_PINFO @@ -222,6 +223,7 @@ typedef enum #define CW_EXCEPTION_RECORD_FROM_SIGINFO_T CW_EXCEPTION_RECORD_FROM_SIGINFO_T #define CW_CYGHEAP_PROFTHR_ALL CW_CYGHEAP_PROFTHR_ALL #define CW_WINPID_TO_CYGWIN_PID CW_WINPID_TO_CYGWIN_PID +#define CW_MAX_CYGWIN_PID CW_MAX_CYGWIN_PID /* Token type for CW_SET_EXTERNAL_TOKEN */ enum diff --git a/winsup/utils/strace.cc b/winsup/utils/strace.cc index 21c0835d4..c8b2e2cf5 100644 --- a/winsup/utils/strace.cc +++ b/winsup/utils/strace.cc @@ -672,6 +672,25 @@ GetFileNameFromHandle(HANDLE hFile, WCHAR pszFilename[MAX_PATH+1]) return result; } +static char * +cygwin_pid (DWORD winpid) +{ + static char buf[48]; + static DWORD max_cygpid = 0; + DWORD cygpid; + + if (!max_cygpid) + max_cygpid = (DWORD) cygwin_internal (CW_MAX_CYGWIN_PID); + + cygpid = (DWORD) cygwin_internal (CW_WINPID_TO_CYGWIN_PID, winpid); + + if (cygpid >= max_cygpid) + snprintf (buf, sizeof buf, "%lu", winpid); + else + snprintf (buf, sizeof buf, "%lu (pid: %lu)", winpid, cygpid); + return buf; +} + static DWORD proc_child (unsigned mask, FILE *ofile, pid_t pid) { @@ -706,7 +725,8 @@ proc_child (unsigned mask, FILE *ofile, pid_t pid) { case CREATE_PROCESS_DEBUG_EVENT: if (events) - fprintf (ofile, "--- Process %lu created\n", ev.dwProcessId); + fprintf (ofile, "--- Process %s created\n", + cygwin_pid (ev.dwProcessId)); if (ev.u.CreateProcessInfo.hFile) CloseHandle (ev.u.CreateProcessInfo.hFile); add_child (ev.dwProcessId, ev.u.CreateProcessInfo.hProcess); @@ -714,8 +734,8 @@ proc_child (unsigned mask, FILE *ofile, pid_t pid) case CREATE_THREAD_DEBUG_EVENT: if (events) - fprintf (ofile, "--- Process %lu thread %lu created\n", - ev.dwProcessId, ev.dwThreadId); + fprintf (ofile, "--- Process %s thread %lu created\n", + cygwin_pid (ev.dwProcessId), ev.dwThreadId); break; case LOAD_DLL_DEBUG_EVENT: @@ -727,8 +747,9 @@ proc_child (unsigned mask, FILE *ofile, pid_t pid) if (!GetFileNameFromHandle(ev.u.LoadDll.hFile, dllname)) wcscpy(dllname, L"(unknown)"); - fprintf (ofile, "--- Process %lu loaded %ls at %p\n", - ev.dwProcessId, dllname, ev.u.LoadDll.lpBaseOfDll); + fprintf (ofile, "--- Process %s loaded %ls at %p\n", + cygwin_pid (ev.dwProcessId), dllname, + ev.u.LoadDll.lpBaseOfDll); } if (ev.u.LoadDll.hFile) @@ -737,8 +758,8 @@ proc_child (unsigned mask, FILE *ofile, pid_t pid) case UNLOAD_DLL_DEBUG_EVENT: if (events) - fprintf (ofile, "--- Process %lu unloaded DLL at %p\n", - ev.dwProcessId, ev.u.UnloadDll.lpBaseOfDll); + fprintf (ofile, "--- Process %s unloaded DLL at %p\n", + cygwin_pid (ev.dwProcessId), ev.u.UnloadDll.lpBaseOfDll); break; case OUTPUT_DEBUG_STRING_EVENT: @@ -749,16 +770,18 @@ proc_child (unsigned mask, FILE *ofile, pid_t pid) case EXIT_PROCESS_DEBUG_EVENT: if (events) - fprintf (ofile, "--- Process %lu exited with status 0x%lx\n", - ev.dwProcessId, ev.u.ExitProcess.dwExitCode); + fprintf (ofile, "--- Process %s exited with status 0x%lx\n", + cygwin_pid (ev.dwProcessId), ev.u.ExitProcess.dwExitCode); res = ev.u.ExitProcess.dwExitCode; remove_child (ev.dwProcessId); break; case EXIT_THREAD_DEBUG_EVENT: if (events) - fprintf (ofile, "--- Process %lu thread %lu exited with status 0x%lx\n", - ev.dwProcessId, ev.dwThreadId, ev.u.ExitThread.dwExitCode); + fprintf (ofile, "--- Process %s thread %lu exited with " + "status 0x%lx\n", + cygwin_pid (ev.dwProcessId), ev.dwThreadId, + ev.u.ExitThread.dwExitCode); break; case EXCEPTION_DEBUG_EVENT: @@ -770,8 +793,8 @@ proc_child (unsigned mask, FILE *ofile, pid_t pid) default: status = DBG_EXCEPTION_NOT_HANDLED; if (ev.u.Exception.dwFirstChance) - fprintf (ofile, "--- Process %lu, exception %08lx at %p\n", - ev.dwProcessId, + fprintf (ofile, "--- Process %s, exception %08lx at %p\n", + cygwin_pid (ev.dwProcessId), ev.u.Exception.ExceptionRecord.ExceptionCode, ev.u.Exception.ExceptionRecord.ExceptionAddress); break; From 4afc52d57cc9355a95728235e7ce3a6664c36df4 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Sat, 23 Mar 2019 17:50:47 +0100 Subject: [PATCH 296/475] Cygwin: sys/cygwin.h: fix formatting Signed-off-by: Corinna Vinschen --- winsup/cygwin/include/sys/cygwin.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/winsup/cygwin/include/sys/cygwin.h b/winsup/cygwin/include/sys/cygwin.h index fc91d04ac..805671ef9 100644 --- a/winsup/cygwin/include/sys/cygwin.h +++ b/winsup/cygwin/include/sys/cygwin.h @@ -54,9 +54,9 @@ enum CCP_CONVTYPE_MASK = 3, /* Or these values to the above as needed. */ - CCP_ABSOLUTE = 0, /* Request absolute path (default). */ - CCP_RELATIVE = 0x100, /* Request to keep path relative. */ - CCP_PROC_CYGDRIVE = 0x200, /* Request to return /proc/cygdrive + CCP_ABSOLUTE = 0, /* Request absolute path (default). */ + CCP_RELATIVE = 0x100, /* Request to keep path relative. */ + CCP_PROC_CYGDRIVE = 0x200, /* Request to return /proc/cygdrive path (only with CCP_*_TO_POSIX). */ CCP_CONVFLAGS_MASK = 0x300, From 5737045c00db0cf9462b556bf56fbfa15c9ba90c Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Sun, 24 Mar 2019 22:13:00 +0100 Subject: [PATCH 297/475] Cygwin: ctrl_c_handler: Use 64 bit timer Just don't use GetTickCount for obvious reasons Signed-off-by: Corinna Vinschen --- winsup/cygwin/exceptions.cc | 6 +++--- winsup/cygwin/tty.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/winsup/cygwin/exceptions.cc b/winsup/cygwin/exceptions.cc index 491eedbe4..da4348fdb 100644 --- a/winsup/cygwin/exceptions.cc +++ b/winsup/cygwin/exceptions.cc @@ -1134,7 +1134,7 @@ ctrl_c_handler (DWORD type) handled *by* the process group leader. */ if (t && (!have_execed || have_execed_cygwin) && t->getpgid () == myself->pid && - (GetTickCount () - t->last_ctrl_c) >= MIN_CTRL_C_SLOP) + (GetTickCount64 () - t->last_ctrl_c) >= MIN_CTRL_C_SLOP) /* Otherwise we just send a SIGINT to the process group and return TRUE (to indicate that we have handled the signal). At this point, type should be a CTRL_C_EVENT or CTRL_BREAK_EVENT. */ @@ -1144,9 +1144,9 @@ ctrl_c_handler (DWORD type) if (type == CTRL_BREAK_EVENT && t->ti.c_cc[VINTR] == 3 && t->ti.c_cc[VQUIT] == 3) sig = SIGQUIT; - t->last_ctrl_c = GetTickCount (); + t->last_ctrl_c = GetTickCount64 (); t->kill_pgrp (sig); - t->last_ctrl_c = GetTickCount (); + t->last_ctrl_c = GetTickCount64 (); return TRUE; } diff --git a/winsup/cygwin/tty.h b/winsup/cygwin/tty.h index 362ae74dc..9aee43b9c 100644 --- a/winsup/cygwin/tty.h +++ b/winsup/cygwin/tty.h @@ -42,7 +42,7 @@ public: pid_t pgid; bool output_stopped; /* FIXME: Maybe do this with a mutex someday? */ fh_devices ntty; - DWORD last_ctrl_c; /* tick count of last ctrl-c */ + ULONGLONG last_ctrl_c; /* tick count of last ctrl-c */ bool is_console; IMPLEMENT_STATUS_FLAG (bool, initialized) From ee1ad64234b61f9deaae64b28313492188c1de43 Mon Sep 17 00:00:00 2001 From: Brian Inglis Date: Sat, 23 Mar 2019 20:22:38 -0600 Subject: [PATCH 298/475] default ps -W process start time to system boot time when inaccessible, 0, -1 --- winsup/utils/ps.cc | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/winsup/utils/ps.cc b/winsup/utils/ps.cc index 4fce3e0b3..c81805ab6 100644 --- a/winsup/utils/ps.cc +++ b/winsup/utils/ps.cc @@ -337,6 +337,17 @@ main (int argc, char *argv[]) p->start_time = to_time_t (&ct); CloseHandle (h); } + if (!h || 0 == p->start_time || -1 == p->start_time) + { + SYSTEM_TIMEOFDAY_INFORMATION stodi; + status = NtQuerySystemInformation (SystemTimeOfDayInformation, + (PVOID) &stodi, sizeof stodi, NULL); + if (!NT_SUCCESS (status)) + fprintf (stderr, + "NtQuerySystemInformation(SystemTimeOfDayInformation), " + "status %08x", status); + p->start_time = to_time_t ((FILETIME*)&stodi.BootTime); + } } char uname[128]; From 23bb2f660807bbc7321a143fa35ce659d79ba245 Mon Sep 17 00:00:00 2001 From: Brian Inglis Date: Sat, 23 Mar 2019 20:22:39 -0600 Subject: [PATCH 299/475] get and convert boot time once and use as needed --- winsup/utils/ps.cc | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/winsup/utils/ps.cc b/winsup/utils/ps.cc index c81805ab6..75a91f5be 100644 --- a/winsup/utils/ps.cc +++ b/winsup/utils/ps.cc @@ -164,6 +164,7 @@ main (int argc, char *argv[]) const char *lfmt = "%c %7d %7d %7d %10u %4s %8u %8s %s\n"; char ch; void *drive_map = NULL; + time_t boot_time = -1; aflag = lflag = fflag = sflag = 0; uid = getuid (); @@ -237,9 +238,12 @@ main (int argc, char *argv[]) if (query == CW_GETPINFO_FULL) { + HANDLE tok; + NTSTATUS status; + SYSTEM_TIMEOFDAY_INFORMATION stodi; + /* Enable debug privilege to allow to enumerate all processes, not only processes in current session. */ - HANDLE tok; if (OpenProcessToken (GetCurrentProcess (), TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES, &tok)) @@ -256,6 +260,15 @@ main (int argc, char *argv[]) } drive_map = (void *) cygwin_internal (CW_ALLOC_DRIVE_MAP); + + /* Get system boot time to default process start time */ + status = NtQuerySystemInformation (SystemTimeOfDayInformation, + (PVOID) &stodi, sizeof stodi, NULL); + if (!NT_SUCCESS (status)) + fprintf (stderr, + "NtQuerySystemInformation(SystemTimeOfDayInformation), " + "status %#010x\n", status); + boot_time = to_time_t ((FILETIME*)&stodi.BootTime); } for (int pid = 0; @@ -337,16 +350,10 @@ main (int argc, char *argv[]) p->start_time = to_time_t (&ct); CloseHandle (h); } + /* Default to boot time when process start time inaccessible, 0, -1 */ if (!h || 0 == p->start_time || -1 == p->start_time) { - SYSTEM_TIMEOFDAY_INFORMATION stodi; - status = NtQuerySystemInformation (SystemTimeOfDayInformation, - (PVOID) &stodi, sizeof stodi, NULL); - if (!NT_SUCCESS (status)) - fprintf (stderr, - "NtQuerySystemInformation(SystemTimeOfDayInformation), " - "status %08x", status); - p->start_time = to_time_t ((FILETIME*)&stodi.BootTime); + p->start_time = boot_time; } } From e8b23909e4f458b923595872719523b2293bd74e Mon Sep 17 00:00:00 2001 From: Andrew Stubbs Date: Mon, 25 Mar 2019 15:33:53 +0000 Subject: [PATCH 300/475] Add missing includes. These missing includes were causing build warnings, but also a real bug in which the "size" parameter to "write" was being passed in 32-bit, whereas it ought to be 64-bit. This led to intermittent bad behaviour. --- newlib/libc/machine/amdgcn/abort.c | 2 +- newlib/libc/machine/amdgcn/getreent.c | 1 + newlib/libc/sys/amdgcn/fstat.c | 2 ++ 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/newlib/libc/machine/amdgcn/abort.c b/newlib/libc/machine/amdgcn/abort.c index ccbca726a..ca9a0a33f 100644 --- a/newlib/libc/machine/amdgcn/abort.c +++ b/newlib/libc/machine/amdgcn/abort.c @@ -13,7 +13,7 @@ * they apply. */ -#include +#include #include #include "exit-value.h" diff --git a/newlib/libc/machine/amdgcn/getreent.c b/newlib/libc/machine/amdgcn/getreent.c index acf10a97f..5a28aa406 100644 --- a/newlib/libc/machine/amdgcn/getreent.c +++ b/newlib/libc/machine/amdgcn/getreent.c @@ -3,6 +3,7 @@ #include #include #include +#include /* Copied from the HSA documentation. */ typedef struct hsa_signal_s { diff --git a/newlib/libc/sys/amdgcn/fstat.c b/newlib/libc/sys/amdgcn/fstat.c index b78715857..2526967ef 100644 --- a/newlib/libc/sys/amdgcn/fstat.c +++ b/newlib/libc/sys/amdgcn/fstat.c @@ -13,6 +13,8 @@ * they apply. */ +#include +#include #include #include From d1be0a59d48222d8ea6261ee3e59de2bc3d149e4 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Wed, 27 Mar 2019 13:53:32 +0100 Subject: [PATCH 301/475] Cygwin: winpids: Fix getting process multiple times Switching to Cywin-only PIDs introduced a new problem when collecting Cygwin processes for `ps -W': A process can show up multiple times again, if the Cygwin procinfo has been opened for a just execing process. The execed process then shows up twice, once as Cygwin process, but with the wrong Windows PID of the execing process, once as Windows-only process. The mechanism used to exclude these stray processes didn't work with the new Cygwin pid handling anymore. To fix this * check if the incoming Windows PID is the same as the PID in the procinfo. If not, we have the PID of the execing process while procinfo was already changed, * always check if the process has already been handled, not only for processes we got a procinfo for, * simplify adding pid to pidlist since pid is now always correct. While at it, fix comments and comment formatting. Signed-off-by: Corinna Vinschen --- winsup/cygwin/pinfo.cc | 46 ++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 24 deletions(-) diff --git a/winsup/cygwin/pinfo.cc b/winsup/cygwin/pinfo.cc index 453861c81..bead85bf8 100644 --- a/winsup/cygwin/pinfo.cc +++ b/winsup/cygwin/pinfo.cc @@ -1437,11 +1437,15 @@ winpids::add (DWORD& nelem, bool winpid, DWORD pid) shared memory region. */ onreturn = OpenProcess (PROCESS_QUERY_LIMITED_INFORMATION, false, pid); - /* If we couldn't open the process then we don't have rights to it and should - make a copy of the shared memory area when it exists (it may not). */ + /* If we couldn't open the process then we don't have rights to it + and should make a copy of the shared memory area when it exists + (it may not). */ perform_copy = onreturn ? make_copy : true; p.init (cygpid, PID_PROCINFO | pinfo_access, NULL); + /* Did we catch the process during exec? Try to fix. */ + if (p && p->dwProcessId != pid) + pid = p->dwProcessId; } /* If we're just looking for winpids then don't do any special cygwin "stuff* */ @@ -1462,40 +1466,33 @@ winpids::add (DWORD& nelem, bool winpid, DWORD pid) return; } +out: /* Scan list of previously recorded pids to make sure that this pid hasn't shown up before. This can happen when a process execs. */ for (unsigned i = 0; i < nelem; i++) - if (pinfolist[i]->pid == p->pid) + if (pidlist[i] == pid) { - if ((_pinfo *) p != (_pinfo *) myself) + if (p && (_pinfo *) p != (_pinfo *) myself) p.release (); return; } - -out: - /* Exit here. - - If p is "false" then, eventually any opened process handle will be closed and - the function will exit without adding anything to the pid list. + /* If p is "false" then, eventually any opened process handle will be closed + and the function will exit without adding anything to the pid list. If p is "true" then we've discovered a cygwin process. Handle "myself" differently. Don't copy it and close/zero the handle we - just opened to it. - If not performing a copy, then keep the process handle open for the duration - of the life of the procinfo region to potential races when a new process uses - this pid. - Otherwise, malloc some memory for a copy of the shared memory. + just opened to it. If not performing a copy, then keep the process handle + open for the duration of the life of the procinfo region to potential + races when a new process uses this pid. Otherwise, malloc some memory + for a copy of the shared memory. - If the malloc failed, then "oh well". Just keep the shared memory around + If malloc failed, then "oh well". Just keep the shared memory around and eventually close the handle when the winpids goes out of scope. If malloc succeeds, copy the procinfo we just grabbed into the new region, release the shared memory and allow the handle to be closed when this - function returns. - - Oh, and add the pid to the list and bump the number of elements. */ - + function returns. */ if (p) { if (p == (_pinfo *) myself) @@ -1519,8 +1516,9 @@ out: } } } + /* Add pid to the list and bump the number of elements. */ if (p || winpid) - pidlist[nelem++] = !p ? pid : p->dwProcessId; + pidlist[nelem++] = pid; } DWORD @@ -1545,9 +1543,9 @@ winpids::enum_processes (bool winpid) f.dbi.ObjectName.Buffer[f.dbi.ObjectName.Length / sizeof (WCHAR)] = L'\0'; if (wcsncmp (f.dbi.ObjectName.Buffer, L"winpid.", 7) == 0) { - DWORD pid = wcstoul (f.dbi.ObjectName.Buffer + 7, NULL, 10); - add (nelem, false, pid); - } + DWORD pid = wcstoul (f.dbi.ObjectName.Buffer + 7, NULL, 10); + add (nelem, false, pid); + } } } else From 9fd429e6a73d306cf23aa84c845639abb35737d3 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Wed, 27 Mar 2019 14:01:17 +0100 Subject: [PATCH 302/475] Cygwin: Bump DLL version to 3.1 Signed-off-by: Corinna Vinschen --- winsup/cygwin/include/cygwin/version.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/winsup/cygwin/include/cygwin/version.h b/winsup/cygwin/include/cygwin/version.h index 0ce7e10da..bb4ffe771 100644 --- a/winsup/cygwin/include/cygwin/version.h +++ b/winsup/cygwin/include/cygwin/version.h @@ -10,8 +10,8 @@ details. */ the Cygwin shared library". This version is used to track important changes to the DLL and is mainly informative in nature. */ -#define CYGWIN_VERSION_DLL_MAJOR 3000 -#define CYGWIN_VERSION_DLL_MINOR 5 +#define CYGWIN_VERSION_DLL_MAJOR 3001 +#define CYGWIN_VERSION_DLL_MINOR 0 /* Major numbers before CYGWIN_VERSION_DLL_EPOCH are incompatible. */ From 5955da96e29f37243205b4294e8aa55a53443416 Mon Sep 17 00:00:00 2001 From: Ken Brown Date: Fri, 22 Mar 2019 19:30:36 +0000 Subject: [PATCH 303/475] Cygwin: FIFO: stop using overlapped I/O Make fhandler_fifo a derived class of fhandler_base instead of fhandler_base_overlapped. Replace the create_pipe macro, which is based on fhandler_pipe::create, by new create_pipe and open_pipe methods. These use NT functions instead of Win32 functions. Replace fifo_name by get_pipe_name, which returns a pointer to a UNICODE_STRING. Remove the fnevent macro, which would now be needed only once. Add a raw_write method, adapted from fhandler_base::raw_write. Adapt all functions to the changes above. --- winsup/cygwin/fhandler.h | 13 +- winsup/cygwin/fhandler_fifo.cc | 339 ++++++++++++++++++++++----------- 2 files changed, 237 insertions(+), 115 deletions(-) diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h index 0da87e985..57e97c277 100644 --- a/winsup/cygwin/fhandler.h +++ b/winsup/cygwin/fhandler.h @@ -1234,14 +1234,21 @@ public: } }; -class fhandler_fifo: public fhandler_base_overlapped +#define CYGWIN_FIFO_PIPE_NAME_LEN 47 + +class fhandler_fifo: public fhandler_base { HANDLE read_ready; HANDLE write_ready; + UNICODE_STRING pipe_name; + WCHAR pipe_name_buf[CYGWIN_FIFO_PIPE_NAME_LEN + 1]; bool __reg2 wait (HANDLE); - char __reg2 *fifo_name (char *, const char *); + NTSTATUS npfs_handle (HANDLE &); + HANDLE create_pipe (); + NTSTATUS open_pipe (); public: fhandler_fifo (); + PUNICODE_STRING get_pipe_name (); int open (int, mode_t); off_t lseek (off_t offset, int whence); int close (); @@ -1249,6 +1256,7 @@ public: bool isfifo () const { return true; } void set_close_on_exec (bool val); void __reg3 raw_read (void *ptr, size_t& ulen); + ssize_t __reg3 raw_write (const void *ptr, size_t ulen); bool arm (HANDLE h); void fixup_after_fork (HANDLE); int __reg2 fstatvfs (struct statvfs *buf); @@ -1262,7 +1270,6 @@ public: { x->pc.free_strings (); *reinterpret_cast (x) = *this; - reinterpret_cast (x)->atomic_write_buf = NULL; x->reset (this); } diff --git a/winsup/cygwin/fhandler_fifo.cc b/winsup/cygwin/fhandler_fifo.cc index 5733ec778..cb269e344 100644 --- a/winsup/cygwin/fhandler_fifo.cc +++ b/winsup/cygwin/fhandler_fifo.cc @@ -7,6 +7,7 @@ details. */ #include "winsup.h" +#include #include "miscfuncs.h" #include "cygerrno.h" @@ -21,26 +22,32 @@ #include "ntdll.h" #include "cygwait.h" +/* This is only to be used for writers. When reading, +STATUS_PIPE_EMPTY simply means there's no data to be read. */ +#define STATUS_PIPE_IS_CLOSED(status) \ + ({ NTSTATUS _s = (status); \ + _s == STATUS_PIPE_CLOSING \ + || _s == STATUS_PIPE_BROKEN \ + || _s == STATUS_PIPE_EMPTY; }) + fhandler_fifo::fhandler_fifo (): - fhandler_base_overlapped (), + fhandler_base (), read_ready (NULL), write_ready (NULL) { - max_atomic_write = DEFAULT_PIPEBUFSIZE; + pipe_name_buf[0] = L'\0'; need_fork_fixup (true); } -#define fnevent(w) fifo_name (npbuf, w "-event") -#define fnpipe() fifo_name (npbuf, "fifo") -#define create_pipe(r, w) \ - fhandler_pipe::create (sa_buf, (r), (w), 0, fnpipe (), open_mode) - -char * -fhandler_fifo::fifo_name (char *buf, const char *what) +PUNICODE_STRING +fhandler_fifo::get_pipe_name () { - /* Generate a semi-unique name to associate with this fifo. */ - __small_sprintf (buf, "%s.%08x.%016X", what, get_dev (), - get_ino ()); - return buf; + if (!pipe_name_buf[0]) + { + __small_swprintf (pipe_name_buf, L"%S-fifo.%08x.%016X", + &cygheap->installation_key, get_dev (), get_ino ()); + RtlInitUnicodeString (&pipe_name, pipe_name_buf); + } + return &pipe_name; } inline PSECURITY_ATTRIBUTES @@ -56,10 +63,8 @@ fhandler_fifo::arm (HANDLE h) const char *what; if (h == read_ready) what = "reader"; - else if (h == write_ready) - what = "writer"; else - what = "overlapped event"; + what = "writer"; debug_only_printf ("arming %s", what); #endif @@ -73,17 +78,113 @@ fhandler_fifo::arm (HANDLE h) return res; } +NTSTATUS +fhandler_fifo::npfs_handle (HANDLE &nph) +{ + static NO_COPY SRWLOCK npfs_lock; + static NO_COPY HANDLE npfs_dirh; + + NTSTATUS status = STATUS_SUCCESS; + OBJECT_ATTRIBUTES attr; + IO_STATUS_BLOCK io; + + /* Lockless after first call. */ + if (npfs_dirh) + { + nph = npfs_dirh; + return STATUS_SUCCESS; + } + AcquireSRWLockExclusive (&npfs_lock); + if (!npfs_dirh) + { + InitializeObjectAttributes (&attr, &ro_u_npfs, 0, NULL, NULL); + status = NtOpenFile (&npfs_dirh, FILE_READ_ATTRIBUTES | SYNCHRONIZE, + &attr, &io, FILE_SHARE_READ | FILE_SHARE_WRITE, + 0); + } + ReleaseSRWLockExclusive (&npfs_lock); + if (NT_SUCCESS (status)) + nph = npfs_dirh; + return status; +} + +/* Called when pipe is opened for reading. */ +HANDLE +fhandler_fifo::create_pipe () +{ + NTSTATUS status; + HANDLE npfsh; + HANDLE ph = NULL; + ACCESS_MASK access; + OBJECT_ATTRIBUTES attr; + IO_STATUS_BLOCK io; + ULONG hattr; + ULONG sharing; + ULONG nonblocking = FILE_PIPE_QUEUE_OPERATION; + ULONG max_instances = 1; + LARGE_INTEGER timeout; + + status = npfs_handle (npfsh); + if (!NT_SUCCESS (status)) + { + __seterrno_from_nt_status (status); + return NULL; + } + access = GENERIC_READ | FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES + | SYNCHRONIZE; + sharing = FILE_SHARE_READ | FILE_SHARE_WRITE; + hattr = OBJ_INHERIT | OBJ_CASE_INSENSITIVE; + InitializeObjectAttributes (&attr, get_pipe_name (), + hattr, npfsh, NULL); + timeout.QuadPart = -500000; + status = NtCreateNamedPipeFile (&ph, access, &attr, &io, sharing, + FILE_CREATE, 0, + FILE_PIPE_MESSAGE_TYPE, + FILE_PIPE_MESSAGE_MODE, + nonblocking, max_instances, + DEFAULT_PIPEBUFSIZE, DEFAULT_PIPEBUFSIZE, + &timeout); + if (!NT_SUCCESS (status)) + __seterrno_from_nt_status (status); + return ph; +} + +/* Called when file is opened for writing. */ +NTSTATUS +fhandler_fifo::open_pipe () +{ + NTSTATUS status; + HANDLE npfsh; + ACCESS_MASK access; + OBJECT_ATTRIBUTES attr; + IO_STATUS_BLOCK io; + ULONG sharing; + HANDLE ph = NULL; + + status = npfs_handle (npfsh); + if (!NT_SUCCESS (status)) + return status; + access = GENERIC_WRITE | SYNCHRONIZE; + InitializeObjectAttributes (&attr, get_pipe_name (), OBJ_INHERIT, + npfsh, NULL); + sharing = FILE_SHARE_READ | FILE_SHARE_WRITE; + status = NtOpenFile (&ph, access, &attr, &io, sharing, 0); + if (NT_SUCCESS (status)) + set_io_handle (ph); + return status; +} + int fhandler_fifo::open (int flags, mode_t) { enum { - success, - error_errno_set, - error_set_errno + success, + error_errno_set, + error_set_errno } res; bool reader, writer, duplexer; - DWORD open_mode = FILE_FLAG_OVERLAPPED; + HANDLE ph = NULL; /* Determine what we're doing with this fhandler: reading, writing, both */ switch (flags & O_ACCMODE) @@ -99,7 +200,6 @@ fhandler_fifo::open (int flags, mode_t) duplexer = false; break; case O_RDWR: - open_mode |= PIPE_ACCESS_DUPLEX; reader = true; writer = false; duplexer = true; @@ -112,22 +212,24 @@ fhandler_fifo::open (int flags, mode_t) debug_only_printf ("reader %d, writer %d, duplexer %d", reader, writer, duplexer); set_flags (flags); + /* Create control events for this named pipe */ char char_sa_buf[1024]; LPSECURITY_ATTRIBUTES sa_buf; sa_buf = sec_user_cloexec (flags & O_CLOEXEC, (PSECURITY_ATTRIBUTES) char_sa_buf, cygheap->user.sid()); - char npbuf[MAX_PATH]; - /* Create control events for this named pipe */ - if (!(read_ready = CreateEvent (sa_buf, duplexer, false, fnevent ("r")))) + char npbuf[MAX_PATH]; + __small_sprintf (npbuf, "r-event.%08x.%016X", get_dev (), get_ino ()); + if (!(read_ready = CreateEvent (sa_buf, duplexer, false, npbuf))) { - debug_printf ("CreatEvent for %s failed, %E", npbuf); + debug_printf ("CreateEvent for %s failed, %E", npbuf); res = error_set_errno; goto out; } - if (!(write_ready = CreateEvent (sa_buf, false, false, fnevent ("w")))) + npbuf[0] = 'w'; + if (!(write_ready = CreateEvent (sa_buf, false, false, npbuf))) { - debug_printf ("CreatEvent for %s failed, %E", npbuf); + debug_printf ("CreateEvent for %s failed, %E", npbuf); res = error_set_errno; goto out; } @@ -135,70 +237,54 @@ fhandler_fifo::open (int flags, mode_t) /* If we're reading, create the pipe, signal that we're ready and wait for a writer. FIXME: Probably need to special case O_RDWR case. */ - if (!reader) - /* We are not a reader */; - else if (create_pipe (&get_io_handle (), NULL)) + if (reader) { - debug_printf ("create of reader failed"); - res = error_set_errno; - goto out; - } - else if (!arm (read_ready)) - { - res = error_set_errno; - goto out; - } - else if (!duplexer && !wait (write_ready)) - { - res = error_errno_set; - goto out; - } - - /* If we're writing, it's a little tricky since it is possible that - we're attempting to open the other end of a pipe which is already - connected. In that case, we detect ERROR_PIPE_BUSY, reset the - read_ready event and wait for the reader to allow us to connect - by signalling read_ready. - - Once the pipe has been set up, we signal write_ready. */ - if (writer) - { - int err; - while (1) - if (!wait (read_ready)) - { - res = error_errno_set; - goto out; - } - else if ((err = create_pipe (NULL, &get_io_handle ())) == 0) - break; - else if (err == ERROR_PIPE_BUSY) - { - debug_only_printf ("pipe busy"); - ResetEvent (read_ready); - } - else - { - debug_printf ("create of writer failed"); - res = error_set_errno; - goto out; - } - if (!arm (write_ready)) + ph = create_pipe (); + if (!ph) + { + debug_printf ("create of reader failed"); + res = error_errno_set; + goto out; + } + else if (!arm (read_ready)) { res = error_set_errno; goto out; } + else if (!duplexer && !wait (write_ready)) + { + res = error_errno_set; + goto out; + } + else + res = success; } - /* If setup_overlapped() succeeds (and why wouldn't it?) we are all set. */ - if (setup_overlapped () == 0) - res = success; - else + /* If we're writing, wait for read_ready and then connect to the + pipe. Then signal write_ready. */ + if (writer) { - debug_printf ("setup_overlapped failed, %E"); - res = error_set_errno; + if (!wait (read_ready)) + { + res = error_errno_set; + goto out; + } + NTSTATUS status = open_pipe (); + if (!NT_SUCCESS (status)) + { + debug_printf ("create of writer failed"); + __seterrno_from_nt_status (status); + res = error_errno_set; + goto out; + } + else if (!arm (write_ready)) + { + res = error_set_errno; + goto out; + } + else + res = success; } - out: if (res == error_set_errno) __seterrno (); @@ -236,10 +322,8 @@ fhandler_fifo::wait (HANDLE h) const char *what; if (h == read_ready) what = "reader"; - else if (h == write_ready) - what = "writer"; else - what = "overlapped event"; + what = "writer"; #endif /* Set the wait to zero for non-blocking I/O-related events. */ DWORD wait = ((h == read_ready || h == write_ready) @@ -279,41 +363,72 @@ fhandler_fifo::wait (HANDLE h) } } +ssize_t __reg3 +fhandler_fifo::raw_write (const void *ptr, size_t len) +{ + ssize_t ret = -1; + NTSTATUS status; + IO_STATUS_BLOCK io; + + status = NtWriteFile (get_handle (), NULL, NULL, NULL, &io, + (PVOID) ptr, len, NULL, NULL); + if (NT_SUCCESS (status)) + { + /* NtWriteFile returns success with # of bytes written == 0 in + case writing on a non-blocking pipe fails if the pipe buffer + is full. */ + if (io.Information == 0) + set_errno (EAGAIN); + else + ret = io.Information; + } + else if (STATUS_PIPE_IS_CLOSED (status)) + { + set_errno (EPIPE); + raise (SIGPIPE); + } + else + __seterrno_from_nt_status (status); + return ret; +} + void __reg3 fhandler_fifo::raw_read (void *in_ptr, size_t& len) { size_t orig_len = len; - for (int i = 0; i < 2; i++) + while (1) { - fhandler_base_overlapped::raw_read (in_ptr, len); - if (len || i || WaitForSingleObject (read_ready, 0) != WAIT_OBJECT_0) - break; - /* If we got here, then fhandler_base_overlapped::raw_read returned 0, - indicating "EOF" and something has set read_ready to zero. That means - we should have a client waiting to connect. - FIXME: If the client CTRL-C's the open during this time then this - could hang indefinitely. Maybe implement a timeout? */ - if (!DisconnectNamedPipe (get_io_handle ())) + len = orig_len; + fhandler_base::raw_read (in_ptr, len); + ssize_t nread = (ssize_t) len; + if (nread > 0) + return; + else if (nread < 0 && GetLastError () != ERROR_NO_DATA) + goto errout; + else if (nread == 0) /* Writer has disconnected. */ { - debug_printf ("DisconnectNamedPipe failed, %E"); - goto errno_out; + /* Not implemented yet. */ } - else if (!ConnectNamedPipe (get_io_handle (), get_overlapped ()) - && GetLastError () != ERROR_IO_PENDING) + if (is_nonblocking ()) { - debug_printf ("ConnectNamedPipe failed, %E"); - goto errno_out; + set_errno (EAGAIN); + goto errout; + } + else + { + /* Allow interruption. Copied from + fhandler_socket_unix::open_reparse_point. */ + pthread_testcancel (); + if (cygwait (NULL, cw_nowait, cw_sig_eintr) == WAIT_SIGNALED + && !_my_tls.call_signal_handler ()) + { + set_errno (EINTR); + goto errout; + } + /* Don't hog the CPU. */ + Sleep (1); } - else if (!arm (read_ready)) - goto errno_out; - else if (!wait (get_overlapped_buffer ()->hEvent)) - goto errout; /* If wait() fails, errno is set so no need to set it */ - len = orig_len; /* Reset since raw_read above set it to zero. */ } - return; - -errno_out: - __seterrno (); errout: len = -1; } @@ -337,7 +452,7 @@ fhandler_fifo::close () int fhandler_fifo::dup (fhandler_base *child, int flags) { - if (fhandler_base_overlapped::dup (child, flags)) + if (fhandler_base::dup (child, flags)) { __seterrno (); return -1; @@ -366,7 +481,7 @@ fhandler_fifo::dup (fhandler_base *child, int flags) void fhandler_fifo::fixup_after_fork (HANDLE parent) { - fhandler_base_overlapped::fixup_after_fork (parent); + fhandler_base::fixup_after_fork (parent); fork_fixup (parent, read_ready, "read_ready"); fork_fixup (parent, write_ready, "write_ready"); } From 48d4cce3be58b1b0d4ca1befbcbe5467a0301f51 Mon Sep 17 00:00:00 2001 From: Ken Brown Date: Fri, 22 Mar 2019 19:30:37 +0000 Subject: [PATCH 304/475] Cygwin: FIFO: allow multiple writers Introduce a 'fifo_client_handler' structure that can be used by a reader to communicate with a writer using an instance of the named pipe. An fhandler_fifo opened for reading creates a thread that does the following: - maintains a list of fifo_client_handlers - listens for_clients trying to connect - creates new pipe instances as needed so that there's always at least one available for connecting. The pipe instances are initially created in blocking mode, but they are set to be non-blocking after a connection is made. fhandler_fifo::raw_read now loops through the connected clients and reads from the first one that has data available. New fhandler_fifo methods: add_client, listen_client, listen_client_thread, check_listen_client_thread. Replace the create_pipe method by create_pipe_instance, which allows unlimited pipe instances. New helper functions: create_event, set_pipe_non_blocking. --- winsup/cygwin/fhandler.h | 31 ++- winsup/cygwin/fhandler_fifo.cc | 368 ++++++++++++++++++++++++++++++--- 2 files changed, 367 insertions(+), 32 deletions(-) diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h index 57e97c277..e7c4af6a1 100644 --- a/winsup/cygwin/fhandler.h +++ b/winsup/cygwin/fhandler.h @@ -1235,20 +1235,49 @@ public: }; #define CYGWIN_FIFO_PIPE_NAME_LEN 47 +#define MAX_CLIENTS 64 + +enum fifo_client_connect_state + { + fc_unknown, + fc_connecting, + fc_connected, + fc_invalid + }; + +struct fifo_client_handler +{ + fhandler_base *fh; + fifo_client_connect_state state; + HANDLE connect_evt; + HANDLE dummy_evt; /* Never signaled. */ + fifo_client_handler () : fh (NULL), state (fc_unknown), connect_evt (NULL), + dummy_evt (NULL) {} + int connect (); + int close (); +}; class fhandler_fifo: public fhandler_base { HANDLE read_ready; HANDLE write_ready; + HANDLE listen_client_thr; + HANDLE lct_termination_evt; UNICODE_STRING pipe_name; WCHAR pipe_name_buf[CYGWIN_FIFO_PIPE_NAME_LEN + 1]; + fifo_client_handler client[MAX_CLIENTS]; + int nclients, nconnected; bool __reg2 wait (HANDLE); NTSTATUS npfs_handle (HANDLE &); - HANDLE create_pipe (); + HANDLE create_pipe_instance (bool); NTSTATUS open_pipe (); + int disconnect_and_reconnect (int); + int add_client (); + bool listen_client (); public: fhandler_fifo (); PUNICODE_STRING get_pipe_name (); + DWORD listen_client_thread (); int open (int, mode_t); off_t lseek (off_t offset, int whence); int close (); diff --git a/winsup/cygwin/fhandler_fifo.cc b/winsup/cygwin/fhandler_fifo.cc index cb269e344..e91e88050 100644 --- a/winsup/cygwin/fhandler_fifo.cc +++ b/winsup/cygwin/fhandler_fifo.cc @@ -31,8 +31,9 @@ STATUS_PIPE_EMPTY simply means there's no data to be read. */ || _s == STATUS_PIPE_EMPTY; }) fhandler_fifo::fhandler_fifo (): - fhandler_base (), - read_ready (NULL), write_ready (NULL) + fhandler_base (), read_ready (NULL), write_ready (NULL), + listen_client_thr (NULL), lct_termination_evt (NULL), nclients (0), + nconnected (0) { pipe_name_buf[0] = L'\0'; need_fork_fixup (true); @@ -78,6 +79,94 @@ fhandler_fifo::arm (HANDLE h) return res; } +static HANDLE +create_event () +{ + NTSTATUS status; + OBJECT_ATTRIBUTES attr; + HANDLE evt = NULL; + + InitializeObjectAttributes (&attr, NULL, 0, NULL, NULL); + status = NtCreateEvent (&evt, EVENT_ALL_ACCESS, &attr, + NotificationEvent, FALSE); + if (!NT_SUCCESS (status)) + __seterrno_from_nt_status (status); + return evt; +} + + +static void +set_pipe_non_blocking (HANDLE ph, bool nonblocking) +{ + NTSTATUS status; + IO_STATUS_BLOCK io; + FILE_PIPE_INFORMATION fpi; + + fpi.ReadMode = FILE_PIPE_MESSAGE_MODE; + fpi.CompletionMode = nonblocking ? FILE_PIPE_COMPLETE_OPERATION + : FILE_PIPE_QUEUE_OPERATION; + status = NtSetInformationFile (ph, &io, &fpi, sizeof fpi, + FilePipeInformation); + if (!NT_SUCCESS (status)) + debug_printf ("NtSetInformationFile(FilePipeInformation): %y", status); +} + +/* The pipe instance is always in blocking mode when this is called. */ +int +fifo_client_handler::connect () +{ + NTSTATUS status; + IO_STATUS_BLOCK io; + + if (connect_evt) + ResetEvent (connect_evt); + else if (!(connect_evt = create_event ())) + return -1; + status = NtFsControlFile (fh->get_handle (), connect_evt, NULL, NULL, &io, + FSCTL_PIPE_LISTEN, NULL, 0, NULL, 0); + switch (status) + { + case STATUS_PENDING: + case STATUS_PIPE_LISTENING: + state = fc_connecting; + break; + case STATUS_PIPE_CONNECTED: + state = fc_connected; + set_pipe_non_blocking (fh->get_handle (), true); + break; + default: + __seterrno_from_nt_status (status); + return -1; + } + return 0; +} + +int +fhandler_fifo::disconnect_and_reconnect (int i) +{ + NTSTATUS status; + IO_STATUS_BLOCK io; + HANDLE ph = client[i].fh->get_handle (); + + status = NtFsControlFile (ph, NULL, NULL, NULL, &io, FSCTL_PIPE_DISCONNECT, + NULL, 0, NULL, 0); + /* Short-lived. Don't use cygwait. We don't want to be interrupted. */ + if (status == STATUS_PENDING + && NtWaitForSingleObject (ph, FALSE, NULL) == WAIT_OBJECT_0) + status = io.Status; + if (!NT_SUCCESS (status)) + { + __seterrno_from_nt_status (status); + return -1; + } + set_pipe_non_blocking (client[i].fh->get_handle (), false); + if (client[i].connect () < 0) + return -1; + if (client[i].state == fc_connected) + nconnected++; + return 0; +} + NTSTATUS fhandler_fifo::npfs_handle (HANDLE &nph) { @@ -108,9 +197,12 @@ fhandler_fifo::npfs_handle (HANDLE &nph) return status; } -/* Called when pipe is opened for reading. */ +/* Called when a FIFO is first opened for reading and again each time + a new client is needed. Each pipe instance is created in blocking + mode so that we can easily wait for a connection. After it is + connected, it is put in nonblocking mode. */ HANDLE -fhandler_fifo::create_pipe () +fhandler_fifo::create_pipe_instance (bool first) { NTSTATUS status; HANDLE npfsh; @@ -121,7 +213,7 @@ fhandler_fifo::create_pipe () ULONG hattr; ULONG sharing; ULONG nonblocking = FILE_PIPE_QUEUE_OPERATION; - ULONG max_instances = 1; + ULONG max_instances = -1; LARGE_INTEGER timeout; status = npfs_handle (npfsh); @@ -133,12 +225,14 @@ fhandler_fifo::create_pipe () access = GENERIC_READ | FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES | SYNCHRONIZE; sharing = FILE_SHARE_READ | FILE_SHARE_WRITE; - hattr = OBJ_INHERIT | OBJ_CASE_INSENSITIVE; + hattr = OBJ_INHERIT; + if (first) + hattr |= OBJ_CASE_INSENSITIVE; InitializeObjectAttributes (&attr, get_pipe_name (), hattr, npfsh, NULL); timeout.QuadPart = -500000; status = NtCreateNamedPipeFile (&ph, access, &attr, &io, sharing, - FILE_CREATE, 0, + first ? FILE_CREATE : FILE_OPEN, 0, FILE_PIPE_MESSAGE_TYPE, FILE_PIPE_MESSAGE_MODE, nonblocking, max_instances, @@ -149,7 +243,7 @@ fhandler_fifo::create_pipe () return ph; } -/* Called when file is opened for writing. */ +/* Called when a FIFO is opened for writing. */ NTSTATUS fhandler_fifo::open_pipe () { @@ -174,6 +268,140 @@ fhandler_fifo::open_pipe () return status; } +int +fhandler_fifo::add_client () +{ + fifo_client_handler fc; + fhandler_base *fh; + bool first = (nclients == 0); + + if (nclients == MAX_CLIENTS) + { + set_errno (EMFILE); + return -1; + } + if (!(fc.dummy_evt = create_event ())) + return -1; + if (!(fh = build_fh_dev (dev ()))) + { + set_errno (EMFILE); + return -1; + } + fc.fh = fh; + HANDLE ph = create_pipe_instance (first); + if (!ph) + goto errout; + fh->set_io_handle (ph); + fh->set_flags (get_flags ()); + if (fc.connect () < 0) + { + fc.close (); + goto errout; + } + if (fc.state == fc_connected) + nconnected++; + client[nclients++] = fc; + return 0; +errout: + delete fh; + return -1; + +} + +/* Just hop to the listen_client_thread method. */ +DWORD WINAPI +listen_client_func (LPVOID param) +{ + fhandler_fifo *fh = (fhandler_fifo *) param; + return fh->listen_client_thread (); +} + +/* Start a thread that listens for client connections. Whenever a new + client connects, it creates a new pipe_instance if necessary. + (There may already be an available instance if a client has + disconnected.) */ +bool +fhandler_fifo::listen_client () +{ + if (!(lct_termination_evt = create_event ())) + return false; + + listen_client_thr = CreateThread (NULL, PREFERRED_IO_BLKSIZE, + listen_client_func, (PVOID) this, 0, NULL); + if (!listen_client_thr) + { + __seterrno (); + HANDLE evt = InterlockedExchangePointer (&lct_termination_evt, NULL); + if (evt) + CloseHandle (evt); + return false; + } + return true; +} + +DWORD +fhandler_fifo::listen_client_thread () +{ + while (1) + { + bool found; + HANDLE w[MAX_CLIENTS + 1]; + int i; + DWORD wait_ret; + + found = false; + for (i = 0; i < nclients; i++) + switch (client[i].state) + { + case fc_invalid: + if (disconnect_and_reconnect (i) < 0) + goto errout; + /* Fall through. */ + case fc_connected: + w[i] = client[i].dummy_evt; + break; + case fc_connecting: + found = true; + w[i] = client[i].connect_evt; + break; + case fc_unknown: /* Shouldn't happen. */ + default: + break; + } + w[nclients] = lct_termination_evt; + if (!found) + { + if (add_client () < 0) + goto errout; + else + continue; + } + if (!arm (read_ready)) + { + __seterrno (); + goto errout; + } + + /* Wait for a client to connect. */ + wait_ret = WaitForMultipleObjects (nclients + 1, w, false, INFINITE); + i = wait_ret - WAIT_OBJECT_0; + if (i < 0 || i > nclients) + goto errout; + else if (i == nclients) /* Reader is closing. */ + return 0; + else + { + client[i].state = fc_connected; + nconnected++; + set_pipe_non_blocking (client[i].fh->get_handle (), true); + yield (); + } + } +errout: + ResetEvent (read_ready); + return -1; +} + int fhandler_fifo::open (int flags, mode_t) { @@ -184,7 +412,6 @@ fhandler_fifo::open (int flags, mode_t) error_set_errno } res; bool reader, writer, duplexer; - HANDLE ph = NULL; /* Determine what we're doing with this fhandler: reading, writing, both */ switch (flags & O_ACCMODE) @@ -212,6 +439,9 @@ fhandler_fifo::open (int flags, mode_t) debug_only_printf ("reader %d, writer %d, duplexer %d", reader, writer, duplexer); set_flags (flags); + if (reader) + nohandle (true); + /* Create control events for this named pipe */ char char_sa_buf[1024]; LPSECURITY_ATTRIBUTES sa_buf; @@ -234,24 +464,42 @@ fhandler_fifo::open (int flags, mode_t) goto out; } - /* If we're reading, create the pipe, signal that we're ready and wait for - a writer. - FIXME: Probably need to special case O_RDWR case. */ + /* If we're reading, start the listen_client thread (which should + signal read_ready), and wait for a writer. */ if (reader) { - ph = create_pipe (); - if (!ph) + if (!listen_client ()) { - debug_printf ("create of reader failed"); + debug_printf ("create of listen_client thread failed"); res = error_errno_set; goto out; } - else if (!arm (read_ready)) + /* Wait for the listen_client thread to create the pipe and + signal read_ready. This should be quick. */ + HANDLE w[2] = { listen_client_thr, read_ready }; + switch (WaitForMultipleObjects (2, w, FALSE, INFINITE)) { + case WAIT_OBJECT_0: + debug_printf ("listen_client_thread exited unexpectedly"); + DWORD err; + GetExitCodeThread (listen_client_thr, &err); + __seterrno_from_win_error (err); + res = error_errno_set; + goto out; + break; + case WAIT_OBJECT_0 + 1: + if (!arm (read_ready)) + { + res = error_set_errno; + goto out; + } + break; + default: res = error_set_errno; goto out; + break; } - else if (!duplexer && !wait (write_ready)) + if (!duplexer && !wait (write_ready)) { res = error_errno_set; goto out; @@ -261,7 +509,8 @@ fhandler_fifo::open (int flags, mode_t) } /* If we're writing, wait for read_ready and then connect to the - pipe. Then signal write_ready. */ + pipe. This should always succeed quickly if the reader's + listen_client thread is running. Then signal write_ready. */ if (writer) { if (!wait (read_ready)) @@ -283,7 +532,10 @@ fhandler_fifo::open (int flags, mode_t) goto out; } else - res = success; + { + set_pipe_non_blocking (get_handle (), true); + res = success; + } } out: if (res == error_set_errno) @@ -302,6 +554,8 @@ out: } if (get_io_handle ()) CloseHandle (get_io_handle ()); + if (listen_client_thr) + CloseHandle (listen_client_thr); } debug_printf ("res %d", res); return res == success; @@ -396,19 +650,36 @@ void __reg3 fhandler_fifo::raw_read (void *in_ptr, size_t& len) { size_t orig_len = len; + + /* Start the listen_client thread if necessary (e.g., after dup or fork). */ + if (!listen_client_thr && !listen_client ()) + goto errout; + while (1) { - len = orig_len; - fhandler_base::raw_read (in_ptr, len); - ssize_t nread = (ssize_t) len; - if (nread > 0) - return; - else if (nread < 0 && GetLastError () != ERROR_NO_DATA) - goto errout; - else if (nread == 0) /* Writer has disconnected. */ + if (nconnected == 0) /* EOF */ { - /* Not implemented yet. */ + len = 0; + return; } + + /* Poll the connected clients for input. */ + for (int i = 0; i < nclients; i++) + if (client[i].state == fc_connected) + { + len = orig_len; + client[i].fh->fhandler_base::raw_read (in_ptr, len); + ssize_t nread = (ssize_t) len; + if (nread > 0) + return; + else if (nread < 0 && GetLastError () != ERROR_NO_DATA) + goto errout; + else if (nread == 0) /* Client has disconnected. */ + { + client[i].state = fc_invalid; + nconnected--; + } + } if (is_nonblocking ()) { set_errno (EAGAIN); @@ -441,12 +712,47 @@ fhandler_fifo::fstatvfs (struct statvfs *sfs) return fh.fstatvfs (sfs); } +int +fifo_client_handler::close () +{ + int res = 0; + + if (fh) + res = fh->close (); + if (connect_evt) + CloseHandle (connect_evt); + if (dummy_evt) + CloseHandle (dummy_evt); + return res; +} + int fhandler_fifo::close () { - CloseHandle (read_ready); - CloseHandle (write_ready); - return fhandler_base::close (); + int res = 0; + HANDLE evt = InterlockedExchangePointer (&lct_termination_evt, NULL); + HANDLE thr = InterlockedExchangePointer (&listen_client_thr, NULL); + if (thr) + { + if (evt) + SetEvent (evt); + WaitForSingleObject (thr, INFINITE); + DWORD err; + GetExitCodeThread (thr, &err); + if (err) + debug_printf ("listen_client_thread exited with code %d", err); + CloseHandle (thr); + } + if (evt) + CloseHandle (evt); + if (read_ready) + CloseHandle (read_ready); + if (write_ready) + CloseHandle (write_ready); + for (int i = 0; i < nclients; i++) + if (client[i].close () < 0) + res = -1; + return fhandler_base::close () || res; } int From c75e077f9953e3ecc6ba371d7ef95e14883a68ba Mon Sep 17 00:00:00 2001 From: Ken Brown Date: Fri, 22 Mar 2019 19:30:38 +0000 Subject: [PATCH 305/475] Cygwin: FIFO: add a spinlock Don't let listen_client_thread and raw_read access the client list simultaneously. --- winsup/cygwin/fhandler.h | 3 +++ winsup/cygwin/fhandler_fifo.cc | 34 +++++++++++++++++++++++++--------- 2 files changed, 28 insertions(+), 9 deletions(-) diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h index e7c4af6a1..997dc0b6d 100644 --- a/winsup/cygwin/fhandler.h +++ b/winsup/cygwin/fhandler.h @@ -1267,6 +1267,7 @@ class fhandler_fifo: public fhandler_base WCHAR pipe_name_buf[CYGWIN_FIFO_PIPE_NAME_LEN + 1]; fifo_client_handler client[MAX_CLIENTS]; int nclients, nconnected; + af_unix_spinlock_t _fifo_client_lock; bool __reg2 wait (HANDLE); NTSTATUS npfs_handle (HANDLE &); HANDLE create_pipe_instance (bool); @@ -1278,6 +1279,8 @@ public: fhandler_fifo (); PUNICODE_STRING get_pipe_name (); DWORD listen_client_thread (); + void fifo_client_lock () { _fifo_client_lock.lock (); } + void fifo_client_unlock () { _fifo_client_lock.unlock (); } int open (int, mode_t); off_t lseek (off_t offset, int whence); int close (); diff --git a/winsup/cygwin/fhandler_fifo.cc b/winsup/cygwin/fhandler_fifo.cc index e91e88050..b0016ee90 100644 --- a/winsup/cygwin/fhandler_fifo.cc +++ b/winsup/cygwin/fhandler_fifo.cc @@ -349,13 +349,17 @@ fhandler_fifo::listen_client_thread () int i; DWORD wait_ret; + fifo_client_lock (); found = false; for (i = 0; i < nclients; i++) switch (client[i].state) { case fc_invalid: if (disconnect_and_reconnect (i) < 0) - goto errout; + { + fifo_client_unlock (); + goto errout; + } /* Fall through. */ case fc_connected: w[i] = client[i].dummy_evt; @@ -369,13 +373,15 @@ fhandler_fifo::listen_client_thread () break; } w[nclients] = lct_termination_evt; + int res = 0; if (!found) - { - if (add_client () < 0) - goto errout; - else - continue; - } + res = add_client (); + fifo_client_unlock (); + if (res < 0) + goto errout; + else if (!found) + continue; + if (!arm (read_ready)) { __seterrno (); @@ -391,9 +397,11 @@ fhandler_fifo::listen_client_thread () return 0; else { + fifo_client_lock (); client[i].state = fc_connected; nconnected++; set_pipe_non_blocking (client[i].fh->get_handle (), true); + fifo_client_unlock (); yield (); } } @@ -664,6 +672,7 @@ fhandler_fifo::raw_read (void *in_ptr, size_t& len) } /* Poll the connected clients for input. */ + fifo_client_lock (); for (int i = 0; i < nclients; i++) if (client[i].state == fc_connected) { @@ -671,15 +680,22 @@ fhandler_fifo::raw_read (void *in_ptr, size_t& len) client[i].fh->fhandler_base::raw_read (in_ptr, len); ssize_t nread = (ssize_t) len; if (nread > 0) - return; + { + fifo_client_unlock (); + return; + } else if (nread < 0 && GetLastError () != ERROR_NO_DATA) - goto errout; + { + fifo_client_unlock (); + goto errout; + } else if (nread == 0) /* Client has disconnected. */ { client[i].state = fc_invalid; nconnected--; } } + fifo_client_unlock (); if (is_nonblocking ()) { set_errno (EAGAIN); From c6e221c03668909f6c3fb399d8888629353b0191 Mon Sep 17 00:00:00 2001 From: Ken Brown Date: Fri, 22 Mar 2019 19:30:38 +0000 Subject: [PATCH 306/475] Cygwin: FIFO: improve EOF detection Add a hit_eof method that tries to detect whether any clients are connected. Before concluding that there are none, it gives the listen_client thread time to update the client data. --- winsup/cygwin/fhandler.h | 1 + winsup/cygwin/fhandler_fifo.cc | 21 ++++++++++++++++++++- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h index 997dc0b6d..af5f500bf 100644 --- a/winsup/cygwin/fhandler.h +++ b/winsup/cygwin/fhandler.h @@ -1277,6 +1277,7 @@ class fhandler_fifo: public fhandler_base bool listen_client (); public: fhandler_fifo (); + bool hit_eof (); PUNICODE_STRING get_pipe_name (); DWORD listen_client_thread (); void fifo_client_lock () { _fifo_client_lock.lock (); } diff --git a/winsup/cygwin/fhandler_fifo.cc b/winsup/cygwin/fhandler_fifo.cc index b0016ee90..1dcb3b3df 100644 --- a/winsup/cygwin/fhandler_fifo.cc +++ b/winsup/cygwin/fhandler_fifo.cc @@ -654,6 +654,25 @@ fhandler_fifo::raw_write (const void *ptr, size_t len) return ret; } +/* A FIFO open for reading is at EOF if no process has it open for + writing. We test this by checking nconnected. But we must take + account of the possible delay from the time of connection to the + time the connection is recorded by the listen_client thread. */ +bool +fhandler_fifo::hit_eof () +{ + fifo_client_lock (); + bool eof = (nconnected == 0); + fifo_client_unlock (); + if (eof) + { + /* Give the listen_client thread time to catch up, then recheck. */ + Sleep (1); + eof = (nconnected == 0); + } + return eof; +} + void __reg3 fhandler_fifo::raw_read (void *in_ptr, size_t& len) { @@ -665,7 +684,7 @@ fhandler_fifo::raw_read (void *in_ptr, size_t& len) while (1) { - if (nconnected == 0) /* EOF */ + if (hit_eof ()) { len = 0; return; From 035bf7dc84d98f6f643ba2dd00b08c34dc8eb984 Mon Sep 17 00:00:00 2001 From: Ken Brown Date: Fri, 22 Mar 2019 19:30:39 +0000 Subject: [PATCH 307/475] Cygwin: FIFO: update clone and dup Deal with all clients. --- winsup/cygwin/fhandler.h | 8 +++++--- winsup/cygwin/fhandler_fifo.cc | 25 +++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h index af5f500bf..0ebc44e0d 100644 --- a/winsup/cygwin/fhandler.h +++ b/winsup/cygwin/fhandler.h @@ -1309,9 +1309,11 @@ public: fhandler_fifo *clone (cygheap_types malloc_type = HEAP_FHANDLER) { void *ptr = (void *) ccalloc (malloc_type, 1, sizeof (fhandler_fifo)); - fhandler_fifo *fh = new (ptr) fhandler_fifo (ptr); - copyto (fh); - return fh; + fhandler_fifo *fhf = new (ptr) fhandler_fifo (ptr); + copyto (fhf); + for (int i = 0; i < nclients; i++) + fhf->client[i].fh = client[i].fh->fhandler_base::clone (); + return fhf; } }; diff --git a/winsup/cygwin/fhandler_fifo.cc b/winsup/cygwin/fhandler_fifo.cc index 1dcb3b3df..c295c2393 100644 --- a/winsup/cygwin/fhandler_fifo.cc +++ b/winsup/cygwin/fhandler_fifo.cc @@ -816,6 +816,31 @@ fhandler_fifo::dup (fhandler_base *child, int flags) __seterrno (); return -1; } + for (int i = 0; i < nclients; i++) + { + if (!DuplicateHandle (GetCurrentProcess (), client[i].fh->get_handle (), + GetCurrentProcess (), + &fhf->client[i].fh->get_handle (), + 0, true, DUPLICATE_SAME_ACCESS) + || !DuplicateHandle (GetCurrentProcess (), client[i].connect_evt, + GetCurrentProcess (), + &fhf->client[i].connect_evt, + 0, true, DUPLICATE_SAME_ACCESS) + || !DuplicateHandle (GetCurrentProcess (), client[i].dummy_evt, + GetCurrentProcess (), + &fhf->client[i].dummy_evt, + 0, true, DUPLICATE_SAME_ACCESS)) + { + CloseHandle (fhf->read_ready); + CloseHandle (fhf->write_ready); + fhf->close (); + __seterrno (); + return -1; + } + } + fhf->listen_client_thr = NULL; + fhf->lct_termination_evt = NULL; + fhf->fifo_client_unlock (); return 0; } From e02a0f729579f11a2cc7442602b3a21359700531 Mon Sep 17 00:00:00 2001 From: Ken Brown Date: Fri, 22 Mar 2019 19:30:40 +0000 Subject: [PATCH 308/475] Cygwin: FIFO: update fixup_after_fork Fixup each client. Reset listen_client_thr and lct_termination_evt. --- winsup/cygwin/fhandler_fifo.cc | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/winsup/cygwin/fhandler_fifo.cc b/winsup/cygwin/fhandler_fifo.cc index c295c2393..7a592aa0d 100644 --- a/winsup/cygwin/fhandler_fifo.cc +++ b/winsup/cygwin/fhandler_fifo.cc @@ -850,6 +850,15 @@ fhandler_fifo::fixup_after_fork (HANDLE parent) fhandler_base::fixup_after_fork (parent); fork_fixup (parent, read_ready, "read_ready"); fork_fixup (parent, write_ready, "write_ready"); + for (int i = 0; i < nclients; i++) + { + client[i].fh->fhandler_base::fixup_after_fork (parent); + fork_fixup (parent, client[i].connect_evt, "connect_evt"); + fork_fixup (parent, client[i].dummy_evt, "dummy_evt"); + } + listen_client_thr = NULL; + lct_termination_evt = NULL; + fifo_client_unlock (); } void From 1aa438a94c9a3b89930bd6a10a6fc8de0c2bd282 Mon Sep 17 00:00:00 2001 From: Ken Brown Date: Fri, 22 Mar 2019 19:30:40 +0000 Subject: [PATCH 309/475] Cygwin: FIFO: update set_close_on_exec Deal with each client. --- winsup/cygwin/fhandler_fifo.cc | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/winsup/cygwin/fhandler_fifo.cc b/winsup/cygwin/fhandler_fifo.cc index 7a592aa0d..2c20444c6 100644 --- a/winsup/cygwin/fhandler_fifo.cc +++ b/winsup/cygwin/fhandler_fifo.cc @@ -867,4 +867,10 @@ fhandler_fifo::set_close_on_exec (bool val) fhandler_base::set_close_on_exec (val); set_no_inheritance (read_ready, val); set_no_inheritance (write_ready, val); + for (int i = 0; i < nclients; i++) + { + client[i].fh->fhandler_base::set_close_on_exec (val); + set_no_inheritance (client[i].connect_evt, val); + set_no_inheritance (client[i].dummy_evt, val); + } } From ee394c311e493ba8e23516a2ba72cadf3d9eaf9a Mon Sep 17 00:00:00 2001 From: Ken Brown Date: Fri, 22 Mar 2019 19:30:41 +0000 Subject: [PATCH 310/475] Cygwin: FIFO: update select Add static functions peek_fifo, thread_fifo, start_thread_fifo, and fifo_cleanup to select.cc. These are based on the corresponding pipe functions, the main difference being that peek_fifo loops through the connected clients to see if any of them have data available for reading. Add the fhandler_fifo methods select_read, select_write, and select_except. Add accessor methods get_nclients, get_handle, and is_connected that are needed by peek_fifo. --- winsup/cygwin/fhandler.h | 4 + winsup/cygwin/select.cc | 161 +++++++++++++++++++++++++++++++++++---- winsup/cygwin/select.h | 7 ++ 3 files changed, 157 insertions(+), 15 deletions(-) diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h index 0ebc44e0d..f6982f0ba 100644 --- a/winsup/cygwin/fhandler.h +++ b/winsup/cygwin/fhandler.h @@ -1278,6 +1278,10 @@ class fhandler_fifo: public fhandler_base public: fhandler_fifo (); bool hit_eof (); + int get_nclients () const { return nclients; } + HANDLE& get_handle () { return fhandler_base::get_handle (); } + HANDLE get_handle (int i) const { return client[i].fh->get_handle (); } + bool is_connected (int i) const { return client[i].state == fc_connected; } PUNICODE_STRING get_pipe_name (); DWORD listen_client_thread (); void fifo_client_lock () { _fifo_client_lock.lock (); } diff --git a/winsup/cygwin/select.cc b/winsup/cygwin/select.cc index 59325860d..991494aa8 100644 --- a/winsup/cygwin/select.cc +++ b/winsup/cygwin/select.cc @@ -822,17 +822,148 @@ fhandler_pipe::select_except (select_stuff *ss) return s; } +static int +peek_fifo (select_record *s, bool from_select) +{ + if (cygheap->fdtab.not_open (s->fd)) + { + s->thread_errno = EBADF; + return -1; + } + + int gotone = 0; + fhandler_fifo *fh = (fhandler_fifo *) s->fh; + + if (s->read_selected) + { + if (s->read_ready) + { + select_printf ("%s, already ready for read", fh->get_name ()); + gotone = 1; + goto out; + } + + if (fh->get_readahead_valid ()) + { + select_printf ("readahead"); + gotone = s->read_ready = true; + goto out; + } + + if (fh->hit_eof ()) + { + select_printf ("read: %s, saw EOF", fh->get_name ()); + gotone = s->read_ready = true; + if (s->except_selected) + gotone += s->except_ready = true; + goto out; + } + + fh->fifo_client_lock (); + for (int i = 0; i < fh->get_nclients (); i++) + if (fh->is_connected (i)) + { + int n = pipe_data_available (s->fd, fh, fh->get_handle (i), + false); + if (n > 0) + { + select_printf ("read: %s, ready for read: avail %d, client %d", + fh->get_name (), n, i); + fh->fifo_client_unlock (); + gotone += s->read_ready = true; + goto out; + } + } + fh->fifo_client_unlock (); + } +out: + if (s->write_selected) + { + gotone += s->write_ready + = pipe_data_available (s->fd, fh, fh->get_handle (), true); + select_printf ("write: %s, gotone %d", fh->get_name (), gotone); + } + return gotone; +} + +static int start_thread_fifo (select_record *me, select_stuff *stuff); + +static DWORD WINAPI +thread_fifo (void *arg) +{ + select_fifo_info *pi = (select_fifo_info *) arg; + DWORD sleep_time = 0; + bool looping = true; + + while (looping) + { + for (select_record *s = pi->start; (s = s->next); ) + if (s->startup == start_thread_fifo) + { + if (peek_fifo (s, true)) + looping = false; + if (pi->stop_thread) + { + select_printf ("stopping"); + looping = false; + break; + } + } + if (!looping) + break; + Sleep (sleep_time >> 3); + if (sleep_time < 80) + ++sleep_time; + if (pi->stop_thread) + break; + } + return 0; +} + +static int +start_thread_fifo (select_record *me, select_stuff *stuff) +{ + select_fifo_info *pi = stuff->device_specific_fifo; + if (pi->start) + me->h = *((select_fifo_info *) stuff->device_specific_fifo)->thread; + else + { + pi->start = &stuff->start; + pi->stop_thread = false; + pi->thread = new cygthread (thread_fifo, pi, "fifosel"); + me->h = *pi->thread; + if (!me->h) + return 0; + } + return 1; +} + +static void +fifo_cleanup (select_record *, select_stuff *stuff) +{ + select_fifo_info *pi = (select_fifo_info *) stuff->device_specific_fifo; + if (!pi) + return; + if (pi->thread) + { + pi->stop_thread = true; + pi->thread->detach (); + } + delete pi; + stuff->device_specific_fifo = NULL; +} + select_record * fhandler_fifo::select_read (select_stuff *ss) { - if (!ss->device_specific_pipe - && (ss->device_specific_pipe = new select_pipe_info) == NULL) + if (!ss->device_specific_fifo + && (ss->device_specific_fifo = new select_fifo_info) == NULL) return NULL; select_record *s = ss->start.next; - s->startup = start_thread_pipe; - s->peek = peek_pipe; + s->startup = start_thread_fifo; + s->peek = peek_fifo; s->verify = verify_ok; - s->cleanup = pipe_cleanup; + s->cleanup = fifo_cleanup; s->read_selected = true; s->read_ready = false; return s; @@ -841,14 +972,14 @@ fhandler_fifo::select_read (select_stuff *ss) select_record * fhandler_fifo::select_write (select_stuff *ss) { - if (!ss->device_specific_pipe - && (ss->device_specific_pipe = new select_pipe_info) == NULL) + if (!ss->device_specific_fifo + && (ss->device_specific_fifo = new select_fifo_info) == NULL) return NULL; select_record *s = ss->start.next; - s->startup = start_thread_pipe; - s->peek = peek_pipe; + s->startup = start_thread_fifo; + s->peek = peek_fifo; s->verify = verify_ok; - s->cleanup = pipe_cleanup; + s->cleanup = fifo_cleanup; s->write_selected = true; s->write_ready = false; return s; @@ -857,14 +988,14 @@ fhandler_fifo::select_write (select_stuff *ss) select_record * fhandler_fifo::select_except (select_stuff *ss) { - if (!ss->device_specific_pipe - && (ss->device_specific_pipe = new select_pipe_info) == NULL) + if (!ss->device_specific_fifo + && (ss->device_specific_fifo = new select_fifo_info) == NULL) return NULL; select_record *s = ss->start.next; - s->startup = start_thread_pipe; - s->peek = peek_pipe; + s->startup = start_thread_fifo; + s->peek = peek_fifo; s->verify = verify_ok; - s->cleanup = pipe_cleanup; + s->cleanup = fifo_cleanup; s->except_selected = true; s->except_ready = false; return s; diff --git a/winsup/cygwin/select.h b/winsup/cygwin/select.h index 71821f76c..19f9d7dc2 100644 --- a/winsup/cygwin/select.h +++ b/winsup/cygwin/select.h @@ -53,6 +53,11 @@ struct select_pipe_info: public select_info select_pipe_info (): select_info () {} }; +struct select_fifo_info: public select_info +{ + select_fifo_info (): select_info () {} +}; + struct select_socket_info: public select_info { int num_w4; @@ -89,6 +94,7 @@ public: select_record start; select_pipe_info *device_specific_pipe; + select_fifo_info *device_specific_fifo; select_socket_info *device_specific_socket; select_serial_info *device_specific_serial; select_signalfd_info *device_specific_signalfd; @@ -102,6 +108,7 @@ public: select_stuff (): return_on_signal (false), always_ready (false), windows_used (false), start (), device_specific_pipe (NULL), + device_specific_fifo (NULL), device_specific_socket (NULL), device_specific_serial (NULL), device_specific_signalfd (NULL) {} From 40db74128ad2ed2431cd67f1c14ab50d4859d4df Mon Sep 17 00:00:00 2001 From: Ken Brown Date: Mon, 25 Mar 2019 23:06:09 +0000 Subject: [PATCH 311/475] Cygwin: FIFO: avoid crashes when cloning a client fhandler_fifo::clone called fhandler_base::clone on each client fhandler. But those fhandlers are actually fhandler_fifo objects, so when fhandler_base::clone calls copyto, it's actually fhandler_fifo::copyto that gets called. This can lead to mysterious crashes. Fix this by simply calling clone (which translates to fhandler_fifo::clone) on each client fhandler. --- winsup/cygwin/fhandler.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h index f6982f0ba..ef34f9c40 100644 --- a/winsup/cygwin/fhandler.h +++ b/winsup/cygwin/fhandler.h @@ -1316,7 +1316,7 @@ public: fhandler_fifo *fhf = new (ptr) fhandler_fifo (ptr); copyto (fhf); for (int i = 0; i < nclients; i++) - fhf->client[i].fh = client[i].fh->fhandler_base::clone (); + fhf->client[i].fh = client[i].fh->clone (); return fhf; } }; From a137da74bae803a4770dce9a6f38f1def582fe80 Mon Sep 17 00:00:00 2001 From: Ken Brown Date: Mon, 25 Mar 2019 23:06:10 +0000 Subject: [PATCH 312/475] Cygwin: FIFO: add support for the duplex case If a FIFO is opened with O_RDWR access, create the pipe with read/write access, and make the first client have the handle of that pipe as its I/O handle. Adjust fhandler_fifo::raw_read to account for the result of trying to read from that client if there's no data. --- winsup/cygwin/fhandler.h | 5 +++ winsup/cygwin/fhandler_fifo.cc | 79 +++++++++++++++++++++++++++++----- 2 files changed, 73 insertions(+), 11 deletions(-) diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h index ef34f9c40..3398cc625 100644 --- a/winsup/cygwin/fhandler.h +++ b/winsup/cygwin/fhandler.h @@ -1253,6 +1253,10 @@ struct fifo_client_handler HANDLE dummy_evt; /* Never signaled. */ fifo_client_handler () : fh (NULL), state (fc_unknown), connect_evt (NULL), dummy_evt (NULL) {} + fifo_client_handler (fhandler_base *_fh, fifo_client_connect_state _state, + HANDLE _connect_evt, HANDLE _dummy_evt) + : fh (_fh), state (_state), connect_evt (_connect_evt), + dummy_evt (_dummy_evt) {} int connect (); int close (); }; @@ -1268,6 +1272,7 @@ class fhandler_fifo: public fhandler_base fifo_client_handler client[MAX_CLIENTS]; int nclients, nconnected; af_unix_spinlock_t _fifo_client_lock; + bool _duplexer; bool __reg2 wait (HANDLE); NTSTATUS npfs_handle (HANDLE &); HANDLE create_pipe_instance (bool); diff --git a/winsup/cygwin/fhandler_fifo.cc b/winsup/cygwin/fhandler_fifo.cc index 2c20444c6..7847cca82 100644 --- a/winsup/cygwin/fhandler_fifo.cc +++ b/winsup/cygwin/fhandler_fifo.cc @@ -33,7 +33,7 @@ STATUS_PIPE_EMPTY simply means there's no data to be read. */ fhandler_fifo::fhandler_fifo (): fhandler_base (), read_ready (NULL), write_ready (NULL), listen_client_thr (NULL), lct_termination_evt (NULL), nclients (0), - nconnected (0) + nconnected (0), _duplexer (false) { pipe_name_buf[0] = L'\0'; need_fork_fixup (true); @@ -224,6 +224,8 @@ fhandler_fifo::create_pipe_instance (bool first) } access = GENERIC_READ | FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES | SYNCHRONIZE; + if (first && _duplexer) + access |= GENERIC_WRITE; sharing = FILE_SHARE_READ | FILE_SHARE_WRITE; hattr = OBJ_INHERIT; if (first) @@ -437,7 +439,7 @@ fhandler_fifo::open (int flags, mode_t) case O_RDWR: reader = true; writer = false; - duplexer = true; + duplexer = _duplexer = true; break; default: set_errno (EINVAL); @@ -447,7 +449,7 @@ fhandler_fifo::open (int flags, mode_t) debug_only_printf ("reader %d, writer %d, duplexer %d", reader, writer, duplexer); set_flags (flags); - if (reader) + if (reader && !duplexer) nohandle (true); /* Create control events for this named pipe */ @@ -472,6 +474,48 @@ fhandler_fifo::open (int flags, mode_t) goto out; } + /* If we're a duplexer, create the pipe and the first client. */ + if (duplexer) + { + HANDLE ph, connect_evt, dummy_evt; + fhandler_base *fh; + + ph = create_pipe_instance (true); + if (!ph) + { + res = error_errno_set; + goto out; + } + set_io_handle (ph); + set_pipe_non_blocking (ph, true); + if (!(fh = build_fh_dev (dev ()))) + { + set_errno (EMFILE); + res = error_errno_set; + goto out; + } + fh->set_io_handle (ph); + fh->set_flags (flags); + if (!(connect_evt = create_event ())) + { + res = error_errno_set; + fh->close (); + delete fh; + goto out; + } + if (!(dummy_evt = create_event ())) + { + res = error_errno_set; + delete fh; + fh->close (); + CloseHandle (connect_evt); + goto out; + } + client[0] = fifo_client_handler (fh, fc_connected, connect_evt, + dummy_evt); + nconnected = nclients = 1; + } + /* If we're reading, start the listen_client thread (which should signal read_ready), and wait for a writer. */ if (reader) @@ -482,8 +526,8 @@ fhandler_fifo::open (int flags, mode_t) res = error_errno_set; goto out; } - /* Wait for the listen_client thread to create the pipe and - signal read_ready. This should be quick. */ + /* Wait for the listen_client thread to signal read_ready. This + should be quick. */ HANDLE w[2] = { listen_client_thr, read_ready }; switch (WaitForMultipleObjects (2, w, FALSE, INFINITE)) { @@ -703,12 +747,25 @@ fhandler_fifo::raw_read (void *in_ptr, size_t& len) fifo_client_unlock (); return; } - else if (nread < 0 && GetLastError () != ERROR_NO_DATA) - { - fifo_client_unlock (); - goto errout; - } - else if (nread == 0) /* Client has disconnected. */ + /* In the duplex case with no data, we seem to get nread + == -1 with ERROR_PIPE_LISTENING on the first attempt to + read from the duplex pipe (client[0]), and nread == 0 + on subsequent attempts. */ + else if (nread < 0) + switch (GetLastError ()) + { + case ERROR_NO_DATA: + break; + case ERROR_PIPE_LISTENING: + if (_duplexer && i == 0) + break; + /* Fall through. */ + default: + fifo_client_unlock (); + goto errout; + } + else if (nread == 0 && (!_duplexer || i > 0)) + /* Client has disconnected. */ { client[i].state = fc_invalid; nconnected--; From f46c9ab46c46cd2bf02eb5e5af591e19b1c5a10a Mon Sep 17 00:00:00 2001 From: "J.H. van de Water" Date: Wed, 27 Mar 2019 17:01:03 +0100 Subject: [PATCH 313/475] Cygwin: fix: seteuid32() must return EPERM if privileges are not held. Starting w/ the intro of S4U, seteuid32() calls lsaprivkeyauth(), then s4uauth(). s4uauth calls LsaRegisterLogonProcess(). LsaRegisterLogonProcess fails w/ STATUS_PORT_CONNECTION_REFUSED, if the proper privileges are not held. Because of RtlNtStatusToDosError(), this status would be mapped to ERROR_ACCESS_DENIED, which in turn would map to EACCES. Therefore it is useless to add this status to errmap[] (errno.cc), as s4auauth() should return EPERM as errno here (i.e. if process is not privileged). Hence the kludge. Before the intro of S4U, seteuid32() called lsaprivkeyauth(), then lsaauth(), then create_token(). Before the intro of Vista, the latter would have called NtCreateToken(). NtCreateToken() would have failed w/ STATUS_PRIVILEGE_NOT_HELD for a process w/o the proper privileges. In that case, calling seteuid32() would have returned EPERM (as required). Since the intro of Vista, and if the process had been started from an UNelevated shell, create_token() does NOT reach NtCreateToken()! As create_token() failed to properly set errno in that case, calling seteuid32() would return errno as set by lsaauth(), i.e. EACCES, not in agreement w/ Posix (a bug which was present for years). (lsaauth() called LsaRegisterLogonProcess() which would fail) --- winsup/cygwin/sec_auth.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/winsup/cygwin/sec_auth.cc b/winsup/cygwin/sec_auth.cc index a76f4534b..83fb39bc5 100644 --- a/winsup/cygwin/sec_auth.cc +++ b/winsup/cygwin/sec_auth.cc @@ -1539,6 +1539,9 @@ s4uauth (bool logon, PCWSTR domain, PCWSTR user, NTSTATUS &ret_status) { debug_printf ("%s: %y", logon ? "LsaRegisterLogonProcess" : "LsaConnectUntrusted", status); + /* If the privilege is not held, set the proper error code. */ + if (status == STATUS_PORT_CONNECTION_REFUSED) + status = STATUS_PRIVILEGE_NOT_HELD; __seterrno_from_nt_status (status); goto out; } From 298581868a5de6747abe8044bf64e5c2379058f8 Mon Sep 17 00:00:00 2001 From: Ken Brown Date: Wed, 27 Mar 2019 18:10:18 +0000 Subject: [PATCH 314/475] Cygwin: document the recent FIFO changes --- winsup/cygwin/release/3.1.0 | 14 ++++++++++++++ winsup/doc/new-features.xml | 12 ++++++++++++ 2 files changed, 26 insertions(+) create mode 100644 winsup/cygwin/release/3.1.0 diff --git a/winsup/cygwin/release/3.1.0 b/winsup/cygwin/release/3.1.0 new file mode 100644 index 000000000..1f017bfd1 --- /dev/null +++ b/winsup/cygwin/release/3.1.0 @@ -0,0 +1,14 @@ +What's new: +----------- + + +What changed: +------------- + +- FIFOs can now be opened multiple times for writing. + Addresses: https://cygwin.com/ml/cygwin/2015-03/msg00047.html + https://cygwin.com/ml/cygwin/2015-12/msg00311.html + + +Bug Fixes +--------- diff --git a/winsup/doc/new-features.xml b/winsup/doc/new-features.xml index e14fbb1e8..c87601e9d 100644 --- a/winsup/doc/new-features.xml +++ b/winsup/doc/new-features.xml @@ -4,6 +4,18 @@ What's new and what changed in Cygwin +What's new and what changed in 3.1 + + + + +FIFOs can now be opened multiple times for writing. + + + + + + What's new and what changed in 3.0 From e0fd15c91b206ff788148b8dd2a37a80c8cad175 Mon Sep 17 00:00:00 2001 From: Ken Brown Date: Wed, 27 Mar 2019 21:29:21 +0000 Subject: [PATCH 315/475] Cygwin: FIFO: implement clear_readahead Make fhandler_base::clear_readahead virtual, and implement fhandler_fifo::clear_readahead. This is called by dtable::fixup_after_exec; it clears the readahead in each client. --- winsup/cygwin/fhandler.h | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h index 3398cc625..21fec9e38 100644 --- a/winsup/cygwin/fhandler.h +++ b/winsup/cygwin/fhandler.h @@ -444,7 +444,7 @@ public: return dev ().native (); } virtual bg_check_types bg_check (int, bool = false) {return bg_ok;} - void clear_readahead () + virtual void clear_readahead () { raixput = raixget = ralen = rabuflen = 0; rabuf = NULL; @@ -1302,6 +1302,12 @@ public: bool arm (HANDLE h); void fixup_after_fork (HANDLE); int __reg2 fstatvfs (struct statvfs *buf); + void clear_readahead () + { + fhandler_base::clear_readahead (); + for (int i = 0; i < nclients; i++) + client[i].fh->clear_readahead (); + } select_record *select_read (select_stuff *); select_record *select_write (select_stuff *); select_record *select_except (select_stuff *); From 023c107a22ebd2f540fa3f4888535aad32839fe2 Mon Sep 17 00:00:00 2001 From: Michael Haubenwallner Date: Tue, 26 Mar 2019 17:38:36 +0100 Subject: [PATCH 316/475] Cygwin: fork: reserve dynloaded dll areas earlier In dll_crt0_0, both threadinterface->Init and sigproc_init allocate windows object handles using unpredictable memory regions, which may collide with dynamically loaded dlls when they were relocated. --- winsup/cygwin/dcrt0.cc | 6 ++++++ winsup/cygwin/fork.cc | 6 ------ 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/winsup/cygwin/dcrt0.cc b/winsup/cygwin/dcrt0.cc index 11edcdf0d..fb726a739 100644 --- a/winsup/cygwin/dcrt0.cc +++ b/winsup/cygwin/dcrt0.cc @@ -632,6 +632,12 @@ child_info_fork::handle_fork () if (fixup_mmaps_after_fork (parent)) api_fatal ("recreate_mmaps_after_fork_failed"); + + /* We need to occupy the address space for dynamically loaded dlls + before we allocate any dynamic object, or we may end up with + error "address space needed by is already occupied" + for no good reason (seen with some relocated dll). */ + dlls.reserve_space (); } bool diff --git a/winsup/cygwin/fork.cc b/winsup/cygwin/fork.cc index 74ee9acf4..7e1c08990 100644 --- a/winsup/cygwin/fork.cc +++ b/winsup/cygwin/fork.cc @@ -136,12 +136,6 @@ frok::child (volatile char * volatile here) { HANDLE& hParent = ch.parent; - /* NOTE: Logically this belongs in dll_list::load_after_fork, but by - doing it here, before the first sync_with_parent, we can exploit - the existing retry mechanism in hopes of getting a more favorable - address space layout next time. */ - dlls.reserve_space (); - sync_with_parent ("after longjmp", true); debug_printf ("child is running. pid %d, ppid %d, stack here %p", myself->pid, myself->ppid, __builtin_frame_address (0)); From a9c661a94d658bbc07dcb4f2c41e07f213584d7f Mon Sep 17 00:00:00 2001 From: Takashi Yano Date: Sat, 30 Mar 2019 16:12:02 +0900 Subject: [PATCH 317/475] Cygwin: [gs]et_io_handle(): renamed to [gs]et_handle(). - Unify get_io_handle() and get_handle() to get_handle(). Both of them returned same value; io_handle. - Rename set_io_handle() to set_handle(). --- winsup/cygwin/dtable.cc | 16 +++++++-------- winsup/cygwin/fhandler.cc | 12 ++++++------ winsup/cygwin/fhandler.h | 9 +++++---- winsup/cygwin/fhandler_console.cc | 26 ++++++++++++------------- winsup/cygwin/fhandler_disk_file.cc | 16 +++++++-------- winsup/cygwin/fhandler_fifo.cc | 12 ++++++------ winsup/cygwin/fhandler_pipe.cc | 2 +- winsup/cygwin/fhandler_process_fd.cc | 6 +++--- winsup/cygwin/fhandler_registry.cc | 6 +++--- winsup/cygwin/fhandler_socket_inet.cc | 10 +++++----- winsup/cygwin/fhandler_socket_unix.cc | 16 +++++++-------- winsup/cygwin/fhandler_tty.cc | 28 +++++++++++++-------------- winsup/cygwin/mmap.cc | 6 +++--- winsup/cygwin/select.cc | 8 ++++---- 14 files changed, 87 insertions(+), 86 deletions(-) diff --git a/winsup/cygwin/dtable.cc b/winsup/cygwin/dtable.cc index 86e0c716d..636221a77 100644 --- a/winsup/cygwin/dtable.cc +++ b/winsup/cygwin/dtable.cc @@ -647,7 +647,7 @@ build_fh_pc (path_conv& pc) else if ((fh->archetype = cygheap->fdtab.find_archetype (fh->dev ()))) { debug_printf ("found an archetype for %s(%d/%d) io_handle %p", fh->get_name (), fh->dev ().get_major (), fh->dev ().get_minor (), - fh->archetype->get_io_handle ()); + fh->archetype->get_handle ()); if (!fh->get_name ()) fh->set_name (fh->archetype->dev ().name ()); } @@ -688,7 +688,7 @@ dtable::dup_worker (fhandler_base *oldfh, int flags) else { if (!oldfh->archetype) - newfh->set_io_handle (NULL); + newfh->set_handle (NULL); newfh->pc.reset_conv_handle (); if (oldfh->dup (newfh, flags)) @@ -708,7 +708,7 @@ dtable::dup_worker (fhandler_base *oldfh, int flags) /* The O_CLOEXEC flag enforces close-on-exec behaviour. */ newfh->set_close_on_exec (!!(flags & O_CLOEXEC)); debug_printf ("duped '%s' old %p, new %p", oldfh->get_name (), - oldfh->get_io_handle (), newfh->get_io_handle ()); + oldfh->get_handle (), newfh->get_handle ()); } } return newfh; @@ -765,7 +765,7 @@ dtable::dup3 (int oldfd, int newfd, int flags) } debug_printf ("newfh->io_handle %p, oldfh->io_handle %p, new win32_name %p, old win32_name %p", - newfh->get_io_handle (), fds[oldfd]->get_io_handle (), newfh->get_win32_name (), fds[oldfd]->get_win32_name ()); + newfh->get_handle (), fds[oldfd]->get_handle (), newfh->get_win32_name (), fds[oldfd]->get_win32_name ()); if (!not_open (newfd)) close (newfd); @@ -891,12 +891,12 @@ dtable::fixup_after_exec () /* Close the handle if it's close-on-exec or if an error was detected (typically with opening a console in a gui app) by fixup_after_exec. */ - if (fh->close_on_exec () || (!fh->nohandle () && !fh->get_io_handle ())) + if (fh->close_on_exec () || (!fh->nohandle () && !fh->get_handle ())) fixup_close (i, fh); else if (fh->get_popen_pid ()) close (i); else if (i == 0) - SetStdHandle (std_consts[i], fh->get_io_handle ()); + SetStdHandle (std_consts[i], fh->get_handle ()); else if (i <= 2) SetStdHandle (std_consts[i], fh->get_output_handle ()); } @@ -913,7 +913,7 @@ dtable::fixup_after_fork (HANDLE parent) { debug_printf ("fd %d (%s)", i, fh->get_name ()); fh->fixup_after_fork (parent); - if (!fh->nohandle () && !fh->get_io_handle ()) + if (!fh->nohandle () && !fh->get_handle ()) { /* This should actually never happen but it's here to make sure we don't crash due to access of an unopened file handle. */ @@ -922,7 +922,7 @@ dtable::fixup_after_fork (HANDLE parent) } } if (i == 0) - SetStdHandle (std_consts[i], fh->get_io_handle ()); + SetStdHandle (std_consts[i], fh->get_handle ()); else if (i <= 2) SetStdHandle (std_consts[i], fh->get_output_handle ()); } diff --git a/winsup/cygwin/fhandler.cc b/winsup/cygwin/fhandler.cc index 659435e0a..b0c9c50c3 100644 --- a/winsup/cygwin/fhandler.cc +++ b/winsup/cygwin/fhandler.cc @@ -461,7 +461,7 @@ fhandler_base::open_with_arch (int flags, mode_t mode) } else if (archetype) { - if (!archetype->get_io_handle ()) + if (!archetype->get_handle ()) { copyto (archetype); archetype_usecount (1); @@ -522,7 +522,7 @@ fhandler_base::open_null (int flags) __seterrno_from_nt_status (status); goto done; } - set_io_handle (fh); + set_handle (fh); set_flags (flags, pc.binmode ()); res = 1; set_open_status (); @@ -775,7 +775,7 @@ fhandler_base::open (int flags, mode_t mode) } } - set_io_handle (fh); + set_handle (fh); set_flags (flags, pc.binmode ()); res = 1; @@ -1298,7 +1298,7 @@ fhandler_base_overlapped::close () /* Cancelling seems to be necessary for cases where a reader is still executing when a signal handler performs a close. */ if (!writer) - CancelIo (get_io_handle ()); + CancelIo (get_handle ()); destroy_overlapped (); res = fhandler_base::close (); } @@ -1382,7 +1382,7 @@ fhandler_base::fstatvfs (struct statvfs *sfs) int fhandler_base::init (HANDLE f, DWORD a, mode_t bin) { - set_io_handle (f); + set_handle (f); access = a; a &= GENERIC_READ | GENERIC_WRITE; int flags = 0; @@ -1417,7 +1417,7 @@ fhandler_base::dup (fhandler_base *child, int) } VerifyHandle (nh); - child->set_io_handle (nh); + child->set_handle (nh); } return 0; } diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h index 21fec9e38..b336eb63a 100644 --- a/winsup/cygwin/fhandler.h +++ b/winsup/cygwin/fhandler.h @@ -227,7 +227,7 @@ class fhandler_base virtual ~fhandler_base (); /* Non-virtual simple accessor functions. */ - void set_io_handle (HANDLE x) { io_handle = x; } + void set_handle (HANDLE x) { io_handle = x; } dev_t& get_device () { return dev (); } _major_t get_major () { return dev ().get_major (); } @@ -430,9 +430,9 @@ public: /* Virtual accessor functions to hide the fact that some fd's have two handles. */ virtual HANDLE& get_handle () { return io_handle; } - virtual HANDLE& get_io_handle () { return io_handle; } - virtual HANDLE& get_io_handle_cyg () { return io_handle; } + virtual HANDLE& get_handle_cyg () { return io_handle; } virtual HANDLE& get_output_handle () { return io_handle; } + virtual HANDLE& get_output_handle_cyg () { return io_handle; } virtual HANDLE get_stat_handle () { return pc.handle () ?: io_handle; } virtual HANDLE get_echo_handle () const { return NULL; } virtual bool hit_eof () {return false;} @@ -1726,6 +1726,7 @@ class fhandler_termios: public fhandler_base need_fork_fixup (true); } HANDLE& get_output_handle () { return output_handle; } + HANDLE& get_output_handle_cyg () { return output_handle; } line_edit_status line_edit (const char *rptr, size_t nread, termios&, ssize_t *bytes_read = NULL); void set_output_handle (HANDLE h) { output_handle = h; } @@ -2109,7 +2110,7 @@ class fhandler_pty_master: public fhandler_pty_common public: HANDLE get_echo_handle () const { return echo_r; } - HANDLE& get_io_handle_cyg () { return io_handle_cyg; } + HANDLE& get_handle_cyg () { return io_handle_cyg; } /* Constructor */ fhandler_pty_master (int); diff --git a/winsup/cygwin/fhandler_console.cc b/winsup/cygwin/fhandler_console.cc index 6a0d640a8..281c2005c 100644 --- a/winsup/cygwin/fhandler_console.cc +++ b/winsup/cygwin/fhandler_console.cc @@ -155,7 +155,7 @@ fhandler_console::set_unit () pc.file_attributes (FILE_ATTRIBUTE_NORMAL); else { - set_io_handle (NULL); + set_handle (NULL); set_output_handle (NULL); created = false; } @@ -298,7 +298,7 @@ fhandler_console::read (void *pv, size_t& buflen) { push_process_state process_state (PID_TTYIN); - HANDLE h = get_io_handle (); + HANDLE h = get_handle (); #define buf ((char *) pv) @@ -818,7 +818,7 @@ fhandler_console::open (int flags, mode_t) tcinit (false); - set_io_handle (NULL); + set_handle (NULL); set_output_handle (NULL); /* Open the input handle as handle_ */ @@ -831,7 +831,7 @@ fhandler_console::open (int flags, mode_t) __seterrno (); return 0; } - set_io_handle (h); + set_handle (h); h = CreateFileW (L"CONOUT$", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, &sec_none, @@ -856,11 +856,11 @@ fhandler_console::open (int flags, mode_t) set_open_status (); DWORD cflags; - if (GetConsoleMode (get_io_handle (), &cflags)) - SetConsoleMode (get_io_handle (), + if (GetConsoleMode (get_handle (), &cflags)) + SetConsoleMode (get_handle (), ENABLE_WINDOW_INPUT | ENABLE_MOUSE_INPUT | cflags); - debug_printf ("opened conin$ %p, conout$ %p", get_io_handle (), + debug_printf ("opened conin$ %p, conout$ %p", get_handle (), get_output_handle ()); return 1; @@ -878,7 +878,7 @@ fhandler_console::open_setup (int flags) int fhandler_console::close () { - CloseHandle (get_io_handle ()); + CloseHandle (get_handle ()); CloseHandle (get_output_handle ()); if (!have_execed) free_console (); @@ -948,7 +948,7 @@ fhandler_console::ioctl (unsigned int cmd, void *arg) DWORD n; int ret = 0; INPUT_RECORD inp[INREC_SIZE]; - if (!PeekConsoleInputW (get_io_handle (), inp, INREC_SIZE, &n)) + if (!PeekConsoleInputW (get_handle (), inp, INREC_SIZE, &n)) { set_errno (EINVAL); return -1; @@ -972,7 +972,7 @@ fhandler_console::tcflush (int queue) if (queue == TCIFLUSH || queue == TCIOFLUSH) { - if (!FlushConsoleInputBuffer (get_io_handle ())) + if (!FlushConsoleInputBuffer (get_handle ())) { __seterrno (); res = -1; @@ -1004,7 +1004,7 @@ fhandler_console::input_tcsetattr (int, struct termios const *t) DWORD oflags; - if (!GetConsoleMode (get_io_handle (), &oflags)) + if (!GetConsoleMode (get_handle (), &oflags)) oflags = 0; DWORD flags = 0; @@ -1050,7 +1050,7 @@ fhandler_console::input_tcsetattr (int, struct termios const *t) res = 0; else { - res = SetConsoleMode (get_io_handle (), flags) ? 0 : -1; + res = SetConsoleMode (get_handle (), flags) ? 0 : -1; if (res < 0) __seterrno (); syscall_printf ("%d = tcsetattr(,%p) enable flags %y, c_lflag %y iflag %y", @@ -1080,7 +1080,7 @@ fhandler_console::tcgetattr (struct termios *t) DWORD flags; - if (!GetConsoleMode (get_io_handle (), &flags)) + if (!GetConsoleMode (get_handle (), &flags)) { __seterrno (); res = -1; diff --git a/winsup/cygwin/fhandler_disk_file.cc b/winsup/cygwin/fhandler_disk_file.cc index 193192762..84d86456b 100644 --- a/winsup/cygwin/fhandler_disk_file.cc +++ b/winsup/cygwin/fhandler_disk_file.cc @@ -212,7 +212,7 @@ fhandler_base::fstat_by_nfs_ea (struct stat *buf) cyg_ldap cldap; bool ldap_open = false; - if (get_io_handle ()) + if (get_handle ()) { /* NFS stumbles over its own caching. If you write to the file, a subsequent fstat does not return the actual size of the file, @@ -220,8 +220,8 @@ fhandler_base::fstat_by_nfs_ea (struct stat *buf) access through another handle invalidates the caching within the NFS client. */ if (get_access () & GENERIC_WRITE) - FlushFileBuffers (get_io_handle ()); - pc.get_finfo (get_io_handle ()); + FlushFileBuffers (get_handle ()); + pc.get_finfo (get_handle ()); } buf->st_dev = nfs_attr->fsid; buf->st_ino = nfs_attr->fileid; @@ -291,7 +291,7 @@ fhandler_base::fstat_by_handle (struct stat *buf) /* If the file has been opened for other purposes than stat, we can't rely on the information stored in pc.fai. So we overwrite them here. */ - if (get_io_handle ()) + if (get_handle ()) { status = pc.get_finfo (h); if (!NT_SUCCESS (status)) @@ -386,7 +386,7 @@ fhandler_base::fstat_fs (struct stat *buf) nohandle (false); close_fs (); nohandle (no_handle); - set_io_handle (NULL); + set_handle (NULL); } if (res) res = fstat_by_name (buf); @@ -1465,7 +1465,7 @@ fhandler_base::open_fs (int flags, mode_t mode) /* The file info in pc is wrong at this point for newly created files. Refresh it before fetching any file info. */ if (new_file) - pc.get_finfo (get_io_handle ()); + pc.get_finfo (get_handle ()); if (pc.isgood_inode (pc.get_ino ())) ino = pc.get_ino (); @@ -2615,7 +2615,7 @@ fhandler_disk_file::fs_ioc_setflags (uint64_t flags) if (fh != get_handle ()) NtClose (fh); NtClose (get_handle ()); - set_io_handle (NULL); + set_handle (NULL); pc.get_wide_win32_path (path); cret = (flags & FS_ENCRYPT_FL) @@ -2630,7 +2630,7 @@ fhandler_disk_file::fs_ioc_setflags (uint64_t flags) __seterrno_from_nt_status (status); return -1; } - set_io_handle (fh); + set_handle (fh); if (!cret) { __seterrno (); diff --git a/winsup/cygwin/fhandler_fifo.cc b/winsup/cygwin/fhandler_fifo.cc index 7847cca82..68b9e7717 100644 --- a/winsup/cygwin/fhandler_fifo.cc +++ b/winsup/cygwin/fhandler_fifo.cc @@ -266,7 +266,7 @@ fhandler_fifo::open_pipe () sharing = FILE_SHARE_READ | FILE_SHARE_WRITE; status = NtOpenFile (&ph, access, &attr, &io, sharing, 0); if (NT_SUCCESS (status)) - set_io_handle (ph); + set_handle (ph); return status; } @@ -293,7 +293,7 @@ fhandler_fifo::add_client () HANDLE ph = create_pipe_instance (first); if (!ph) goto errout; - fh->set_io_handle (ph); + fh->set_handle (ph); fh->set_flags (get_flags ()); if (fc.connect () < 0) { @@ -486,7 +486,7 @@ fhandler_fifo::open (int flags, mode_t) res = error_errno_set; goto out; } - set_io_handle (ph); + set_handle (ph); set_pipe_non_blocking (ph, true); if (!(fh = build_fh_dev (dev ()))) { @@ -494,7 +494,7 @@ fhandler_fifo::open (int flags, mode_t) res = error_errno_set; goto out; } - fh->set_io_handle (ph); + fh->set_handle (ph); fh->set_flags (flags); if (!(connect_evt = create_event ())) { @@ -604,8 +604,8 @@ out: CloseHandle (write_ready); write_ready = NULL; } - if (get_io_handle ()) - CloseHandle (get_io_handle ()); + if (get_handle ()) + CloseHandle (get_handle ()); if (listen_client_thr) CloseHandle (listen_client_thr); } diff --git a/winsup/cygwin/fhandler_pipe.cc b/winsup/cygwin/fhandler_pipe.cc index 31e73ceb0..edbaded68 100644 --- a/winsup/cygwin/fhandler_pipe.cc +++ b/winsup/cygwin/fhandler_pipe.cc @@ -97,7 +97,7 @@ fhandler_pipe::open (int flags, mode_t mode) || (rwflags == O_WRONLY && !(cfd->get_access () & GENERIC_WRITE))) continue; cfd->copyto (this); - set_io_handle (NULL); + set_handle (NULL); pc.reset_conv_handle (); if (!cfd->dup (this, flags)) return 1; diff --git a/winsup/cygwin/fhandler_process_fd.cc b/winsup/cygwin/fhandler_process_fd.cc index 3bf8b74d8..71ba8b645 100644 --- a/winsup/cygwin/fhandler_process_fd.cc +++ b/winsup/cygwin/fhandler_process_fd.cc @@ -116,7 +116,7 @@ fhandler_process_fd::fd_reopen (int flags, mode_t mode) fh = fetch_fh (hdl, 0); if (!fh) return NULL; - fh->set_io_handle (hdl); + fh->set_handle (hdl); int ret = fh->open_with_arch (flags, mode); CloseHandle (hdl); if (!ret) @@ -139,7 +139,7 @@ fhandler_process_fd::fstat (struct stat *statbuf) fh = fetch_fh (hdl, 0); if (!fh) return -1; - fh->set_io_handle (hdl); + fh->set_handle (hdl); int ret = fh->fstat (statbuf); CloseHandle (hdl); delete fh; @@ -155,7 +155,7 @@ fhandler_process_fd::link (const char *newpath) fh = fetch_fh (hdl, FFH_LINKAT); if (!fh) return -1; - fh->set_io_handle (hdl); + fh->set_handle (hdl); int ret = fh->link (newpath); CloseHandle (hdl); delete fh; diff --git a/winsup/cygwin/fhandler_registry.cc b/winsup/cygwin/fhandler_registry.cc index 6c6702afd..ecaed085c 100644 --- a/winsup/cygwin/fhandler_registry.cc +++ b/winsup/cygwin/fhandler_registry.cc @@ -826,7 +826,7 @@ fhandler_registry::open (int flags, mode_t mode) } else { - set_io_handle (fetch_hkey (i)); + set_handle (fetch_hkey (i)); /* Marking as nohandle allows to call dup on pseudo registry handles. */ if (get_handle () >= HKEY_CLASSES_ROOT) @@ -881,7 +881,7 @@ fhandler_registry::open (int flags, mode_t mode) else flags |= O_DIROPEN; - set_io_handle (handle); + set_handle (handle); set_close_on_exec (!!(flags & O_CLOEXEC)); value_name = cwcsdup (dec_file); @@ -1118,7 +1118,7 @@ fhandler_registry::dup (fhandler_base *child, int flags) allows fhandler_base::dup to succeed as usual for nohandle fhandlers. Here we just have to fix up by copying the pseudo handle value. */ if ((HKEY) get_handle () >= HKEY_CLASSES_ROOT) - fhs->set_io_handle (get_handle ()); + fhs->set_handle (get_handle ()); if (value_name) fhs->value_name = cwcsdup (value_name); return ret; diff --git a/winsup/cygwin/fhandler_socket_inet.cc b/winsup/cygwin/fhandler_socket_inet.cc index dbfbcf588..46af1c4be 100644 --- a/winsup/cygwin/fhandler_socket_inet.cc +++ b/winsup/cygwin/fhandler_socket_inet.cc @@ -518,14 +518,14 @@ fhandler_socket_wsock::fixup_after_fork (HANDLE parent) if (new_sock == INVALID_SOCKET) { set_winsock_errno (); - set_io_handle ((HANDLE) INVALID_SOCKET); + set_handle ((HANDLE) INVALID_SOCKET); } else { /* Even though the original socket was not inheritable, the duplicated socket is potentially inheritable again. */ SetHandleInformation ((HANDLE) new_sock, HANDLE_FLAG_INHERIT, 0); - set_io_handle ((HANDLE) new_sock); + set_handle ((HANDLE) new_sock); debug_printf ("WSASocket succeeded (%p)", new_sock); } } @@ -571,13 +571,13 @@ fhandler_socket_wsock::dup (fhandler_base *child, int flags) cygheap->user.deimpersonate (); fhs->init_fixup_before (); - fhs->set_io_handle (get_io_handle ()); + fhs->set_handle (get_handle ()); int ret = fhs->fixup_before_fork_exec (GetCurrentProcessId ()); cygheap->user.reimpersonate (); if (!ret) { fhs->fixup_after_fork (GetCurrentProcess ()); - if (fhs->get_io_handle() != (HANDLE) INVALID_SOCKET) + if (fhs->get_handle() != (HANDLE) INVALID_SOCKET) return 0; } cygheap->fdtab.dec_need_fixup_before (); @@ -645,7 +645,7 @@ fhandler_socket_wsock::set_socket_handle (SOCKET sock, int af, int type, } } } - set_io_handle ((HANDLE) sock); + set_handle ((HANDLE) sock); set_addr_family (af); set_socket_type (type); if (!init_events ()) diff --git a/winsup/cygwin/fhandler_socket_unix.cc b/winsup/cygwin/fhandler_socket_unix.cc index e71d2a722..eea7e76b3 100644 --- a/winsup/cygwin/fhandler_socket_unix.cc +++ b/winsup/cygwin/fhandler_socket_unix.cc @@ -938,7 +938,7 @@ fhandler_socket_unix::open_pipe (PUNICODE_STRING pipe_name, bool xchg_sock_info) status = NtOpenFile (&ph, access, &attr, &io, sharing, 0); if (NT_SUCCESS (status)) { - set_io_handle (ph); + set_handle (ph); if (xchg_sock_info) send_sock_info (false); } @@ -1365,7 +1365,7 @@ fhandler_socket_unix::socket (int af, int type, int protocol, int flags) if (flags & SOCK_CLOEXEC) set_close_on_exec (true); init_cred (); - set_io_handle (NULL); + set_handle (NULL); set_unique_id (); set_ino (get_unique_id ()); return 0; @@ -1412,7 +1412,7 @@ fhandler_socket_unix::socketpair (int af, int type, int protocol, int flags, pipe = create_pipe (true); if (!pipe) goto create_pipe_failed; - set_io_handle (pipe); + set_handle (pipe); sun_path (&sun); fh->peer_sun_path (&sun); connect_state (listener); @@ -1483,12 +1483,12 @@ fhandler_socket_unix::bind (const struct sockaddr *name, int namelen) binding_state (unbound); return -1; } - set_io_handle (pipe); + set_handle (pipe); } backing_file_handle = unnamed ? autobind (&sun) : create_file (&sun); if (!backing_file_handle) { - set_io_handle (NULL); + set_handle (NULL); if (pipe) NtClose (pipe); binding_state (unbound); @@ -1538,7 +1538,7 @@ fhandler_socket_unix::listen (int backlog) connect_state (unconnected); return -1; } - set_io_handle (pipe); + set_handle (pipe); state_lock (); set_cred (); state_unlock (); @@ -1575,7 +1575,7 @@ fhandler_socket_unix::accept4 (struct sockaddr *peer, int *len, int flags) else { /* Set new io handle. */ - set_io_handle (new_inst); + set_handle (new_inst); io_unlock (); /* Prepare new file descriptor. */ cygheap_fdnew fd; @@ -1600,7 +1600,7 @@ fhandler_socket_unix::accept4 (struct sockaddr *peer, int *len, int flags) sock->pc.set_nt_native_path (pc.get_nt_native_path ()); sock->connect_state (connected); sock->binding_state (binding_state ()); - sock->set_io_handle (accepted); + sock->set_handle (accepted); sock->sun_path (sun_path ()); sock->sock_cred (sock_cred ()); diff --git a/winsup/cygwin/fhandler_tty.cc b/winsup/cygwin/fhandler_tty.cc index 7fe46ebef..312c2d083 100644 --- a/winsup/cygwin/fhandler_tty.cc +++ b/winsup/cygwin/fhandler_tty.cc @@ -235,7 +235,7 @@ fhandler_pty_master::process_slave_output (char *buf, size_t len, int pktmode_on /* Check echo pipe first. */ if (::bytes_available (echo_cnt, echo_r) && echo_cnt > 0) break; - if (!::bytes_available (n, get_io_handle_cyg ())) + if (!::bytes_available (n, get_handle_cyg ())) goto err; if (n) break; @@ -296,7 +296,7 @@ fhandler_pty_master::process_slave_output (char *buf, size_t len, int pktmode_on goto err; } } - else if (!ReadFile (get_io_handle_cyg (), outbuf, rlen, &n, NULL)) + else if (!ReadFile (get_handle_cyg (), outbuf, rlen, &n, NULL)) { termios_printf ("ReadFile failed, %E"); goto err; @@ -494,7 +494,7 @@ fhandler_pty_slave::open (int flags, mode_t) termios_printf ("duplicated to_master_cyg %p->%p from pty_owner", get_ttyp ()->to_master_cyg (), to_master_cyg_local); - set_io_handle (from_master_local); + set_handle (from_master_local); set_output_handle (to_master_local); set_output_handle_cyg (to_master_cyg_local); @@ -1347,11 +1347,11 @@ fhandler_pty_master::close () if (!ForceCloseHandle (to_master)) termios_printf ("error closing to_master %p, %E", to_master); from_master = to_master = NULL; - if (!ForceCloseHandle (get_io_handle_cyg ())) - termios_printf ("error closing io_handle_cyg %p, %E", get_io_handle_cyg ()); + if (!ForceCloseHandle (get_handle_cyg ())) + termios_printf ("error closing io_handle_cyg %p, %E", get_handle_cyg ()); if (!ForceCloseHandle (to_master_cyg)) termios_printf ("error closing to_master_cyg %p, %E", to_master_cyg); - get_io_handle_cyg () = to_master_cyg = NULL; + get_handle_cyg () = to_master_cyg = NULL; ForceCloseHandle (echo_r); ForceCloseHandle (echo_w); echo_r = echo_w = NULL; @@ -1458,7 +1458,7 @@ fhandler_pty_master::ioctl (unsigned int cmd, void *arg) case FIONREAD: { DWORD n; - if (!::bytes_available (n, get_io_handle_cyg ())) + if (!::bytes_available (n, get_handle_cyg ())) { set_errno (EINVAL); return -1; @@ -1662,7 +1662,7 @@ fhandler_pty_master::pty_master_fwd_thread () termios_printf("Started."); for (;;) { - if (!ReadFile (get_io_handle (), outbuf, sizeof outbuf, &rlen, NULL)) + if (!ReadFile (get_handle (), outbuf, sizeof outbuf, &rlen, NULL)) { termios_printf ("ReadFile for forwarding failed, %E"); break; @@ -1715,7 +1715,7 @@ fhandler_pty_master::setup () char pipename[sizeof("ptyNNNN-to-master-cyg")]; __small_sprintf (pipename, "pty%d-to-master", unit); - res = fhandler_pipe::create (&sec_none, &get_io_handle (), &to_master, + res = fhandler_pipe::create (&sec_none, &get_handle (), &to_master, fhandler_pty_common::pipesize, pipename, 0); if (res) { @@ -1724,7 +1724,7 @@ fhandler_pty_master::setup () } __small_sprintf (pipename, "pty%d-to-master-cyg", unit); - res = fhandler_pipe::create (&sec_none, &get_io_handle_cyg (), &to_master_cyg, + res = fhandler_pipe::create (&sec_none, &get_handle_cyg (), &to_master_cyg, fhandler_pty_common::pipesize, pipename, 0); if (res) { @@ -1732,7 +1732,7 @@ fhandler_pty_master::setup () goto err; } - ProtectHandle1 (get_io_handle (), from_pty); + ProtectHandle1 (get_handle (), from_pty); __small_sprintf (pipename, "pty%d-echoloop", unit); res = fhandler_pipe::create (&sec_none, &echo_r, &echo_w, @@ -1807,14 +1807,14 @@ fhandler_pty_master::setup () dev ().parse (DEV_PTYM_MAJOR, unit); termios_printf ("this %p, pty%d opened - from_pty <%p,%p>, to_pty %p", - this, unit, get_io_handle (), get_io_handle_cyg (), + this, unit, get_handle (), get_handle_cyg (), get_output_handle ()); return true; err: __seterrno (); - close_maybe (get_io_handle ()); - close_maybe (get_io_handle_cyg ()); + close_maybe (get_handle ()); + close_maybe (get_handle_cyg ()); close_maybe (get_output_handle ()); close_maybe (input_available_event); close_maybe (output_mutex); diff --git a/winsup/cygwin/mmap.cc b/winsup/cygwin/mmap.cc index 1d81d534f..9eb1643a0 100644 --- a/winsup/cygwin/mmap.cc +++ b/winsup/cygwin/mmap.cc @@ -516,7 +516,7 @@ mmap_record::alloc_fh () { if (anonymous ()) { - fh_anonymous.set_io_handle (INVALID_HANDLE_VALUE); + fh_anonymous.set_handle (INVALID_HANDLE_VALUE); fh_anonymous.set_access (GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE); return &fh_anonymous; } @@ -901,7 +901,7 @@ mmap64 (void *addr, size_t len, int prot, int flags, int fd, off_t off) size_t pagesize = wincap.allocation_granularity (); - fh_anonymous.set_io_handle (INVALID_HANDLE_VALUE); + fh_anonymous.set_handle (INVALID_HANDLE_VALUE); fh_anonymous.set_access (GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE); /* EINVAL error conditions. */ @@ -1033,7 +1033,7 @@ mmap64 (void *addr, size_t len, int prot, int flags, int fd, off_t off) fh_disk_file = new (ccalloc (HEAP_FHANDLER, 1, sizeof *fh_disk_file)) fhandler_disk_file; fh_disk_file->set_name (fh->pc); - fh_disk_file->set_io_handle (h); + fh_disk_file->set_handle (h); fh_disk_file->set_access (fh->get_access () | GENERIC_EXECUTE); fh = fh_disk_file; } diff --git a/winsup/cygwin/select.cc b/winsup/cygwin/select.cc index 991494aa8..9b18e8f80 100644 --- a/winsup/cygwin/select.cc +++ b/winsup/cygwin/select.cc @@ -74,7 +74,7 @@ details. */ }) #define set_handle_or_return_if_not_open(h, s) \ - h = (s)->fh->get_io_handle_cyg (); \ + h = (s)->fh->get_handle_cyg (); \ if (cygheap->fdtab.not_open ((s)->fd)) \ { \ (s)->thread_errno = EBADF; \ @@ -1459,7 +1459,7 @@ fhandler_base::select_read (select_stuff *ss) s->startup = no_startup; s->verify = verify_ok; } - s->h = get_io_handle_cyg (); + s->h = get_handle_cyg (); s->read_selected = true; s->read_ready = true; return s; @@ -1474,7 +1474,7 @@ fhandler_base::select_write (select_stuff *ss) s->startup = no_startup; s->verify = verify_ok; } - s->h = get_handle (); + s->h = get_output_handle_cyg (); s->write_selected = true; s->write_ready = true; return s; @@ -1747,7 +1747,7 @@ fhandler_socket_unix::select_read (select_stuff *ss) s->startup = no_startup; s->verify = verify_ok; } - s->h = get_io_handle_cyg (); + s->h = get_handle_cyg (); s->read_selected = true; s->read_ready = true; return s; From 7b8049f7a3d6af99634abf20f72e1582e755d761 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Sun, 31 Mar 2019 12:49:26 +0200 Subject: [PATCH 318/475] Cygwin: document ps -W duplication bug fix Signed-off-by: Corinna Vinschen --- winsup/cygwin/release/3.0.5 | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/winsup/cygwin/release/3.0.5 b/winsup/cygwin/release/3.0.5 index a52412cd2..b17acf48a 100644 --- a/winsup/cygwin/release/3.0.5 +++ b/winsup/cygwin/release/3.0.5 @@ -14,3 +14,7 @@ Bug Fixes - Fix a crash in wcsxfrm_l if destination size is 0. Addresses: https://cygwin.com/ml/cygwin/2019-03/msg00492.html + +- Fix a problem in process enumeration which led to `ps -W' showing + Cygwin processes twice and potentially with incorrect Windows PID. + Addresses: Report on IRC From bd627864ab4189984cdb0892c00f91e39c4e8243 Mon Sep 17 00:00:00 2001 From: Takashi Yano Date: Mon, 1 Apr 2019 00:47:46 +0900 Subject: [PATCH 319/475] Cygwin: console: support 24 bit color - Add 24 bit color support using xterm compatibility mode in Windows 10 1703 or later. - Add fake 24 bit color support for legacy console, which uses the nearest color from 16 system colors. --- winsup/cygwin/environ.cc | 7 +- winsup/cygwin/fhandler.h | 4 + winsup/cygwin/fhandler_console.cc | 230 +++++++++++++++++++++++++----- winsup/cygwin/select.cc | 8 ++ winsup/cygwin/wincap.cc | 10 ++ winsup/cygwin/wincap.h | 2 + 6 files changed, 227 insertions(+), 34 deletions(-) diff --git a/winsup/cygwin/environ.cc b/winsup/cygwin/environ.cc index 21f13734c..a47ed72e7 100644 --- a/winsup/cygwin/environ.cc +++ b/winsup/cygwin/environ.cc @@ -869,7 +869,8 @@ win32env_to_cygenv (PWCHAR rawenv, bool posify) char *newp; int i; int sawTERM = 0; - static char NO_COPY cygterm[] = "TERM=cygwin"; + const char cygterm[] = "TERM=cygwin"; + const char xterm[] = "TERM=xterm-256color"; char *tmpbuf = tp.t_get (); PWCHAR w; @@ -899,8 +900,10 @@ win32env_to_cygenv (PWCHAR rawenv, bool posify) debug_printf ("%p: %s", envp[i], envp[i]); } + /* If console has 24 bit color capability, TERM=xterm-256color, + otherwise, TERM=cygwin */ if (!sawTERM) - envp[i++] = strdup (cygterm); + envp[i++] = strdup (wincap.has_con_24bit_colors () ? xterm : cygterm); envp[i] = NULL; return envp; diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h index b336eb63a..66e724bcb 100644 --- a/winsup/cygwin/fhandler.h +++ b/winsup/cygwin/fhandler.h @@ -1778,6 +1778,8 @@ enum ansi_intensity #define eattitle 7 #define gotparen 8 #define gotrparen 9 +#define eatpalette 10 +#define endpalette 11 #define MAXARGS 10 enum cltype @@ -1791,6 +1793,8 @@ enum cltype class dev_console { + pid_t owner; + WORD default_color, underline_color, dim_color; /* Used to determine if an input keystroke should be modified with META. */ diff --git a/winsup/cygwin/fhandler_console.cc b/winsup/cygwin/fhandler_console.cc index 281c2005c..6b14d4a25 100644 --- a/winsup/cygwin/fhandler_console.cc +++ b/winsup/cygwin/fhandler_console.cc @@ -15,6 +15,7 @@ details. */ #include #include #include +#include #include "cygerrno.h" #include "security.h" #include "path.h" @@ -32,6 +33,17 @@ details. */ #include "child_info.h" #include "cygwait.h" +/* Not yet defined in Mingw-w64 */ +#ifndef ENABLE_VIRTUAL_TERMINAL_PROCESSING +#define ENABLE_VIRTUAL_TERMINAL_PROCESSING 0x0004 +#endif /* ENABLE_VIRTUAL_TERMINAL_PROCESSING */ +#ifndef DISABLE_NEWLINE_AUTO_RETURN +#define DISABLE_NEWLINE_AUTO_RETURN 0x0008 +#endif /* DISABLE_NEWLINE_AUTO_RETURN */ +#ifndef ENABLE_VIRTUAL_TERMINAL_INPUT +#define ENABLE_VIRTUAL_TERMINAL_INPUT 0x0200 +#endif /* ENABLE_VIRTUAL_TERMINAL_INPUT */ + /* Don't make this bigger than NT_MAX_PATH as long as the temporary buffer is allocated using tmp_pathbuf!!! */ #define CONVERT_LIMIT NT_MAX_PATH @@ -148,7 +160,11 @@ fhandler_console::set_unit () if (created) shared_console_info->tty_min_state.setntty (DEV_CONS_MAJOR, console_unit (me)); devset = (fh_devices) shared_console_info->tty_min_state.getntty (); + if (created) + con.owner = getpid (); } + if (!created && shared_console_info && kill (con.owner, 0) == -1) + con.owner = getpid (); dev ().parse (devset); if (devset != FH_ERROR) @@ -167,33 +183,33 @@ void fhandler_console::setup () { if (set_unit ()) - { - con.scroll_region.Bottom = -1; - con.dwLastCursorPosition.X = -1; - con.dwLastCursorPosition.Y = -1; - con.dwLastMousePosition.X = -1; - con.dwLastMousePosition.Y = -1; - con.dwLastButtonState = 0; /* none pressed */ - con.last_button_code = 3; /* released */ - con.underline_color = FOREGROUND_GREEN | FOREGROUND_BLUE; - con.dim_color = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE; - con.meta_mask = LEFT_ALT_PRESSED; - /* Set the mask that determines if an input keystroke is modified by - META. We set this based on the keyboard layout language loaded - for the current thread. The left key always generates - META, but the right key only generates META if we are using - an English keyboard because many "international" keyboards - replace common shell symbols ('[', '{', etc.) with accented - language-specific characters (umlaut, accent grave, etc.). On - these keyboards right (called AltGr) is used to produce the - shell symbols and should not be interpreted as META. */ - if (PRIMARYLANGID (LOWORD (GetKeyboardLayout (0))) == LANG_ENGLISH) - con.meta_mask |= RIGHT_ALT_PRESSED; - con.set_default_attr (); - con.backspace_keycode = CERASE; - con.cons_rapoi = NULL; - shared_console_info->tty_min_state.is_console = true; - } + { + con.scroll_region.Bottom = -1; + con.dwLastCursorPosition.X = -1; + con.dwLastCursorPosition.Y = -1; + con.dwLastMousePosition.X = -1; + con.dwLastMousePosition.Y = -1; + con.dwLastButtonState = 0; /* none pressed */ + con.last_button_code = 3; /* released */ + con.underline_color = FOREGROUND_GREEN | FOREGROUND_BLUE; + con.dim_color = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE; + con.meta_mask = LEFT_ALT_PRESSED; + /* Set the mask that determines if an input keystroke is modified by + META. We set this based on the keyboard layout language loaded + for the current thread. The left key always generates + META, but the right key only generates META if we are using + an English keyboard because many "international" keyboards + replace common shell symbols ('[', '{', etc.) with accented + language-specific characters (umlaut, accent grave, etc.). On + these keyboards right (called AltGr) is used to produce the + shell symbols and should not be interpreted as META. */ + if (PRIMARYLANGID (LOWORD (GetKeyboardLayout (0))) == LANG_ENGLISH) + con.meta_mask |= RIGHT_ALT_PRESSED; + con.set_default_attr (); + con.backspace_keycode = CERASE; + con.cons_rapoi = NULL; + shared_console_info->tty_min_state.is_console = true; + } } /* Return the tty structure associated with a given tty number. If the @@ -435,7 +451,8 @@ fhandler_console::read (void *pv, size_t& buflen) toadd = tmp; } /* Allow Ctrl-Space to emit ^@ */ - else if (input_rec.Event.KeyEvent.wVirtualKeyCode == VK_SPACE + else if (input_rec.Event.KeyEvent.wVirtualKeyCode + == (wincap.has_con_24bit_colors () ? '2' : VK_SPACE) && (ctrl_key_state & CTRL_PRESSED) && !(ctrl_key_state & ALT_PRESSED)) toadd = ""; @@ -855,10 +872,24 @@ fhandler_console::open (int flags, mode_t) get_ttyp ()->rstcons (false); set_open_status (); + if (getpid () == con.owner && wincap.has_con_24bit_colors ()) + { + DWORD dwMode; + /* Enable xterm compatible mode in output */ + GetConsoleMode (get_output_handle (), &dwMode); + dwMode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING; + SetConsoleMode (get_output_handle (), dwMode); + /* Enable xterm compatible mode in input */ + GetConsoleMode (get_handle (), &dwMode); + dwMode |= ENABLE_VIRTUAL_TERMINAL_INPUT; + SetConsoleMode (get_handle (), dwMode); + } + DWORD cflags; if (GetConsoleMode (get_handle (), &cflags)) - SetConsoleMode (get_handle (), - ENABLE_WINDOW_INPUT | ENABLE_MOUSE_INPUT | cflags); + SetConsoleMode (get_handle (), ENABLE_WINDOW_INPUT + | (wincap.has_con_24bit_colors () ? 0 : ENABLE_MOUSE_INPUT) + | cflags); debug_printf ("opened conin$ %p, conout$ %p", get_handle (), get_output_handle ()); @@ -878,6 +909,22 @@ fhandler_console::open_setup (int flags) int fhandler_console::close () { + debug_printf ("closing: %p, %p", get_handle (), get_output_handle ()); + + if (shared_console_info && getpid () == con.owner && + wincap.has_con_24bit_colors ()) + { + DWORD dwMode; + /* Disable xterm compatible mode in input */ + GetConsoleMode (get_handle (), &dwMode); + dwMode &= ~ENABLE_VIRTUAL_TERMINAL_INPUT; + SetConsoleMode (get_handle (), dwMode); + /* Disable xterm compatible mode in output */ + GetConsoleMode (get_output_handle (), &dwMode); + dwMode &= ~ENABLE_VIRTUAL_TERMINAL_PROCESSING; + SetConsoleMode (get_output_handle (), dwMode); + } + CloseHandle (get_handle ()); CloseHandle (get_output_handle ()); if (!have_execed) @@ -987,6 +1034,13 @@ fhandler_console::output_tcsetattr (int, struct termios const *t) /* All the output bits we can ignore */ DWORD flags = ENABLE_PROCESSED_OUTPUT | ENABLE_WRAP_AT_EOL_OUTPUT; + /* If system has 24 bit color capability, use xterm compatible mode. */ + if (wincap.has_con_24bit_colors ()) + { + flags |= ENABLE_VIRTUAL_TERMINAL_PROCESSING; + if (!(t->c_oflag & OPOST) || !(t->c_oflag & ONLCR)) + flags |= DISABLE_NEWLINE_AUTO_RETURN; + } int res = SetConsoleMode (get_output_handle (), flags) ? 0 : -1; if (res) @@ -1043,7 +1097,11 @@ fhandler_console::input_tcsetattr (int, struct termios const *t) flags |= ENABLE_PROCESSED_INPUT; } - flags |= ENABLE_WINDOW_INPUT | ENABLE_MOUSE_INPUT; + flags |= ENABLE_WINDOW_INPUT | + (wincap.has_con_24bit_colors () ? 0 : ENABLE_MOUSE_INPUT); + /* if system has 24 bit color capability, use xterm compatible mode. */ + if (wincap.has_con_24bit_colors ()) + flags |= ENABLE_VIRTUAL_TERMINAL_INPUT; int res; if (flags == oflags) @@ -1602,11 +1660,32 @@ static const char base_chars[256] = /*F0 F1 F2 F3 F4 F5 F6 F7 */ NOR, NOR, NOR, NOR, NOR, NOR, NOR, NOR, /*F8 F9 FA FB FC FD FE FF */ NOR, NOR, NOR, NOR, NOR, NOR, NOR, NOR }; +static const char table256[256] = +{ + 0, 4, 2, 6, 1, 5, 3, 7, 8,12,10,14, 9,13,11,15, + 0, 1, 1, 1, 9, 9, 2, 3, 3, 3, 3, 9, 2, 3, 3, 3, + 3,11, 2, 3, 3, 3,11,11,10, 3, 3,11,11,11,10,10, + 11,11,11,11, 4, 5, 5, 5, 5, 9, 6, 8, 8, 8, 8, 9, + 6, 8, 8, 8, 8, 7, 6, 8, 8, 8, 7, 7, 6, 8, 8, 7, + 7,11,10,10, 7, 7,11,11, 4, 5, 5, 5, 5,13, 6, 8, + 8, 8, 8, 7, 6, 8, 8, 8, 7, 7, 6, 8, 8, 7, 7, 7, + 6, 8, 7, 7, 7, 7,14, 7, 7, 7, 7, 7, 4, 5, 5, 5, + 13,13, 6, 8, 8, 8, 7, 7, 6, 8, 8, 7, 7, 7, 6, 8, + 7, 7, 7, 7,14, 7, 7, 7, 7, 7,14, 7, 7, 7, 7,15, + 12, 5, 5,13,13,13, 6, 8, 8, 7, 7,13, 6, 8, 7, 7, + 7, 7,14, 7, 7, 7, 7, 7,14, 7, 7, 7, 7,15,14,14, + 7, 7,15,15,12,12,13,13,13,13,12,12, 7, 7,13,13, + 14, 7, 7, 7, 7, 7,14, 7, 7, 7, 7,15,14,14, 7, 7, + 15,15,14,14, 7,15,15,15, 0, 0, 0, 0, 0, 0, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7,15,15 +}; + void fhandler_console::char_command (char c) { int x, y, n; char buf[40]; + int r, g, b; switch (c) { @@ -1678,6 +1757,40 @@ fhandler_console::char_command (char c) case 37: /* WHITE foreg */ con.fg = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED; break; + case 38: + if (con.nargs < 1) + /* Sequence error (abort) */ + break; + switch (con.args[1]) + { + case 2: + if (con.nargs != 4) + /* Sequence error (abort) */ + break; + r = con.args[2]; + g = con.args[3]; + b = con.args[4]; + r = r < (95 + 1) / 2 ? 0 : r > 255 ? 5 : (r - 55 + 20) / 40; + g = g < (95 + 1) / 2 ? 0 : g > 255 ? 5 : (g - 55 + 20) / 40; + b = b < (95 + 1) / 2 ? 0 : b > 255 ? 5 : (b - 55 + 20) / 40; + con.fg = table256[16 + r*36 + g*6 + b]; + break; + case 5: + if (con.nargs != 2) + /* Sequence error (abort) */ + break; + { + int idx = con.args[2]; + if (idx < 0) + idx = 0; + if (idx > 255) + idx = 255; + con.fg = table256[idx]; + } + break; + } + i += con.nargs; + break; case 39: con.fg = con.default_color & FOREGROUND_ATTR_MASK; break; @@ -1705,6 +1818,40 @@ fhandler_console::char_command (char c) case 47: /* WHITE background */ con.bg = BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED; break; + case 48: + if (con.nargs < 1) + /* Sequence error (abort) */ + break; + switch (con.args[1]) + { + case 2: + if (con.nargs != 4) + /* Sequence error (abort) */ + break; + r = con.args[2]; + g = con.args[3]; + b = con.args[4]; + r = r < (95 + 1) / 2 ? 0 : r > 255 ? 5 : (r - 55 + 20) / 40; + g = g < (95 + 1) / 2 ? 0 : g > 255 ? 5 : (g - 55 + 20) / 40; + b = b < (95 + 1) / 2 ? 0 : b > 255 ? 5 : (b - 55 + 20) / 40; + con.bg = table256[16 + r*36 + g*6 + b] << 4; + break; + case 5: + if (con.nargs != 2) + /* Sequence error (abort) */ + break; + { + int idx = con.args[2]; + if (idx < 0) + idx = 0; + if (idx > 255) + idx = 255; + con.bg = table256[idx] << 4; + } + break; + } + i += con.nargs; + break; case 49: con.bg = con.default_color & BACKGROUND_ATTR_MASK; break; @@ -2143,10 +2290,12 @@ fhandler_console::write_normal (const unsigned char *src, /* Loop over src buffer as long as we have just simple characters. Stop as soon as we reach the conversion limit, or if we encounter a control character or a truncated or invalid mutibyte sequence. */ + /* If system has 24 bit color capability, just write all control + sequences to console since xterm compatible mode is enabled. */ memset (&ps, 0, sizeof ps); while (found < end && found - src < CONVERT_LIMIT - && base_chars[*found] == NOR) + && (wincap.has_con_24bit_colors () || base_chars[*found] == NOR) ) { switch (ret = f_mbtowc (_REENT, NULL, (const char *) found, end - found, &ps)) @@ -2394,6 +2543,8 @@ fhandler_console::write (const void *vsrc, size_t len) con.rarg = con.rarg * 10 + (*src - '0'); else if (*src == ';' && (con.rarg == 2 || con.rarg == 0)) con.state = gettitle; + else if (*src == ';' && (con.rarg == 4 || con.rarg == 104)) + con.state = eatpalette; else con.state = eattitle; src++; @@ -2416,6 +2567,21 @@ fhandler_console::write (const void *vsrc, size_t len) src++; break; } + case eatpalette: + if (*src == '\033') + con.state = endpalette; + else if (*src == '\a') + con.state = normal; + src++; + break; + case endpalette: + if (*src == '\\') + con.state = normal; + else + /* Sequence error (abort) */ + con.state = normal; + src++; + break; case gotsquare: if (*src == ';') { diff --git a/winsup/cygwin/select.cc b/winsup/cygwin/select.cc index 9b18e8f80..28adcf3e7 100644 --- a/winsup/cygwin/select.cc +++ b/winsup/cygwin/select.cc @@ -1053,6 +1053,14 @@ peek_console (select_record *me, bool) else if (irec.Event.KeyEvent.uChar.UnicodeChar || fhandler_console::get_nonascii_key (irec, tmpbuf)) return me->read_ready = true; + /* Allow Ctrl-Space for ^@ */ + else if ( (irec.Event.KeyEvent.wVirtualKeyCode == VK_SPACE + || irec.Event.KeyEvent.wVirtualKeyCode == '2') + && (irec.Event.KeyEvent.dwControlKeyState & + (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)) + && !(irec.Event.KeyEvent.dwControlKeyState + & (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED)) ) + return me->read_ready = true; } /* Ignore key up events, except for Alt+Numpad events. */ else if (is_alt_numpad_event (&irec)) diff --git a/winsup/cygwin/wincap.cc b/winsup/cygwin/wincap.cc index 5bc9c3778..86dc631ec 100644 --- a/winsup/cygwin/wincap.cc +++ b/winsup/cygwin/wincap.cc @@ -40,6 +40,7 @@ wincaps wincap_vista __attribute__((section (".cygwin_dll_common"), shared)) = { has_case_sensitive_dirs:false, has_posix_rename_semantics:false, no_msv1_0_s4u_logon_in_wow64:true, + has_con_24bit_colors:false, }, }; @@ -65,6 +66,7 @@ wincaps wincap_7 __attribute__((section (".cygwin_dll_common"), shared)) = { has_case_sensitive_dirs:false, has_posix_rename_semantics:false, no_msv1_0_s4u_logon_in_wow64:true, + has_con_24bit_colors:false, }, }; @@ -90,6 +92,7 @@ wincaps wincap_8 __attribute__((section (".cygwin_dll_common"), shared)) = { has_case_sensitive_dirs:false, has_posix_rename_semantics:false, no_msv1_0_s4u_logon_in_wow64:false, + has_con_24bit_colors:false, }, }; @@ -115,6 +118,7 @@ wincaps wincap_8_1 __attribute__((section (".cygwin_dll_common"), shared)) = { has_case_sensitive_dirs:false, has_posix_rename_semantics:false, no_msv1_0_s4u_logon_in_wow64:false, + has_con_24bit_colors:false, }, }; @@ -140,6 +144,7 @@ wincaps wincap_10_1507 __attribute__((section (".cygwin_dll_common"), shared)) has_case_sensitive_dirs:false, has_posix_rename_semantics:false, no_msv1_0_s4u_logon_in_wow64:false, + has_con_24bit_colors:false, }, }; @@ -165,6 +170,7 @@ wincaps wincap_10_1511 __attribute__((section (".cygwin_dll_common"), shared)) = has_case_sensitive_dirs:false, has_posix_rename_semantics:false, no_msv1_0_s4u_logon_in_wow64:false, + has_con_24bit_colors:false, }, }; @@ -190,6 +196,7 @@ wincaps wincap_10_1703 __attribute__((section (".cygwin_dll_common"), shared)) = has_case_sensitive_dirs:false, has_posix_rename_semantics:false, no_msv1_0_s4u_logon_in_wow64:false, + has_con_24bit_colors:true, }, }; @@ -215,6 +222,7 @@ wincaps wincap_10_1709 __attribute__((section (".cygwin_dll_common"), shared)) = has_case_sensitive_dirs:false, has_posix_rename_semantics:false, no_msv1_0_s4u_logon_in_wow64:false, + has_con_24bit_colors:true, }, }; @@ -240,6 +248,7 @@ wincaps wincap_10_1803 __attribute__((section (".cygwin_dll_common"), shared)) = has_case_sensitive_dirs:true, has_posix_rename_semantics:false, no_msv1_0_s4u_logon_in_wow64:false, + has_con_24bit_colors:true, }, }; @@ -265,6 +274,7 @@ wincaps wincap_10_1809 __attribute__((section (".cygwin_dll_common"), shared)) = has_case_sensitive_dirs:true, has_posix_rename_semantics:true, no_msv1_0_s4u_logon_in_wow64:false, + has_con_24bit_colors:true, }, }; diff --git a/winsup/cygwin/wincap.h b/winsup/cygwin/wincap.h index 0e83f6794..73b6f5ffc 100644 --- a/winsup/cygwin/wincap.h +++ b/winsup/cygwin/wincap.h @@ -34,6 +34,7 @@ struct wincaps unsigned has_case_sensitive_dirs : 1; unsigned has_posix_rename_semantics : 1; unsigned no_msv1_0_s4u_logon_in_wow64 : 1; + unsigned has_con_24bit_colors : 1; }; }; @@ -89,6 +90,7 @@ public: bool IMPLEMENT (has_case_sensitive_dirs) bool IMPLEMENT (has_posix_rename_semantics) bool IMPLEMENT (no_msv1_0_s4u_logon_in_wow64) + bool IMPLEMENT (has_con_24bit_colors) void disable_case_sensitive_dirs () { From 8382778cdb571453b6f00dc1d9cb3d3c7dd58b55 Mon Sep 17 00:00:00 2001 From: Takashi Yano Date: Mon, 1 Apr 2019 00:47:47 +0900 Subject: [PATCH 320/475] Cygwin: console: fix select() behaviour - Previously, select() would return when only one key is typed even in canonical mode. With this patch, it returns after one line is completed. --- winsup/cygwin/fhandler.h | 12 +- winsup/cygwin/fhandler_console.cc | 838 ++++++++++++++++-------------- winsup/cygwin/select.cc | 81 +-- 3 files changed, 484 insertions(+), 447 deletions(-) diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h index 66e724bcb..e4a6de610 100644 --- a/winsup/cygwin/fhandler.h +++ b/winsup/cygwin/fhandler.h @@ -1884,6 +1884,15 @@ public: tty_min tty_min_state; dev_console con; }; + bool input_ready; + enum input_states + { + input_error = -1, + input_processing = 0, + input_ok = 1, + input_signalled = 2, + input_winch = 3 + }; private: static const unsigned MAX_WRITE_CHARS; static console_state *shared_console_info; @@ -1969,7 +1978,7 @@ private: void fixup_after_fork (HANDLE) {fixup_after_fork_exec (false);} void set_close_on_exec (bool val); void set_input_state (); - void send_winch_maybe (); + bool send_winch_maybe (); void setup (); bool set_unit (); static bool need_invisible (); @@ -1992,6 +2001,7 @@ private: copyto (fh); return fh; } + input_states process_input_message (); friend tty_min * tty_list::get_cttyp (); }; diff --git a/winsup/cygwin/fhandler_console.cc b/winsup/cygwin/fhandler_console.cc index 6b14d4a25..160ae284a 100644 --- a/winsup/cygwin/fhandler_console.cc +++ b/winsup/cygwin/fhandler_console.cc @@ -53,7 +53,9 @@ details. */ #define con (shared_console_info->con) #define srTop (con.b.srWindow.Top + con.scroll_region.Top) -#define srBottom ((con.scroll_region.Bottom < 0) ? con.b.srWindow.Bottom : con.b.srWindow.Top + con.scroll_region.Bottom) +#define srBottom ((con.scroll_region.Bottom < 0) ? \ + con.b.srWindow.Bottom : \ + con.b.srWindow.Top + con.scroll_region.Bottom) const unsigned fhandler_console::MAX_WRITE_CHARS = 16384; @@ -149,16 +151,19 @@ fhandler_console::set_unit () shared_unit : FH_ERROR; created = false; } - else if ((!generic_console && (myself->ctty != -1 && !iscons_dev (myself->ctty))) + else if ((!generic_console && + (myself->ctty != -1 && !iscons_dev (myself->ctty))) || !(me = GetConsoleWindow ())) devset = FH_ERROR; else { created = true; - shared_console_info = open_shared_console (me, cygheap->console_h, created); + shared_console_info = + open_shared_console (me, cygheap->console_h, created); ProtectHandleINH (cygheap->console_h); if (created) - shared_console_info->tty_min_state.setntty (DEV_CONS_MAJOR, console_unit (me)); + shared_console_info-> + tty_min_state.setntty (DEV_CONS_MAJOR, console_unit (me)); devset = (fh_devices) shared_console_info->tty_min_state.getntty (); if (created) con.owner = getpid (); @@ -251,7 +256,8 @@ fhandler_console::set_raw_win32_keyboard_mode (bool new_mode) { bool old_mode = con.raw_win32_keyboard_mode; con.raw_win32_keyboard_mode = new_mode; - syscall_printf ("raw keyboard mode %sabled", con.raw_win32_keyboard_mode ? "en" : "dis"); + syscall_printf ("raw keyboard mode %sabled", + con.raw_win32_keyboard_mode ? "en" : "dis"); return old_mode; }; @@ -267,7 +273,7 @@ fhandler_console::set_cursor_maybe () } } -void +bool fhandler_console::send_winch_maybe () { SHORT y = con.dwWinSize.Y; @@ -279,7 +285,9 @@ fhandler_console::send_winch_maybe () con.scroll_region.Top = 0; con.scroll_region.Bottom = -1; get_ttyp ()->kill_pgrp (SIGWINCH); + return true; } + return false; } /* Check whether a mouse event is to be reported as an escape sequence */ @@ -299,7 +307,8 @@ fhandler_console::mouse_aware (MOUSE_EVENT_RECORD& mouse_event) con.dwMousePosition.X = mouse_event.dwMousePosition.X - now.srWindow.Left; con.dwMousePosition.Y = mouse_event.dwMousePosition.Y - now.srWindow.Top; - return ((mouse_event.dwEventFlags == 0 || mouse_event.dwEventFlags == DOUBLE_CLICK) + return ((mouse_event.dwEventFlags == 0 + || mouse_event.dwEventFlags == DOUBLE_CLICK) && mouse_event.dwButtonState != con.dwLastButtonState) || mouse_event.dwEventFlags == MOUSE_WHEELED || (mouse_event.dwEventFlags == MOUSE_MOVED @@ -312,36 +321,17 @@ fhandler_console::mouse_aware (MOUSE_EVENT_RECORD& mouse_event) void __reg3 fhandler_console::read (void *pv, size_t& buflen) { + termios_printf ("read(%p,%d)", pv, buflen); + push_process_state process_state (PID_TTYIN); - HANDLE h = get_handle (); - -#define buf ((char *) pv) - - int ch; - set_input_state (); - - /* Check console read-ahead buffer filled from terminal requests */ - if (con.cons_rapoi && *con.cons_rapoi) - { - *buf = *con.cons_rapoi++; - buflen = 1; - return; - } - - int copied_chars = get_readahead_into_buffer (buf, buflen); - - if (copied_chars) - { - buflen = copied_chars; - return; - } + int copied_chars = 0; DWORD timeout = is_nonblocking () ? 0 : INFINITE; - char tmp[60]; - termios ti = get_ttyp ()->ti; - for (;;) + set_input_state (); + + while (!input_ready && !get_cons_readahead_valid ()) { int bgres; if ((bgres = bg_check (SIGTTIN)) <= bg_eof) @@ -350,8 +340,8 @@ fhandler_console::read (void *pv, size_t& buflen) return; } - set_cursor_maybe (); /* to make cursor appear on the screen immediately */ - switch (cygwait (h, timeout)) + set_cursor_maybe (); /* to make cursor appear on the screen immediately */ + switch (cygwait (get_handle (), timeout)) { case WAIT_OBJECT_0: break; @@ -369,354 +359,41 @@ fhandler_console::read (void *pv, size_t& buflen) goto err; } - DWORD nread; - INPUT_RECORD input_rec; - const char *toadd = NULL; +#define buf ((char *) pv) - if (!ReadConsoleInputW (h, &input_rec, 1, &nread)) + int ret; + ret = process_input_message (); + switch (ret) { - syscall_printf ("ReadConsoleInput failed, %E"); - goto err; /* seems to be failure */ - } - - const WCHAR &unicode_char = input_rec.Event.KeyEvent.uChar.UnicodeChar; - const DWORD &ctrl_key_state = input_rec.Event.KeyEvent.dwControlKeyState; - - /* check the event that occurred */ - switch (input_rec.EventType) - { - case KEY_EVENT: - - con.nModifiers = 0; - -#ifdef DEBUGGING - /* allow manual switching to/from raw mode via ctrl-alt-scrolllock */ - if (input_rec.Event.KeyEvent.bKeyDown - && input_rec.Event.KeyEvent.wVirtualKeyCode == VK_SCROLL - && (ctrl_key_state & (LEFT_ALT_PRESSED | LEFT_CTRL_PRESSED)) - == (LEFT_ALT_PRESSED | LEFT_CTRL_PRESSED)) - { - set_raw_win32_keyboard_mode (!con.raw_win32_keyboard_mode); - continue; - } -#endif - - if (con.raw_win32_keyboard_mode) - { - __small_sprintf (tmp, "\033{%u;%u;%u;%u;%u;%luK", - input_rec.Event.KeyEvent.bKeyDown, - input_rec.Event.KeyEvent.wRepeatCount, - input_rec.Event.KeyEvent.wVirtualKeyCode, - input_rec.Event.KeyEvent.wVirtualScanCode, - input_rec.Event.KeyEvent.uChar.UnicodeChar, - input_rec.Event.KeyEvent.dwControlKeyState); - toadd = tmp; - nread = strlen (toadd); - break; - } - - /* Ignore key up events, except for Alt+Numpad events. */ - if (!input_rec.Event.KeyEvent.bKeyDown && - !is_alt_numpad_event (&input_rec)) - continue; - /* Ignore Alt+Numpad keys. They are eventually handled below after - releasing the Alt key. */ - if (input_rec.Event.KeyEvent.bKeyDown - && is_alt_numpad_key (&input_rec)) - continue; - - if (ctrl_key_state & SHIFT_PRESSED) - con.nModifiers |= 1; - if (ctrl_key_state & RIGHT_ALT_PRESSED) - con.nModifiers |= 2; - if (ctrl_key_state & CTRL_PRESSED) - con.nModifiers |= 4; - if (ctrl_key_state & LEFT_ALT_PRESSED) - con.nModifiers |= 8; - - /* Allow Backspace to emit ^? and escape sequences. */ - if (input_rec.Event.KeyEvent.wVirtualKeyCode == VK_BACK) - { - char c = con.backspace_keycode; - nread = 0; - if (ctrl_key_state & ALT_PRESSED) - { - if (con.metabit) - c |= 0x80; - else - tmp[nread++] = '\e'; - } - tmp[nread++] = c; - tmp[nread] = 0; - toadd = tmp; - } - /* Allow Ctrl-Space to emit ^@ */ - else if (input_rec.Event.KeyEvent.wVirtualKeyCode - == (wincap.has_con_24bit_colors () ? '2' : VK_SPACE) - && (ctrl_key_state & CTRL_PRESSED) - && !(ctrl_key_state & ALT_PRESSED)) - toadd = ""; - else if (unicode_char == 0 - /* arrow/function keys */ - || (input_rec.Event.KeyEvent.dwControlKeyState & ENHANCED_KEY)) - { - toadd = get_nonascii_key (input_rec, tmp); - if (!toadd) - { - con.nModifiers = 0; - continue; - } - nread = strlen (toadd); - } - else - { - nread = con.con_to_str (tmp + 1, 59, unicode_char); - /* Determine if the keystroke is modified by META. The tricky - part is to distinguish whether the right Alt key should be - recognized as Alt, or as AltGr. */ - bool meta = - /* Alt but not AltGr (= left ctrl + right alt)? */ - (ctrl_key_state & ALT_PRESSED) != 0 - && ((ctrl_key_state & CTRL_PRESSED) == 0 - /* but also allow Alt-AltGr: */ - || (ctrl_key_state & ALT_PRESSED) == ALT_PRESSED - || (unicode_char <= 0x1f || unicode_char == 0x7f)); - if (!meta) - { - /* Determine if the character is in the current multibyte - charset. The test is easy. If the multibyte sequence - is > 1 and the first byte is ASCII CAN, the character - has been translated into the ASCII CAN + UTF-8 replacement - sequence. If so, just ignore the keypress. - FIXME: Is there a better solution? */ - if (nread > 1 && tmp[1] == 0x18) - beep (); - else - toadd = tmp + 1; - } - else if (con.metabit) - { - tmp[1] |= 0x80; - toadd = tmp + 1; - } - else - { - tmp[0] = '\033'; - tmp[1] = cyg_tolower (tmp[1]); - toadd = tmp; - nread++; - con.nModifiers &= ~4; - } - } - break; - - case MOUSE_EVENT: - send_winch_maybe (); - { - MOUSE_EVENT_RECORD& mouse_event = input_rec.Event.MouseEvent; - /* As a unique guard for mouse report generation, - call mouse_aware() which is common with select(), so the result - of select() and the actual read() will be consistent on the - issue of whether input (i.e. a mouse escape sequence) will - be available or not */ - if (mouse_aware (mouse_event)) - { - /* Note: Reported mouse position was already retrieved by - mouse_aware() and adjusted by window scroll buffer offset */ - - /* Treat the double-click event like a regular button press */ - if (mouse_event.dwEventFlags == DOUBLE_CLICK) - { - syscall_printf ("mouse: double-click -> click"); - mouse_event.dwEventFlags = 0; - } - - /* This code assumes Windows never reports multiple button - events at the same time. */ - int b = 0; - char sz[32]; - char mode6_term = 'M'; - - if (mouse_event.dwEventFlags == MOUSE_WHEELED) - { - if (mouse_event.dwButtonState & 0xFF800000) - { - b = 0x41; - strcpy (sz, "wheel down"); - } - else - { - b = 0x40; - strcpy (sz, "wheel up"); - } - } - else - { - /* Ignore unimportant mouse buttons */ - mouse_event.dwButtonState &= 0x7; - - if (mouse_event.dwEventFlags == MOUSE_MOVED) - { - b = con.last_button_code; - } - else if (mouse_event.dwButtonState < con.dwLastButtonState && !con.ext_mouse_mode6) - { - b = 3; - strcpy (sz, "btn up"); - } - else if ((mouse_event.dwButtonState & 1) != (con.dwLastButtonState & 1)) - { - b = 0; - strcpy (sz, "btn1 down"); - } - else if ((mouse_event.dwButtonState & 2) != (con.dwLastButtonState & 2)) - { - b = 2; - strcpy (sz, "btn2 down"); - } - else if ((mouse_event.dwButtonState & 4) != (con.dwLastButtonState & 4)) - { - b = 1; - strcpy (sz, "btn3 down"); - } - - if (con.ext_mouse_mode6 /* distinguish release */ - && mouse_event.dwButtonState < con.dwLastButtonState) - mode6_term = 'm'; - - con.last_button_code = b; - - if (mouse_event.dwEventFlags == MOUSE_MOVED) - { - b += 32; - strcpy (sz, "move"); - } - else - { - /* Remember the modified button state */ - con.dwLastButtonState = mouse_event.dwButtonState; - } - } - - /* Remember mouse position */ - con.dwLastMousePosition.X = con.dwMousePosition.X; - con.dwLastMousePosition.Y = con.dwMousePosition.Y; - - /* Remember the modifiers */ - con.nModifiers = 0; - if (mouse_event.dwControlKeyState & SHIFT_PRESSED) - con.nModifiers |= 0x4; - if (mouse_event.dwControlKeyState & ALT_PRESSED) - con.nModifiers |= 0x8; - if (mouse_event.dwControlKeyState & CTRL_PRESSED) - con.nModifiers |= 0x10; - - /* Indicate the modifiers */ - b |= con.nModifiers; - - /* We can now create the code. */ - if (con.ext_mouse_mode6) - { - __small_sprintf (tmp, "\033[<%d;%d;%d%c", b, - con.dwMousePosition.X + 1, - con.dwMousePosition.Y + 1, - mode6_term); - nread = strlen (tmp); - } - else if (con.ext_mouse_mode15) - { - __small_sprintf (tmp, "\033[%d;%d;%dM", b + 32, - con.dwMousePosition.X + 1, - con.dwMousePosition.Y + 1); - nread = strlen (tmp); - } - else if (con.ext_mouse_mode5) - { - unsigned int xcode = con.dwMousePosition.X + ' ' + 1; - unsigned int ycode = con.dwMousePosition.Y + ' ' + 1; - - __small_sprintf (tmp, "\033[M%c", b + ' '); - nread = 4; - /* the neat nested encoding function of mintty - does not compile in g++, so let's unfold it: */ - if (xcode < 0x80) - tmp [nread++] = xcode; - else if (xcode < 0x800) - { - tmp [nread++] = 0xC0 + (xcode >> 6); - tmp [nread++] = 0x80 + (xcode & 0x3F); - } - else - tmp [nread++] = 0; - if (ycode < 0x80) - tmp [nread++] = ycode; - else if (ycode < 0x800) - { - tmp [nread++] = 0xC0 + (ycode >> 6); - tmp [nread++] = 0x80 + (ycode & 0x3F); - } - else - tmp [nread++] = 0; - } - else - { - unsigned int xcode = con.dwMousePosition.X + ' ' + 1; - unsigned int ycode = con.dwMousePosition.Y + ' ' + 1; - if (xcode >= 256) - xcode = 0; - if (ycode >= 256) - ycode = 0; - __small_sprintf (tmp, "\033[M%c%c%c", b + ' ', - xcode, ycode); - nread = 6; /* tmp may contain NUL bytes */ - } - syscall_printf ("mouse: %s at (%d,%d)", sz, - con.dwMousePosition.X, - con.dwMousePosition.Y); - - toadd = tmp; - } - } - break; - - case FOCUS_EVENT: - if (con.use_focus) - { - if (input_rec.Event.FocusEvent.bSetFocus) - __small_sprintf (tmp, "\033[I"); - else - __small_sprintf (tmp, "\033[O"); - - toadd = tmp; - nread = 3; - } - break; - - case WINDOW_BUFFER_SIZE_EVENT: - send_winch_maybe (); - /* fall through */ - default: + case input_error: + goto err; + case input_processing: continue; - } - - if (toadd) - { - line_edit_status res = line_edit (toadd, nread, ti); - if (res == line_edit_signalled) - goto sig_exit; - else if (res == line_edit_input_done) - break; + case input_ok: /* input ready */ + break; + case input_signalled: /* signalled */ + goto sig_exit; + case input_winch: + continue; + default: + /* Should not come here */ + goto err; } } - while (buflen) - if ((ch = get_readahead ()) < 0) - break; - else - { - buf[copied_chars++] = (unsigned char)(ch & 0xff); - buflen--; - } + /* Check console read-ahead buffer filled from terminal requests */ + while (con.cons_rapoi && *con.cons_rapoi && buflen) + { + buf[copied_chars++] = *con.cons_rapoi++; + buflen --; + } + + copied_chars += + get_readahead_into_buffer (buf + copied_chars, buflen); + + if (!ralen) + input_ready = false; + #undef buf buflen = copied_chars; @@ -732,6 +409,366 @@ sig_exit: buflen = (size_t) -1; } +fhandler_console::input_states +fhandler_console::process_input_message (void) +{ + char tmp[60]; + + if (!shared_console_info) + return input_error; + + termios *ti = &(get_ttyp ()->ti); + + DWORD nread; + INPUT_RECORD input_rec; + const char *toadd = NULL; + + if (!ReadConsoleInputW (get_handle (), &input_rec, 1, &nread)) + { + termios_printf ("ReadConsoleInput failed, %E"); + return input_error; + } + + const WCHAR &unicode_char = input_rec.Event.KeyEvent.uChar.UnicodeChar; + const DWORD &ctrl_key_state = input_rec.Event.KeyEvent.dwControlKeyState; + + /* check the event that occurred */ + switch (input_rec.EventType) + { + case KEY_EVENT: + + con.nModifiers = 0; + +#ifdef DEBUGGING + /* allow manual switching to/from raw mode via ctrl-alt-scrolllock */ + if (input_rec.Event.KeyEvent.bKeyDown + && input_rec.Event.KeyEvent.wVirtualKeyCode == VK_SCROLL + && (ctrl_key_state & (LEFT_ALT_PRESSED | LEFT_CTRL_PRESSED)) + == (LEFT_ALT_PRESSED | LEFT_CTRL_PRESSED)) + { + set_raw_win32_keyboard_mode (!con.raw_win32_keyboard_mode); + return input_processing; + } +#endif + + if (con.raw_win32_keyboard_mode) + { + __small_sprintf (tmp, "\033{%u;%u;%u;%u;%u;%luK", + input_rec.Event.KeyEvent.bKeyDown, + input_rec.Event.KeyEvent.wRepeatCount, + input_rec.Event.KeyEvent.wVirtualKeyCode, + input_rec.Event.KeyEvent.wVirtualScanCode, + input_rec.Event.KeyEvent.uChar.UnicodeChar, + input_rec.Event.KeyEvent.dwControlKeyState); + toadd = tmp; + nread = strlen (toadd); + break; + } + + /* Ignore key up events, except for Alt+Numpad events. */ + if (!input_rec.Event.KeyEvent.bKeyDown && + !is_alt_numpad_event (&input_rec)) + return input_processing; + /* Ignore Alt+Numpad keys. They are eventually handled below after + releasing the Alt key. */ + if (input_rec.Event.KeyEvent.bKeyDown + && is_alt_numpad_key (&input_rec)) + return input_processing; + + if (ctrl_key_state & SHIFT_PRESSED) + con.nModifiers |= 1; + if (ctrl_key_state & RIGHT_ALT_PRESSED) + con.nModifiers |= 2; + if (ctrl_key_state & CTRL_PRESSED) + con.nModifiers |= 4; + if (ctrl_key_state & LEFT_ALT_PRESSED) + con.nModifiers |= 8; + + /* Allow Backspace to emit ^? and escape sequences. */ + if (input_rec.Event.KeyEvent.wVirtualKeyCode == VK_BACK) + { + char c = con.backspace_keycode; + nread = 0; + if (ctrl_key_state & ALT_PRESSED) + { + if (con.metabit) + c |= 0x80; + else + tmp[nread++] = '\e'; + } + tmp[nread++] = c; + tmp[nread] = 0; + toadd = tmp; + } + /* Allow Ctrl-Space to emit ^@ */ + else if (input_rec.Event.KeyEvent.wVirtualKeyCode + == (wincap.has_con_24bit_colors () ? '2' : VK_SPACE) + && (ctrl_key_state & CTRL_PRESSED) + && !(ctrl_key_state & ALT_PRESSED)) + toadd = ""; + else if (unicode_char == 0 + /* arrow/function keys */ + || (input_rec.Event.KeyEvent.dwControlKeyState & ENHANCED_KEY)) + { + toadd = get_nonascii_key (input_rec, tmp); + if (!toadd) + { + con.nModifiers = 0; + return input_processing; + } + nread = strlen (toadd); + } + else + { + nread = con.con_to_str (tmp + 1, 59, unicode_char); + /* Determine if the keystroke is modified by META. The tricky + part is to distinguish whether the right Alt key should be + recognized as Alt, or as AltGr. */ + bool meta = + /* Alt but not AltGr (= left ctrl + right alt)? */ + (ctrl_key_state & ALT_PRESSED) != 0 + && ((ctrl_key_state & CTRL_PRESSED) == 0 + /* but also allow Alt-AltGr: */ + || (ctrl_key_state & ALT_PRESSED) == ALT_PRESSED + || (unicode_char <= 0x1f || unicode_char == 0x7f)); + if (!meta) + { + /* Determine if the character is in the current multibyte + charset. The test is easy. If the multibyte sequence + is > 1 and the first byte is ASCII CAN, the character + has been translated into the ASCII CAN + UTF-8 replacement + sequence. If so, just ignore the keypress. + FIXME: Is there a better solution? */ + if (nread > 1 && tmp[1] == 0x18) + beep (); + else + toadd = tmp + 1; + } + else if (con.metabit) + { + tmp[1] |= 0x80; + toadd = tmp + 1; + } + else + { + tmp[0] = '\033'; + tmp[1] = cyg_tolower (tmp[1]); + toadd = tmp; + nread++; + con.nModifiers &= ~4; + } + } + break; + + case MOUSE_EVENT: + send_winch_maybe (); + { + MOUSE_EVENT_RECORD& mouse_event = input_rec.Event.MouseEvent; + /* As a unique guard for mouse report generation, + call mouse_aware() which is common with select(), so the result + of select() and the actual read() will be consistent on the + issue of whether input (i.e. a mouse escape sequence) will + be available or not */ + if (mouse_aware (mouse_event)) + { + /* Note: Reported mouse position was already retrieved by + mouse_aware() and adjusted by window scroll buffer offset */ + + /* Treat the double-click event like a regular button press */ + if (mouse_event.dwEventFlags == DOUBLE_CLICK) + { + syscall_printf ("mouse: double-click -> click"); + mouse_event.dwEventFlags = 0; + } + + /* This code assumes Windows never reports multiple button + events at the same time. */ + int b = 0; + char sz[32]; + char mode6_term = 'M'; + + if (mouse_event.dwEventFlags == MOUSE_WHEELED) + { + if (mouse_event.dwButtonState & 0xFF800000) + { + b = 0x41; + strcpy (sz, "wheel down"); + } + else + { + b = 0x40; + strcpy (sz, "wheel up"); + } + } + else + { + /* Ignore unimportant mouse buttons */ + mouse_event.dwButtonState &= 0x7; + + if (mouse_event.dwEventFlags == MOUSE_MOVED) + { + b = con.last_button_code; + } + else if (mouse_event.dwButtonState < con.dwLastButtonState + && !con.ext_mouse_mode6) + { + b = 3; + strcpy (sz, "btn up"); + } + else if ((mouse_event.dwButtonState & 1) + != (con.dwLastButtonState & 1)) + { + b = 0; + strcpy (sz, "btn1 down"); + } + else if ((mouse_event.dwButtonState & 2) + != (con.dwLastButtonState & 2)) + { + b = 2; + strcpy (sz, "btn2 down"); + } + else if ((mouse_event.dwButtonState & 4) + != (con.dwLastButtonState & 4)) + { + b = 1; + strcpy (sz, "btn3 down"); + } + + if (con.ext_mouse_mode6 /* distinguish release */ + && mouse_event.dwButtonState < con.dwLastButtonState) + mode6_term = 'm'; + + con.last_button_code = b; + + if (mouse_event.dwEventFlags == MOUSE_MOVED) + { + b += 32; + strcpy (sz, "move"); + } + else + { + /* Remember the modified button state */ + con.dwLastButtonState = mouse_event.dwButtonState; + } + } + + /* Remember mouse position */ + con.dwLastMousePosition.X = con.dwMousePosition.X; + con.dwLastMousePosition.Y = con.dwMousePosition.Y; + + /* Remember the modifiers */ + con.nModifiers = 0; + if (mouse_event.dwControlKeyState & SHIFT_PRESSED) + con.nModifiers |= 0x4; + if (mouse_event.dwControlKeyState & ALT_PRESSED) + con.nModifiers |= 0x8; + if (mouse_event.dwControlKeyState & CTRL_PRESSED) + con.nModifiers |= 0x10; + + /* Indicate the modifiers */ + b |= con.nModifiers; + + /* We can now create the code. */ + if (con.ext_mouse_mode6) + { + __small_sprintf (tmp, "\033[<%d;%d;%d%c", b, + con.dwMousePosition.X + 1, + con.dwMousePosition.Y + 1, + mode6_term); + nread = strlen (tmp); + } + else if (con.ext_mouse_mode15) + { + __small_sprintf (tmp, "\033[%d;%d;%dM", b + 32, + con.dwMousePosition.X + 1, + con.dwMousePosition.Y + 1); + nread = strlen (tmp); + } + else if (con.ext_mouse_mode5) + { + unsigned int xcode = con.dwMousePosition.X + ' ' + 1; + unsigned int ycode = con.dwMousePosition.Y + ' ' + 1; + + __small_sprintf (tmp, "\033[M%c", b + ' '); + nread = 4; + /* the neat nested encoding function of mintty + does not compile in g++, so let's unfold it: */ + if (xcode < 0x80) + tmp [nread++] = xcode; + else if (xcode < 0x800) + { + tmp [nread++] = 0xC0 + (xcode >> 6); + tmp [nread++] = 0x80 + (xcode & 0x3F); + } + else + tmp [nread++] = 0; + if (ycode < 0x80) + tmp [nread++] = ycode; + else if (ycode < 0x800) + { + tmp [nread++] = 0xC0 + (ycode >> 6); + tmp [nread++] = 0x80 + (ycode & 0x3F); + } + else + tmp [nread++] = 0; + } + else + { + unsigned int xcode = con.dwMousePosition.X + ' ' + 1; + unsigned int ycode = con.dwMousePosition.Y + ' ' + 1; + if (xcode >= 256) + xcode = 0; + if (ycode >= 256) + ycode = 0; + __small_sprintf (tmp, "\033[M%c%c%c", b + ' ', + xcode, ycode); + nread = 6; /* tmp may contain NUL bytes */ + } + syscall_printf ("mouse: %s at (%d,%d)", sz, + con.dwMousePosition.X, + con.dwMousePosition.Y); + + toadd = tmp; + } + } + break; + + case FOCUS_EVENT: + if (con.use_focus) + { + if (input_rec.Event.FocusEvent.bSetFocus) + __small_sprintf (tmp, "\033[I"); + else + __small_sprintf (tmp, "\033[O"); + + toadd = tmp; + nread = 3; + } + break; + + case WINDOW_BUFFER_SIZE_EVENT: + if (send_winch_maybe ()) + return input_winch; + /* fall through */ + default: + return input_processing; + } + + if (toadd) + { + ssize_t ret; + line_edit_status res = line_edit (toadd, nread, *ti, &ret); + if (res == line_edit_signalled) + return input_signalled; + else if (res == line_edit_input_done) + { + input_ready = true; + return input_ok; + } + } + return input_processing; +} + void fhandler_console::set_input_state () { @@ -749,7 +786,8 @@ dev_console::fillin (HANDLE h) dwWinSize.Y = 1 + b.srWindow.Bottom - b.srWindow.Top; dwWinSize.X = 1 + b.srWindow.Right - b.srWindow.Left; if (b.dwCursorPosition.Y > dwEnd.Y - || (b.dwCursorPosition.Y >= dwEnd.Y && b.dwCursorPosition.X > dwEnd.X)) + || (b.dwCursorPosition.Y >= dwEnd.Y + && b.dwCursorPosition.X > dwEnd.X)) dwEnd = b.dwCursorPosition; } else @@ -765,7 +803,8 @@ dev_console::fillin (HANDLE h) } void __reg3 -dev_console::scroll_buffer (HANDLE h, int x1, int y1, int x2, int y2, int xn, int yn) +dev_console::scroll_buffer (HANDLE h, int x1, int y1, int x2, int y2, + int xn, int yn) { /* Scroll the screen context. x1, y1 - ul corner @@ -786,7 +825,8 @@ dev_console::scroll_buffer (HANDLE h, int x1, int y1, int x2, int y2, int xn, in sr1.Bottom = y2 >= 0 ? y2 : b.srWindow.Bottom; sr2.Top = b.srWindow.Top + scroll_region.Top; sr2.Left = 0; - sr2.Bottom = (scroll_region.Bottom < 0) ? b.srWindow.Bottom : b.srWindow.Top + scroll_region.Bottom; + sr2.Bottom = (scroll_region.Bottom < 0) ? + b.srWindow.Bottom : b.srWindow.Top + scroll_region.Bottom; sr2.Right = dwWinSize.X - 1; if (sr1.Bottom > sr2.Bottom && sr1.Top <= sr2.Bottom) sr1.Bottom = sr2.Bottom; @@ -796,13 +836,15 @@ dev_console::scroll_buffer (HANDLE h, int x1, int y1, int x2, int y2, int xn, in } inline void -fhandler_console::scroll_buffer (int x1, int y1, int x2, int y2, int xn, int yn) +fhandler_console::scroll_buffer (int x1, int y1, int x2, int y2, + int xn, int yn) { con.scroll_buffer (get_output_handle (), x1, y1, x2, y2, xn, yn); } inline void -fhandler_console::scroll_buffer_screen (int x1, int y1, int x2, int y2, int xn, int yn) +fhandler_console::scroll_buffer_screen (int x1, int y1, int x2, int y2, + int xn, int yn) { if (y1 >= 0) y1 += con.b.srWindow.Top; @@ -1168,7 +1210,7 @@ fhandler_console::tcgetattr (struct termios *t) } fhandler_console::fhandler_console (fh_devices unit) : - fhandler_termios () + fhandler_termios (), input_ready (false) { if (unit > 0) dev ().parse (unit); @@ -1869,16 +1911,19 @@ fhandler_console::char_command (char c) case 1: /* blinking block (default) */ case 2: /* steady block */ console_cursor_info.dwSize = 100; - SetConsoleCursorInfo (get_output_handle (), &console_cursor_info); + SetConsoleCursorInfo (get_output_handle (), + &console_cursor_info); break; case 3: /* blinking underline */ case 4: /* steady underline */ - console_cursor_info.dwSize = 10; /* or Windows default 25? */ - SetConsoleCursorInfo (get_output_handle (), &console_cursor_info); + console_cursor_info.dwSize = 10; /* or Windows default 25? */ + SetConsoleCursorInfo (get_output_handle (), + &console_cursor_info); break; default: /* use value as percentage */ console_cursor_info.dwSize = con.args[0]; - SetConsoleCursorInfo (get_output_handle (), &console_cursor_info); + SetConsoleCursorInfo (get_output_handle (), + &console_cursor_info); break; } } @@ -1891,7 +1936,8 @@ fhandler_console::char_command (char c) { case 4: /* Insert mode */ con.insert_mode = (c == 'h') ? true : false; - syscall_printf ("insert mode %sabled", con.insert_mode ? "en" : "dis"); + syscall_printf ("insert mode %sabled", + con.insert_mode ? "en" : "dis"); break; } break; @@ -2078,7 +2124,8 @@ fhandler_console::char_command (char c) /* Generate Secondary Device Attribute report, using 67 = ASCII 'C' to indicate Cygwin (convention used by Rxvt, Urxvt, Screen, Mintty), and cygwin version for terminal version. */ - __small_sprintf (buf, "\033[>67;%d%02d;0c", CYGWIN_VERSION_DLL_MAJOR, CYGWIN_VERSION_DLL_MINOR); + __small_sprintf (buf, "\033[>67;%d%02d;0c", + CYGWIN_VERSION_DLL_MAJOR, CYGWIN_VERSION_DLL_MINOR); else strcpy (buf, "\033[?6c"); /* The generated report needs to be injected for read-ahead into the @@ -2088,6 +2135,9 @@ fhandler_console::char_command (char c) con.cons_rapoi = NULL; strcpy (con.cons_rabuf, buf); con.cons_rapoi = con.cons_rabuf; + /* Wake up read() or select() by sending a message + which has no effect */ + PostMessageW (GetConsoleWindow (), WM_SETFOCUS, 0, 0); break; case 'n': switch (con.args[0]) @@ -2100,6 +2150,9 @@ fhandler_console::char_command (char c) con.cons_rapoi = NULL; strcpy (con.cons_rabuf, buf); con.cons_rapoi = con.cons_rabuf; + /* Wake up read() or select() by sending a message + which has no effect */ + PostMessageW (GetConsoleWindow (), WM_SETFOCUS, 0, 0); break; default: goto bad_escape; @@ -2278,7 +2331,8 @@ fhandler_console::write_normal (const unsigned char *src, nfound - trunc_buf.buf); if (!write_console (write_buf, buf_len, done)) { - debug_printf ("multibyte sequence write failed, handle %p", get_output_handle ()); + debug_printf ("multibyte sequence write failed, handle %p", + get_output_handle ()); return 0; } found = src + (nfound - trunc_buf.buf - trunc_buf.len); @@ -2378,7 +2432,8 @@ do_print: y--; } } - cursor_set (false, ((get_ttyp ()->ti.c_oflag & ONLCR) ? 0 : x), y + 1); + cursor_set (false, + ((get_ttyp ()->ti.c_oflag & ONLCR) ? 0 : x), y + 1); break; case BAK: cursor_rel (-1, 0); @@ -2837,7 +2892,8 @@ fhandler_console::create_invisible_console_workaround () /* Create a new hidden process. Use the two event handles as argv[1] and argv[2]. */ - BOOL x = CreateProcessW (NULL, cmd, &sec_none_nih, &sec_none_nih, true, + BOOL x = CreateProcessW (NULL, cmd, + &sec_none_nih, &sec_none_nih, true, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi); if (x) { diff --git a/winsup/cygwin/select.cc b/winsup/cygwin/select.cc index 28adcf3e7..790f15791 100644 --- a/winsup/cygwin/select.cc +++ b/winsup/cygwin/select.cc @@ -202,7 +202,9 @@ select (int maxfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, right value >= 0, matching the number of bits set in the fds records. if ret is 0, continue to loop. */ ret = sel.poll (readfds, writefds, exceptfds); - if (!ret) + if (ret < 0) + wait_state = select_stuff::select_signalled; + else if (!ret) wait_state = select_stuff::select_set_zero; } /* Always clean up everything here. If we're looping then build it @@ -479,6 +481,7 @@ was_timeout: events like mouse movements. The verify function will detect these situations. If it returns false, then this wakeup was a false alarm and we should go back to waiting. */ + int ret = 0; while ((s = s->next)) if (s->saw_error ()) { @@ -488,8 +491,13 @@ was_timeout: } else if ((((wait_ret >= m && s->windows_handle) || s->h == w4[wait_ret])) - && s->verify (s, readfds, writefds, exceptfds)) + && (ret = s->verify (s, readfds, writefds, exceptfds)) > 0) res = select_ok; + else if (ret < 0) + { + res = select_signalled; + goto out; + } select_printf ("res after verify %d", res); break; @@ -539,8 +547,12 @@ select_stuff::poll (fd_set *readfds, fd_set *writefds, fd_set *exceptfds) int n = 0; select_record *s = &start; while ((s = s->next)) - n += (!s->peek || s->peek (s, true)) ? - set_bits (s, readfds, writefds, exceptfds) : 0; + { + int ret = s->peek ? s->peek (s, true) : 1; + if (ret < 0) + return -1; + n += (ret > 0) ? set_bits (s, readfds, writefds, exceptfds) : 0; + } return n; } @@ -1010,16 +1022,10 @@ peek_console (select_record *me, bool) return me->write_ready; if (fh->get_cons_readahead_valid ()) - { - select_printf ("cons_readahead"); - return me->read_ready = true; - } + return me->read_ready = true; - if (fh->get_readahead_valid ()) - { - select_printf ("readahead"); - return me->read_ready = true; - } + if (fh->input_ready) + return me->read_ready = true; if (me->read_ready) { @@ -1030,54 +1036,20 @@ peek_console (select_record *me, bool) INPUT_RECORD irec; DWORD events_read; HANDLE h; - char tmpbuf[17]; set_handle_or_return_if_not_open (h, me); - for (;;) + while (!fh->input_ready && !fh->get_cons_readahead_valid ()) if (fh->bg_check (SIGTTIN, true) <= bg_eof) return me->read_ready = true; else if (!PeekConsoleInputW (h, &irec, 1, &events_read) || !events_read) break; - else + else if (fhandler_console::input_winch == fh->process_input_message ()) { - fh->send_winch_maybe (); - if (irec.EventType == KEY_EVENT) - { - if (irec.Event.KeyEvent.bKeyDown) - { - /* Ignore Alt+Numpad keys. They are eventually handled in the - key-up case below. */ - if (is_alt_numpad_key (&irec)) - ; - /* Handle normal input. */ - else if (irec.Event.KeyEvent.uChar.UnicodeChar - || fhandler_console::get_nonascii_key (irec, tmpbuf)) - return me->read_ready = true; - /* Allow Ctrl-Space for ^@ */ - else if ( (irec.Event.KeyEvent.wVirtualKeyCode == VK_SPACE - || irec.Event.KeyEvent.wVirtualKeyCode == '2') - && (irec.Event.KeyEvent.dwControlKeyState & - (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)) - && !(irec.Event.KeyEvent.dwControlKeyState - & (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED)) ) - return me->read_ready = true; - } - /* Ignore key up events, except for Alt+Numpad events. */ - else if (is_alt_numpad_event (&irec)) - return me->read_ready = true; - } - else - { - if (irec.EventType == MOUSE_EVENT - && fh->mouse_aware (irec.Event.MouseEvent)) - return me->read_ready = true; - if (irec.EventType == FOCUS_EVENT && fh->focus_aware ()) - return me->read_ready = true; - } - - /* Read and discard the event */ - ReadConsoleInputW (h, &irec, 1, &events_read); + set_sig_errno (EINTR); + return -1; } + if (fh->input_ready || fh->get_cons_readahead_valid ()) + return me->read_ready = true; return me->write_ready; } @@ -1089,7 +1061,6 @@ verify_console (select_record *me, fd_set *rfds, fd_set *wfds, return peek_console (me, true); } - select_record * fhandler_console::select_read (select_stuff *ss) { @@ -1104,7 +1075,7 @@ fhandler_console::select_read (select_stuff *ss) s->peek = peek_console; s->h = get_handle (); s->read_selected = true; - s->read_ready = get_readahead_valid (); + s->read_ready = input_ready || get_cons_readahead_valid (); return s; } From f4b47827cf87f055687a0c52a3485d42b3e2b941 Mon Sep 17 00:00:00 2001 From: Takashi Yano Date: Mon, 1 Apr 2019 00:47:48 +0900 Subject: [PATCH 321/475] Cygwin: console: Make I/O functions thread-safe - POSIX states I/O functions shall be thread-safe, however, cygwin console I/O functions were not. This patch makes console I/O functions thread-safe. --- winsup/cygwin/fhandler.h | 18 +++- winsup/cygwin/fhandler_console.cc | 136 +++++++++++++++++++++++++++++- winsup/cygwin/select.cc | 23 +++-- 3 files changed, 165 insertions(+), 12 deletions(-) diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h index e4a6de610..bc66377cd 100644 --- a/winsup/cygwin/fhandler.h +++ b/winsup/cygwin/fhandler.h @@ -1698,6 +1698,12 @@ class fhandler_serial: public fhandler_base } }; +#define acquire_input_mutex(ms) \ + __acquire_input_mutex (__PRETTY_FUNCTION__, __LINE__, ms) + +#define release_input_mutex() \ + __release_input_mutex (__PRETTY_FUNCTION__, __LINE__) + #define acquire_output_mutex(ms) \ __acquire_output_mutex (__PRETTY_FUNCTION__, __LINE__, ms) @@ -1897,6 +1903,7 @@ private: static const unsigned MAX_WRITE_CHARS; static console_state *shared_console_info; static bool invisible_console; + HANDLE input_mutex, output_mutex; /* Used when we encounter a truncated multi-byte sequence. The lead bytes are stored here and revisited in the next write call. */ @@ -1966,8 +1973,11 @@ private: bool focus_aware () {return shared_console_info->con.use_focus;} bool get_cons_readahead_valid () { - return shared_console_info->con.cons_rapoi != NULL && + acquire_input_mutex (INFINITE); + bool ret = shared_console_info->con.cons_rapoi != NULL && *shared_console_info->con.cons_rapoi; + release_input_mutex (); + return ret; } select_record *select_read (select_stuff *); @@ -2002,6 +2012,12 @@ private: return fh; } input_states process_input_message (); + void setup_io_mutex (void); + DWORD __acquire_input_mutex (const char *fn, int ln, DWORD ms); + void __release_input_mutex (const char *fn, int ln); + DWORD __acquire_output_mutex (const char *fn, int ln, DWORD ms); + void __release_output_mutex (const char *fn, int ln); + friend tty_min * tty_list::get_cttyp (); }; diff --git a/winsup/cygwin/fhandler_console.cc b/winsup/cygwin/fhandler_console.cc index 160ae284a..6d42ed888 100644 --- a/winsup/cygwin/fhandler_console.cc +++ b/winsup/cygwin/fhandler_console.cc @@ -232,6 +232,45 @@ tty_list::get_cttyp () return NULL; } +void +fhandler_console::setup_io_mutex (void) +{ + char buf[MAX_PATH]; + DWORD res; + + res = WAIT_FAILED; + if (!input_mutex || WAIT_FAILED == (res = acquire_input_mutex (0))) + { + shared_name (buf, "cygcons.input.mutex", get_minor ()); + input_mutex = OpenMutex (MAXIMUM_ALLOWED, TRUE, buf); + if (!input_mutex) + input_mutex = CreateMutex (&sec_none, FALSE, buf); + if (!input_mutex) + { + __seterrno (); + return; + } + } + if (res == WAIT_OBJECT_0) + release_input_mutex (); + + res = WAIT_FAILED; + if (!output_mutex || WAIT_FAILED == (res = acquire_output_mutex (0))) + { + shared_name (buf, "cygcons.output.mutex", get_minor ()); + output_mutex = OpenMutex (MAXIMUM_ALLOWED, TRUE, buf); + if (!output_mutex) + output_mutex = CreateMutex (&sec_none, FALSE, buf); + if (!output_mutex) + { + __seterrno (); + return; + } + } + if (res == WAIT_OBJECT_0) + release_output_mutex (); +} + inline DWORD dev_console::con_to_str (char *d, int dlen, WCHAR w) { @@ -362,7 +401,9 @@ fhandler_console::read (void *pv, size_t& buflen) #define buf ((char *) pv) int ret; + acquire_input_mutex (INFINITE); ret = process_input_message (); + release_input_mutex (); switch (ret) { case input_error: @@ -382,6 +423,7 @@ fhandler_console::read (void *pv, size_t& buflen) } /* Check console read-ahead buffer filled from terminal requests */ + acquire_input_mutex (INFINITE); while (con.cons_rapoi && *con.cons_rapoi && buflen) { buf[copied_chars++] = *con.cons_rapoi++; @@ -393,6 +435,7 @@ fhandler_console::read (void *pv, size_t& buflen) if (!ralen) input_ready = false; + release_input_mutex (); #undef buf @@ -903,6 +946,8 @@ fhandler_console::open (int flags, mode_t) } set_output_handle (h); + setup_io_mutex (); + if (con.fillin (get_output_handle ())) { con.current_win32_attr = con.b.wAttributes; @@ -953,6 +998,11 @@ fhandler_console::close () { debug_printf ("closing: %p, %p", get_handle (), get_output_handle ()); + CloseHandle (input_mutex); + input_mutex = NULL; + CloseHandle (output_mutex); + output_mutex = NULL; + if (shared_console_info && getpid () == con.owner && wincap.has_con_24bit_colors ()) { @@ -980,6 +1030,7 @@ fhandler_console::ioctl (unsigned int cmd, void *arg) int res = fhandler_termios::ioctl (cmd, arg); if (res <= 0) return res; + acquire_output_mutex (INFINITE); switch (cmd) { case TIOCGWINSZ: @@ -995,20 +1046,25 @@ fhandler_console::ioctl (unsigned int cmd, void *arg) syscall_printf ("WINSZ: (row=%d,col=%d)", ((struct winsize *) arg)->ws_row, ((struct winsize *) arg)->ws_col); + release_output_mutex (); return 0; } else { syscall_printf ("WINSZ failed"); __seterrno (); + release_output_mutex (); return -1; } + release_output_mutex (); return 0; case TIOCSWINSZ: bg_check (SIGTTOU); + release_output_mutex (); return 0; case KDGKBMETA: *(int *) arg = (con.metabit) ? K_METABIT : K_ESCPREFIX; + release_output_mutex (); return 0; case KDSKBMETA: if ((intptr_t) arg == K_METABIT) @@ -1018,16 +1074,20 @@ fhandler_console::ioctl (unsigned int cmd, void *arg) else { set_errno (EINVAL); + release_output_mutex (); return -1; } + release_output_mutex (); return 0; case TIOCLINUX: if (*(unsigned char *) arg == 6) { *(unsigned char *) arg = (unsigned char) con.nModifiers; + release_output_mutex (); return 0; } set_errno (EINVAL); + release_output_mutex (); return -1; case FIONREAD: { @@ -1040,17 +1100,20 @@ fhandler_console::ioctl (unsigned int cmd, void *arg) if (!PeekConsoleInputW (get_handle (), inp, INREC_SIZE, &n)) { set_errno (EINVAL); + release_output_mutex (); return -1; } while (n-- > 0) if (inp[n].EventType == KEY_EVENT && inp[n].Event.KeyEvent.bKeyDown) ++ret; *(int *) arg = ret; + release_output_mutex (); return 0; } break; } + release_output_mutex (); return fhandler_base::ioctl (cmd, arg); } @@ -1075,6 +1138,7 @@ fhandler_console::output_tcsetattr (int, struct termios const *t) { /* All the output bits we can ignore */ + acquire_output_mutex (INFINITE); DWORD flags = ENABLE_PROCESSED_OUTPUT | ENABLE_WRAP_AT_EOL_OUTPUT; /* If system has 24 bit color capability, use xterm compatible mode. */ if (wincap.has_con_24bit_colors ()) @@ -1087,6 +1151,7 @@ fhandler_console::output_tcsetattr (int, struct termios const *t) int res = SetConsoleMode (get_output_handle (), flags) ? 0 : -1; if (res) __seterrno_from_win_error (GetLastError ()); + release_output_mutex (); syscall_printf ("%d = tcsetattr(,%p) (ENABLE FLAGS %y) (lflag %y oflag %y)", res, t, flags, t->c_lflag, t->c_oflag); return res; @@ -1097,6 +1162,7 @@ fhandler_console::input_tcsetattr (int, struct termios const *t) { /* Ignore the optional_actions stuff, since all output is emitted instantly */ + acquire_input_mutex (INFINITE); DWORD oflags; @@ -1158,6 +1224,7 @@ fhandler_console::input_tcsetattr (int, struct termios const *t) } get_ttyp ()->rstcons (false); + release_input_mutex (); return res; } @@ -1210,7 +1277,8 @@ fhandler_console::tcgetattr (struct termios *t) } fhandler_console::fhandler_console (fh_devices unit) : - fhandler_termios (), input_ready (false) + fhandler_termios (), input_ready (false), + input_mutex (NULL), output_mutex (NULL) { if (unit > 0) dev ().parse (unit); @@ -2132,9 +2200,11 @@ fhandler_console::char_command (char c) fhandler_console object associated with standard input. So puts_readahead does not work. Use a common console read-ahead buffer instead. */ + acquire_input_mutex (INFINITE); con.cons_rapoi = NULL; strcpy (con.cons_rabuf, buf); con.cons_rapoi = con.cons_rabuf; + release_input_mutex (); /* Wake up read() or select() by sending a message which has no effect */ PostMessageW (GetConsoleWindow (), WM_SETFOCUS, 0, 0); @@ -2147,9 +2217,11 @@ fhandler_console::char_command (char c) y -= con.b.srWindow.Top; /* x -= con.b.srWindow.Left; // not available yet */ __small_sprintf (buf, "\033[%d;%dR", y + 1, x + 1); + acquire_input_mutex (INFINITE); con.cons_rapoi = NULL; strcpy (con.cons_rabuf, buf); con.cons_rapoi = con.cons_rabuf; + release_input_mutex (); /* Wake up read() or select() by sending a message which has no effect */ PostMessageW (GetConsoleWindow (), WM_SETFOCUS, 0, 0); @@ -2487,6 +2559,7 @@ fhandler_console::write (const void *vsrc, size_t len) return (ssize_t) bg; push_process_state process_state (PID_TTYOU); + acquire_output_mutex (INFINITE); /* Run and check for ansi sequences */ unsigned const char *src = (unsigned char *) vsrc; @@ -2507,7 +2580,10 @@ fhandler_console::write (const void *vsrc, size_t len) case normal: src = write_normal (src, end); if (!src) /* write_normal failed */ - return -1; + { + release_output_mutex (); + return -1; + } break; case gotesc: if (*src == '[') /* CSI Control Sequence Introducer */ @@ -2676,6 +2752,7 @@ fhandler_console::write (const void *vsrc, size_t len) break; } } + release_output_mutex (); syscall_printf ("%ld = fhandler_console::write(...)", len); @@ -2803,6 +2880,7 @@ void fhandler_console::fixup_after_fork_exec (bool execing) { set_unit (); + setup_io_mutex (); } // #define WINSTA_ACCESS (WINSTA_READATTRIBUTES | STANDARD_RIGHTS_READ | STANDARD_RIGHTS_WRITE | WINSTA_CREATEDESKTOP | WINSTA_EXITWINDOWS) @@ -2986,3 +3064,57 @@ fhandler_console::need_invisible () debug_printf ("invisible_console %d", invisible_console); return b; } + +DWORD +fhandler_console::__acquire_input_mutex (const char *fn, int ln, DWORD ms) +{ +#ifdef DEBUGGING + strace.prntf (_STRACE_TERMIOS, fn, "(%d): trying to get input_mutex", ln); +#endif + DWORD res = WaitForSingleObject (input_mutex, ms); + if (res != WAIT_OBJECT_0) + strace.prntf (_STRACE_TERMIOS, fn, + "(%d): Failed to acquire input_mutex %08x", + ln, GetLastError ()); +#ifdef DEBUGGING + else + strace.prntf (_STRACE_TERMIOS, fn, "(%d): got input_mutex", ln); +#endif + return res; +} + +void +fhandler_console::__release_input_mutex (const char *fn, int ln) +{ + ReleaseMutex (input_mutex); +#ifdef DEBUGGING + strace.prntf (_STRACE_TERMIOS, fn, "(%d): release input_mutex", ln); +#endif +} + +DWORD +fhandler_console::__acquire_output_mutex (const char *fn, int ln, DWORD ms) +{ +#ifdef DEBUGGING + strace.prntf (_STRACE_TERMIOS, fn, "(%d): trying to get output_mutex", ln); +#endif + DWORD res = WaitForSingleObject (output_mutex, ms); + if (res != WAIT_OBJECT_0) + strace.prntf (_STRACE_TERMIOS, fn, + "(%d): Failed to acquire output_mutex %08x", + ln, GetLastError ()); +#ifdef DEBUGGING + else + strace.prntf (_STRACE_TERMIOS, fn, "(%d): got output_mutex", ln); +#endif + return res; +} + +void +fhandler_console::__release_output_mutex (const char *fn, int ln) +{ + ReleaseMutex (output_mutex); +#ifdef DEBUGGING + strace.prntf (_STRACE_TERMIOS, fn, "(%d): release output_mutex", ln); +#endif +} diff --git a/winsup/cygwin/select.cc b/winsup/cygwin/select.cc index 790f15791..85242ec06 100644 --- a/winsup/cygwin/select.cc +++ b/winsup/cygwin/select.cc @@ -1039,15 +1039,20 @@ peek_console (select_record *me, bool) set_handle_or_return_if_not_open (h, me); while (!fh->input_ready && !fh->get_cons_readahead_valid ()) - if (fh->bg_check (SIGTTIN, true) <= bg_eof) - return me->read_ready = true; - else if (!PeekConsoleInputW (h, &irec, 1, &events_read) || !events_read) - break; - else if (fhandler_console::input_winch == fh->process_input_message ()) - { - set_sig_errno (EINTR); - return -1; - } + { + if (fh->bg_check (SIGTTIN, true) <= bg_eof) + return me->read_ready = true; + else if (!PeekConsoleInputW (h, &irec, 1, &events_read) || !events_read) + break; + fh->acquire_input_mutex (INFINITE); + if (fhandler_console::input_winch == fh->process_input_message ()) + { + set_sig_errno (EINTR); + fh->release_input_mutex (); + return -1; + } + fh->release_input_mutex (); + } if (fh->input_ready || fh->get_cons_readahead_valid ()) return me->read_ready = true; From de3c82ee6d28be3aa72a9c4f6e498505af79c2f3 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Sun, 31 Mar 2019 19:36:23 +0200 Subject: [PATCH 322/475] Cygwin: Add console patches to release notes Signed-off-by: Corinna Vinschen --- winsup/cygwin/release/3.1.0 | 9 +++++++++ winsup/doc/new-features.xml | 6 ++++++ 2 files changed, 15 insertions(+) diff --git a/winsup/cygwin/release/3.1.0 b/winsup/cygwin/release/3.1.0 index 1f017bfd1..d55b65517 100644 --- a/winsup/cygwin/release/3.1.0 +++ b/winsup/cygwin/release/3.1.0 @@ -1,6 +1,10 @@ What's new: ----------- +- Add 24 bit color support using xterm compatibility mode in Windows 10 + 1703 or later. Add fake 24 bit color support for legacy console, + which uses the nearest color from 16 system colors. + What changed: ------------- @@ -12,3 +16,8 @@ What changed: Bug Fixes --------- + +- Fix select() on console in canonical mode. Return after one line is + completed, instead of when only one key is typed. + +- Make console I/O functions thread-safe. diff --git a/winsup/doc/new-features.xml b/winsup/doc/new-features.xml index c87601e9d..829f81721 100644 --- a/winsup/doc/new-features.xml +++ b/winsup/doc/new-features.xml @@ -12,6 +12,12 @@ FIFOs can now be opened multiple times for writing. + +Add 24 bit color support using xterm compatibility mode in Windows 10 +1703 or later. Add fake 24 bit color support for legacy console, which +uses the nearest color from 16 system colors. + + From 557227dda3ed6ce1c4cf104cc7671d56a141da38 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Tue, 2 Apr 2019 13:00:22 +0200 Subject: [PATCH 323/475] Cygwin: winpids: Fix getting process multiple times, take 2 commit d1be0a59d48222d8ea6261ee3e59de2bc3d149e4, "Cygwin: winpids: Fix getting process multiple times" fixed duplicate processes in ps -W output, but it fixed the symptom, not the cause. It also didn't fix the problem that the `ps' process itself may show up twice in its own output. This patch fixes it. The spawn worker only deleted the "winpid.PID" symlink of the current process if the child is a non-Cygwin process, under the assumption that the exec'ing process exits anyway. However, the Window in which both winpid.PID symlinks point to the same cygpid.PID area is just too long. The spawn worker now also deletes its own winpid.PID symlink if the exec'ed process is a Cygwin process. Additionally the fix from d1be0a59d48222d8ea6261ee3e59de2bc3d149e4 is now performed on the calling process, too. Signed-off-by: Corinna Vinschen --- winsup/cygwin/pinfo.cc | 6 +++--- winsup/cygwin/release/3.0.6 | 14 ++++++++++++++ winsup/cygwin/spawn.cc | 9 ++++----- 3 files changed, 21 insertions(+), 8 deletions(-) create mode 100644 winsup/cygwin/release/3.0.6 diff --git a/winsup/cygwin/pinfo.cc b/winsup/cygwin/pinfo.cc index bead85bf8..d002268ed 100644 --- a/winsup/cygwin/pinfo.cc +++ b/winsup/cygwin/pinfo.cc @@ -1443,10 +1443,10 @@ winpids::add (DWORD& nelem, bool winpid, DWORD pid) perform_copy = onreturn ? make_copy : true; p.init (cygpid, PID_PROCINFO | pinfo_access, NULL); - /* Did we catch the process during exec? Try to fix. */ - if (p && p->dwProcessId != pid) - pid = p->dwProcessId; } + /* Did we catch the process during exec? Try to fix. */ + if (p && p->dwProcessId != pid) + pid = p->dwProcessId; /* If we're just looking for winpids then don't do any special cygwin "stuff* */ if (winpid) diff --git a/winsup/cygwin/release/3.0.6 b/winsup/cygwin/release/3.0.6 new file mode 100644 index 000000000..14a83290e --- /dev/null +++ b/winsup/cygwin/release/3.0.6 @@ -0,0 +1,14 @@ +What's new: +----------- + + +What changed: +------------- + + +Bug Fixes +--------- + +- Fix the problem that `ps' or `pstree' may show up in their own + output twice. + Addresses: Report on IRC diff --git a/winsup/cygwin/spawn.cc b/winsup/cygwin/spawn.cc index 4e549f7d4..579b3c9c3 100644 --- a/winsup/cygwin/spawn.cc +++ b/winsup/cygwin/spawn.cc @@ -727,16 +727,15 @@ child_info_spawn::worker (const char *prog_arg, const char *const *argv, myself->dwProcessId = pi.dwProcessId; strace.execing = 1; myself.hProcess = hExeced = pi.hProcess; + HANDLE old_winpid_hdl = myself.shared_winpid_handle (); if (!real_path.iscygexec ()) { /* If the child process is not a Cygwin process, we have to - create a new winpid symlink and drop the old one on - behalf of the child process not being able to do this - by itself. */ - HANDLE old_winpid_hdl = myself.shared_winpid_handle (); + create a new winpid symlink on behalf of the child process + not being able to do this by itself. */ myself.create_winpid_symlink (); - NtClose (old_winpid_hdl); } + NtClose (old_winpid_hdl); real_path.get_wide_win32_path (myself->progname); // FIXME: race? sigproc_printf ("new process name %W", myself->progname); if (!iscygwin ()) From c4c614046308a55e4b478c3609f05101c1b8e6b6 Mon Sep 17 00:00:00 2001 From: Sandra Loosemore Date: Wed, 3 Apr 2019 09:59:36 -0600 Subject: [PATCH 324/475] Add a dummy interrupt handler to nios2 crt0.s. The location of the handler at offset 0x20 from the start of memory, immediately after the 32-byte reset vector, matches the expectations of real hardware (e.g., a 3c120 board). --- libgloss/nios2/crt0.S | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/libgloss/nios2/crt0.S b/libgloss/nios2/crt0.S index 77eacb30a..c4dd4c610 100644 --- a/libgloss/nios2/crt0.S +++ b/libgloss/nios2/crt0.S @@ -1,6 +1,6 @@ /* crt0.S -- startup code for Nios II QEMU generic-nommu board emulation. - Copyright (c) 2018 Mentor Graphics + Copyright (c) 2018-2019 Mentor Graphics The authors hereby grant permission to use, copy, modify, distribute, and license this software and its documentation for any purpose, provided @@ -81,6 +81,18 @@ __reset: .size __reset, . - __reset +/* Provide a stub interrupt handler that waits in a busy loop. + The alignment puts it at offset 0x20 from the base of RAM. */ + + .align 5 + + .globl __interrupt_handler + .type __interrupt_handler, @function +__interrupt_handler: +0: + br 0b + + .size __interrupt_handler, . - __interrupt_handler /* __start is the ELF entry point. */ From d3a69d32b1b21b3885d3c8222c0c316be646ddf1 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Wed, 3 Apr 2019 18:14:30 +0200 Subject: [PATCH 325/475] Cygwin: signals: restore sigmask from context given to signal handler In case SA_SIGINFO flag is given, the signal handler may change the context and the application is supposed to pick up from the changed context. So far we don't do that, so the context given to the signal handler is basically read-only, unless the signal handler calls setcontext or swapcontext. For a start, restore the thread's signal mask from the uc_sigmask value of the context given to the signal handler. If that's feasible for Cygwin, we restore the entire context from the context changed by the signal handler in a followup patch. Signed-off-by: Corinna Vinschen --- winsup/cygwin/exceptions.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/winsup/cygwin/exceptions.cc b/winsup/cygwin/exceptions.cc index da4348fdb..a9b378133 100644 --- a/winsup/cygwin/exceptions.cc +++ b/winsup/cygwin/exceptions.cc @@ -1818,7 +1818,8 @@ _cygtls::call_signal_handler () incyg = true; - set_signal_mask (_my_tls.sigmask, this_oldmask); + set_signal_mask (_my_tls.sigmask, (this_sa_flags & SA_SIGINFO) + ? context.uc_sigmask : this_oldmask); if (this_errno >= 0) set_errno (this_errno); } From 6a06c6bc8f8492ea09aa3ae180fe94e4ac265611 Mon Sep 17 00:00:00 2001 From: Takashi Yano Date: Thu, 4 Apr 2019 01:25:31 +0900 Subject: [PATCH 326/475] Cygwin: console: fix key input for native console application - After 24 bit color support patch, arrow keys and function keys do not work properly in native console applications if they are started in cygwin console. This patch fixes this issue. --- winsup/cygwin/fhandler_console.cc | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/winsup/cygwin/fhandler_console.cc b/winsup/cygwin/fhandler_console.cc index 6d42ed888..e3656a33a 100644 --- a/winsup/cygwin/fhandler_console.cc +++ b/winsup/cygwin/fhandler_console.cc @@ -455,6 +455,15 @@ sig_exit: fhandler_console::input_states fhandler_console::process_input_message (void) { + if (wincap.has_con_24bit_colors ()) + { + DWORD dwMode; + /* Enable xterm compatible mode in input */ + GetConsoleMode (get_handle (), &dwMode); + dwMode |= ENABLE_VIRTUAL_TERMINAL_INPUT; + SetConsoleMode (get_handle (), dwMode); + } + char tmp[60]; if (!shared_console_info) @@ -2881,6 +2890,14 @@ fhandler_console::fixup_after_fork_exec (bool execing) { set_unit (); setup_io_mutex (); + if (wincap.has_con_24bit_colors ()) + { + DWORD dwMode; + /* Disable xterm compatible mode in input */ + GetConsoleMode (get_handle (), &dwMode); + dwMode &= ~ENABLE_VIRTUAL_TERMINAL_INPUT; + SetConsoleMode (get_handle (), dwMode); + } } // #define WINSTA_ACCESS (WINSTA_READATTRIBUTES | STANDARD_RIGHTS_READ | STANDARD_RIGHTS_WRITE | WINSTA_CREATEDESKTOP | WINSTA_EXITWINDOWS) From c5f9eed1c045ad05e968c9a9b8fb22b1d46cd8ea Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Thu, 4 Apr 2019 21:25:47 +0200 Subject: [PATCH 327/475] Cygwin: signals: make setcontext work from signal handlers Signed-off-by: Corinna Vinschen --- winsup/cygwin/exceptions.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/winsup/cygwin/exceptions.cc b/winsup/cygwin/exceptions.cc index a9b378133..0aaeee52f 100644 --- a/winsup/cygwin/exceptions.cc +++ b/winsup/cygwin/exceptions.cc @@ -1867,6 +1867,7 @@ setcontext (const ucontext_t *ucp) { PCONTEXT ctx = (PCONTEXT) &ucp->uc_mcontext; _my_tls.sigmask = ucp->uc_sigmask; + _my_tls.incyg = true; #ifdef __x86_64__ /* Apparently a call to NtContinue works on 64 bit as well, but using RtlRestoreContext is the blessed way. */ From 181ca73e493ee134aec1431f398423ed619627b2 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Fri, 5 Apr 2019 11:25:19 +0200 Subject: [PATCH 328/475] Cygwin: follow context if changed inside SA_SIGINFO signal handler Signed-off-by: Corinna Vinschen --- winsup/cygwin/exceptions.cc | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/winsup/cygwin/exceptions.cc b/winsup/cygwin/exceptions.cc index 0aaeee52f..e5e770370 100644 --- a/winsup/cygwin/exceptions.cc +++ b/winsup/cygwin/exceptions.cc @@ -1645,7 +1645,7 @@ _cygtls::call_signal_handler () siginfo_t thissi = infodata; void (*thisfunc) (int, siginfo_t *, void *) = func; - ucontext_t *thiscontext = NULL; + ucontext_t *thiscontext = NULL, context_copy; /* Only make a context for SA_SIGINFO handlers */ if (this_sa_flags & SA_SIGINFO) @@ -1701,6 +1701,7 @@ _cygtls::call_signal_handler () ? (uintptr_t) thissi.si_addr : 0; thiscontext = &context; + context_copy = context; } int this_errno = saved_errno; @@ -1822,6 +1823,14 @@ _cygtls::call_signal_handler () ? context.uc_sigmask : this_oldmask); if (this_errno >= 0) set_errno (this_errno); + if (this_sa_flags & SA_SIGINFO) + { + /* If more than just the sigmask in the context has been changed by + the signal handler, call setcontext. */ + context_copy.uc_sigmask = context.uc_sigmask; + if (memcmp (&context, &context_copy, sizeof context) != 0) + setcontext (&context); + } } /* FIXME: Since 2011 this return statement always returned 1 (meaning From 372874364eb2752ac095f55172de3dc11372f03f Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Fri, 5 Apr 2019 12:13:44 +0200 Subject: [PATCH 329/475] Cygwin: signals: setcontext: fix setting sigmask Signed-off-by: Corinna Vinschen --- winsup/cygwin/exceptions.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/winsup/cygwin/exceptions.cc b/winsup/cygwin/exceptions.cc index e5e770370..1765f43b5 100644 --- a/winsup/cygwin/exceptions.cc +++ b/winsup/cygwin/exceptions.cc @@ -1875,7 +1875,7 @@ extern "C" int setcontext (const ucontext_t *ucp) { PCONTEXT ctx = (PCONTEXT) &ucp->uc_mcontext; - _my_tls.sigmask = ucp->uc_sigmask; + set_signal_mask (_my_tls.sigmask, ucp->uc_sigmask); _my_tls.incyg = true; #ifdef __x86_64__ /* Apparently a call to NtContinue works on 64 bit as well, but using From f0ea836b753b0756b00866ac8b909a0a7dfbac5f Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Sat, 6 Apr 2019 18:03:22 +0200 Subject: [PATCH 330/475] Cygwin: add latest signal handling fixes to release notes Signed-off-by: Corinna Vinschen --- winsup/cygwin/release/3.0.6 | 9 +++++++-- winsup/cygwin/release/3.1.0 | 3 +++ winsup/doc/new-features.xml | 5 +++++ 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/winsup/cygwin/release/3.0.6 b/winsup/cygwin/release/3.0.6 index 14a83290e..d9fca5875 100644 --- a/winsup/cygwin/release/3.0.6 +++ b/winsup/cygwin/release/3.0.6 @@ -9,6 +9,11 @@ What changed: Bug Fixes --------- -- Fix the problem that `ps' or `pstree' may show up in their own - output twice. +- Fix the problem that `ps' or `pstree' may show up in their own output twice. Addresses: Report on IRC + +- Honor setting uc_sigmask in a sigaction signal handler. + Addresses: https://cygwin.com/ml/cygwin/2019-04/msg00016.html + +- Fix signal handling if setcontext is called from a signal handler. + Addresses: Self-tested. diff --git a/winsup/cygwin/release/3.1.0 b/winsup/cygwin/release/3.1.0 index d55b65517..95569fc2b 100644 --- a/winsup/cygwin/release/3.1.0 +++ b/winsup/cygwin/release/3.1.0 @@ -13,6 +13,9 @@ What changed: Addresses: https://cygwin.com/ml/cygwin/2015-03/msg00047.html https://cygwin.com/ml/cygwin/2015-12/msg00311.html +- If a SA_SIGINFO signal handler changes the ucontext_t pointed to by + the third parameter, follow it after returning from the handler. + Bug Fixes --------- diff --git a/winsup/doc/new-features.xml b/winsup/doc/new-features.xml index 829f81721..376789cda 100644 --- a/winsup/doc/new-features.xml +++ b/winsup/doc/new-features.xml @@ -18,6 +18,11 @@ Add 24 bit color support using xterm compatibility mode in Windows 10 uses the nearest color from 16 system colors. + +If a SA_SIGINFO signal handler changes the ucontext_t pointed to by the +third parameter, follow it after returning from the handler. + + From 2607639992f6600135532831c8357c10cb248821 Mon Sep 17 00:00:00 2001 From: "Erik M. Bray" Date: Wed, 10 Apr 2019 17:05:22 +0200 Subject: [PATCH 331/475] Improve error handling in /proc/[pid]/ virtual files. * Changes error handling to allow /proc/[pid]/ virtual files to be empty in some cases (in this case the file's formatter should return -1 upon error, not 0). * Better error handling of /proc/[pid]/stat for zombie processes: previously trying to open this file on zombie processes resulted in an EINVAL being returned by open(). Now the file can be read, and fields that can no longer be read are just zeroed. * Similarly for /proc/[pid]/statm for zombie processes. * Similarly for /proc/[pid]/maps for zombie processes (in this case the file can be read but is zero-length, which is consistent with observed behavior on Linux. --- winsup/cygwin/fhandler_process.cc | 35 ++++++++++++++++++++++++------- 1 file changed, 28 insertions(+), 7 deletions(-) diff --git a/winsup/cygwin/fhandler_process.cc b/winsup/cygwin/fhandler_process.cc index 44410b223..5ee129317 100644 --- a/winsup/cygwin/fhandler_process.cc +++ b/winsup/cygwin/fhandler_process.cc @@ -355,7 +355,7 @@ fhandler_process::fill_filebuf () } else filesize = process_tab[fileid].format_func (p, filebuf); - return !filesize ? false : true; + return filesize < 0 ? false : true; } return false; } @@ -818,7 +818,22 @@ format_process_maps (void *data, char *&destbuf) HANDLE proc = OpenProcess (PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, p->dwProcessId); if (!proc) - return 0; + { + if (!(p->process_state & PID_EXITED)) + { + DWORD error = GetLastError (); + __seterrno_from_win_error (error); + debug_printf ("OpenProcess: ret %u; pid: %d", error, p->dwProcessId); + return -1; + } + else + { + /* Else it's a zombie process; just return an empty string */ + destbuf = (char *) crealloc_abort (destbuf, 1); + destbuf[0] = '\0'; + return 0; + } + } NTSTATUS status; PROCESS_BASIC_INFORMATION pbi; @@ -1101,9 +1116,14 @@ format_process_stat (void *data, char *&destbuf) FALSE, p->dwProcessId); if (hProcess == NULL) { - DWORD error = GetLastError (); - __seterrno_from_win_error (error); - debug_printf ("OpenProcess: ret %u", error); + if (!(p->process_state & PID_EXITED)) + { + DWORD error = GetLastError (); + __seterrno_from_win_error (error); + debug_printf ("OpenProcess: ret %u; pid: %d", error, p->dwProcessId); + return -1; + } + /* Else it's a zombie process; just leave each structure zero'd */ } else { @@ -1258,9 +1278,10 @@ format_process_statm (void *data, char *&destbuf) { _pinfo *p = (_pinfo *) data; size_t vmsize = 0, vmrss = 0, vmtext = 0, vmdata = 0, vmlib = 0, vmshare = 0; + if (!get_mem_values (p->dwProcessId, vmsize, vmrss, vmtext, vmdata, - vmlib, vmshare)) - return 0; + vmlib, vmshare) && !(p->process_state & PID_EXITED)) + return -1; /* Error out unless it's a zombie process */ destbuf = (char *) crealloc_abort (destbuf, 96); return __small_sprintf (destbuf, "%lu %lu %lu %lu %lu %lu 0\n", From 630808d2a2865634df3f54cec403a058511596e7 Mon Sep 17 00:00:00 2001 From: Christophe Lyon Date: Mon, 1 Apr 2019 17:30:53 +0000 Subject: [PATCH 332/475] Make more macro checks ARMv8-M baseline proof. Commit 69f4c4029183fb26d2fcae00790881620c1978a3 improved most macro checks to be ARMv8-M baseline proof, but missed a few occurrences which otherwise fail to build when using a CPU setting such as cortex-m0 or cortex-m23. This patch brings the same changes as the ones that were committed to libgloss at that time. newlib: * libc/sys/arm/crt0.S: Use THUMB1_ONLY rather than __ARM_ARCH_6M__. --- newlib/libc/sys/arm/crt0.S | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/newlib/libc/sys/arm/crt0.S b/newlib/libc/sys/arm/crt0.S index 64d425900..8c9f7be38 100644 --- a/newlib/libc/sys/arm/crt0.S +++ b/newlib/libc/sys/arm/crt0.S @@ -85,7 +85,7 @@ /* Stack limit is at end of data. */ /* Allow slop for stack overflow handling and small frames. */ -#ifdef __ARM_ARCH_6M__ +#ifdef THUMB1_ONLY ldr r0, .LC2 adds r0, #128 adds r0, #128 @@ -137,7 +137,7 @@ beq .LC27 /* Allow slop for stack overflow handling and small frames. */ -#ifdef __ARM_ARCH_6M__ +#ifdef THUMB1_ONLY adds r2, #128 adds r2, #128 mov sl, r2 @@ -164,7 +164,7 @@ #ifdef __thumb2__ it eq #endif -#ifdef __ARM_ARCH_6M__ +#ifdef THUMB1_ONLY bne .LC28 ldr r3, .LC0 .LC28: @@ -219,7 +219,7 @@ this default 64k is enough for the program being executed. However, it ensures that this simple crt0 world will not immediately cause an overflow event: */ -#ifdef __ARM_ARCH_6M__ +#ifdef THUMB1_ONLY movs r2, #64 lsls r2, r2, #10 subs r2, r3, r2 From cc430406ac09d99570b5218668f2bb00371ae983 Mon Sep 17 00:00:00 2001 From: Christophe Lyon Date: Wed, 10 Apr 2019 15:04:13 +0000 Subject: [PATCH 333/475] Include code in trap.S for APCS only. The code in trap.S is to support the old APCS chunked stack variant, which dates back to the Acorn days, so put it under #ifndef __ARM_EABI__. * libgloss/arm/trap.S: Use __ARM_EABI rather than PREFER_THUMB. * newlib/libc/sys/arm/trap.S: Use __ARM_EABI rather than __thumb2__. --- libgloss/arm/trap.S | 2 +- newlib/libc/sys/arm/trap.S | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libgloss/arm/trap.S b/libgloss/arm/trap.S index d854b57bb..845ad0173 100644 --- a/libgloss/arm/trap.S +++ b/libgloss/arm/trap.S @@ -1,6 +1,6 @@ #include "arm.h" /* Run-time exception support */ -#ifndef PREFER_THUMB +#ifndef __ARM_EABI__ #include "swi.h" /* .text is used instead of .section .text so it works with arm-aout too. */ diff --git a/newlib/libc/sys/arm/trap.S b/newlib/libc/sys/arm/trap.S index 21b6937f9..681b3dbe0 100644 --- a/newlib/libc/sys/arm/trap.S +++ b/newlib/libc/sys/arm/trap.S @@ -1,5 +1,5 @@ /* Run-time exception support */ -#if !defined(__thumb2__) +#ifndef __ARM_EABI__ #include "swi.h" /* .text is used instead of .section .text so it works with arm-aout too. */ From a0b0a4a01820661724ee08f54fbba7a51b190c96 Mon Sep 17 00:00:00 2001 From: Alexander Fedotov Date: Thu, 11 Apr 2019 15:28:05 +0300 Subject: [PATCH 334/475] Align comments and spaces in libgloss/arm/crt0.S and newlib/libc/sys/arm/crt0.S to ease further code alignment. --- libgloss/arm/crt0.S | 135 +++++++++++++++++++------------------ newlib/libc/sys/arm/crt0.S | 18 ++--- 2 files changed, 78 insertions(+), 75 deletions(-) diff --git a/libgloss/arm/crt0.S b/libgloss/arm/crt0.S index c708f63d8..1deb73aa5 100644 --- a/libgloss/arm/crt0.S +++ b/libgloss/arm/crt0.S @@ -68,8 +68,10 @@ #endif .endm +/******************************************************************************* +* Main library startup code. +*******************************************************************************/ .align 0 - FUNC_START _mainCRTStartup FUNC_START _start #if defined(__ELF__) && !defined(__USING_SJLJ_EXCEPTIONS__) @@ -90,14 +92,14 @@ #endif #endif -/* Start by setting up a stack */ +/* Start by setting up a stack. */ #ifdef ARM_RDP_MONITOR - /* Issue Demon SWI to read stack info */ - swi SWI_GetEnv /* Returns command line in r0 */ - mov sp,r1 /* and the highest memory address in r1 */ + /* Issue Demon SWI to read stack info. */ + swi SWI_GetEnv /* Returns command line in r0. */ + mov sp,r1 /* and the highest memory address in r1. */ - /* stack limit is at end of data */ - /* allow slop for stack overflow handling and small frames */ + /* Stack limit is at end of data. */ + /* Allow slop for stack overflow handling and small frames. */ #ifdef THUMB1_ONLY ldr r0, .LC2 adds r0, #128 @@ -109,19 +111,19 @@ #endif #else #ifdef ARM_RDI_MONITOR - /* Issue Angel SWI to read stack info */ + /* Issue Angel SWI to read stack info. */ movs r0, #AngelSWI_Reason_HeapInfo - adr r1, .LC0 /* point at ptr to 4 words to receive data */ + adr r1, .LC0 /* Point at ptr to 4 words to receive data. */ #ifdef THUMB_VXM bkpt AngelSWI #elif defined(__thumb2__) - /* We are in thumb mode for startup on armv7 architectures. */ + /* We are in thumb mode for startup on armv7 architectures. */ AngelSWIAsm (AngelSWI) #else - /* We are always in ARM mode for startup on pre armv7 archs. */ + /* We are always in ARM mode for startup on pre armv7 archs. */ AngelSWIAsm (AngelSWI_ARM) #endif - ldr r0, .LC0 /* point at values read */ + ldr r0, .LC0 /* Point at values read. */ /* Set __heap_limit. */ ldr r1, [r0, #4] @@ -148,14 +150,15 @@ to skip setting sp/sl to 0 here. - Considering M-profile processors, We might want to initialize sp by the first entry of vector table and return 0 to SYS_HEAPINFO - semihosting call, which will be skipped here. */ + semihosting call, which will be skipped here. */ cmp r1, #0 beq .LC26 mov sp, r1 .LC26: cmp r2, #0 beq .LC27 - /* allow slop for stack overflow handling and small frames */ + + /* Allow slop for stack overflow handling and small frames. */ #ifdef THUMB1_ONLY adds r2, #128 adds r2, #128 @@ -163,9 +166,10 @@ #else add sl, r2, #256 #endif + .LC27: #else - /* Set up the stack pointer to a fixed value */ + /* Set up the stack pointer to a fixed value. */ /* Changes by toralf: - Allow linker script to provide stack via __stack symbol - see defintion of .Lstack @@ -175,7 +179,7 @@ Loosely based on init.s from ARM/Motorola example code. Note: Mode switch via CPSR is not allowed once in non-privileged mode, so we take care not to enter "User" to set up its sp, - and also skip most operations if already in that mode. */ + and also skip most operations if already in that mode. */ ldr r3, .Lstack cmp r3, #0 @@ -192,42 +196,42 @@ /* Note: This 'mov' is essential when starting in User, and ensures we always get *some* sp value for the initial mode, even if we have somehow missed it below (in which case it gets the same - value as FIQ - not ideal, but better than nothing.) */ + value as FIQ - not ideal, but better than nothing). */ mov sp, r3 #ifdef PREFER_THUMB /* XXX Fill in stack assignments for interrupt modes. */ #else mrs r2, CPSR - tst r2, #0x0F /* Test mode bits - in User of all are 0 */ - beq .LC23 /* "eq" means r2 AND #0x0F is 0 */ - msr CPSR_c, #0xD1 /* FIRQ mode, interrupts disabled */ + tst r2, #0x0F /* Test mode bits - in User of all are 0. */ + beq .LC23 /* "eq" means r2 AND #0x0F is 0. */ + msr CPSR_c, #0xD1 /* FIRQ mode, interrupts disabled. */ mov sp, r3 - sub sl, sp, #0x1000 /* This mode also has its own sl (see below) */ + sub sl, sp, #0x1000 /* This mode also has its own sl (see below). */ mov r3, sl - msr CPSR_c, #0xD7 /* Abort mode, interrupts disabled */ + msr CPSR_c, #0xD7 /* Abort mode, interrupts disabled. */ mov sp, r3 sub r3, r3, #0x1000 - msr CPSR_c, #0xDB /* Undefined mode, interrupts disabled */ + msr CPSR_c, #0xDB /* Undefined mode, interrupts disabled. */ mov sp, r3 sub r3, r3, #0x1000 - msr CPSR_c, #0xD2 /* IRQ mode, interrupts disabled */ + msr CPSR_c, #0xD2 /* IRQ mode, interrupts disabled. */ mov sp, r3 sub r3, r3, #0x2000 - msr CPSR_c, #0xD3 /* Supervisory mode, interrupts disabled */ + msr CPSR_c, #0xD3 /* Supervisory mode, interrupts disabled. */ mov sp, r3 - sub r3, r3, #0x8000 /* Min size 32k */ - bic r3, r3, #0x00FF /* Align with current 64k block */ + sub r3, r3, #0x8000 /* Min size 32k. */ + bic r3, r3, #0x00FF /* Align with current 64k block. */ bic r3, r3, #0xFF00 str r3, [r3, #-4] /* Move value into user mode sp without */ - ldmdb r3, {sp}^ /* changing modes, via '^' form of ldm */ + ldmdb r3, {sp}^ /* changing modes, via '^' form of ldm. */ orr r2, r2, #0xC0 /* Back to original mode, presumably SVC, */ - msr CPSR_c, r2 /* with FIQ/IRQ disable bits forced to 1 */ + msr CPSR_c, r2 /* with FIQ/IRQ disable bits forced to 1. */ #endif .LC23: /* Setup a default stack-limit in-case the code has been @@ -243,24 +247,24 @@ subs r2, r3, r2 mov sl, r2 #else - sub sl, r3, #64 << 10 /* Still assumes 256bytes below sl */ + sub sl, r3, #64 << 10 /* Still assumes 256bytes below sl. */ #endif #endif #endif /* Zero the memory in the .bss section. */ - movs a2, #0 /* Second arg: fill value */ - mov fp, a2 /* Null frame pointer */ - mov r7, a2 /* Null frame pointer for Thumb */ + movs a2, #0 /* Second arg: fill value. */ + mov fp, a2 /* Null frame pointer. */ + mov r7, a2 /* Null frame pointer for Thumb. */ - ldr a1, .LC1 /* First arg: start of memory block */ + ldr a1, .LC1 /* First arg: start of memory block. */ ldr a3, .LC2 - subs a3, a3, a1 /* Third arg: length of block */ + subs a3, a3, a1 /* Third arg: length of block. */ #if __thumb__ && !defined(PREFER_THUMB) - /* Enter Thumb mode.... */ - add a4, pc, #1 /* Get the address of the Thumb block */ - bx a4 /* Go there and start Thumb decoding */ + /* Enter Thumb mode... */ + add a4, pc, #1 /* Get the address of the Thumb block. */ + bx a4 /* Go there and start Thumb decoding. */ .code 16 .global __change_mode @@ -271,9 +275,8 @@ __change_mode: bl FUNCTION (memset) #if !defined (ARM_RDP_MONITOR) && !defined (ARM_RDI_MONITOR) /* Changes by toralf: Taken from libgloss/m68k/crt0.S - * initialize target specific stuff. Only execute these - * functions it they exist. - */ + initialize target specific stuff. Only execute these + functions it they exist. */ ldr r3, .Lhwinit cmp r3, #0 beq .LC24 @@ -285,24 +288,24 @@ __change_mode: indirect_call r3 .LC25: - movs r0, #0 /* no arguments */ - movs r1, #0 /* no argv either */ + movs r0, #0 /* No arguments. */ + movs r1, #0 /* No argv either. */ #else - /* Need to set up standard file handles */ + /* Need to set up standard file handles. */ bl FUNCTION (initialise_monitor_handles) #ifdef ARM_RDP_MONITOR - swi SWI_GetEnv /* sets r0 to point to the command line */ + swi SWI_GetEnv /* Sets r0 to point to the command line. */ movs r1, r0 #else movs r0, #AngelSWI_Reason_GetCmdLine - ldr r1, .LC30 /* Space for command line */ + ldr r1, .LC30 /* Space for command line. */ AngelSWIAsm (AngelSWI) ldr r1, .LC30 ldr r1, [r1] #endif - /* Parse string at r1 */ - movs r0, #0 /* count of arguments so far */ + /* Parse string at r1. */ + movs r0, #0 /* Count of arguments so far. */ /* Push a NULL argument onto the end of the list. */ #ifdef __thumb__ push {r0} @@ -310,7 +313,7 @@ __change_mode: stmfd sp!, {r0} #endif .LC10: -/* Skip leading blanks */ +/* Skip leading blanks. */ #ifdef __thumb__ ldrb r3, [r1] adds r1, #1 @@ -322,7 +325,7 @@ __change_mode: cmp r3, #' ' beq .LC10 -/* See whether we are scanning a string */ +/* See whether we are scanning a string. */ cmp r3, #'"' #ifdef __thumb__ beq .LC20 @@ -333,17 +336,17 @@ __change_mode: b .LC22 .LC21: - movs r2, #' ' /* terminator type */ - subs r1, r1, #1 /* adjust back to point at start char */ + movs r2, #' ' /* Terminator type. */ + subs r1, r1, #1 /* Adjust back to point at start char. */ .LC22: #else cmpne r3, #'\'' moveq r2, r3 - movne r2, #' ' /* terminator type */ - subne r1, r1, #1 /* adjust back to point at start char */ + movne r2, #' ' /* Terminator type. */ + subne r1, r1, #1 /* Adjust back to point at start char. */ #endif -/* Stack a pointer to the current argument */ +/* Stack a pointer to the current argument. */ #ifdef __thumb__ push {r1} #else @@ -359,16 +362,16 @@ __change_mode: #endif cmp r3, #0 beq .LC12 - cmp r2, r3 /* reached terminator? */ + cmp r2, r3 /* Reached terminator ? */ bne .LC11 movs r2, #0 subs r3, r1, #1 - strb r2, [r3] /* terminate the arg string */ + strb r2, [r3] /* Terminate the arg string. */ b .LC10 .LC12: - mov r1, sp /* point at stacked arg pointers */ - /* We've now got the stacked args in order reverse the */ + mov r1, sp /* Point at stacked arg pointers. */ + /* We've now got the stacked args in order, reverse them. */ #ifdef __thumb__ movs r2, r0 lsls r2, #2 @@ -390,10 +393,10 @@ __change_mode: bics r4, r5 mov sp, r4 #else - add r2, sp, r0, LSL #2 /* End of args */ - mov r3, sp /* Start of args */ + add r2, sp, r0, LSL #2 /* End of args. */ + mov r3, sp /* Start of args. */ .LC13: cmp r2, r3 - ldrhi r4,[r2, #-4] /* Reverse ends of list */ + ldrhi r4,[r2, #-4] /* Reverse ends of list. */ ldrhi r5, [r3] strhi r5, [r2, #-4]! strhi r4, [r3], #4 @@ -431,7 +434,6 @@ __change_mode: #if __thumb__ && !defined(PREFER_THUMB) /* Come out of Thumb mode. This code should be redundant. */ - mov a4, pc bx a4 @@ -447,7 +449,6 @@ change_back: /* For Thumb, constants must be after the code since only positive offsets are supported for PC relative addresses. */ - .align 0 .LC0: #ifdef ARM_RDI_MONITOR @@ -457,13 +458,13 @@ change_back: /* Changes by toralf: Provide alternative "stack" variable whose value may be defined externally; .Lstack will be used instead of .LC0 if it points to a non-0 value. Also set up references to "hooks" that - may be used by the application to provide additional init code. */ - + may be used by the application to provide additional init code. */ #ifdef __pe__ .word 0x800000 #else .word 0x80000 /* Top of RAM on the PIE board. */ #endif + .Lstack: .word __stack .Lhwinit: @@ -476,7 +477,7 @@ change_back: runtime (meaning "ignore setting") for the variables, when the user does not provide the symbols. (The linker uses a weak symbol if, and only if, a normal version of the same symbol isn't provided - e.g. by a linker script or another object file.) */ + e.g. by a linker script or another object file.) */ .weak __stack .weak FUNCTION (hardware_init_hook) diff --git a/newlib/libc/sys/arm/crt0.S b/newlib/libc/sys/arm/crt0.S index 8c9f7be38..7a6b40d9a 100644 --- a/newlib/libc/sys/arm/crt0.S +++ b/newlib/libc/sys/arm/crt0.S @@ -50,13 +50,13 @@ .global \name .thumb_func \name: -.endm +.endm #else .code 32 .macro FUNC_START name - .global \name + .global \name \name: -.endm +.endm #endif .macro indirect_call reg @@ -68,8 +68,10 @@ #endif .endm +/******************************************************************************* +* Main library startup code. +*******************************************************************************/ .align 0 - FUNC_START _mainCRTStartup FUNC_START _start #if defined(__ELF__) && !defined(__USING_SJLJ_EXCEPTIONS__) @@ -399,7 +401,7 @@ __change_mode: bl FUNCTION (_init) movs r0, r4 movs r1, r5 -#endif +#endif bl FUNCTION (main) bl FUNCTION (exit) /* Should not return. */ @@ -420,7 +422,7 @@ change_back: #endif /* For Thumb, constants must be after the code since only - positive offsets are supported for PC relative addresses. */ + positive offsets are supported for PC relative addresses. */ .align 0 .LC0: #ifdef ARM_RDI_MONITOR @@ -430,7 +432,7 @@ change_back: /* Changes by toralf: Provide alternative "stack" variable whose value may be defined externally; .Lstack will be used instead of .LC0 if it points to a non-0 value. Also set up references to "hooks" that - may be used by the application to provide additional init code. */ + may be used by the application to provide additional init code. */ #ifdef __pe__ .word 0x800000 #else @@ -449,7 +451,7 @@ change_back: runtime (meaning "ignore setting") for the variables, when the user does not provide the symbols. (The linker uses a weak symbol if, and only if, a normal version of the same symbol isn't provided - e.g. by a linker script or another object file). */ + e.g. by a linker script or another object file.) */ .weak __stack .weak FUNCTION (hardware_init_hook) From 204efa6bbac2b355c65818100414c3ce2cda2a9e Mon Sep 17 00:00:00 2001 From: Michael Haubenwallner Date: Fri, 12 Apr 2019 15:32:56 +0200 Subject: [PATCH 335/475] Cygwin: use win pid+threadid for forkables dirname Rather than newest last write time of all dlls loaded, use the forking process' windows pid and windows thread id as directory name to create the forkable hardlinks into. While this may create hardlinks more often, it does avoid conflicts between dlls not having the newest last write time. --- winsup/cygwin/forkable.cc | 26 +++++++------------------- 1 file changed, 7 insertions(+), 19 deletions(-) diff --git a/winsup/cygwin/forkable.cc b/winsup/cygwin/forkable.cc index d1b0f5723..4580610b1 100644 --- a/winsup/cygwin/forkable.cc +++ b/winsup/cygwin/forkable.cc @@ -340,30 +340,18 @@ exename (PWCHAR buf, ssize_t bufsize) return format_IndexNumber (buf, bufsize, &d->fii.IndexNumber); } -/* Into buf if not NULL, write the newest dll's LastWriteTime. +/* Into buf if not NULL, write the current Windows Thread Identifier. Return the number of characters (that would be) written. */ static int -lwtimename (PWCHAR buf, ssize_t bufsize) +winthrname (PWCHAR buf, ssize_t bufsize) { if (!buf) - return sizeof (LARGE_INTEGER) * 2; - if (bufsize >= 0 && bufsize <= (int)sizeof (LARGE_INTEGER) * 2) + return sizeof (DWORD) * 4; + if (bufsize >= 0 && bufsize <= (int)sizeof (DWORD) * 4) return 0; - LARGE_INTEGER newest = { 0 }; - /* Need by-handle-file-information for _all_ loaded dlls, - as most recent ctime forms the hardlinks directory. */ - dll *d = &dlls.start; - while ((d = d->next)) - { - /* LastWriteTime more properly tells the last file-content modification - time, because a newly created hardlink may have a different - CreationTime compared to the original file. */ - if (d->fbi.LastWriteTime.QuadPart > newest.QuadPart) - newest = d->fbi.LastWriteTime; - } - - return __small_swprintf (buf, L"%016X", newest); + return __small_swprintf (buf, L"%08X%08X", + GetCurrentProcessId(), GetCurrentThreadId()); } struct namepart { @@ -382,7 +370,7 @@ forkable_nameparts[] = { { L"", sidname, true, true, }, { L"", exename, false, false, }, { MUTEXSEP, NULL, false, false, }, - { L"", lwtimename, true, true, }, + { L"", winthrname, true, true, }, { NULL, NULL }, }; From a2e81650d159d539d078194fa88f297b4fde77e5 Mon Sep 17 00:00:00 2001 From: Jozef Lawrynowicz Date: Fri, 12 Apr 2019 11:49:11 +0100 Subject: [PATCH 336/475] Fix definition of write() to use const char * for the type of the buffer --- libgloss/msp430/write.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/libgloss/msp430/write.c b/libgloss/msp430/write.c index 3a5a9f810..3e1086c00 100644 --- a/libgloss/msp430/write.c +++ b/libgloss/msp430/write.c @@ -16,7 +16,7 @@ #include "cio.h" static int -write_chunk (int fd, char *buf, int len) +write_chunk (int fd, const char *buf, int len) { __CIOBUF__.length[0] = len; __CIOBUF__.length[1] = len >> 8; @@ -35,10 +35,11 @@ write_chunk (int fd, char *buf, int len) #include int -write (int fd, char *buf, int len) +write (int fd, const char *buf, int len) { int rv = 0; int c; + int i = 0; #if 0 if (fd == 2) fprintf (stderr, "%.*s", buf, len); @@ -48,12 +49,12 @@ write (int fd, char *buf, int len) while (len > 0) { int l = (len > CIO_BUF_SIZE) ? CIO_BUF_SIZE : len; - c = write_chunk (fd, buf, l); + c = write_chunk (fd, buf + i, l); if (c < 0) return c; rv += l; len -= l; - buf += l; + i += l; } return rv; } From 2af6ad9f05e36a3d4527430a526a445359cfa006 Mon Sep 17 00:00:00 2001 From: Jozef Lawrynowicz Date: Fri, 12 Apr 2019 11:57:59 +0100 Subject: [PATCH 337/475] Copy prerequisite file for "tiny" printf implementation Use newlib/libc/stdio/nano-vfprintf.c as baseline for tiny-printf.c --- newlib/libc/machine/msp430/tiny-printf.c | 661 +++++++++++++++++++++++ 1 file changed, 661 insertions(+) create mode 100644 newlib/libc/machine/msp430/tiny-printf.c diff --git a/newlib/libc/machine/msp430/tiny-printf.c b/newlib/libc/machine/msp430/tiny-printf.c new file mode 100644 index 000000000..bc7ed0743 --- /dev/null +++ b/newlib/libc/machine/msp430/tiny-printf.c @@ -0,0 +1,661 @@ +/* + * Copyright (c) 1990 The Regents of the University of California. + * All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Chris Torek. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * Copyright (c) 2012-2014 ARM Ltd + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the company may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY ARM LTD ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL ARM LTD BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* +FUNCTION +<>, <>, <>, <>, <>, <>---format argument list + +INDEX + vfprintf +INDEX + _vfprintf_r +INDEX + vprintf +INDEX + _vprintf_r +INDEX + vsprintf +INDEX + _vsprintf_r +INDEX + vsnprintf +INDEX + _vsnprintf_r +INDEX + vasprintf +INDEX + _vasprintf_r +INDEX + vasnprintf +INDEX + _vasnprintf_r + +SYNOPSIS + #include + #include + int vprintf(const char *<[fmt]>, va_list <[list]>); + int vfprintf(FILE *<[fp]>, const char *<[fmt]>, va_list <[list]>); + int vsprintf(char *<[str]>, const char *<[fmt]>, va_list <[list]>); + int vsnprintf(char *<[str]>, size_t <[size]>, const char *<[fmt]>, + va_list <[list]>); + int vasprintf(char **<[strp]>, const char *<[fmt]>, va_list <[list]>); + char *vasnprintf(char *<[str]>, size_t *<[size]>, const char *<[fmt]>, + va_list <[list]>); + + int _vprintf_r(struct _reent *<[reent]>, const char *<[fmt]>, + va_list <[list]>); + int _vfprintf_r(struct _reent *<[reent]>, FILE *<[fp]>, + const char *<[fmt]>, va_list <[list]>); + int _vsprintf_r(struct _reent *<[reent]>, char *<[str]>, + const char *<[fmt]>, va_list <[list]>); + int _vasprintf_r(struct _reent *<[reent]>, char **<[str]>, + const char *<[fmt]>, va_list <[list]>); + int _vsnprintf_r(struct _reent *<[reent]>, char *<[str]>, + size_t <[size]>, const char *<[fmt]>, va_list <[list]>); + char *_vasnprintf_r(struct _reent *<[reent]>, char *<[str]>, + size_t *<[size]>, const char *<[fmt]>, va_list <[list]>); + +DESCRIPTION +<>, <>, <>, <>, <>, +and <> are (respectively) variants of <>, +<>, <>, <>, <>, and +<>. They differ only in allowing their caller to pass the +variable argument list as a <> object (initialized by +<>) rather than directly accepting a variable number of +arguments. The caller is responsible for calling <>. + +<<_vprintf_r>>, <<_vfprintf_r>>, <<_vasprintf_r>>, <<_vsprintf_r>>, +<<_vsnprintf_r>>, and <<_vasnprintf_r>> are reentrant versions of the +above. + +RETURNS +The return values are consistent with the corresponding functions. + +PORTABILITY +ANSI C requires <>, <>, <>, and +<>. The remaining functions are newlib extensions. + +Supporting OS subroutines required: <>, <>, <>, +<>, <>, <>, <>. +*/ + +#if defined(LIBC_SCCS) && !defined(lint) +/*static char *sccsid = "from: @(#)vfprintf.c 5.50 (Berkeley) 12/16/92";*/ +static char *rcsid = "$Id$"; +#endif /* LIBC_SCCS and not lint */ + +/* Actual printf innards. + This code is large and complicated... */ +#include + +#define VFPRINTF vfprintf +#ifdef STRING_ONLY +# define _VFPRINTF_R _svfprintf_r +#else +# define _VFPRINTF_R _vfprintf_r +#endif + +#include <_ansi.h> +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "local.h" +#include "../stdlib/local.h" +#include "fvwrite.h" +#include "vfieeefp.h" +#include "nano-vfprintf_local.h" + +/* The __ssputs_r function is shared between all versions of vfprintf + and vfwprintf. */ +#ifdef STRING_ONLY +int +__ssputs_r (struct _reent *ptr, + FILE *fp, + const char *buf, + size_t len) +{ + register int w; + + w = fp->_w; + if (len >= w && fp->_flags & (__SMBF | __SOPT)) + { + /* Must be asprintf family. */ + unsigned char *str; + int curpos = (fp->_p - fp->_bf._base); + /* Choose a geometric growth factor to avoid + * quadratic realloc behavior, but use a rate less + * than (1+sqrt(5))/2 to accomodate malloc + * overhead. asprintf EXPECTS us to overallocate, so + * that it can add a trailing \0 without + * reallocating. The new allocation should thus be + * max(prev_size*1.5, curpos+len+1). */ + int newsize = fp->_bf._size * 3 / 2; + if (newsize < curpos + len + 1) + newsize = curpos + len + 1; + if (fp->_flags & __SOPT) + { + /* asnprintf leaves original buffer alone. */ + str = (unsigned char *)_malloc_r (ptr, newsize); + if (!str) + { + ptr->_errno = ENOMEM; + goto err; + } + memcpy (str, fp->_bf._base, curpos); + fp->_flags = (fp->_flags & ~__SOPT) | __SMBF; + } + else + { + str = (unsigned char *)_realloc_r (ptr, fp->_bf._base, newsize); + if (!str) + { + /* Free unneeded buffer. */ + _free_r (ptr, fp->_bf._base); + /* Ensure correct errno, even if free changed it. */ + ptr->_errno = ENOMEM; + goto err; + } + } + fp->_bf._base = str; + fp->_p = str + curpos; + fp->_bf._size = newsize; + w = len; + fp->_w = newsize - curpos; + } + if (len < w) + w = len; + + (void)memmove ((void *) fp->_p, (void *) buf, (size_t) (w)); + fp->_w -= w; + fp->_p += w; + return 0; + +err: + fp->_flags |= __SERR; + return EOF; +} +/* __ssprint_r is the original implementation of __SPRINT. In nano + version formatted IO it is reimplemented as __ssputs_r for non-wide + char output, but __ssprint_r cannot be discarded because it is used + by a serial of functions like svfwprintf for wide char output. */ +int +__ssprint_r (struct _reent *ptr, + FILE *fp, + register struct __suio *uio) +{ + register size_t len; + register int w; + register struct __siov *iov; + register const char *p = NULL; + + iov = uio->uio_iov; + len = 0; + + if (uio->uio_resid == 0) + { + uio->uio_iovcnt = 0; + return (0); + } + + do + { + while (len == 0) + { + p = iov->iov_base; + len = iov->iov_len; + iov++; + } + w = fp->_w; + if (len >= w && fp->_flags & (__SMBF | __SOPT)) + { + /* Must be asprintf family. */ + unsigned char *str; + int curpos = (fp->_p - fp->_bf._base); + /* Choose a geometric growth factor to avoid + * quadratic realloc behavior, but use a rate less + * than (1+sqrt(5))/2 to accomodate malloc + * overhead. asprintf EXPECTS us to overallocate, so + * that it can add a trailing \0 without + * reallocating. The new allocation should thus be + * max(prev_size*1.5, curpos+len+1). */ + int newsize = fp->_bf._size * 3 / 2; + if (newsize < curpos + len + 1) + newsize = curpos + len + 1; + + if (fp->_flags & __SOPT) + { + /* asnprintf leaves original buffer alone. */ + str = (unsigned char *)_malloc_r (ptr, newsize); + if (!str) + { + ptr->_errno = ENOMEM; + goto err; + } + memcpy (str, fp->_bf._base, curpos); + fp->_flags = (fp->_flags & ~__SOPT) | __SMBF; + } + else + { + str = (unsigned char *)_realloc_r (ptr, fp->_bf._base, + newsize); + if (!str) + { + /* Free unneeded buffer. */ + _free_r (ptr, fp->_bf._base); + /* Ensure correct errno, even if free changed it. */ + ptr->_errno = ENOMEM; + goto err; + } + } + fp->_bf._base = str; + fp->_p = str + curpos; + fp->_bf._size = newsize; + w = len; + fp->_w = newsize - curpos; + } + if (len < w) + w = len; + + (void)memmove ((void *) fp->_p, (void *) p, (size_t) (w)); + fp->_w -= w; + fp->_p += w; + /* Pretend we copied all. */ + w = len; + p += w; + len -= w; + } + while ((uio->uio_resid -= w) != 0); + + uio->uio_resid = 0; + uio->uio_iovcnt = 0; + return 0; + +err: + fp->_flags |= __SERR; + uio->uio_resid = 0; + uio->uio_iovcnt = 0; + return EOF; +} +#else +/* As __ssputs_r, __sprint_r is used by output functions for wide char, + like vfwprint. */ +/* Flush out all the vectors defined by the given uio, + then reset it so that it can be reused. */ +int +__sprint_r (struct _reent *ptr, + FILE *fp, + register struct __suio *uio) +{ + register int err = 0; + + if (uio->uio_resid == 0) + { + uio->uio_iovcnt = 0; + return 0; + } +#ifdef _WIDE_ORIENT + if (fp->_flags2 & __SWID) + { + struct __siov *iov; + wchar_t *p; + int i, len; + + iov = uio->uio_iov; + for (; uio->uio_resid != 0; + uio->uio_resid -= len * sizeof (wchar_t), iov++) + { + p = (wchar_t *) iov->iov_base; + len = iov->iov_len / sizeof (wchar_t); + for (i = 0; i < len; i++) + { + if (_fputwc_r (ptr, p[i], fp) == WEOF) + { + err = -1; + goto out; + } + } + } + } + else +#endif + err = __sfvwrite_r(ptr, fp, uio); +out: + uio->uio_resid = 0; + uio->uio_iovcnt = 0; + return err; +} + +_NOINLINE_STATIC int +__sfputc_r (struct _reent *ptr, + int c, + FILE *fp) +{ + if (--fp->_w >= 0 || (fp->_w >= fp->_lbfsize && (char)c != '\n')) + return (*fp->_p++ = c); + else + return (__swbuf_r(ptr, c, fp)); +} + +int +__sfputs_r (struct _reent *ptr, + FILE *fp, + const char *buf, + size_t len) +{ + register int i; + +#ifdef _WIDE_ORIENT + if (fp->_flags2 & __SWID) + { + wchar_t *p; + + p = (wchar_t *) buf; + for (i = 0; i < (len / sizeof (wchar_t)); i++) + { + if (_fputwc_r (ptr, p[i], fp) == WEOF) + return -1; + } + } + else +#endif + { + for (i = 0; i < len; i++) + { + /* Call __sfputc_r to skip _fputc_r. */ + if (__sfputc_r (ptr, (int)buf[i], fp) == EOF) + return -1; + } + } + return (0); +} +#endif /* STRING_ONLY. */ + +int _VFPRINTF_R (struct _reent *, FILE *, const char *, va_list); + +#ifndef STRING_ONLY +int +VFPRINTF (FILE * fp, + const char *fmt0, + va_list ap) +{ + int result; + result = _VFPRINTF_R (_REENT, fp, fmt0, ap); + return result; +} + +int +vfiprintf (FILE *, const char *, __VALIST) + _ATTRIBUTE ((__alias__("vfprintf"))); +#endif + +#ifdef STRING_ONLY +# define __SPRINT __ssputs_r +#else +# define __SPRINT __sfputs_r +#endif + +/* Do not need FLUSH for all sprintf functions. */ +#ifdef STRING_ONLY +# define FLUSH() +#else +# define FLUSH() +#endif + +int +_VFPRINTF_R (struct _reent *data, + FILE * fp, + const char *fmt0, + va_list ap) +{ + register char *fmt; /* Format string. */ + register int n, m; /* Handy integers (short term usage). */ + register char *cp; /* Handy char pointer (short term usage). */ + const char *flag_chars; + struct _prt_data_t prt_data; /* All data for decoding format string. */ + va_list ap_copy; + + /* Output function pointer. */ + int (*pfunc)(struct _reent *, FILE *, const char *, size_t len); + + pfunc = __SPRINT; + +#ifndef STRING_ONLY + /* Initialize std streams if not dealing with sprintf family. */ + CHECK_INIT (data, fp); + _newlib_flockfile_start (fp); + + /* Sorry, fprintf(read_only_file, "") returns EOF, not 0. */ + if (cantwrite (data, fp)) + { + _newlib_flockfile_exit (fp); + return (EOF); + } + +#else + /* Create initial buffer if we are called by asprintf family. */ + if (fp->_flags & __SMBF && !fp->_bf._base) + { + fp->_bf._base = fp->_p = _malloc_r (data, 64); + if (!fp->_p) + { + data->_errno = ENOMEM; + return EOF; + } + fp->_bf._size = 64; + } +#endif + + fmt = (char *)fmt0; + prt_data.ret = 0; + prt_data.blank = ' '; + prt_data.zero = '0'; + + /* GCC PR 14577 at https://gcc.gnu.org/bugzilla/show_bug.cgi?id=14557 */ + va_copy (ap_copy, ap); + + /* Scan the format for conversions (`%' character). */ + for (;;) + { + cp = fmt; + while (*fmt != '\0' && *fmt != '%') + fmt += 1; + + if ((m = fmt - cp) != 0) + { + PRINT (cp, m); + prt_data.ret += m; + } + if (*fmt == '\0') + goto done; + + fmt++; /* Skip over '%'. */ + + prt_data.flags = 0; + prt_data.width = 0; + prt_data.prec = -1; + prt_data.dprec = 0; + prt_data.l_buf[0] = '\0'; +#ifdef FLOATING_POINT + prt_data.lead = 0; +#endif + /* The flags. */ + /* + * ``Note that 0 is taken as a flag, not as the + * beginning of a field width.'' + * -- ANSI X3J11 + */ + flag_chars = "#-0+ "; + for (; cp = memchr (flag_chars, *fmt, 5); fmt++) + prt_data.flags |= (1 << (cp - flag_chars)); + + if (prt_data.flags & SPACESGN) + prt_data.l_buf[0] = ' '; + + /* + * ``If the space and + flags both appear, the space + * flag will be ignored.'' + * -- ANSI X3J11 + */ + if (prt_data.flags & PLUSSGN) + prt_data.l_buf[0] = '+'; + + /* The width. */ + if (*fmt == '*') + { + /* + * ``A negative field width argument is taken as a + * - flag followed by a positive field width.'' + * -- ANSI X3J11 + * They don't exclude field widths read from args. + */ + prt_data.width = GET_ARG (n, ap_copy, int); + if (prt_data.width < 0) + { + prt_data.width = -prt_data.width; + prt_data.flags |= LADJUST; + } + fmt++; + } + else + { + for (; is_digit (*fmt); fmt++) + prt_data.width = 10 * prt_data.width + to_digit (*fmt); + } + + /* The precision. */ + if (*fmt == '.') + { + fmt++; + if (*fmt == '*') + { + fmt++; + prt_data.prec = GET_ARG (n, ap_copy, int); + if (prt_data.prec < 0) + prt_data.prec = -1; + } + else + { + prt_data.prec = 0; + for (; is_digit (*fmt); fmt++) + prt_data.prec = 10 * prt_data.prec + to_digit (*fmt); + } + } + + /* The length modifiers. */ + flag_chars = "hlL"; + if ((cp = memchr (flag_chars, *fmt, 3)) != NULL) + { + prt_data.flags |= (SHORTINT << (cp - flag_chars)); + fmt++; + } + + /* The conversion specifiers. */ + prt_data.code = *fmt++; + cp = memchr ("efgEFG", prt_data.code, 6); +#ifdef FLOATING_POINT + /* If cp is not NULL, we are facing FLOATING POINT NUMBER. */ + if (cp) + { + /* Consume floating point argument if _printf_float is not + linked. */ + if (_printf_float == NULL) + { + if (prt_data.flags & LONGDBL) + GET_ARG (N, ap_copy, _LONG_DOUBLE); + else + GET_ARG (N, ap_copy, double); + } + else + n = _printf_float (data, &prt_data, fp, pfunc, &ap_copy); + } + else +#endif + n = _printf_i (data, &prt_data, fp, pfunc, &ap_copy); + + if (n == -1) + goto error; + + prt_data.ret += n; + } +done: + FLUSH (); +error: +#ifndef STRING_ONLY + _newlib_flockfile_end (fp); +#endif + va_end (ap_copy); + return (__sferror (fp) ? EOF : prt_data.ret); +} + +#ifdef STRING_ONLY +int +_svfiprintf_r (struct _reent *, FILE *, const char *, __VALIST) + _ATTRIBUTE ((__alias__("_svfprintf_r"))); +#else +int +_vfiprintf_r (struct _reent *, FILE *, const char *, __VALIST) + _ATTRIBUTE ((__alias__("_vfprintf_r"))); +#endif From 1e6c561d48ff8bc34683f763f168ee244af53c88 Mon Sep 17 00:00:00 2001 From: Jozef Lawrynowicz Date: Fri, 12 Apr 2019 12:08:22 +0100 Subject: [PATCH 338/475] Implement reduced code size "tiny" printf and puts "tiny" printf is derived from _vfprintf_r in libc/stdio/nano-vfprintf.c. "tiny" puts has been implemented so that it just calls write, without any other processing. Support for buffering, reentrancy and streams has been removed from these functions to achieve reduced code size. This reduced code size implementation of printf and puts can be enabled in an application by passing "--wrap printf" and "--wrap puts" to the GNU linker. This will replace references to "printf" and "puts" in user code with "__wrap_printf" and "__wrap_puts" respectively. If there is no implementation of these __wrap* functions in user code, these "tiny" printf and puts implementations will be linked into the final executable. The wrapping mechanism is supposed to be invisible to the user: - A GCC wrapper option such as "-mtiny-printf" will be added to alias these wrap commands. - If the user is unaware of the "tiny" implementation, and chooses to implement their own __wrap_printf and __wrap_puts, their own implementation will be automatically chosen over the "tiny" printf and puts from the library. Newlib must be configured with --enable-newlib-nano-formatted-io for the "tiny" printf and puts functions to be built into the library. Code size reduction examples: printf("Hello World\n") baseline - msp430-elf-gcc gcc-8_3_0-release text data bss 5638 214 26 "tiny" puts enabled text data bss 714 90 20 printf("Hello %d\n", a) baseline - msp430-elf-gcc gcc-8_3_0-release text data bss 10916 614 28 "tiny" printf enabled text data bss 4632 280 20 --- newlib/libc/machine/msp430/Makefile.am | 9 +- newlib/libc/machine/msp430/Makefile.in | 33 +- newlib/libc/machine/msp430/configure | 28 ++ newlib/libc/machine/msp430/configure.in | 11 + newlib/libc/machine/msp430/tiny-printf.c | 457 ++--------------------- newlib/libc/machine/msp430/tiny-puts.c | 20 + 6 files changed, 131 insertions(+), 427 deletions(-) create mode 100644 newlib/libc/machine/msp430/tiny-puts.c diff --git a/newlib/libc/machine/msp430/Makefile.am b/newlib/libc/machine/msp430/Makefile.am index 0b5791448..fd327f5c8 100644 --- a/newlib/libc/machine/msp430/Makefile.am +++ b/newlib/libc/machine/msp430/Makefile.am @@ -21,9 +21,16 @@ AM_CCASFLAGS = $(INCLUDES) noinst_LIBRARIES = lib.a -lib_a_SOURCES = setjmp.S +lib_a_SOURCES = setjmp.S $(TINY_SOURCES) lib_a_CCASFLAGS=$(AM_CCASFLAGS) lib_a_CFLAGS=$(AM_CFLAGS) +# tiny-printf.c and tiny-puts.c are derived from the nano printf/puts +# functions, so other supporting nano functions are required, and the tiny +# printf/puts will not work without them. +if NEWLIB_NANO_FORMATTED_IO +TINY_SOURCES = tiny-puts.c tiny-printf.c +endif + ACLOCAL_AMFLAGS = -I ../../.. -I ../../../.. CONFIG_STATUS_DEPENDENCIES = $(newlib_basedir)/configure.host diff --git a/newlib/libc/machine/msp430/Makefile.in b/newlib/libc/machine/msp430/Makefile.in index 89b36a8e4..6f837c91f 100644 --- a/newlib/libc/machine/msp430/Makefile.in +++ b/newlib/libc/machine/msp430/Makefile.in @@ -82,7 +82,10 @@ LIBRARIES = $(noinst_LIBRARIES) ARFLAGS = cru lib_a_AR = $(AR) $(ARFLAGS) lib_a_LIBADD = -am_lib_a_OBJECTS = lib_a-setjmp.$(OBJEXT) +@NEWLIB_NANO_FORMATTED_IO_TRUE@am__objects_1 = \ +@NEWLIB_NANO_FORMATTED_IO_TRUE@ lib_a-tiny-puts.$(OBJEXT) \ +@NEWLIB_NANO_FORMATTED_IO_TRUE@ lib_a-tiny-printf.$(OBJEXT) +am_lib_a_OBJECTS = lib_a-setjmp.$(OBJEXT) $(am__objects_1) lib_a_OBJECTS = $(am_lib_a_OBJECTS) DEFAULT_INCLUDES = -I.@am__isrc@ depcomp = @@ -195,6 +198,7 @@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ +runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ @@ -208,15 +212,20 @@ AUTOMAKE_OPTIONS = cygnus INCLUDES = $(NEWLIB_CFLAGS) $(CROSS_CFLAGS) $(TARGET_CFLAGS) AM_CCASFLAGS = $(INCLUDES) noinst_LIBRARIES = lib.a -lib_a_SOURCES = setjmp.S +lib_a_SOURCES = setjmp.S $(TINY_SOURCES) lib_a_CCASFLAGS = $(AM_CCASFLAGS) lib_a_CFLAGS = $(AM_CFLAGS) + +# tiny-printf.c and tiny-puts.c are derived from the nano printf/puts +# functions, so other supporting nano functions are required, and the tiny +# printf/puts will not work without them. +@NEWLIB_NANO_FORMATTED_IO_TRUE@TINY_SOURCES = tiny-puts.c tiny-printf.c ACLOCAL_AMFLAGS = -I ../../.. -I ../../../.. CONFIG_STATUS_DEPENDENCIES = $(newlib_basedir)/configure.host all: all-am .SUFFIXES: -.SUFFIXES: .S .o .obj +.SUFFIXES: .S .c .o .obj am--refresh: Makefile @: $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @@ -277,6 +286,24 @@ lib_a-setjmp.o: setjmp.S lib_a-setjmp.obj: setjmp.S $(CCAS) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CCASFLAGS) $(CCASFLAGS) -c -o lib_a-setjmp.obj `if test -f 'setjmp.S'; then $(CYGPATH_W) 'setjmp.S'; else $(CYGPATH_W) '$(srcdir)/setjmp.S'; fi` +.c.o: + $(COMPILE) -c $< + +.c.obj: + $(COMPILE) -c `$(CYGPATH_W) '$<'` + +lib_a-tiny-puts.o: tiny-puts.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-tiny-puts.o `test -f 'tiny-puts.c' || echo '$(srcdir)/'`tiny-puts.c + +lib_a-tiny-puts.obj: tiny-puts.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-tiny-puts.obj `if test -f 'tiny-puts.c'; then $(CYGPATH_W) 'tiny-puts.c'; else $(CYGPATH_W) '$(srcdir)/tiny-puts.c'; fi` + +lib_a-tiny-printf.o: tiny-printf.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-tiny-printf.o `test -f 'tiny-printf.c' || echo '$(srcdir)/'`tiny-printf.c + +lib_a-tiny-printf.obj: tiny-printf.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-tiny-printf.obj `if test -f 'tiny-printf.c'; then $(CYGPATH_W) 'tiny-printf.c'; else $(CYGPATH_W) '$(srcdir)/tiny-printf.c'; fi` + ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ diff --git a/newlib/libc/machine/msp430/configure b/newlib/libc/machine/msp430/configure index 35078c605..9d5cd33a6 100755 --- a/newlib/libc/machine/msp430/configure +++ b/newlib/libc/machine/msp430/configure @@ -640,6 +640,8 @@ build newlib_basedir MAY_SUPPLY_SYSCALLS_FALSE MAY_SUPPLY_SYSCALLS_TRUE +NEWLIB_NANO_FORMATTED_IO_FALSE +NEWLIB_NANO_FORMATTED_IO_TRUE target_alias host_alias build_alias @@ -681,6 +683,7 @@ SHELL' ac_subst_files='' ac_user_opts=' enable_option_checking +enable_newlib_nano_formatted_io enable_multilib enable_target_optspace enable_malloc_debugging @@ -1318,6 +1321,7 @@ Optional Features: --disable-option-checking ignore unrecognized --enable/--with options --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --enable-newlib-nano-formatted-io Use small-footprint nano-formatted-IO implementation --enable-multilib build many library versions (default) --enable-target-optspace optimize for space --enable-malloc-debugging indicate malloc debugging requested @@ -1837,6 +1841,26 @@ ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. +# Check whether --enable-newlib_nano_formatted_io was given. +if test "${enable_newlib_nano_formatted_io+set}" = set; then : + enableval=$enable_newlib_nano_formatted_io; case "${enableval}" in + yes) newlib_nano_formatted_io=yes ;; + no) newlib_nano_formatted_io=no ;; + *) as_fn_error $? "bad value ${enableval} for newlib-nano-formatted-io" "$LINENO" 5 ;; + esac +else + newlib_nano_formatted_io=no +fi + + if test x$newlib_nano_formatted_io = xyes; then + NEWLIB_NANO_FORMATTED_IO_TRUE= + NEWLIB_NANO_FORMATTED_IO_FALSE='#' +else + NEWLIB_NANO_FORMATTED_IO_TRUE='#' + NEWLIB_NANO_FORMATTED_IO_FALSE= +fi + + # Make sure we can run config.sub. $SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || @@ -3575,6 +3599,10 @@ LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs +if test -z "${NEWLIB_NANO_FORMATTED_IO_TRUE}" && test -z "${NEWLIB_NANO_FORMATTED_IO_FALSE}"; then + as_fn_error $? "conditional \"NEWLIB_NANO_FORMATTED_IO\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi if test -z "${MAY_SUPPLY_SYSCALLS_TRUE}" && test -z "${MAY_SUPPLY_SYSCALLS_FALSE}"; then as_fn_error $? "conditional \"MAY_SUPPLY_SYSCALLS\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 diff --git a/newlib/libc/machine/msp430/configure.in b/newlib/libc/machine/msp430/configure.in index 563f8a30d..4c0f864b0 100644 --- a/newlib/libc/machine/msp430/configure.in +++ b/newlib/libc/machine/msp430/configure.in @@ -21,6 +21,17 @@ AC_CONFIG_SRCDIR([setjmp.S]) dnl Can't be done in NEWLIB_CONFIGURE because that confuses automake. AC_CONFIG_AUX_DIR(../../../..) +dnl Support --enable-newlib-nano-formatted-io required by tiny-printf.c +dnl and tiny-puts.c +AC_ARG_ENABLE(newlib_nano_formatted_io, +[ --enable-newlib-nano-formatted-io Use small-footprint nano-formatted-IO implementation], +[case "${enableval}" in + yes) newlib_nano_formatted_io=yes ;; + no) newlib_nano_formatted_io=no ;; + *) AC_MSG_ERROR(bad value ${enableval} for newlib-nano-formatted-io) ;; + esac],[newlib_nano_formatted_io=no]) +AM_CONDITIONAL(NEWLIB_NANO_FORMATTED_IO, test x$newlib_nano_formatted_io = xyes) + NEWLIB_CONFIGURE(../../..) AC_CONFIG_FILES([Makefile]) diff --git a/newlib/libc/machine/msp430/tiny-printf.c b/newlib/libc/machine/msp430/tiny-printf.c index bc7ed0743..f2412a0e6 100644 --- a/newlib/libc/machine/msp430/tiny-printf.c +++ b/newlib/libc/machine/msp430/tiny-printf.c @@ -58,100 +58,11 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/* -FUNCTION -<>, <>, <>, <>, <>, <>---format argument list - -INDEX - vfprintf -INDEX - _vfprintf_r -INDEX - vprintf -INDEX - _vprintf_r -INDEX - vsprintf -INDEX - _vsprintf_r -INDEX - vsnprintf -INDEX - _vsnprintf_r -INDEX - vasprintf -INDEX - _vasprintf_r -INDEX - vasnprintf -INDEX - _vasnprintf_r - -SYNOPSIS - #include - #include - int vprintf(const char *<[fmt]>, va_list <[list]>); - int vfprintf(FILE *<[fp]>, const char *<[fmt]>, va_list <[list]>); - int vsprintf(char *<[str]>, const char *<[fmt]>, va_list <[list]>); - int vsnprintf(char *<[str]>, size_t <[size]>, const char *<[fmt]>, - va_list <[list]>); - int vasprintf(char **<[strp]>, const char *<[fmt]>, va_list <[list]>); - char *vasnprintf(char *<[str]>, size_t *<[size]>, const char *<[fmt]>, - va_list <[list]>); - - int _vprintf_r(struct _reent *<[reent]>, const char *<[fmt]>, - va_list <[list]>); - int _vfprintf_r(struct _reent *<[reent]>, FILE *<[fp]>, - const char *<[fmt]>, va_list <[list]>); - int _vsprintf_r(struct _reent *<[reent]>, char *<[str]>, - const char *<[fmt]>, va_list <[list]>); - int _vasprintf_r(struct _reent *<[reent]>, char **<[str]>, - const char *<[fmt]>, va_list <[list]>); - int _vsnprintf_r(struct _reent *<[reent]>, char *<[str]>, - size_t <[size]>, const char *<[fmt]>, va_list <[list]>); - char *_vasnprintf_r(struct _reent *<[reent]>, char *<[str]>, - size_t *<[size]>, const char *<[fmt]>, va_list <[list]>); - -DESCRIPTION -<>, <>, <>, <>, <>, -and <> are (respectively) variants of <>, -<>, <>, <>, <>, and -<>. They differ only in allowing their caller to pass the -variable argument list as a <> object (initialized by -<>) rather than directly accepting a variable number of -arguments. The caller is responsible for calling <>. - -<<_vprintf_r>>, <<_vfprintf_r>>, <<_vasprintf_r>>, <<_vsprintf_r>>, -<<_vsnprintf_r>>, and <<_vasnprintf_r>> are reentrant versions of the -above. - -RETURNS -The return values are consistent with the corresponding functions. - -PORTABILITY -ANSI C requires <>, <>, <>, and -<>. The remaining functions are newlib extensions. - -Supporting OS subroutines required: <>, <>, <>, -<>, <>, <>, <>. -*/ - #if defined(LIBC_SCCS) && !defined(lint) /*static char *sccsid = "from: @(#)vfprintf.c 5.50 (Berkeley) 12/16/92";*/ static char *rcsid = "$Id$"; #endif /* LIBC_SCCS and not lint */ -/* Actual printf innards. - This code is large and complicated... */ -#include - -#define VFPRINTF vfprintf -#ifdef STRING_ONLY -# define _VFPRINTF_R _svfprintf_r -#else -# define _VFPRINTF_R _vfprintf_r -#endif - #include <_ansi.h> #include #include @@ -162,310 +73,35 @@ static char *rcsid = "$Id$"; #include #include #include -#include "local.h" -#include "../stdlib/local.h" -#include "fvwrite.h" -#include "vfieeefp.h" -#include "nano-vfprintf_local.h" +#include +#include +#include "../../stdio/local.h" +#include "../../stdlib/local.h" +#include "../../stdio/fvwrite.h" +#include "../../stdio/nano-vfprintf_local.h" -/* The __ssputs_r function is shared between all versions of vfprintf - and vfwprintf. */ -#ifdef STRING_ONLY +/* Bypass *putc* fns called by the default _sfputs_r to save code size. + Among other things, this means there is no buffering of the string before + it is sent to <>, but <> does its own buffering so we won't + lose chars when buf is larger than sizeof(CIOBUF). */ int -__ssputs_r (struct _reent *ptr, +__tiny__sfputs_r (struct _reent *ptr, FILE *fp, const char *buf, size_t len) { - register int w; - - w = fp->_w; - if (len >= w && fp->_flags & (__SMBF | __SOPT)) - { - /* Must be asprintf family. */ - unsigned char *str; - int curpos = (fp->_p - fp->_bf._base); - /* Choose a geometric growth factor to avoid - * quadratic realloc behavior, but use a rate less - * than (1+sqrt(5))/2 to accomodate malloc - * overhead. asprintf EXPECTS us to overallocate, so - * that it can add a trailing \0 without - * reallocating. The new allocation should thus be - * max(prev_size*1.5, curpos+len+1). */ - int newsize = fp->_bf._size * 3 / 2; - if (newsize < curpos + len + 1) - newsize = curpos + len + 1; - if (fp->_flags & __SOPT) - { - /* asnprintf leaves original buffer alone. */ - str = (unsigned char *)_malloc_r (ptr, newsize); - if (!str) - { - ptr->_errno = ENOMEM; - goto err; - } - memcpy (str, fp->_bf._base, curpos); - fp->_flags = (fp->_flags & ~__SOPT) | __SMBF; - } - else - { - str = (unsigned char *)_realloc_r (ptr, fp->_bf._base, newsize); - if (!str) - { - /* Free unneeded buffer. */ - _free_r (ptr, fp->_bf._base); - /* Ensure correct errno, even if free changed it. */ - ptr->_errno = ENOMEM; - goto err; - } - } - fp->_bf._base = str; - fp->_p = str + curpos; - fp->_bf._size = newsize; - w = len; - fp->_w = newsize - curpos; - } - if (len < w) - w = len; - - (void)memmove ((void *) fp->_p, (void *) buf, (size_t) (w)); - fp->_w -= w; - fp->_p += w; - return 0; - -err: - fp->_flags |= __SERR; - return EOF; -} -/* __ssprint_r is the original implementation of __SPRINT. In nano - version formatted IO it is reimplemented as __ssputs_r for non-wide - char output, but __ssprint_r cannot be discarded because it is used - by a serial of functions like svfwprintf for wide char output. */ -int -__ssprint_r (struct _reent *ptr, - FILE *fp, - register struct __suio *uio) -{ - register size_t len; - register int w; - register struct __siov *iov; - register const char *p = NULL; - - iov = uio->uio_iov; - len = 0; - - if (uio->uio_resid == 0) - { - uio->uio_iovcnt = 0; - return (0); - } - - do - { - while (len == 0) - { - p = iov->iov_base; - len = iov->iov_len; - iov++; - } - w = fp->_w; - if (len >= w && fp->_flags & (__SMBF | __SOPT)) - { - /* Must be asprintf family. */ - unsigned char *str; - int curpos = (fp->_p - fp->_bf._base); - /* Choose a geometric growth factor to avoid - * quadratic realloc behavior, but use a rate less - * than (1+sqrt(5))/2 to accomodate malloc - * overhead. asprintf EXPECTS us to overallocate, so - * that it can add a trailing \0 without - * reallocating. The new allocation should thus be - * max(prev_size*1.5, curpos+len+1). */ - int newsize = fp->_bf._size * 3 / 2; - if (newsize < curpos + len + 1) - newsize = curpos + len + 1; - - if (fp->_flags & __SOPT) - { - /* asnprintf leaves original buffer alone. */ - str = (unsigned char *)_malloc_r (ptr, newsize); - if (!str) - { - ptr->_errno = ENOMEM; - goto err; - } - memcpy (str, fp->_bf._base, curpos); - fp->_flags = (fp->_flags & ~__SOPT) | __SMBF; - } - else - { - str = (unsigned char *)_realloc_r (ptr, fp->_bf._base, - newsize); - if (!str) - { - /* Free unneeded buffer. */ - _free_r (ptr, fp->_bf._base); - /* Ensure correct errno, even if free changed it. */ - ptr->_errno = ENOMEM; - goto err; - } - } - fp->_bf._base = str; - fp->_p = str + curpos; - fp->_bf._size = newsize; - w = len; - fp->_w = newsize - curpos; - } - if (len < w) - w = len; - - (void)memmove ((void *) fp->_p, (void *) p, (size_t) (w)); - fp->_w -= w; - fp->_p += w; - /* Pretend we copied all. */ - w = len; - p += w; - len -= w; - } - while ((uio->uio_resid -= w) != 0); - - uio->uio_resid = 0; - uio->uio_iovcnt = 0; - return 0; - -err: - fp->_flags |= __SERR; - uio->uio_resid = 0; - uio->uio_iovcnt = 0; - return EOF; -} -#else -/* As __ssputs_r, __sprint_r is used by output functions for wide char, - like vfwprint. */ -/* Flush out all the vectors defined by the given uio, - then reset it so that it can be reused. */ -int -__sprint_r (struct _reent *ptr, - FILE *fp, - register struct __suio *uio) -{ - register int err = 0; - - if (uio->uio_resid == 0) - { - uio->uio_iovcnt = 0; - return 0; - } -#ifdef _WIDE_ORIENT - if (fp->_flags2 & __SWID) - { - struct __siov *iov; - wchar_t *p; - int i, len; - - iov = uio->uio_iov; - for (; uio->uio_resid != 0; - uio->uio_resid -= len * sizeof (wchar_t), iov++) - { - p = (wchar_t *) iov->iov_base; - len = iov->iov_len / sizeof (wchar_t); - for (i = 0; i < len; i++) - { - if (_fputwc_r (ptr, p[i], fp) == WEOF) - { - err = -1; - goto out; - } - } - } - } - else -#endif - err = __sfvwrite_r(ptr, fp, uio); -out: - uio->uio_resid = 0; - uio->uio_iovcnt = 0; - return err; -} - -_NOINLINE_STATIC int -__sfputc_r (struct _reent *ptr, - int c, - FILE *fp) -{ - if (--fp->_w >= 0 || (fp->_w >= fp->_lbfsize && (char)c != '\n')) - return (*fp->_p++ = c); - else - return (__swbuf_r(ptr, c, fp)); + return write (1, buf, len); } +/* VFPRINTF_R from nano-vfprintf.c but: + - No support for reentrancy + - No support for streams + - __SINGLE_THREAD__ assumed. + - No STRING_ONLY variant (either way the formatted string would end up + being sent to <> via <<__tiny__sfputs_r>>. + Basically, format the string as normal, and send it to write. */ int -__sfputs_r (struct _reent *ptr, - FILE *fp, - const char *buf, - size_t len) -{ - register int i; - -#ifdef _WIDE_ORIENT - if (fp->_flags2 & __SWID) - { - wchar_t *p; - - p = (wchar_t *) buf; - for (i = 0; i < (len / sizeof (wchar_t)); i++) - { - if (_fputwc_r (ptr, p[i], fp) == WEOF) - return -1; - } - } - else -#endif - { - for (i = 0; i < len; i++) - { - /* Call __sfputc_r to skip _fputc_r. */ - if (__sfputc_r (ptr, (int)buf[i], fp) == EOF) - return -1; - } - } - return (0); -} -#endif /* STRING_ONLY. */ - -int _VFPRINTF_R (struct _reent *, FILE *, const char *, va_list); - -#ifndef STRING_ONLY -int -VFPRINTF (FILE * fp, - const char *fmt0, - va_list ap) -{ - int result; - result = _VFPRINTF_R (_REENT, fp, fmt0, ap); - return result; -} - -int -vfiprintf (FILE *, const char *, __VALIST) - _ATTRIBUTE ((__alias__("vfprintf"))); -#endif - -#ifdef STRING_ONLY -# define __SPRINT __ssputs_r -#else -# define __SPRINT __sfputs_r -#endif - -/* Do not need FLUSH for all sprintf functions. */ -#ifdef STRING_ONLY -# define FLUSH() -#else -# define FLUSH() -#endif - -int -_VFPRINTF_R (struct _reent *data, +__tiny_vfprintf_r (struct _reent *data, FILE * fp, const char *fmt0, va_list ap) @@ -480,33 +116,7 @@ _VFPRINTF_R (struct _reent *data, /* Output function pointer. */ int (*pfunc)(struct _reent *, FILE *, const char *, size_t len); - pfunc = __SPRINT; - -#ifndef STRING_ONLY - /* Initialize std streams if not dealing with sprintf family. */ - CHECK_INIT (data, fp); - _newlib_flockfile_start (fp); - - /* Sorry, fprintf(read_only_file, "") returns EOF, not 0. */ - if (cantwrite (data, fp)) - { - _newlib_flockfile_exit (fp); - return (EOF); - } - -#else - /* Create initial buffer if we are called by asprintf family. */ - if (fp->_flags & __SMBF && !fp->_bf._base) - { - fp->_bf._base = fp->_p = _malloc_r (data, 64); - if (!fp->_p) - { - data->_errno = ENOMEM; - return EOF; - } - fp->_bf._size = 64; - } -#endif + pfunc = __tiny__sfputs_r; fmt = (char *)fmt0; prt_data.ret = 0; @@ -641,21 +251,22 @@ _VFPRINTF_R (struct _reent *data, prt_data.ret += n; } done: - FLUSH (); error: -#ifndef STRING_ONLY - _newlib_flockfile_end (fp); -#endif va_end (ap_copy); return (__sferror (fp) ? EOF : prt_data.ret); } -#ifdef STRING_ONLY int -_svfiprintf_r (struct _reent *, FILE *, const char *, __VALIST) - _ATTRIBUTE ((__alias__("_svfprintf_r"))); -#else -int -_vfiprintf_r (struct _reent *, FILE *, const char *, __VALIST) - _ATTRIBUTE ((__alias__("_vfprintf_r"))); -#endif +__wrap_printf (const char *__restrict fmt, ...) +{ + int ret; + va_list ap; + struct _reent *ptr = _REENT; + + va_start (ap, fmt); + ret = __tiny_vfprintf_r (ptr, _stdout_r (ptr), fmt, ap); + va_end (ap); + return ret; +} + +int printf (const char *__restrict fmt, ...) __attribute__ ((weak, alias ("__wrap_printf"))); diff --git a/newlib/libc/machine/msp430/tiny-puts.c b/newlib/libc/machine/msp430/tiny-puts.c new file mode 100644 index 000000000..6a59f23b0 --- /dev/null +++ b/newlib/libc/machine/msp430/tiny-puts.c @@ -0,0 +1,20 @@ +#include +#include +#include +#include + +int write (int fd, const char *buf, int len); + +int +__wrap_puts (const char * s) +{ + int res = write (1, s, strlen (s)); + if (res == EOF) + { + write (1, "\n", 1); + return EOF; + } + return write (1, "\n", 1); +} + +int puts (const char * s) __attribute__ ((weak, alias ("__wrap_puts"))); From b63843ed569c1e4b15f2b197733c334cee1c4454 Mon Sep 17 00:00:00 2001 From: Ken Brown Date: Sun, 14 Apr 2019 19:15:56 +0000 Subject: [PATCH 339/475] Cygwin: FIFO: rename client[] to fc_handler[] The word "client" suggests something that holds a handle to the client side of the pipe (in Windows terminology). But our fifo_client_handlers hold a handle the server side of the pipe, and they *connect* to clients. --- winsup/cygwin/fhandler.h | 20 +++---- winsup/cygwin/fhandler_fifo.cc | 96 +++++++++++++++++----------------- winsup/cygwin/select.cc | 2 +- 3 files changed, 59 insertions(+), 59 deletions(-) diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h index bc66377cd..2898db4df 100644 --- a/winsup/cygwin/fhandler.h +++ b/winsup/cygwin/fhandler.h @@ -1269,8 +1269,8 @@ class fhandler_fifo: public fhandler_base HANDLE lct_termination_evt; UNICODE_STRING pipe_name; WCHAR pipe_name_buf[CYGWIN_FIFO_PIPE_NAME_LEN + 1]; - fifo_client_handler client[MAX_CLIENTS]; - int nclients, nconnected; + fifo_client_handler fc_handler[MAX_CLIENTS]; + int nhandlers, nconnected; af_unix_spinlock_t _fifo_client_lock; bool _duplexer; bool __reg2 wait (HANDLE); @@ -1278,15 +1278,15 @@ class fhandler_fifo: public fhandler_base HANDLE create_pipe_instance (bool); NTSTATUS open_pipe (); int disconnect_and_reconnect (int); - int add_client (); + int add_client_handler (); bool listen_client (); public: fhandler_fifo (); bool hit_eof (); - int get_nclients () const { return nclients; } + int get_nhandlers () const { return nhandlers; } HANDLE& get_handle () { return fhandler_base::get_handle (); } - HANDLE get_handle (int i) const { return client[i].fh->get_handle (); } - bool is_connected (int i) const { return client[i].state == fc_connected; } + HANDLE get_handle (int i) const { return fc_handler[i].fh->get_handle (); } + bool is_connected (int i) const { return fc_handler[i].state == fc_connected; } PUNICODE_STRING get_pipe_name (); DWORD listen_client_thread (); void fifo_client_lock () { _fifo_client_lock.lock (); } @@ -1305,8 +1305,8 @@ public: void clear_readahead () { fhandler_base::clear_readahead (); - for (int i = 0; i < nclients; i++) - client[i].fh->clear_readahead (); + for (int i = 0; i < nhandlers; i++) + fc_handler[i].fh->clear_readahead (); } select_record *select_read (select_stuff *); select_record *select_write (select_stuff *); @@ -1326,8 +1326,8 @@ public: void *ptr = (void *) ccalloc (malloc_type, 1, sizeof (fhandler_fifo)); fhandler_fifo *fhf = new (ptr) fhandler_fifo (ptr); copyto (fhf); - for (int i = 0; i < nclients; i++) - fhf->client[i].fh = client[i].fh->clone (); + for (int i = 0; i < nhandlers; i++) + fhf->fc_handler[i].fh = fc_handler[i].fh->clone (); return fhf; } }; diff --git a/winsup/cygwin/fhandler_fifo.cc b/winsup/cygwin/fhandler_fifo.cc index 68b9e7717..901696444 100644 --- a/winsup/cygwin/fhandler_fifo.cc +++ b/winsup/cygwin/fhandler_fifo.cc @@ -32,7 +32,7 @@ STATUS_PIPE_EMPTY simply means there's no data to be read. */ fhandler_fifo::fhandler_fifo (): fhandler_base (), read_ready (NULL), write_ready (NULL), - listen_client_thr (NULL), lct_termination_evt (NULL), nclients (0), + listen_client_thr (NULL), lct_termination_evt (NULL), nhandlers (0), nconnected (0), _duplexer (false) { pipe_name_buf[0] = L'\0'; @@ -146,7 +146,7 @@ fhandler_fifo::disconnect_and_reconnect (int i) { NTSTATUS status; IO_STATUS_BLOCK io; - HANDLE ph = client[i].fh->get_handle (); + HANDLE ph = fc_handler[i].fh->get_handle (); status = NtFsControlFile (ph, NULL, NULL, NULL, &io, FSCTL_PIPE_DISCONNECT, NULL, 0, NULL, 0); @@ -159,10 +159,10 @@ fhandler_fifo::disconnect_and_reconnect (int i) __seterrno_from_nt_status (status); return -1; } - set_pipe_non_blocking (client[i].fh->get_handle (), false); - if (client[i].connect () < 0) + set_pipe_non_blocking (fc_handler[i].fh->get_handle (), false); + if (fc_handler[i].connect () < 0) return -1; - if (client[i].state == fc_connected) + if (fc_handler[i].state == fc_connected) nconnected++; return 0; } @@ -198,9 +198,9 @@ fhandler_fifo::npfs_handle (HANDLE &nph) } /* Called when a FIFO is first opened for reading and again each time - a new client is needed. Each pipe instance is created in blocking - mode so that we can easily wait for a connection. After it is - connected, it is put in nonblocking mode. */ + a new client handler is needed. Each pipe instance is created in + blocking mode so that we can easily wait for a connection. After + it is connected, it is put in nonblocking mode. */ HANDLE fhandler_fifo::create_pipe_instance (bool first) { @@ -271,13 +271,13 @@ fhandler_fifo::open_pipe () } int -fhandler_fifo::add_client () +fhandler_fifo::add_client_handler () { fifo_client_handler fc; fhandler_base *fh; - bool first = (nclients == 0); + bool first = (nhandlers == 0); - if (nclients == MAX_CLIENTS) + if (nhandlers == MAX_CLIENTS) { set_errno (EMFILE); return -1; @@ -302,7 +302,7 @@ fhandler_fifo::add_client () } if (fc.state == fc_connected) nconnected++; - client[nclients++] = fc; + fc_handler[nhandlers++] = fc; return 0; errout: delete fh; @@ -353,8 +353,8 @@ fhandler_fifo::listen_client_thread () fifo_client_lock (); found = false; - for (i = 0; i < nclients; i++) - switch (client[i].state) + for (i = 0; i < nhandlers; i++) + switch (fc_handler[i].state) { case fc_invalid: if (disconnect_and_reconnect (i) < 0) @@ -364,20 +364,20 @@ fhandler_fifo::listen_client_thread () } /* Fall through. */ case fc_connected: - w[i] = client[i].dummy_evt; + w[i] = fc_handler[i].dummy_evt; break; case fc_connecting: found = true; - w[i] = client[i].connect_evt; + w[i] = fc_handler[i].connect_evt; break; case fc_unknown: /* Shouldn't happen. */ default: break; } - w[nclients] = lct_termination_evt; + w[nhandlers] = lct_termination_evt; int res = 0; if (!found) - res = add_client (); + res = add_client_handler (); fifo_client_unlock (); if (res < 0) goto errout; @@ -391,18 +391,18 @@ fhandler_fifo::listen_client_thread () } /* Wait for a client to connect. */ - wait_ret = WaitForMultipleObjects (nclients + 1, w, false, INFINITE); + wait_ret = WaitForMultipleObjects (nhandlers + 1, w, false, INFINITE); i = wait_ret - WAIT_OBJECT_0; - if (i < 0 || i > nclients) + if (i < 0 || i > nhandlers) goto errout; - else if (i == nclients) /* Reader is closing. */ + else if (i == nhandlers) /* Reader is closing. */ return 0; else { fifo_client_lock (); - client[i].state = fc_connected; + fc_handler[i].state = fc_connected; nconnected++; - set_pipe_non_blocking (client[i].fh->get_handle (), true); + set_pipe_non_blocking (fc_handler[i].fh->get_handle (), true); fifo_client_unlock (); yield (); } @@ -474,7 +474,7 @@ fhandler_fifo::open (int flags, mode_t) goto out; } - /* If we're a duplexer, create the pipe and the first client. */ + /* If we're a duplexer, create the pipe and the first client handler. */ if (duplexer) { HANDLE ph, connect_evt, dummy_evt; @@ -511,9 +511,9 @@ fhandler_fifo::open (int flags, mode_t) CloseHandle (connect_evt); goto out; } - client[0] = fifo_client_handler (fh, fc_connected, connect_evt, + fc_handler[0] = fifo_client_handler (fh, fc_connected, connect_evt, dummy_evt); - nconnected = nclients = 1; + nconnected = nhandlers = 1; } /* If we're reading, start the listen_client thread (which should @@ -736,11 +736,11 @@ fhandler_fifo::raw_read (void *in_ptr, size_t& len) /* Poll the connected clients for input. */ fifo_client_lock (); - for (int i = 0; i < nclients; i++) - if (client[i].state == fc_connected) + for (int i = 0; i < nhandlers; i++) + if (fc_handler[i].state == fc_connected) { len = orig_len; - client[i].fh->fhandler_base::raw_read (in_ptr, len); + fc_handler[i].fh->fhandler_base::raw_read (in_ptr, len); ssize_t nread = (ssize_t) len; if (nread > 0) { @@ -749,7 +749,7 @@ fhandler_fifo::raw_read (void *in_ptr, size_t& len) } /* In the duplex case with no data, we seem to get nread == -1 with ERROR_PIPE_LISTENING on the first attempt to - read from the duplex pipe (client[0]), and nread == 0 + read from the duplex pipe (fc_handler[0]), and nread == 0 on subsequent attempts. */ else if (nread < 0) switch (GetLastError ()) @@ -767,7 +767,7 @@ fhandler_fifo::raw_read (void *in_ptr, size_t& len) else if (nread == 0 && (!_duplexer || i > 0)) /* Client has disconnected. */ { - client[i].state = fc_invalid; + fc_handler[i].state = fc_invalid; nconnected--; } } @@ -841,8 +841,8 @@ fhandler_fifo::close () CloseHandle (read_ready); if (write_ready) CloseHandle (write_ready); - for (int i = 0; i < nclients; i++) - if (client[i].close () < 0) + for (int i = 0; i < nhandlers; i++) + if (fc_handler[i].close () < 0) res = -1; return fhandler_base::close () || res; } @@ -873,19 +873,19 @@ fhandler_fifo::dup (fhandler_base *child, int flags) __seterrno (); return -1; } - for (int i = 0; i < nclients; i++) + for (int i = 0; i < nhandlers; i++) { - if (!DuplicateHandle (GetCurrentProcess (), client[i].fh->get_handle (), + if (!DuplicateHandle (GetCurrentProcess (), fc_handler[i].fh->get_handle (), GetCurrentProcess (), - &fhf->client[i].fh->get_handle (), + &fhf->fc_handler[i].fh->get_handle (), 0, true, DUPLICATE_SAME_ACCESS) - || !DuplicateHandle (GetCurrentProcess (), client[i].connect_evt, + || !DuplicateHandle (GetCurrentProcess (), fc_handler[i].connect_evt, GetCurrentProcess (), - &fhf->client[i].connect_evt, + &fhf->fc_handler[i].connect_evt, 0, true, DUPLICATE_SAME_ACCESS) - || !DuplicateHandle (GetCurrentProcess (), client[i].dummy_evt, + || !DuplicateHandle (GetCurrentProcess (), fc_handler[i].dummy_evt, GetCurrentProcess (), - &fhf->client[i].dummy_evt, + &fhf->fc_handler[i].dummy_evt, 0, true, DUPLICATE_SAME_ACCESS)) { CloseHandle (fhf->read_ready); @@ -907,11 +907,11 @@ fhandler_fifo::fixup_after_fork (HANDLE parent) fhandler_base::fixup_after_fork (parent); fork_fixup (parent, read_ready, "read_ready"); fork_fixup (parent, write_ready, "write_ready"); - for (int i = 0; i < nclients; i++) + for (int i = 0; i < nhandlers; i++) { - client[i].fh->fhandler_base::fixup_after_fork (parent); - fork_fixup (parent, client[i].connect_evt, "connect_evt"); - fork_fixup (parent, client[i].dummy_evt, "dummy_evt"); + fc_handler[i].fh->fhandler_base::fixup_after_fork (parent); + fork_fixup (parent, fc_handler[i].connect_evt, "connect_evt"); + fork_fixup (parent, fc_handler[i].dummy_evt, "dummy_evt"); } listen_client_thr = NULL; lct_termination_evt = NULL; @@ -924,10 +924,10 @@ fhandler_fifo::set_close_on_exec (bool val) fhandler_base::set_close_on_exec (val); set_no_inheritance (read_ready, val); set_no_inheritance (write_ready, val); - for (int i = 0; i < nclients; i++) + for (int i = 0; i < nhandlers; i++) { - client[i].fh->fhandler_base::set_close_on_exec (val); - set_no_inheritance (client[i].connect_evt, val); - set_no_inheritance (client[i].dummy_evt, val); + fc_handler[i].fh->fhandler_base::set_close_on_exec (val); + set_no_inheritance (fc_handler[i].connect_evt, val); + set_no_inheritance (fc_handler[i].dummy_evt, val); } } diff --git a/winsup/cygwin/select.cc b/winsup/cygwin/select.cc index 85242ec06..d257cc4ed 100644 --- a/winsup/cygwin/select.cc +++ b/winsup/cygwin/select.cc @@ -872,7 +872,7 @@ peek_fifo (select_record *s, bool from_select) } fh->fifo_client_lock (); - for (int i = 0; i < fh->get_nclients (); i++) + for (int i = 0; i < fh->get_nhandlers (); i++) if (fh->is_connected (i)) { int n = pipe_data_available (s->fd, fh, fh->get_handle (i), From 528169992668a7e292b8c1c5a39e2c1e24ff6683 Mon Sep 17 00:00:00 2001 From: Ken Brown Date: Sun, 14 Apr 2019 19:15:56 +0000 Subject: [PATCH 340/475] Cygwin: FIFO: hit_eof: add a call to fifo_client_lock The second check of nconnected needs to be protected by a lock as well as the first. --- winsup/cygwin/fhandler_fifo.cc | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/winsup/cygwin/fhandler_fifo.cc b/winsup/cygwin/fhandler_fifo.cc index 901696444..70551ebac 100644 --- a/winsup/cygwin/fhandler_fifo.cc +++ b/winsup/cygwin/fhandler_fifo.cc @@ -705,15 +705,20 @@ fhandler_fifo::raw_write (const void *ptr, size_t len) bool fhandler_fifo::hit_eof () { - fifo_client_lock (); - bool eof = (nconnected == 0); - fifo_client_unlock (); - if (eof) - { - /* Give the listen_client thread time to catch up, then recheck. */ - Sleep (1); + bool eof; + bool retry = true; + +retry: + fifo_client_lock (); eof = (nconnected == 0); - } + fifo_client_unlock (); + if (eof && retry) + { + retry = false; + /* Give the listen_client thread time to catch up. */ + Sleep (1); + goto retry; + } return eof; } From 164378951757bb4bd5554c9034fb97cf1649cbeb Mon Sep 17 00:00:00 2001 From: Ken Brown Date: Sun, 14 Apr 2019 19:15:57 +0000 Subject: [PATCH 341/475] Cygwin: FIFO: remember the type of the fhandler Add data members 'reader', 'writer', and 'duplexer' to the fhandler_fifo class. Set them in fhandler_fifo::open. ('duplexer' replaces the previous '_duplexer'.) This will be useful in later commits. --- winsup/cygwin/fhandler.h | 2 +- winsup/cygwin/fhandler_fifo.cc | 14 ++++---------- 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h index 2898db4df..59d9dad16 100644 --- a/winsup/cygwin/fhandler.h +++ b/winsup/cygwin/fhandler.h @@ -1272,7 +1272,7 @@ class fhandler_fifo: public fhandler_base fifo_client_handler fc_handler[MAX_CLIENTS]; int nhandlers, nconnected; af_unix_spinlock_t _fifo_client_lock; - bool _duplexer; + bool reader, writer, duplexer; bool __reg2 wait (HANDLE); NTSTATUS npfs_handle (HANDLE &); HANDLE create_pipe_instance (bool); diff --git a/winsup/cygwin/fhandler_fifo.cc b/winsup/cygwin/fhandler_fifo.cc index 70551ebac..258c3cf8a 100644 --- a/winsup/cygwin/fhandler_fifo.cc +++ b/winsup/cygwin/fhandler_fifo.cc @@ -33,7 +33,7 @@ STATUS_PIPE_EMPTY simply means there's no data to be read. */ fhandler_fifo::fhandler_fifo (): fhandler_base (), read_ready (NULL), write_ready (NULL), listen_client_thr (NULL), lct_termination_evt (NULL), nhandlers (0), - nconnected (0), _duplexer (false) + nconnected (0), reader (false), writer (false), duplexer (false) { pipe_name_buf[0] = L'\0'; need_fork_fixup (true); @@ -224,7 +224,7 @@ fhandler_fifo::create_pipe_instance (bool first) } access = GENERIC_READ | FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES | SYNCHRONIZE; - if (first && _duplexer) + if (first && duplexer) access |= GENERIC_WRITE; sharing = FILE_SHARE_READ | FILE_SHARE_WRITE; hattr = OBJ_INHERIT; @@ -421,25 +421,19 @@ fhandler_fifo::open (int flags, mode_t) error_errno_set, error_set_errno } res; - bool reader, writer, duplexer; /* Determine what we're doing with this fhandler: reading, writing, both */ switch (flags & O_ACCMODE) { case O_RDONLY: reader = true; - writer = false; - duplexer = false; break; case O_WRONLY: writer = true; - reader = false; - duplexer = false; break; case O_RDWR: reader = true; - writer = false; - duplexer = _duplexer = true; + duplexer = true; break; default: set_errno (EINVAL); @@ -769,7 +763,7 @@ fhandler_fifo::raw_read (void *in_ptr, size_t& len) fifo_client_unlock (); goto errout; } - else if (nread == 0 && (!_duplexer || i > 0)) + else if (nread == 0 && (!duplexer || i > 0)) /* Client has disconnected. */ { fc_handler[i].state = fc_invalid; From 0c72e766e2bd4b504030a502c0c46e41d268e052 Mon Sep 17 00:00:00 2001 From: Ken Brown Date: Sun, 14 Apr 2019 19:15:58 +0000 Subject: [PATCH 342/475] Cygwin: FIFO: fix a thinko in listen_client_thread --- winsup/cygwin/fhandler_fifo.cc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/winsup/cygwin/fhandler_fifo.cc b/winsup/cygwin/fhandler_fifo.cc index 258c3cf8a..764420ffd 100644 --- a/winsup/cygwin/fhandler_fifo.cc +++ b/winsup/cygwin/fhandler_fifo.cc @@ -362,7 +362,10 @@ fhandler_fifo::listen_client_thread () fifo_client_unlock (); goto errout; } - /* Fall through. */ + else + /* Recheck fc_handler[i].state. */ + i--; + break; case fc_connected: w[i] = fc_handler[i].dummy_evt; break; From 513f050cbf1b9e1ac40e08d258e496272bde920f Mon Sep 17 00:00:00 2001 From: Ken Brown Date: Sun, 14 Apr 2019 19:15:58 +0000 Subject: [PATCH 343/475] Cygwin: FIFO: fix the error checking in raw_read If the pipe is empty, we can get either ERROR_NO_DATA or ERROR_PIPE_LISTENING. --- winsup/cygwin/fhandler_fifo.cc | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/winsup/cygwin/fhandler_fifo.cc b/winsup/cygwin/fhandler_fifo.cc index 764420ffd..2da579b95 100644 --- a/winsup/cygwin/fhandler_fifo.cc +++ b/winsup/cygwin/fhandler_fifo.cc @@ -749,19 +749,16 @@ fhandler_fifo::raw_read (void *in_ptr, size_t& len) fifo_client_unlock (); return; } - /* In the duplex case with no data, we seem to get nread - == -1 with ERROR_PIPE_LISTENING on the first attempt to - read from the duplex pipe (fc_handler[0]), and nread == 0 - on subsequent attempts. */ + /* If the pipe is empty, we usually get nread == -1 with + ERROR_NO_DATA or ERROR_PIPE_LISTENING. An exception is + that in the duplex case we may get nread == 0 when we + attempt to read from the duplex pipe (fc_handler[0]). */ else if (nread < 0) switch (GetLastError ()) { case ERROR_NO_DATA: - break; case ERROR_PIPE_LISTENING: - if (_duplexer && i == 0) - break; - /* Fall through. */ + break; default: fifo_client_unlock (); goto errout; From 10bf30bebf7feebbc3e376cbcac62a242cc240f3 Mon Sep 17 00:00:00 2001 From: Ken Brown Date: Sun, 14 Apr 2019 19:15:59 +0000 Subject: [PATCH 344/475] Cygwin: check for STATUS_PENDING in fhandler_base::raw_read If NtReadFile returns STATUS_PENDING, wait for the read to complete. This can happen, for instance, in the case of a FIFO opened with O_RDRW. --- winsup/cygwin/fhandler.cc | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/winsup/cygwin/fhandler.cc b/winsup/cygwin/fhandler.cc index b0c9c50c3..a0c3dcce2 100644 --- a/winsup/cygwin/fhandler.cc +++ b/winsup/cygwin/fhandler.cc @@ -215,11 +215,23 @@ fhandler_base::raw_read (void *ptr, size_t& len) NTSTATUS status; IO_STATUS_BLOCK io; int try_noreserve = 1; + DWORD waitret = WAIT_OBJECT_0; retry: status = NtReadFile (get_handle (), NULL, NULL, NULL, &io, ptr, len, NULL, NULL); - if (NT_SUCCESS (status)) + if (status == STATUS_PENDING) + { + waitret = cygwait (get_handle (), cw_infinite, + cw_cancel | cw_sig_eintr); + if (waitret == WAIT_OBJECT_0) + status = io.Status; + } + if (waitret == WAIT_CANCELED) + pthread::static_cancel_self (); + else if (waitret == WAIT_SIGNALED) + set_errno (EINTR); + else if (NT_SUCCESS (status)) len = io.Information; else { From d243b3c70ea4db87432bccc9437d45f4b740f2ff Mon Sep 17 00:00:00 2001 From: Ken Brown Date: Sun, 14 Apr 2019 19:16:00 +0000 Subject: [PATCH 345/475] Cygwin: FIFO: code simplification: don't overload get_handle Rename fhandler_fifo::get_handle(int) to get_fc_handle(int), and remove fhandler_fifo::get_handle(void). --- winsup/cygwin/fhandler.h | 7 ++++--- winsup/cygwin/select.cc | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h index 59d9dad16..1e26c651f 100644 --- a/winsup/cygwin/fhandler.h +++ b/winsup/cygwin/fhandler.h @@ -1284,9 +1284,10 @@ public: fhandler_fifo (); bool hit_eof (); int get_nhandlers () const { return nhandlers; } - HANDLE& get_handle () { return fhandler_base::get_handle (); } - HANDLE get_handle (int i) const { return fc_handler[i].fh->get_handle (); } - bool is_connected (int i) const { return fc_handler[i].state == fc_connected; } + HANDLE get_fc_handle (int i) const + { return fc_handler[i].fh->get_handle (); } + bool is_connected (int i) const + { return fc_handler[i].state == fc_connected; } PUNICODE_STRING get_pipe_name (); DWORD listen_client_thread (); void fifo_client_lock () { _fifo_client_lock.lock (); } diff --git a/winsup/cygwin/select.cc b/winsup/cygwin/select.cc index d257cc4ed..9cf892801 100644 --- a/winsup/cygwin/select.cc +++ b/winsup/cygwin/select.cc @@ -875,7 +875,7 @@ peek_fifo (select_record *s, bool from_select) for (int i = 0; i < fh->get_nhandlers (); i++) if (fh->is_connected (i)) { - int n = pipe_data_available (s->fd, fh, fh->get_handle (i), + int n = pipe_data_available (s->fd, fh, fh->get_fc_handle (i), false); if (n > 0) { From 3ef03376c5b8de8b2a80aded2f3602931cc26ae5 Mon Sep 17 00:00:00 2001 From: Ken Brown Date: Sun, 14 Apr 2019 19:16:00 +0000 Subject: [PATCH 346/475] Cygwin: FIFO: fix fifo_client_handler::close Make sure that fhandler_base::close rather than fhandler_fifo::close is called on the fhandler. Also, delete the fhandler, since we allocated it. --- winsup/cygwin/fhandler_fifo.cc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/winsup/cygwin/fhandler_fifo.cc b/winsup/cygwin/fhandler_fifo.cc index 2da579b95..f9796f300 100644 --- a/winsup/cygwin/fhandler_fifo.cc +++ b/winsup/cygwin/fhandler_fifo.cc @@ -809,7 +809,10 @@ fifo_client_handler::close () int res = 0; if (fh) - res = fh->close (); + { + res = fh->fhandler_base::close (); + delete fh; + } if (connect_evt) CloseHandle (connect_evt); if (dummy_evt) From 6b20be09442d09e745d60e76dc680b8fd45d36ea Mon Sep 17 00:00:00 2001 From: Ken Brown Date: Sun, 14 Apr 2019 19:16:01 +0000 Subject: [PATCH 347/475] Cygwin: FIFO: fix the use of the read_ready event Make read_ready a manual reset event. It should always be set shortly after startup of the listen_client thread and remain set until the thread terminates. (We don't want writers to connect without being recorded in the client handler list.) Remove the unnecessary code that checks for read_ready when a reader is opening. --- winsup/cygwin/fhandler_fifo.cc | 51 +++++++++++----------------------- 1 file changed, 16 insertions(+), 35 deletions(-) diff --git a/winsup/cygwin/fhandler_fifo.cc b/winsup/cygwin/fhandler_fifo.cc index f9796f300..479021e8e 100644 --- a/winsup/cygwin/fhandler_fifo.cc +++ b/winsup/cygwin/fhandler_fifo.cc @@ -344,6 +344,8 @@ fhandler_fifo::listen_client () DWORD fhandler_fifo::listen_client_thread () { + DWORD ret = -1; + while (1) { bool found; @@ -360,7 +362,7 @@ fhandler_fifo::listen_client_thread () if (disconnect_and_reconnect (i) < 0) { fifo_client_unlock (); - goto errout; + goto out; } else /* Recheck fc_handler[i].state. */ @@ -383,23 +385,27 @@ fhandler_fifo::listen_client_thread () res = add_client_handler (); fifo_client_unlock (); if (res < 0) - goto errout; + goto out; else if (!found) continue; + /* Allow a writer to open. */ if (!arm (read_ready)) { __seterrno (); - goto errout; + goto out; } /* Wait for a client to connect. */ wait_ret = WaitForMultipleObjects (nhandlers + 1, w, false, INFINITE); i = wait_ret - WAIT_OBJECT_0; if (i < 0 || i > nhandlers) - goto errout; - else if (i == nhandlers) /* Reader is closing. */ - return 0; + goto out; + else if (i == nhandlers) /* Thread termination requested. */ + { + ret = 0; + goto out; + } else { fifo_client_lock (); @@ -410,9 +416,9 @@ fhandler_fifo::listen_client_thread () yield (); } } -errout: +out: ResetEvent (read_ready); - return -1; + return ret; } int @@ -457,7 +463,7 @@ fhandler_fifo::open (int flags, mode_t) char npbuf[MAX_PATH]; __small_sprintf (npbuf, "r-event.%08x.%016X", get_dev (), get_ino ()); - if (!(read_ready = CreateEvent (sa_buf, duplexer, false, npbuf))) + if (!(read_ready = CreateEvent (sa_buf, true, false, npbuf))) { debug_printf ("CreateEvent for %s failed, %E", npbuf); res = error_set_errno; @@ -523,32 +529,7 @@ fhandler_fifo::open (int flags, mode_t) res = error_errno_set; goto out; } - /* Wait for the listen_client thread to signal read_ready. This - should be quick. */ - HANDLE w[2] = { listen_client_thr, read_ready }; - switch (WaitForMultipleObjects (2, w, FALSE, INFINITE)) - { - case WAIT_OBJECT_0: - debug_printf ("listen_client_thread exited unexpectedly"); - DWORD err; - GetExitCodeThread (listen_client_thr, &err); - __seterrno_from_win_error (err); - res = error_errno_set; - goto out; - break; - case WAIT_OBJECT_0 + 1: - if (!arm (read_ready)) - { - res = error_set_errno; - goto out; - } - break; - default: - res = error_set_errno; - goto out; - break; - } - if (!duplexer && !wait (write_ready)) + else if (!duplexer && !wait (write_ready)) { res = error_errno_set; goto out; From c5bc7a806521ce8d72f8ffc1c5c4c5efac87606f Mon Sep 17 00:00:00 2001 From: Ken Brown Date: Sun, 14 Apr 2019 19:16:02 +0000 Subject: [PATCH 348/475] Cygwin: FIFO: use a retry loop when opening a writer There may be short periods when there's no pipe instance available. Keep trying. --- winsup/cygwin/fhandler_fifo.cc | 52 ++++++++++++++++++++-------------- 1 file changed, 31 insertions(+), 21 deletions(-) diff --git a/winsup/cygwin/fhandler_fifo.cc b/winsup/cygwin/fhandler_fifo.cc index 479021e8e..d4d2b3883 100644 --- a/winsup/cygwin/fhandler_fifo.cc +++ b/winsup/cygwin/fhandler_fifo.cc @@ -30,6 +30,12 @@ STATUS_PIPE_EMPTY simply means there's no data to be read. */ || _s == STATUS_PIPE_BROKEN \ || _s == STATUS_PIPE_EMPTY; }) +#define STATUS_PIPE_NO_INSTANCE_AVAILABLE(status) \ + ({ NTSTATUS _s = (status); \ + _s == STATUS_INSTANCE_NOT_AVAILABLE \ + || _s == STATUS_PIPE_NOT_AVAILABLE \ + || _s == STATUS_PIPE_BUSY; }) + fhandler_fifo::fhandler_fifo (): fhandler_base (), read_ready (NULL), write_ready (NULL), listen_client_thr (NULL), lct_termination_evt (NULL), nhandlers (0), @@ -543,28 +549,32 @@ fhandler_fifo::open (int flags, mode_t) listen_client thread is running. Then signal write_ready. */ if (writer) { - if (!wait (read_ready)) + while (1) { - res = error_errno_set; - goto out; - } - NTSTATUS status = open_pipe (); - if (!NT_SUCCESS (status)) - { - debug_printf ("create of writer failed"); - __seterrno_from_nt_status (status); - res = error_errno_set; - goto out; - } - else if (!arm (write_ready)) - { - res = error_set_errno; - goto out; - } - else - { - set_pipe_non_blocking (get_handle (), true); - res = success; + if (!wait (read_ready)) + { + res = error_errno_set; + goto out; + } + NTSTATUS status = open_pipe (); + if (NT_SUCCESS (status)) + { + set_pipe_non_blocking (get_handle (), true); + if (!arm (write_ready)) + res = error_set_errno; + else + res = success; + goto out; + } + else if (STATUS_PIPE_NO_INSTANCE_AVAILABLE (status)) + Sleep (1); + else + { + debug_printf ("create of writer failed"); + __seterrno_from_nt_status (status); + res = error_errno_set; + goto out; + } } } out: From 7b28776d3fe6909abb10273af2a3bfdca6351292 Mon Sep 17 00:00:00 2001 From: Ken Brown Date: Sun, 14 Apr 2019 19:16:02 +0000 Subject: [PATCH 349/475] Cygwin: FIFO: fix clone After copyto is called, make the new fhandler's pipe_name point to the new fhandler's pipe_name_buf, which is a *copy* of the old fhandler's pipe_name_buf. Previously, get_pipe_name would return the wrong result after a clone/dup, causing create_pipe_instance and open_pipe to fail. Also, stop the listen_client thread when cloning. Otherwise the thread can keep accepting connections that the cloned fhandler won't know about. Do this via a new method fhandler_fifo::stop_listen_client, extracted from fhandler_fifo::close. --- winsup/cygwin/fhandler.h | 6 ++++++ winsup/cygwin/fhandler_fifo.cc | 20 +++++++++++++++----- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h index 1e26c651f..aea02c2b3 100644 --- a/winsup/cygwin/fhandler.h +++ b/winsup/cygwin/fhandler.h @@ -1280,6 +1280,7 @@ class fhandler_fifo: public fhandler_base int disconnect_and_reconnect (int); int add_client_handler (); bool listen_client (); + int stop_listen_client (); public: fhandler_fifo (); bool hit_eof (); @@ -1326,7 +1327,12 @@ public: { void *ptr = (void *) ccalloc (malloc_type, 1, sizeof (fhandler_fifo)); fhandler_fifo *fhf = new (ptr) fhandler_fifo (ptr); + /* We don't want our client list to change any more. */ + stop_listen_client (); copyto (fhf); + /* fhf->pipe_name_buf is a *copy* of this->pipe_name_buf, but + fhf->pipe_name.Buffer == this->pipe_name_buf. */ + fhf->pipe_name.Buffer = fhf->pipe_name_buf; for (int i = 0; i < nhandlers; i++) fhf->fc_handler[i].fh = fc_handler[i].fh->clone (); return fhf; diff --git a/winsup/cygwin/fhandler_fifo.cc b/winsup/cygwin/fhandler_fifo.cc index d4d2b3883..a3ecbeb4a 100644 --- a/winsup/cygwin/fhandler_fifo.cc +++ b/winsup/cygwin/fhandler_fifo.cc @@ -812,9 +812,9 @@ fifo_client_handler::close () } int -fhandler_fifo::close () +fhandler_fifo::stop_listen_client () { - int res = 0; + int ret = 0; HANDLE evt = InterlockedExchangePointer (&lct_termination_evt, NULL); HANDLE thr = InterlockedExchangePointer (&listen_client_thr, NULL); if (thr) @@ -825,19 +825,29 @@ fhandler_fifo::close () DWORD err; GetExitCodeThread (thr, &err); if (err) - debug_printf ("listen_client_thread exited with code %d", err); + { + ret = -1; + debug_printf ("listen_client_thread exited with error, %E"); + } CloseHandle (thr); } if (evt) CloseHandle (evt); + return ret; +} + +int +fhandler_fifo::close () +{ + int ret = stop_listen_client (); if (read_ready) CloseHandle (read_ready); if (write_ready) CloseHandle (write_ready); for (int i = 0; i < nhandlers; i++) if (fc_handler[i].close () < 0) - res = -1; - return fhandler_base::close () || res; + ret = -1; + return fhandler_base::close () || ret; } int From a7d08b3ecd721e98757f8f96945660809ec6a3da Mon Sep 17 00:00:00 2001 From: Ken Brown Date: Sun, 14 Apr 2019 19:16:03 +0000 Subject: [PATCH 350/475] Cygwin: FIFO: start the listen_client thread when duping a reader Otherwise it doesn't get started until the dup'd fd tries to read, which delays client connections. --- winsup/cygwin/fhandler_fifo.cc | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/winsup/cygwin/fhandler_fifo.cc b/winsup/cygwin/fhandler_fifo.cc index a3ecbeb4a..fe4c67bdf 100644 --- a/winsup/cygwin/fhandler_fifo.cc +++ b/winsup/cygwin/fhandler_fifo.cc @@ -853,19 +853,20 @@ fhandler_fifo::close () int fhandler_fifo::dup (fhandler_base *child, int flags) { + int ret = -1; + fhandler_fifo *fhf = NULL; + if (fhandler_base::dup (child, flags)) - { - __seterrno (); - return -1; - } - fhandler_fifo *fhf = (fhandler_fifo *) child; + goto out; + + fhf = (fhandler_fifo *) child; if (!DuplicateHandle (GetCurrentProcess (), read_ready, GetCurrentProcess (), &fhf->read_ready, 0, true, DUPLICATE_SAME_ACCESS)) { fhf->close (); __seterrno (); - return -1; + goto out; } if (!DuplicateHandle (GetCurrentProcess (), write_ready, GetCurrentProcess (), &fhf->write_ready, @@ -874,7 +875,7 @@ fhandler_fifo::dup (fhandler_base *child, int flags) CloseHandle (fhf->read_ready); fhf->close (); __seterrno (); - return -1; + goto out; } for (int i = 0; i < nhandlers; i++) { @@ -895,13 +896,16 @@ fhandler_fifo::dup (fhandler_base *child, int flags) CloseHandle (fhf->write_ready); fhf->close (); __seterrno (); - return -1; + goto out; } } fhf->listen_client_thr = NULL; fhf->lct_termination_evt = NULL; fhf->fifo_client_unlock (); - return 0; + if (!reader || fhf->listen_client ()) + ret = 0; +out: + return ret; } void From bb466278713a68d68fd507cb8f2ace6142f0a58c Mon Sep 17 00:00:00 2001 From: Ken Brown Date: Mon, 15 Apr 2019 15:43:57 +0000 Subject: [PATCH 351/475] Cygwin: FIFO: improve raw_write Don't set the write end of the pipe to non-blocking mode if the FIFO is opened in blocking mode. In fhandler_fifo::raw_write in blocking mode, wait for the write to complete rather than returning -1 with EAGAIN. If the amount to write is large, write in smaller chunks (of size determined by a new data member max_atomic_write), as in fhandler_base_overlapped. For convenience, add two new NTSTATUS codes, STATUS_THREAD_SIGNALED and STATUS_THREAD_CANCELED, to ntdll.h. --- winsup/cygwin/fhandler.h | 1 + winsup/cygwin/fhandler_fifo.cc | 99 ++++++++++++++++++++++++++-------- winsup/cygwin/ntdll.h | 4 +- 3 files changed, 82 insertions(+), 22 deletions(-) diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h index aea02c2b3..fd205a6db 100644 --- a/winsup/cygwin/fhandler.h +++ b/winsup/cygwin/fhandler.h @@ -1273,6 +1273,7 @@ class fhandler_fifo: public fhandler_base int nhandlers, nconnected; af_unix_spinlock_t _fifo_client_lock; bool reader, writer, duplexer; + size_t max_atomic_write; bool __reg2 wait (HANDLE); NTSTATUS npfs_handle (HANDLE &); HANDLE create_pipe_instance (bool); diff --git a/winsup/cygwin/fhandler_fifo.cc b/winsup/cygwin/fhandler_fifo.cc index fe4c67bdf..d2f8b99bc 100644 --- a/winsup/cygwin/fhandler_fifo.cc +++ b/winsup/cygwin/fhandler_fifo.cc @@ -39,7 +39,8 @@ STATUS_PIPE_EMPTY simply means there's no data to be read. */ fhandler_fifo::fhandler_fifo (): fhandler_base (), read_ready (NULL), write_ready (NULL), listen_client_thr (NULL), lct_termination_evt (NULL), nhandlers (0), - nconnected (0), reader (false), writer (false), duplexer (false) + nconnected (0), reader (false), writer (false), duplexer (false), + max_atomic_write (DEFAULT_PIPEBUFSIZE) { pipe_name_buf[0] = L'\0'; need_fork_fixup (true); @@ -559,7 +560,7 @@ fhandler_fifo::open (int flags, mode_t) NTSTATUS status = open_pipe (); if (NT_SUCCESS (status)) { - set_pipe_non_blocking (get_handle (), true); + set_pipe_non_blocking (get_handle (), flags & O_NONBLOCK); if (!arm (write_ready)) res = error_set_errno; else @@ -661,28 +662,84 @@ ssize_t __reg3 fhandler_fifo::raw_write (const void *ptr, size_t len) { ssize_t ret = -1; - NTSTATUS status; + size_t nbytes = 0, chunk; + NTSTATUS status = STATUS_SUCCESS; IO_STATUS_BLOCK io; + HANDLE evt = NULL; - status = NtWriteFile (get_handle (), NULL, NULL, NULL, &io, - (PVOID) ptr, len, NULL, NULL); - if (NT_SUCCESS (status)) - { - /* NtWriteFile returns success with # of bytes written == 0 in - case writing on a non-blocking pipe fails if the pipe buffer - is full. */ - if (io.Information == 0) - set_errno (EAGAIN); - else - ret = io.Information; - } - else if (STATUS_PIPE_IS_CLOSED (status)) - { - set_errno (EPIPE); - raise (SIGPIPE); - } + if (len <= max_atomic_write) + chunk = len; + else if (is_nonblocking ()) + chunk = len = max_atomic_write; else - __seterrno_from_nt_status (status); + chunk = max_atomic_write; + + /* Create a wait event if the FIFO is in blocking mode. */ + if (!is_nonblocking () && !(evt = CreateEvent (NULL, false, false, NULL))) + return -1; + + /* Write in chunks, accumulating a total. If there's an error, just + return the accumulated total unless the first write fails, in + which case return -1. */ + while (nbytes < len) + { + ULONG_PTR nbytes_now = 0; + size_t left = len - nbytes; + size_t len1; + if (left > chunk) + len1 = chunk; + else + len1 = left; + nbytes_now = 0; + status = NtWriteFile (get_handle (), evt, NULL, NULL, &io, + (PVOID) ptr, len1, NULL, NULL); + if (evt && status == STATUS_PENDING) + { + DWORD waitret = cygwait (evt, cw_infinite, cw_cancel | cw_sig_eintr); + switch (waitret) + { + case WAIT_OBJECT_0: + status = io.Status; + break; + case WAIT_SIGNALED: + status = STATUS_THREAD_SIGNALED; + break; + case WAIT_CANCELED: + status = STATUS_THREAD_CANCELED; + break; + default: + break; + } + } + if (NT_SUCCESS (status)) + { + nbytes_now = io.Information; + /* NtWriteFile returns success with # of bytes written == 0 + if writing on a non-blocking pipe fails because the pipe + buffer doesn't have sufficient space. */ + if (nbytes_now == 0) + set_errno (EAGAIN); + ptr = ((char *) ptr) + chunk; + nbytes += nbytes_now; + } + else if (STATUS_PIPE_IS_CLOSED (status)) + { + set_errno (EPIPE); + raise (SIGPIPE); + } + else + __seterrno_from_nt_status (status); + if (nbytes_now == 0) + len = 0; /* Terminate loop. */ + if (nbytes > 0) + ret = nbytes; + } + if (evt) + CloseHandle (evt); + if (status == STATUS_THREAD_SIGNALED && !_my_tls.call_signal_handler ()) + set_errno (EINTR); + else if (status == STATUS_THREAD_CANCELED) + pthread::static_cancel_self (); return ret; } diff --git a/winsup/cygwin/ntdll.h b/winsup/cygwin/ntdll.h index b41b99b4b..e19cc8ab5 100644 --- a/winsup/cygwin/ntdll.h +++ b/winsup/cygwin/ntdll.h @@ -15,7 +15,9 @@ extern GUID __cygwin_socket_guid; #define CYGWIN_SOCKET_GUID (&__cygwin_socket_guid) -/* custom status code: */ +/* Custom Cygwin-only status codes. */ +#define STATUS_THREAD_SIGNALED ((NTSTATUS)0xe0000001) +#define STATUS_THREAD_CANCELED ((NTSTATUS)0xe0000002) #define STATUS_ILLEGAL_DLL_PSEUDO_RELOCATION ((NTSTATUS) 0xe0000269) /* Simplify checking for a transactional error code. */ From 2b4cf7622e65af1af831d2c48daa2a52ec3c56fa Mon Sep 17 00:00:00 2001 From: Ken Brown Date: Sun, 14 Apr 2019 19:16:04 +0000 Subject: [PATCH 352/475] Cygwin: FIFO: fix and simplify listen_client_thread Remove fifo_client_handler::connect and move its code into listen_client_thread. That way we can check the return status when a client handler's connect_evt is signaled. Previously we incorrectly assumed there was a successful connection. Also simplify listen_client_thread in the following ways: - Replace fhandler_fifo::disconnect_and_reconnect by a new delete_client_handler method. Now we just delete invalid client handlers rather than trying to re-use them. - Try to maintain a client handler list that consists of connected client handlers and exactly one that is listening for a connection. This allows us to call WaitForMultipleObjects with only two wait objects. - Remove 'dummy_evt' from the fifo_client_handler struct; it is no longer needed. - On exit from listen_client_thread, delete the "extra" (listening) client handler. Otherwise there could be a connection that doesn't get recorded in the client handler list. This could happen when a file descriptor is being duplicated. --- winsup/cygwin/fhandler.h | 11 +- winsup/cygwin/fhandler_fifo.cc | 251 ++++++++++++++------------------- 2 files changed, 109 insertions(+), 153 deletions(-) diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h index fd205a6db..8fb176b24 100644 --- a/winsup/cygwin/fhandler.h +++ b/winsup/cygwin/fhandler.h @@ -1250,13 +1250,10 @@ struct fifo_client_handler fhandler_base *fh; fifo_client_connect_state state; HANDLE connect_evt; - HANDLE dummy_evt; /* Never signaled. */ - fifo_client_handler () : fh (NULL), state (fc_unknown), connect_evt (NULL), - dummy_evt (NULL) {} + fifo_client_handler () : fh (NULL), state (fc_unknown), connect_evt (NULL) {} fifo_client_handler (fhandler_base *_fh, fifo_client_connect_state _state, - HANDLE _connect_evt, HANDLE _dummy_evt) - : fh (_fh), state (_state), connect_evt (_connect_evt), - dummy_evt (_dummy_evt) {} + HANDLE _connect_evt) + : fh (_fh), state (_state), connect_evt (_connect_evt) {} int connect (); int close (); }; @@ -1278,8 +1275,8 @@ class fhandler_fifo: public fhandler_base NTSTATUS npfs_handle (HANDLE &); HANDLE create_pipe_instance (bool); NTSTATUS open_pipe (); - int disconnect_and_reconnect (int); int add_client_handler (); + void delete_client_handler (int); bool listen_client (); int stop_listen_client (); public: diff --git a/winsup/cygwin/fhandler_fifo.cc b/winsup/cygwin/fhandler_fifo.cc index d2f8b99bc..1d02adbaa 100644 --- a/winsup/cygwin/fhandler_fifo.cc +++ b/winsup/cygwin/fhandler_fifo.cc @@ -118,62 +118,6 @@ set_pipe_non_blocking (HANDLE ph, bool nonblocking) debug_printf ("NtSetInformationFile(FilePipeInformation): %y", status); } -/* The pipe instance is always in blocking mode when this is called. */ -int -fifo_client_handler::connect () -{ - NTSTATUS status; - IO_STATUS_BLOCK io; - - if (connect_evt) - ResetEvent (connect_evt); - else if (!(connect_evt = create_event ())) - return -1; - status = NtFsControlFile (fh->get_handle (), connect_evt, NULL, NULL, &io, - FSCTL_PIPE_LISTEN, NULL, 0, NULL, 0); - switch (status) - { - case STATUS_PENDING: - case STATUS_PIPE_LISTENING: - state = fc_connecting; - break; - case STATUS_PIPE_CONNECTED: - state = fc_connected; - set_pipe_non_blocking (fh->get_handle (), true); - break; - default: - __seterrno_from_nt_status (status); - return -1; - } - return 0; -} - -int -fhandler_fifo::disconnect_and_reconnect (int i) -{ - NTSTATUS status; - IO_STATUS_BLOCK io; - HANDLE ph = fc_handler[i].fh->get_handle (); - - status = NtFsControlFile (ph, NULL, NULL, NULL, &io, FSCTL_PIPE_DISCONNECT, - NULL, 0, NULL, 0); - /* Short-lived. Don't use cygwait. We don't want to be interrupted. */ - if (status == STATUS_PENDING - && NtWaitForSingleObject (ph, FALSE, NULL) == WAIT_OBJECT_0) - status = io.Status; - if (!NT_SUCCESS (status)) - { - __seterrno_from_nt_status (status); - return -1; - } - set_pipe_non_blocking (fc_handler[i].fh->get_handle (), false); - if (fc_handler[i].connect () < 0) - return -1; - if (fc_handler[i].state == fc_connected) - nconnected++; - return 0; -} - NTSTATUS fhandler_fifo::npfs_handle (HANDLE &nph) { @@ -280,41 +224,49 @@ fhandler_fifo::open_pipe () int fhandler_fifo::add_client_handler () { + int ret = -1; fifo_client_handler fc; fhandler_base *fh; + HANDLE ph = NULL; bool first = (nhandlers == 0); if (nhandlers == MAX_CLIENTS) { set_errno (EMFILE); - return -1; + goto out; } - if (!(fc.dummy_evt = create_event ())) - return -1; + if (!(fc.connect_evt = create_event ())) + goto out; if (!(fh = build_fh_dev (dev ()))) { set_errno (EMFILE); - return -1; + goto out; } - fc.fh = fh; - HANDLE ph = create_pipe_instance (first); + ph = create_pipe_instance (first); if (!ph) - goto errout; - fh->set_handle (ph); - fh->set_flags (get_flags ()); - if (fc.connect () < 0) { - fc.close (); - goto errout; + delete fh; + goto out; } - if (fc.state == fc_connected) - nconnected++; - fc_handler[nhandlers++] = fc; - return 0; -errout: - delete fh; - return -1; + else + { + fh->set_handle (ph); + fh->set_flags (get_flags ()); + ret = 0; + fc.fh = fh; + fc_handler[nhandlers++] = fc; + } +out: + return ret; +} +void +fhandler_fifo::delete_client_handler (int i) +{ + fc_handler[i].close (); + if (i < --nhandlers) + memmove (fc_handler + i, fc_handler + i + 1, + (nhandlers - i) * sizeof (fc_handler[i])); } /* Just hop to the listen_client_thread method. */ @@ -355,46 +307,23 @@ fhandler_fifo::listen_client_thread () while (1) { - bool found; - HANDLE w[MAX_CLIENTS + 1]; - int i; - DWORD wait_ret; + /* At the beginning of the loop, all client handlers are + in the fc_connected or fc_invalid state. */ + /* Delete any invalid clients. */ fifo_client_lock (); - found = false; - for (i = 0; i < nhandlers; i++) - switch (fc_handler[i].state) - { - case fc_invalid: - if (disconnect_and_reconnect (i) < 0) - { - fifo_client_unlock (); - goto out; - } - else - /* Recheck fc_handler[i].state. */ - i--; - break; - case fc_connected: - w[i] = fc_handler[i].dummy_evt; - break; - case fc_connecting: - found = true; - w[i] = fc_handler[i].connect_evt; - break; - case fc_unknown: /* Shouldn't happen. */ - default: - break; - } - w[nhandlers] = lct_termination_evt; - int res = 0; - if (!found) - res = add_client_handler (); - fifo_client_unlock (); - if (res < 0) + int i = 0; + while (i < nhandlers) + { + if (fc_handler[i].state == fc_invalid) + delete_client_handler (i); + else + i++; + } + + /* Create a new client handler. */ + if (add_client_handler () < 0) goto out; - else if (!found) - continue; /* Allow a writer to open. */ if (!arm (read_ready)) @@ -402,26 +331,73 @@ fhandler_fifo::listen_client_thread () __seterrno (); goto out; } + fifo_client_unlock (); - /* Wait for a client to connect. */ - wait_ret = WaitForMultipleObjects (nhandlers + 1, w, false, INFINITE); - i = wait_ret - WAIT_OBJECT_0; - if (i < 0 || i > nhandlers) - goto out; - else if (i == nhandlers) /* Thread termination requested. */ + /* Listen for a writer to connect to the new client handler. */ + fifo_client_handler& fc = fc_handler[nhandlers - 1]; + do + { + NTSTATUS status; + IO_STATUS_BLOCK io; + + status = NtFsControlFile (fc.fh->get_handle (), fc.connect_evt, + NULL, NULL, &io, FSCTL_PIPE_LISTEN, + NULL, 0, NULL, 0); + if (status == STATUS_PENDING) + { + HANDLE w[2] = { fc.connect_evt, lct_termination_evt }; + DWORD waitret = WaitForMultipleObjects (2, w, false, INFINITE); + switch (waitret) + { + case WAIT_OBJECT_0: + status = io.Status; + break; + case WAIT_OBJECT_0 + 1: + ret = 0; + status = STATUS_THREAD_IS_TERMINATING; + break; + default: + __seterrno (); + debug_printf ("WaitForMultipleObjects failed, %E"); + status = STATUS_THREAD_IS_TERMINATING; + break; + } + } + switch (status) + { + case STATUS_SUCCESS: + case STATUS_PIPE_CONNECTED: + fifo_client_lock (); + fc.state = fc_connected; + nconnected++; + set_pipe_non_blocking (fc.fh->get_handle (), true); + fifo_client_unlock (); + break; + case STATUS_PIPE_LISTENING: + /* Retry. */ + fc.state = fc_connecting; + ResetEvent (fc.connect_evt); + break; + case STATUS_THREAD_IS_TERMINATING: + fifo_client_lock (); + delete_client_handler (nhandlers - 1); + fifo_client_unlock (); + goto out; + default: + __seterrno_from_nt_status (status); + fifo_client_lock (); + delete_client_handler (nhandlers - 1); + fifo_client_unlock (); + goto out; + } + } while (fc.state == fc_connecting); + /* Check for thread termination in case WaitForMultipleObjects + didn't get called above. */ + if (IsEventSignalled (lct_termination_evt)) { ret = 0; goto out; } - else - { - fifo_client_lock (); - fc_handler[i].state = fc_connected; - nconnected++; - set_pipe_non_blocking (fc_handler[i].fh->get_handle (), true); - fifo_client_unlock (); - yield (); - } } out: ResetEvent (read_ready); @@ -487,7 +463,7 @@ fhandler_fifo::open (int flags, mode_t) /* If we're a duplexer, create the pipe and the first client handler. */ if (duplexer) { - HANDLE ph, connect_evt, dummy_evt; + HANDLE ph, connect_evt; fhandler_base *fh; ph = create_pipe_instance (true); @@ -513,16 +489,7 @@ fhandler_fifo::open (int flags, mode_t) delete fh; goto out; } - if (!(dummy_evt = create_event ())) - { - res = error_errno_set; - delete fh; - fh->close (); - CloseHandle (connect_evt); - goto out; - } - fc_handler[0] = fifo_client_handler (fh, fc_connected, connect_evt, - dummy_evt); + fc_handler[0] = fifo_client_handler (fh, fc_connected, connect_evt); nconnected = nhandlers = 1; } @@ -863,8 +830,6 @@ fifo_client_handler::close () } if (connect_evt) CloseHandle (connect_evt); - if (dummy_evt) - CloseHandle (dummy_evt); return res; } @@ -943,10 +908,6 @@ fhandler_fifo::dup (fhandler_base *child, int flags) || !DuplicateHandle (GetCurrentProcess (), fc_handler[i].connect_evt, GetCurrentProcess (), &fhf->fc_handler[i].connect_evt, - 0, true, DUPLICATE_SAME_ACCESS) - || !DuplicateHandle (GetCurrentProcess (), fc_handler[i].dummy_evt, - GetCurrentProcess (), - &fhf->fc_handler[i].dummy_evt, 0, true, DUPLICATE_SAME_ACCESS)) { CloseHandle (fhf->read_ready); @@ -975,7 +936,6 @@ fhandler_fifo::fixup_after_fork (HANDLE parent) { fc_handler[i].fh->fhandler_base::fixup_after_fork (parent); fork_fixup (parent, fc_handler[i].connect_evt, "connect_evt"); - fork_fixup (parent, fc_handler[i].dummy_evt, "dummy_evt"); } listen_client_thr = NULL; lct_termination_evt = NULL; @@ -992,6 +952,5 @@ fhandler_fifo::set_close_on_exec (bool val) { fc_handler[i].fh->fhandler_base::set_close_on_exec (val); set_no_inheritance (fc_handler[i].connect_evt, val); - set_no_inheritance (fc_handler[i].dummy_evt, val); } } From 38ecf252e56326bbdb5952ca75a8fad99cd1679d Mon Sep 17 00:00:00 2001 From: Jozef Lawrynowicz Date: Mon, 15 Apr 2019 18:06:09 +0100 Subject: [PATCH 353/475] Fix incorrect assembly code in _msp430_run_array --- libgloss/msp430/crt0.S | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libgloss/msp430/crt0.S b/libgloss/msp430/crt0.S index f5ab8d335..53162e6bd 100644 --- a/libgloss/msp430/crt0.S +++ b/libgloss/msp430/crt0.S @@ -246,8 +246,8 @@ _msp430_run_array: jeq _msp430_run_done mov_ @R4, R7 add_ R6, R4 - call_ @R7 - br_ _msp430_run_array + call_ R7 + br_ #_msp430_run_array _msp430_run_done: ret_ From f811485ffb78286929cd555d65bb70b8cac51c0c Mon Sep 17 00:00:00 2001 From: Jozef Lawrynowicz Date: Wed, 17 Apr 2019 13:17:38 +0100 Subject: [PATCH 354/475] MSP430: Make the inclusion of run_*_array fns depend on defined assembler symbols Many of the MSP430 crt functions (e.g. to initialize bss) are linked "dynamically", based on symbols defined in the program. The GNU assembler defines the symbols corresponding to the crt functions by examining the section names in the input file. If GCC has been configured with --enable-initfini-array, then .init_array and .fini_array will hold pointers to global constructors/destructors. These sections can also hold functions that need to be executed for other purposes. The attached patch puts the __crt0_run_{preinit,init,fini}_array and __crt0_run_array functions in their own object files, so they will only be linked when needed. Successfully regtested the DejaGNU GCC testsuite using the binutils and newlib changes together with GCC trunk configured with --enable-initfini-array. --- libgloss/msp430/Makefile.in | 4 ++ libgloss/msp430/crt0.S | 79 +++++++++++++++++++++++++++---------- libgloss/msp430/crtn.S | 13 +++++- 3 files changed, 74 insertions(+), 22 deletions(-) diff --git a/libgloss/msp430/Makefile.in b/libgloss/msp430/Makefile.in index 73079d65b..77c9b8b21 100644 --- a/libgloss/msp430/Makefile.in +++ b/libgloss/msp430/Makefile.in @@ -87,6 +87,10 @@ CRT_OBJS = \ crt_main.o \ crt_main_minrt.o \ crt_callexit.o \ + crt_run_init_array.o \ + crt_run_preinit_array.o \ + crt_run_fini_array.o \ + crt_run_array.o \ crt_init.o #### Host specific Makefile fragment comes in here. diff --git a/libgloss/msp430/crt0.S b/libgloss/msp430/crt0.S index 53162e6bd..42464ddbe 100644 --- a/libgloss/msp430/crt0.S +++ b/libgloss/msp430/crt0.S @@ -62,6 +62,13 @@ START_CRT_FUNC 0000 start END_CRT_FUNC start #endif +;; Some of the CRT functions below will only be present in the final linked +;; executable if the assembler decides they are needed. It will only define +;; the symbol necessary to prevent them being garbage collected by the linker +;; if the file being assembled has a specific section. +;; The CRT functions this applies to are: +;; init_bss, movedata, move_highdata, init_highbss, run_init_array, +;; run_preinit_array, run_fini_array and run_array. #if Lbss ;; Note - this section is only included in the startup code of the @@ -215,44 +222,69 @@ END_CRT_FUNC call_exit ;---------------------------------------- #ifndef MINRT -#if L0 - .section ".crt_0900main_init", "ax", @progbits - .global _msp430_run_init_array - .type _msp430_run_init_array,@function -_msp430_run_init_array: - mov_ #__init_array_start, R4 - mov_ #__init_array_end, R5 - mov_ #PTRsz, R6 - br_ #_msp430_run_array - .global _msp430_run_preinit_array - .type _msp430_run_preinit_array,@function -_msp430_run_preinit_array: +#if Lrun_preinit_array +;; Note - this section is only included in the startup code of the application +;; if it is needed. It is responsible for setting up the arguments +;; required for __crt0_run_array, to run the functions in .preinit_array. +START_CRT_FUNC 0910 run_preinit_array + mov_ #__preinit_array_start, R4 mov_ #__preinit_array_end, R5 mov_ #PTRsz, R6 - br_ #_msp430_run_array + br_ #__crt0_run_array + +END_CRT_FUNC run_preinit_array +#endif /* Lrun_preinit_array */ + +#if Lrun_init_array +;; Note - this section is only included in the startup code of the application +;; if it is needed. It is responsible for setting up the arguments +;; required for __crt0_run_array, to run the functions in .init_array. +START_CRT_FUNC 0920 run_init_array + + mov_ #__init_array_start, R4 + mov_ #__init_array_end, R5 + mov_ #PTRsz, R6 + br_ #__crt0_run_array + +END_CRT_FUNC run_init_array +#endif /* Lrun_init_array */ + +#if Lrun_fini_array +;; Note - this section is only included in the startup code of the application +;; if it is needed. It is responsible for setting up the arguments +;; required for __crt0_run_array, to run the functions in .fini_array. +START_CRT_FUNC 0930 run_fini_array - .global _msp430_run_fini_array - .type _msp430_run_fini_array,@function -_msp430_run_fini_array: mov_ #__fini_array_start, R4 mov_ #__fini_array_end, R5 mov_ #-PTRsz, R6 - br_ #_msp430_run_array + br_ #__crt0_run_array + +END_CRT_FUNC run_fini_array +#endif /* Lrun_fini_array */ + +#if Lrun_array +;; Note - this section is only included in the startup code of the application +;; if it is needed by one of the above run_*_array functions. +START_CRT_FUNC 0980 run_array -_msp430_run_array: cmp_ R4, R5 jeq _msp430_run_done mov_ @R4, R7 add_ R6, R4 call_ R7 - br_ #_msp430_run_array + br_ #__crt0_run_array + +END_CRT_FUNC run_array _msp430_run_done: ret_ +#endif /* Lrun_array */ ;---------------------------------------- +#if L0 .section .init,"ax" @@ -263,7 +295,14 @@ __msp430_init: .global __msp430_fini __msp430_fini: - call_ #_msp430_run_fini_array + call_ #__crt0_run_fini_array +;; If this function is not defined externally, we don't need it to do +;; anything. + .text + .weak __crt0_run_fini_array +__crt0_run_fini_array: + ret_ + #endif #endif /* not MINRT */ diff --git a/libgloss/msp430/crtn.S b/libgloss/msp430/crtn.S index 939d5ce6f..110fc3090 100644 --- a/libgloss/msp430/crtn.S +++ b/libgloss/msp430/crtn.S @@ -15,8 +15,8 @@ #ifndef MINRT .section .init,"ax" - call_ #_msp430_run_preinit_array - call_ #_msp430_run_init_array + call_ #__crt0_run_preinit_array + call_ #__crt0_run_init_array ret_ .global __msp430_init_end __msp430_init_end: @@ -28,5 +28,14 @@ __msp430_init_end: __msp430_fini_end: .text +;; If these functions are not defined externally, we don't need them to do +;; anything. + .balign 2 + .weak __crt0_run_preinit_array + .weak __crt0_run_init_array +__crt0_run_preinit_array: +__crt0_run_init_array: + ret_ + #endif From 230c5df2dfddeb83d31b16f791a079871ba224e8 Mon Sep 17 00:00:00 2001 From: Ken Brown Date: Thu, 18 Apr 2019 15:39:52 +0000 Subject: [PATCH 355/475] Cygwin: FIFO: avoid hang after exec Define fhandler:fifo::fixup_after_exec, which sets listen_client_thr and lct_termination_evt to NULL. This forces the listen_client thread to restart on the first attempt to read after an exec. Previously the exec'd process could hang in fhandler_fifo::raw_read. --- winsup/cygwin/fhandler.h | 1 + winsup/cygwin/fhandler_fifo.cc | 9 +++++++++ 2 files changed, 10 insertions(+) diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h index 8fb176b24..da007ee45 100644 --- a/winsup/cygwin/fhandler.h +++ b/winsup/cygwin/fhandler.h @@ -1301,6 +1301,7 @@ public: ssize_t __reg3 raw_write (const void *ptr, size_t ulen); bool arm (HANDLE h); void fixup_after_fork (HANDLE); + void fixup_after_exec (); int __reg2 fstatvfs (struct statvfs *buf); void clear_readahead () { diff --git a/winsup/cygwin/fhandler_fifo.cc b/winsup/cygwin/fhandler_fifo.cc index 1d02adbaa..bc9c23998 100644 --- a/winsup/cygwin/fhandler_fifo.cc +++ b/winsup/cygwin/fhandler_fifo.cc @@ -942,6 +942,15 @@ fhandler_fifo::fixup_after_fork (HANDLE parent) fifo_client_unlock (); } +void +fhandler_fifo::fixup_after_exec () +{ + fhandler_base::fixup_after_exec (); + listen_client_thr = NULL; + lct_termination_evt = NULL; + fifo_client_unlock (); +} + void fhandler_fifo::set_close_on_exec (bool val) { From 28182bca18bc2774641ca06620274a9b24e633e1 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Fri, 19 Apr 2019 18:01:44 +0200 Subject: [PATCH 356/475] Cygwin: drop unsupported Windows 10 versions * Pre-release version still reporting kernel version 6.4. * Windows 10 1511 is out of support since 2017-10-10. Signed-off-by: Corinna Vinschen --- winsup/cygwin/wincap.cc | 32 +------------------------------- 1 file changed, 1 insertion(+), 31 deletions(-) diff --git a/winsup/cygwin/wincap.cc b/winsup/cygwin/wincap.cc index 86dc631ec..17e0cf1be 100644 --- a/winsup/cygwin/wincap.cc +++ b/winsup/cygwin/wincap.cc @@ -148,32 +148,6 @@ wincaps wincap_10_1507 __attribute__((section (".cygwin_dll_common"), shared)) }, }; -wincaps wincap_10_1511 __attribute__((section (".cygwin_dll_common"), shared)) = { - def_guard_pages:2, - { - is_server:false, - needs_count_in_si_lpres2:false, - needs_query_information:false, - has_gaa_largeaddress_bug:false, - has_broken_alloc_console:true, - has_console_logon_sid:true, - has_precise_system_time:true, - has_microsoft_accounts:true, - has_processor_groups:true, - has_broken_prefetchvm:false, - has_new_pebteb_region:true, - has_broken_whoami:false, - has_unprivileged_createsymlink:false, - has_unbiased_interrupt_time:true, - has_precise_interrupt_time:true, - has_posix_unlink_semantics:false, - has_case_sensitive_dirs:false, - has_posix_rename_semantics:false, - no_msv1_0_s4u_logon_in_wow64:false, - has_con_24bit_colors:false, - }, -}; - wincaps wincap_10_1703 __attribute__((section (".cygwin_dll_common"), shared)) = { def_guard_pages:2, { @@ -311,10 +285,8 @@ wincapc::init () caps = &wincap_8; break; case 3: - caps = &wincap_8_1; - break; default: - caps = &wincap_10_1507; + caps = &wincap_8_1; break; } break; @@ -328,8 +300,6 @@ wincapc::init () caps = &wincap_10_1709; else if (version.dwBuildNumber >= 15063) caps = &wincap_10_1703; - else if (version.dwBuildNumber >= 10586) - caps = &wincap_10_1511; else caps = & wincap_10_1507; } From 4ecea14a5800e2f134f6e61d4eb8720982782a43 Mon Sep 17 00:00:00 2001 From: Ken Brown Date: Sat, 20 Apr 2019 11:44:01 -0400 Subject: [PATCH 357/475] Cygwin: FIFO: stop the listen_client thread on an opening error Don't just close the thread handle. --- winsup/cygwin/fhandler_fifo.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/winsup/cygwin/fhandler_fifo.cc b/winsup/cygwin/fhandler_fifo.cc index bc9c23998..409144fda 100644 --- a/winsup/cygwin/fhandler_fifo.cc +++ b/winsup/cygwin/fhandler_fifo.cc @@ -563,7 +563,7 @@ out: if (get_handle ()) CloseHandle (get_handle ()); if (listen_client_thr) - CloseHandle (listen_client_thr); + stop_listen_client (); } debug_printf ("res %d", res); return res == success; From ef269531a96b649ae27395f272cf95aa2c7062fa Mon Sep 17 00:00:00 2001 From: Ken Brown Date: Sat, 20 Apr 2019 11:49:35 -0400 Subject: [PATCH 358/475] Cygwin: FIFO: duplicate the i/o handle when opening a duplexer Don't use the same i/o handle for the first client handler as is used for the fhandler itself; this can lead to a later attempt to close the same handle twice. Instead use a duplicate. --- winsup/cygwin/fhandler_fifo.cc | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/winsup/cygwin/fhandler_fifo.cc b/winsup/cygwin/fhandler_fifo.cc index 409144fda..0a6dc0591 100644 --- a/winsup/cygwin/fhandler_fifo.cc +++ b/winsup/cygwin/fhandler_fifo.cc @@ -480,7 +480,14 @@ fhandler_fifo::open (int flags, mode_t) res = error_errno_set; goto out; } - fh->set_handle (ph); + if (!DuplicateHandle (GetCurrentProcess (), ph, GetCurrentProcess (), + &fh->get_handle (), 0, true, DUPLICATE_SAME_ACCESS)) + { + res = error_set_errno; + fh->close (); + delete fh; + goto out; + } fh->set_flags (flags); if (!(connect_evt = create_event ())) { From 24c56e5a2c4d5b0970252fccdff327f2480ca024 Mon Sep 17 00:00:00 2001 From: Ken Brown Date: Sat, 20 Apr 2019 11:22:29 -0400 Subject: [PATCH 359/475] Cygwin: FIFO: avoid WFMO error in listen_client_thread Don't set lct_termination_evt to NULL too early in fhandler_fifo::stop_listen_client. Doing so leads to an "Invalid Handle" error in WFMO. --- winsup/cygwin/fhandler_fifo.cc | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/winsup/cygwin/fhandler_fifo.cc b/winsup/cygwin/fhandler_fifo.cc index 0a6dc0591..0e4bf3aee 100644 --- a/winsup/cygwin/fhandler_fifo.cc +++ b/winsup/cygwin/fhandler_fifo.cc @@ -844,22 +844,24 @@ int fhandler_fifo::stop_listen_client () { int ret = 0; - HANDLE evt = InterlockedExchangePointer (&lct_termination_evt, NULL); - HANDLE thr = InterlockedExchangePointer (&listen_client_thr, NULL); + HANDLE thr, evt; + + thr = InterlockedExchangePointer (&listen_client_thr, NULL); if (thr) { - if (evt) - SetEvent (evt); + if (lct_termination_evt) + SetEvent (lct_termination_evt); WaitForSingleObject (thr, INFINITE); DWORD err; GetExitCodeThread (thr, &err); if (err) { ret = -1; - debug_printf ("listen_client_thread exited with error, %E"); + debug_printf ("listen_client_thread exited with error"); } CloseHandle (thr); } + evt = InterlockedExchangePointer (&lct_termination_evt, NULL); if (evt) CloseHandle (evt); return ret; From 252cd0ce2bfb74e8cdd79c9d4c48d11beb21d8e9 Mon Sep 17 00:00:00 2001 From: Ken Brown Date: Sat, 20 Apr 2019 11:31:08 -0400 Subject: [PATCH 360/475] Cygwin: FIFO: close connect_evt handles as soon as possible Keeping them open too long can cause an attempt to close them twice after a fork or exec. --- winsup/cygwin/fhandler_fifo.cc | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/winsup/cygwin/fhandler_fifo.cc b/winsup/cygwin/fhandler_fifo.cc index 0e4bf3aee..3ee307bcc 100644 --- a/winsup/cygwin/fhandler_fifo.cc +++ b/winsup/cygwin/fhandler_fifo.cc @@ -363,6 +363,7 @@ fhandler_fifo::listen_client_thread () break; } } + HANDLE evt = NULL; switch (status) { case STATUS_SUCCESS: @@ -371,6 +372,9 @@ fhandler_fifo::listen_client_thread () fc.state = fc_connected; nconnected++; set_pipe_non_blocking (fc.fh->get_handle (), true); + evt = InterlockedExchangePointer (&fc.connect_evt, NULL); + if (evt) + CloseHandle (evt); fifo_client_unlock (); break; case STATUS_PIPE_LISTENING: @@ -400,6 +404,8 @@ fhandler_fifo::listen_client_thread () } } out: + if (ret < 0) + debug_printf ("exiting lct with error, %E"); ResetEvent (read_ready); return ret; } @@ -829,14 +835,15 @@ int fifo_client_handler::close () { int res = 0; + HANDLE evt = InterlockedExchangePointer (&connect_evt, NULL); + if (evt) + CloseHandle (evt); if (fh) { res = fh->fhandler_base::close (); delete fh; } - if (connect_evt) - CloseHandle (connect_evt); return res; } @@ -913,11 +920,7 @@ fhandler_fifo::dup (fhandler_base *child, int flags) if (!DuplicateHandle (GetCurrentProcess (), fc_handler[i].fh->get_handle (), GetCurrentProcess (), &fhf->fc_handler[i].fh->get_handle (), - 0, true, DUPLICATE_SAME_ACCESS) - || !DuplicateHandle (GetCurrentProcess (), fc_handler[i].connect_evt, - GetCurrentProcess (), - &fhf->fc_handler[i].connect_evt, - 0, true, DUPLICATE_SAME_ACCESS)) + 0, true, DUPLICATE_SAME_ACCESS)) { CloseHandle (fhf->read_ready); CloseHandle (fhf->write_ready); From 4443100b53f4ede899da9ebcdea87d3dea93eb4a Mon Sep 17 00:00:00 2001 From: Ken Brown Date: Sat, 20 Apr 2019 11:41:12 -0400 Subject: [PATCH 361/475] Cygwin: FIFO: stop the listen_client thread before fork/exec Add methods need_fixup_before, init_fixup_before, and fixup_before_fork_exec to accomplish this. Stopping the thread makes sure that the client handler lists of the parent and child remain in sync while the forking/execing is in progress. --- winsup/cygwin/fhandler.h | 3 +++ winsup/cygwin/fhandler_fifo.cc | 15 +++++++++++++-- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h index da007ee45..0df25aa40 100644 --- a/winsup/cygwin/fhandler.h +++ b/winsup/cygwin/fhandler.h @@ -1300,6 +1300,9 @@ public: void __reg3 raw_read (void *ptr, size_t& ulen); ssize_t __reg3 raw_write (const void *ptr, size_t ulen); bool arm (HANDLE h); + bool need_fixup_before () const { return reader; } + int fixup_before_fork_exec (DWORD) { return stop_listen_client (); } + void init_fixup_before (); void fixup_after_fork (HANDLE); void fixup_after_exec (); int __reg2 fstatvfs (struct statvfs *buf); diff --git a/winsup/cygwin/fhandler_fifo.cc b/winsup/cygwin/fhandler_fifo.cc index 3ee307bcc..9b94a6da9 100644 --- a/winsup/cygwin/fhandler_fifo.cc +++ b/winsup/cygwin/fhandler_fifo.cc @@ -522,7 +522,10 @@ fhandler_fifo::open (int flags, mode_t) goto out; } else - res = success; + { + init_fixup_before (); + res = success; + } } /* If we're writing, wait for read_ready and then connect to the @@ -752,7 +755,7 @@ fhandler_fifo::raw_read (void *in_ptr, size_t& len) { size_t orig_len = len; - /* Start the listen_client thread if necessary (e.g., after dup or fork). */ + /* Start the listen_client thread if necessary (e.g., after fork or exec). */ if (!listen_client_thr && !listen_client ()) goto errout; @@ -934,10 +937,18 @@ fhandler_fifo::dup (fhandler_base *child, int flags) fhf->fifo_client_unlock (); if (!reader || fhf->listen_client ()) ret = 0; + if (reader) + fhf->init_fixup_before (); out: return ret; } +void +fhandler_fifo::init_fixup_before () +{ + cygheap->fdtab.inc_need_fixup_before (); +} + void fhandler_fifo::fixup_after_fork (HANDLE parent) { From 9957a7895be652b502f53811e581d923f93c135f Mon Sep 17 00:00:00 2001 From: Ken Brown Date: Sat, 20 Apr 2019 11:46:09 -0400 Subject: [PATCH 362/475] Cygwin: FIFO: restart listen_client thread after fork/exec This allows writers to connect immediately. Previously the lct wasn't restarted until the reader attempted to read. --- winsup/cygwin/fhandler_fifo.cc | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/winsup/cygwin/fhandler_fifo.cc b/winsup/cygwin/fhandler_fifo.cc index 9b94a6da9..ac2196c92 100644 --- a/winsup/cygwin/fhandler_fifo.cc +++ b/winsup/cygwin/fhandler_fifo.cc @@ -755,7 +755,7 @@ fhandler_fifo::raw_read (void *in_ptr, size_t& len) { size_t orig_len = len; - /* Start the listen_client thread if necessary (e.g., after fork or exec). */ + /* Start the listen_client thread if necessary (shouldn't be). */ if (!listen_client_thr && !listen_client ()) goto errout; @@ -960,18 +960,16 @@ fhandler_fifo::fixup_after_fork (HANDLE parent) fc_handler[i].fh->fhandler_base::fixup_after_fork (parent); fork_fixup (parent, fc_handler[i].connect_evt, "connect_evt"); } - listen_client_thr = NULL; - lct_termination_evt = NULL; - fifo_client_unlock (); + if (reader && !listen_client ()) + debug_printf ("failed to start lct, %E"); } void fhandler_fifo::fixup_after_exec () { fhandler_base::fixup_after_exec (); - listen_client_thr = NULL; - lct_termination_evt = NULL; - fifo_client_unlock (); + if (reader && !listen_client ()) + debug_printf ("failed to start lct, %E"); } void From 489e7e20480ff34a519d7299b226c56fa99f14a8 Mon Sep 17 00:00:00 2001 From: "Erik M. Bray" Date: Tue, 23 Apr 2019 16:55:33 +0200 Subject: [PATCH 363/475] Minor improvements to socket error handling: * Change default fallback for failed winsock error -> POSIX error mappings to EACCES, which is a valid errno for more socket-related syscalls. * Added a few previously missing entries to the wsock_errmap table that have obvious POSIX errno.h analogues. --- winsup/cygwin/net.cc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/winsup/cygwin/net.cc b/winsup/cygwin/net.cc index cd296d19d..437712c63 100644 --- a/winsup/cygwin/net.cc +++ b/winsup/cygwin/net.cc @@ -177,6 +177,9 @@ static const errmap_t wsock_errmap[] = { {WSAEREMOTE, "WSAEREMOTE", EREMOTE}, {WSAEINVAL, "WSAEINVAL", EINVAL}, {WSAEFAULT, "WSAEFAULT", EFAULT}, + {WSAEBADF, "WSAEBADF", EBADF}, + {WSAEACCES, "WSAEACCES", EACCES}, + {WSAEMFILE, "WSAEMFILE", EMFILE}, {0, "NOERROR", 0}, {0, NULL, 0} }; @@ -188,7 +191,7 @@ find_winsock_errno (DWORD why) if (why == wsock_errmap[i].w) return wsock_errmap[i].e; - return EPERM; + return EACCES; } void From f527171a9395f316889e0e2b12fffac14bdf98c4 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Thu, 25 Apr 2019 18:49:32 +0200 Subject: [PATCH 364/475] Cygwin: define MSG_EOR and refuse in send(2) Signed-off-by: Corinna Vinschen --- winsup/cygwin/fhandler_socket_inet.cc | 7 +++++++ winsup/cygwin/include/cygwin/socket.h | 2 ++ winsup/cygwin/release/3.1.0 | 4 ++++ 3 files changed, 13 insertions(+) diff --git a/winsup/cygwin/fhandler_socket_inet.cc b/winsup/cygwin/fhandler_socket_inet.cc index 46af1c4be..6f4383861 100644 --- a/winsup/cygwin/fhandler_socket_inet.cc +++ b/winsup/cygwin/fhandler_socket_inet.cc @@ -1351,6 +1351,13 @@ fhandler_socket_wsock::send_internal (struct _WSAMSG *wsamsg, int flags) DWORD wait_flags = flags & MSG_DONTWAIT; bool nosignal = !!(flags & MSG_NOSIGNAL); + /* MSG_EOR not supported by any protocol */ + if (flags & MSG_EOR) + { + set_errno (EOPNOTSUPP); + return SOCKET_ERROR; + } + flags &= (MSG_OOB | MSG_DONTROUTE); if (wsamsg->Control.len > 0) use_sendmsg = true; diff --git a/winsup/cygwin/include/cygwin/socket.h b/winsup/cygwin/include/cygwin/socket.h index 77d87ff09..cdfa4b933 100644 --- a/winsup/cygwin/include/cygwin/socket.h +++ b/winsup/cygwin/include/cygwin/socket.h @@ -207,6 +207,8 @@ struct OLD_msghdr /* AF_UNIX specific */ #define MSG_CMSG_CLOEXEC 0x1000 /* Set O_CLOEXEC on fd's passed via SCM_RIGHTS */ +/* MSG_EOR is not supported. We use the MSG_PARTIAL flag here */ +#define MSG_EOR 0x8000 /* Terminates a record */ /* Setsockoptions(2) level. Thanks to BSD these must match IPPROTO_xxx */ #define SOL_IP 0 diff --git a/winsup/cygwin/release/3.1.0 b/winsup/cygwin/release/3.1.0 index 95569fc2b..fe65e5082 100644 --- a/winsup/cygwin/release/3.1.0 +++ b/winsup/cygwin/release/3.1.0 @@ -24,3 +24,7 @@ Bug Fixes completed, instead of when only one key is typed. - Make console I/O functions thread-safe. + +- Define missing MSG_EOR. It's unsupported by the underlying Winsock + layer so using it in send(2), sendto(2), or sendmsg(2) will return -1 + with errno set to EOPNOTSUPP and recvmsg(2) will never return it. From 440559c40a4879ddfe0a73282aab994c53955cef Mon Sep 17 00:00:00 2001 From: Ken Brown Date: Thu, 25 Apr 2019 18:21:11 -0400 Subject: [PATCH 365/475] Cygwin: FIFO: synchronize the blocking mode of a writer's pipe The blocking mode of the Windows pipe underlying a writer is set to match that of the writer itself when the latter is opened. Define fhandler_fifo::fcntl to keep the pipe and the writer in sync if the blocking mode is changed via fcntl. --- winsup/cygwin/fhandler.h | 1 + winsup/cygwin/fhandler_fifo.cc | 16 ++++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h index 0df25aa40..f5ed61cc4 100644 --- a/winsup/cygwin/fhandler.h +++ b/winsup/cygwin/fhandler.h @@ -1294,6 +1294,7 @@ public: int open (int, mode_t); off_t lseek (off_t offset, int whence); int close (); + int fcntl (int cmd, intptr_t); int dup (fhandler_base *child, int); bool isfifo () const { return true; } void set_close_on_exec (bool val); diff --git a/winsup/cygwin/fhandler_fifo.cc b/winsup/cygwin/fhandler_fifo.cc index ac2196c92..a1e395bf6 100644 --- a/winsup/cygwin/fhandler_fifo.cc +++ b/winsup/cygwin/fhandler_fifo.cc @@ -891,6 +891,22 @@ fhandler_fifo::close () return fhandler_base::close () || ret; } +/* If we're a writer, keep the nonblocking state of the windows pipe + in sync with our nonblocking state. */ +int +fhandler_fifo::fcntl (int cmd, intptr_t arg) +{ + if (cmd != F_SETFL || !writer) + return fhandler_base::fcntl (cmd, arg); + + const bool was_nonblocking = is_nonblocking (); + int res = fhandler_base::fcntl (cmd, arg); + const bool now_nonblocking = is_nonblocking (); + if (now_nonblocking != was_nonblocking) + set_pipe_non_blocking (get_handle (), now_nonblocking); + return res; +} + int fhandler_fifo::dup (fhandler_base *child, int flags) { From ab2901c843c2b9226f9319a8242fffbdf002e8bc Mon Sep 17 00:00:00 2001 From: Faraz Shahbazker Date: Sun, 28 Apr 2019 18:17:14 +0000 Subject: [PATCH 366/475] Fix order of eh_frame sections in linker scripts The compiler driver positions the linker script at the end of the linker command-line, after crtend.o. As a result, any INPUT objects and archive GROUPs introduced by the linker script are placed after crtend.o and the end-of-frame marker provided by crtend.o ends up in between .eh_frames instead of being at the end. This has always been a problem, but a binutils update to clean-up redundant NULL markers in .eh_frame exposes it as a execution failure in exception-handling tests. This patch re-orders .eh_frames in all MIPS linker scripts so that the one from crtend.o is always placed last. libgloss/ * mips/array.ld: Re-order to place .eh_frame from crtend.o after all other .eh_frame sections. * mips/cfe.ld: Likewise. * mips/ddb-kseg0.ld: Likewise. * mips/ddb.ld: Likewise. * mips/dve.ld: Likewise. * mips/idt.ld: Likewise. * mips/idt32.ld: Likewise. * mips/idt64.ld: Likewise. * mips/jmr3904app.ld: Likewise. * mips/lsi.ld: Likewise. * mips/mti32.ld: Likewise. * mips/mti64.ld: Likewise. * mips/mti64_64.ld: Likewise. * mips/mti64_n32.ld: Likewise. * mips/nullmon.ld: Likewise. * mips/pmon.ld: Likewise. * mips/sde32.ld: Likewise. * mips/sde64.ld: Likewise. --- libgloss/mips/array.ld | 7 ++++++- libgloss/mips/cfe.ld | 8 +++++++- libgloss/mips/ddb-kseg0.ld | 7 ++++++- libgloss/mips/ddb.ld | 7 ++++++- libgloss/mips/dve.ld | 8 +++++++- libgloss/mips/idt.ld | 8 +++++++- libgloss/mips/idt32.ld | 7 ++++++- libgloss/mips/idt64.ld | 7 ++++++- libgloss/mips/jmr3904app.ld | 7 ++++++- libgloss/mips/lsi.ld | 7 ++++++- libgloss/mips/mti32.ld | 7 ++++++- libgloss/mips/mti64.ld | 8 +++++++- libgloss/mips/mti64_64.ld | 8 +++++++- libgloss/mips/mti64_n32.ld | 8 +++++++- libgloss/mips/nullmon.ld | 8 +++++++- libgloss/mips/pmon.ld | 8 +++++++- libgloss/mips/sde32.ld | 8 +++++++- libgloss/mips/sde64.ld | 8 +++++++- 18 files changed, 118 insertions(+), 18 deletions(-) diff --git a/libgloss/mips/array.ld b/libgloss/mips/array.ld index fc4cc8fc2..2bc49c71b 100644 --- a/libgloss/mips/array.ld +++ b/libgloss/mips/array.ld @@ -100,7 +100,12 @@ SECTIONS } .eh_frame_hdr : { *(.eh_frame_hdr) } - .eh_frame : { KEEP (*(.eh_frame)) } + .eh_frame : { + /* The .eh_frame section from the crtend file contains the + end of eh_frame marker and it must be last. */ + KEEP (*(EXCLUDE_FILE (*crtend.o) .eh_frame)) + KEEP (*(.eh_frame)) + } .gcc_except_table : { *(.gcc_except_table) } .jcr : { KEEP (*(.jcr)) } .ctors : diff --git a/libgloss/mips/cfe.ld b/libgloss/mips/cfe.ld index 58e8014d7..78fb8533f 100644 --- a/libgloss/mips/cfe.ld +++ b/libgloss/mips/cfe.ld @@ -55,7 +55,13 @@ SECTIONS _etext = .; .eh_frame_hdr : { *(.eh_frame_hdr) } - .eh_frame : { KEEP (*(.eh_frame)) } + .eh_frame : + { + /* The .eh_frame section from the crtend file contains the + end of eh_frame marker and it must be last. */ + KEEP (*(EXCLUDE_FILE (*crtend.o) .eh_frame)) + KEEP (*(.eh_frame)) + } .gcc_except_table : { *(.gcc_except_table) } .jcr : { KEEP (*(.jcr)) } .ctors : diff --git a/libgloss/mips/ddb-kseg0.ld b/libgloss/mips/ddb-kseg0.ld index db3759ea6..74bc1b09c 100644 --- a/libgloss/mips/ddb-kseg0.ld +++ b/libgloss/mips/ddb-kseg0.ld @@ -49,7 +49,12 @@ SECTIONS } .eh_frame_hdr : { *(.eh_frame_hdr) } - .eh_frame : { KEEP (*(.eh_frame)) } + .eh_frame : { + /* The .eh_frame section from the crtend file contains the + end of eh_frame marker and it must be last. */ + KEEP (*(EXCLUDE_FILE (*crtend.o) .eh_frame)) + KEEP (*(.eh_frame)) + } .gcc_except_table : { *(.gcc_except_table) } .jcr : { KEEP (*(.jcr)) } .ctors : diff --git a/libgloss/mips/ddb.ld b/libgloss/mips/ddb.ld index 028078353..8fcafd361 100644 --- a/libgloss/mips/ddb.ld +++ b/libgloss/mips/ddb.ld @@ -49,7 +49,12 @@ SECTIONS } .eh_frame_hdr : { *(.eh_frame_hdr) } - .eh_frame : { KEEP (*(.eh_frame)) } + .eh_frame : { + /* The .eh_frame section from the crtend file contains the + end of eh_frame marker and it must be last. */ + KEEP (*(EXCLUDE_FILE (*crtend.o) .eh_frame)) + KEEP (*(.eh_frame)) + } .gcc_except_table : { *(.gcc_except_table) } .jcr : { KEEP (*(.jcr)) } .ctors : diff --git a/libgloss/mips/dve.ld b/libgloss/mips/dve.ld index 073d1e9ca..adce60f82 100644 --- a/libgloss/mips/dve.ld +++ b/libgloss/mips/dve.ld @@ -49,7 +49,13 @@ SECTIONS } .eh_frame_hdr : { *(.eh_frame_hdr) } - .eh_frame : { KEEP (*(.eh_frame)) } + .eh_frame : + { + /* The .eh_frame section from the crtend file contains the + end of eh_frame marker and it must be last. */ + KEEP (*(EXCLUDE_FILE (*crtend.o) .eh_frame)) + KEEP (*(.eh_frame)) + } .gcc_except_table : { *(.gcc_except_table) } .jcr : { KEEP (*(.jcr)) } .ctors : diff --git a/libgloss/mips/idt.ld b/libgloss/mips/idt.ld index 05b39b78d..0d69af452 100644 --- a/libgloss/mips/idt.ld +++ b/libgloss/mips/idt.ld @@ -56,7 +56,13 @@ SECTIONS _etext = .; .eh_frame_hdr : { *(.eh_frame_hdr) } - .eh_frame : { KEEP (*(.eh_frame)) } + .eh_frame : + { + /* The .eh_frame section from the crtend file contains the + end of eh_frame marker and it must be last. */ + KEEP (*(EXCLUDE_FILE (*crtend.o) .eh_frame)) + KEEP (*(.eh_frame)) + } .gcc_except_table : { *(.gcc_except_table) } .jcr : { KEEP (*(.jcr)) } .ctors : diff --git a/libgloss/mips/idt32.ld b/libgloss/mips/idt32.ld index 95555291e..175a98b61 100644 --- a/libgloss/mips/idt32.ld +++ b/libgloss/mips/idt32.ld @@ -58,7 +58,12 @@ SECTIONS .eh_frame_hdr : { *(.eh_frame_hdr) } - .eh_frame : { KEEP (*(.eh_frame)) } + .eh_frame : { + /* The .eh_frame section from the crtend file contains the + end of eh_frame marker and it must be last. */ + KEEP (*(EXCLUDE_FILE (*crtend.o) .eh_frame)) + KEEP (*(.eh_frame)) + } .gcc_except_table : { *(.gcc_except_table) } .jcr : { KEEP (*(.jcr)) } .ctors : diff --git a/libgloss/mips/idt64.ld b/libgloss/mips/idt64.ld index 4a958202f..bd217e535 100644 --- a/libgloss/mips/idt64.ld +++ b/libgloss/mips/idt64.ld @@ -59,7 +59,12 @@ SECTIONS _etext = .; .eh_frame_hdr : { *(.eh_frame_hdr) } - .eh_frame : { KEEP (*(.eh_frame)) } + .eh_frame : { + /* The .eh_frame section from the crtend file contains the + end of eh_frame marker and it must be last. */ + KEEP (*(EXCLUDE_FILE (*crtend.o) .eh_frame)) + KEEP (*(.eh_frame)) + } .gcc_except_table : { *(.gcc_except_table) } .jcr : { KEEP (*(.jcr)) } .ctors : diff --git a/libgloss/mips/jmr3904app.ld b/libgloss/mips/jmr3904app.ld index 3056a36bf..d5b310918 100644 --- a/libgloss/mips/jmr3904app.ld +++ b/libgloss/mips/jmr3904app.ld @@ -48,7 +48,12 @@ SECTIONS } .eh_frame_hdr : { *(.eh_frame_hdr) } - .eh_frame : { KEEP (*(.eh_frame)) } + .eh_frame : { + /* The .eh_frame section from the crtend file contains the + end of eh_frame marker and it must be last. */ + KEEP (*(EXCLUDE_FILE (*crtend.o) .eh_frame)) + KEEP (*(.eh_frame)) + } .gcc_except_table : { *(.gcc_except_table) } .jcr : { KEEP (*(.jcr)) } .ctors : diff --git a/libgloss/mips/lsi.ld b/libgloss/mips/lsi.ld index 839382527..ca64ab927 100644 --- a/libgloss/mips/lsi.ld +++ b/libgloss/mips/lsi.ld @@ -48,7 +48,12 @@ SECTIONS } .eh_frame_hdr : { *(.eh_frame_hdr) } - .eh_frame : { KEEP (*(.eh_frame)) } + .eh_frame : { + /* The .eh_frame section from the crtend file contains the + end of eh_frame marker and it must be last. */ + KEEP (*(EXCLUDE_FILE (*crtend.o) .eh_frame)) + KEEP (*(.eh_frame)) + } .gcc_except_table : { *(.gcc_except_table) } .jcr : { KEEP (*(.jcr)) } .ctors : diff --git a/libgloss/mips/mti32.ld b/libgloss/mips/mti32.ld index 2739c620f..41592d12a 100644 --- a/libgloss/mips/mti32.ld +++ b/libgloss/mips/mti32.ld @@ -57,7 +57,12 @@ SECTIONS _etext = .; .eh_frame_hdr : { *(.eh_frame_hdr) } - .eh_frame : { KEEP (*(.eh_frame)) } + .eh_frame : { + /* The .eh_frame section from the crtend file contains the + end of eh_frame marker and it must be last. */ + KEEP (*(EXCLUDE_FILE (*crtend.o) .eh_frame)) + KEEP (*(.eh_frame)) + } .gcc_except_table : { *(.gcc_except_table) } .jcr : { KEEP (*(.jcr)) } .ctors : diff --git a/libgloss/mips/mti64.ld b/libgloss/mips/mti64.ld index 15975ad89..8a47c4760 100644 --- a/libgloss/mips/mti64.ld +++ b/libgloss/mips/mti64.ld @@ -59,7 +59,13 @@ SECTIONS _etext = .; .eh_frame_hdr : { *(.eh_frame_hdr) } - .eh_frame : { KEEP (*(.eh_frame)) } + .eh_frame : + { + /* The .eh_frame section from the crtend file contains the + end of eh_frame marker and it must be last. */ + KEEP (*(EXCLUDE_FILE (*crtend.o) .eh_frame)) + KEEP (*(.eh_frame)) + } .gcc_except_table : { *(.gcc_except_table) } .jcr : { KEEP (*(.jcr)) } .ctors : diff --git a/libgloss/mips/mti64_64.ld b/libgloss/mips/mti64_64.ld index 7a2074f1a..81704f065 100644 --- a/libgloss/mips/mti64_64.ld +++ b/libgloss/mips/mti64_64.ld @@ -62,7 +62,13 @@ SECTIONS _etext = .; .eh_frame_hdr : { *(.eh_frame_hdr) } - .eh_frame : { KEEP (*(.eh_frame)) } + .eh_frame : + { + /* The .eh_frame section from the crtend file contains the + end of eh_frame marker and it must be last. */ + KEEP (*(EXCLUDE_FILE (*crtend.o) .eh_frame)) + KEEP (*(.eh_frame)) + } .gcc_except_table : { *(.gcc_except_table) } .jcr : { KEEP (*(.jcr)) } .ctors : diff --git a/libgloss/mips/mti64_n32.ld b/libgloss/mips/mti64_n32.ld index 4003845e0..6c5380934 100644 --- a/libgloss/mips/mti64_n32.ld +++ b/libgloss/mips/mti64_n32.ld @@ -62,7 +62,13 @@ SECTIONS _etext = .; .eh_frame_hdr : { *(.eh_frame_hdr) } - .eh_frame : { KEEP (*(.eh_frame)) } + .eh_frame : + { + /* The .eh_frame section from the crtend file contains the + end of eh_frame marker and it must be last. */ + KEEP (*(EXCLUDE_FILE (*crtend.o) .eh_frame)) + KEEP (*(.eh_frame)) + } .gcc_except_table : { *(.gcc_except_table) } .jcr : { KEEP (*(.jcr)) } .ctors : diff --git a/libgloss/mips/nullmon.ld b/libgloss/mips/nullmon.ld index c90aed308..14b0d0e59 100644 --- a/libgloss/mips/nullmon.ld +++ b/libgloss/mips/nullmon.ld @@ -50,7 +50,13 @@ SECTIONS } .eh_frame_hdr : { *(.eh_frame_hdr) } - .eh_frame : { KEEP (*(.eh_frame)) } + .eh_frame : + { + /* The .eh_frame section from the crtend file contains the + end of eh_frame marker and it must be last. */ + KEEP (*(EXCLUDE_FILE (*crtend.o) .eh_frame)) + KEEP (*(.eh_frame)) + } .gcc_except_table : { *(.gcc_except_table) } .jcr : { KEEP (*(.jcr)) } .ctors : diff --git a/libgloss/mips/pmon.ld b/libgloss/mips/pmon.ld index 81fd8ee31..244c1f65b 100644 --- a/libgloss/mips/pmon.ld +++ b/libgloss/mips/pmon.ld @@ -50,7 +50,13 @@ SECTIONS } .eh_frame_hdr : { *(.eh_frame_hdr) } - .eh_frame : { KEEP (*(.eh_frame)) } + .eh_frame : + { + /* The .eh_frame section from the crtend file contains the + end of eh_frame marker and it must be last. */ + KEEP (*(EXCLUDE_FILE (*crtend.o) .eh_frame)) + KEEP (*(.eh_frame)) + } .gcc_except_table : { *(.gcc_except_table) } .jcr : { KEEP (*(.jcr)) } .ctors : diff --git a/libgloss/mips/sde32.ld b/libgloss/mips/sde32.ld index 715639ef5..657f5f31b 100644 --- a/libgloss/mips/sde32.ld +++ b/libgloss/mips/sde32.ld @@ -57,7 +57,13 @@ SECTIONS _etext = .; .eh_frame_hdr : { *(.eh_frame_hdr) } - .eh_frame : { KEEP (*(.eh_frame)) } + .eh_frame : + { + /* The .eh_frame section from the crtend file contains the + end of eh_frame marker and it must be last. */ + KEEP (*(EXCLUDE_FILE (*crtend.o) .eh_frame)) + KEEP (*(.eh_frame)) + } .gcc_except_table : { *(.gcc_except_table) } .jcr : { KEEP (*(.jcr)) } .ctors : diff --git a/libgloss/mips/sde64.ld b/libgloss/mips/sde64.ld index 1bd11f6f8..e3a0f298b 100644 --- a/libgloss/mips/sde64.ld +++ b/libgloss/mips/sde64.ld @@ -59,7 +59,13 @@ SECTIONS _etext = .; .eh_frame_hdr : { *(.eh_frame_hdr) } - .eh_frame : { KEEP (*(.eh_frame)) } + .eh_frame : + { + /* The .eh_frame section from the crtend file contains the + end of eh_frame marker and it must be last. */ + KEEP (*(EXCLUDE_FILE (*crtend.o) .eh_frame)) + KEEP (*(.eh_frame)) + } .gcc_except_table : { *(.gcc_except_table) } .jcr : { KEEP (*(.jcr)) } .ctors : From a4e62e3a4c6799944e1f0cc03568722997b8379b Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Tue, 30 Apr 2019 11:52:29 +0200 Subject: [PATCH 367/475] Cygwin: update era and message locale data Signed-off-by: Corinna Vinschen --- winsup/cygwin/lc_era.h | 8 +- winsup/cygwin/lc_msg.h | 650 +++++++++++++++++++++-------------------- 2 files changed, 341 insertions(+), 317 deletions(-) diff --git a/winsup/cygwin/lc_era.h b/winsup/cygwin/lc_era.h index ef0fda694..8eb0b426a 100644 --- a/winsup/cygwin/lc_era.h +++ b/winsup/cygwin/lc_era.h @@ -1,5 +1,5 @@ /* This struct of LC_TIME ERA data has been generated by fetching locale - data from a Linux system using glibc-2.11-2.i686 on 2010-02-22. */ + data from a Linux system using glibc-2.28-27.fc29.x86_64 on 2019-04-30. */ struct lc_era_t { @@ -18,11 +18,13 @@ struct lc_era_t static struct lc_era_t lc_era[] = { + { "az_IR", L"\x202b%A %Oe %B %Oy\x060c \x0633\x0627\x0639\x0627\x062a %OH:%OM:%OS (%Z)\x202c", L"%Oy/%Om/%Od", L"\x202b%A %Oe %B %Oy\x060c %OH:%OM:%OS\x202c", L"%OH:%OM:%OS", L"", L"", L"", L"", L"", L"\x06f0\x06f0;\x06f0\x06f1;\x06f0\x06f2;\x06f0\x06f3;\x06f0\x06f4;\x06f0\x06f5;\x06f0\x06f6;\x06f0\x06f7;\x06f0\x06f8;\x06f0\x06f9;\x06f1\x06f0;\x06f1\x06f1;\x06f1\x06f2;\x06f1\x06f3;\x06f1\x06f4;\x06f1\x06f5;\x06f1\x06f6;\x06f1\x06f7;\x06f1\x06f8;\x06f1\x06f9;\x06f2\x06f0;\x06f2\x06f1;\x06f2\x06f2;\x06f2\x06f3;\x06f2\x06f4;\x06f2\x06f5;\x06f2\x06f6;\x06f2\x06f7;\x06f2\x06f8;\x06f2\x06f9;\x06f3\x06f0;\x06f3\x06f1;\x06f3\x06f2;\x06f3\x06f3;\x06f3\x06f4;\x06f3\x06f5;\x06f3\x06f6;\x06f3\x06f7;\x06f3\x06f8;\x06f3\x06f9;\x06f4\x06f0;\x06f4\x06f1;\x06f4\x06f2;\x06f4\x06f3;\x06f4\x06f4;\x06f4\x06f5;\x06f4\x06f6;\x06f4\x06f7;\x06f4\x06f8;\x06f4\x06f9;\x06f5\x06f0;\x06f5\x06f1;\x06f5\x06f2;\x06f5\x06f3;\x06f5\x06f4;\x06f5\x06f5;\x06f5\x06f6;\x06f5\x06f7;\x06f5\x06f8;\x06f5\x06f9;\x06f6\x06f0;\x06f6\x06f1;\x06f6\x06f2;\x06f6\x06f3;\x06f6\x06f4;\x06f6\x06f5;\x06f6\x06f6;\x06f6\x06f7;\x06f6\x06f8;\x06f6\x06f9;\x06f7\x06f0;\x06f7\x06f1;\x06f7\x06f2;\x06f7\x06f3;\x06f7\x06f4;\x06f7\x06f5;\x06f7\x06f6;\x06f7\x06f7;\x06f7\x06f8;\x06f7\x06f9;\x06f8\x06f0;\x06f8\x06f1;\x06f8\x06f2;\x06f8\x06f3;\x06f8\x06f4;\x06f8\x06f5;\x06f8\x06f6;\x06f8\x06f7;\x06f8\x06f8;\x06f8\x06f9;\x06f9\x06f0;\x06f9\x06f1;\x06f9\x06f2;\x06f9\x06f3;\x06f9\x06f4;\x06f9\x06f5;\x06f9\x06f6;\x06f9\x06f7;\x06f9\x06f8;\x06f9\x06f9" }, { "fa_IR", L"\x202b%A %Oe %B %Oy\x060c \x0633\x0627\x0639\x062a %OH:%OM:%OS (%Z)\x202c", L"%Oy/%Om/%Od", L"\x202b%A %Oe %B %Oy\x060c %OH:%OM:%OS\x202c", L"%OH:%OM:%OS", L"", L"", L"", L"", L"", L"\x06f0\x06f0;\x06f0\x06f1;\x06f0\x06f2;\x06f0\x06f3;\x06f0\x06f4;\x06f0\x06f5;\x06f0\x06f6;\x06f0\x06f7;\x06f0\x06f8;\x06f0\x06f9;\x06f1\x06f0;\x06f1\x06f1;\x06f1\x06f2;\x06f1\x06f3;\x06f1\x06f4;\x06f1\x06f5;\x06f1\x06f6;\x06f1\x06f7;\x06f1\x06f8;\x06f1\x06f9;\x06f2\x06f0;\x06f2\x06f1;\x06f2\x06f2;\x06f2\x06f3;\x06f2\x06f4;\x06f2\x06f5;\x06f2\x06f6;\x06f2\x06f7;\x06f2\x06f8;\x06f2\x06f9;\x06f3\x06f0;\x06f3\x06f1;\x06f3\x06f2;\x06f3\x06f3;\x06f3\x06f4;\x06f3\x06f5;\x06f3\x06f6;\x06f3\x06f7;\x06f3\x06f8;\x06f3\x06f9;\x06f4\x06f0;\x06f4\x06f1;\x06f4\x06f2;\x06f4\x06f3;\x06f4\x06f4;\x06f4\x06f5;\x06f4\x06f6;\x06f4\x06f7;\x06f4\x06f8;\x06f4\x06f9;\x06f5\x06f0;\x06f5\x06f1;\x06f5\x06f2;\x06f5\x06f3;\x06f5\x06f4;\x06f5\x06f5;\x06f5\x06f6;\x06f5\x06f7;\x06f5\x06f8;\x06f5\x06f9;\x06f6\x06f0;\x06f6\x06f1;\x06f6\x06f2;\x06f6\x06f3;\x06f6\x06f4;\x06f6\x06f5;\x06f6\x06f6;\x06f6\x06f7;\x06f6\x06f8;\x06f6\x06f9;\x06f7\x06f0;\x06f7\x06f1;\x06f7\x06f2;\x06f7\x06f3;\x06f7\x06f4;\x06f7\x06f5;\x06f7\x06f6;\x06f7\x06f7;\x06f7\x06f8;\x06f7\x06f9;\x06f8\x06f0;\x06f8\x06f1;\x06f8\x06f2;\x06f8\x06f3;\x06f8\x06f4;\x06f8\x06f5;\x06f8\x06f6;\x06f8\x06f7;\x06f8\x06f8;\x06f8\x06f9;\x06f9\x06f0;\x06f9\x06f1;\x06f9\x06f2;\x06f9\x06f3;\x06f9\x06f4;\x06f9\x06f5;\x06f9\x06f6;\x06f9\x06f7;\x06f9\x06f8;\x06f9\x06f9" }, - { "ja_JP", L"%Y\x5e74 %b %e\x65e5 %A %H:%M:%S %Z", L"%Y\x5e74%m\x6708%d\x65e5", L"%Y\x5e74%m\x6708%d\x65e5 %H\x6642%M\x5206%S\x79d2", L"%H\x6642%M\x5206%S\x79d2", L"%p%I\x6642%M\x5206%S\x79d2", L"+:2:1990/01/01:+*:\x5e73\x6210:%EC%Ey\x5e74;+:1:1989/01/08:1989/12/31:\x5e73\x6210:%EC\x5143\x5e74;+:2:1927/01/01:1989/01/07:\x662d\x548c:%EC%Ey\x5e74;+:1:1926/12/25:1926/12/31:\x662d\x548c:%EC\x5143\x5e74;+:2:1913/01/01:1926/12/24:\x5927\x6b63:%EC%Ey\x5e74;+:1:1912/07/30:1912/12/31:\x5927\x6b63:%EC\x5143\x5e74;+:6:1873/01/01:1912/07/29:\x660e\x6cbb:%EC%Ey\x5e74;+:1:0001/01/01:1872/12/31:\x897f\x66a6:%EC%Ey\x5e74;+:1:-0001/12/31:-*:\x7d00\x5143\x524d:%EC%Ey\x5e74", L"%EY%m\x6708%d\x65e5", L"%EY%m\x6708%d\x65e5 %H\x6642%M\x5206%S\x79d2", L"", L"\x3007;\x4e00;\x4e8c;\x4e09;\x56db;\x4e94;\x516d;\x4e03;\x516b;\x4e5d;\x5341;\x5341\x4e00;\x5341\x4e8c;\x5341\x4e09;\x5341\x56db;\x5341\x4e94;\x5341\x516d;\x5341\x4e03;\x5341\x516b;\x5341\x4e5d;\x4e8c\x5341;\x4e8c\x5341\x4e00;\x4e8c\x5341\x4e8c;\x4e8c\x5341\x4e09;\x4e8c\x5341\x56db;\x4e8c\x5341\x4e94;\x4e8c\x5341\x516d;\x4e8c\x5341\x4e03;\x4e8c\x5341\x516b;\x4e8c\x5341\x4e5d;\x4e09\x5341;\x4e09\x5341\x4e00;\x4e09\x5341\x4e8c;\x4e09\x5341\x4e09;\x4e09\x5341\x56db;\x4e09\x5341\x4e94;\x4e09\x5341\x516d;\x4e09\x5341\x4e03;\x4e09\x5341\x516b;\x4e09\x5341\x4e5d;\x56db\x5341;\x56db\x5341\x4e00;\x56db\x5341\x4e8c;\x56db\x5341\x4e09;\x56db\x5341\x56db;\x56db\x5341\x4e94;\x56db\x5341\x516d;\x56db\x5341\x4e03;\x56db\x5341\x516b;\x56db\x5341\x4e5d;\x4e94\x5341;\x4e94\x5341\x4e00;\x4e94\x5341\x4e8c;\x4e94\x5341\x4e09;\x4e94\x5341\x56db;\x4e94\x5341\x4e94;\x4e94\x5341\x516d;\x4e94\x5341\x4e03;\x4e94\x5341\x516b;\x4e94\x5341\x4e5d;\x516d\x5341;\x516d\x5341\x4e00;\x516d\x5341\x4e8c;\x516d\x5341\x4e09;\x516d\x5341\x56db;\x516d\x5341\x4e94;\x516d\x5341\x516d;\x516d\x5341\x4e03;\x516d\x5341\x516b;\x516d\x5341\x4e5d;\x4e03\x5341;\x4e03\x5341\x4e00;\x4e03\x5341\x4e8c;\x4e03\x5341\x4e09;\x4e03\x5341\x56db;\x4e03\x5341\x4e94;\x4e03\x5341\x516d;\x4e03\x5341\x4e03;\x4e03\x5341\x516b;\x4e03\x5341\x4e5d;\x516b\x5341;\x516b\x5341\x4e00;\x516b\x5341\x4e8c;\x516b\x5341\x4e09;\x516b\x5341\x56db;\x516b\x5341\x4e94;\x516b\x5341\x516d;\x516b\x5341\x4e03;\x516b\x5341\x516b;\x516b\x5341\x4e5d;\x4e5d\x5341;\x4e5d\x5341\x4e00;\x4e5d\x5341\x4e8c;\x4e5d\x5341\x4e09;\x4e5d\x5341\x56db;\x4e5d\x5341\x4e94;\x4e5d\x5341\x516d;\x4e5d\x5341\x4e03;\x4e5d\x5341\x516b;\x4e5d\x5341\x4e5d" }, + { "ja_JP", L"%Y\x5e74 %b %e\x65e5 %A %H:%M:%S %Z", L"%Y\x5e74%m\x6708%d\x65e5", L"%Y\x5e74%m\x6708%d\x65e5 %H\x6642%M\x5206%S\x79d2", L"%H\x6642%M\x5206%S\x79d2", L"%p%I\x6642%M\x5206%S\x79d2", L"+:2:2020/01/01:+*:\x4ee4\x548c:%EC%Ey\x5e74;+:1:2019/05/01:2019/12/31:\x4ee4\x548c:%EC\x5143\x5e74;+:2:1990/01/01:2019/04/30:\x5e73\x6210:%EC%Ey\x5e74;+:1:1989/01/08:1989/12/31:\x5e73\x6210:%EC\x5143\x5e74;+:2:1927/01/01:1989/01/07:\x662d\x548c:%EC%Ey\x5e74;+:1:1926/12/25:1926/12/31:\x662d\x548c:%EC\x5143\x5e74;+:2:1913/01/01:1926/12/24:\x5927\x6b63:%EC%Ey\x5e74;+:2:1912/07/30:1912/12/31:\x5927\x6b63:%EC\x5143\x5e74;+:6:1873/01/01:1912/07/29:\x660e\x6cbb:%EC%Ey\x5e74;+:1:0001/01/01:1872/12/31:\x897f\x66a6:%EC%Ey\x5e74;+:1:-0001/12/31:-*:\x7d00\x5143\x524d:%EC%Ey\x5e74", L"%EY%m\x6708%d\x65e5", L"%EY%m\x6708%d\x65e5 %H\x6642%M\x5206%S\x79d2", L"", L"\x3007;\x4e00;\x4e8c;\x4e09;\x56db;\x4e94;\x516d;\x4e03;\x516b;\x4e5d;\x5341;\x5341\x4e00;\x5341\x4e8c;\x5341\x4e09;\x5341\x56db;\x5341\x4e94;\x5341\x516d;\x5341\x4e03;\x5341\x516b;\x5341\x4e5d;\x4e8c\x5341;\x4e8c\x5341\x4e00;\x4e8c\x5341\x4e8c;\x4e8c\x5341\x4e09;\x4e8c\x5341\x56db;\x4e8c\x5341\x4e94;\x4e8c\x5341\x516d;\x4e8c\x5341\x4e03;\x4e8c\x5341\x516b;\x4e8c\x5341\x4e5d;\x4e09\x5341;\x4e09\x5341\x4e00;\x4e09\x5341\x4e8c;\x4e09\x5341\x4e09;\x4e09\x5341\x56db;\x4e09\x5341\x4e94;\x4e09\x5341\x516d;\x4e09\x5341\x4e03;\x4e09\x5341\x516b;\x4e09\x5341\x4e5d;\x56db\x5341;\x56db\x5341\x4e00;\x56db\x5341\x4e8c;\x56db\x5341\x4e09;\x56db\x5341\x56db;\x56db\x5341\x4e94;\x56db\x5341\x516d;\x56db\x5341\x4e03;\x56db\x5341\x516b;\x56db\x5341\x4e5d;\x4e94\x5341;\x4e94\x5341\x4e00;\x4e94\x5341\x4e8c;\x4e94\x5341\x4e09;\x4e94\x5341\x56db;\x4e94\x5341\x4e94;\x4e94\x5341\x516d;\x4e94\x5341\x4e03;\x4e94\x5341\x516b;\x4e94\x5341\x4e5d;\x516d\x5341;\x516d\x5341\x4e00;\x516d\x5341\x4e8c;\x516d\x5341\x4e09;\x516d\x5341\x56db;\x516d\x5341\x4e94;\x516d\x5341\x516d;\x516d\x5341\x4e03;\x516d\x5341\x516b;\x516d\x5341\x4e5d;\x4e03\x5341;\x4e03\x5341\x4e00;\x4e03\x5341\x4e8c;\x4e03\x5341\x4e09;\x4e03\x5341\x56db;\x4e03\x5341\x4e94;\x4e03\x5341\x516d;\x4e03\x5341\x4e03;\x4e03\x5341\x516b;\x4e03\x5341\x4e5d;\x516b\x5341;\x516b\x5341\x4e00;\x516b\x5341\x4e8c;\x516b\x5341\x4e09;\x516b\x5341\x56db;\x516b\x5341\x4e94;\x516b\x5341\x516d;\x516b\x5341\x4e03;\x516b\x5341\x516b;\x516b\x5341\x4e5d;\x4e5d\x5341;\x4e5d\x5341\x4e00;\x4e5d\x5341\x4e8c;\x4e5d\x5341\x4e09;\x4e5d\x5341\x56db;\x4e5d\x5341\x4e94;\x4e5d\x5341\x516d;\x4e5d\x5341\x4e03;\x4e5d\x5341\x516b;\x4e5d\x5341\x4e5d;%EY%m\x6708%d\x65e5 %H\x6642%M\x5206%S\x79d2" }, { "lo_LA", L"%a %e %b %Ey %H:%M:%S %Z", L"%d/%m/%Ey", L"%a %e %b %Ey, %H:%M:%S", L"%H:%M:%S", L"%I:%M:%S %p", L"+:1:-543/01/01:+*:\x0e9e.\x0eaa.:%EC %Ey", L"%e %b %Ey", L"\x0ea7\x0eb1\x0e99%A\x0e97\x0eb5\x0ec8 %e %B %EC %Ey, %H.%M.%S \x0e99.", L"%H.%M.%S \x0e99.", L"" }, + { "lzh_TW", L"\x516c\x66c6 %C%Oy\x5e74 %B %Oe\x65e5 %A %OH\x6642%OM\x5206%OS\x79d2", L"%OC%Oy\x5e74%B%Od\x65e5", L"%OC%Oy\x5e74%B%Od\x65e5 (%A) %OH\x6642%OM\x5206%OS\x79d2", L"%OH\x6642%OM\x5206%OS\x79d2", L"%p %OI\x6642%OM\x5206%OS\x79d2", L"", L"", L"", L"", L"\x3007;\x4e00;\x4e8c;\x4e09;\x56db;\x4e94;\x516d;\x4e03;\x516b;\x4e5d;\x5341;\x5341\x4e00;\x5341\x4e8c;\x5341\x4e09;\x5341\x56db;\x5341\x4e94;\x5341\x516d;\x5341\x4e03;\x5341\x516b;\x5341\x4e5d;\x5eff;\x5eff\x4e00;\x5eff\x4e8c;\x5eff\x4e09;\x5eff\x56db;\x5eff\x4e94;\x5eff\x516d;\x5eff\x4e03;\x5eff\x516b;\x5eff\x4e5d;\x5345;\x5345\x4e00" }, { "my_MM", L"%a %b %e %H:%M:%S %Z %Y", L"%OC%Oy %b %Od %A", L"%OC%Oy %b %Od %A %OI:%OM:%OS %Op %Z", L"%OI:%OM:%OS %p", L"%OI:%OM:%OS %p", L"", L"", L"", L"", L"\x1040\x1040;\x1040\x1041;\x1040\x1042;\x1040\x1043;\x1040\x1044;\x1040\x1045;\x1040\x1046;\x1040\x1047;\x1040\x1048;\x1040\x1049;\x1041\x1040;\x1041\x1041;\x1041\x1042;\x1041\x1043;\x1041\x1044;\x1041\x1045;\x1041\x1046;\x1041\x1047;\x1041\x1048;\x1041\x1049;\x1042\x1040;\x1042\x1041;\x1042\x1042;\x1042\x1043;\x1042\x1044;\x1042\x1045;\x1042\x1046;\x1042\x1047;\x1042\x1048;\x1042\x1049;\x1043\x1040;\x1043\x1041;\x1043\x1042;\x1043\x1043;\x1043\x1044;\x1043\x1045;\x1043\x1046;\x1043\x1047;\x1043\x1048;\x1043\x1049;\x1044\x1040;\x1044\x1041;\x1044\x1042;\x1044\x1043;\x1044\x1044;\x1044\x1045;\x1044\x1046;\x1044\x1047;\x1044\x1048;\x1044\x1049;\x1045\x1040;\x1045\x1041;\x1045\x1042;\x1045\x1043;\x1045\x1044;\x1045\x1045;\x1045\x1046;\x1045\x1047;\x1045\x1048;\x1045\x1049;\x1046\x1040;\x1046\x1041;\x1046\x1042;\x1046\x1043;\x1046\x1044;\x1046\x1045;\x1046\x1046;\x1046\x1047;\x1046\x1048;\x1046\x1049;\x1047\x1040;\x1047\x1041;\x1047\x1042;\x1047\x1043;\x1047\x1044;\x1047\x1045;\x1047\x1046;\x1047\x1047;\x1047\x1048;\x1047\x1049;\x1048\x1040;\x1048\x1041;\x1048\x1042;\x1048\x1043;\x1048\x1044;\x1048\x1045;\x1048\x1046;\x1048\x1047;\x1048\x1048;\x1048\x1049;\x1049\x1040;\x1049\x1041;\x1049\x1042;\x1049\x1043;\x1049\x1044;\x1049\x1045;\x1049\x1046;\x1049\x1047;\x1049\x1048;\x1049\x1049" }, { "or_IN", L"%a %b %e %H:%M:%S %Z %Y", L"%Od-%Om-%Oy", L"%Oe %B %Oy %OI:%OM:%OS %p %Z", L"%OI:%OM:%OS %p", L"%OI:%OM:%OS %p", L"", L"", L"", L"", L"\x0b66;\x0b67;\x0b68;\x0b69;\x0b6a;\x0b6b;\x0b6c;\x0b6d;\x0b6e;\x0b6f;\x0b67\x0b66;\x0b67\x0b67;\x0b67\x0b68;\x0b67\x0b69;\x0b67\x0b6a;\x0b67\x0b6b;\x0b67\x0b6c;\x0b67\x0b6d;\x0b67\x0b6e;\x0b67\x0b6f;\x0b68\x0b66;\x0b68\x0b67;\x0b68\x0b68;\x0b68\x0b69;\x0b68\x0b6a;\x0b68\x0b6b;\x0b68\x0b6c;\x0b68\x0b6d;\x0b68\x0b6e;\x0b68\x0b6f;\x0b69\x0b66;\x0b69\x0b67;\x0b69\x0b68;\x0b69\x0b69;\x0b69\x0b6a;\x0b69\x0b6b;\x0b69\x0b6c;\x0b69\x0b6d;\x0b69\x0b6e;\x0b69\x0b6f;\x0b6a\x0b66;\x0b6a\x0b67;\x0b6a\x0b68;\x0b6a\x0b69;\x0b6a\x0b6a;\x0b6a\x0b6b;\x0b6a\x0b6c;\x0b6a\x0b6d;\x0b6a\x0b6e;\x0b6a\x0b6f;\x0b6b\x0b66;\x0b6b\x0b67;\x0b6b\x0b68;\x0b6b\x0b69;\x0b6b\x0b6a;\x0b6b\x0b6b;\x0b6b\x0b6c;\x0b6b\x0b6d;\x0b6b\x0b6e;\x0b6b\x0b6f;\x0b6c\x0b66;\x0b6c\x0b67;\x0b6c\x0b68;\x0b6c\x0b69;\x0b6c\x0b6a;\x0b6c\x0b6b;\x0b6c\x0b6c;\x0b6c\x0b6d;\x0b6c\x0b6e;\x0b6c\x0b6f;\x0b6d\x0b66;\x0b6d\x0b67;\x0b6d\x0b68;\x0b6d\x0b69;\x0b6d\x0b6a;\x0b6d\x0b6b;\x0b6d\x0b6c;\x0b6d\x0b6d;\x0b6d\x0b6e;\x0b6d\x0b6f;\x0b6e\x0b66;\x0b6e\x0b67;\x0b6e\x0b68;\x0b6e\x0b69;\x0b6e\x0b6a;\x0b6e\x0b6b;\x0b6e\x0b6c;\x0b6e\x0b6d;\x0b6e\x0b6e;\x0b6e\x0b6f;\x0b6f\x0b66;\x0b6f\x0b67;\x0b6f\x0b68;\x0b6f\x0b69;\x0b6f\x0b6a;\x0b6f\x0b6b;\x0b6f\x0b6c;\x0b6f\x0b6d;\x0b6f\x0b6e;\x0b6f\x0b6f" }, + { "shn_MM", L"%a %b %e %H:%M:%S %Z %Y", L"%OC%Oy %b %Od %A", L"%OC%Oy %b %Od %A %OI:%OM:%OS %Op %Z", L"%OH:%OM:%OS %p", L"%OI:%OM:%OS %p", L"", L"", L"", L"", L"\x1090\x1090;\x1090\x1091;\x1090\x1092;\x1090\x1093;\x1090\x1094;\x1090\x1095;\x1090\x1096;\x1090\x1097;\x1090\x1098;\x1090\x1099;\x1091\x1090;\x1091\x1091;\x1091\x1092;\x1091\x1093;\x1091\x1094;\x1091\x1095;\x1091\x1096;\x1091\x1097;\x1091\x1098;\x1091\x1099;\x1092\x1090;\x1092\x1091;\x1092\x1092;\x1092\x1093;\x1092\x1094;\x1092\x1095;\x1092\x1096;\x1092\x1097;\x1092\x1098;\x1092\x1099;\x1093\x1090;\x1093\x1091;\x1093\x1092;\x1093\x1093;\x1093\x1094;\x1093\x1095;\x1093\x1096;\x1093\x1097;\x1093\x1098;\x1093\x1099;\x1094\x1090;\x1094\x1091;\x1094\x1092;\x1094\x1093;\x1094\x1094;\x1094\x1095;\x1094\x1096;\x1094\x1097;\x1094\x1098;\x1094\x1099;\x1095\x1090;\x1095\x1091;\x1095\x1092;\x1095\x1093;\x1095\x1094;\x1095\x1095;\x1095\x1096;\x1095\x1097;\x1095\x1098;\x1095\x1099;\x1096\x1090;\x1096\x1091;\x1096\x1092;\x1096\x1093;\x1096\x1094;\x1096\x1095;\x1096\x1096;\x1096\x1097;\x1096\x1098;\x1096\x1099;\x1097\x1090;\x1097\x1091;\x1097\x1092;\x1097\x1093;\x1097\x1094;\x1097\x1095;\x1097\x1096;\x1097\x1097;\x1097\x1098;\x1097\x1099;\x1098\x1090;\x1098\x1091;\x1098\x1092;\x1098\x1093;\x1098\x1094;\x1098\x1095;\x1098\x1096;\x1098\x1097;\x1098\x1098;\x1098\x1099;\x1099\x1090;\x1099\x1091;\x1099\x1092;\x1099\x1093;\x1099\x1094;\x1099\x1095;\x1099\x1096;\x1099\x1097;\x1099\x1098;\x1099\x1099" }, { "th_TH", L"%a %e %b %Ey %H:%M:%S %Z", L"%d/%m/%Ey", L"%a %e %b %Ey, %H:%M:%S", L"%H:%M:%S", L"%I:%M:%S %p", L"+:1:-543/01/01:+*:\x0e1e.\x0e28.:%EC %Ey", L"%e %b %Ey", L"\x0e27\x0e31\x0e19%A\x0e17\x0e35\x0e48 %e %B %EC %Ey, %H.%M.%S \x0e19.", L"%H.%M.%S \x0e19.", L"" }, - { "uk_UA", L"%A, %-d %Om %Y %X %z", L"%d.%m.%y", L"%a, %d-%b-%Y %X %z", L"%T", L"", L"", L"", L"", L"", L"0;\x0441\x0456\x0447\x043d\x044f;\x043b\x044e\x0442\x043e\x0433\x043e;\x0431\x0435\x0440\x0435\x0437\x043d\x044f;\x043a\x0432\x0456\x0442\x043d\x044f;\x0442\x0440\x0430\x0432\x043d\x044f;\x0447\x0435\x0440\x0432\x043d\x044f;\x043b\x0438\x043f\x043d\x044f;\x0441\x0435\x0440\x043f\x043d\x044f;\x0432\x0435\x0440\x0435\x0441\x043d\x044f;\x0436\x043e\x0432\x0442\x043d\x044f;\x043b\x0438\x0441\x0442\x043e\x043f\x0430\x0434\x0430;\x0433\x0440\x0443\x0434\x043d\x044f" }, }; diff --git a/winsup/cygwin/lc_msg.h b/winsup/cygwin/lc_msg.h index 15c970711..7bc9a20a6 100644 --- a/winsup/cygwin/lc_msg.h +++ b/winsup/cygwin/lc_msg.h @@ -1,5 +1,5 @@ /* This struct of LC_MESSAGES data has been generated by fetching locale - data from a Linux system using glibc-2.21-8.fc22.x86_64 on 2015-11-17. */ + data from a Linux system using glibc-2.28-27.fc29.x86_64 on 2019-04-30. */ struct lc_msg_t { @@ -12,317 +12,339 @@ struct lc_msg_t static struct lc_msg_t lc_msg[] = { - { "aa_DJ", L"^[oOyY].*", L"^[mnMN].*", L"", L"" }, - { "aa_ER", L"^[yY].*", L"^[mnMN].*", L"", L"" }, - { "aa_ER@saaho", L"^[yY].*", L"^[mnMN].*", L"", L"" }, - { "aa_ET", L"^[yY].*", L"^[mnMN].*", L"", L"" }, - { "af_ZA", L"^[jJyY]", L"^[nN]", L"", L"" }, - { "ak_GH", L"^[yY].*", L"^[dDnN].*", L"Yiw", L"Daabi" }, - { "am_ET", L"^[yY].*", L"^[nN].*", L"", L"" }, - { "an_ES", L"^[sSyY].*", L"^[nN].*", L"", L"" }, - { "anp_IN", L"^[\x0939\x0935yY]", L"^[\x0928\x0907nN]", L"", L"" }, - { "ar_AE", L"^[\x0646yY].*", L"^[\x0644nN].*", L"\x0646\x0639\x0645", L"\x0644\x0627" }, - { "ar_BH", L"^[\x0646yY].*", L"^[\x0644nN].*", L"\x0646\x0639\x0645", L"\x0644\x0627" }, - { "ar_DZ", L"^[\x0646yY].*", L"^[\x0644nN].*", L"\x0646\x0639\x0645", L"\x0644\x0627" }, - { "ar_EG", L"^[\x0646yY].*", L"^[\x0644nN].*", L"\x0646\x0639\x0645", L"\x0644\x0627" }, - { "ar_IN", L"^[\x0646yY].*", L"^[\x0644nN].*", L"\x0646\x0639\x0645", L"\x0644\x0627" }, - { "ar_IQ", L"^[\x0646yY].*", L"^[\x0644nN].*", L"\x0646\x0639\x0645", L"\x0644\x0627" }, - { "ar_JO", L"^[\x0646yY].*", L"^[\x0644nN].*", L"\x0646\x0639\x0645", L"\x0644\x0627" }, - { "ar_KW", L"^[\x0646yY].*", L"^[\x0644nN].*", L"\x0646\x0639\x0645", L"\x0644\x0627" }, - { "ar_LB", L"^[\x0646yY].*", L"^[\x0644nN].*", L"\x0646\x0639\x0645", L"\x0644\x0627" }, - { "ar_LY", L"^[\x0646yY].*", L"^[\x0644nN].*", L"\x0646\x0639\x0645", L"\x0644\x0627" }, - { "ar_MA", L"^[\x0646yY].*", L"^[\x0644nN].*", L"\x0646\x0639\x0645", L"\x0644\x0627" }, - { "ar_OM", L"^[\x0646yY].*", L"^[\x0644nN].*", L"\x0646\x0639\x0645", L"\x0644\x0627" }, - { "ar_QA", L"^[\x0646yY].*", L"^[\x0644nN].*", L"\x0646\x0639\x0645", L"\x0644\x0627" }, - { "ar_SA", L"^[\x0646yY].*", L"^[\x0644nN].*", L"\x0646\x0639\x0645", L"\x0644\x0627" }, - { "ar_SD", L"^[\x0646yY].*", L"^[\x0644nN].*", L"\x0646\x0639\x0645", L"\x0644\x0627" }, - { "ar_SS", L"^[\x0646yY].*", L"^[\x0644nN].*", L"\x0646\x0639\x0645", L"\x0644\x0627" }, - { "ar_SY", L"^[\x0646yY].*", L"^[\x0644nN].*", L"\x0646\x0639\x0645", L"\x0644\x0627" }, - { "ar_TN", L"^[\x0646yY].*", L"^[\x0644nN].*", L"\x0646\x0639\x0645", L"\x0644\x0627" }, - { "ar_YE", L"^[\x0646yY].*", L"^[\x0644nN].*", L"\x0646\x0639\x0645", L"\x0644\x0627" }, - { "as_IN", L"^[yY\x09b9].*", L"^[nN\x09a8].*", L"\x09b9\x09df", L"\x09a8\x09b9\x09df" }, - { "ast_ES", L"^[sSyY].*", L"^[nN].*", L"", L"" }, - { "ayc_PE", L"^[uUsSyY].*", L"^[jJnN].*", L"Ukhamawa", L"Janiwa" }, - { "az_AZ", L"^[Bb].*", L"^[YyNn].*", L"b\x0259li", L"yox" }, - { "be_BY", L"^[\x0422\x0442Yy].*", L"^[\x041d\x043dNn].*", L"", L"" }, - { "be_BY@latin", L"^[TtYy].*", L"^[Nn].*", L"", L"" }, - { "bem_ZM", L"^[yYeE].*", L"^[nNaA].*", L"", L"" }, - { "ber_DZ", L"^[Bb].*", L"^[YyNn].*", L"b\x0259li", L"yox" }, - { "ber_MA", L"^[Bb].*", L"^[YyNn].*", L"b\x0259li", L"yox" }, - { "bg_BG", L"^[+1\x0414\x0434\x0044\x0064YyOo].*", L"^[-0\x041d\x043dNnKk].*", L"", L"" }, - { "bho_IN", L"^[yY].*", L"^[nN].*", L"", L"" }, - { "bn_BD", L"^[\x09b9\x09cd\x09af\x09be\x0981yY]", L"^[\x09a8\x09benN]", L"\x09b9\x09cd\x09af\x09be\x0981", L"\x09a8\x09be" }, - { "bn_IN", L"^[\x09b9\x09cd\x09af\x09be\x0981yY]", L"^[\x09a8\x09benN]", L"\x09b9\x09cd\x09af\x09be\x0981", L"\x09a8\x09be" }, - { "bo_CN", L"^[\x0f68Yy].*", L"^[\x0f58Nn].*", L"\x0f68\x0f72\x0f53", L"\x0f58\x0f7a\x0f53" }, - { "bo_IN", L"^[\x0f68Yy].*", L"^[\x0f58Nn].*", L"\x0f68\x0f72\x0f53", L"\x0f58\x0f7a\x0f53" }, - { "br_FR", L"^[oOyY].*", L"^[nN].*", L"", L"" }, - { "br_FR@euro", L"^[oOyY].*", L"^[nN].*", L"", L"" }, - { "brx_IN", L"^(\x0928\x0902\x0917\x094c|[yY])", L"^(\x0928\x0919\x093e|[nN])", L"", L"" }, - { "bs_BA", L"^[dDyY]*.", L"^[nN]*.", L"", L"" }, - { "byn_ER", L"^[yY].*", L"^[nN].*", L"", L"" }, - { "ca_AD", L"^[sSyY].*", L"^[nN].*", L"", L"" }, - { "ca_ES", L"^[sSyY].*", L"^[nN].*", L"", L"" }, - { "ca_ES@euro", L"^[sSyY].*", L"^[nN].*", L"", L"" }, - { "ca_FR", L"^[sSyY].*", L"^[nN].*", L"", L"" }, - { "ca_IT", L"^[sSyY].*", L"^[nN].*", L"", L"" }, - { "ce_RU", L"^[\x0414\x0434Yy].*", L"^[\x041c\x043cNn].*", L"", L"" }, - { "cmn_TW", L"^[yY\x662f]", L"^[nN\x4e0d\x5426]", L"", L"" }, - { "crh_UA", L"^[yYeE]", L"^[nNhH]", L"ebet", L"hay\x0131r" }, - { "cs_CZ", L"^[aAyY].*", L"^[nN].*", L"ano", L"ne" }, - { "csb_PL", L"^[JjTtYy].*", L"^[nN].*", L"", L"" }, - { "cv_RU", L"^[yY].*", L"^[nN].*", L"", L"" }, - { "cy_GB", L"^[iItTyY].*", L"^[nN].*", L"ie", L"na" }, - { "da_DK", L"^[1JjYy].*", L"^[0Nn].*", L"", L"" }, - { "de_AT", L"^[jJyY].*", L"^[nN].*", L"", L"" }, - { "de_AT@euro", L"^[jJyY].*", L"^[nN].*", L"", L"" }, - { "de_BE", L"^[jJyY].*", L"^[nN].*", L"", L"" }, - { "de_BE@euro", L"^[jJyY].*", L"^[nN].*", L"", L"" }, - { "de_CH", L"^[jJyY].*", L"^[nN].*", L"", L"" }, - { "de_DE", L"^[jJyY].*", L"^[nN].*", L"", L"" }, - { "de_DE@euro", L"^[jJyY].*", L"^[nN].*", L"", L"" }, - { "de_LU", L"^[jJyY].*", L"^[nN].*", L"", L"" }, - { "de_LU@euro", L"^[jJyY].*", L"^[nN].*", L"", L"" }, - { "doi_IN", L"^(\x0911\x0939|[yY])", L"^(\x0928\x093e|[nN])", L"", L"" }, - { "dv_MV", L"^[yY].*", L"^[nN].*", L"", L"" }, - { "dz_BT", L"^[\x0f68Yy].*", L"^[\x0f58Nn].*", L"\x0f68\x0f72\x0f53", L"\x0f58\x0f7a\x0f53" }, - { "el_CY", L"^[\x03bd\x039dyY].*", L"^[\x03bf\x039fnN].*", L"", L"" }, - { "el_GR", L"^[\x03bd\x039dyY].*", L"^[\x03bf\x039fnN].*", L"", L"" }, - { "en_AG", L"^[yY].*", L"^[nN].*", L"", L"" }, - { "en_AU", L"^[yY].*", L"^[nN].*", L"", L"" }, - { "en_BW", L"^[yY]", L"^[nN]", L"", L"" }, - { "en_CA", L"^[yYoO].*", L"^[nN].*", L"Yes", L"No" }, - { "en_DK", L"^[1JjsSyYoO].*", L"^[0nN].*", L"", L"" }, - { "en_GB", L"^[yY].*", L"^[nN].*", L"", L"" }, - { "en_HK", L"^[yY]", L"^[nN]", L"Yes", L"No" }, - { "en_IE", L"^[yY].*", L"^[nN].*", L"", L"" }, - { "en_IE@euro", L"^[yY].*", L"^[nN].*", L"", L"" }, - { "en_IN", L"^[yY]", L"^[nN]", L"Yes", L"No" }, - { "en_NG", L"^[yY]", L"^[nN]", L"", L"" }, - { "en_NZ", L"^[yY].*", L"^[nN].*", L"", L"" }, - { "en_PH", L"^[yY]", L"^[nN]", L"Yes", L"No" }, - { "en_SG", L"^[yY]", L"^[nN]", L"Yes", L"No" }, - { "en_US", L"^[yY].*", L"^[nN].*", L"Yes", L"No" }, - { "en_ZA", L"^[yY]", L"^[nN]", L"", L"" }, - { "en_ZM", L"^[yYeE].*", L"^[nNaA].*", L"", L"" }, - { "en_ZW", L"^[yY]", L"^[nN]", L"", L"" }, - { "es_AR", L"^[sSyY].*", L"^[nN].*", L"Si", L"No" }, - { "es_BO", L"^[sSyY].*", L"^[nN].*", L"Si", L"No" }, - { "es_CL", L"^[sSyY].*", L"^[nN].*", L"Si", L"No" }, - { "es_CO", L"^[sSyY].*", L"^[nN].*", L"Si", L"No" }, - { "es_CR", L"^[sSyY].*", L"^[nN].*", L"Si", L"No" }, - { "es_CU", L"^[sSyY].*", L"^[nN].*", L"Si", L"No" }, - { "es_DO", L"^[sSyY].*", L"^[nN].*", L"Si", L"No" }, - { "es_EC", L"^[sSyY].*", L"^[nN].*", L"Si", L"No" }, - { "es_ES", L"^[sSyY].*", L"^[nN].*", L"Si", L"No" }, - { "es_ES@euro", L"^[sSyY].*", L"^[nN].*", L"Si", L"No" }, - { "es_GT", L"^[sSyY].*", L"^[nN].*", L"Si", L"No" }, - { "es_HN", L"^[sSyY].*", L"^[nN].*", L"Si", L"No" }, - { "es_MX", L"^[sSyY].*", L"^[nN].*", L"Si", L"No" }, - { "es_NI", L"^[sSyY].*", L"^[nN].*", L"Si", L"No" }, - { "es_PA", L"^[sSyY].*", L"^[nN].*", L"Si", L"No" }, - { "es_PE", L"^[sSyY].*", L"^[nN].*", L"Si", L"No" }, - { "es_PR", L"^[sSyY].*", L"^[nN].*", L"Si", L"No" }, - { "es_PY", L"^[sSyY].*", L"^[nN].*", L"Si", L"No" }, - { "es_SV", L"^[sSyY].*", L"^[nN].*", L"Si", L"No" }, - { "es_US", L"^[sSyY].*", L"^[nN].*", L"", L"" }, - { "es_UY", L"^[sSyY].*", L"^[nN].*", L"Si", L"No" }, - { "es_VE", L"^[sSyY].*", L"^[nN].*", L"Si", L"No" }, - { "et_EE", L"^[JjYy].*", L"^[EeNn].*", L"", L"" }, - { "eu_ES", L"^[bBsSyY].*", L"^[eEnN].*", L"", L"" }, - { "eu_ES@euro", L"^[bBsSyY].*", L"^[eEnN].*", L"", L"" }, - { "fa_IR", L"^[yY\x0622\x0628Hf].*", L"^[nN\x062e\x0646ok].*", L"", L"" }, - { "ff_SN", L"^[yYeE].*", L"^[nNaA].*", L"", L"" }, - { "fi_FI", L"^[KkYy].*", L"^[EeNn].*", L"Kyll\x00e4", L"Ei" }, - { "fi_FI@euro", L"^[KkYy].*", L"^[EeNn].*", L"Kyll\x00e4", L"Ei" }, - { "fil_PH", L"[oOyY].*", L"[hHnN].*", L"oo", L"hindi" }, - { "fo_FO", L"^[JjYy].*", L"^[Nn].*", L"", L"" }, - { "fr_BE", L"^[oOjJyY1].*", L"^[nN0].*", L"", L"" }, - { "fr_BE@euro", L"^[oOjJyY1].*", L"^[nN0].*", L"", L"" }, - { "fr_CA", L"^[oOyY].*", L"^[nN].*", L"", L"" }, - { "fr_CH", L"^[OojJsSyY].*", L"^[nN].*", L"", L"" }, - { "fr_FR", L"^[oOyY].*", L"^[nN].*", L"", L"" }, - { "fr_FR@euro", L"^[oOyY].*", L"^[nN].*", L"", L"" }, - { "fr_LU", L"^[oOyY].*", L"^[nN].*", L"", L"" }, - { "fr_LU@euro", L"^[oOyY].*", L"^[nN].*", L"", L"" }, - { "fur_IT", L"^[sSjJoOyY].*", L"^[nN].*", L"", L"" }, - { "fy_DE", L"^[jJyY].*", L"^[nN].*", L"", L"" }, - { "fy_NL", L"^[jJyY].*", L"^[nN].*", L"", L"" }, - { "ga_IE", L"^[tTyY].*", L"^[nN].*", L"", L"" }, - { "ga_IE@euro", L"^[tTyY].*", L"^[nN].*", L"", L"" }, - { "gd_GB", L"^[tTyY].*", L"^[cCnN].*", L"", L"" }, - { "gez_ER", L"^[yY].*", L"^[nN].*", L"", L"" }, - { "gez_ER@abegede", L"^[yY].*", L"^[nN].*", L"", L"" }, - { "gez_ET", L"^[yY].*", L"^[nN].*", L"", L"" }, - { "gez_ET@abegede", L"^[yY].*", L"^[nN].*", L"", L"" }, - { "gl_ES", L"^[sSyY].*", L"^[nN].*", L"", L"" }, - { "gl_ES@euro", L"^[sSyY].*", L"^[nN].*", L"", L"" }, - { "gu_IN", L"^[yY\x0ab9]", L"^[nN\x0aa8]", L"", L"" }, - { "gv_GB", L"^[yY].*", L"^[nN].*", L"", L"" }, - { "ha_NG", L"^[TtiIYy].*", L"^[bBaAnN].*", L"Toh", L"Babu" }, - { "hak_TW", L"^[yY\x4fc2]", L"^[nN\x6bcb]", L"", L"" }, - { "he_IL", L"^[Yy\x05db].*", L"^[Nn\x05dc].*", L"", L"" }, - { "hi_IN", L"^[yY].*", L"^[nN].*", L"", L"" }, - { "hne_IN", L"^[\x0939\x0935yY]", L"^[\x0928\x0907nN]", L"\x0939\x0935", L"\x0928\x0907" }, - { "hr_HR", L"^[dDyY].*", L"^[nN].*", L"", L"" }, - { "hsb_DE", L"^[hHyY].*", L"^[nN].*", L"haj", L"n\x011b" }, - { "ht_HT", L"^[wWoOyY].*", L"^[nN].*", L"Wi", L"Non" }, - { "hu_HU", L"^[IiYy].*", L"^[nN].*", L"", L"" }, - { "hy_AM", L"^[yYsS\x0561\x0531]", L"^[nN\x0578\x0548]", L"\x0561\x0575\x0578", L"\x0578\x0579" }, - { "ia_FR", L"^[sSyY].*", L"^[nN].*", L"Si", L"No" }, - { "id_ID", L"^[yY].*", L"^[tTnN].*", L"", L"" }, - { "ig_NG", L"^[EeIiYy].*", L"^[0MmNn].*", L"Ee", L"Mba" }, - { "ik_CA", L"[yYiIaA].*", L"[nNqQ].*", L"aa", L"qa\x00f1\x0061\x0061" }, - { "is_IS", L"^[jJyY].*", L"^[nN].*", L"", L"" }, - { "it_CH", L"^[sSjJoOyY].*", L"^[nN].*", L"", L"" }, - { "it_IT", L"^[sSyY].*", L"^[nN].*", L"", L"" }, - { "it_IT@euro", L"^[sSyY].*", L"^[nN].*", L"", L"" }, - { "iu_CA", L"[yYsS].*", L"[nN].*", L"", L"" }, - { "iw_IL", L"^[Yy\x05db].*", L"^[Nn\x05dc].*", L"", L"" }, - { "ja_JP", L"^([yY\xff59\xff39]|\x306f\x3044|\x30cf\x30a4)", L"^([nN\xff4e\xff2e]|\x3044\x3044\x3048|\x30a4\x30a4\x30a8)", L"\x306f\x3044", L"\x3044\x3044\x3048" }, - { "ka_GE", L"^[1yYkKxX\x10ee].*", L"^[0nNaA\x10d0].*", L"", L"" }, - { "kk_KZ", L"^[\x0418\x0438Yy].*", L"^[\x0416\x0436Nn].*", L"", L"" }, - { "kl_GL", L"^[JjYyAa].*", L"^[Nn].*", L"", L"" }, - { "km_KH", L"^[yY]([eE][sS])?", L"^[nN][oO]?", L"yes:YES:y:Y", L"no:NO:n:N" }, - { "kn_IN", L"^[yY].*", L"^[nN].*", L"", L"" }, - { "ko_KR", L"^[yY\xc608]", L"^[nN\xc544]", L"", L"\xc544\xb2c8\xc624" }, - { "kok_IN", L"^(\x0939\x092f|[yY])", L"^(\x0928\x094d\x0939\x0940|[nN])", L"", L"" }, - { "ks_IN", L"^[\x0622yY].*", L"^[\x0646nN].*", L"\x0622", L"\x0646\x0639" }, - { "ks_IN@devanagari", L"^[yY].*", L"^[nN].*", L"", L"" }, - { "ku_TR", L"^[eEdDyY].*", L"^[nN].*", L"er\x00ea", L"n\x00e2" }, - { "kw_GB", L"^[eEyY].*", L"^[nN].*", L"", L"" }, - { "ky_KG", L"^[\x041e\x043eYy].*", L"^[\x0416\x0436Nn].*", L"\x041e\x043e\x0431\x0430", L"\x0416\x043e\x043a" }, - { "lb_LU", L"^[jJyY].*", L"^[nN].*", L"", L"" }, - { "lg_UG", L"^[yY]", L"^[nN]", L"", L"" }, - { "li_BE", L"^[jJyY].*", L"^[nN].*", L"", L"" }, - { "li_NL", L"^[jJyY].*", L"^[nN].*", L"", L"" }, - { "lij_IT", L"^[sSyY].*", L"^[nN].*", L"", L"" }, - { "lo_LA", L"^[yY\x0ea1]", L"^[nN\x0e9a]", L"\x0ec1\x0ea1\x0ec8\x0e99", L"\x0e9a\x0ecd\x0ec8\x0ec1\x0ea1\x0ec8\x0e99" }, - { "lt_LT", L"^[TtYy].*", L"^[Nn].*", L"", L"" }, - { "lv_LV", L"^[JjYy].*", L"^[Nn].*", L"", L"" }, - { "lzh_TW", L"^[yY\x662f]", L"^[nN\x975e]", L"", L"" }, - { "mag_IN", L"^[yY].*", L"^[nN].*", L"", L"" }, - { "mai_IN", L"^[yY].*", L"^[nN].*", L"", L"" }, - { "mg_MG", L"^[eEyY].*", L"^[tTnN].*", L"", L"" }, - { "mhr_RU", L"^[\x0422\x0442Yy].*", L"^[\x0423\x0443Nn].*", L"", L"" }, - { "mi_NZ", L"^[1yY\x0101\x0100\x00e4\x00c4\x0061\x0041].*", L"^[0nNkK].*", L"\x0101\x0065", L"k\x0101ore" }, - { "mk_MK", L"^[\x0414\x0434\x0044\x0064Yy1].*", L"^[\x041d\x043dNn0].*", L"\x0434\x0430", L"\x043d\x0435" }, - { "ml_IN", L"^[\x0d05\x0d24\x0d46yY]", L"^[\x0d05\x0d32\x0d4d\x0d32nN]", L"\x0d05\x0d24\x0d46", L"\x0d05\x0d32\x0d4d\x0d32" }, - { "mn_MN", L"^[\x0442\x0422yY].*", L"^[\x04af\x04aenN].*", L"", L"" }, - { "mni_IN", L"^[yY]", L"^[nN]", L"Yes", L"No" }, - { "mr_IN", L"^(Yes|[yY])", L"^(No|[nN])", L"", L"" }, - { "ms_MY", L"^[yY]", L"^[tT]", L"Ya", L"Tidak" }, - { "mt_MT", L"^(Yes|[yY])", L"^(No|[nN])", L"", L"" }, - { "my_MM", L"^[yY\x101f].*", L"^[nN\x1019].*", L"\x101f\x102f\x1010\x103a\x1010\x101a\x103a", L"\x1019\x101f\x102f\x1010\x103a\x1018\x1030\x1038" }, - { "nan_TW", L"^[yY\x662f]", L"^[nN\x4f13]", L"", L"" }, - { "nan_TW@latin", L"^[sS].*", L"^[mM].*", L"S\x012b", L"M\x0304-S\x012b" }, - { "nb_NO", L"^[JjYy].*", L"^[Nn].*", L"", L"" }, - { "nds_DE", L"^[jJyY].*", L"^[nN].*", L"", L"" }, - { "nds_NL", L"^[jJyY].*", L"^[nN].*", L"", L"" }, - { "ne_NP", L"^[yY].*", L"^[nN].*", L"", L"" }, - { "nhn_MX", L"^[sSqQyY].*", L"^[nNaA].*", L"quema", L"ahmo" }, - { "niu_NU", L"^[\x0113\x0112yY].*", L"^[nN].*", L"Talia", L"Nakai" }, - { "niu_NZ", L"^[\x0113\x0112yY].*", L"^[nN].*", L"Talia", L"Nakai" }, - { "nl_AW", L"^[jJyY].*", L"^[nN].*", L"", L"" }, - { "nl_BE", L"^[jJyY].*", L"^[nN].*", L"", L"" }, - { "nl_BE@euro", L"^[jJyY].*", L"^[nN].*", L"", L"" }, - { "nl_NL", L"^[jJyY].*", L"^[nN].*", L"", L"" }, - { "nl_NL@euro", L"^[jJyY].*", L"^[nN].*", L"", L"" }, - { "nn_NO", L"^[JjYy].*", L"^[Nn].*", L"", L"" }, - { "no_NO", L"^[JjYy].*", L"^[Nn].*", L"", L"" }, - { "nr_ZA", L"^[yY]", L"^[nN]", L"", L"" }, - { "nso_ZA", L"^[yYeE]", L"^[nNaA]", L"", L"" }, - { "oc_FR", L"^[oOsSyY].*", L"^[nN].*", L"", L"" }, - { "om_ET", L"^[yY].*", L"^[nN].*", L"", L"" }, - { "om_KE", L"^[yY].*", L"^[nN].*", L"", L"" }, - { "or_IN", L"^[yY].*", L"^[nN].*", L"", L"" }, - { "os_RU", L"^[\x0423\x0434Yy].*", L"^[\x0443\x043dNn].*", L"", L"" }, - { "pa_IN", L"^[yY].*", L"^[nN].*", L"", L"" }, - { "pa_PK", L"^[yY\x0647\x0628\x0066].*", L"^[nN\x0646o].*", L"\x0628\x0644\x0643\x0644", L"\x0646\x0647\x064a\x06ba" }, - { "pap_AN", L"^[jJyY].*", L"^[nN].*", L"", L"" }, - { "pap_AW", L"^[jJyY].*", L"^[nN].*", L"", L"" }, - { "pap_CW", L"^[jJyY].*", L"^[nN].*", L"", L"" }, - { "pl_PL", L"^[TtYy].*", L"^[nN].*", L"", L"" }, - { "ps_AF", L"^[yY\x0628\x0066].*", L"^[nN\x062e\x0646o].*", L"", L"" }, - { "pt_BR", L"^[SsyY].*", L"^[nN].*", L"", L"" }, - { "pt_PT", L"^[SsyY].*", L"^[nN].*", L"", L"" }, - { "pt_PT@euro", L"^[SsyY].*", L"^[nN].*", L"", L"" }, - { "quz_PE", L"^[aAsSyY].*", L"^[mMnN].*", L"Ar\x00ed", L"Manan" }, - { "raj_IN", L"^[yY].*", L"^[nN].*", L"", L"" }, - { "ro_RO", L"^[DdYy].*", L"^[nN].*", L"", L"" }, - { "ru_RU", L"^[\x0414\x0434Yy].*", L"^[\x041d\x043dNn].*", L"", L"" }, - { "ru_UA", L"^[\x0414\x0434Yy].*", L"^[\x041d\x043dNn].*", L"", L"" }, - { "rw_RW", L"^[yY]", L"^[nNoO]", L"", L"" }, - { "sa_IN", L"^[aAyY].*", L"^[nN].*", L"", L"" }, - { "sat_IN", L"^(\x0939\x094b\x092f|[yY])", L"^(\x092c\x093e\x0919|[nN])", L"", L"" }, - { "sc_IT", L"^[sSjJoOyY].*", L"^[nN].*", L"", L"" }, - { "sd_IN", L"^[\x0646yY].*", L"^[\x0644nN].*", L"\x0646\x0639\x0645", L"\x0644\x0627" }, - { "sd_IN@devanagari", L"^[yY].*", L"^[nN].*", L"", L"" }, - { "se_NO", L"^[JjYy].*", L"^[Ii].*", L"", L"" }, - { "shs_CA", L"^[yYoO].*", L"^[nN].*", L"Yes", L"No" }, - { "si_LK", L"^[\x0d94Yy]", L"^[\x0db1Nn]", L"\x0d94\x0dc0\x0dca", L"\x0db1\x0dd0\x0dad" }, - { "sid_ET", L"^[yY].*", L"^[nN].*", L"", L"" }, - { "sk_SK", L"^[aA\x00e1\x00c1yY].*", L"^[nN].*", L"\x00e1no", L"nie" }, - { "sl_SI", L"^[YyJj].*", L"^[Nn].*", L"", L"" }, - { "so_DJ", L"^[oOyY].*", L"^[nN].*", L"", L"" }, - { "so_ET", L"^[yY].*", L"^[nN].*", L"", L"" }, - { "so_KE", L"^[yY].*", L"^[nN].*", L"", L"" }, - { "so_SO", L"^[yY].*", L"^[nN].*", L"", L"" }, - { "sq_AL", L"^[yYpP].*", L"^[nNjJ].*", L"", L"" }, - { "sq_MK", L"^[yYpP].*", L"^[nNjJ].*", L"", L"" }, - { "sr_CS", L"^[\x0414\x0434\x0044\x0064Yy]", L"^[\x041d\x043dNn]", L"", L"" }, - { "sr_CS@latin", L"^[dDyY]", L"^[nN]", L"", L"" }, - { "sr_ME", L"^[\x0414\x0434\x0044\x0064Yy]", L"^[\x041d\x043dNn]", L"", L"" }, - { "sr_ME@latin", L"^[dDyY]", L"^[nN]", L"", L"" }, - { "sr_RS", L"^[\x0414\x0434\x0044\x0064Yy]", L"^[\x041d\x043dNn]", L"", L"" }, - { "sr_RS@latin", L"^[dDyY]", L"^[nN]", L"", L"" }, - { "sr_SP", L"^[\x0414\x0434\x0044\x0064Yy]", L"^[\x041d\x043dNn]", L"", L"" }, - { "sr_SP@latin", L"^[dDyY]", L"^[nN]", L"", L"" }, - { "ss_ZA", L"^[yY]", L"^[nNaA]", L"", L"" }, - { "st_ZA", L"^[yY]", L"^[nN]", L"", L"" }, - { "sv_FI", L"^[jJyY].*", L"^[nN].*", L"", L"" }, - { "sv_FI@euro", L"^[jJyY].*", L"^[nN].*", L"", L"" }, - { "sv_SE", L"^[jJyY].*", L"^[nN].*", L"", L"" }, - { "sw_KE", L"^[nNyY].*", L"^[hHlL].*", L"", L"" }, - { "sw_TZ", L"^[nNyY].*", L"^[hHlL].*", L"", L"" }, - { "szl_PL", L"^[JjTtYy].*", L"^[nN].*", L"", L"" }, - { "ta_IN", L"^[\x0b86\x0bae\x0bcdyY]", L"^[\x0b87\x0bb2\x0bcd\x0bb2\x0bc8nN]", L"\x0b86\x0bae\x0bcd", L"\x0b87\x0bb2\x0bcd\x0bb2\x0bc8" }, - { "ta_LK", L"^[\x0b86\x0bae\x0bcdyY]", L"^[\x0b87\x0bb2\x0bcd\x0bb2\x0bc8nN]", L"\x0b86\x0bae\x0bcd", L"\x0b87\x0bb2\x0bcd\x0bb2\x0bc8" }, - { "te_IN", L"^[yY\x0c05].*", L"^[nN\x0c15].*", L"\x0c05\x0c35\x0c28\x0c41", L"\x0c15\x0c3e\x0c26\x0c41" }, - { "tg_TJ", L"^[\x04b2\x04b3\x0425\x0445\x0414\x0434Yy].*", L"^[\x041d\x043dNn].*", L"\x0434\x0430", L"\x043d\x0435\x0442" }, - { "th_TH", L"^[yY\x0e0a]", L"^[nN\x0e21]", L"\x0e43\x0e0a\x0e48", L"\x0e44\x0e21\x0e48\x0e43\x0e0a\x0e48" }, - { "the_NP", L"^[yY].*", L"^[nN].*", L"", L"" }, - { "ti_ER", L"^[yY].*", L"^[nN].*", L"", L"" }, - { "ti_ET", L"^[yY].*", L"^[nN].*", L"", L"" }, - { "tig_ER", L"^[yY].*", L"^[nN].*", L"", L"" }, - { "tk_TM", L"^[hH].*", L"^[\x00fd\x00ddnN].*", L"hawa", L"\x00fdok" }, - { "tl_PH", L"^[yY].*", L"^[nN].*", L"Yes", L"No" }, - { "tn_ZA", L"^[yYeE]", L"^[nN]", L"", L"" }, - { "tr_CY", L"^[yYeE]", L"^[nNhH]", L"evet", L"hay\x0131r" }, - { "tr_TR", L"^[yYeE]", L"^[nNhH]", L"evet", L"hay\x0131r" }, - { "ts_ZA", L"^[yY]", L"^[nN]", L"", L"" }, - { "tt_RU", L"^[\x0414\x0434Yy].*", L"^[\x041d\x043dNn].*", L"\x04d8\x0439\x0435", L"\x042e\x043a" }, - { "tt_RU@iqtelif", L"^[Ee].*", L"^[YyNn].*", L"ey\x00ed", L"yuq" }, - { "ug_CN", L"^[yY].*", L"^[nN].*", L"Yes", L"No" }, - { "uk_UA", L"^([Yy+]|[\x0422\x0442][\x0410\x0430][\x041a\x043a]?)$", L"^([Nn-]|[\x041d\x043d][\x0406\x0456])$", L"\x0442\x0430\x043a", L"\x043d\x0456" }, - { "unm_US", L"^[yY].*", L"^[kKmM].*", L"", L"" }, - { "ur_IN", L"^[\x06c1yY].*", L"^[\x0646nN].*", L"\x06c1\x0627\x06ba", L"\x0646\x06c1\x06cc\x06ba" }, - { "ur_PK", L"^[yY\x0647\x0628\x0066].*", L"^[nN\x0646o].*", L"\x0628\x0644\x0643\x0644", L"\x0646\x0647\x064a\x06ba" }, - { "uz_UZ", L"^[YyHh].*", L"^[JjNn].*", L"Ha", L"Yo'q" }, - { "uz_UZ@cyrillic", L"^[\x04b2\x04b3Yy].*", L"^[\x0419\x0439Nn].*", L"\x04b2\x0430", L"\x0419\x045e\x049b" }, - { "ve_ZA", L"^[yYeE]", L"^[nNhH]", L"", L"" }, - { "vi_VN", L"^[1yYcC].*", L"^[0nNkK].*", L"C\x00f3", L"Kh\x00f4ng" }, - { "wa_BE", L"^[oOyYaAwW].*", L"^[nN].*", L"Oyi", L"Neni" }, - { "wa_BE@euro", L"^[oOyYaAwW].*", L"^[nN].*", L"Oyi", L"Neni" }, - { "wae_CH", L"^[jJyY].*", L"^[nN].*", L"Ja", L"Nei" }, - { "wal_ET", L"^[yY].*", L"^[nN].*", L"", L"" }, - { "wo_SN", L"^[wWyY].*", L"^[dDnN].*", L"", L"" }, - { "xh_ZA", L"^[yYeE]", L"^[nNhH]", L"", L"" }, - { "yi_US", L"^[Yy\x05d9].*", L"^[Nn\x05e0\x05e7].*", L"\x05d9\x05d0\x05b8", L"\x05e7\x05f2\x05df" }, - { "yo_NG", L"^[EeyY].*", L"^[rROoKkNn].*", L"B\x1eb9\x0301\x1eb9\x0300 ni", L"B\x1eb9\x0301\x1eb9\x0300 k\x1ecd\x0301" }, - { "yue_HK", L"^[yY]", L"^[nN]", L"", L"" }, - { "zh_CN", L"^[yY\x662f]", L"^[nN\x4e0d\x5426]", L"", L"" }, - { "zh_HK", L"^[yY\x662f]", L"^[nN\x4e0d\x5426]", L"", L"" }, - { "zh_SG", L"^[yY]", L"^[nN]", L"Yes", L"No" }, - { "zh_TW", L"^[yY\x662f]", L"^[nN\x4e0d\x5426]", L"", L"" }, - { "zu_ZA", L"^[yY]", L"^[nNcC]", L"", L"" }, + { "aa_DJ", L"^[+1yY]", L"^[-0mnMN]", L"Yeey", L"Maleey" }, + { "aa_ER", L"^[+1yY]", L"^[-0mnMN]", L"Yeey", L"Maleey" }, + { "aa_ER@saaho", L"^[+1yY]", L"^[-0mnMN]", L"Yeey", L"Maleey" }, + { "aa_ET", L"^[+1yY]", L"^[-0mnMN]", L"Yeey", L"Maleey" }, + { "af_ZA", L"^[+1jJyY]", L"^[-0nN]", L"ja", L"nee" }, + { "agr_PE", L"^[+1eEsSyY]", L"^[-0aAnN]", L"ehe", L"atsa" }, + { "ak_GH", L"^[+1yY]", L"^[-0dDnN]", L"Yiw", L"Daabi" }, + { "am_ET", L"^([+1yY\x12ce]|\x12a0\x12ce\x1295)", L"^([-0nN\x12ed]|\x12a0\x12ed)", L"\x12a0\x12ce\x1295", L"\x12a0\x12ed" }, + { "an_ES", L"^[+1sSyY]", L"^[-0nN]", L"s\x00ed", L"no" }, + { "anp_IN", L"^[+1\x0939\x0935yY]", L"^[-0\x0928\x0907nN]", L"\x0939\x093e\x0901", L"\x0928\x0939\x0940\x0902" }, + { "ar_AE", L"^[+1\x0646yY]", L"^[-0\x0644nN]", L"\x0646\x0639\x0645", L"\x0644\x0627" }, + { "ar_BH", L"^[+1\x0646yY]", L"^[-0\x0644nN]", L"\x0646\x0639\x0645", L"\x0644\x0627" }, + { "ar_DZ", L"^[+1\x0646yY]", L"^[-0\x0644nN]", L"\x0646\x0639\x0645", L"\x0644\x0627" }, + { "ar_EG", L"^[+1\x0646yY]", L"^[-0\x0644nN]", L"\x0646\x0639\x0645", L"\x0644\x0627" }, + { "ar_IN", L"^[+1\x0646yY]", L"^[-0\x0644nN]", L"\x0646\x0639\x0645", L"\x0644\x0627" }, + { "ar_IQ", L"^[+1\x0646yY]", L"^[-0\x0644nN]", L"\x0646\x0639\x0645", L"\x0644\x0627" }, + { "ar_JO", L"^[+1\x0646yY]", L"^[-0\x0644nN]", L"\x0646\x0639\x0645", L"\x0644\x0627" }, + { "ar_KW", L"^[+1\x0646yY]", L"^[-0\x0644nN]", L"\x0646\x0639\x0645", L"\x0644\x0627" }, + { "ar_LB", L"^[+1\x0646yY]", L"^[-0\x0644nN]", L"\x0646\x0639\x0645", L"\x0644\x0627" }, + { "ar_LY", L"^[+1\x0646yY]", L"^[-0\x0644nN]", L"\x0646\x0639\x0645", L"\x0644\x0627" }, + { "ar_MA", L"^[+1\x0646yY]", L"^[-0\x0644nN]", L"\x0646\x0639\x0645", L"\x0644\x0627" }, + { "ar_OM", L"^[+1\x0646yY]", L"^[-0\x0644nN]", L"\x0646\x0639\x0645", L"\x0644\x0627" }, + { "ar_QA", L"^[+1\x0646yY]", L"^[-0\x0644nN]", L"\x0646\x0639\x0645", L"\x0644\x0627" }, + { "ar_SA", L"^[+1\x0646yY]", L"^[-0\x0644nN]", L"\x0646\x0639\x0645", L"\x0644\x0627" }, + { "ar_SD", L"^[+1\x0646yY]", L"^[-0\x0644nN]", L"\x0646\x0639\x0645", L"\x0644\x0627" }, + { "ar_SS", L"^[+1\x0646yY]", L"^[-0\x0644nN]", L"\x0646\x0639\x0645", L"\x0644\x0627" }, + { "ar_SY", L"^[+1\x0646yY]", L"^[-0\x0644nN]", L"\x0646\x0639\x0645", L"\x0644\x0627" }, + { "ar_TN", L"^[+1\x0646yY]", L"^[-0\x0644nN]", L"\x0646\x0639\x0645", L"\x0644\x0627" }, + { "ar_YE", L"^[+1\x0646yY]", L"^[-0\x0644nN]", L"\x0646\x0639\x0645", L"\x0644\x0627" }, + { "as_IN", L"^[+1yY\x09b9]", L"^[-0nN\x09a8]", L"\x09b9\x09df", L"\x09a8\x09b9\x09df" }, + { "ast_ES", L"^[+1sSyY]", L"^[-0nN]", L"s\x00ed", L"non" }, + { "ayc_PE", L"^[+1uUsSyY]", L"^[-0jJnN]", L"Ukhamawa", L"Janiwa" }, + { "az_AZ", L"^[+1bBhH]", L"^[-0YyNn]", L"h\x0259", L"yox" }, + { "az_IR", L"^[+1yY\x0647\x0628]", L"^[-0nN\x06cc\x062e]", L"\x0647\x0646", L"\x06cc\x0648\x0652\x062e" }, + { "be_BY", L"^[+1yY\x0422\x0442]", L"^[-0nN\x041d\x043d]", L"\x0442\x0430\x043a", L"\x043d\x0435" }, + { "be_BY@latin", L"^[+1TtYy]", L"^[-0Nn]", L"", L"" }, + { "bem_ZM", L"^[+1yYeE]", L"^[-0nNaA]", L"Ee", L"Awe" }, + { "ber_DZ", L"^[+1yYiI]", L"^[-0nNuUaA]", L"Ih", L"Uhu" }, + { "ber_MA", L"^[+1Bb]", L"^[-0YyNn]", L"b\x0259li", L"yox" }, + { "bg_BG", L"^[+1yYdDoO\x0414\x0434]", L"^[-0nNkK\x041d\x043d]", L"\x0434\x0430", L"\x043d\x0435" }, + { "bho_IN", L"^[+1yY\x0939]", L"^[-0nN\x0928]", L"\x0939\x093e\x0901", L"\x0928\x0939\x0940\x0902" }, + { "bho_NP", L"^[+1yY\x0939]", L"^[-0nN\x0928]", L"\x0939\x093e\x0901", L"\x0928\x0939\x0940\x0902" }, + { "bi_VU", L"^[+1yY]", L"^[-0nN]", L"Yes", L"No" }, + { "bn_BD", L"^[+1yY\x09b9]", L"^[-0nN\x09a8]", L"\x09b9\x09cd\x09af\x09be\x0981", L"\x09a8\x09be" }, + { "bn_IN", L"^[+1yY\x09b9]", L"^[-0nN\x09a8]", L"\x09b9\x09cd\x09af\x09be\x0981", L"\x09a8\x09be" }, + { "bo_CN", L"^[+1yY\x0f68]", L"^[-0nN\x0f58]", L"\x0f61\x0f72\x0f53\x0f0d", L"\x0f58\x0f72\x0f53\x0f0d" }, + { "bo_IN", L"^[+1yY\x0f68]", L"^[-0nN\x0f58]", L"\x0f61\x0f72\x0f53\x0f0d", L"\x0f58\x0f72\x0f53\x0f0d" }, + { "br_FR", L"^[+1oOyY]", L"^[-0kKnN]", L"ya", L"ket" }, + { "br_FR@euro", L"^[+1oOyY]", L"^[-0kKnN]", L"ya", L"ket" }, + { "brx_IN", L"^[+1yY\x0939]", L"^[-0nN\x0928]", L"\x0939\x093e\x0901", L"\x0928\x0939\x0940\x0902" }, + { "bs_BA", L"^[+1dDyY]", L"^[-0nN]", L"da", L"ne" }, + { "byn_ER", L"^[+1yY\x12a5]", L"^[-0nN\x1290]", L"\x12a5\x12c8", L"\x1290\x1296\x12a5" }, + { "ca_AD", L"^[+1sSyY]", L"^[-0nN]", L"s\x00ed", L"no" }, + { "ca_ES", L"^[+1sSyY]", L"^[-0nN]", L"s\x00ed", L"no" }, + { "ca_ES@euro", L"^[+1sSyY]", L"^[-0nN]", L"s\x00ed", L"no" }, + { "ca_ES@valencia", L"^[+1sSyY]", L"^[-0nN]", L"s\x00ed", L"no" }, + { "ca_FR", L"^[+1sSyY]", L"^[-0nN]", L"s\x00ed", L"no" }, + { "ca_IT", L"^[+1sSyY]", L"^[-0nN]", L"s\x00ed", L"no" }, + { "ce_RU", L"^[+1yY\x0414\x0434]", L"^[-0nN\x041c\x043c]", L"", L"" }, + { "chr_US", L"^([+1yY]|\x13a5\x13a5)", L"^([-0nN]|\x13a5\x13dd)", L"\x13a5\x13a5", L"\x13a5\x13dd" }, + { "cmn_TW", L"^[+1yY\xff59\xff39\x662f]", L"^[-0nN\xff4e\xff2e\x4e0d\x5426]", L"\x662f", L"\x4e0d\x662f" }, + { "crh_UA", L"^[+1yYeE]", L"^[-0nNhH]", L"ebet", L"hay\x0131r" }, + { "cs_CZ", L"^[+1aAyY]", L"^[-0nN]", L"ano", L"ne" }, + { "csb_PL", L"^[+1JjTtYy]", L"^[-0nN]", L"jo", L"ni\x00e9" }, + { "cv_RU", L"^[+1yY]", L"^[-0nN]", L"", L"" }, + { "cy_GB", L"^[+1iItTyY]", L"^[-0nN]", L"ie", L"na" }, + { "da_DK", L"^[+1JjYy]", L"^[-0Nn]", L"ja", L"nej" }, + { "de_AT", L"^[+1jJyY]", L"^[-0nN]", L"ja", L"nein" }, + { "de_AT@euro", L"^[+1jJyY]", L"^[-0nN]", L"ja", L"nein" }, + { "de_BE", L"^[+1jJyY]", L"^[-0nN]", L"ja", L"nein" }, + { "de_BE@euro", L"^[+1jJyY]", L"^[-0nN]", L"ja", L"nein" }, + { "de_CH", L"^[+1jJyY]", L"^[-0nN]", L"ja", L"nein" }, + { "de_DE", L"^[+1jJyY]", L"^[-0nN]", L"ja", L"nein" }, + { "de_DE@euro", L"^[+1jJyY]", L"^[-0nN]", L"ja", L"nein" }, + { "de_IT", L"^[+1jJyY]", L"^[-0nN]", L"ja", L"nein" }, + { "de_LU", L"^[+1jJyY]", L"^[-0nN]", L"ja", L"nein" }, + { "de_LU@euro", L"^[+1jJyY]", L"^[-0nN]", L"ja", L"nein" }, + { "doi_IN", L"^[+1yY\x0911]", L"^[-0nN\x0928]", L"\x0911\x0939", L"\x0928\x093e" }, + { "dsb_DE", L"^[+1jJhHyY]", L"^[-0nN]", L"jo", L"n\x011b" }, + { "dv_MV", L"^[+1yY]", L"^[-0nN]", L"", L"" }, + { "dz_BT", L"^[+1yY\x0f68]", L"^[-0nN\x0f58]", L"\x0f68\x0f72\x0f53\x0f0b", L"\x0f58\x0f7a\x0f53\x0f0b" }, + { "el_CY", L"^[+1yY\x03bd\x039d]", L"^[-0nN\x03bf\x039f\x03cc\x038c]", L"\x03bd\x03b1\x03b9", L"\x03cc\x03c7\x03b9" }, + { "el_GR", L"^[+1yY\x03bd\x039d]", L"^[-0nN\x03bf\x039f\x03cc\x038c]", L"\x03bd\x03b1\x03b9", L"\x03cc\x03c7\x03b9" }, + { "el_GR@euro", L"^[+1yY\x03bd\x039d]", L"^[-0nN\x03bf\x039f\x03cc\x038c]", L"\x03bd\x03b1\x03b9", L"\x03cc\x03c7\x03b9" }, + { "en_AG", L"^[+1yY]", L"^[-0nN]", L"yes", L"no" }, + { "en_AU", L"^[+1yY]", L"^[-0nN]", L"yes", L"no" }, + { "en_BW", L"^[+1yY]", L"^[-0nN]", L"yes", L"no" }, + { "en_CA", L"^[+1yYoO]", L"^[-0nN]", L"yes", L"no" }, + { "en_DK", L"^[+1yYjJsSoO]", L"^[-0nN]", L"yes", L"no" }, + { "en_GB", L"^[+1yY]", L"^[-0nN]", L"yes", L"no" }, + { "en_HK", L"^[+1yY]", L"^[-0nN]", L"yes", L"no" }, + { "en_IE", L"^[+1yY]", L"^[-0nN]", L"yes", L"no" }, + { "en_IE@euro", L"^[+1yY]", L"^[-0nN]", L"yes", L"no" }, + { "en_IL", L"^[+1yY]", L"^[-0nN]", L"yes", L"no" }, + { "en_IN", L"^[+1yY]", L"^[-0nN]", L"yes", L"no" }, + { "en_NG", L"^[+1yY]", L"^[-0nN]", L"yes", L"no" }, + { "en_NZ", L"^[+1yY]", L"^[-0nN]", L"yes", L"no" }, + { "en_PH", L"^[+1yY]", L"^[-0nN]", L"yes", L"no" }, + { "en_SG", L"^[+1yY]", L"^[-0nN]", L"yes", L"no" }, + { "en_US", L"^[+1yY]", L"^[-0nN]", L"yes", L"no" }, + { "en_ZA", L"^[+1yY]", L"^[-0nN]", L"yes", L"no" }, + { "en_ZM", L"^[+1yYeE]", L"^[-0nNaA]", L"Ee", L"Awe" }, + { "en_ZW", L"^[+1yY]", L"^[-0nN]", L"yes", L"no" }, + { "es_AR", L"^[+1sSyY]", L"^[-0nN]", L"s\x00ed", L"no" }, + { "es_BO", L"^[+1sSyY]", L"^[-0nN]", L"s\x00ed", L"no" }, + { "es_CL", L"^[+1sSyY]", L"^[-0nN]", L"s\x00ed", L"no" }, + { "es_CO", L"^[+1sSyY]", L"^[-0nN]", L"s\x00ed", L"no" }, + { "es_CR", L"^[+1sSyY]", L"^[-0nN]", L"s\x00ed", L"no" }, + { "es_CU", L"^[+1sSyY]", L"^[-0nN]", L"s\x00ed", L"no" }, + { "es_DO", L"^[+1sSyY]", L"^[-0nN]", L"s\x00ed", L"no" }, + { "es_EC", L"^[+1sSyY]", L"^[-0nN]", L"s\x00ed", L"no" }, + { "es_ES", L"^[+1sSyY]", L"^[-0nN]", L"s\x00ed", L"no" }, + { "es_ES@euro", L"^[+1sSyY]", L"^[-0nN]", L"s\x00ed", L"no" }, + { "es_GT", L"^[+1sSyY]", L"^[-0nN]", L"s\x00ed", L"no" }, + { "es_HN", L"^[+1sSyY]", L"^[-0nN]", L"s\x00ed", L"no" }, + { "es_MX", L"^[+1sSyY]", L"^[-0nN]", L"s\x00ed", L"no" }, + { "es_NI", L"^[+1sSyY]", L"^[-0nN]", L"s\x00ed", L"no" }, + { "es_PA", L"^[+1sSyY]", L"^[-0nN]", L"s\x00ed", L"no" }, + { "es_PE", L"^[+1sSyY]", L"^[-0nN]", L"s\x00ed", L"no" }, + { "es_PR", L"^[+1sSyY]", L"^[-0nN]", L"s\x00ed", L"no" }, + { "es_PY", L"^[+1sSyY]", L"^[-0nN]", L"s\x00ed", L"no" }, + { "es_SV", L"^[+1sSyY]", L"^[-0nN]", L"s\x00ed", L"no" }, + { "es_US", L"^[+1sSyY]", L"^[-0nN]", L"s\x00ed", L"no" }, + { "es_UY", L"^[+1sSyY]", L"^[-0nN]", L"s\x00ed", L"no" }, + { "es_VE", L"^[+1sSyY]", L"^[-0nN]", L"s\x00ed", L"no" }, + { "et_EE", L"^[+1JjYy]", L"^[-0EeNn]", L"jah", L"ei" }, + { "eu_ES", L"^[+1bBsSyY]", L"^[-0eEnN]", L"bai", L"ez" }, + { "eu_ES@euro", L"^[+1bBsSyY]", L"^[-0eEnN]", L"bai", L"ez" }, + { "fa_IR", L"^[+1yY\x0622\x0628Hf]", L"^[-0nN\x062e\x0646ok]", L"\x0628\x0644\x0647", L"\x0646\x0647" }, + { "ff_SN", L"^[+1yYeE]", L"^[-0nNaA]", L"Eey", L"Alaa" }, + { "fi_FI", L"^[+1KkYy]", L"^[-0EeNn]", L"kyll\x00e4", L"ei" }, + { "fi_FI@euro", L"^[+1KkYy]", L"^[-0EeNn]", L"kyll\x00e4", L"ei" }, + { "fil_PH", L"^[+1oOyY]", L"^[-0hHnN]", L"oo", L"hindi" }, + { "fo_FO", L"^[+1JjYy]", L"^[-0Nn]", L"j\x00e1", L"nei" }, + { "fr_BE", L"^[+1oOjJyY]", L"^[-0nN]", L"oui", L"non" }, + { "fr_BE@euro", L"^[+1oOjJyY]", L"^[-0nN]", L"oui", L"non" }, + { "fr_CA", L"^[+1oOyY]", L"^[-0nN]", L"oui", L"non" }, + { "fr_CH", L"^[+1OojJsSyY]", L"^[-0nN]", L"oui", L"non" }, + { "fr_FR", L"^[+1oOyY]", L"^[-0nN]", L"oui", L"non" }, + { "fr_FR@euro", L"^[+1oOyY]", L"^[-0nN]", L"oui", L"non" }, + { "fr_LU", L"^[+1oOyY]", L"^[-0nN]", L"oui", L"non" }, + { "fr_LU@euro", L"^[+1oOyY]", L"^[-0nN]", L"oui", L"non" }, + { "fur_IT", L"^[+1sSjJoOyY]", L"^[-0nN]", L"s\x00ec", L"no" }, + { "fy_DE", L"^[+1jJyY]", L"^[-0nN]", L"ja", L"nee" }, + { "fy_NL", L"^[+1jJyY]", L"^[-0nN]", L"ja", L"nee" }, + { "ga_IE", L"^[+1tTyY]", L"^[-0nN]", L"t\x00e1", L"n\x00edl" }, + { "ga_IE@euro", L"^[+1tTyY]", L"^[-0nN]", L"t\x00e1", L"n\x00edl" }, + { "gd_GB", L"^[+1tTyY]", L"^[-0cCnN]", L"tha", L"chan eil" }, + { "gez_ER", L"^[+1yY\x12a5]", L"^[-0nN\x1290]", L"\x12a5\x12c8", L"\x1290\x1296\x12a5" }, + { "gez_ER@abegede", L"^[+1yY\x12a5]", L"^[-0nN\x1290]", L"\x12a5\x12c8", L"\x1290\x1296\x12a5" }, + { "gez_ET", L"^[+1\x12a5yY]", L"^[-0\x1290nN]", L"\x12a5\x12c8", L"\x1290\x1296\x12a5" }, + { "gez_ET@abegede", L"^[+1\x12a5yY]", L"^[-0\x1290nN]", L"\x12a5\x12c8", L"\x1290\x1296\x12a5" }, + { "gl_ES", L"^[+1sSyY]", L"^[-0nN]", L"si", L"non" }, + { "gl_ES@euro", L"^[+1sSyY]", L"^[-0nN]", L"si", L"non" }, + { "gu_IN", L"^[+1yY\x0ab9]", L"^[-0nN\x0aa8]", L"\x0ab9\x0abe", L"\x0aa8\x0ab9\x0ac0\x0a82" }, + { "gv_GB", L"^[+1yY]", L"^[-0nN]", L"", L"" }, + { "ha_NG", L"^[+1TtiIYy]", L"^[-0bBaAnN]", L"i", L"a\x02bc\x0061" }, + { "hak_TW", L"^[+1yY\xff59\xff39\x4fc2]", L"^[-0nN\xff4e\xff2e\x6bcb]", L"", L"" }, + { "he_IL", L"^[+1yY\x05db]", L"^[-0nN\x05dc]", L"\x05db\x05df", L"\x05dc\x05d0" }, + { "hi_IN", L"^[+1yY\x0939]", L"^[-0nN\x0928]", L"\x0939\x093e\x0901", L"\x0928\x0939\x0940\x0902" }, + { "hif_FJ", L"^[+1hHyY]", L"^[-0nN]", L"Haan", L"Nahi" }, + { "hne_IN", L"^[+1yY\x0939]", L"^[-0nN\x0928]", L"\x0939\x0935", L"\x0928\x0907" }, + { "hr_HR", L"^[+1dDyY]", L"^[-0nN]", L"da", L"ne" }, + { "hsb_DE", L"^[+1hHyY]", L"^[-0nN]", L"haj", L"n\x011b" }, + { "ht_HT", L"^[+1wWoOyY]", L"^[-0nN]", L"Wi", L"Non" }, + { "hu_HU", L"^[+1IiYy]", L"^[-0nN]", L"igen", L"nem" }, + { "hy_AM", L"^[+1yYsS\x0561\x0531]", L"^[-0nN\x0578\x0548]", L"\x0561\x0575\x0578", L"\x0578\x0579" }, + { "ia_FR", L"^[+1sSyY]", L"^[-0nN]", L"Si", L"No" }, + { "id_ID", L"^[+1yY]", L"^[-0tTnN]", L"ya", L"tidak" }, + { "ig_NG", L"^[+1EeIiYy]", L"^[-0MmNn]", L"Eye", L"Mba" }, + { "ik_CA", L"^[+1yYiIaA]", L"^[-0nNqQ]", L"aa", L"qa\x00f1\x0061\x0061" }, + { "is_IS", L"^[+1jJyY]", L"^[-0nN]", L"j\x00e1", L"nei" }, + { "it_CH", L"^[+1sSjJoOyY]", L"^[-0nN]", L"s\x00ec", L"no" }, + { "it_IT", L"^[+1sSyY]", L"^[-0nN]", L"s\x00ec", L"no" }, + { "it_IT@euro", L"^[+1sSyY]", L"^[-0nN]", L"s\x00ec", L"no" }, + { "iu_CA", L"^[+1yYsS]", L"^[-0nN]", L"", L"" }, + { "ja_JP", L"^([+1yY\xff59\xff39]|\x306f\x3044|\x30cf\x30a4)", L"^([-0nN\xff4e\xff2e]|\x3044\x3044\x3048|\x30a4\x30a4\x30a8)", L"\x306f\x3044", L"\x3044\x3044\x3048" }, + { "ka_GE", L"^[+1yYkKxX\x10d9]", L"^[-0nNaA\x10d0]", L"\x10d9\x10d8", L"\x10d0\x10e0\x10d0" }, + { "kab_DZ", L"^[+1yYiI]", L"^[-0nNuUaA]", L"Ih", L"Uhu" }, + { "kk_KZ", L"^[+1yY\x0418\x0438]", L"^[-0nN\x0416\x0436N]", L"\x0438\x04d9", L"\x0436\x043e\x049b" }, + { "kl_GL", L"^[+1JjYyAa]", L"^[-0Nn]", L"aap", L"naagga" }, + { "km_KH", L"^[+1yY\x1794]", L"^[-0nN\x1791]", L"\x1794\x17b6\x1791/\x1785\x17b6\x179f", L"\x1791\x17c1" }, + { "kn_IN", L"^[+1yY\x0cb9]", L"^[-0nN\x0c87]", L"\x0cb9\x0ccc\x0ca6\x0cc1", L"\x0c87\x0cb2\x0ccd\x0cb2" }, + { "ko_KR", L"^[+1yY\xff59\xff39\xc608]", L"^[-0nN\xff4e\xff2e\xc544]", L"\xc608", L"\xc544\xb2c8\xc694" }, + { "kok_IN", L"^[+1yY\x0939]", L"^[-0nN\x0928]", L"\x0939\x092f", L"\x0928\x094d\x0939\x0940" }, + { "ks_IN", L"^[+1yY\x0622]", L"^[-0nN\x0646]", L"\x0622", L"\x0646\x0639" }, + { "ks_IN@devanagari", L"^[+1yY\x0907]", L"^[-0nN\x0928]", L"\x0907\x0902\x0928", L"\x0928" }, + { "ku_TR", L"^[+1eEdDyY]", L"^[-0nN]", L"er\x00ea", L"n\x00e2" }, + { "kw_GB", L"^[+1eEyY]", L"^[-0nN]", L"ea", L"na" }, + { "ky_KG", L"^[+1yY\x041e\x043e]", L"^[-0nN\x0416\x0436]", L"\x043e\x043e\x0431\x0430", L"\x0436\x043e\x043a" }, + { "lb_LU", L"^[+1jJyY]", L"^[-0nN]", L"jo", L"nee" }, + { "lg_UG", L"^[+1yY]", L"^[-0nN]", L"Ye", L"Nedda" }, + { "li_BE", L"^[+1jJyY]", L"^[-0nN]", L"ja", L"nee" }, + { "li_NL", L"^[+1jJyY]", L"^[-0nN]", L"", L"" }, + { "lij_IT", L"^[+1sSyY]", L"^[-0nN]", L"", L"" }, + { "ln_CD", L"^[yYiI\x00ed\x00cd]", L"^[nNtT]", L"\x00cdyo", L"T\x025b\x0302" }, + { "lo_LA", L"^[+1yY\x0ea1]", L"^[-0nN\x0e9a]", L"\x0ec1\x0ea1\x0ec8\x0e99", L"\x0e9a\x0ecd\x0ec8\x0ec1\x0ea1\x0ec8\x0e99" }, + { "lt_LT", L"^[+1TtYy]", L"^[-0Nn]", L"taip", L"ne" }, + { "lv_LV", L"^[+1JjYy]", L"^[-0Nn]", L"j\x0101", L"n\x0113" }, + { "lzh_TW", L"^[+1yY\xff59\xff39\x662f]", L"^[-0nN\xff4e\xff2e\x975e]", L"", L"" }, + { "mag_IN", L"^[+1yY\x0939]", L"^[-0nN\x0928]", L"\x0939\x093e\x0901", L"\x0928\x0939\x0940\x0902" }, + { "mai_IN", L"^[+1yY\x0939]", L"^[-0nN\x0928]", L"\x0939\x093e\x0901", L"\x0928\x0939\x0940\x0902" }, + { "mai_NP", L"^[+1yY\x0939]", L"^[-0nN\x0928]", L"\x0939\x093e\x0901", L"\x0928\x0939\x0940\x0902" }, + { "mfe_MU", L"^[+1yYwW]", L"^[-0nN]", L"Wi", L"Non" }, + { "mg_MG", L"^[+1eEyY]", L"^[-0tTnN]", L"Eny", L"Tsia" }, + { "mhr_RU", L"^[+1yY\x0422\x0442]", L"^[-0nN\x0423\x0443]", L"", L"" }, + { "mi_NZ", L"^[+1yY\x0101\x0100\x00e4\x00c4\x0061\x0041]", L"^[-0nNkK]", L"\x0101\x0065", L"k\x0101ore" }, + { "miq_NI", L"^[+1sSyY]", L"^[-0nN]", L"s\x00ed", L"no" }, + { "mjw_IN", L"^[+1yY]", L"^[-0nN]", L"yes", L"no" }, + { "mk_MK", L"^[+1yY\x0414\x0434\x0064\x0044]", L"^[-0nN\x041d\x043d]", L"\x0434\x0430", L"\x043d\x0435" }, + { "ml_IN", L"^[+1yY\x0d09]", L"^[-0nN\x0d05]", L"\x0d09\x0d35\x0d4d\x0d35\x0d4d", L"\x0d05\x0d32\x0d4d\x0d32" }, + { "mn_MN", L"^[+1\x0442\x0422yY]", L"^[-0\x04af\x04aenN]", L"\x0442\x0438\x0439\x043c", L"\x04af\x0433\x04af\x0439" }, + { "mni_IN", L"^[+1yY]", L"^[-0nN]", L"yes", L"no" }, + { "mr_IN", L"^[+1yY\x0939]", L"^[-0nN\x0928]", L"\x0939\x094b\x092f", L"\x0928\x093e\x0939\x0940" }, + { "ms_MY", L"^[+1yY]", L"^[-0tTnN]", L"ya", L"tidak" }, + { "mt_MT", L"^[+1yYiI]", L"^[-0nNlL]", L"iva", L"le" }, + { "my_MM", L"^[+1yY\x101f]", L"^[-0nN\x1019]", L"\x101f\x102f\x1010\x103a\x1010\x101a\x103a", L"\x1019\x101f\x102f\x1010\x103a\x1018\x1030\x1038" }, + { "nan_TW", L"^[+1yY\xff59\xff39\x662f]", L"^[-0nN\xff4e\xff2e\x4f13]", L"", L"" }, + { "nan_TW@latin", L"^[+1yYsS]", L"^[-0nNmM]", L"S\x012b", L"M\x0304-S\x012b" }, + { "nb_NO", L"^[+1JjYy]", L"^[-0Nn]", L"ja", L"nei" }, + { "nds_DE", L"^[+1jJyY]", L"^[-0nN]", L"jo", L"nee" }, + { "nds_NL", L"^[+1jJyY]", L"^[-0nN]", L"jo", L"nee" }, + { "ne_NP", L"^[+1yY]", L"^[-0nN]", L"\x0939\x094b", L"\x0939\x094b\x0907\x0928" }, + { "nhn_MX", L"^[+1sSqQyY]", L"^[-0nNaA]", L"quema", L"ahmo" }, + { "niu_NU", L"^[+1yY\x0113\x0112]", L"^[-0nN]", L"Talia", L"Nakai" }, + { "niu_NZ", L"^[+1yY\x0113\x0112]", L"^[-0nN]", L"Talia", L"Nakai" }, + { "nl_AW", L"^[+1jJyY]", L"^[-0nN]", L"ja", L"nee" }, + { "nl_BE", L"^[+1jJyY]", L"^[-0nN]", L"ja", L"nee" }, + { "nl_BE@euro", L"^[+1jJyY]", L"^[-0nN]", L"ja", L"nee" }, + { "nl_NL", L"^[+1jJyY]", L"^[-0nN]", L"ja", L"nee" }, + { "nl_NL@euro", L"^[+1jJyY]", L"^[-0nN]", L"ja", L"nee" }, + { "nn_NO", L"^[+1JjYy]", L"^[-0Nn]", L"ja", L"nei" }, + { "no_NO", L"^[+1JjYy]", L"^[-0Nn]", L"ja", L"nei" }, + { "nr_ZA", L"^[+1yY]", L"^[-0nN]", L"", L"" }, + { "nso_ZA", L"^[+1yYeE]", L"^[-0nNaA]", L"", L"" }, + { "oc_FR", L"^[+1oOsSyY]", L"^[-0nN]", L"", L"" }, + { "om_ET", L"^[+1eEyY]", L"^[-0mMnN]", L"eeyyee", L"miti" }, + { "om_KE", L"^[+1eEyY]", L"^[-0mMnN]", L"eeyyee", L"miti" }, + { "or_IN", L"^[+1yY\x0b39]", L"^[-0nN\x0b28]", L"\x0b39\x0b01", L"\x0b28\x0b3e" }, + { "os_RU", L"^[+1yY\x0443\x0423]", L"^[-0nN\x043d\x041d]", L"\x0443\x043e\x0439\x044b", L"\x043d\x04d5\x0439\x044b" }, + { "pa_IN", L"^[+1yY\x0a39]", L"^[-0nN\x0a28]", L"\x0a39\x0a3e\x0a02", L"\x0a28\x0a39\x0a40\x0a02" }, + { "pa_PK", L"^[+1yY\x0647\x0628\x0066]", L"^[-0nN\x0646o]", L"\x0628\x0644\x0643\x0644", L"\x0646\x0647\x064a\x06ba" }, + { "pap_AW", L"^[+1sSyY]", L"^[-0nN]", L"s\x00ed", L"n\x00f2" }, + { "pap_CW", L"^[+1sSyY]", L"^[-0nN]", L"s\x00ed", L"n\x00f2" }, + { "pl_PL", L"^[+1TtYy]", L"^[-0nN]", L"tak", L"nie" }, + { "ps_AF", L"^[+1yY\x0628\x0066]", L"^[-0nN\x062e\x0646o]", L"\x0647\x0648", L"\x0646\x0647" }, + { "pt_BR", L"^[+1SsyY]", L"^[-0nN]", L"sim", L"n\x00e3o" }, + { "pt_PT", L"^[+1SsyY]", L"^[-0nN]", L"sim", L"n\x00e3o" }, + { "pt_PT@euro", L"^[+1SsyY]", L"^[-0nN]", L"sim", L"n\x00e3o" }, + { "quz_PE", L"^[+1aAsSyY]", L"^[-0mMnN]", L"Ar\x00ed", L"Manan" }, + { "raj_IN", L"^[+1yY]", L"^[-0nN]", L"", L"" }, + { "ro_RO", L"^[+1DdYy]", L"^[-0nN]", L"da", L"nu" }, + { "ru_RU", L"^[+1yY\x0414\x0434]", L"^[-0nN\x041d\x043d]", L"\x0434\x0430", L"\x043d\x0435\x0442" }, + { "ru_UA", L"^[+1yY\x0414\x0434]", L"^[-0nN\x041d\x043d]", L"\x0434\x0430", L"\x043d\x0435\x0442" }, + { "rw_RW", L"^[+1yY]", L"^[-0nNoO]", L"", L"" }, + { "sa_IN", L"^[+1aAyY\x0906]", L"^[-0nN\x0928]", L"\x0906\x092e\x094d", L"\x0928" }, + { "sah_RU", L"^[+1yY\x0434\x0414\x044d\x042d]", L"^[-0nN\x043d\x041d\x0441\x0421]", L"\x044d\x044d\x0445", L"\x0441\x0443\x043e\x0445" }, + { "sat_IN", L"^[+1yY\x0939]", L"^[-0nN\x092c]", L"\x0939\x094b\x092f", L"\x092c\x093e\x0919" }, + { "sc_IT", L"^[+1eEaAsSoOyY]", L"^[-0nN]", L"eja", L"nono" }, + { "sd_IN", L"^[+1\x0646yY]", L"^[-0\x0644nN]", L"\x0646\x0639\x0645", L"\x0644\x0627" }, + { "sd_IN@devanagari", L"^[+1yY]", L"^[-0nN]", L"", L"" }, + { "se_NO", L"^[+1JjYy]", L"^[-0IiNn]", L"jo", L"ii" }, + { "sgs_LT", L"^[+1TtYy]", L"^[-0Nn]", L"t\x01e1p", L"n\x0113" }, + { "shn_MM", L"^[+1yY\x101f]", L"^[-0nN\x1019]", L"\x101f\x102f\x1010\x103a\x1010\x101a\x103a", L"\x1019\x101f\x102f\x1010\x103a\x1018\x1030\x1038" }, + { "shs_CA", L"^[+1yYoO]", L"^[-0nN]", L"yes", L"no" }, + { "si_LK", L"^[+1yY\x0d94]", L"^[-0nN\x0db1]", L"\x0d94\x0dc0\x0dca", L"\x0db1\x0dd0\x0dad" }, + { "sid_ET", L"^[+1\x12a5yY]", L"^[-0\x1290nN]", L"\x12a5\x12c8", L"\x1290\x1296\x12a5" }, + { "sk_SK", L"^[+1aA\x00e1\x00c1yY]", L"^[-0nN]", L"\x00e1no", L"nie" }, + { "sl_SI", L"^[+1YyJj]", L"^[-0Nn]", L"da", L"ne" }, + { "sm_WS", L"^[+1iIyY]", L"^[-0lLnN]", L"ioe", L"leai" }, + { "so_DJ", L"^[+1oOyY]", L"^[-0nN]", L"haa", L"maya" }, + { "so_ET", L"^[+1\x12a5yY]", L"^[-0\x1290nN]", L"\x12a5\x12c8", L"\x1290\x1296\x12a5" }, + { "so_KE", L"^[+1yY]", L"^[-0nN]", L"haa", L"maya" }, + { "so_SO", L"^[+1yY]", L"^[-0nN]", L"haa", L"maya" }, + { "sq_AL", L"^[+1yYpP]", L"^[-0nNjJ]", L"po", L"jo" }, + { "sq_MK", L"^[+1yYpP]", L"^[-0nNjJ]", L"po", L"jo" }, + { "sr_CS", L"^[+1yYdD\x0414\x0434]", L"^[-0nN\x041d\x043d]", L"\x0434\x0430", L"\x043d\x0435" }, + { "sr_CS@latin", L"^[+1dDyY]", L"^[-0nN]", L"da", L"ne" }, + { "sr_ME", L"^[+1yYdD\x0414\x0434]", L"^[-0nN\x041d\x043d]", L"\x0434\x0430", L"\x043d\x0435" }, + { "sr_ME@latin", L"^[+1dDyY]", L"^[-0nN]", L"da", L"ne" }, + { "sr_RS", L"^[+1yYdD\x0414\x0434]", L"^[-0nN\x041d\x043d]", L"\x0434\x0430", L"\x043d\x0435" }, + { "sr_RS@latin", L"^[+1dDyY]", L"^[-0nN]", L"da", L"ne" }, + { "sr_SP", L"^[+1yYdD\x0414\x0434]", L"^[-0nN\x041d\x043d]", L"\x0434\x0430", L"\x043d\x0435" }, + { "sr_SP@latin", L"^[+1dDyY]", L"^[-0nN]", L"da", L"ne" }, + { "ss_ZA", L"^[+1yY]", L"^[-0nNaA]", L"", L"" }, + { "st_ZA", L"^[+1yY]", L"^[-0nN]", L"", L"" }, + { "sv_FI", L"^[+1jJyY]", L"^[-0nN]", L"ja", L"nej" }, + { "sv_FI@euro", L"^[+1jJyY]", L"^[-0nN]", L"ja", L"nej" }, + { "sv_SE", L"^[+1jJyY]", L"^[-0nN]", L"ja", L"nej" }, + { "sw_KE", L"^[+1nNyY]", L"^[-0hHlL]", L"Ndiyo", L"Hapana" }, + { "sw_TZ", L"^[+1nNyY]", L"^[-0hHlL]", L"Ndiyo", L"Hapana" }, + { "szl_PL", L"^[+1JjTtYy]", L"^[-0nN]", L"", L"" }, + { "ta_IN", L"^[+1yY\x0b86]", L"^[-0nN\x0b87]", L"\x0b86\x0bae\x0bcd", L"\x0b87\x0bb2\x0bcd\x0bb2\x0bc8" }, + { "ta_LK", L"^[+1yY\x0b86]", L"^[-0nN\x0b87]", L"\x0b86\x0bae\x0bcd", L"\x0b87\x0bb2\x0bcd\x0bb2\x0bc8" }, + { "te_IN", L"^[+1yY\x0c05]", L"^[-0nN\x0c35]", L"\x0c05\x0c35\x0c41\x0c28\x0c41", L"\x0c35\x0c26\x0c4d\x0c26\x0c41" }, + { "tg_TJ", L"^[+1yY\x04b2\x04b3\x0425\x0445\x0414\x0434]", L"^[-0nN\x041d\x043d]", L"\x04b3\x0430", L"\x043d\x0435" }, + { "th_TH", L"^[+1yY\x0e0a]", L"^[-0nN\x0e21]", L"\x0e43\x0e0a\x0e48", L"\x0e44\x0e21\x0e48\x0e43\x0e0a\x0e48" }, + { "the_NP", L"^[+1yY]", L"^[-0nN]", L"", L"" }, + { "ti_ER", L"^[+1yY\x12a5]", L"^[-0nN\x1290]", L"\x12a5\x12c8", L"\x1290\x1296\x12a5" }, + { "ti_ET", L"^[+1\x12a5yY]", L"^[-0\x1290nN]", L"\x12a5\x12c8", L"\x1290\x1296\x12a5" }, + { "tig_ER", L"^[+1yY\x12a5]", L"^[-0nN\x1290]", L"\x12a5\x12c8", L"\x1290\x1296\x12a5" }, + { "tk_TM", L"^[+1hH]", L"^[-0nN\x00fd\x00dd]", L"hawa", L"\x00fdok" }, + { "tl_PH", L"^[+1oOyY]", L"^[-0hHnN]", L"oo", L"hindi" }, + { "tn_ZA", L"^[+1yYeE]", L"^[-0nN]", L"", L"" }, + { "to_TO", L"^[+1yY]", L"^[-0nN]", L"\x02bbIo", L"\x02bbIkai" }, + { "tpi_PG", L"^[+1yY]", L"^[-0nN]", L"yes", L"nogat" }, + { "tr_CY", L"^[+1yYeE]", L"^[-0nNhH]", L"evet", L"hay\x0131r" }, + { "tr_TR", L"^[+1yYeE]", L"^[-0nNhH]", L"evet", L"hay\x0131r" }, + { "ts_ZA", L"^[+1iIyY]", L"^[-0eEnN]", L"Ina", L"Ee" }, + { "tt_RU", L"^[+1yY\x04d9\x04d8]", L"^[-0nN\x044e\x042e]", L"\x04d9\x0439\x0435", L"\x044e\x043a" }, + { "tt_RU@iqtelif", L"^[+1Ee]", L"^[-0YyNn]", L"ey\x00ed", L"yuq" }, + { "ug_CN", L"^[+1yY\x06be]", L"^[-0nN\x064a]", L"\x06be\x06d5\x0626\x06d5", L"\x064a\x0627\x0642" }, + { "uk_UA", L"^([+1Yy]|[\x0422\x0442][\x0410\x0430][\x041a\x043a]?)$", L"^([-0Nn]|[\x041d\x043d][\x0406\x0456])$", L"\x0442\x0430\x043a", L"\x043d\x0456" }, + { "unm_US", L"^[+1yY]", L"^[-0kKmM]", L"", L"" }, + { "ur_IN", L"^[+1yY\x06c1]", L"^[-0nN\x0646]", L"\x06c1\x0627\x06ba", L"\x0646\x06c1\x06cc\x06ba" }, + { "ur_PK", L"^[+1yY\x0647\x0628\x0066]", L"^[-0nN\x0646o]", L"\x06c1\x0627\x06ba", L"\x0646\x06c1\x06cc\x06ba" }, + { "uz_UZ", L"^[+1hH\x04b2\x04b3]", L"^[-0nNyYjJ\x0419\x0439]", L"ha", L"yo\x2018q" }, + { "uz_UZ@cyrillic", L"^[+1hH\x04b2\x04b3]", L"^[-0nNyYjJ\x0419\x0439]", L"\x04b3\x0430", L"\x0439\x045e\x049b" }, + { "ve_ZA", L"^[+1yYeE]", L"^[-0nNhH]", L"", L"" }, + { "vi_VN", L"^[+1yYcC]", L"^[-0nNkK]", L"C\x00f3", L"Kh\x00f4ng" }, + { "wa_BE", L"^[+1oOyYaAwW]", L"^[-0nN]", L"Oyi", L"Neni" }, + { "wa_BE@euro", L"^[+1oOyYaAwW]", L"^[-0nN]", L"Oyi", L"Neni" }, + { "wae_CH", L"^[+1jJyY]", L"^[-0nN]", L"ja", L"nei" }, + { "wal_ET", L"^[+1\x12a5yY]", L"^[-0\x1290nN]", L"\x12a5\x12c8", L"\x1290\x1296\x12a5" }, + { "wo_SN", L"^[+1wWyY]", L"^[-0dDnN]", L"waaw", L"d\x00e9\x0065\x0064\x0065t" }, + { "xh_ZA", L"^[+1yYeE]", L"^[-0nNhH]", L"ewe", L"hayi" }, + { "yi_US", L"^[+1yY\x05d9]", L"^[-0nN\x05e0\x05e7]", L"\x05d9\x05d0\x05b8", L"\x05e7\x05f2\x05df" }, + { "yo_NG", L"^[+1EeyYNn]", L"^[-0rROoKk]", L"B\x1eb9\x0301\x1eb9\x0300ni", L"B\x1eb9\x0301\x1eb9\x0300k\x1ecd\x0301" }, + { "yue_HK", L"^[+1yY]", L"^[-0nN]", L"\x4fc2", L"\x5514\x4fc2" }, + { "yuw_PG", L"^[+1yY\x00f6\x00d6]", L"^[-0nNmM]", L"\x00f6\x00f6", L"muuno" }, + { "zh_CN", L"^[+1yY\xff59\xff39\x662f]", L"^[-0nN\xff4e\xff2e\x4e0d\x5426]", L"\x662f", L"\x4e0d\x662f" }, + { "zh_HK", L"^[+1yY\xff59\xff39\x662f]", L"^[-0nN\xff4e\xff2e\x4e0d\x5426]", L"\x662f", L"\x5426" }, + { "zh_SG", L"^[+1yY\xff59\xff39\x662f]", L"^[-0nN\xff4e\xff2e\x4e0d\x5426]", L"\x662f", L"\x4e0d\x662f" }, + { "zh_TW", L"^[+1yY\xff59\xff39\x662f]", L"^[-0nN\xff4e\xff2e\x4e0d\x5426]", L"\x662f", L"\x4e0d\x662f" }, + { "zu_ZA", L"^[+1yY]", L"^[-0nNcC]", L"yebo", L"cha" }, }; From 4c79da8017946147ab128ced1d74907ad0448603 Mon Sep 17 00:00:00 2001 From: Michael Haubenwallner Date: Tue, 30 Apr 2019 16:14:09 +0200 Subject: [PATCH 368/475] Cygwin: dll_list: drop FILE_BASIC_INFORMATION Querying FILE_BASIC_INFORMATION is needless since using win pid+threadid for forkables dirname rather than newest last write time. --- winsup/cygwin/dll_init.cc | 1 - winsup/cygwin/dll_init.h | 1 - winsup/cygwin/forkable.cc | 7 +++---- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/winsup/cygwin/dll_init.cc b/winsup/cygwin/dll_init.cc index 4baa48dc1..28f4e53a8 100644 --- a/winsup/cygwin/dll_init.cc +++ b/winsup/cygwin/dll_init.cc @@ -372,7 +372,6 @@ dll_list::alloc (HINSTANCE h, per_process *p, dll_type type) d->image_size = ((pefile*)h)->optional_hdr ()->SizeOfImage; d->preferred_base = (void*) ((pefile*)h)->optional_hdr()->ImageBase; d->type = type; - d->fbi.FileAttributes = INVALID_FILE_ATTRIBUTES; d->fii.IndexNumber.QuadPart = -1LL; if (!forkntsize) d->forkable_ntname = NULL; diff --git a/winsup/cygwin/dll_init.h b/winsup/cygwin/dll_init.h index c4a133f01..0a9749638 100644 --- a/winsup/cygwin/dll_init.h +++ b/winsup/cygwin/dll_init.h @@ -59,7 +59,6 @@ struct dll DWORD image_size; void* preferred_base; PWCHAR modname; - FILE_BASIC_INFORMATION fbi; FILE_INTERNAL_INFORMATION fii; PWCHAR forkable_ntname; WCHAR ntname[1]; /* must be the last data member */ diff --git a/winsup/cygwin/forkable.cc b/winsup/cygwin/forkable.cc index 4580610b1..30833c406 100644 --- a/winsup/cygwin/forkable.cc +++ b/winsup/cygwin/forkable.cc @@ -158,7 +158,7 @@ rmdirs (WCHAR ntmaxpathbuf[NT_MAX_PATH]) static bool stat_real_file_once (dll *d) { - if (d->fbi.FileAttributes != INVALID_FILE_ATTRIBUTES) + if (d->fii.IndexNumber.QuadPart != -1LL) return true; tmp_pathbuf tp; @@ -194,13 +194,12 @@ stat_real_file_once (dll *d) if (fhandle == INVALID_HANDLE_VALUE) return false; - if (!dll_list::read_fii (fhandle, &d->fii) || - !dll_list::read_fbi (fhandle, &d->fbi)) + if (!dll_list::read_fii (fhandle, &d->fii)) system_printf ("WARNING: Unable to read real file attributes for %W", pmsi1->SectionFileName.Buffer); NtClose (fhandle); - return d->fbi.FileAttributes != INVALID_FILE_ATTRIBUTES; + return d->fii.IndexNumber.QuadPart != -1LL; } /* easy use of NtOpenFile */ From 0f5776c47ca08c31c939f4b9faf6c105b61fa688 Mon Sep 17 00:00:00 2001 From: Michael Haubenwallner Date: Tue, 30 Apr 2019 16:14:55 +0200 Subject: [PATCH 369/475] Cygwin: dll_list: stat_real_file_once as dll method Make stat_real_file_once a method of struct dll, to be more flexible on where to use. Also, debug print memory section name queried for a dll. This is a preparation to query the file id when loading the dll. --- winsup/cygwin/dll_init.h | 1 + winsup/cygwin/forkable.cc | 22 ++++++++++++---------- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/winsup/cygwin/dll_init.h b/winsup/cygwin/dll_init.h index 0a9749638..e4fbde867 100644 --- a/winsup/cygwin/dll_init.h +++ b/winsup/cygwin/dll_init.h @@ -65,6 +65,7 @@ struct dll void detach (); int init (); + bool stat_real_file_once (); void nominate_forkable (PCWCHAR); bool create_forkable (); void run_dtors () diff --git a/winsup/cygwin/forkable.cc b/winsup/cygwin/forkable.cc index 30833c406..912a9ac8c 100644 --- a/winsup/cygwin/forkable.cc +++ b/winsup/cygwin/forkable.cc @@ -155,10 +155,10 @@ rmdirs (WCHAR ntmaxpathbuf[NT_MAX_PATH]) file name, as GetModuleFileNameW () yields the as-loaded name. While we have the file handle open, also read the attributes. NOTE: Uses dll_list::nt_max_path_buf (). */ -static bool -stat_real_file_once (dll *d) +bool +dll::stat_real_file_once () { - if (d->fii.IndexNumber.QuadPart != -1LL) + if (fii.IndexNumber.QuadPart != -1LL) return true; tmp_pathbuf tp; @@ -171,35 +171,37 @@ stat_real_file_once (dll *d) RtlInitEmptyUnicodeString (&msi2.SectionFileName, tp.w_get (), 65535); /* Retry opening the real file name until that does not change any more. */ - status = NtQueryVirtualMemory (NtCurrentProcess (), d->handle, + status = NtQueryVirtualMemory (NtCurrentProcess (), handle, MemorySectionName, pmsi1, 65536, NULL); while (NT_SUCCESS (status) && !RtlEqualUnicodeString (&msi2.SectionFileName, &pmsi1->SectionFileName, FALSE)) { + debug_printf ("for %s at %p got memory section name '%W'", + ntname, handle, pmsi1->SectionFileName.Buffer); RtlCopyUnicodeString (&msi2.SectionFileName, &pmsi1->SectionFileName); if (fhandle != INVALID_HANDLE_VALUE) NtClose (fhandle); pmsi1->SectionFileName.Buffer[pmsi1->SectionFileName.Length] = L'\0'; fhandle = dll_list::ntopenfile (pmsi1->SectionFileName.Buffer, &fstatus); - status = NtQueryVirtualMemory (NtCurrentProcess (), d->handle, + status = NtQueryVirtualMemory (NtCurrentProcess (), handle, MemorySectionName, pmsi1, 65536, NULL); } if (!NT_SUCCESS (status)) system_printf ("WARNING: Unable (ntstatus %y) to query real file for %W", - status, d->ntname); + status, ntname); else if (fhandle == INVALID_HANDLE_VALUE) system_printf ("WARNING: Unable (ntstatus %y) to open real file for %W", - fstatus, d->ntname); + fstatus, ntname); if (fhandle == INVALID_HANDLE_VALUE) return false; - if (!dll_list::read_fii (fhandle, &d->fii)) + if (!dll_list::read_fii (fhandle, &fii)) system_printf ("WARNING: Unable to read real file attributes for %W", pmsi1->SectionFileName.Buffer); NtClose (fhandle); - return d->fii.IndexNumber.QuadPart != -1LL; + return fii.IndexNumber.QuadPart != -1LL; } /* easy use of NtOpenFile */ @@ -605,7 +607,7 @@ dll_list::prepare_forkables_nomination () { dll *d = &dlls.start; while ((d = d->next)) - stat_real_file_once (d); /* uses nt_max_path_buf () */ + d->stat_real_file_once (); /* uses nt_max_path_buf () */ PWCHAR pbuf = nt_max_path_buf (); From e33db96a14b85d2a2a414de784013637bc4e1fcc Mon Sep 17 00:00:00 2001 From: Michael Haubenwallner Date: Tue, 30 Apr 2019 16:15:30 +0200 Subject: [PATCH 370/475] Cygwin: dll_list: query dll file id at load time NtQueryVirtualMemory for MemorySectionName does not reliable return the changed dll file name when another process does move the file around, and we may end up creating forkable hardlinks to wrong dll files. So query the file id when loading the dll rather than before fork. --- winsup/cygwin/dll_init.cc | 2 ++ winsup/cygwin/forkable.cc | 4 ---- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/winsup/cygwin/dll_init.cc b/winsup/cygwin/dll_init.cc index 28f4e53a8..4ba1bd22d 100644 --- a/winsup/cygwin/dll_init.cc +++ b/winsup/cygwin/dll_init.cc @@ -380,6 +380,8 @@ dll_list::alloc (HINSTANCE h, per_process *p, dll_type type) d->forkable_ntname = d->ntname + ntnamelen + 1; *d->forkable_ntname = L'\0'; } + if (forkables_supported ()) + d->stat_real_file_once (); /* uses nt_max_path_buf () */ append (d); if (type == DLL_LOAD) loaded_dlls++; diff --git a/winsup/cygwin/forkable.cc b/winsup/cygwin/forkable.cc index 912a9ac8c..e78784c2f 100644 --- a/winsup/cygwin/forkable.cc +++ b/winsup/cygwin/forkable.cc @@ -605,10 +605,6 @@ dll_list::forkable_ntnamesize (dll_type type, PCWCHAR fullntname, PCWCHAR modnam void dll_list::prepare_forkables_nomination () { - dll *d = &dlls.start; - while ((d = d->next)) - d->stat_real_file_once (); /* uses nt_max_path_buf () */ - PWCHAR pbuf = nt_max_path_buf (); bool needsep = false; From 4ac32559c0907c45e09249c0b255532cf72e8fe0 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Tue, 30 Apr 2019 18:47:02 +0200 Subject: [PATCH 371/475] Cygwin: Add release info for 3.0.7 Signed-off-by: Corinna Vinschen (cherry picked from commit 01c253a4c58b6c1da01615431bdc4c88fcba48ea) --- winsup/cygwin/release/3.0.7 | 16 ++++++++++++++++ winsup/doc/new-features.xml | 5 +++++ 2 files changed, 21 insertions(+) create mode 100644 winsup/cygwin/release/3.0.7 diff --git a/winsup/cygwin/release/3.0.7 b/winsup/cygwin/release/3.0.7 new file mode 100644 index 000000000..1dbbc5341 --- /dev/null +++ b/winsup/cygwin/release/3.0.7 @@ -0,0 +1,16 @@ +What's new: +----------- + + +What changed: +------------- + +- Updated era and message locale data, in particular add era data for + the new Tennō. + + +Bug Fixes +--------- + +- Fix WinSock error mapping to POSIX error codes. + Addresses: https://cygwin.com/ml/cygwin/2019-04/msg00160.html diff --git a/winsup/doc/new-features.xml b/winsup/doc/new-features.xml index 376789cda..1ce011e3b 100644 --- a/winsup/doc/new-features.xml +++ b/winsup/doc/new-features.xml @@ -31,6 +31,11 @@ third parameter, follow it after returning from the handler. + +Updated era and message locale data, in particular add era data for +the new Tennō. + + Support for CLOCK_REALTIME_COARSE, CLOCK_MONOTONIC_COARSE, CLOCK_MONOTONIC_RAW, CLOCK_BOOTTIME, CLOCK_REALTIME_ALARM, From b6ebca61e3c745e4db417a23c270e353f44d398d Mon Sep 17 00:00:00 2001 From: Michael Haubenwallner Date: Thu, 2 May 2019 10:05:25 +0200 Subject: [PATCH 372/475] Cygwin: dll_list: drop unused read_fbi method --- winsup/cygwin/dll_init.h | 1 - winsup/cygwin/forkable.cc | 23 ----------------------- 2 files changed, 24 deletions(-) diff --git a/winsup/cygwin/dll_init.h b/winsup/cygwin/dll_init.h index e4fbde867..3c274cf35 100644 --- a/winsup/cygwin/dll_init.h +++ b/winsup/cygwin/dll_init.h @@ -119,7 +119,6 @@ public: ULONG openopts = 0, ACCESS_MASK access = 0, HANDLE rootDir = NULL); static bool read_fii (HANDLE fh, PFILE_INTERNAL_INFORMATION pfii); - static bool read_fbi (HANDLE fh, PFILE_BASIC_INFORMATION pfbi); static PWCHAR form_ntname (PWCHAR ntbuf, size_t bufsize, PCWCHAR name); static PWCHAR form_shortname (PWCHAR shortbuf, size_t bufsize, PCWCHAR name); static PWCHAR nt_max_path_buf () diff --git a/winsup/cygwin/forkable.cc b/winsup/cygwin/forkable.cc index e78784c2f..1dcafe5e1 100644 --- a/winsup/cygwin/forkable.cc +++ b/winsup/cygwin/forkable.cc @@ -268,29 +268,6 @@ dll_list::read_fii (HANDLE fh, PFILE_INTERNAL_INFORMATION pfii) return true; } -bool -dll_list::read_fbi (HANDLE fh, PFILE_BASIC_INFORMATION pfbi) -{ - pfbi->FileAttributes = INVALID_FILE_ATTRIBUTES; - pfbi->LastWriteTime.QuadPart = -1LL; - - NTSTATUS status; - IO_STATUS_BLOCK iosb; - status = NtQueryInformationFile (fh, &iosb, - pfbi, sizeof (*pfbi), - FileBasicInformation); - if (!NT_SUCCESS (status)) - { - system_printf ("WARNING: %y = NtQueryInformationFile (%p," - " BasicInfo, io.Status %y)", - status, fh, iosb.Status); - pfbi->FileAttributes = INVALID_FILE_ATTRIBUTES; - pfbi->LastWriteTime.QuadPart = -1LL; - return false; - } - return true; -} - /* Into buf if not NULL, write the IndexNumber in pli. Return the number of characters (that would be) written. */ static int From 674b4fe995d28a140cd2f1fec856d27b53ea62a9 Mon Sep 17 00:00:00 2001 From: Ken Brown Date: Thu, 9 May 2019 10:41:41 -0400 Subject: [PATCH 373/475] Revert "Cygwin: check for STATUS_PENDING in fhandler_base::raw_read" This reverts commit 10bf30bebf7feebbc3e376cbcac62a242cc240f3. It was made because an incorrect implementation of duplex FIFOs. --- winsup/cygwin/fhandler.cc | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/winsup/cygwin/fhandler.cc b/winsup/cygwin/fhandler.cc index a0c3dcce2..b0c9c50c3 100644 --- a/winsup/cygwin/fhandler.cc +++ b/winsup/cygwin/fhandler.cc @@ -215,23 +215,11 @@ fhandler_base::raw_read (void *ptr, size_t& len) NTSTATUS status; IO_STATUS_BLOCK io; int try_noreserve = 1; - DWORD waitret = WAIT_OBJECT_0; retry: status = NtReadFile (get_handle (), NULL, NULL, NULL, &io, ptr, len, NULL, NULL); - if (status == STATUS_PENDING) - { - waitret = cygwait (get_handle (), cw_infinite, - cw_cancel | cw_sig_eintr); - if (waitret == WAIT_OBJECT_0) - status = io.Status; - } - if (waitret == WAIT_CANCELED) - pthread::static_cancel_self (); - else if (waitret == WAIT_SIGNALED) - set_errno (EINTR); - else if (NT_SUCCESS (status)) + if (NT_SUCCESS (status)) len = io.Information; else { From 1372021a2dc380946f9d8b549315975205132413 Mon Sep 17 00:00:00 2001 From: Ken Brown Date: Thu, 9 May 2019 10:47:47 -0400 Subject: [PATCH 374/475] Cygwin: FIFO: remove incorrect duplexer code raw_read had some code that was based on an incorrect implementation of duplexers. --- winsup/cygwin/fhandler_fifo.cc | 23 ++++++++--------------- 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/winsup/cygwin/fhandler_fifo.cc b/winsup/cygwin/fhandler_fifo.cc index a1e395bf6..dd59eb6e0 100644 --- a/winsup/cygwin/fhandler_fifo.cc +++ b/winsup/cygwin/fhandler_fifo.cc @@ -780,21 +780,14 @@ fhandler_fifo::raw_read (void *in_ptr, size_t& len) fifo_client_unlock (); return; } - /* If the pipe is empty, we usually get nread == -1 with - ERROR_NO_DATA or ERROR_PIPE_LISTENING. An exception is - that in the duplex case we may get nread == 0 when we - attempt to read from the duplex pipe (fc_handler[0]). */ - else if (nread < 0) - switch (GetLastError ()) - { - case ERROR_NO_DATA: - case ERROR_PIPE_LISTENING: - break; - default: - fifo_client_unlock (); - goto errout; - } - else if (nread == 0 && (!duplexer || i > 0)) + /* If the pipe is empty, we get nread == -1 with + ERROR_NO_DATA. */ + else if (nread < 0 && GetLastError () != ERROR_NO_DATA) + { + fifo_client_unlock (); + goto errout; + } + else if (nread == 0) /* Client has disconnected. */ { fc_handler[i].state = fc_invalid; From f3d1fe2ff81ad6f5327caa9229626e39101da2c9 Mon Sep 17 00:00:00 2001 From: Ken Brown Date: Thu, 9 May 2019 10:58:29 -0400 Subject: [PATCH 375/475] Cygwin: FIFO: add 'record_connection' method Future commits will have to re-use the code for recording a client connection. For convenience, factor out this code into a new method. --- winsup/cygwin/fhandler.h | 1 + winsup/cygwin/fhandler_fifo.cc | 23 ++++++++++++++--------- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h index f5ed61cc4..3b2b194e8 100644 --- a/winsup/cygwin/fhandler.h +++ b/winsup/cygwin/fhandler.h @@ -1279,6 +1279,7 @@ class fhandler_fifo: public fhandler_base void delete_client_handler (int); bool listen_client (); int stop_listen_client (); + void record_connection (fifo_client_handler&); public: fhandler_fifo (); bool hit_eof (); diff --git a/winsup/cygwin/fhandler_fifo.cc b/winsup/cygwin/fhandler_fifo.cc index dd59eb6e0..8dfe49662 100644 --- a/winsup/cygwin/fhandler_fifo.cc +++ b/winsup/cygwin/fhandler_fifo.cc @@ -300,6 +300,19 @@ fhandler_fifo::listen_client () return true; } +void +fhandler_fifo::record_connection (fifo_client_handler& fc) +{ + fifo_client_lock (); + fc.state = fc_connected; + nconnected++; + set_pipe_non_blocking (fc.fh->get_handle (), true); + fifo_client_unlock (); + HANDLE evt = InterlockedExchangePointer (&fc.connect_evt, NULL); + if (evt) + CloseHandle (evt); +} + DWORD fhandler_fifo::listen_client_thread () { @@ -363,19 +376,11 @@ fhandler_fifo::listen_client_thread () break; } } - HANDLE evt = NULL; switch (status) { case STATUS_SUCCESS: case STATUS_PIPE_CONNECTED: - fifo_client_lock (); - fc.state = fc_connected; - nconnected++; - set_pipe_non_blocking (fc.fh->get_handle (), true); - evt = InterlockedExchangePointer (&fc.connect_evt, NULL); - if (evt) - CloseHandle (evt); - fifo_client_unlock (); + record_connection (fc); break; case STATUS_PIPE_LISTENING: /* Retry. */ From 00b2e56d3184231264005d6b1f60b1f40023907b Mon Sep 17 00:00:00 2001 From: Ken Brown Date: Thu, 9 May 2019 11:23:44 -0400 Subject: [PATCH 376/475] Cygwin: FIFO: re-implement duplexers When opening a duplexer, open a client connection to the first client handler. Previously we gave the duplexer a bogus write handle, which was just a duplicate of the first client handler's handle. This meant that we had a pipe server with no clients connected, and all I/O attempts failed with STATUS_PIPE_LISTENING. Extend the last fcntl change to duplexers. Remove a now unused fifo_client_handler constructor, as well as the long unusued method fifo_client_handler::connect. Don't create the pipe in duplex mode; the server handle will only be used for reading. --- winsup/cygwin/fhandler.h | 4 --- winsup/cygwin/fhandler_fifo.cc | 45 ++++++++++------------------------ 2 files changed, 13 insertions(+), 36 deletions(-) diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h index 3b2b194e8..16165c42f 100644 --- a/winsup/cygwin/fhandler.h +++ b/winsup/cygwin/fhandler.h @@ -1251,10 +1251,6 @@ struct fifo_client_handler fifo_client_connect_state state; HANDLE connect_evt; fifo_client_handler () : fh (NULL), state (fc_unknown), connect_evt (NULL) {} - fifo_client_handler (fhandler_base *_fh, fifo_client_connect_state _state, - HANDLE _connect_evt) - : fh (_fh), state (_state), connect_evt (_connect_evt) {} - int connect (); int close (); }; diff --git a/winsup/cygwin/fhandler_fifo.cc b/winsup/cygwin/fhandler_fifo.cc index 8dfe49662..1a1610998 100644 --- a/winsup/cygwin/fhandler_fifo.cc +++ b/winsup/cygwin/fhandler_fifo.cc @@ -175,8 +175,6 @@ fhandler_fifo::create_pipe_instance (bool first) } access = GENERIC_READ | FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES | SYNCHRONIZE; - if (first && duplexer) - access |= GENERIC_WRITE; sharing = FILE_SHARE_READ | FILE_SHARE_WRITE; hattr = OBJ_INHERIT; if (first) @@ -474,41 +472,23 @@ fhandler_fifo::open (int flags, mode_t) /* If we're a duplexer, create the pipe and the first client handler. */ if (duplexer) { - HANDLE ph, connect_evt; - fhandler_base *fh; - - ph = create_pipe_instance (true); - if (!ph) + if (add_client_handler () < 0) { res = error_errno_set; goto out; } - set_handle (ph); - set_pipe_non_blocking (ph, true); - if (!(fh = build_fh_dev (dev ()))) + NTSTATUS status = open_pipe (); + if (NT_SUCCESS (status)) { - set_errno (EMFILE); + record_connection (fc_handler[0]); + set_pipe_non_blocking (get_handle (), flags & O_NONBLOCK); + } + else + { + __seterrno_from_nt_status (status); res = error_errno_set; goto out; } - if (!DuplicateHandle (GetCurrentProcess (), ph, GetCurrentProcess (), - &fh->get_handle (), 0, true, DUPLICATE_SAME_ACCESS)) - { - res = error_set_errno; - fh->close (); - delete fh; - goto out; - } - fh->set_flags (flags); - if (!(connect_evt = create_event ())) - { - res = error_errno_set; - fh->close (); - delete fh; - goto out; - } - fc_handler[0] = fifo_client_handler (fh, fc_connected, connect_evt); - nconnected = nhandlers = 1; } /* If we're reading, start the listen_client thread (which should @@ -889,12 +869,13 @@ fhandler_fifo::close () return fhandler_base::close () || ret; } -/* If we're a writer, keep the nonblocking state of the windows pipe - in sync with our nonblocking state. */ +/* If we have a write handle (i.e., we're a duplexer or a writer), + keep the nonblocking state of the windows pipe in sync with our + nonblocking state. */ int fhandler_fifo::fcntl (int cmd, intptr_t arg) { - if (cmd != F_SETFL || !writer) + if (cmd != F_SETFL || nohandle ()) return fhandler_base::fcntl (cmd, arg); const bool was_nonblocking = is_nonblocking (); From 816c6da53a86edf7f734cab0cd146b6813a220de Mon Sep 17 00:00:00 2001 From: Ken Brown Date: Thu, 9 May 2019 11:36:26 -0400 Subject: [PATCH 377/475] Cygwin: FIFO: add a HANDLE parameter to open_pipe It's now up to the caller to pass a handle to open_pipe and, if desired, to call set_handle on return. This will be useful for a future commit, in which we will open a client connection without setting an io_handle. --- winsup/cygwin/fhandler.h | 2 +- winsup/cygwin/fhandler_fifo.cc | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h index 16165c42f..683aae15c 100644 --- a/winsup/cygwin/fhandler.h +++ b/winsup/cygwin/fhandler.h @@ -1270,7 +1270,7 @@ class fhandler_fifo: public fhandler_base bool __reg2 wait (HANDLE); NTSTATUS npfs_handle (HANDLE &); HANDLE create_pipe_instance (bool); - NTSTATUS open_pipe (); + NTSTATUS open_pipe (HANDLE&); int add_client_handler (); void delete_client_handler (int); bool listen_client (); diff --git a/winsup/cygwin/fhandler_fifo.cc b/winsup/cygwin/fhandler_fifo.cc index 1a1610998..4d05727cb 100644 --- a/winsup/cygwin/fhandler_fifo.cc +++ b/winsup/cygwin/fhandler_fifo.cc @@ -194,9 +194,9 @@ fhandler_fifo::create_pipe_instance (bool first) return ph; } -/* Called when a FIFO is opened for writing. */ +/* Connect to a pipe instance. */ NTSTATUS -fhandler_fifo::open_pipe () +fhandler_fifo::open_pipe (HANDLE& ph) { NTSTATUS status; HANDLE npfsh; @@ -204,7 +204,6 @@ fhandler_fifo::open_pipe () OBJECT_ATTRIBUTES attr; IO_STATUS_BLOCK io; ULONG sharing; - HANDLE ph = NULL; status = npfs_handle (npfsh); if (!NT_SUCCESS (status)) @@ -214,8 +213,6 @@ fhandler_fifo::open_pipe () npfsh, NULL); sharing = FILE_SHARE_READ | FILE_SHARE_WRITE; status = NtOpenFile (&ph, access, &attr, &io, sharing, 0); - if (NT_SUCCESS (status)) - set_handle (ph); return status; } @@ -472,16 +469,19 @@ fhandler_fifo::open (int flags, mode_t) /* If we're a duplexer, create the pipe and the first client handler. */ if (duplexer) { + HANDLE ph = NULL; + if (add_client_handler () < 0) { res = error_errno_set; goto out; } - NTSTATUS status = open_pipe (); + NTSTATUS status = open_pipe (ph); if (NT_SUCCESS (status)) { record_connection (fc_handler[0]); - set_pipe_non_blocking (get_handle (), flags & O_NONBLOCK); + set_handle (ph); + set_pipe_non_blocking (ph, flags & O_NONBLOCK); } else { @@ -525,7 +525,7 @@ fhandler_fifo::open (int flags, mode_t) res = error_errno_set; goto out; } - NTSTATUS status = open_pipe (); + NTSTATUS status = open_pipe (get_handle ()); if (NT_SUCCESS (status)) { set_pipe_non_blocking (get_handle (), flags & O_NONBLOCK); From c12053a793246742f7c7a177b9e7656c602c52d2 Mon Sep 17 00:00:00 2001 From: Ken Brown Date: Thu, 9 May 2019 11:55:30 -0400 Subject: [PATCH 378/475] Cygwin: FIFO: don't leave a pending listen request On exit from the listen_client thread, make sure there's no pending FSCTL_PIPE_LISTEN request. Otherwise we might get a client connection after restarting the thread, and we won't have a handle for communicating with that client. Remove the retry loop in the case of STATUS_PIPE_LISTENING; that case shouldn't occur. Remove the now-unused fc_connecting value from fifo_client_connect_state. --- winsup/cygwin/fhandler.h | 1 - winsup/cygwin/fhandler_fifo.cc | 111 ++++++++++++++++++--------------- 2 files changed, 59 insertions(+), 53 deletions(-) diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h index 683aae15c..f4c0f0301 100644 --- a/winsup/cygwin/fhandler.h +++ b/winsup/cygwin/fhandler.h @@ -1240,7 +1240,6 @@ public: enum fifo_client_connect_state { fc_unknown, - fc_connecting, fc_connected, fc_invalid }; diff --git a/winsup/cygwin/fhandler_fifo.cc b/winsup/cygwin/fhandler_fifo.cc index 4d05727cb..0d4a8b8ee 100644 --- a/winsup/cygwin/fhandler_fifo.cc +++ b/winsup/cygwin/fhandler_fifo.cc @@ -272,10 +272,7 @@ listen_client_func (LPVOID param) return fh->listen_client_thread (); } -/* Start a thread that listens for client connections. Whenever a new - client connects, it creates a new pipe_instance if necessary. - (There may already be an available instance if a client has - disconnected.) */ +/* Start a thread that listens for client connections. */ bool fhandler_fifo::listen_client () { @@ -331,70 +328,80 @@ fhandler_fifo::listen_client_thread () /* Create a new client handler. */ if (add_client_handler () < 0) - goto out; + { + fifo_client_unlock (); + goto out; + } /* Allow a writer to open. */ if (!arm (read_ready)) { + fifo_client_unlock (); __seterrno (); goto out; } - fifo_client_unlock (); /* Listen for a writer to connect to the new client handler. */ fifo_client_handler& fc = fc_handler[nhandlers - 1]; - do - { - NTSTATUS status; - IO_STATUS_BLOCK io; + NTSTATUS status; + IO_STATUS_BLOCK io; - status = NtFsControlFile (fc.fh->get_handle (), fc.connect_evt, - NULL, NULL, &io, FSCTL_PIPE_LISTEN, - NULL, 0, NULL, 0); - if (status == STATUS_PENDING) + status = NtFsControlFile (fc.fh->get_handle (), fc.connect_evt, + NULL, NULL, &io, FSCTL_PIPE_LISTEN, + NULL, 0, NULL, 0); + fifo_client_unlock (); + if (status == STATUS_PENDING) + { + HANDLE w[2] = { fc.connect_evt, lct_termination_evt }; + DWORD waitret = WaitForMultipleObjects (2, w, false, INFINITE); + switch (waitret) { - HANDLE w[2] = { fc.connect_evt, lct_termination_evt }; - DWORD waitret = WaitForMultipleObjects (2, w, false, INFINITE); - switch (waitret) - { - case WAIT_OBJECT_0: - status = io.Status; - break; - case WAIT_OBJECT_0 + 1: - ret = 0; - status = STATUS_THREAD_IS_TERMINATING; - break; - default: - __seterrno (); - debug_printf ("WaitForMultipleObjects failed, %E"); - status = STATUS_THREAD_IS_TERMINATING; - break; - } - } - switch (status) - { - case STATUS_SUCCESS: - case STATUS_PIPE_CONNECTED: - record_connection (fc); + case WAIT_OBJECT_0: + status = io.Status; break; - case STATUS_PIPE_LISTENING: - /* Retry. */ - fc.state = fc_connecting; - ResetEvent (fc.connect_evt); + case WAIT_OBJECT_0 + 1: + ret = 0; + status = STATUS_THREAD_IS_TERMINATING; break; - case STATUS_THREAD_IS_TERMINATING: - fifo_client_lock (); - delete_client_handler (nhandlers - 1); - fifo_client_unlock (); - goto out; default: - __seterrno_from_nt_status (status); - fifo_client_lock (); - delete_client_handler (nhandlers - 1); - fifo_client_unlock (); - goto out; + __seterrno (); + debug_printf ("WaitForMultipleObjects failed, %E"); + status = STATUS_THREAD_IS_TERMINATING; + break; } - } while (fc.state == fc_connecting); + } + HANDLE ph = NULL; + switch (status) + { + case STATUS_SUCCESS: + case STATUS_PIPE_CONNECTED: + record_connection (fc); + break; + case STATUS_THREAD_IS_TERMINATING: + /* Try to cancel the pending listen. Otherwise the first + writer to connect after the thread is restarted will be + invisible. + + FIXME: Is there a direct way to do this? We do it by + opening and closing a write handle to the client side. */ + open_pipe (ph); + /* We don't care about the return value of open_pipe. Even + if the latter failed, a writer might have connected. */ + if (WaitForSingleObject (fc.connect_evt, 0) == WAIT_OBJECT_0 + && (NT_SUCCESS (io.Status) || io.Status == STATUS_PIPE_CONNECTED)) + record_connection (fc); + else + fc.state = fc_invalid; + /* By closing ph we ensure that if fc connected to ph, fc + will be declared invalid on the next read attempt. */ + if (ph) + CloseHandle (ph); + goto out; + default: + __seterrno_from_nt_status (status); + fc.state = fc_invalid; + goto out; + } /* Check for thread termination in case WaitForMultipleObjects didn't get called above. */ if (IsEventSignalled (lct_termination_evt)) From 7ad80b3c233c96218985e603cfcb8051e1771505 Mon Sep 17 00:00:00 2001 From: Ken Brown Date: Thu, 9 May 2019 12:04:14 -0400 Subject: [PATCH 379/475] Cygwin: FIFO: set client handler flags more accurately Reflect the fact that client handlers are only used for reading and that, after connection, they are always nonblocking. --- winsup/cygwin/fhandler_fifo.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/winsup/cygwin/fhandler_fifo.cc b/winsup/cygwin/fhandler_fifo.cc index 0d4a8b8ee..1b1b3c7eb 100644 --- a/winsup/cygwin/fhandler_fifo.cc +++ b/winsup/cygwin/fhandler_fifo.cc @@ -246,7 +246,8 @@ fhandler_fifo::add_client_handler () else { fh->set_handle (ph); - fh->set_flags (get_flags ()); + fh->set_flags ((openflags & ~O_ACCMODE) | O_RDONLY); + fh->set_nonblocking (false); ret = 0; fc.fh = fh; fc_handler[nhandlers++] = fc; @@ -298,6 +299,7 @@ fhandler_fifo::record_connection (fifo_client_handler& fc) fifo_client_lock (); fc.state = fc_connected; nconnected++; + fc.fh->set_nonblocking (true); set_pipe_non_blocking (fc.fh->get_handle (), true); fifo_client_unlock (); HANDLE evt = InterlockedExchangePointer (&fc.connect_evt, NULL); From 102571f85da6344591848df2c8ebc200699cb031 Mon Sep 17 00:00:00 2001 From: Ken Brown Date: Thu, 9 May 2019 12:28:21 -0400 Subject: [PATCH 380/475] Cygwin: FIFO: improve the check for the listen_client thread Add a method fhandler_fifo::check_listen_client_thread that checks whether the thread is running. Use it in raw_read instead of just testing the handle listen_client_thr. --- winsup/cygwin/fhandler.h | 1 + winsup/cygwin/fhandler_fifo.cc | 34 ++++++++++++++++++++++++++++++++-- 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h index f4c0f0301..969b23a14 100644 --- a/winsup/cygwin/fhandler.h +++ b/winsup/cygwin/fhandler.h @@ -1274,6 +1274,7 @@ class fhandler_fifo: public fhandler_base void delete_client_handler (int); bool listen_client (); int stop_listen_client (); + int check_listen_client_thread (); void record_connection (fifo_client_handler&); public: fhandler_fifo (); diff --git a/winsup/cygwin/fhandler_fifo.cc b/winsup/cygwin/fhandler_fifo.cc index 1b1b3c7eb..4bf157d39 100644 --- a/winsup/cygwin/fhandler_fifo.cc +++ b/winsup/cygwin/fhandler_fifo.cc @@ -744,13 +744,43 @@ retry: return eof; } +/* Is the lct running? */ +int +fhandler_fifo::check_listen_client_thread () +{ + int ret = 0; + + if (listen_client_thr) + { + DWORD waitret = WaitForSingleObject (listen_client_thr, 0); + switch (waitret) + { + case WAIT_OBJECT_0: + CloseHandle (listen_client_thr); + break; + case WAIT_TIMEOUT: + ret = 1; + break; + default: + debug_printf ("WaitForSingleObject failed, %E"); + ret = -1; + __seterrno (); + CloseHandle (listen_client_thr); + break; + } + } + return ret; +} + void __reg3 fhandler_fifo::raw_read (void *in_ptr, size_t& len) { size_t orig_len = len; - /* Start the listen_client thread if necessary (shouldn't be). */ - if (!listen_client_thr && !listen_client ()) + /* Make sure the lct is running. */ + int res = check_listen_client_thread (); + debug_printf ("lct status %d", res); + if (res < 0 || (res == 0 && !listen_client ())) goto errout; while (1) From 0771fc703158b67ec14d82a3bb3ec1b4b72b094c Mon Sep 17 00:00:00 2001 From: Ken Brown Date: Thu, 9 May 2019 12:32:17 -0400 Subject: [PATCH 381/475] Cygwin: FIFO: make read_ready an auto-reset event There's no point in allowing a writer to attempt to open until we've created a pipe instance. --- winsup/cygwin/fhandler_fifo.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/winsup/cygwin/fhandler_fifo.cc b/winsup/cygwin/fhandler_fifo.cc index 4bf157d39..dab7df92b 100644 --- a/winsup/cygwin/fhandler_fifo.cc +++ b/winsup/cygwin/fhandler_fifo.cc @@ -461,7 +461,7 @@ fhandler_fifo::open (int flags, mode_t) char npbuf[MAX_PATH]; __small_sprintf (npbuf, "r-event.%08x.%016X", get_dev (), get_ino ()); - if (!(read_ready = CreateEvent (sa_buf, true, false, npbuf))) + if (!(read_ready = CreateEvent (sa_buf, false, false, npbuf))) { debug_printf ("CreateEvent for %s failed, %E", npbuf); res = error_set_errno; From e91bc190ff685bca726024da353f0921660bc863 Mon Sep 17 00:00:00 2001 From: Ken Brown Date: Thu, 9 May 2019 12:35:58 -0400 Subject: [PATCH 382/475] Cygwin: FIFO: code simplifications. There's no longer a need to consider the connect_evt after fork/exec. After stopping the listen_client thread, all client handlers should be in the fc_connected or fc_invalid states, so their connect_evt members won't be used again. Also remove code in fhandler_fifo::dup that just repeats things already done in stop_listen_client. --- winsup/cygwin/fhandler_fifo.cc | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/winsup/cygwin/fhandler_fifo.cc b/winsup/cygwin/fhandler_fifo.cc index dab7df92b..3fabbc3b4 100644 --- a/winsup/cygwin/fhandler_fifo.cc +++ b/winsup/cygwin/fhandler_fifo.cc @@ -966,9 +966,6 @@ fhandler_fifo::dup (fhandler_base *child, int flags) goto out; } } - fhf->listen_client_thr = NULL; - fhf->lct_termination_evt = NULL; - fhf->fifo_client_unlock (); if (!reader || fhf->listen_client ()) ret = 0; if (reader) @@ -990,10 +987,7 @@ fhandler_fifo::fixup_after_fork (HANDLE parent) fork_fixup (parent, read_ready, "read_ready"); fork_fixup (parent, write_ready, "write_ready"); for (int i = 0; i < nhandlers; i++) - { - fc_handler[i].fh->fhandler_base::fixup_after_fork (parent); - fork_fixup (parent, fc_handler[i].connect_evt, "connect_evt"); - } + fc_handler[i].fh->fhandler_base::fixup_after_fork (parent); if (reader && !listen_client ()) debug_printf ("failed to start lct, %E"); } @@ -1013,8 +1007,5 @@ fhandler_fifo::set_close_on_exec (bool val) set_no_inheritance (read_ready, val); set_no_inheritance (write_ready, val); for (int i = 0; i < nhandlers; i++) - { - fc_handler[i].fh->fhandler_base::set_close_on_exec (val); - set_no_inheritance (fc_handler[i].connect_evt, val); - } + fc_handler[i].fh->fhandler_base::set_close_on_exec (val); } From a9a0d219a417a8079b878ce967f72997789e328a Mon Sep 17 00:00:00 2001 From: Faraz Shahbazker Date: Thu, 2 May 2019 16:16:44 +0000 Subject: [PATCH 383/475] Make .data section placement coincide with _fdata symbol The _fdata symbol in MIPS linker scripts is aligned to a 16-byte boundary. The ALIGN function does not implicitly update current location counter. If sections positioned after the assignment do not have the same natural alignment as the ALIGN function then the start of the section group will not coincide with the value of the symbol. Given the linker command sequence: symbol = ALIGN (NN); (.section*) where the idiom implies a desire to mark the beginning of .section with symbol, there must be an assignment to the location counter between the assignment to symbol and the .section pattern. libgloss/ * mips/array.ld: Update the location counter to match _fdata. * mips/cfe.ld: Likewise. * mips/ddb-kseg0.ld: Likewise. * mips/ddb.ld: Likewise. * mips/dve.ld: Likewise. * mips/idt.ld: Likewise. * mips/idt32.ld: Likewise. * mips/idt64.ld: Likewise. * mips/idtecoff.ld: Likewise. * mips/jmr3904app-java.ld: Likewise. * mips/jmr3904app.ld: Likewise. * mips/jmr3904dram-java.ld: Likewise. * mips/jmr3904dram.ld: Likewise. * mips/lsi.ld: Likewise. * mips/mti32.ld: Likewise. * mips/mti64.ld: Likewise. * mips/mti64_64.ld: Likewise. * mips/mti64_n32.ld: Likewise. * mips/nullmon.ld: Likewise. * mips/pmon.ld: Likewise. * mips/sde32.ld: Likewise. * mips/sde64.ld: Likewise. --- libgloss/mips/array.ld | 1 + libgloss/mips/cfe.ld | 1 + libgloss/mips/ddb-kseg0.ld | 1 + libgloss/mips/ddb.ld | 1 + libgloss/mips/dve.ld | 1 + libgloss/mips/idt.ld | 1 + libgloss/mips/idt32.ld | 1 + libgloss/mips/idt64.ld | 1 + libgloss/mips/idtecoff.ld | 1 + libgloss/mips/jmr3904app-java.ld | 1 + libgloss/mips/jmr3904app.ld | 1 + libgloss/mips/jmr3904dram-java.ld | 1 + libgloss/mips/jmr3904dram.ld | 1 + libgloss/mips/lsi.ld | 1 + libgloss/mips/mti32.ld | 1 + libgloss/mips/mti64.ld | 1 + libgloss/mips/mti64_64.ld | 1 + libgloss/mips/mti64_n32.ld | 1 + libgloss/mips/nullmon.ld | 1 + libgloss/mips/pmon.ld | 1 + libgloss/mips/sde32.ld | 1 + libgloss/mips/sde64.ld | 1 + 22 files changed, 22 insertions(+) diff --git a/libgloss/mips/array.ld b/libgloss/mips/array.ld index 2bc49c71b..0492ae550 100644 --- a/libgloss/mips/array.ld +++ b/libgloss/mips/array.ld @@ -148,6 +148,7 @@ SECTIONS *(.gnu.linkonce.r.*) } _fdata = ALIGN(16); + . = _fdata; .data : { *(.data) *(.data.*) diff --git a/libgloss/mips/cfe.ld b/libgloss/mips/cfe.ld index 78fb8533f..9a0f8d59d 100644 --- a/libgloss/mips/cfe.ld +++ b/libgloss/mips/cfe.ld @@ -104,6 +104,7 @@ SECTIONS *(.gnu.linkonce.r.*) } _fdata = ALIGN(16); + . = _fdata; .data : { *(.data) *(.data.*) diff --git a/libgloss/mips/ddb-kseg0.ld b/libgloss/mips/ddb-kseg0.ld index 74bc1b09c..8c1f926a1 100644 --- a/libgloss/mips/ddb-kseg0.ld +++ b/libgloss/mips/ddb-kseg0.ld @@ -97,6 +97,7 @@ SECTIONS *(.gnu.linkonce.r.*) } _fdata = ALIGN(16); + . = _fdata; .data : { *(.data) *(.data.*) diff --git a/libgloss/mips/ddb.ld b/libgloss/mips/ddb.ld index 8fcafd361..299106fb2 100644 --- a/libgloss/mips/ddb.ld +++ b/libgloss/mips/ddb.ld @@ -97,6 +97,7 @@ SECTIONS *(.gnu.linkonce.r.*) } _fdata = ALIGN(16); + . = _fdata; .data : { *(.data) *(.data.*) diff --git a/libgloss/mips/dve.ld b/libgloss/mips/dve.ld index adce60f82..96abbbe32 100644 --- a/libgloss/mips/dve.ld +++ b/libgloss/mips/dve.ld @@ -98,6 +98,7 @@ SECTIONS *(.gnu.linkonce.r.*) } _fdata = ALIGN(16); + . = _fdata; .data : { *(.data) *(.data.*) diff --git a/libgloss/mips/idt.ld b/libgloss/mips/idt.ld index 0d69af452..b4608bfbc 100644 --- a/libgloss/mips/idt.ld +++ b/libgloss/mips/idt.ld @@ -105,6 +105,7 @@ SECTIONS *(.gnu.linkonce.r.*) } _fdata = ALIGN(16); + . = _fdata; .data : { *(.data) *(.data.*) diff --git a/libgloss/mips/idt32.ld b/libgloss/mips/idt32.ld index 175a98b61..5084df7a6 100644 --- a/libgloss/mips/idt32.ld +++ b/libgloss/mips/idt32.ld @@ -106,6 +106,7 @@ SECTIONS *(.gnu.linkonce.r.*) } _fdata = ALIGN(16); + . = _fdata; .data : { *(.data) *(.data.*) diff --git a/libgloss/mips/idt64.ld b/libgloss/mips/idt64.ld index bd217e535..a1121c663 100644 --- a/libgloss/mips/idt64.ld +++ b/libgloss/mips/idt64.ld @@ -107,6 +107,7 @@ SECTIONS *(.gnu.linkonce.r.*) } _fdata = ALIGN(16); + . = _fdata; .data : { *(.data) *(.data.*) diff --git a/libgloss/mips/idtecoff.ld b/libgloss/mips/idtecoff.ld index 2788cc824..0297c6095 100644 --- a/libgloss/mips/idtecoff.ld +++ b/libgloss/mips/idtecoff.ld @@ -57,6 +57,7 @@ SECTIONS *(.gnu.linkonce.r.*) } _fdata = ALIGN(16); + . = _fdata; .data : { *(.data) *(.data.*) diff --git a/libgloss/mips/jmr3904app-java.ld b/libgloss/mips/jmr3904app-java.ld index 98ce5357c..92de26d06 100644 --- a/libgloss/mips/jmr3904app-java.ld +++ b/libgloss/mips/jmr3904app-java.ld @@ -57,6 +57,7 @@ SECTIONS *(.gnu.linkonce.r.*) } _fdata = ALIGN(16); + . = _fdata; .data : { *(.data) *(.data.*) diff --git a/libgloss/mips/jmr3904app.ld b/libgloss/mips/jmr3904app.ld index d5b310918..367fc471b 100644 --- a/libgloss/mips/jmr3904app.ld +++ b/libgloss/mips/jmr3904app.ld @@ -96,6 +96,7 @@ SECTIONS *(.gnu.linkonce.r.*) } _fdata = ALIGN(16); + . = _fdata; .data : { *(.data) *(.data.*) diff --git a/libgloss/mips/jmr3904dram-java.ld b/libgloss/mips/jmr3904dram-java.ld index 71e84032e..4c0681a4b 100644 --- a/libgloss/mips/jmr3904dram-java.ld +++ b/libgloss/mips/jmr3904dram-java.ld @@ -59,6 +59,7 @@ SECTIONS *(.gnu.linkonce.r.*) } _fdata = ALIGN(16); + . = _fdata; .data : { *(.data) *(.data.*) diff --git a/libgloss/mips/jmr3904dram.ld b/libgloss/mips/jmr3904dram.ld index a2cb1eae5..9e7d25545 100644 --- a/libgloss/mips/jmr3904dram.ld +++ b/libgloss/mips/jmr3904dram.ld @@ -56,6 +56,7 @@ SECTIONS *(.gnu.linkonce.r.*) } _fdata = ALIGN(16); + . = fdata; .data : { *(.data) *(.data.*) diff --git a/libgloss/mips/lsi.ld b/libgloss/mips/lsi.ld index ca64ab927..780c31cac 100644 --- a/libgloss/mips/lsi.ld +++ b/libgloss/mips/lsi.ld @@ -96,6 +96,7 @@ SECTIONS *(.gnu.linkonce.r.*) } _fdata = ALIGN(16); + . = _fdata; .data : { *(.data) *(.data.*) diff --git a/libgloss/mips/mti32.ld b/libgloss/mips/mti32.ld index 41592d12a..3c8daf6f1 100644 --- a/libgloss/mips/mti32.ld +++ b/libgloss/mips/mti32.ld @@ -110,6 +110,7 @@ SECTIONS *(.gnu.linkonce.r.*) } _fdata = ALIGN(16); + . = _fdata; .data : { *(.data) *(.data.*) diff --git a/libgloss/mips/mti64.ld b/libgloss/mips/mti64.ld index 8a47c4760..74d778412 100644 --- a/libgloss/mips/mti64.ld +++ b/libgloss/mips/mti64.ld @@ -113,6 +113,7 @@ SECTIONS *(.gnu.linkonce.r.*) } _fdata = ALIGN(16); + . = _fdata; .data : { *(.data) *(.data.*) diff --git a/libgloss/mips/mti64_64.ld b/libgloss/mips/mti64_64.ld index 81704f065..d33d156b4 100644 --- a/libgloss/mips/mti64_64.ld +++ b/libgloss/mips/mti64_64.ld @@ -116,6 +116,7 @@ SECTIONS *(.gnu.linkonce.r.*) } _fdata = ALIGN(16); + . = _fdata; .data : { *(.data) *(.data.*) diff --git a/libgloss/mips/mti64_n32.ld b/libgloss/mips/mti64_n32.ld index 6c5380934..5098a88d0 100644 --- a/libgloss/mips/mti64_n32.ld +++ b/libgloss/mips/mti64_n32.ld @@ -116,6 +116,7 @@ SECTIONS *(.gnu.linkonce.r.*) } _fdata = ALIGN(16); + . = _fdata; .data : { *(.data) *(.data.*) diff --git a/libgloss/mips/nullmon.ld b/libgloss/mips/nullmon.ld index 14b0d0e59..5ea8b59ac 100644 --- a/libgloss/mips/nullmon.ld +++ b/libgloss/mips/nullmon.ld @@ -99,6 +99,7 @@ SECTIONS *(.gnu.linkonce.r.*) } _fdata = ALIGN(16); + . = _fdata; .data : { *(.data) *(.data.*) diff --git a/libgloss/mips/pmon.ld b/libgloss/mips/pmon.ld index 244c1f65b..fff6f6696 100644 --- a/libgloss/mips/pmon.ld +++ b/libgloss/mips/pmon.ld @@ -99,6 +99,7 @@ SECTIONS *(.gnu.linkonce.r.*) } _fdata = ALIGN(16); + . = _fdata; .data : { *(.data) *(.data.*) diff --git a/libgloss/mips/sde32.ld b/libgloss/mips/sde32.ld index 657f5f31b..7273107c1 100644 --- a/libgloss/mips/sde32.ld +++ b/libgloss/mips/sde32.ld @@ -106,6 +106,7 @@ SECTIONS *(.gnu.linkonce.r.*) } _fdata = ALIGN(16); + . = _fdata; .data : { *(.data) *(.data.*) diff --git a/libgloss/mips/sde64.ld b/libgloss/mips/sde64.ld index e3a0f298b..0bcbe98f3 100644 --- a/libgloss/mips/sde64.ld +++ b/libgloss/mips/sde64.ld @@ -108,6 +108,7 @@ SECTIONS *(.gnu.linkonce.r.*) } _fdata = ALIGN(16); + . = _fdata; .data : { *(.data) *(.data.*) From 5c86f0da5f07791c01477380a0635c6d38a9b33b Mon Sep 17 00:00:00 2001 From: Jim Wilson Date: Wed, 22 May 2019 17:36:57 -0700 Subject: [PATCH 384/475] RISC-V: Add size optimized memcpy, memmove, memset and strcmp. This patch adds implementations of memcpy, memmove, memset and strcmp optimized for size. The changes have been tested in riscv/riscv-gnu-toolchain by riscv-dejagnu with riscv-sim.exp/riscv-sim-nano.exp. --- newlib/libc/machine/riscv/Makefile.am | 3 +- newlib/libc/machine/riscv/Makefile.in | 23 +++++++++++++- newlib/libc/machine/riscv/memcpy-asm.S | 32 +++++++++++++++++++ newlib/libc/machine/riscv/memcpy.c | 5 +++ newlib/libc/machine/riscv/memmove-stub.c | 14 +++++++++ newlib/libc/machine/riscv/memmove.S | 40 ++++++++++++++++++++++++ newlib/libc/machine/riscv/memset.S | 15 +++++++++ newlib/libc/machine/riscv/strcmp.S | 16 ++++++++++ 8 files changed, 146 insertions(+), 2 deletions(-) create mode 100644 newlib/libc/machine/riscv/memcpy-asm.S create mode 100644 newlib/libc/machine/riscv/memmove-stub.c create mode 100644 newlib/libc/machine/riscv/memmove.S diff --git a/newlib/libc/machine/riscv/Makefile.am b/newlib/libc/machine/riscv/Makefile.am index 676df3e88..017b4be2e 100644 --- a/newlib/libc/machine/riscv/Makefile.am +++ b/newlib/libc/machine/riscv/Makefile.am @@ -8,7 +8,8 @@ AM_CCASFLAGS = $(INCLUDES) noinst_LIBRARIES = lib.a -lib_a_SOURCES = memset.S memcpy.c strlen.c strcpy.c strcmp.S setjmp.S ieeefp.c ffs.c +lib_a_SOURCES = memmove.S memmove-stub.c memset.S memcpy-asm.S memcpy.c strlen.c \ + strcpy.c strcmp.S setjmp.S ieeefp.c ffs.c lib_a_CCASFLAGS=$(AM_CCASFLAGS) lib_a_CFLAGS=$(AM_CFLAGS) diff --git a/newlib/libc/machine/riscv/Makefile.in b/newlib/libc/machine/riscv/Makefile.in index fd6d2ef14..304dd35ae 100644 --- a/newlib/libc/machine/riscv/Makefile.in +++ b/newlib/libc/machine/riscv/Makefile.in @@ -70,6 +70,8 @@ ARFLAGS = cru lib_a_AR = $(AR) $(ARFLAGS) lib_a_LIBADD = am_lib_a_OBJECTS = lib_a-memset.$(OBJEXT) lib_a-memcpy.$(OBJEXT) \ + lib_a-memcpy-asm.$(OBJEXT) \ + lib_a-memmove.$(OBJEXT) lib_a-memmove-stub.$(OBJEXT) \ lib_a-strlen.$(OBJEXT) lib_a-strcpy.$(OBJEXT) \ lib_a-strcmp.$(OBJEXT) lib_a-setjmp.$(OBJEXT) \ lib_a-ieeefp.$(OBJEXT) lib_a-ffs.$(OBJEXT) @@ -198,7 +200,8 @@ AUTOMAKE_OPTIONS = cygnus INCLUDES = $(NEWLIB_CFLAGS) $(CROSS_CFLAGS) $(TARGET_CFLAGS) AM_CCASFLAGS = $(INCLUDES) noinst_LIBRARIES = lib.a -lib_a_SOURCES = memset.S memcpy.c strlen.c strcpy.c strcmp.S setjmp.S ieeefp.c ffs.c +lib_a_SOURCES = memcpy-asm.S memmove.S memmove-stub.c memset.S memcpy.c strlen.c \ + strcpy.c strcmp.S setjmp.S ieeefp.c ffs.c lib_a_CCASFLAGS = $(AM_CCASFLAGS) lib_a_CFLAGS = $(AM_CFLAGS) ACLOCAL_AMFLAGS = -I ../../.. -I ../../../.. @@ -261,6 +264,18 @@ distclean-compile: .S.obj: $(CPPASCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` +lib_a-memmove.o: memmove.S + $(CCAS) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CCASFLAGS) $(CCASFLAGS) -c -o lib_a-memmove.o `test -f 'memmove.S' || echo '$(srcdir)/'`memmove.S + +lib_a-memmove.obj: memmove.S + $(CCAS) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CCASFLAGS) $(CCASFLAGS) -c -o lib_a-memmove.obj `if test -f 'memmove.S'; then $(CYGPATH_W) 'memmove.S'; else $(CYGPATH_W) '$(srcdir)/memmove.S'; fi` + +lib_a-memcpy-asm.o: memcpy-asm.S + $(CCAS) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CCASFLAGS) $(CCASFLAGS) -c -o lib_a-memcpy-asm.o `test -f 'memcpy-asm.S' || echo '$(srcdir)/'`memcpy-asm.S + +lib_a-memcpy-asm.obj: memcpy-asm.S + $(CCAS) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CCASFLAGS) $(CCASFLAGS) -c -o lib_a-memcpy-asm.obj `if test -f 'memcpy-asm.S'; then $(CYGPATH_W) 'memcpy-asm.S'; else $(CYGPATH_W) '$(srcdir)/memcpy-asm.S'; fi` + lib_a-memset.o: memset.S $(CCAS) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CCASFLAGS) $(CCASFLAGS) -c -o lib_a-memset.o `test -f 'memset.S' || echo '$(srcdir)/'`memset.S @@ -285,6 +300,12 @@ lib_a-setjmp.obj: setjmp.S .c.obj: $(COMPILE) -c `$(CYGPATH_W) '$<'` +lib_a-memmove-stub.o: memmove-stub.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-memmove-stub.o `test -f 'memmove-stub.c' || echo '$(srcdir)/'`memmove-stub.c + +lib_a-memmove-stub.obj: memmove-stub.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-memmove-stub.obj `if test -f 'memmove-stub.c'; then $(CYGPATH_W) 'memmove-stub.c'; else $(CYGPATH_W) '$(srcdir)/memmove-stub.c'; fi` + lib_a-memcpy.o: memcpy.c $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-memcpy.o `test -f 'memcpy.c' || echo '$(srcdir)/'`memcpy.c diff --git a/newlib/libc/machine/riscv/memcpy-asm.S b/newlib/libc/machine/riscv/memcpy-asm.S new file mode 100644 index 000000000..5571e4704 --- /dev/null +++ b/newlib/libc/machine/riscv/memcpy-asm.S @@ -0,0 +1,32 @@ +/* Copyright (c) 2019 SiFive Inc. All rights reserved. + + This copyrighted material is made available to anyone wishing to use, + modify, copy, or redistribute it subject to the terms and conditions + of the FreeBSD License. This program is distributed in the hope that + it will be useful, but WITHOUT ANY WARRANTY expressed or implied, + including the implied warranties of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. A copy of this license is available at + http://www.opensource.org/licenses. +*/ + +#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__) +.text +.global memcpy +.type memcpy, @function +memcpy: + mv t1, a0 + beqz a2, 2f + +1: + lb t2, 0(a1) + sb t2, 0(t1) + add a2, a2, -1 + add t1, t1, 1 + add a1, a1, 1 + bnez a2, 1b + +2: + ret + + .size memcpy, .-memcpy +#endif diff --git a/newlib/libc/machine/riscv/memcpy.c b/newlib/libc/machine/riscv/memcpy.c index a0ab78a0a..07e8e0076 100644 --- a/newlib/libc/machine/riscv/memcpy.c +++ b/newlib/libc/machine/riscv/memcpy.c @@ -9,6 +9,10 @@ http://www.opensource.org/licenses. */ +#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__) +//memcpy defined in memcpy-asm.S +#else + #include #include #include "../../string/local.h" @@ -81,3 +85,4 @@ small: goto small; return aa; } +#endif diff --git a/newlib/libc/machine/riscv/memmove-stub.c b/newlib/libc/machine/riscv/memmove-stub.c new file mode 100644 index 000000000..d882e46c1 --- /dev/null +++ b/newlib/libc/machine/riscv/memmove-stub.c @@ -0,0 +1,14 @@ +/* Copyright (c) 2019 SiFive Inc. All rights reserved. + + This copyrighted material is made available to anyone wishing to use, + modify, copy, or redistribute it subject to the terms and conditions + of the FreeBSD License. This program is distributed in the hope that + it will be useful, but WITHOUT ANY WARRANTY expressed or implied, + including the implied warranties of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. A copy of this license is available at + http://www.opensource.org/licenses. +*/ + +#if !defined(PREFER_SIZE_OVER_SPEED) && !defined(__OPTIMIZE_SIZE__) +#include "../../string/memmove.c" +#endif diff --git a/newlib/libc/machine/riscv/memmove.S b/newlib/libc/machine/riscv/memmove.S new file mode 100644 index 000000000..66d9cd494 --- /dev/null +++ b/newlib/libc/machine/riscv/memmove.S @@ -0,0 +1,40 @@ +/* Copyright (c) 2019 SiFive Inc. All rights reserved. + + This copyrighted material is made available to anyone wishing to use, + modify, copy, or redistribute it subject to the terms and conditions + of the FreeBSD License. This program is distributed in the hope that + it will be useful, but WITHOUT ANY WARRANTY expressed or implied, + including the implied warranties of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. A copy of this license is available at + http://www.opensource.org/licenses. +*/ + +#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__) +.text +.global memmove +.type memmove, @function +memmove: + beqz a2, 2f + + mv t1, a0 + li a3, 1 + bgtu a1, a0, 1f + + li a3, -1 + addi a4, a2 , -1 + add t1, t1, a4 + add a1, a1, a4 + +1: + lb t2, 0(a1) + sb t2, 0(t1) + add a2, a2, -1 + add t1, t1, a3 + add a1, a1, a3 + bnez a2, 1b + +2: + ret + + .size memmove, .-memmove +#endif diff --git a/newlib/libc/machine/riscv/memset.S b/newlib/libc/machine/riscv/memset.S index 337ed5365..a717ae7fb 100644 --- a/newlib/libc/machine/riscv/memset.S +++ b/newlib/libc/machine/riscv/memset.S @@ -13,6 +13,20 @@ .global memset .type memset, @function memset: +#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__) + mv t1, a0 + beqz a2, 2f + +1: + sb a1, 0(t1) + add a2, a2, -1 + add t1, t1, 1 + bnez a2, 1b + +2: + ret + +#else li t1, 15 move a4, a0 bleu a2, t1, .Ltiny @@ -95,4 +109,5 @@ memset: add a2, a2, a5 bleu a2, t1, .Ltiny j .Laligned +#endif .size memset, .-memset diff --git a/newlib/libc/machine/riscv/strcmp.S b/newlib/libc/machine/riscv/strcmp.S index 71c08537e..eaf6d4b3c 100644 --- a/newlib/libc/machine/riscv/strcmp.S +++ b/newlib/libc/machine/riscv/strcmp.S @@ -19,6 +19,21 @@ .globl strcmp .type strcmp, @function strcmp: +#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__) +1: + lbu a2, 0(a0) + lbu a3, 0(a1) + add a0, a0, 1 + add a1, a1, 1 + bne a2, a3, 2f + bnez a2, 1b + +2: + sub a0, a2, a3 + ret + +.size strcmp, .-strcmp +#else or a4, a0, a1 li t2, -1 and a4, a4, SZREG-1 @@ -146,3 +161,4 @@ strcmp: mask: .dword 0x7f7f7f7f7f7f7f7f #endif +#endif From 77ac27dcf8ebd6ea314b32e563f3d128fe431581 Mon Sep 17 00:00:00 2001 From: Jim Wilson Date: Wed, 22 May 2019 17:41:25 -0700 Subject: [PATCH 385/475] RISC-V: Add _LITE_EXIT in crt0.S. This patch adds _LITE_EXIT in crt0.S to enable "lite exit" technique in RISC-V. The changes have been tested in riscv/riscv-gnu-toolchain by riscv-dejagnu with riscv-sim.exp/riscv-sim-nano.exp. --- libgloss/riscv/crt0.S | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/libgloss/riscv/crt0.S b/libgloss/riscv/crt0.S index 588becfae..160c07853 100644 --- a/libgloss/riscv/crt0.S +++ b/libgloss/riscv/crt0.S @@ -9,6 +9,8 @@ http://www.opensource.org/licenses. */ +#include "newlib.h" + #========================================================================= # crt0.S : Entry point for RISC-V user programs #========================================================================= @@ -30,9 +32,20 @@ _start: sub a2, a2, a0 li a1, 0 call memset +#ifdef _LITE_EXIT + # Make reference to atexit weak to avoid unconditionally pulling in + # support code. Refer to comments in __atexit.c for more details. + .weak atexit + la a0, atexit + beqz a0, .Lweak_atexit + .weak __libc_fini_array +#endif la a0, __libc_fini_array # Register global termination functions call atexit # to be called upon exit +#ifdef _LITE_EXIT +.Lweak_atexit: +#endif call __libc_init_array # Run global initialization functions lw a0, 0(sp) # a0 = argc From 5bb8d445f480ee344e81326d8387da0c4ef009c8 Mon Sep 17 00:00:00 2001 From: Ken Brown Date: Thu, 23 May 2019 08:34:09 -0400 Subject: [PATCH 386/475] Cygwin: FIFO: Open only one handle to NPFS Make npfs_handle a static member function of fhandler_fifo, as in fhandler_socket_unix. --- winsup/cygwin/fhandler.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h index 969b23a14..f244f3486 100644 --- a/winsup/cygwin/fhandler.h +++ b/winsup/cygwin/fhandler.h @@ -1267,7 +1267,7 @@ class fhandler_fifo: public fhandler_base bool reader, writer, duplexer; size_t max_atomic_write; bool __reg2 wait (HANDLE); - NTSTATUS npfs_handle (HANDLE &); + static NTSTATUS npfs_handle (HANDLE &); HANDLE create_pipe_instance (bool); NTSTATUS open_pipe (HANDLE&); int add_client_handler (); From d79aa0f5939be2640b90971d022b98054b86d249 Mon Sep 17 00:00:00 2001 From: Ken Brown Date: Tue, 28 May 2019 15:50:05 -0400 Subject: [PATCH 387/475] Cygwin: FIFO: respect the O_CLOEXEC flag Set the inheritance of the Windows pipe handles according to the O_CLOEXEC flag. Previously the pipe was always created and opened with OBJ_INHERIT. --- winsup/cygwin/fhandler_fifo.cc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/winsup/cygwin/fhandler_fifo.cc b/winsup/cygwin/fhandler_fifo.cc index 3fabbc3b4..c9ff0a309 100644 --- a/winsup/cygwin/fhandler_fifo.cc +++ b/winsup/cygwin/fhandler_fifo.cc @@ -176,7 +176,7 @@ fhandler_fifo::create_pipe_instance (bool first) access = GENERIC_READ | FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES | SYNCHRONIZE; sharing = FILE_SHARE_READ | FILE_SHARE_WRITE; - hattr = OBJ_INHERIT; + hattr = openflags & O_CLOEXEC ? 0 : OBJ_INHERIT; if (first) hattr |= OBJ_CASE_INSENSITIVE; InitializeObjectAttributes (&attr, get_pipe_name (), @@ -209,7 +209,8 @@ fhandler_fifo::open_pipe (HANDLE& ph) if (!NT_SUCCESS (status)) return status; access = GENERIC_WRITE | SYNCHRONIZE; - InitializeObjectAttributes (&attr, get_pipe_name (), OBJ_INHERIT, + InitializeObjectAttributes (&attr, get_pipe_name (), + openflags & O_CLOEXEC ? 0 : OBJ_INHERIT, npfsh, NULL); sharing = FILE_SHARE_READ | FILE_SHARE_WRITE; status = NtOpenFile (&ph, access, &attr, &io, sharing, 0); From 66e75b696133e889f514415a259d8d8d56f35d16 Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Thu, 16 May 2019 14:40:32 +0200 Subject: [PATCH 388/475] Avoid cyclic header dependencies RTEMS uses a considerable part of FreeBSD kernel and user space sources. These sources are compiled with a __FreeBSD__ define. On 2018-06-26 Gerald Pfeifer changed the GCC provided so that it includes if __FreeBSD__ is defined. The Newlib included which includes on RTEMS which includes . To get rid of this cyclic dependency move the optional _flock_t definition to . Signed-off-by: Sebastian Huber --- newlib/libc/include/sys/_types.h | 5 ----- newlib/libc/include/sys/reent.h | 5 +++++ 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/newlib/libc/include/sys/_types.h b/newlib/libc/include/sys/_types.h index fc10531d5..90383b083 100644 --- a/newlib/libc/include/sys/_types.h +++ b/newlib/libc/include/sys/_types.h @@ -22,7 +22,6 @@ #include #include #include -#include #ifndef __machine_blkcnt_t_defined typedef long __blkcnt_t; @@ -171,10 +170,6 @@ typedef struct } _mbstate_t; #endif -#ifndef __machine_flock_t_defined -typedef _LOCK_RECURSIVE_T _flock_t; -#endif - #ifndef __machine_iconv_t_defined /* Iconv descriptor type */ typedef void *_iconv_t; diff --git a/newlib/libc/include/sys/reent.h b/newlib/libc/include/sys/reent.h index 6e55e1c1f..7f8124deb 100644 --- a/newlib/libc/include/sys/reent.h +++ b/newlib/libc/include/sys/reent.h @@ -30,6 +30,11 @@ typedef unsigned __Long __ULong; #include #endif +#ifndef __machine_flock_t_defined +#include +typedef _LOCK_RECURSIVE_T _flock_t; +#endif + #ifndef __Long #define __Long __int32_t typedef __uint32_t __ULong; From 86809750bb4e6b0cda331ae9919f3d0e9bd53586 Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Thu, 16 May 2019 14:40:33 +0200 Subject: [PATCH 389/475] Avoid dependency in Including could result in cyclic header dependencies. Signed-off-by: Sebastian Huber --- newlib/libc/include/sys/_types.h | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/newlib/libc/include/sys/_types.h b/newlib/libc/include/sys/_types.h index 90383b083..0ed56ed44 100644 --- a/newlib/libc/include/sys/_types.h +++ b/newlib/libc/include/sys/_types.h @@ -210,10 +210,15 @@ typedef unsigned short __nlink_t; typedef long __suseconds_t; /* microseconds (signed) */ typedef unsigned long __useconds_t; /* microseconds (unsigned) */ -#ifdef __GNUCLIKE_BUILTIN_VARARGS +/* + * Must be identical to the __GNUCLIKE_BUILTIN_VAALIST definition in + * . The must not be included here to avoid cyclic + * header dependencies. + */ +#if __GNUC_MINOR__ > 95 || __GNUC__ >= 3 typedef __builtin_va_list __va_list; #else typedef char * __va_list; -#endif /* __GNUCLIKE_BUILTIN_VARARGS */ +#endif #endif /* _SYS__TYPES_H */ From f5a5a23ea8c73f9d2a2fdcb471883989f23f9e4b Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Thu, 16 May 2019 14:40:34 +0200 Subject: [PATCH 390/475] Fix issues with A commit from 2016 tried to address this GCC provided issue #if (defined (__FreeBSD__) && (__FreeBSD__ >= 5)) \ || defined(__DragonFly__) \ || defined(__FreeBSD_kernel__) /* __size_t is a typedef on FreeBSD 5, must not trash it. */ #elif defined (__VMS__) /* __size_t is also a typedef on VMS. */ #else #define __size_t #endif with an include of before in . Is is not robust enough. Do the include of in directly and request only the necessary types. Signed-off-by: Sebastian Huber --- newlib/libc/include/sys/_types.h | 6 +++--- newlib/libc/include/sys/types.h | 2 -- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/newlib/libc/include/sys/_types.h b/newlib/libc/include/sys/_types.h index 0ed56ed44..017a0aaf6 100644 --- a/newlib/libc/include/sys/_types.h +++ b/newlib/libc/include/sys/_types.h @@ -19,6 +19,9 @@ #ifndef _SYS__TYPES_H #define _SYS__TYPES_H +#define __need_size_t +#define __need_wint_t +#include #include #include #include @@ -154,9 +157,6 @@ typedef long _ssize_t; typedef _ssize_t __ssize_t; -#define __need_wint_t -#include - #ifndef __machine_mbstate_t_defined /* Conversion state information. */ typedef struct diff --git a/newlib/libc/include/sys/types.h b/newlib/libc/include/sys/types.h index 19e3de689..4613ac81f 100644 --- a/newlib/libc/include/sys/types.h +++ b/newlib/libc/include/sys/types.h @@ -42,8 +42,6 @@ typedef __intptr_t register_t; #ifndef __need_inttypes #define _SYS_TYPES_H -/* must be before for __size_t considerations */ -#include #include #include From ee7e49e19388fd0f19ca1c4773d3efc5fa123d58 Mon Sep 17 00:00:00 2001 From: Jinke Fan Date: Fri, 17 May 2019 11:29:11 +0800 Subject: [PATCH 391/475] Add support for Hygon Dhyana processor -Add vendor identification -Support in get_cpu_cache Background: Chengdu Haiguang IC Design Co., Ltd (Hygon) is a Joint Venture between AMD and Haiguang Information Technology Co.,Ltd., aims at providing high performance x86 processor for China server market. Its first generation processor codename is Dhyana, which originates from AMD technology and shares most of the architecture with AMD's family 17h, but with different CPU Vendor ID("HygonGenuine")/Family series number(Family 18h). Related Hygon kernel patch can be found on: http://lkml.kernel.org/r/5ce86123a7b9dad925ac583d88d2f921040e859b.1538583282.git.puwen@hygon.cn Signed-off-by: Jinke Fan --- winsup/cygwin/fhandler_proc.cc | 3 ++- winsup/cygwin/sysconf.cc | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/winsup/cygwin/fhandler_proc.cc b/winsup/cygwin/fhandler_proc.cc index a6a0b683c..c461bbc75 100644 --- a/winsup/cygwin/fhandler_proc.cc +++ b/winsup/cygwin/fhandler_proc.cc @@ -706,7 +706,8 @@ format_proc_cpuinfo (void *, char *&destbuf) /* Vendor identification. */ bool is_amd = false, is_intel = false; - if (!strcmp ((char*)vendor_id, "AuthenticAMD")) + if (!strcmp ((char*)vendor_id, "AuthenticAMD") + || !strcmp((char*)vendor_id, "HygonGenuine")) is_amd = true; else if (!strcmp ((char*)vendor_id, "GenuineIntel")) is_intel = true; diff --git a/winsup/cygwin/sysconf.cc b/winsup/cygwin/sysconf.cc index 216e5142f..3440c09ee 100644 --- a/winsup/cygwin/sysconf.cc +++ b/winsup/cygwin/sysconf.cc @@ -486,7 +486,8 @@ get_cpu_cache (int in) vendor_id[3] = 0; if (!strcmp ((char*) vendor_id, "GenuineIntel")) return get_cpu_cache_intel (in, maxf & 0xffff); - else if (!strcmp ((char*)vendor_id, "AuthenticAMD")) + else if (!strcmp ((char*)vendor_id, "AuthenticAMD") + || !strcmp((char*)vendor_id, "HygonGenuine")) { uint32_t maxe = 0, unused; cpuid (&maxe, &unused, &unused, &unused, 0x80000000); From d5daede26c651f4e9d6c7abbd2dd2937a1e24e2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucio=20Andr=C3=A9s=20Illanes=20Albornoz?= Date: Sat, 1 Jun 2019 10:33:19 +0200 Subject: [PATCH 392/475] Fix vfwscanf(3) assignment suppression flag handling bug newlib's vfwscanf(3) (or specifically, __SVFWSCANF_R()) fails to correctly set the assignment-suppressing character (`*') flag[1] which, when present in the formatting string, results in undefined behaviour comprising retrieving and dereferencing a pointer that was not supplied by the caller as such or at all. When compared to the vfscanf(3) implementation, this would appear to be over the missing goto match_failure statement preceded by the flags test seen below. Hence, this patch (re)introduces it. [1] -- --- newlib/libc/stdio/vfwscanf.c | 1 + 1 file changed, 1 insertion(+) diff --git a/newlib/libc/stdio/vfwscanf.c b/newlib/libc/stdio/vfwscanf.c index 0464b0837..ffb6cc85b 100644 --- a/newlib/libc/stdio/vfwscanf.c +++ b/newlib/libc/stdio/vfwscanf.c @@ -602,6 +602,7 @@ __SVFWSCANF_R (struct _reent *rptr, case L'*': if ((flags & (CHAR | SHORT | LONG | LONGDBL | SUPPRESS | MALLOC)) || width) + goto match_failure; flags |= SUPPRESS; goto again; case L'l': From 6c9ad75a4bd40e9d72a109d17cc9fe6cc754af08 Mon Sep 17 00:00:00 2001 From: Michael Haubenwallner Date: Fri, 3 May 2019 16:14:14 +0200 Subject: [PATCH 393/475] Cygwin: dll_list: stat_real_file_once with ntname NtQueryVirtualMemory for MemorySectionName may return some old path even if the process was just started, for when some directory in between was renamed - maybe because the NT file cache is hot for the old path still. This was seen during gcc bootstrap, returning a MemorySectionName of ".../gcc/xgcc.exe" even if started as ".../prev-gcc/xgcc.exe", where the directory rename from "gcc" to "prev-gcc" was done the moment before. As we stat the module's real file right after loading now, there is no point in using NtQueryVirtualMemory with MemorySectionName any more, and we can use what GetModuleFileName returned instead. --- winsup/cygwin/dll_init.cc | 2 +- winsup/cygwin/forkable.cc | 42 ++++++++------------------------------- 2 files changed, 9 insertions(+), 35 deletions(-) diff --git a/winsup/cygwin/dll_init.cc b/winsup/cygwin/dll_init.cc index 4ba1bd22d..6a4ed269e 100644 --- a/winsup/cygwin/dll_init.cc +++ b/winsup/cygwin/dll_init.cc @@ -381,7 +381,7 @@ dll_list::alloc (HINSTANCE h, per_process *p, dll_type type) *d->forkable_ntname = L'\0'; } if (forkables_supported ()) - d->stat_real_file_once (); /* uses nt_max_path_buf () */ + d->stat_real_file_once (); append (d); if (type == DLL_LOAD) loaded_dlls++; diff --git a/winsup/cygwin/forkable.cc b/winsup/cygwin/forkable.cc index 1dcafe5e1..4fbc2abb3 100644 --- a/winsup/cygwin/forkable.cc +++ b/winsup/cygwin/forkable.cc @@ -161,44 +161,18 @@ dll::stat_real_file_once () if (fii.IndexNumber.QuadPart != -1LL) return true; - tmp_pathbuf tp; - - HANDLE fhandle = INVALID_HANDLE_VALUE; - NTSTATUS status, fstatus; - PMEMORY_SECTION_NAME pmsi1; - MEMORY_SECTION_NAME msi2; - pmsi1 = (PMEMORY_SECTION_NAME) dll_list::nt_max_path_buf (); - RtlInitEmptyUnicodeString (&msi2.SectionFileName, tp.w_get (), 65535); - - /* Retry opening the real file name until that does not change any more. */ - status = NtQueryVirtualMemory (NtCurrentProcess (), handle, - MemorySectionName, pmsi1, 65536, NULL); - while (NT_SUCCESS (status) && - !RtlEqualUnicodeString (&msi2.SectionFileName, - &pmsi1->SectionFileName, FALSE)) - { - debug_printf ("for %s at %p got memory section name '%W'", - ntname, handle, pmsi1->SectionFileName.Buffer); - RtlCopyUnicodeString (&msi2.SectionFileName, &pmsi1->SectionFileName); - if (fhandle != INVALID_HANDLE_VALUE) - NtClose (fhandle); - pmsi1->SectionFileName.Buffer[pmsi1->SectionFileName.Length] = L'\0'; - fhandle = dll_list::ntopenfile (pmsi1->SectionFileName.Buffer, &fstatus); - status = NtQueryVirtualMemory (NtCurrentProcess (), handle, - MemorySectionName, pmsi1, 65536, NULL); - } - if (!NT_SUCCESS (status)) - system_printf ("WARNING: Unable (ntstatus %y) to query real file for %W", - status, ntname); - else if (fhandle == INVALID_HANDLE_VALUE) - system_printf ("WARNING: Unable (ntstatus %y) to open real file for %W", - fstatus, ntname); + NTSTATUS fstatus; + HANDLE fhandle = dll_list::ntopenfile (ntname, &fstatus); if (fhandle == INVALID_HANDLE_VALUE) - return false; + { + system_printf ("WARNING: Unable (ntstatus %y) to open real file %W", + fstatus, ntname); + return false; + } if (!dll_list::read_fii (fhandle, &fii)) system_printf ("WARNING: Unable to read real file attributes for %W", - pmsi1->SectionFileName.Buffer); + ntname); NtClose (fhandle); return fii.IndexNumber.QuadPart != -1LL; From a9c27900e3d98fa4e57405e7abc10c260f2167d2 Mon Sep 17 00:00:00 2001 From: Michael Haubenwallner Date: Mon, 13 May 2019 16:36:23 +0200 Subject: [PATCH 394/475] Cygwin: dll_list: no recursive use of nt_max_path_buf Querying the ntlength and existence of the /var/run/cygfork directory in the very first Cygwin process should not use nt_max_path_buf, as that one is used by dll_list::alloc already. --- winsup/cygwin/forkable.cc | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/winsup/cygwin/forkable.cc b/winsup/cygwin/forkable.cc index 4fbc2abb3..350a95c3e 100644 --- a/winsup/cygwin/forkable.cc +++ b/winsup/cygwin/forkable.cc @@ -472,17 +472,21 @@ dll_list::forkable_ntnamesize (dll_type type, PCWCHAR fullntname, PCWCHAR modnam if (cygwin_shared->forkable_hardlink_support == 0) /* Unknown */ { /* check existence of forkables dir */ - PWCHAR pbuf = nt_max_path_buf (); + /* nt_max_path_buf () is already used in dll_list::alloc. + But as this is run in the very first cygwin process only, + using some heap is not a performance issue here. */ + PWCHAR pbuf = (PWCHAR) cmalloc_abort (HEAP_BUF, + NT_MAX_PATH * sizeof (WCHAR)); + PWCHAR pnext = pbuf; for (namepart const *part = forkable_nameparts; part->text; ++part) { if (part->textfunc) - pbuf += part->textfunc (pbuf, -1); + pnext += part->textfunc (pnext, -1); else - pbuf += __small_swprintf (pbuf, L"%W", part->text); + pnext += __small_swprintf (pnext, L"%W", part->text); if (part->mutex_from_dir) break; /* up to first mutex-naming dir */ } - pbuf = nt_max_path_buf (); UNICODE_STRING fn; RtlInitUnicodeString (&fn, pbuf); @@ -504,6 +508,7 @@ dll_list::forkable_ntnamesize (dll_type type, PCWCHAR fullntname, PCWCHAR modnam cygwin_shared->forkable_hardlink_support = -1; /* No */ debug_printf ("disabled, missing or not on NTFS %W", fn.Buffer); } + cfree (pbuf); } if (!forkables_supported ()) From a8c23e4423ebb3458db93341d8a9bc73b0a04b03 Mon Sep 17 00:00:00 2001 From: Michael Haubenwallner Date: Tue, 30 Apr 2019 09:09:13 +0200 Subject: [PATCH 395/475] Cygwin: fork: Always pause child after fixups. Pause the child process after performing fork fixups even if there were no dynamically loaded dlls with extra data/bss transfers to wait for. This allows the parent process to cancel the current fork call even if the child process was successfully initialized already. This is a preparation for when the parent does remember the child no earlier than after successful child initialization. --- winsup/cygwin/fork.cc | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/winsup/cygwin/fork.cc b/winsup/cygwin/fork.cc index 7e1c08990..59b13806c 100644 --- a/winsup/cygwin/fork.cc +++ b/winsup/cygwin/fork.cc @@ -180,13 +180,10 @@ frok::child (volatile char * volatile here) cygheap->fdtab.fixup_after_fork (hParent); - /* If we haven't dynamically loaded any dlls, just signal the parent. - Otherwise, tell the parent that we've loaded all the dlls - and wait for the parent to fill in the loaded dlls' data/bss. */ - if (!load_dlls) - sync_with_parent ("performed fork fixup", false); - else - sync_with_parent ("loaded dlls", true); + /* Signal that we have successfully initialized, so the parent can + - transfer data/bss for dynamically loaded dlls (if any), or + - terminate the current fork call even if the child is initialized. */ + sync_with_parent ("performed fork fixups and dynamic dll loading", true); init_console_handler (myself->ctty > 0); ForceCloseHandle1 (fork_info->forker_finished, forker_finished); @@ -477,7 +474,8 @@ frok::parent (volatile char * volatile stack_here) } } - /* Start thread, and then wait for it to reload dlls. */ + /* Start the child up, and then wait for it to + perform fork fixups and dynamic dll loading (if any). */ resume_child (forker_finished); if (!ch.sync (child->pid, hchild, FORK_WAIT_TIMEOUT)) { @@ -508,10 +506,11 @@ frok::parent (volatile char * volatile stack_here) goto cleanup; } } - /* Start the child up again. */ - resume_child (forker_finished); } + /* Finally start the child up. */ + resume_child (forker_finished); + ForceCloseHandle (forker_finished); forker_finished = NULL; From f03ea8e1c57bd5cea83f6cd47fa02870bdfeb1c5 Mon Sep 17 00:00:00 2001 From: Michael Haubenwallner Date: Thu, 2 May 2019 12:12:44 +0200 Subject: [PATCH 396/475] Cygwin: fork: Remember child not before success. Do not remember the child before it was successfully initialized, or we would need more sophisticated cleanup on child initialization failure, like cleaning up the process table and suppressing SIGCHILD delivery with multiple threads ("waitproc") involved. Compared to that, the potential slowdown due to an extra yield () call should be negligible. --- winsup/cygwin/fork.cc | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/winsup/cygwin/fork.cc b/winsup/cygwin/fork.cc index 59b13806c..c69081fc0 100644 --- a/winsup/cygwin/fork.cc +++ b/winsup/cygwin/fork.cc @@ -181,7 +181,8 @@ frok::child (volatile char * volatile here) cygheap->fdtab.fixup_after_fork (hParent); /* Signal that we have successfully initialized, so the parent can - - transfer data/bss for dynamically loaded dlls (if any), or + - transfer data/bss for dynamically loaded dlls (if any), and + - start up some tracker threads to remember the child, or - terminate the current fork call even if the child is initialized. */ sync_with_parent ("performed fork fixups and dynamic dll loading", true); @@ -411,20 +412,6 @@ frok::parent (volatile char * volatile stack_here) child.hProcess = hchild; ch.postfork (child); - /* Hopefully, this will succeed. The alternative to doing things this - way is to reserve space prior to calling CreateProcess and then fill - it in afterwards. This requires more bookkeeping than I like, though, - so we'll just do it the easy way. So, terminate any child process if - we can't actually record the pid in the internal table. */ - if (!child.remember (false)) - { - this_errno = EAGAIN; -#ifdef DEBUGGING0 - error ("child remember failed"); -#endif - goto cleanup; - } - /* CHILD IS STOPPED */ debug_printf ("child is alive (but stopped)"); @@ -508,6 +495,20 @@ frok::parent (volatile char * volatile stack_here) } } + /* Hopefully, this will succeed. The alternative to doing things this + way is to reserve space prior to calling CreateProcess and then fill + it in afterwards. This requires more bookkeeping than I like, though, + so we'll just do it the easy way. So, terminate any child process if + we can't actually record the pid in the internal table. */ + if (!child.remember (false)) + { + this_errno = EAGAIN; +#ifdef DEBUGGING0 + error ("child remember failed"); +#endif + goto cleanup; + } + /* Finally start the child up. */ resume_child (forker_finished); From e1254add73b1fb834933b38a5163d72c30c2330b Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Tue, 4 Jun 2019 16:58:53 +0200 Subject: [PATCH 397/475] Cygwin: Allow accessing 48 bit address space in Windows 8.1 or later 64 bit Windows started out with a 44 bit address space due to a restriction of the AMD64 CPUs at the time. Starting with Windows 8.1, these CPUs are not supported anymore and Windows switched to the full 48 bit address space supported by AMD64. Cygwin didn't follow suit yet so mmaps are still restricted to the lower 44 bit address space. Fix that by using a system-specific upper address for mmap allocations, 44 bit up to Windows 8, 48 bit starting with Windows 8.1. While at it, move the heap by another 8 Gigs to leave some space for a potential extension of DLL address space, and restrict the mmap lower address so the heap can grow to 32 Gigs before colliding with mmaps. --- winsup/cygwin/heap.cc | 6 +++--- winsup/cygwin/mmap.cc | 6 ++++-- winsup/cygwin/wincap.cc | 9 +++++++++ winsup/cygwin/wincap.h | 4 ++++ 4 files changed, 20 insertions(+), 5 deletions(-) diff --git a/winsup/cygwin/heap.cc b/winsup/cygwin/heap.cc index e18cd5508..b839c8cd4 100644 --- a/winsup/cygwin/heap.cc +++ b/winsup/cygwin/heap.cc @@ -34,9 +34,9 @@ eval_start_address () executable starts at 0x1:00400000L, the Cygwin DLL starts at 0x1:80040000L, other rebased DLLs are located in the region from 0x2:00000000L up to 0x4:00000000L, -auto-image-based DLLs are located - in the region from 0x4:00000000L up to 0x6:00000000L. - So we let the heap start at 0x6:00000000L. */ - uintptr_t start_address = 0x600000000L; + in the region from 0x4:00000000L up to 0x6:00000000L. Leave another + 8 Gigs slack space, so lets start the heap at 0x8:00000000L. */ + uintptr_t start_address = 0x800000000L; #else /* Windows performs heap ASLR. This spoils the entire region below 0x20000000 for us, because that region is used by Windows to randomize diff --git a/winsup/cygwin/mmap.cc b/winsup/cygwin/mmap.cc index 9eb1643a0..8b1aedc48 100644 --- a/winsup/cygwin/mmap.cc +++ b/winsup/cygwin/mmap.cc @@ -801,8 +801,10 @@ mmap_worker (mmap_list *map_list, fhandler_base *fh, caddr_t base, size_t len, #ifdef __x86_64__ /* The memory region used for memory maps */ -#define MMAP_STORAGE_LOW 0x00800000000L /* Leave 8 Gigs for heap. */ -#define MMAP_STORAGE_HIGH 0x70000000000L /* Leave enough room for OS. */ +#define MMAP_STORAGE_LOW 0x001000000000L /* Leave 32 Gigs for heap. */ +/* Up to Win 8 only supporting 44 bit address space, starting with Win 8.1 + 48 bit address space. */ +#define MMAP_STORAGE_HIGH wincap.mmap_storage_high () /* FIXME? Unfortunately the OS doesn't support a top down allocation with a ceiling value. The ZeroBits mechanism only works for diff --git a/winsup/cygwin/wincap.cc b/winsup/cygwin/wincap.cc index 17e0cf1be..5c6e6428e 100644 --- a/winsup/cygwin/wincap.cc +++ b/winsup/cygwin/wincap.cc @@ -20,6 +20,7 @@ details. */ wincaps wincap_vista __attribute__((section (".cygwin_dll_common"), shared)) = { def_guard_pages:1, + mmap_storage_high:0x070000000000LL, { is_server:false, needs_count_in_si_lpres2:true, @@ -46,6 +47,7 @@ wincaps wincap_vista __attribute__((section (".cygwin_dll_common"), shared)) = { wincaps wincap_7 __attribute__((section (".cygwin_dll_common"), shared)) = { def_guard_pages:1, + mmap_storage_high:0x070000000000LL, { is_server:false, needs_count_in_si_lpres2:false, @@ -72,6 +74,7 @@ wincaps wincap_7 __attribute__((section (".cygwin_dll_common"), shared)) = { wincaps wincap_8 __attribute__((section (".cygwin_dll_common"), shared)) = { def_guard_pages:2, + mmap_storage_high:0x070000000000LL, { is_server:false, needs_count_in_si_lpres2:false, @@ -98,6 +101,7 @@ wincaps wincap_8 __attribute__((section (".cygwin_dll_common"), shared)) = { wincaps wincap_8_1 __attribute__((section (".cygwin_dll_common"), shared)) = { def_guard_pages:2, + mmap_storage_high:0x700000000000LL, { is_server:false, needs_count_in_si_lpres2:false, @@ -124,6 +128,7 @@ wincaps wincap_8_1 __attribute__((section (".cygwin_dll_common"), shared)) = { wincaps wincap_10_1507 __attribute__((section (".cygwin_dll_common"), shared)) = { def_guard_pages:2, + mmap_storage_high:0x700000000000LL, { is_server:false, needs_count_in_si_lpres2:false, @@ -150,6 +155,7 @@ wincaps wincap_10_1507 __attribute__((section (".cygwin_dll_common"), shared)) wincaps wincap_10_1703 __attribute__((section (".cygwin_dll_common"), shared)) = { def_guard_pages:2, + mmap_storage_high:0x700000000000LL, { is_server:false, needs_count_in_si_lpres2:false, @@ -176,6 +182,7 @@ wincaps wincap_10_1703 __attribute__((section (".cygwin_dll_common"), shared)) = wincaps wincap_10_1709 __attribute__((section (".cygwin_dll_common"), shared)) = { def_guard_pages:2, + mmap_storage_high:0x700000000000LL, { is_server:false, needs_count_in_si_lpres2:false, @@ -202,6 +209,7 @@ wincaps wincap_10_1709 __attribute__((section (".cygwin_dll_common"), shared)) = wincaps wincap_10_1803 __attribute__((section (".cygwin_dll_common"), shared)) = { def_guard_pages:2, + mmap_storage_high:0x700000000000LL, { is_server:false, needs_count_in_si_lpres2:false, @@ -228,6 +236,7 @@ wincaps wincap_10_1803 __attribute__((section (".cygwin_dll_common"), shared)) = wincaps wincap_10_1809 __attribute__((section (".cygwin_dll_common"), shared)) = { def_guard_pages:2, + mmap_storage_high:0x700000000000LL, { is_server:false, needs_count_in_si_lpres2:false, diff --git a/winsup/cygwin/wincap.h b/winsup/cygwin/wincap.h index 73b6f5ffc..ba01a1565 100644 --- a/winsup/cygwin/wincap.h +++ b/winsup/cygwin/wincap.h @@ -12,6 +12,7 @@ details. */ struct wincaps { DWORD def_guard_pages; + int64_t mmap_storage_high; /* The bitfields must be 8 byte aligned on x86_64, otherwise the bitfield ops generated by gcc are off by 4 bytes. */ struct __attribute__ ((aligned (8))) { @@ -71,6 +72,9 @@ public: { return ((wincaps *) this->caps)->def_guard_pages * page_size (); } +#ifdef __x86_64__ + intptr_t IMPLEMENT (mmap_storage_high) +#endif bool IMPLEMENT (is_server) bool IMPLEMENT (needs_count_in_si_lpres2) bool IMPLEMENT (needs_query_information) From 5c2a3661c1aeefb0591ce46e8ab3274f0c6d9112 Mon Sep 17 00:00:00 2001 From: Yaakov Selkowitz Date: Thu, 23 May 2019 11:47:36 -0400 Subject: [PATCH 398/475] cygcheck: expand common_apps list An increasing number of tools are being included in Windows which have the same names as those included in Cygwin packages. Indicating which one is first in PATH can be helpful in diagnosing behavioural discrepencies between them. Also, fix the alphabetization of ssh. --- winsup/utils/cygcheck.cc | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/winsup/utils/cygcheck.cc b/winsup/utils/cygcheck.cc index d5972c0cf..2cc25d985 100644 --- a/winsup/utils/cygcheck.cc +++ b/winsup/utils/cygcheck.cc @@ -99,28 +99,43 @@ static common_apps[] = { {"awk", 0}, {"bash", 0}, {"cat", 0}, + {"certutil", 0}, + {"clinfo", 0}, + {"comp", 0}, + {"convert", 0}, {"cp", 0}, {"cpp", 1}, {"crontab", 0}, + {"curl", 0}, + {"expand", 0}, {"find", 0}, + {"ftp", 0}, {"gcc", 0}, {"gdb", 0}, {"grep", 0}, + {"hostname", 0}, {"kill", 0}, + {"klist", 0}, {"ld", 0}, {"ls", 0}, {"make", 0}, {"mv", 0}, + {"nslookup", 0}, {"patch", 0}, {"perl", 0}, + {"replace", 0}, {"rm", 0}, {"sed", 0}, - {"ssh", 0}, {"sh", 0}, + {"shutdown", 0}, + {"sort", 0}, + {"ssh", 0}, {"tar", 0}, {"test", 0}, + {"timeout", 0}, {"vi", 0}, {"vim", 0}, + {"whoami", 0}, {0, 0} }; From b0c033bf3fae810b9e5a5c69f17bd4de63725691 Mon Sep 17 00:00:00 2001 From: Ben Wijen Date: Mon, 3 Jun 2019 20:15:50 +0200 Subject: [PATCH 399/475] mkdir: always check-for-existence MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When using NtCreateFile when creating a directory that already exists, it will correctly return 'STATUS_OBJECT_NAME_COLLISION'. However using this function to create a directory (and all its parents) a normal use would be to start with mkdir(‘/cygdrive/c’) which translates to ‘C:\’ for which it'll instead return ‘STATUS_ACCESS_DENIED’. --- winsup/cygwin/dir.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/winsup/cygwin/dir.cc b/winsup/cygwin/dir.cc index f43eae461..b757851d5 100644 --- a/winsup/cygwin/dir.cc +++ b/winsup/cygwin/dir.cc @@ -331,8 +331,10 @@ mkdir (const char *dir, mode_t mode) debug_printf ("got %d error from build_fh_name", fh->error ()); set_errno (fh->error ()); } + else if (fh->exists ()) + set_errno (EEXIST); else if (has_dot_last_component (dir, true)) - set_errno (fh->exists () ? EEXIST : ENOENT); + set_errno (ENOENT); else if (!fh->mkdir (mode)) res = 0; delete fh; From 605bdcd410384dda6db66b9b8cd19e863702e1bb Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Wed, 5 Jun 2019 20:08:34 +0200 Subject: [PATCH 400/475] Cygwin: map beyond EOF on 64 bit and WOW64 as well 32 bit Cygwin performs a POSIX-compatible mapping after EOF which is not supported in this form on Windows. The 64 bit Windows kernel never supported the AT_ROUND_TO_PAGE mapping flag, so we couldn't page-aligned map the space right after the file's EOF. So mapping beyond EOF was disabled in 64 bit Windows and WOW64. However, if mmap works, a matching munmap should work as well, *and* it should not accidentally unmap unrelated memory. Therefore we enable mapping beyond EOF on 64 bit as well. Since that mapping is always 64K aligned, the are between the last file page and the next 64K allocation boundary will be unallocated. There's no way around that. Signed-off-by: Corinna Vinschen --- winsup/cygwin/mmap.cc | 35 ++++++++++++++++++++++++----------- 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/winsup/cygwin/mmap.cc b/winsup/cygwin/mmap.cc index 8b1aedc48..797373742 100644 --- a/winsup/cygwin/mmap.cc +++ b/winsup/cygwin/mmap.cc @@ -834,7 +834,7 @@ public: { /* If it points to a free area, big enough to fulfill the request, return the address. */ - if (VirtualQuery (in_addr, &mbi, sizeof mbi) + if (VirtualQuery (in_addr, &mbi, sizeof mbi) && mbi.State == MEM_FREE && mbi.RegionSize >= size) return in_addr; @@ -1075,14 +1075,17 @@ mmap64 (void *addr, size_t len, int prot, int flags, int fd, off_t off) } fsiz -= off; /* We're creating the pages beyond EOF as reserved, anonymous pages. - Note that this isn't done in 64 bit environments since apparently - 64 bit systems don't support the AT_ROUND_TO_PAGE flag, which is - required to get this right. Too bad. */ + Note that 64 bit environments don't support the AT_ROUND_TO_PAGE + flag, which is required to get this right for the remainder of + the first 64K block the file ends in. We perform the workaround + nevertheless to support expectations that the range mapped beyond + EOF can be safely munmap'ed instead of being taken by another, + totally unrelated mapping. */ + if ((off_t) len > fsiz && !autogrow (flags)) + orig_len = len; #ifdef __i386__ - if (!wincap.is_wow64 () - && (((off_t) len > fsiz && !autogrow (flags)) - || roundup2 (len, wincap.page_size ()) - < roundup2 (len, pagesize))) + else if (!wincap.is_wow64 () && roundup2 (len, wincap.page_size ()) + < roundup2 (len, pagesize)) orig_len = len; #endif if ((off_t) len > fsiz) @@ -1185,12 +1188,22 @@ go_ahead: raise a SIGBUS when trying to access them. AT_ROUND_TO_PAGE and page protection on shared pages is only supported by the 32 bit environment, so don't even try on 64 bit or even WOW64. - This is accomplished by not setting orig_len on 64 bit above. */ - len = roundup2 (len, wincap.page_size ()); + This results in an allocation gap in the first 64K block the file + ends in, but there's nothing at all we can do about that. */ +#ifdef __x86_64__ + len = roundup2 (len, wincap.allocation_granularity ()); +#else + len = roundup2 (len, wincap.is_wow64 () ? wincap.allocation_granularity () + : wincap.page_size ()); +#endif if (orig_len - len) { orig_len -= len; - size_t valid_page_len = orig_len % pagesize; + size_t valid_page_len = 0; +#ifndef __x86_64__ + if (!wincap.is_wow64 ()) + valid_page_len = orig_len % pagesize; +#endif size_t sigbus_page_len = orig_len - valid_page_len; caddr_t at_base = base + len; From 160f9f0bf26cf9864bf8f26b1816ae4a3fe13c8d Mon Sep 17 00:00:00 2001 From: pfg Date: Mon, 27 Nov 2017 15:01:59 +0000 Subject: [PATCH 401/475] sys/sys: further adoption of SPDX licensing ID tags. Mainly focus on files that use BSD 2-Clause license, however the tool I was using misidentified many licenses so this was mostly a manual - error prone - task. The Software Package Data Exchange (SPDX) group provides a specification to make it easier for automated tools to detect and summarize well known opensource licenses. We are gradually adopting the specification, noting that the tags are considered only advisory and do not, in any way, superceed or replace the license texts. --- newlib/libc/include/sys/tree.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/newlib/libc/include/sys/tree.h b/newlib/libc/include/sys/tree.h index f4167c4e4..aef934a10 100644 --- a/newlib/libc/include/sys/tree.h +++ b/newlib/libc/include/sys/tree.h @@ -3,6 +3,8 @@ /* $FreeBSD$ */ /*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * * Copyright 2002 Niels Provos * All rights reserved. * From 4feb21d705f09263cd867f4787a0d24360810577 Mon Sep 17 00:00:00 2001 From: trasz Date: Wed, 8 May 2019 18:47:00 +0000 Subject: [PATCH 402/475] Mark inline functions with __unused; prevents compiler warning when they end up being unused. Reviewed by: kib Obtained from: OpenBSD MFC after: 2 weeks Sponsored by: Klara Inc. Differential Revision: https://reviews.freebsd.org/D20185 --- newlib/libc/include/sys/tree.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/newlib/libc/include/sys/tree.h b/newlib/libc/include/sys/tree.h index aef934a10..fd66ceba1 100644 --- a/newlib/libc/include/sys/tree.h +++ b/newlib/libc/include/sys/tree.h @@ -1,6 +1,6 @@ /* $NetBSD: tree.h,v 1.8 2004/03/28 19:38:30 provos Exp $ */ /* $OpenBSD: tree.h,v 1.7 2002/10/17 21:51:54 art Exp $ */ -/* $FreeBSD$ */ +/* $FreeBSD: head/sys/sys/tree.h 347360 2019-05-08 18:47:00Z trasz $ */ /*- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD @@ -90,7 +90,7 @@ struct { \ SPLAY_RIGHT(tmp, field) = (head)->sph_root; \ (head)->sph_root = tmp; \ } while (/*CONSTCOND*/ 0) - + #define SPLAY_ROTATE_LEFT(head, tmp, field) do { \ SPLAY_RIGHT((head)->sph_root, field) = SPLAY_LEFT(tmp, field); \ SPLAY_LEFT(tmp, field) = (head)->sph_root; \ @@ -125,7 +125,7 @@ struct type *name##_SPLAY_INSERT(struct name *, struct type *); \ struct type *name##_SPLAY_REMOVE(struct name *, struct type *); \ \ /* Finds the node with the same key as elm */ \ -static __inline struct type * \ +static __unused __inline struct type * \ name##_SPLAY_FIND(struct name *head, struct type *elm) \ { \ if (SPLAY_EMPTY(head)) \ @@ -136,7 +136,7 @@ name##_SPLAY_FIND(struct name *head, struct type *elm) \ return (NULL); \ } \ \ -static __inline struct type * \ +static __unused __inline struct type * \ name##_SPLAY_NEXT(struct name *head, struct type *elm) \ { \ name##_SPLAY(head, elm); \ @@ -150,7 +150,7 @@ name##_SPLAY_NEXT(struct name *head, struct type *elm) \ return (elm); \ } \ \ -static __inline struct type * \ +static __unused __inline struct type * \ name##_SPLAY_MIN_MAX(struct name *head, int val) \ { \ name##_SPLAY_MINMAX(head, val); \ From 007bc1923c505f18dce5949b57a849640f25b15c Mon Sep 17 00:00:00 2001 From: Jeff Johnston Date: Fri, 7 Jun 2019 13:55:43 -0400 Subject: [PATCH 403/475] Add gfortran support for AMD GCN From: Kwok Cheung Yeung This patch adds enough support for constructors/destructors and OS functions to be able to link and run gfortran programs on AMD GCN. There's no actual ability to do I/O operations on this targets, besides "write" to stdout and stderr, so most of the functions are just stubs. --- newlib/configure.host | 1 + newlib/libc/sys/amdgcn/Makefile.am | 3 +- newlib/libc/sys/amdgcn/Makefile.in | 52 ++++++++++++++++++++++++++++-- newlib/libc/sys/amdgcn/fcntl.c | 24 ++++++++++++++ newlib/libc/sys/amdgcn/getpid.c | 20 ++++++++++++ newlib/libc/sys/amdgcn/kill.c | 23 +++++++++++++ newlib/libc/sys/amdgcn/open.c | 25 ++++++++++++++ newlib/libc/sys/amdgcn/raise.c | 20 ++++++++++++ newlib/libc/sys/amdgcn/stat.c | 24 ++++++++++++++ newlib/libc/sys/amdgcn/unlink.c | 23 +++++++++++++ 10 files changed, 212 insertions(+), 3 deletions(-) create mode 100644 newlib/libc/sys/amdgcn/fcntl.c create mode 100644 newlib/libc/sys/amdgcn/getpid.c create mode 100644 newlib/libc/sys/amdgcn/kill.c create mode 100644 newlib/libc/sys/amdgcn/open.c create mode 100644 newlib/libc/sys/amdgcn/raise.c create mode 100644 newlib/libc/sys/amdgcn/stat.c create mode 100644 newlib/libc/sys/amdgcn/unlink.c diff --git a/newlib/configure.host b/newlib/configure.host index fa805d61a..87bf78a3a 100644 --- a/newlib/configure.host +++ b/newlib/configure.host @@ -121,6 +121,7 @@ case "${host_cpu}" in amdgcn*) newlib_cflags="${newlib_cflags} -D__DYNAMIC_REENT__" machine_dir=amdgcn + libc_cv_initfinit_array=yes ;; arc*) machine_dir=arc diff --git a/newlib/libc/sys/amdgcn/Makefile.am b/newlib/libc/sys/amdgcn/Makefile.am index 171677694..2b0c63bc4 100644 --- a/newlib/libc/sys/amdgcn/Makefile.am +++ b/newlib/libc/sys/amdgcn/Makefile.am @@ -8,7 +8,8 @@ AM_CCASFLAGS = $(INCLUDES) $(CFLAGS) noinst_LIBRARIES = lib.a -lib_a_SOURCES = close.c fstat.c isatty.c lseek.c read.c write.c +lib_a_SOURCES = close.c fstat.c isatty.c lseek.c read.c write.c \ + fcntl.c getpid.c kill.c open.c raise.c stat.c unlink.c lib_a_CCASFLAGS = $(AM_CCASFLAGS) lib_a_CFLAGS = $(AM_CFLAGS) diff --git a/newlib/libc/sys/amdgcn/Makefile.in b/newlib/libc/sys/amdgcn/Makefile.in index dc22992e5..fd1a10b84 100644 --- a/newlib/libc/sys/amdgcn/Makefile.in +++ b/newlib/libc/sys/amdgcn/Makefile.in @@ -71,7 +71,11 @@ lib_a_AR = $(AR) $(ARFLAGS) lib_a_LIBADD = am_lib_a_OBJECTS = lib_a-close.$(OBJEXT) lib_a-fstat.$(OBJEXT) \ lib_a-isatty.$(OBJEXT) lib_a-lseek.$(OBJEXT) \ - lib_a-read.$(OBJEXT) lib_a-write.$(OBJEXT) + lib_a-read.$(OBJEXT) lib_a-write.$(OBJEXT) \ + lib_a-fcntl.$(OBJEXT) lib_a-getpid.$(OBJEXT) \ + lib_a-kill.$(OBJEXT) lib_a-open.$(OBJEXT) \ + lib_a-raise.$(OBJEXT) lib_a-stat.$(OBJEXT) \ + lib_a-unlink.$(OBJEXT) lib_a_OBJECTS = $(am_lib_a_OBJECTS) DEFAULT_INCLUDES = -I.@am__isrc@ depcomp = @@ -195,7 +199,9 @@ AUTOMAKE_OPTIONS = cygnus INCLUDES = $(NEWLIB_CFLAGS) $(CROSS_CFLAGS) $(TARGET_CFLAGS) AM_CCASFLAGS = $(INCLUDES) $(CFLAGS) noinst_LIBRARIES = lib.a -lib_a_SOURCES = close.c fstat.c isatty.c lseek.c read.c write.c +lib_a_SOURCES = close.c fstat.c isatty.c lseek.c read.c write.c \ + fcntl.c getpid.c kill.c open.c raise.c stat.c unlink.c + lib_a_CCASFLAGS = $(AM_CCASFLAGS) lib_a_CFLAGS = $(AM_CFLAGS) ACLOCAL_AMFLAGS = -I ../../.. -I ../../../.. @@ -294,6 +300,48 @@ lib_a-write.o: write.c lib_a-write.obj: write.c $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-write.obj `if test -f 'write.c'; then $(CYGPATH_W) 'write.c'; else $(CYGPATH_W) '$(srcdir)/write.c'; fi` +lib_a-fcntl.o: fcntl.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-fcntl.o `test -f 'fcntl.c' || echo '$(srcdir)/'`fcntl.c + +lib_a-fcntl.obj: fcntl.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-fcntl.obj `if test -f 'fcntl.c'; then $(CYGPATH_W) 'fcntl.c'; else $(CYGPATH_W) '$(srcdir)/fcntl.c'; fi` + +lib_a-getpid.o: getpid.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-getpid.o `test -f 'getpid.c' || echo '$(srcdir)/'`getpid.c + +lib_a-getpid.obj: getpid.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-getpid.obj `if test -f 'getpid.c'; then $(CYGPATH_W) 'getpid.c'; else $(CYGPATH_W) '$(srcdir)/getpid.c'; fi` + +lib_a-kill.o: kill.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-kill.o `test -f 'kill.c' || echo '$(srcdir)/'`kill.c + +lib_a-kill.obj: kill.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-kill.obj `if test -f 'kill.c'; then $(CYGPATH_W) 'kill.c'; else $(CYGPATH_W) '$(srcdir)/kill.c'; fi` + +lib_a-open.o: open.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-open.o `test -f 'open.c' || echo '$(srcdir)/'`open.c + +lib_a-open.obj: open.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-open.obj `if test -f 'open.c'; then $(CYGPATH_W) 'open.c'; else $(CYGPATH_W) '$(srcdir)/open.c'; fi` + +lib_a-raise.o: raise.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-raise.o `test -f 'raise.c' || echo '$(srcdir)/'`raise.c + +lib_a-raise.obj: raise.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-raise.obj `if test -f 'raise.c'; then $(CYGPATH_W) 'raise.c'; else $(CYGPATH_W) '$(srcdir)/raise.c'; fi` + +lib_a-stat.o: stat.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-stat.o `test -f 'stat.c' || echo '$(srcdir)/'`stat.c + +lib_a-stat.obj: stat.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-stat.obj `if test -f 'stat.c'; then $(CYGPATH_W) 'stat.c'; else $(CYGPATH_W) '$(srcdir)/stat.c'; fi` + +lib_a-unlink.o: unlink.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-unlink.o `test -f 'unlink.c' || echo '$(srcdir)/'`unlink.c + +lib_a-unlink.obj: unlink.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-unlink.obj `if test -f 'unlink.c'; then $(CYGPATH_W) 'unlink.c'; else $(CYGPATH_W) '$(srcdir)/unlink.c'; fi` + ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ diff --git a/newlib/libc/sys/amdgcn/fcntl.c b/newlib/libc/sys/amdgcn/fcntl.c new file mode 100644 index 000000000..b334715e8 --- /dev/null +++ b/newlib/libc/sys/amdgcn/fcntl.c @@ -0,0 +1,24 @@ +/* + * Support file for amdgcn in newlib. + * Copyright (c) 2019 Mentor Graphics. + * + * The authors hereby grant permission to use, copy, modify, distribute, + * and license this software and its documentation for any purpose, provided + * that existing copyright notices are retained in all copies and that this + * notice is included verbatim in any distributions. No written agreement, + * license, or royalty fee is required for any of the authorized uses. + * Modifications to this software may be copyrighted by their authors + * and need not follow the licensing terms described here, provided that + * the new terms are clearly indicated on the first page of each file where + * they apply. + */ + +#include + +int fcntl (int fd, + int flag, + int arg) +{ + errno = EINVAL; + return -1; +} diff --git a/newlib/libc/sys/amdgcn/getpid.c b/newlib/libc/sys/amdgcn/getpid.c new file mode 100644 index 000000000..5e9cb5973 --- /dev/null +++ b/newlib/libc/sys/amdgcn/getpid.c @@ -0,0 +1,20 @@ +/* + * Support file for amdgcn in newlib. + * Copyright (c) 2019 Mentor Graphics. + * + * The authors hereby grant permission to use, copy, modify, distribute, + * and license this software and its documentation for any purpose, provided + * that existing copyright notices are retained in all copies and that this + * notice is included verbatim in any distributions. No written agreement, + * license, or royalty fee is required for any of the authorized uses. + * Modifications to this software may be copyrighted by their authors + * and need not follow the licensing terms described here, provided that + * the new terms are clearly indicated on the first page of each file where + * they apply. + */ + +int +getpid (void) +{ + return 0; +} diff --git a/newlib/libc/sys/amdgcn/kill.c b/newlib/libc/sys/amdgcn/kill.c new file mode 100644 index 000000000..94c6843bf --- /dev/null +++ b/newlib/libc/sys/amdgcn/kill.c @@ -0,0 +1,23 @@ +/* + * Support file for amdgcn in newlib. + * Copyright (c) 2019 Mentor Graphics. + * + * The authors hereby grant permission to use, copy, modify, distribute, + * and license this software and its documentation for any purpose, provided + * that existing copyright notices are retained in all copies and that this + * notice is included verbatim in any distributions. No written agreement, + * license, or royalty fee is required for any of the authorized uses. + * Modifications to this software may be copyrighted by their authors + * and need not follow the licensing terms described here, provided that + * the new terms are clearly indicated on the first page of each file where + * they apply. + */ + +#include + +int kill (int pid, + int sig) +{ + errno = ESRCH; + return -1; +} diff --git a/newlib/libc/sys/amdgcn/open.c b/newlib/libc/sys/amdgcn/open.c new file mode 100644 index 000000000..bb2c5af17 --- /dev/null +++ b/newlib/libc/sys/amdgcn/open.c @@ -0,0 +1,25 @@ +/* + * Support file for amdgcn in newlib. + * Copyright (c) 2019 Mentor Graphics. + * + * The authors hereby grant permission to use, copy, modify, distribute, + * and license this software and its documentation for any purpose, provided + * that existing copyright notices are retained in all copies and that this + * notice is included verbatim in any distributions. No written agreement, + * license, or royalty fee is required for any of the authorized uses. + * Modifications to this software may be copyrighted by their authors + * and need not follow the licensing terms described here, provided that + * the new terms are clearly indicated on the first page of each file where + * they apply. + */ + +#include +#include + +int +open (const char *file, + int flags, ...) +{ + errno = EACCES; + return -1; +} diff --git a/newlib/libc/sys/amdgcn/raise.c b/newlib/libc/sys/amdgcn/raise.c new file mode 100644 index 000000000..d5c19cd84 --- /dev/null +++ b/newlib/libc/sys/amdgcn/raise.c @@ -0,0 +1,20 @@ +/* + * Support file for amdgcn in newlib. + * Copyright (c) 2019 Mentor Graphics. + * + * The authors hereby grant permission to use, copy, modify, distribute, + * and license this software and its documentation for any purpose, provided + * that existing copyright notices are retained in all copies and that this + * notice is included verbatim in any distributions. No written agreement, + * license, or royalty fee is required for any of the authorized uses. + * Modifications to this software may be copyrighted by their authors + * and need not follow the licensing terms described here, provided that + * the new terms are clearly indicated on the first page of each file where + * they apply. + */ + +int +raise (int sig) +{ + return -1; +} diff --git a/newlib/libc/sys/amdgcn/stat.c b/newlib/libc/sys/amdgcn/stat.c new file mode 100644 index 000000000..710074807 --- /dev/null +++ b/newlib/libc/sys/amdgcn/stat.c @@ -0,0 +1,24 @@ +/* + * Support file for amdgcn in newlib. + * Copyright (c) 2019 Mentor Graphics. + * + * The authors hereby grant permission to use, copy, modify, distribute, + * and license this software and its documentation for any purpose, provided + * that existing copyright notices are retained in all copies and that this + * notice is included verbatim in any distributions. No written agreement, + * license, or royalty fee is required for any of the authorized uses. + * Modifications to this software may be copyrighted by their authors + * and need not follow the licensing terms described here, provided that + * the new terms are clearly indicated on the first page of each file where + * they apply. + */ + +#include + +int +stat (const char *file, + struct stat *pstat) +{ + errno = EACCES; + return -1; +} diff --git a/newlib/libc/sys/amdgcn/unlink.c b/newlib/libc/sys/amdgcn/unlink.c new file mode 100644 index 000000000..059c1d57c --- /dev/null +++ b/newlib/libc/sys/amdgcn/unlink.c @@ -0,0 +1,23 @@ +/* + * Support file for amdgcn in newlib. + * Copyright (c) 2019 Mentor Graphics. + * + * The authors hereby grant permission to use, copy, modify, distribute, + * and license this software and its documentation for any purpose, provided + * that existing copyright notices are retained in all copies and that this + * notice is included verbatim in any distributions. No written agreement, + * license, or royalty fee is required for any of the authorized uses. + * Modifications to this software may be copyrighted by their authors + * and need not follow the licensing terms described here, provided that + * the new terms are clearly indicated on the first page of each file where + * they apply. + */ + +#include + +int +unlink (const char *file) +{ + errno = EACCES; + return -1; +} From eb429ad509bf30a27a40b7a9b68d65915e18fb4f Mon Sep 17 00:00:00 2001 From: Jeff Johnston Date: Fri, 7 Jun 2019 13:57:45 -0400 Subject: [PATCH 404/475] Fix __getreent stack calculations for AMD GCN From: Andrew Stubbs Fix a bug in which the high-part of 64-bit values are being corrupted, leading to erroneous stack overflow errors. The problem was only that the mixed-size calculations are being treated as signed when they should be unsigned. --- newlib/libc/machine/amdgcn/getreent.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/newlib/libc/machine/amdgcn/getreent.c b/newlib/libc/machine/amdgcn/getreent.c index 5a28aa406..bc50ca022 100644 --- a/newlib/libc/machine/amdgcn/getreent.c +++ b/newlib/libc/machine/amdgcn/getreent.c @@ -35,9 +35,9 @@ __getreent (void) s[4:5] contains the dispatch pointer. WARNING: this code will break if s[0:3] is ever used for anything! */ - const register long buffer_descriptor asm("s0"); - long private_segment = buffer_descriptor & 0x0000ffffffffffff; - const register int stack_offset asm("s11"); + const register unsigned long buffer_descriptor asm("s0"); + unsigned long private_segment = buffer_descriptor & 0x0000ffffffffffff; + const register unsigned int stack_offset asm("s11"); const register hsa_kernel_dispatch_packet_t *dispatch_ptr asm("s4"); struct data { @@ -45,9 +45,9 @@ __getreent (void) struct _reent reent; } *data; - long stack_base = private_segment + stack_offset; - long stack_end = stack_base + dispatch_ptr->private_segment_size * 64; - long addr = (stack_end - sizeof(struct data)) & ~7; + unsigned long stack_base = private_segment + stack_offset; + unsigned long stack_end = stack_base + dispatch_ptr->private_segment_size * 64; + unsigned long addr = (stack_end - sizeof(struct data)) & ~7; data = (struct data *)addr; register long sp asm("s16"); From 000f2409b118e85daaa7064b5375245b8f48ab27 Mon Sep 17 00:00:00 2001 From: Ken Brown Date: Tue, 11 Jun 2019 08:11:01 -0400 Subject: [PATCH 405/475] Revert "Cygwin: fork: Remember child not before success." This reverts commit f03ea8e1c57bd5cea83f6cd47fa02870bdfeb1c5. That commit leads to fork problems if cygserver is running: https://cygwin.com/ml/cygwin-patches/2019-q2/msg00155.html --- winsup/cygwin/fork.cc | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/winsup/cygwin/fork.cc b/winsup/cygwin/fork.cc index c69081fc0..59b13806c 100644 --- a/winsup/cygwin/fork.cc +++ b/winsup/cygwin/fork.cc @@ -181,8 +181,7 @@ frok::child (volatile char * volatile here) cygheap->fdtab.fixup_after_fork (hParent); /* Signal that we have successfully initialized, so the parent can - - transfer data/bss for dynamically loaded dlls (if any), and - - start up some tracker threads to remember the child, or + - transfer data/bss for dynamically loaded dlls (if any), or - terminate the current fork call even if the child is initialized. */ sync_with_parent ("performed fork fixups and dynamic dll loading", true); @@ -412,6 +411,20 @@ frok::parent (volatile char * volatile stack_here) child.hProcess = hchild; ch.postfork (child); + /* Hopefully, this will succeed. The alternative to doing things this + way is to reserve space prior to calling CreateProcess and then fill + it in afterwards. This requires more bookkeeping than I like, though, + so we'll just do it the easy way. So, terminate any child process if + we can't actually record the pid in the internal table. */ + if (!child.remember (false)) + { + this_errno = EAGAIN; +#ifdef DEBUGGING0 + error ("child remember failed"); +#endif + goto cleanup; + } + /* CHILD IS STOPPED */ debug_printf ("child is alive (but stopped)"); @@ -495,20 +508,6 @@ frok::parent (volatile char * volatile stack_here) } } - /* Hopefully, this will succeed. The alternative to doing things this - way is to reserve space prior to calling CreateProcess and then fill - it in afterwards. This requires more bookkeeping than I like, though, - so we'll just do it the easy way. So, terminate any child process if - we can't actually record the pid in the internal table. */ - if (!child.remember (false)) - { - this_errno = EAGAIN; -#ifdef DEBUGGING0 - error ("child remember failed"); -#endif - goto cleanup; - } - /* Finally start the child up. */ resume_child (forker_finished); From ad101bcb0f55f0eb1a9f60187f949c3decd855e4 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Wed, 12 Jun 2019 22:31:14 +0200 Subject: [PATCH 406/475] Rename back to libX11 provides . The build of libX11 itself adds include/X11 to the compiler's include path. This results in a name collision with /usr/include/xlocale.h on case-insensitive filesystems. Commit 90e35b1eb3df renamed sys/_locale.h to xlocale.h in March 2017 under the assumption that we should provide the locale_t type in the same file as on Linux, FreeBSD, and Darwin. A few weeks later (June 2017), glibc removed the xlocale.h file in favor of bits/types/locale_t.h, which shouldn't be included directly anyway. For reference and the reasoning, see https://sourceware.org/git/?p=glibc.git;a=commit;h=f0be25b6336d Given the above, revert 90e35b1eb3df4070e68afc5e7060665214d586be and fix additional usage of xlocale.h. --- newlib/libc/include/ctype.h | 2 +- newlib/libc/include/inttypes.h | 2 +- newlib/libc/include/langinfo.h | 2 +- newlib/libc/include/locale.h | 2 +- newlib/libc/include/stdlib.h | 2 +- newlib/libc/include/string.h | 2 +- newlib/libc/include/strings.h | 2 +- newlib/libc/include/{xlocale.h => sys/_locale.h} | 6 +++--- newlib/libc/include/time.h | 2 +- newlib/libc/include/wchar.h | 2 +- newlib/libc/include/wctype.h | 2 +- winsup/cygwin/include/monetary.h | 2 +- winsup/cygwin/release/3.1.0 | 3 +++ winsup/doc/new-features.xml | 6 ++++++ 14 files changed, 23 insertions(+), 14 deletions(-) rename newlib/libc/include/{xlocale.h => sys/_locale.h} (70%) diff --git a/newlib/libc/include/ctype.h b/newlib/libc/include/ctype.h index 1cee6953b..a0009af17 100644 --- a/newlib/libc/include/ctype.h +++ b/newlib/libc/include/ctype.h @@ -5,7 +5,7 @@ #include #if __POSIX_VISIBLE >= 200809 || __MISC_VISIBLE || defined (_COMPILING_NEWLIB) -#include +#include #endif _BEGIN_STD_C diff --git a/newlib/libc/include/inttypes.h b/newlib/libc/include/inttypes.h index 694ba8fcf..073215476 100644 --- a/newlib/libc/include/inttypes.h +++ b/newlib/libc/include/inttypes.h @@ -22,7 +22,7 @@ #include #if __BSD_VISIBLE -#include +#include #endif #define __STRINGIFY(a) #a diff --git a/newlib/libc/include/langinfo.h b/newlib/libc/include/langinfo.h index d2b7a031c..fcf986cce 100644 --- a/newlib/libc/include/langinfo.h +++ b/newlib/libc/include/langinfo.h @@ -32,7 +32,7 @@ #include #include #if __POSIX_VISIBLE >= 200809 -#include +#include #endif #ifndef _NL_ITEM_DECLARED diff --git a/newlib/libc/include/locale.h b/newlib/libc/include/locale.h index d11eb00fb..8abb8db92 100644 --- a/newlib/libc/include/locale.h +++ b/newlib/libc/include/locale.h @@ -23,7 +23,7 @@ #if __POSIX_VISIBLE >= 200809 || defined (_COMPILING_NEWLIB) -#include +#include #define LC_ALL_MASK (1 << LC_ALL) #define LC_COLLATE_MASK (1 << LC_COLLATE) diff --git a/newlib/libc/include/stdlib.h b/newlib/libc/include/stdlib.h index 933d181e1..15b349440 100644 --- a/newlib/libc/include/stdlib.h +++ b/newlib/libc/include/stdlib.h @@ -27,7 +27,7 @@ #endif #if __GNU_VISIBLE -#include +#include #endif _BEGIN_STD_C diff --git a/newlib/libc/include/string.h b/newlib/libc/include/string.h index 04c4d1828..60e837bc0 100644 --- a/newlib/libc/include/string.h +++ b/newlib/libc/include/string.h @@ -17,7 +17,7 @@ #include #if __POSIX_VISIBLE >= 200809 -#include +#include #endif #if __BSD_VISIBLE diff --git a/newlib/libc/include/strings.h b/newlib/libc/include/strings.h index 7e2e557e7..f0f7ee137 100644 --- a/newlib/libc/include/strings.h +++ b/newlib/libc/include/strings.h @@ -33,7 +33,7 @@ #include #if __POSIX_VISIBLE >= 200809 -#include +#include #endif #ifndef _SIZE_T_DECLARED diff --git a/newlib/libc/include/xlocale.h b/newlib/libc/include/sys/_locale.h similarity index 70% rename from newlib/libc/include/xlocale.h rename to newlib/libc/include/sys/_locale.h index f9554269c..ce6f9955c 100644 --- a/newlib/libc/include/xlocale.h +++ b/newlib/libc/include/sys/_locale.h @@ -1,7 +1,7 @@ /* Definition of opaque POSIX-1.2008 type locale_t for userspace. */ -#ifndef _XLOCALE_H -#define _XLOCALE_H +#ifndef _SYS__LOCALE_H +#define _SYS__LOCALE_H #include #include @@ -9,4 +9,4 @@ struct __locale_t; typedef struct __locale_t *locale_t; -#endif /* _XLOCALE_H */ +#endif /* _SYS__LOCALE_H */ diff --git a/newlib/libc/include/time.h b/newlib/libc/include/time.h index d69d19969..3031590b4 100644 --- a/newlib/libc/include/time.h +++ b/newlib/libc/include/time.h @@ -29,7 +29,7 @@ #include #if __POSIX_VISIBLE >= 200809 -#include +#include #endif _BEGIN_STD_C diff --git a/newlib/libc/include/wchar.h b/newlib/libc/include/wchar.h index 9f2441c4f..c04a6510e 100644 --- a/newlib/libc/include/wchar.h +++ b/newlib/libc/include/wchar.h @@ -64,7 +64,7 @@ typedef __gnuc_va_list va_list; #endif #if __POSIX_VISIBLE >= 200809 -#include +#include #endif _BEGIN_STD_C diff --git a/newlib/libc/include/wctype.h b/newlib/libc/include/wctype.h index 9b710900d..e5452bfc3 100644 --- a/newlib/libc/include/wctype.h +++ b/newlib/libc/include/wctype.h @@ -8,7 +8,7 @@ #include #if __POSIX_VISIBLE >= 200809 -#include +#include #endif #ifndef WEOF diff --git a/winsup/cygwin/include/monetary.h b/winsup/cygwin/include/monetary.h index 82a6312bf..1c3479bd8 100644 --- a/winsup/cygwin/include/monetary.h +++ b/winsup/cygwin/include/monetary.h @@ -32,7 +32,7 @@ #include #include #if __POSIX_VISIBLE >= 200809 -#include +#include #endif __BEGIN_DECLS diff --git a/winsup/cygwin/release/3.1.0 b/winsup/cygwin/release/3.1.0 index fe65e5082..bdbbf092d 100644 --- a/winsup/cygwin/release/3.1.0 +++ b/winsup/cygwin/release/3.1.0 @@ -16,6 +16,9 @@ What changed: - If a SA_SIGINFO signal handler changes the ucontext_t pointed to by the third parameter, follow it after returning from the handler. +- Eliminate a header file name collision with on case + insensitive filesystems by reverting back to . + Bug Fixes --------- diff --git a/winsup/doc/new-features.xml b/winsup/doc/new-features.xml index 1ce011e3b..49aa5da74 100644 --- a/winsup/doc/new-features.xml +++ b/winsup/doc/new-features.xml @@ -8,6 +8,12 @@ + +Eliminate a header file name collision with <X11/XLocale.h> on +case insensitive filesystems by reverting <xlocale.h> back to +<sys/_locale.h>. + + FIFOs can now be opened multiple times for writing. From 724c18ff7e05545555689854571ea27ed73e8f0b Mon Sep 17 00:00:00 2001 From: Ken Brown Date: Sat, 8 Jun 2019 11:05:39 -0400 Subject: [PATCH 407/475] Cygwin: FIFO: fix signal handling in raw_read and raw_write cygwait wasn't being called correctly. Also do some minor cleanup in raw_read and raw_write. --- winsup/cygwin/fhandler_fifo.cc | 85 +++++++++++++++++++++------------- 1 file changed, 54 insertions(+), 31 deletions(-) diff --git a/winsup/cygwin/fhandler_fifo.cc b/winsup/cygwin/fhandler_fifo.cc index c9ff0a309..f63787f57 100644 --- a/winsup/cygwin/fhandler_fifo.cc +++ b/winsup/cygwin/fhandler_fifo.cc @@ -640,11 +640,15 @@ ssize_t __reg3 fhandler_fifo::raw_write (const void *ptr, size_t len) { ssize_t ret = -1; - size_t nbytes = 0, chunk; + size_t nbytes = 0; + ULONG chunk; NTSTATUS status = STATUS_SUCCESS; IO_STATUS_BLOCK io; HANDLE evt = NULL; + if (!len) + return 0; + if (len <= max_atomic_write) chunk = len; else if (is_nonblocking ()) @@ -654,7 +658,10 @@ fhandler_fifo::raw_write (const void *ptr, size_t len) /* Create a wait event if the FIFO is in blocking mode. */ if (!is_nonblocking () && !(evt = CreateEvent (NULL, false, false, NULL))) - return -1; + { + __seterrno (); + return -1; + } /* Write in chunks, accumulating a total. If there's an error, just return the accumulated total unless the first write fails, in @@ -663,33 +670,35 @@ fhandler_fifo::raw_write (const void *ptr, size_t len) { ULONG_PTR nbytes_now = 0; size_t left = len - nbytes; - size_t len1; + ULONG len1; + DWORD waitret = WAIT_OBJECT_0; + if (left > chunk) len1 = chunk; else - len1 = left; + len1 = (ULONG) left; nbytes_now = 0; status = NtWriteFile (get_handle (), evt, NULL, NULL, &io, (PVOID) ptr, len1, NULL, NULL); if (evt && status == STATUS_PENDING) { - DWORD waitret = cygwait (evt, cw_infinite, cw_cancel | cw_sig_eintr); - switch (waitret) - { - case WAIT_OBJECT_0: - status = io.Status; - break; - case WAIT_SIGNALED: - status = STATUS_THREAD_SIGNALED; - break; - case WAIT_CANCELED: - status = STATUS_THREAD_CANCELED; - break; - default: - break; - } + waitret = cygwait (evt); + if (waitret == WAIT_OBJECT_0) + status = io.Status; } - if (NT_SUCCESS (status)) + if (waitret == WAIT_CANCELED) + status = STATUS_THREAD_CANCELED; + else if (waitret == WAIT_SIGNALED) + status = STATUS_THREAD_SIGNALED; + else if (isclosed ()) /* A signal handler might have closed the fd. */ + { + if (waitret == WAIT_OBJECT_0) + set_errno (EBADF); + else + __seterrno (); + len = (size_t) -1; + } + else if (NT_SUCCESS (status)) { nbytes_now = io.Information; /* NtWriteFile returns success with # of bytes written == 0 @@ -714,7 +723,7 @@ fhandler_fifo::raw_write (const void *ptr, size_t len) } if (evt) CloseHandle (evt); - if (status == STATUS_THREAD_SIGNALED && !_my_tls.call_signal_handler ()) + if (status == STATUS_THREAD_SIGNALED && ret < 0) set_errno (EINTR); else if (status == STATUS_THREAD_CANCELED) pthread::static_cancel_self (); @@ -784,6 +793,9 @@ fhandler_fifo::raw_read (void *in_ptr, size_t& len) if (res < 0 || (res == 0 && !listen_client ())) goto errout; + if (!len) + return; + while (1) { if (hit_eof ()) @@ -827,21 +839,32 @@ fhandler_fifo::raw_read (void *in_ptr, size_t& len) } else { - /* Allow interruption. Copied from - fhandler_socket_unix::open_reparse_point. */ - pthread_testcancel (); - if (cygwait (NULL, cw_nowait, cw_sig_eintr) == WAIT_SIGNALED - && !_my_tls.call_signal_handler ()) + /* Allow interruption. */ + DWORD waitret = cygwait (NULL, cw_nowait, cw_cancel | cw_sig_eintr); + if (waitret == WAIT_CANCELED) + pthread::static_cancel_self (); + else if (waitret == WAIT_SIGNALED) { - set_errno (EINTR); - goto errout; + if (_my_tls.call_signal_handler ()) + continue; + else + { + set_errno (EINTR); + goto errout; + } } - /* Don't hog the CPU. */ - Sleep (1); } + /* We might have been closed by a signal handler or another thread. */ + if (isclosed ()) + { + set_errno (EBADF); + goto errout; + } + /* Don't hog the CPU. */ + Sleep (1); } errout: - len = -1; + len = (size_t) -1; } int __reg2 From a9b6d328823abaea1b94af95866fbe4eccdd8960 Mon Sep 17 00:00:00 2001 From: Ken Brown Date: Sat, 22 Jun 2019 11:46:49 -0400 Subject: [PATCH 408/475] Cygwin: FIFO: add some error checking Change the return type of fhandler_fifo::delete_client_handler from void to int so that we can report errors. --- winsup/cygwin/fhandler.h | 2 +- winsup/cygwin/fhandler_fifo.cc | 13 ++++++++++--- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h index f244f3486..156baed9c 100644 --- a/winsup/cygwin/fhandler.h +++ b/winsup/cygwin/fhandler.h @@ -1271,7 +1271,7 @@ class fhandler_fifo: public fhandler_base HANDLE create_pipe_instance (bool); NTSTATUS open_pipe (HANDLE&); int add_client_handler (); - void delete_client_handler (int); + int delete_client_handler (int); bool listen_client (); int stop_listen_client (); int check_listen_client_thread (); diff --git a/winsup/cygwin/fhandler_fifo.cc b/winsup/cygwin/fhandler_fifo.cc index f63787f57..4568ea080 100644 --- a/winsup/cygwin/fhandler_fifo.cc +++ b/winsup/cygwin/fhandler_fifo.cc @@ -257,13 +257,14 @@ out: return ret; } -void +int fhandler_fifo::delete_client_handler (int i) { - fc_handler[i].close (); + int ret = fc_handler[i].close (); if (i < --nhandlers) memmove (fc_handler + i, fc_handler + i + 1, (nhandlers - i) * sizeof (fc_handler[i])); + return ret; } /* Just hop to the listen_client_thread method. */ @@ -324,7 +325,13 @@ fhandler_fifo::listen_client_thread () while (i < nhandlers) { if (fc_handler[i].state == fc_invalid) - delete_client_handler (i); + { + if (delete_client_handler (i) < 0) + { + fifo_client_unlock (); + goto out; + } + } else i++; } From 281d3bf060d4de516cd5b47f14598bced786f053 Mon Sep 17 00:00:00 2001 From: Ken Brown Date: Sat, 22 Jun 2019 10:07:48 -0400 Subject: [PATCH 409/475] Cygwin: FIFO: clean up locks Make sure to use the fifo_client lock when (and only when) it is needed. --- winsup/cygwin/fhandler_fifo.cc | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/winsup/cygwin/fhandler_fifo.cc b/winsup/cygwin/fhandler_fifo.cc index 4568ea080..4291a7e5c 100644 --- a/winsup/cygwin/fhandler_fifo.cc +++ b/winsup/cygwin/fhandler_fifo.cc @@ -251,7 +251,9 @@ fhandler_fifo::add_client_handler () fh->set_nonblocking (false); ret = 0; fc.fh = fh; + fifo_client_lock (); fc_handler[nhandlers++] = fc; + fifo_client_unlock (); } out: return ret; @@ -298,12 +300,10 @@ fhandler_fifo::listen_client () void fhandler_fifo::record_connection (fifo_client_handler& fc) { - fifo_client_lock (); fc.state = fc_connected; nconnected++; fc.fh->set_nonblocking (true); set_pipe_non_blocking (fc.fh->get_handle (), true); - fifo_client_unlock (); HANDLE evt = InterlockedExchangePointer (&fc.connect_evt, NULL); if (evt) CloseHandle (evt); @@ -335,18 +335,15 @@ fhandler_fifo::listen_client_thread () else i++; } + fifo_client_unlock (); /* Create a new client handler. */ if (add_client_handler () < 0) - { - fifo_client_unlock (); - goto out; - } + goto out; /* Allow a writer to open. */ if (!arm (read_ready)) { - fifo_client_unlock (); __seterrno (); goto out; } @@ -359,7 +356,6 @@ fhandler_fifo::listen_client_thread () status = NtFsControlFile (fc.fh->get_handle (), fc.connect_evt, NULL, NULL, &io, FSCTL_PIPE_LISTEN, NULL, 0, NULL, 0); - fifo_client_unlock (); if (status == STATUS_PENDING) { HANDLE w[2] = { fc.connect_evt, lct_termination_evt }; @@ -381,6 +377,7 @@ fhandler_fifo::listen_client_thread () } } HANDLE ph = NULL; + fifo_client_lock (); switch (status) { case STATUS_SUCCESS: @@ -406,12 +403,15 @@ fhandler_fifo::listen_client_thread () will be declared invalid on the next read attempt. */ if (ph) CloseHandle (ph); + fifo_client_unlock (); goto out; default: __seterrno_from_nt_status (status); fc.state = fc_invalid; + fifo_client_unlock (); goto out; } + fifo_client_unlock (); /* Check for thread termination in case WaitForMultipleObjects didn't get called above. */ if (IsEventSignalled (lct_termination_evt)) @@ -933,9 +933,11 @@ fhandler_fifo::close () CloseHandle (read_ready); if (write_ready) CloseHandle (write_ready); + fifo_client_lock (); for (int i = 0; i < nhandlers; i++) if (fc_handler[i].close () < 0) ret = -1; + fifo_client_unlock (); return fhandler_base::close () || ret; } @@ -983,6 +985,7 @@ fhandler_fifo::dup (fhandler_base *child, int flags) __seterrno (); goto out; } + fifo_client_lock (); for (int i = 0; i < nhandlers; i++) { if (!DuplicateHandle (GetCurrentProcess (), fc_handler[i].fh->get_handle (), @@ -990,6 +993,7 @@ fhandler_fifo::dup (fhandler_base *child, int flags) &fhf->fc_handler[i].fh->get_handle (), 0, true, DUPLICATE_SAME_ACCESS)) { + fifo_client_unlock (); CloseHandle (fhf->read_ready); CloseHandle (fhf->write_ready); fhf->close (); @@ -997,6 +1001,7 @@ fhandler_fifo::dup (fhandler_base *child, int flags) goto out; } } + fifo_client_unlock (); if (!reader || fhf->listen_client ()) ret = 0; if (reader) @@ -1017,8 +1022,10 @@ fhandler_fifo::fixup_after_fork (HANDLE parent) fhandler_base::fixup_after_fork (parent); fork_fixup (parent, read_ready, "read_ready"); fork_fixup (parent, write_ready, "write_ready"); + fifo_client_lock (); for (int i = 0; i < nhandlers; i++) fc_handler[i].fh->fhandler_base::fixup_after_fork (parent); + fifo_client_unlock (); if (reader && !listen_client ()) debug_printf ("failed to start lct, %E"); } @@ -1037,6 +1044,8 @@ fhandler_fifo::set_close_on_exec (bool val) fhandler_base::set_close_on_exec (val); set_no_inheritance (read_ready, val); set_no_inheritance (write_ready, val); + fifo_client_lock (); for (int i = 0; i < nhandlers; i++) fc_handler[i].fh->fhandler_base::set_close_on_exec (val); + fifo_client_unlock (); } From d1b36ea949e275c803787523b0b04657895638fc Mon Sep 17 00:00:00 2001 From: Ken Brown Date: Sat, 22 Jun 2019 13:58:12 -0400 Subject: [PATCH 410/475] Cygwin: FIFO: avoid deadlock when closing fhandler_fifo::close could be called from a signal handler or another thread at a time when another function is holding the fifo_client lock. This could prevent the listen_client thread from acting on the thread termination event. Avoid a deadlock by calling fifo_client_unlock at the beginning of fhandler_fifo::close. --- winsup/cygwin/fhandler_fifo.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/winsup/cygwin/fhandler_fifo.cc b/winsup/cygwin/fhandler_fifo.cc index 4291a7e5c..8afa39747 100644 --- a/winsup/cygwin/fhandler_fifo.cc +++ b/winsup/cygwin/fhandler_fifo.cc @@ -928,6 +928,9 @@ fhandler_fifo::stop_listen_client () int fhandler_fifo::close () { + /* Avoid deadlock with lct in case this is called from a signal + handler or another thread. */ + fifo_client_unlock (); int ret = stop_listen_client (); if (read_ready) CloseHandle (read_ready); From 5bd5e3dc6c576224bbff65014af66d1fbe879751 Mon Sep 17 00:00:00 2001 From: Ken Brown Date: Fri, 21 Jun 2019 18:49:11 -0400 Subject: [PATCH 411/475] Cygwin: FIFO: improve termination of the listen_client thread Add a method fifo_client_handler::pipe_state that queries Windows for the state of a pipe instance. Use this to help terminate the listen_client thread cleanly. If the last client handler is useless, delete it instead of declaring it invalid. --- winsup/cygwin/fhandler.h | 9 +++++ winsup/cygwin/fhandler_fifo.cc | 61 +++++++++++++++++++++++++--------- 2 files changed, 55 insertions(+), 15 deletions(-) diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h index 156baed9c..293a3e06e 100644 --- a/winsup/cygwin/fhandler.h +++ b/winsup/cygwin/fhandler.h @@ -1244,6 +1244,11 @@ enum fifo_client_connect_state fc_invalid }; +enum +{ + FILE_PIPE_INPUT_AVAILABLE_STATE = 5 +}; + struct fifo_client_handler { fhandler_base *fh; @@ -1251,6 +1256,10 @@ struct fifo_client_handler HANDLE connect_evt; fifo_client_handler () : fh (NULL), state (fc_unknown), connect_evt (NULL) {} int close (); +/* Returns FILE_PIPE_DISCONNECTED_STATE, FILE_PIPE_LISTENING_STATE, + FILE_PIPE_CONNECTED_STATE, FILE_PIPE_CLOSING_STATE, + FILE_PIPE_INPUT_AVAILABLE_STATE, or -1 on error. */ + int pipe_state (); }; class fhandler_fifo: public fhandler_base diff --git a/winsup/cygwin/fhandler_fifo.cc b/winsup/cygwin/fhandler_fifo.cc index 8afa39747..b96c4d5e2 100644 --- a/winsup/cygwin/fhandler_fifo.cc +++ b/winsup/cygwin/fhandler_fifo.cc @@ -377,6 +377,7 @@ fhandler_fifo::listen_client_thread () } } HANDLE ph = NULL; + int ps = -1; fifo_client_lock (); switch (status) { @@ -385,29 +386,38 @@ fhandler_fifo::listen_client_thread () record_connection (fc); break; case STATUS_THREAD_IS_TERMINATING: - /* Try to cancel the pending listen. Otherwise the first - writer to connect after the thread is restarted will be - invisible. - - FIXME: Is there a direct way to do this? We do it by - opening and closing a write handle to the client side. */ - open_pipe (ph); - /* We don't care about the return value of open_pipe. Even - if the latter failed, a writer might have connected. */ - if (WaitForSingleObject (fc.connect_evt, 0) == WAIT_OBJECT_0 + /* Force NtFsControlFile to complete. Otherwise the next + writer to connect might not be recorded in the client + handler list. */ + status = open_pipe (ph); + if (NT_SUCCESS (status) && (NT_SUCCESS (io.Status) || io.Status == STATUS_PIPE_CONNECTED)) - record_connection (fc); + { + debug_printf ("successfully connected bogus client"); + if (delete_client_handler (nhandlers - 1) < 0) + ret = -1; + } + else if ((ps = fc.pipe_state ()) == FILE_PIPE_CONNECTED_STATE + || ps == FILE_PIPE_INPUT_AVAILABLE_STATE) + { + /* A connection was made under our nose. */ + debug_printf ("recording connection before terminating"); + record_connection (fc); + } else - fc.state = fc_invalid; - /* By closing ph we ensure that if fc connected to ph, fc - will be declared invalid on the next read attempt. */ + { + debug_printf ("failed to terminate NtFsControlFile cleanly"); + delete_client_handler (nhandlers - 1); + ret = -1; + } if (ph) CloseHandle (ph); fifo_client_unlock (); goto out; default: + debug_printf ("NtFsControlFile status %y", status); __seterrno_from_nt_status (status); - fc.state = fc_invalid; + delete_client_handler (nhandlers - 1); fifo_client_unlock (); goto out; } @@ -898,6 +908,27 @@ fifo_client_handler::close () return res; } +int +fifo_client_handler::pipe_state () +{ + IO_STATUS_BLOCK io; + FILE_PIPE_LOCAL_INFORMATION fpli; + NTSTATUS status; + + status = NtQueryInformationFile (fh->get_handle (), &io, &fpli, + sizeof (fpli), FilePipeLocalInformation); + if (!NT_SUCCESS (status)) + { + debug_printf ("NtQueryInformationFile status %y", status); + __seterrno_from_nt_status (status); + return -1; + } + else if (fpli.ReadDataAvailable > 0) + return FILE_PIPE_INPUT_AVAILABLE_STATE; + else + return fpli.NamedPipeState; +} + int fhandler_fifo::stop_listen_client () { From 5b2696cb83617234446f3f4a304573c6aa3125d3 Mon Sep 17 00:00:00 2001 From: Ken Brown Date: Fri, 21 Jun 2019 17:33:30 -0400 Subject: [PATCH 412/475] Cygwin: FIFO: simplify raw_read Call NtReadFile directly instead of calling fhandler_base::raw_read. In addition to being simpler, this gives us access to the return value from NtReadFile. --- winsup/cygwin/fhandler_fifo.cc | 50 +++++++++++++++++++++------------- 1 file changed, 31 insertions(+), 19 deletions(-) diff --git a/winsup/cygwin/fhandler_fifo.cc b/winsup/cygwin/fhandler_fifo.cc index b96c4d5e2..b755544aa 100644 --- a/winsup/cygwin/fhandler_fifo.cc +++ b/winsup/cygwin/fhandler_fifo.cc @@ -802,8 +802,6 @@ fhandler_fifo::check_listen_client_thread () void __reg3 fhandler_fifo::raw_read (void *in_ptr, size_t& len) { - size_t orig_len = len; - /* Make sure the lct is running. */ int res = check_listen_client_thread (); debug_printf ("lct status %d", res); @@ -826,26 +824,40 @@ fhandler_fifo::raw_read (void *in_ptr, size_t& len) for (int i = 0; i < nhandlers; i++) if (fc_handler[i].state == fc_connected) { - len = orig_len; - fc_handler[i].fh->fhandler_base::raw_read (in_ptr, len); - ssize_t nread = (ssize_t) len; - if (nread > 0) - { - fifo_client_unlock (); - return; - } - /* If the pipe is empty, we get nread == -1 with - ERROR_NO_DATA. */ - else if (nread < 0 && GetLastError () != ERROR_NO_DATA) - { - fifo_client_unlock (); - goto errout; - } - else if (nread == 0) - /* Client has disconnected. */ + NTSTATUS status; + IO_STATUS_BLOCK io; + size_t nbytes = 0; + + status = NtReadFile (get_fc_handle (i), NULL, NULL, NULL, + &io, in_ptr, len, NULL, NULL); + switch (status) { + case STATUS_SUCCESS: + case STATUS_BUFFER_OVERFLOW: + /* io.Information is supposedly valid. */ + nbytes = io.Information; + if (nbytes > 0) + { + len = nbytes; + fifo_client_unlock (); + return; + } + break; + case STATUS_PIPE_EMPTY: + break; + case STATUS_PIPE_BROKEN: + /* Client has disconnected. Mark the client handler + to be deleted when it's safe to do that. */ fc_handler[i].state = fc_invalid; nconnected--; + break; + default: + debug_printf ("NtReadFile status %y", status); + __seterrno_from_nt_status (status); + fc_handler[i].state = fc_invalid; + nconnected--; + fifo_client_unlock (); + goto errout; } } fifo_client_unlock (); From 6e7e82fee758695c3e46618038325d41e44fbef5 Mon Sep 17 00:00:00 2001 From: Ken Brown Date: Thu, 20 Jun 2019 15:14:47 -0400 Subject: [PATCH 413/475] Cygwin: FIFO: remove fifo_client_handler::connect_evt It's not needed. Instead just create and use an event in fhandler_fifo::listen_client_thread. --- winsup/cygwin/fhandler.h | 3 +-- winsup/cygwin/fhandler_fifo.cc | 28 ++++++++++++++-------------- 2 files changed, 15 insertions(+), 16 deletions(-) diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h index 293a3e06e..185de988a 100644 --- a/winsup/cygwin/fhandler.h +++ b/winsup/cygwin/fhandler.h @@ -1253,8 +1253,7 @@ struct fifo_client_handler { fhandler_base *fh; fifo_client_connect_state state; - HANDLE connect_evt; - fifo_client_handler () : fh (NULL), state (fc_unknown), connect_evt (NULL) {} + fifo_client_handler () : fh (NULL), state (fc_unknown) {} int close (); /* Returns FILE_PIPE_DISCONNECTED_STATE, FILE_PIPE_LISTENING_STATE, FILE_PIPE_CONNECTED_STATE, FILE_PIPE_CLOSING_STATE, diff --git a/winsup/cygwin/fhandler_fifo.cc b/winsup/cygwin/fhandler_fifo.cc index b755544aa..a060cb3fc 100644 --- a/winsup/cygwin/fhandler_fifo.cc +++ b/winsup/cygwin/fhandler_fifo.cc @@ -231,8 +231,6 @@ fhandler_fifo::add_client_handler () set_errno (EMFILE); goto out; } - if (!(fc.connect_evt = create_event ())) - goto out; if (!(fh = build_fh_dev (dev ()))) { set_errno (EMFILE); @@ -304,15 +302,16 @@ fhandler_fifo::record_connection (fifo_client_handler& fc) nconnected++; fc.fh->set_nonblocking (true); set_pipe_non_blocking (fc.fh->get_handle (), true); - HANDLE evt = InterlockedExchangePointer (&fc.connect_evt, NULL); - if (evt) - CloseHandle (evt); } DWORD fhandler_fifo::listen_client_thread () { DWORD ret = -1; + HANDLE evt; + + if (!(evt = create_event ())) + goto out; while (1) { @@ -353,12 +352,11 @@ fhandler_fifo::listen_client_thread () NTSTATUS status; IO_STATUS_BLOCK io; - status = NtFsControlFile (fc.fh->get_handle (), fc.connect_evt, - NULL, NULL, &io, FSCTL_PIPE_LISTEN, - NULL, 0, NULL, 0); + status = NtFsControlFile (fc.fh->get_handle (), evt, NULL, NULL, &io, + FSCTL_PIPE_LISTEN, NULL, 0, NULL, 0); if (status == STATUS_PENDING) { - HANDLE w[2] = { fc.connect_evt, lct_termination_evt }; + HANDLE w[2] = { evt, lct_termination_evt }; DWORD waitret = WaitForMultipleObjects (2, w, false, INFINITE); switch (waitret) { @@ -384,6 +382,7 @@ fhandler_fifo::listen_client_thread () case STATUS_SUCCESS: case STATUS_PIPE_CONNECTED: record_connection (fc); + ResetEvent (evt); break; case STATUS_THREAD_IS_TERMINATING: /* Force NtFsControlFile to complete. Otherwise the next @@ -431,9 +430,13 @@ fhandler_fifo::listen_client_thread () } } out: - if (ret < 0) - debug_printf ("exiting lct with error, %E"); + if (evt) + CloseHandle (evt); ResetEvent (read_ready); + if (ret < 0) + debug_printf ("exiting with error, %E"); + else + debug_printf ("exiting without error"); return ret; } @@ -908,10 +911,7 @@ int fifo_client_handler::close () { int res = 0; - HANDLE evt = InterlockedExchangePointer (&connect_evt, NULL); - if (evt) - CloseHandle (evt); if (fh) { res = fh->fhandler_base::close (); From 23570916173c9f16213f1a524ddc96878b4c9d80 Mon Sep 17 00:00:00 2001 From: Ken Brown Date: Wed, 19 Jun 2019 11:14:37 -0400 Subject: [PATCH 414/475] Cygwin: FIFO: slightly change the use of write_ready Make it a manual reset event. It's only used once to allow a reader to open, and there's no reason to ever reset it. Defensively set it when a client connection is recorded, even though it should be set by the writer that connected. --- winsup/cygwin/fhandler_fifo.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/winsup/cygwin/fhandler_fifo.cc b/winsup/cygwin/fhandler_fifo.cc index a060cb3fc..e0af54b2e 100644 --- a/winsup/cygwin/fhandler_fifo.cc +++ b/winsup/cygwin/fhandler_fifo.cc @@ -298,6 +298,7 @@ fhandler_fifo::listen_client () void fhandler_fifo::record_connection (fifo_client_handler& fc) { + SetEvent (write_ready); fc.state = fc_connected; nconnected++; fc.fh->set_nonblocking (true); @@ -489,7 +490,7 @@ fhandler_fifo::open (int flags, mode_t) goto out; } npbuf[0] = 'w'; - if (!(write_ready = CreateEvent (sa_buf, false, false, npbuf))) + if (!(write_ready = CreateEvent (sa_buf, true, false, npbuf))) { debug_printf ("CreateEvent for %s failed, %E", npbuf); res = error_set_errno; From d54edfdf81b20832aff8627b31a579fb5ba0106e Mon Sep 17 00:00:00 2001 From: Ken Brown Date: Sat, 22 Jun 2019 11:49:44 -0400 Subject: [PATCH 415/475] Cygwin: FIFO: minor cleanup Don't use a label with the same name as a variable. Also fix indentation in fhandler.h. --- winsup/cygwin/fhandler.h | 10 +++++----- winsup/cygwin/fhandler_fifo.cc | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h index 185de988a..7e59d84d0 100644 --- a/winsup/cygwin/fhandler.h +++ b/winsup/cygwin/fhandler.h @@ -1238,11 +1238,11 @@ public: #define MAX_CLIENTS 64 enum fifo_client_connect_state - { - fc_unknown, - fc_connected, - fc_invalid - }; +{ + fc_unknown, + fc_connected, + fc_invalid +}; enum { diff --git a/winsup/cygwin/fhandler_fifo.cc b/winsup/cygwin/fhandler_fifo.cc index e0af54b2e..edc6caeb3 100644 --- a/winsup/cygwin/fhandler_fifo.cc +++ b/winsup/cygwin/fhandler_fifo.cc @@ -761,7 +761,7 @@ fhandler_fifo::hit_eof () bool eof; bool retry = true; -retry: +repeat: fifo_client_lock (); eof = (nconnected == 0); fifo_client_unlock (); @@ -770,7 +770,7 @@ retry: retry = false; /* Give the listen_client thread time to catch up. */ Sleep (1); - goto retry; + goto repeat; } return eof; } From 641ecb07533e85211b6abce334c85967f3f90209 Mon Sep 17 00:00:00 2001 From: Mark Geisert Date: Sun, 23 Jun 2019 14:51:06 -0700 Subject: [PATCH 416/475] Cygwin: Implement sched_[gs]etaffinity() This patch set implements the Linux syscalls sched_getaffinity, sched_setaffinity, pthread_getaffinity_np, and pthread_setaffinity_np. Linux has a straightforward view of the cpu sets used in affinity masks. They are simply long (1024-bit) bit masks. This code emulates that view while internally dealing with Windows' distribution of available CPUs among processor groups. --- newlib/libc/include/sched.h | 23 ++ winsup/cygwin/common.din | 4 + winsup/cygwin/include/cygwin/version.h | 4 +- winsup/cygwin/include/pthread.h | 2 + winsup/cygwin/miscfuncs.cc | 20 +- winsup/cygwin/miscfuncs.h | 1 + winsup/cygwin/release/3.1.0 | 3 + winsup/cygwin/sched.cc | 308 +++++++++++++++++++++++++ winsup/cygwin/thread.cc | 19 ++ winsup/doc/new-features.xml | 6 + winsup/doc/posix.xml | 4 + 11 files changed, 389 insertions(+), 5 deletions(-) diff --git a/newlib/libc/include/sched.h b/newlib/libc/include/sched.h index 1016235bb..fc44209d6 100644 --- a/newlib/libc/include/sched.h +++ b/newlib/libc/include/sched.h @@ -92,6 +92,29 @@ int sched_yield( void ); #if __GNU_VISIBLE int sched_getcpu(void); + +/* Affinity-related definitions, here until numerous enough to separate out */ +#ifdef __x86_64__ +typedef uint64_t __cpu_mask; +#else +typedef uint32_t __cpu_mask; +#endif +#define __CPU_SETSIZE 1024 // maximum number of logical processors tracked +#define __NCPUBITS (8 * sizeof (__cpu_mask)) // max size of processor group +#define __CPU_GROUPMAX (__CPU_SETSIZE / __NCPUBITS) // maximum group number + +#define __CPUELT(cpu) ((cpu) / __NCPUBITS) +#define __CPUMASK(cpu) ((__cpu_mask) 1 << ((cpu) % __NCPUBITS)) + +typedef struct +{ + __cpu_mask __bits[__CPU_GROUPMAX]; +} cpu_set_t; + +int sched_getaffinity (pid_t, size_t, cpu_set_t *); +int sched_get_thread_affinity (void *, size_t, cpu_set_t *); +int sched_setaffinity (pid_t, size_t, const cpu_set_t *); +int sched_set_thread_affinity (void *, size_t, const cpu_set_t *); #endif #ifdef __cplusplus diff --git a/winsup/cygwin/common.din b/winsup/cygwin/common.din index 68b95d470..81292ab7b 100644 --- a/winsup/cygwin/common.din +++ b/winsup/cygwin/common.din @@ -1084,6 +1084,7 @@ pthread_create SIGFE pthread_detach SIGFE pthread_equal SIGFE pthread_exit SIGFE +pthread_getaffinity_np SIGFE pthread_getattr_np SIGFE pthread_getconcurrency SIGFE pthread_getcpuclockid SIGFE @@ -1128,6 +1129,7 @@ pthread_rwlockattr_getpshared SIGFE pthread_rwlockattr_init SIGFE pthread_rwlockattr_setpshared SIGFE pthread_self SIGFE +pthread_setaffinity_np SIGFE pthread_setcancelstate SIGFE pthread_setcanceltype SIGFE pthread_setconcurrency SIGFE @@ -1248,10 +1250,12 @@ scandirat SIGFE scanf SIGFE sched_get_priority_max SIGFE sched_get_priority_min SIGFE +sched_getaffinity SIGFE sched_getcpu SIGFE sched_getparam SIGFE sched_getscheduler NOSIGFE sched_rr_get_interval SIGFE +sched_setaffinity SIGFE sched_setparam SIGFE sched_setscheduler SIGFE sched_yield SIGFE diff --git a/winsup/cygwin/include/cygwin/version.h b/winsup/cygwin/include/cygwin/version.h index bb4ffe771..b70b9e281 100644 --- a/winsup/cygwin/include/cygwin/version.h +++ b/winsup/cygwin/include/cygwin/version.h @@ -509,12 +509,14 @@ details. */ 336: New Cygwin PID algorithm (yeah, not really an API change) 337: MOUNT_BINARY -> MOUNT_TEXT 338: Export secure_getenv. + 339: Export sched_getaffinity, sched_setaffinity, pthread_getaffinity_np, + pthread_setaffinity_np. Note that we forgot to bump the api for ualarm, strtoll, strtoull, sigaltstack, sethostname. */ #define CYGWIN_VERSION_API_MAJOR 0 -#define CYGWIN_VERSION_API_MINOR 338 +#define CYGWIN_VERSION_API_MINOR 339 /* There is also a compatibity version number associated with the shared memory regions. It is incremented when incompatible changes are made to the shared diff --git a/winsup/cygwin/include/pthread.h b/winsup/cygwin/include/pthread.h index 2ccf1cf8b..4ef3aeab7 100644 --- a/winsup/cygwin/include/pthread.h +++ b/winsup/cygwin/include/pthread.h @@ -226,8 +226,10 @@ void pthread_testcancel (void); /* Non posix calls */ #if __GNU_VISIBLE +int pthread_getaffinity_np (pthread_t, size_t, cpu_set_t *); int pthread_getattr_np (pthread_t, pthread_attr_t *); int pthread_getname_np (pthread_t, char *, size_t) __attribute__((__nonnull__(2))); +int pthread_setaffinity_np (pthread_t, size_t, const cpu_set_t *); int pthread_setname_np (pthread_t, const char *) __attribute__((__nonnull__(2))); int pthread_sigqueue (pthread_t *, int, const union sigval); int pthread_timedjoin_np (pthread_t, void **, const struct timespec *); diff --git a/winsup/cygwin/miscfuncs.cc b/winsup/cygwin/miscfuncs.cc index b5dfffc7d..e02bc9c1f 100644 --- a/winsup/cygwin/miscfuncs.cc +++ b/winsup/cygwin/miscfuncs.cc @@ -963,17 +963,19 @@ SetThreadName(DWORD dwThreadID, const char* threadName) #define add_size(p,s) ((p) = ((__typeof__(p))((PBYTE)(p)+(s)))) +static WORD num_cpu_per_group = 0; +static WORD group_count = 0; + WORD __get_cpus_per_group (void) { - static WORD num_cpu_per_group = 0; - tmp_pathbuf tp; if (num_cpu_per_group) return num_cpu_per_group; num_cpu_per_group = 64; + group_count = 1; PSYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX lpi = (PSYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX) tp.c_get (); @@ -1005,10 +1007,20 @@ __get_cpus_per_group (void) actually available CPUs. The ActiveProcessorCount is correct though. So we just use ActiveProcessorCount for now, hoping for the best. */ - num_cpu_per_group - = plpi->Group.GroupInfo[0].ActiveProcessorCount; + num_cpu_per_group = plpi->Group.GroupInfo[0].ActiveProcessorCount; + + /* Follow that lead to get the group count. */ + group_count = plpi->Group.ActiveGroupCount; break; } return num_cpu_per_group; } + +WORD +__get_group_count (void) +{ + if (group_count == 0) + (void) __get_cpus_per_group (); // caller should have called this first + return group_count; +} diff --git a/winsup/cygwin/miscfuncs.h b/winsup/cygwin/miscfuncs.h index b983e6d81..d1e519fa6 100644 --- a/winsup/cygwin/miscfuncs.h +++ b/winsup/cygwin/miscfuncs.h @@ -120,5 +120,6 @@ extern "C" HANDLE WINAPI CygwinCreateThread (LPTHREAD_START_ROUTINE thread_func, void SetThreadName (DWORD dwThreadID, const char* threadName); WORD __get_cpus_per_group (void); +WORD __get_group_count (void); #endif /*_MISCFUNCS_H*/ diff --git a/winsup/cygwin/release/3.1.0 b/winsup/cygwin/release/3.1.0 index bdbbf092d..a2bdc8f3c 100644 --- a/winsup/cygwin/release/3.1.0 +++ b/winsup/cygwin/release/3.1.0 @@ -5,6 +5,9 @@ What's new: 1703 or later. Add fake 24 bit color support for legacy console, which uses the nearest color from 16 system colors. +- New APIs: sched_getaffinity, sched_setaffinity, pthread_getaffinity_np, + pthread_setaffinity_np. + What changed: ------------- diff --git a/winsup/cygwin/sched.cc b/winsup/cygwin/sched.cc index 10168e641..e7b44d319 100644 --- a/winsup/cygwin/sched.cc +++ b/winsup/cygwin/sched.cc @@ -424,4 +424,312 @@ sched_getcpu () return pnum.Group * __get_cpus_per_group () + pnum.Number; } +/* construct an affinity mask with just the 'count' lower-order bits set */ +static __cpu_mask +groupmask (int count) +{ + if (count >= (int) (NBBY * sizeof (__cpu_mask))) + return ~(__cpu_mask) 0; + else + return ((__cpu_mask) 1 << count) - 1; +} + +/* return the affinity mask of the indicated group from the given cpu set */ +static __cpu_mask +getgroup (size_t sizeof_set, const cpu_set_t *set, int groupnum) +{ + int groupsize = __get_cpus_per_group (); + int bitindex = groupnum * groupsize; + + int setsize = NBBY * sizeof_set; // bit size of whole cpu set + if (bitindex + groupsize > setsize) + return (__cpu_mask) 0; + + int wordsize = NBBY * sizeof (cpu_set_t); + int wordindex = bitindex / wordsize; + + __cpu_mask result = set->__bits[wordindex]; + int offset = bitindex % wordsize; + if (offset) + { + result >>= offset; + offset = wordsize - offset; + } + else + offset = wordsize; + + if (offset < groupsize) + result |= (set->__bits[wordindex + 1] << offset); + if (groupsize < wordsize) + result &= groupmask (groupsize); + + return result; +} + +/* set the given affinity mask for indicated group within the given cpu set */ +static __cpu_mask +setgroup (size_t sizeof_set, cpu_set_t *set, int groupnum, __cpu_mask aff) +{ + int groupsize = __get_cpus_per_group (); + int bitindex = groupnum * groupsize; + + int setsize = NBBY * sizeof_set; // bit size of whole cpu set + if (bitindex + groupsize > setsize) + return (__cpu_mask) 0; + + int wordsize = NBBY * sizeof (cpu_set_t); + int wordindex = bitindex / wordsize; + int offset = bitindex % wordsize; + __cpu_mask mask = groupmask (groupsize); + aff &= mask; + + set->__bits[wordindex] &= ~(mask << offset); + set->__bits[wordindex] |= aff << offset; + + if ((bitindex + groupsize - 1) / wordsize != wordindex) + { + offset = wordsize - offset; + set->__bits[wordindex + 1] &= ~(mask >> offset); + set->__bits[wordindex + 1] |= aff >> offset; + } + + return aff; +} + +/* figure out which processor group the set bits indicate; can only be one */ +static int +whichgroup (size_t sizeof_set, const cpu_set_t *set) +{ + int res = -1; + int maxgroup = min (__get_group_count (), + (NBBY * sizeof_set) / __get_cpus_per_group ()); + + for (int i = 0; i < maxgroup; ++i) + if (getgroup (sizeof_set, set, i)) + { + if (res >= 0) + return -1; // error return if more than one group indicated + else + res = i; // remember first group found + } + + return res; +} + +int +sched_get_thread_affinity (HANDLE thread, size_t sizeof_set, cpu_set_t *set) +{ + int status = 0; + + if (thread) + { + memset (set, 0, sizeof_set); + if (wincap.has_processor_groups () && __get_group_count () > 1) + { + GROUP_AFFINITY ga; + + if (!GetThreadGroupAffinity (thread, &ga)) + { + status = geterrno_from_win_error (GetLastError (), EPERM); + goto done; + } + setgroup (sizeof_set, set, ga.Group, ga.Mask); + } + else + { + THREAD_BASIC_INFORMATION tbi; + + status = NtQueryInformationThread (thread, ThreadBasicInformation, + &tbi, sizeof (tbi), NULL); + if (NT_SUCCESS (status)) + setgroup (sizeof_set, set, 0, tbi.AffinityMask); + else + status = geterrno_from_nt_status (status); + } + } + else + status = ESRCH; + +done: + return status; +} + +int +sched_getaffinity (pid_t pid, size_t sizeof_set, cpu_set_t *set) +{ + HANDLE process = 0; + int status = 0; + + pinfo p (pid ? pid : getpid ()); + if (p) + { + process = pid && pid != myself->pid ? + OpenProcess (PROCESS_QUERY_LIMITED_INFORMATION, FALSE, + p->dwProcessId) : GetCurrentProcess (); + KAFFINITY procmask; + KAFFINITY sysmask; + + if (!GetProcessAffinityMask (process, &procmask, &sysmask)) + { + status = geterrno_from_win_error (GetLastError (), EPERM); + goto done; + } + memset (set, 0, sizeof_set); + if (wincap.has_processor_groups () && __get_group_count () > 1) + { + USHORT groupcount = __CPU_GROUPMAX; + USHORT grouparray[__CPU_GROUPMAX]; + + if (!GetProcessGroupAffinity (process, &groupcount, grouparray)) + { + status = geterrno_from_win_error (GetLastError (), EPERM); + goto done; + } + + KAFFINITY miscmask = groupmask (__get_cpus_per_group ()); + for (int i = 0; i < groupcount; i++) + setgroup (sizeof_set, set, grouparray[i], miscmask); + } + else + setgroup (sizeof_set, set, 0, procmask); + } + else + status = ESRCH; + +done: + if (process && process != GetCurrentProcess ()) + CloseHandle (process); + + if (status) + { + set_errno (status); + status = -1; + } + else + { + /* Emulate documented Linux kernel behavior on successful return */ + status = wincap.cpu_count (); + } + return status; +} + +int +sched_set_thread_affinity (HANDLE thread, size_t sizeof_set, const cpu_set_t *set) +{ + int group = whichgroup (sizeof_set, set); + int status = 0; + + if (thread) + { + if (wincap.has_processor_groups () && __get_group_count () > 1) + { + GROUP_AFFINITY ga; + + if (group < 0) + { + status = EINVAL; + goto done; + } + memset (&ga, 0, sizeof (ga)); + ga.Mask = getgroup (sizeof_set, set, group); + ga.Group = group; + if (!SetThreadGroupAffinity (thread, &ga, NULL)) + { + status = geterrno_from_win_error (GetLastError (), EPERM); + goto done; + } + } + else + { + if (group != 0) + { + status = EINVAL; + goto done; + } + if (!SetThreadAffinityMask (thread, getgroup (sizeof_set, set, 0))) + { + status = geterrno_from_win_error (GetLastError (), EPERM); + goto done; + } + } + } + else + status = ESRCH; + +done: + return status; +} + +int +sched_setaffinity (pid_t pid, size_t sizeof_set, const cpu_set_t *set) +{ + int group = whichgroup (sizeof_set, set); + HANDLE process = 0; + int status = 0; + + pinfo p (pid ? pid : getpid ()); + if (p) + { + process = pid && pid != myself->pid ? + OpenProcess (PROCESS_SET_INFORMATION, FALSE, + p->dwProcessId) : GetCurrentProcess (); + if (wincap.has_processor_groups () && __get_group_count () > 1) + { + USHORT groupcount = __CPU_GROUPMAX; + USHORT grouparray[__CPU_GROUPMAX]; + + if (!GetProcessGroupAffinity (process, &groupcount, grouparray)) + { + status = geterrno_from_win_error (GetLastError (), EPERM); + goto done; + } + if (group < 0) + { + status = EINVAL; + goto done; + } + if (groupcount == 1 && grouparray[0] == group) + { + if (!SetProcessAffinityMask (process, getgroup (sizeof_set, set, group))) + status = geterrno_from_win_error (GetLastError (), EPERM); + goto done; + } + + /* If we get here, the user is trying to add the process to another + group or move it from current group to another group. These ops + are not allowed by Windows. One has to move one or more of the + process' threads to the new group(s) one by one. Here, we bail. + */ + status = EINVAL; + goto done; + } + else + { + if (group != 0) + { + status = EINVAL; + goto done; + } + if (!SetProcessAffinityMask (process, getgroup (sizeof_set, set, 0))) + { + status = geterrno_from_win_error (GetLastError (), EPERM); + goto done; + } + } + } + else + status = ESRCH; + +done: + if (process && process != GetCurrentProcess ()) + CloseHandle (process); + + if (status) + { + set_errno (status); + status = -1; + } + return status; +} + } /* extern C */ diff --git a/winsup/cygwin/thread.cc b/winsup/cygwin/thread.cc index f353dd497..43a6c88b3 100644 --- a/winsup/cygwin/thread.cc +++ b/winsup/cygwin/thread.cc @@ -23,6 +23,7 @@ details. */ #include "winsup.h" #include "miscfuncs.h" #include "path.h" +#include #include #include "sigproc.h" #include "fhandler.h" @@ -2606,6 +2607,24 @@ pthread_timedjoin_np (pthread_t thread, void **return_val, return pthread::join (&thread, (void **) return_val, &timeout); } +extern "C" int +pthread_getaffinity_np (pthread_t thread, size_t sizeof_set, cpu_set_t *set) +{ + if (!pthread::is_good_object (&thread)) + return ESRCH; + + return sched_get_thread_affinity (thread->win32_obj_id, sizeof_set, set); +} + +extern "C" int +pthread_setaffinity_np (pthread_t thread, size_t sizeof_set, const cpu_set_t *set) +{ + if (!pthread::is_good_object (&thread)) + return ESRCH; + + return sched_set_thread_affinity (thread->win32_obj_id, sizeof_set, set); +} + extern "C" int pthread_getattr_np (pthread_t thread, pthread_attr_t *attr) { diff --git a/winsup/doc/new-features.xml b/winsup/doc/new-features.xml index 49aa5da74..43ca11fef 100644 --- a/winsup/doc/new-features.xml +++ b/winsup/doc/new-features.xml @@ -29,6 +29,12 @@ If a SA_SIGINFO signal handler changes the ucontext_t pointed to by the third parameter, follow it after returning from the handler. + +Support for getting and setting process and thread affinities. New APIs: +sched_getaffinity, sched_setaffinity, pthread_getaffinity_np, +pthread_setaffinity_np. + + diff --git a/winsup/doc/posix.xml b/winsup/doc/posix.xml index d49cf5591..8e88245ac 100644 --- a/winsup/doc/posix.xml +++ b/winsup/doc/posix.xml @@ -1359,8 +1359,10 @@ also IEEE Std 1003.1-2008 (POSIX.1-2008). pow10f pow10l ppoll + pthread_getaffinity_np pthread_getattr_np pthread_getname_np + pthread_setaffinity_np pthread_setname_np pthread_sigqueue pthread_timedjoin_np @@ -1374,7 +1376,9 @@ also IEEE Std 1003.1-2008 (POSIX.1-2008). rawmemchr removexattr scandirat + sched_getaffinity sched_getcpu + sched_setaffinity secure_getenv setxattr signalfd From 301facfb60db2adb8306009ac27f3b9afd08bb5e Mon Sep 17 00:00:00 2001 From: Jozef Lawrynowicz Date: Tue, 25 Jun 2019 11:45:02 +0100 Subject: [PATCH 417/475] Support calculation of pointer size for __int20__ type in _intsup.h GCC r272640 modifies the MSP430 target to use "__int20__" for PTRDIFF_TYPE (and therefore INTPTR_TYPE) instead of "__int20". To support the calculation of pointer size in newlib/libc/include/sys/_intsup.h, definitions for __int20__ need to be added. --- newlib/libc/include/sys/_intsup.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/newlib/libc/include/sys/_intsup.h b/newlib/libc/include/sys/_intsup.h index 88d7400d8..993121ba8 100644 --- a/newlib/libc/include/sys/_intsup.h +++ b/newlib/libc/include/sys/_intsup.h @@ -37,6 +37,7 @@ #pragma push_macro("char") #pragma push_macro("short") #pragma push_macro("__int20") +#pragma push_macro("__int20__") #pragma push_macro("int") #pragma push_macro("long") #undef signed @@ -45,12 +46,14 @@ #undef short #undef int #undef __int20 +#undef __int20__ #undef long #define signed +0 #define unsigned +0 #define char +0 #define short +1 #define __int20 +2 +#define __int20__ +2 #define int +2 #define long +4 #if (__INTPTR_TYPE__ == 8 || __INTPTR_TYPE__ == 10) @@ -189,6 +192,7 @@ #pragma pop_macro("char") #pragma pop_macro("short") #pragma pop_macro("__int20") +#pragma pop_macro("__int20__") #pragma pop_macro("int") #pragma pop_macro("long") From a90aa583fbe7898a7a2699ee380de7783b6e8ed4 Mon Sep 17 00:00:00 2001 From: Alexander Fedotov Date: Mon, 24 Jun 2019 17:40:17 +0300 Subject: [PATCH 418/475] Arm: Use lrdimon-v2m_nano when semihosting v2 and nano selected respectively --- libgloss/arm/elf-rdimon-v2m.specs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libgloss/arm/elf-rdimon-v2m.specs b/libgloss/arm/elf-rdimon-v2m.specs index e4f2545a4..c87e3fced 100644 --- a/libgloss/arm/elf-rdimon-v2m.specs +++ b/libgloss/arm/elf-rdimon-v2m.specs @@ -12,7 +12,7 @@ %{!specs=nano.specs:-lc} %{specs=nano.specs:-lc_nano} *rdimon_libgloss: -%{!specs=nano.specs:-lrdimon-v2m} %{specs=nano.specs:-lrdimon_nano} +%{!specs=nano.specs:-lrdimon-v2m} %{specs=nano.specs:-lrdimon-v2m_nano} *link_gcc_c_sequence: %(rdimon_link_gcc_c_sequence) --start-group %G %(rdimon_libc) %(rdimon_libgloss) --end-group From 9604a251bdeb3ae4a4c958efc14b4694d7324d11 Mon Sep 17 00:00:00 2001 From: Ken Brown Date: Mon, 24 Jun 2019 12:28:48 -0400 Subject: [PATCH 419/475] Cygwin: timerfd: avoid a deadlock Add a function timerfd_tracker::enter_critical_section_cancelable, which is like enter_critical_section but honors a cancel event. Call this when a timer expires while the timerfd thread is in its inner loop. This avoids a deadlock if timerfd_tracker::dtor has entered its critical section and is trying to cancel the thread. See https://cygwin.com/ml/cygwin/2019-06/msg00096.html. --- winsup/cygwin/release/3.1.0 | 3 +++ winsup/cygwin/timerfd.cc | 24 +++++++++++++++++++++++- winsup/cygwin/timerfd.h | 2 ++ 3 files changed, 28 insertions(+), 1 deletion(-) diff --git a/winsup/cygwin/release/3.1.0 b/winsup/cygwin/release/3.1.0 index a2bdc8f3c..e8144d4d0 100644 --- a/winsup/cygwin/release/3.1.0 +++ b/winsup/cygwin/release/3.1.0 @@ -34,3 +34,6 @@ Bug Fixes - Define missing MSG_EOR. It's unsupported by the underlying Winsock layer so using it in send(2), sendto(2), or sendmsg(2) will return -1 with errno set to EOPNOTSUPP and recvmsg(2) will never return it. + +- Fix a race condition in the timerfd code. + Addresses: https://cygwin.com/ml/cygwin/2019-06/msg00096.html diff --git a/winsup/cygwin/timerfd.cc b/winsup/cygwin/timerfd.cc index 8e4c94e66..f1a4c2804 100644 --- a/winsup/cygwin/timerfd.cc +++ b/winsup/cygwin/timerfd.cc @@ -89,6 +89,25 @@ timerfd_tracker::handle_timechange_window () } } +/* Like enter_critical_section, but returns -1 on a cancel event. */ +int +timerfd_tracker::enter_critical_section_cancelable () +{ + HANDLE w[2] = { cancel_evt, _access_mtx }; + DWORD waitret = WaitForMultipleObjects (2, w, FALSE, INFINITE); + + switch (waitret) + { + case WAIT_OBJECT_0: + return -1; + case WAIT_OBJECT_0 + 1: + case WAIT_ABANDONED_0 + 1: + return 1; + default: + return 0; + } +} + DWORD timerfd_tracker::thread_func () { @@ -137,7 +156,10 @@ timerfd_tracker::thread_func () continue; } - if (!enter_critical_section ()) + int ec = enter_critical_section_cancelable (); + if (ec < 0) + goto canceled; + else if (!ec) continue; /* Make sure we haven't been abandoned and/or disarmed in the meantime */ diff --git a/winsup/cygwin/timerfd.h b/winsup/cygwin/timerfd.h index 154be0847..80688e79e 100644 --- a/winsup/cygwin/timerfd.h +++ b/winsup/cygwin/timerfd.h @@ -86,6 +86,8 @@ class timerfd_tracker /* cygheap! */ return (WaitForSingleObject (_access_mtx, INFINITE) & ~WAIT_ABANDONED_0) == WAIT_OBJECT_0; } + /* A version that honors a cancel event, for use in thread_func. */ + int enter_critical_section_cancelable (); void leave_critical_section () { ReleaseMutex (_access_mtx); From 3dcc10ec902370d8290ef793275de1e7f3679bf3 Mon Sep 17 00:00:00 2001 From: Ken Brown Date: Tue, 25 Jun 2019 16:38:39 -0400 Subject: [PATCH 420/475] Tweak release message --- winsup/cygwin/release/3.1.0 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/winsup/cygwin/release/3.1.0 b/winsup/cygwin/release/3.1.0 index e8144d4d0..c8fe5556e 100644 --- a/winsup/cygwin/release/3.1.0 +++ b/winsup/cygwin/release/3.1.0 @@ -35,5 +35,5 @@ Bug Fixes layer so using it in send(2), sendto(2), or sendmsg(2) will return -1 with errno set to EOPNOTSUPP and recvmsg(2) will never return it. -- Fix a race condition in the timerfd code. +- Fix a timerfd deadlock. Addresses: https://cygwin.com/ml/cygwin/2019-06/msg00096.html From 09e2ec87efa5ba167dffd19d39ce7a59b7ef7877 Mon Sep 17 00:00:00 2001 From: Ken Brown Date: Tue, 25 Jun 2019 17:14:50 -0400 Subject: [PATCH 421/475] Cygwin: FIFO: fix a thinko in raw_write Remove a line that has no effect. --- winsup/cygwin/fhandler_fifo.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/winsup/cygwin/fhandler_fifo.cc b/winsup/cygwin/fhandler_fifo.cc index edc6caeb3..737264b85 100644 --- a/winsup/cygwin/fhandler_fifo.cc +++ b/winsup/cygwin/fhandler_fifo.cc @@ -717,7 +717,6 @@ fhandler_fifo::raw_write (const void *ptr, size_t len) set_errno (EBADF); else __seterrno (); - len = (size_t) -1; } else if (NT_SUCCESS (status)) { From 8b080534cadd8b9e920c8b023e341937a2e274bc Mon Sep 17 00:00:00 2001 From: Martin Erik Werner Date: Wed, 26 Jun 2019 17:44:54 +0200 Subject: [PATCH 422/475] or1k: Correct longjmp return value Invert equality check instruction to correct the return value handling in longjmp. The return value should be the value of the second argument to longjmp, unless the argument value was 0 in which case it should be 1. Previously, longjmp would set return value 1 if the second argument was non-zero, and 0 if it was 0, which was incorrect. --- newlib/libc/machine/or1k/setjmp.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/newlib/libc/machine/or1k/setjmp.S b/newlib/libc/machine/or1k/setjmp.S index 5c023278d..0b93a0342 100644 --- a/newlib/libc/machine/or1k/setjmp.S +++ b/newlib/libc/machine/or1k/setjmp.S @@ -70,7 +70,7 @@ longjmp: /* If the second argument to longjmp is zero, set return address to 1, otherwise set it to the value of the second argument */ l.addi r11, r0, 1 - l.sfne r4, r0 + l.sfeq r4, r0 l.bf 1f l.nop l.addi r11, r4, 0 From 40b947e7d53f44d82fb0a0971d543715ecd37070 Mon Sep 17 00:00:00 2001 From: Mark Geisert Date: Wed, 26 Jun 2019 22:31:56 -0700 Subject: [PATCH 423/475] Cygwin: Use correct string conversion Correct the string conversion calls so both argv elements get converted at full precision. --- winsup/utils/cygwin-console-helper.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/winsup/utils/cygwin-console-helper.cc b/winsup/utils/cygwin-console-helper.cc index 8f62ed7e6..0e04f4d18 100644 --- a/winsup/utils/cygwin-console-helper.cc +++ b/winsup/utils/cygwin-console-helper.cc @@ -5,9 +5,9 @@ main (int argc, char **argv) char *end; if (argc != 3) exit (1); - HANDLE h = (HANDLE) strtoul (argv[1], &end, 0); + HANDLE h = (HANDLE) strtoull (argv[1], &end, 0); SetEvent (h); - h = (HANDLE) strtoul (argv[2], &end, 0); + h = (HANDLE) strtoull (argv[2], &end, 0); WaitForSingleObject (h, INFINITE); exit (0); } From f96f7bec6bea49b7c44b16bf70dc66f7ecb2787f Mon Sep 17 00:00:00 2001 From: Mark Geisert Date: Tue, 25 Jun 2019 00:54:41 -0700 Subject: [PATCH 424/475] Cygwin: Build cygwin-console-helper with correct compiler --- winsup/utils/Makefile.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/winsup/utils/Makefile.in b/winsup/utils/Makefile.in index b64f457e7..cebf39572 100644 --- a/winsup/utils/Makefile.in +++ b/winsup/utils/Makefile.in @@ -64,7 +64,7 @@ MINGW_BINS := ${addsuffix .exe,cygcheck cygwin-console-helper ldh strace} # List all objects to be compiled in MinGW mode. Any object not on this # list will will be compiled in Cygwin mode implicitly, so there is no # need for a CYGWIN_OBJS. -MINGW_OBJS := bloda.o cygcheck.o dump_setup.o ldh.o path.o strace.o +MINGW_OBJS := bloda.o cygcheck.o cygwin-console-helper.o dump_setup.o ldh.o path.o strace.o MINGW_LDFLAGS:=-static CYGCHECK_OBJS:=cygcheck.o bloda.o path.o dump_setup.o From 739e89cbe6d0f416d9799e1c296d2d15d7fac4e5 Mon Sep 17 00:00:00 2001 From: Martin Erik Werner Date: Thu, 27 Jun 2019 10:03:48 +0200 Subject: [PATCH 425/475] or1k: Avoid write outside setjmp buf & shrink buf Update the offsets used to save registers into the stejmp jmp_buf structure in order to: * Avoid writing the supervision register outside the buffer and thus clobbering something on the stack. Previously the supervision register was written at offset 124 while the buffer was of length 124. * Shrink the jmp_buf down to the size actually needed, by avoiding holes at the locations of omitted registers. --- newlib/libc/include/machine/setjmp.h | 5 ++- newlib/libc/machine/or1k/setjmp.S | 56 ++++++++++++++-------------- 2 files changed, 32 insertions(+), 29 deletions(-) diff --git a/newlib/libc/include/machine/setjmp.h b/newlib/libc/include/machine/setjmp.h index 9212f840b..6b37bcce4 100644 --- a/newlib/libc/include/machine/setjmp.h +++ b/newlib/libc/include/machine/setjmp.h @@ -2,7 +2,10 @@ _BEGIN_STD_C #if defined(__or1k__) || defined(__or1knd__) -#define _JBLEN 31 /* 32 GPRs - r0 */ +/* + * r1, r2, r9, r14, r16 .. r30, SR. + */ +#define _JBLEN 13 #define _JBTYPE unsigned long #endif diff --git a/newlib/libc/machine/or1k/setjmp.S b/newlib/libc/machine/or1k/setjmp.S index 0b93a0342..f0663f37c 100644 --- a/newlib/libc/machine/or1k/setjmp.S +++ b/newlib/libc/machine/or1k/setjmp.S @@ -29,25 +29,25 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .type setjmp,@function setjmp: - l.sw 4(r3), r1 - l.sw 8(r3), r2 + l.sw 0(r3), r1 + l.sw 4(r3), r2 /* Skip r3-r8 as they are not preserved across function calls */ - l.sw 36(r3), r9 + l.sw 8(r3), r9 /* Skip r10 as it's preserved to be used by TLS */ /* Skip r11, setjmp always set it to 0 */ /* The following set if registers are preserved across function calls */ - l.sw 52(r3), r14 - l.sw 60(r3), r16 - l.sw 68(r3), r18 - l.sw 76(r3), r20 - l.sw 84(r3), r22 - l.sw 92(r3), r24 - l.sw 100(r3), r26 - l.sw 108(r3), r28 - l.sw 116(r3), r30 + l.sw 12(r3), r14 + l.sw 16(r3), r16 + l.sw 20(r3), r18 + l.sw 24(r3), r20 + l.sw 28(r3), r22 + l.sw 32(r3), r24 + l.sw 36(r3), r26 + l.sw 40(r3), r28 + l.sw 44(r3), r30 /* Save Status Register */ l.mfspr r13, r0, 17 - l.sw 124(r3), r13 + l.sw 48(r3), r13 /* Set result register to 0 and jump */ // Different cases for optional delay slot #if defined(__OR1K_NODELAY__) @@ -77,32 +77,32 @@ longjmp: /* Load status register */ 1: - l.lwz r15, 124(r3) + l.lwz r15, 48(r3) l.mtspr r0, r15, 17 - l.lwz r1, 4(r3) - l.lwz r2, 8(r3) + l.lwz r1, 0(r3) + l.lwz r2, 4(r3) /* Skip r3-r8 as they are not preserved across function calls */ - l.lwz r9, 36(r3) + l.lwz r9, 8(r3) /* Skip r11 as it's always set by longjmp */ - l.lwz r14, 52(r3) - l.lwz r16, 60(r3) - l.lwz r18, 68(r3) - l.lwz r20, 76(r3) - l.lwz r22, 84(r3) - l.lwz r24, 92(r3) - l.lwz r26, 100(r3) - l.lwz r28, 108(r3) + l.lwz r14, 12(r3) + l.lwz r16, 16(r3) + l.lwz r18, 20(r3) + l.lwz r20, 24(r3) + l.lwz r22, 28(r3) + l.lwz r24, 32(r3) + l.lwz r26, 36(r3) + l.lwz r28, 40(r3) // Different cases for optional delay slot #if defined(__OR1K_NODELAY__) - l.lwz r30, 116(r3) + l.lwz r30, 44(r3) l.jr r9 #elif defined(__OR1K_DELAY__) l.jr r9 - l.lwz r30, 116(r3) + l.lwz r30, 44(r3) #else - l.lwz r30, 116(r3) + l.lwz r30, 44(r3) l.jr r9 l.nop #endif From aa55d22cb55d67d7f77ee9d58f9016c42c3ee495 Mon Sep 17 00:00:00 2001 From: Ken Brown Date: Thu, 27 Jun 2019 07:46:14 -0400 Subject: [PATCH 426/475] Cygwin: honor the O_PATH flag when opening a FIFO Previously fhandler_fifo::open would treat the FIFO as a reader and would block, waiting for a writer. --- winsup/cygwin/fhandler_fifo.cc | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/winsup/cygwin/fhandler_fifo.cc b/winsup/cygwin/fhandler_fifo.cc index 737264b85..92797ce60 100644 --- a/winsup/cygwin/fhandler_fifo.cc +++ b/winsup/cygwin/fhandler_fifo.cc @@ -451,11 +451,18 @@ fhandler_fifo::open (int flags, mode_t) error_set_errno } res; + if (flags & O_PATH) + { + query_open (query_read_attributes); + nohandle (true); + } + /* Determine what we're doing with this fhandler: reading, writing, both */ switch (flags & O_ACCMODE) { case O_RDONLY: - reader = true; + if (!query_open ()) + reader = true; break; case O_WRONLY: writer = true; @@ -577,6 +584,8 @@ fhandler_fifo::open (int flags, mode_t) } } } + if (query_open ()) + res = success; out: if (res == error_set_errno) __seterrno (); From 383e19ca552234fa9af47e80cb00d843a96de9e3 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Wed, 26 Jun 2019 15:08:57 +0200 Subject: [PATCH 427/475] sched: Move Cygwin cpuset definitions into Cygwin-specific header This avoids build breakage on RTEMS. Signed-off-by: Corinna Vinschen --- newlib/libc/include/sched.h | 18 ---------------- winsup/cygwin/include/sys/_pthreadtypes.h | 5 +++-- winsup/cygwin/include/sys/cpuset.h | 25 +++++++++++++++++++++++ 3 files changed, 28 insertions(+), 20 deletions(-) create mode 100644 winsup/cygwin/include/sys/cpuset.h diff --git a/newlib/libc/include/sched.h b/newlib/libc/include/sched.h index fc44209d6..79b775e22 100644 --- a/newlib/libc/include/sched.h +++ b/newlib/libc/include/sched.h @@ -93,24 +93,6 @@ int sched_yield( void ); #if __GNU_VISIBLE int sched_getcpu(void); -/* Affinity-related definitions, here until numerous enough to separate out */ -#ifdef __x86_64__ -typedef uint64_t __cpu_mask; -#else -typedef uint32_t __cpu_mask; -#endif -#define __CPU_SETSIZE 1024 // maximum number of logical processors tracked -#define __NCPUBITS (8 * sizeof (__cpu_mask)) // max size of processor group -#define __CPU_GROUPMAX (__CPU_SETSIZE / __NCPUBITS) // maximum group number - -#define __CPUELT(cpu) ((cpu) / __NCPUBITS) -#define __CPUMASK(cpu) ((__cpu_mask) 1 << ((cpu) % __NCPUBITS)) - -typedef struct -{ - __cpu_mask __bits[__CPU_GROUPMAX]; -} cpu_set_t; - int sched_getaffinity (pid_t, size_t, cpu_set_t *); int sched_get_thread_affinity (void *, size_t, cpu_set_t *); int sched_setaffinity (pid_t, size_t, const cpu_set_t *); diff --git a/winsup/cygwin/include/sys/_pthreadtypes.h b/winsup/cygwin/include/sys/_pthreadtypes.h index 3063e8334..e951fee63 100644 --- a/winsup/cygwin/include/sys/_pthreadtypes.h +++ b/winsup/cygwin/include/sys/_pthreadtypes.h @@ -1,5 +1,4 @@ -/* machine/types.h - Written by Robert Collins +/* sys/_pthreadtypes.h This file is part of Cygwin. @@ -10,6 +9,8 @@ details. */ #ifndef _SYS__PTHREADTYPES_H_ #define _SYS__PTHREADTYPES_H_ +#include + #if !defined(__INSIDE_CYGWIN__) || !defined(__cplusplus) typedef struct __pthread_t {char __dummy;} *pthread_t; diff --git a/winsup/cygwin/include/sys/cpuset.h b/winsup/cygwin/include/sys/cpuset.h new file mode 100644 index 000000000..a83163d01 --- /dev/null +++ b/winsup/cygwin/include/sys/cpuset.h @@ -0,0 +1,25 @@ +/* sys/cpuset.h + +This file is part of Cygwin. + +This software is a copyrighted work licensed under the terms of the +Cygwin license. Please consult the file "CYGWIN_LICENSE" for +details. */ + +#ifndef _SYS_CPUSET_H_ +#define _SYS_CPUSET_H_ + +typedef __SIZE_TYPE__ __cpu_mask; +#define __CPU_SETSIZE 1024 // maximum number of logical processors tracked +#define __NCPUBITS (8 * sizeof (__cpu_mask)) // max size of processor group +#define __CPU_GROUPMAX (__CPU_SETSIZE / __NCPUBITS) // maximum group number + +#define __CPUELT(cpu) ((cpu) / __NCPUBITS) +#define __CPUMASK(cpu) ((__cpu_mask) 1 << ((cpu) % __NCPUBITS)) + +typedef struct +{ + __cpu_mask __bits[__CPU_GROUPMAX]; +} cpu_set_t; + +#endif /* _SYS_CPUSET_H_ */ From fff17ad73f6ae6b75ef293e17a837f23f6134753 Mon Sep 17 00:00:00 2001 From: Mark Geisert Date: Wed, 26 Jun 2019 02:44:56 -0700 Subject: [PATCH 428/475] Cygwin: Fix return value of sched_getaffinity Have sched_getaffinity() interface like glibc's, and provide an undocumented internal interface __sched_getaffinity_sys() like the Linux kernel's sched_getaffinity() for benefit of taskset(1). --- winsup/cygwin/common.din | 1 + winsup/cygwin/include/cygwin/version.h | 2 +- winsup/cygwin/include/sys/cpuset.h | 10 +++++++++ winsup/cygwin/sched.cc | 29 +++++++++++++++++--------- 4 files changed, 31 insertions(+), 11 deletions(-) diff --git a/winsup/cygwin/common.din b/winsup/cygwin/common.din index 81292ab7b..9cb67992b 100644 --- a/winsup/cygwin/common.din +++ b/winsup/cygwin/common.din @@ -98,6 +98,7 @@ __res_querydomain SIGFE __res_search SIGFE __res_send SIGFE __res_state SIGFE +__sched_getaffinity_sys SIGFE __signbitd NOSIGFE __signbitf NOSIGFE __signgam NOSIGFE diff --git a/winsup/cygwin/include/cygwin/version.h b/winsup/cygwin/include/cygwin/version.h index b70b9e281..f47055d84 100644 --- a/winsup/cygwin/include/cygwin/version.h +++ b/winsup/cygwin/include/cygwin/version.h @@ -510,7 +510,7 @@ details. */ 337: MOUNT_BINARY -> MOUNT_TEXT 338: Export secure_getenv. 339: Export sched_getaffinity, sched_setaffinity, pthread_getaffinity_np, - pthread_setaffinity_np. + pthread_setaffinity_np, __sched_getaffinity_sys. Note that we forgot to bump the api for ualarm, strtoll, strtoull, sigaltstack, sethostname. */ diff --git a/winsup/cygwin/include/sys/cpuset.h b/winsup/cygwin/include/sys/cpuset.h index a83163d01..4857b879d 100644 --- a/winsup/cygwin/include/sys/cpuset.h +++ b/winsup/cygwin/include/sys/cpuset.h @@ -9,6 +9,10 @@ details. */ #ifndef _SYS_CPUSET_H_ #define _SYS_CPUSET_H_ +#ifdef __cplusplus +extern "C" { +#endif + typedef __SIZE_TYPE__ __cpu_mask; #define __CPU_SETSIZE 1024 // maximum number of logical processors tracked #define __NCPUBITS (8 * sizeof (__cpu_mask)) // max size of processor group @@ -22,4 +26,10 @@ typedef struct __cpu_mask __bits[__CPU_GROUPMAX]; } cpu_set_t; +int __sched_getaffinity_sys (pid_t, size_t, cpu_set_t *); + +#ifdef __cplusplus +} +#endif + #endif /* _SYS_CPUSET_H_ */ diff --git a/winsup/cygwin/sched.cc b/winsup/cygwin/sched.cc index e7b44d319..fdb8ba738 100644 --- a/winsup/cygwin/sched.cc +++ b/winsup/cygwin/sched.cc @@ -555,8 +555,9 @@ done: } int -sched_getaffinity (pid_t pid, size_t sizeof_set, cpu_set_t *set) +__sched_getaffinity_sys (pid_t pid, size_t sizeof_set, cpu_set_t *set) { + /* Emulate Linux raw sched_getaffinity syscall for benefit of taskset(1) */ HANDLE process = 0; int status = 0; @@ -603,14 +604,21 @@ done: if (status) { set_errno (status); - status = -1; + return -1; } - else - { - /* Emulate documented Linux kernel behavior on successful return */ - status = wincap.cpu_count (); - } - return status; + + /* On successful return, we would ordinarily return 0, but instead we + emulate the behavior of the raw sched_getaffinity syscall on Linux. */ + return min (sizeof_set, sizeof (cpu_set_t)); +} + +int +sched_getaffinity (pid_t pid, size_t sizeof_set, cpu_set_t *set) +{ + /* Emulate the Linux glibc interface of sched_getaffinity() by calling + the raw syscall emulation and mapping positive results to 0. */ + int status = __sched_getaffinity_sys (pid, sizeof_set, set); + return status > 0 ? 0 : status; } int @@ -727,9 +735,10 @@ done: if (status) { set_errno (status); - status = -1; + return -1; } - return status; + + return 0; } } /* extern C */ From 0d24a86822a5ee73d6a6aa69e2a0118aa1e35204 Mon Sep 17 00:00:00 2001 From: Jeff Johnston Date: Tue, 9 Jul 2019 13:06:59 -0400 Subject: [PATCH 429/475] Set errno in expm1{,f} / log1p{,f} 2019-07-09 Joern Rennecke * libm/common/s_expm1.c ("math_config.h"): Include. (expm1): Use __math_oflow to set errno. * libm/common/s_log1p.c ("math_config.h"): Include. (log1p): Use __math_divzero and __math_invalid to set errno. * libm/common/sf_expm1.c ("math_config.h"): Include. (expm1f): Use __math_oflow to set errno. * libm/common/sf_log1p.c ("math_config.h"): Include. (log1pf): Use __math_divzero and __math_invalid to set errno. --- newlib/libm/common/s_expm1.c | 3 ++- newlib/libm/common/s_log1p.c | 7 +++++-- newlib/libm/common/sf_expm1.c | 3 ++- newlib/libm/common/sf_log1p.c | 7 +++++-- 4 files changed, 14 insertions(+), 6 deletions(-) diff --git a/newlib/libm/common/s_expm1.c b/newlib/libm/common/s_expm1.c index a4c391209..10b0c8efb 100644 --- a/newlib/libm/common/s_expm1.c +++ b/newlib/libm/common/s_expm1.c @@ -142,6 +142,7 @@ PORTABILITY */ #include "fdlibm.h" +#include "math_config.h" #ifndef _DOUBLE_IS_32BITS @@ -190,7 +191,7 @@ Q5 = -2.01099218183624371326e-07; /* BE8AFDB7 6E09C32D */ return x+x; /* NaN */ else return (xsb==0)? x:-1.0;/* exp(+-inf)={inf,-1} */ } - if(x > o_threshold) return huge*huge; /* overflow */ + if(x > o_threshold) return __math_oflow (0); /* overflow */ } if(xsb!=0) { /* x < -56*ln2, return -1.0 with inexact */ if(x+tiny<0.0) /* raise inexact */ diff --git a/newlib/libm/common/s_log1p.c b/newlib/libm/common/s_log1p.c index 359c257d8..c44461e8d 100644 --- a/newlib/libm/common/s_log1p.c +++ b/newlib/libm/common/s_log1p.c @@ -113,6 +113,7 @@ Interface Definition (Issue 2). */ #include "fdlibm.h" +#include "math_config.h" #ifndef _DOUBLE_IS_32BITS @@ -154,8 +155,10 @@ static double zero = 0.0; k = 1; if (hx < 0x3FDA827A) { /* x < 0.41422 */ if(ax>=0x3ff00000) { /* x <= -1.0 */ - if(x==-1.0) return -two54/zero; /* log1p(-1)=+inf */ - else return (x-x)/(x-x); /* log1p(x<-1)=NaN */ + if(x==-1.0) + return __math_divzero (1); /* log1p(-1)=-inf */ + else + return __math_invalid (x); /* log1p(x<-1)=NaN */ } if(ax<0x3e200000) { /* |x| < 2**-29 */ if(two54+x>zero /* raise inexact */ diff --git a/newlib/libm/common/sf_expm1.c b/newlib/libm/common/sf_expm1.c index 4ba3b815a..ed9865072 100644 --- a/newlib/libm/common/sf_expm1.c +++ b/newlib/libm/common/sf_expm1.c @@ -14,6 +14,7 @@ */ #include "fdlibm.h" +#include "math_config.h" #ifdef __v810__ #define const @@ -60,7 +61,7 @@ Q5 = -2.0109921195e-07; /* 0xb457edbb */ if(FLT_UWORD_IS_INFINITE(hx)) return (xsb==0)? x:-1.0;/* exp(+-inf)={inf,-1} */ if(xsb == 0 && hx > FLT_UWORD_LOG_MAX) /* if x>=o_threshold */ - return huge*huge; /* overflow */ + return __math_oflowf (0); /* overflow */ if(xsb!=0) { /* x < -27*ln2, return -1.0 with inexact */ if(x+tiny<(float)0.0) /* raise inexact */ return tiny-one; /* return -1 */ diff --git a/newlib/libm/common/sf_log1p.c b/newlib/libm/common/sf_log1p.c index e09170f3e..d86768082 100644 --- a/newlib/libm/common/sf_log1p.c +++ b/newlib/libm/common/sf_log1p.c @@ -14,6 +14,7 @@ */ #include "fdlibm.h" +#include "math_config.h" #ifdef __STDC__ static const float @@ -54,8 +55,10 @@ static float zero = 0.0; if (!FLT_UWORD_IS_FINITE(hx)) return x+x; if (hx < 0x3ed413d7) { /* x < 0.41422 */ if(ax>=0x3f800000) { /* x <= -1.0 */ - if(x==(float)-1.0) return -two25/zero; /* log1p(-1)=+inf */ - else return (x-x)/(x-x); /* log1p(x<-1)=NaN */ + if(x==(float)-1.0) + return __math_divzero (1); /* log1p(-1)=-inf */ + else + return __math_invalid (x); /* log1p(x<-1)=NaN */ } if(ax<0x31000000) { /* |x| < 2**-29 */ if(two25+x>zero /* raise inexact */ From 948d40e4829e9a6895e6b831ebcb688af849fb90 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Fri, 12 Jul 2019 16:32:45 +0200 Subject: [PATCH 430/475] Cygwin: return full sigset_t from sig_send So far sig_send's return type is int. The problem with this is that sig_send returns a sigset_t on __SIGPENDING, and sigset_t is defined as long type. So the function only returns the lower 32 bit of sigset_t, which is fine on 32 bit, but casts away the pending RT signals on 64 bit. Fix this by changing the return type of sig_send to sigset_t, so as not to narrow down the sigset when returning from handling __SIGPENDING. Make sure to cast correctly in all invocations of sig_send. Signed-off-by: Corinna Vinschen --- winsup/cygwin/fhandler_signalfd.cc | 2 +- winsup/cygwin/signal.cc | 4 ++-- winsup/cygwin/sigproc.cc | 8 ++++---- winsup/cygwin/sigproc.h | 6 +++--- winsup/cygwin/thread.cc | 4 ++-- 5 files changed, 12 insertions(+), 12 deletions(-) diff --git a/winsup/cygwin/fhandler_signalfd.cc b/winsup/cygwin/fhandler_signalfd.cc index 6c7da02e9..4d89a6c5b 100644 --- a/winsup/cygwin/fhandler_signalfd.cc +++ b/winsup/cygwin/fhandler_signalfd.cc @@ -151,7 +151,7 @@ fhandler_signalfd::write (const void *, size_t) int fhandler_signalfd::poll () { - sigset_t outset = (sigset_t) sig_send (myself, __SIGPENDING, &_my_tls); + sigset_t outset = sig_send (myself, __SIGPENDING, &_my_tls); if (outset == SIG_BAD_MASK) return -1; if ((outset & sigset) != 0) diff --git a/winsup/cygwin/signal.cc b/winsup/cygwin/signal.cc index 9c51ec129..920a533f3 100644 --- a/winsup/cygwin/signal.cc +++ b/winsup/cygwin/signal.cc @@ -264,7 +264,7 @@ _pinfo::kill (siginfo_t& si) if (si.si_signo == 0) res = 0; - else if ((res = sig_send (this, si))) + else if ((res = (int) sig_send (this, si))) { sigproc_printf ("%d = sig_send, %E ", res); res = -1; @@ -718,7 +718,7 @@ sigqueue (pid_t pid, int sig, const union sigval value) si.si_signo = sig; si.si_code = SI_QUEUE; si.si_value = value; - return sig_send (dest, si); + return (int) sig_send (dest, si); } extern "C" int diff --git a/winsup/cygwin/sigproc.cc b/winsup/cygwin/sigproc.cc index 3b6492bb4..cba1af785 100644 --- a/winsup/cygwin/sigproc.cc +++ b/winsup/cygwin/sigproc.cc @@ -422,7 +422,7 @@ _cygtls::remove_pending_sigs () extern "C" int sigpending (sigset_t *mask) { - sigset_t outset = (sigset_t) sig_send (myself, __SIGPENDING, &_my_tls); + sigset_t outset = sig_send (myself, __SIGPENDING, &_my_tls); if (outset == SIG_BAD_MASK) return -1; *mask = outset; @@ -503,7 +503,7 @@ exit_thread (DWORD res) ExitThread (res); } -int __reg3 +sigset_t __reg3 sig_send (_pinfo *p, int sig, _cygtls *tls) { siginfo_t si = {}; @@ -516,7 +516,7 @@ sig_send (_pinfo *p, int sig, _cygtls *tls) If pinfo *p == NULL, send to the current process. If sending to this process, wait for notification that a signal has completed before returning. */ -int __reg3 +sigset_t __reg3 sig_send (_pinfo *p, siginfo_t& si, _cygtls *tls) { int rc = 1; @@ -748,7 +748,7 @@ out: if (si.si_signo != __SIGPENDING) /* nothing */; else if (!rc) - rc = (int) pending; + rc = pending; else rc = SIG_BAD_MASK; sigproc_printf ("returning %p from sending signal %d", rc, si.si_signo); diff --git a/winsup/cygwin/sigproc.h b/winsup/cygwin/sigproc.h index 9beb31dcf..a6f1428ce 100644 --- a/winsup/cygwin/sigproc.h +++ b/winsup/cygwin/sigproc.h @@ -71,8 +71,8 @@ class _pinfo; void __stdcall proc_terminate (); void __stdcall sigproc_init (); bool __reg1 pid_exists (pid_t); -int __reg3 sig_send (_pinfo *, siginfo_t&, class _cygtls * = NULL); -int __reg3 sig_send (_pinfo *, int, class _cygtls * = NULL); +sigset_t __reg3 sig_send (_pinfo *, siginfo_t&, class _cygtls * = NULL); +sigset_t __reg3 sig_send (_pinfo *, int, class _cygtls * = NULL); void __stdcall signal_fixup_after_exec (); void __stdcall sigalloc (); @@ -109,7 +109,7 @@ class lock_signals public: lock_signals () { - worked = sig_send (NULL, __SIGHOLD) == 0; + worked = (bool) sig_send (NULL, __SIGHOLD) == 0; } operator int () const { diff --git a/winsup/cygwin/thread.cc b/winsup/cygwin/thread.cc index 43a6c88b3..e09507e07 100644 --- a/winsup/cygwin/thread.cc +++ b/winsup/cygwin/thread.cc @@ -3311,7 +3311,7 @@ pthread_kill (pthread_t thread, int sig) rval = ESRCH; else if (sig) { - rval = sig_send (NULL, si, thread->cygtls); + rval = (int) sig_send (NULL, si, thread->cygtls); if (rval == -1) rval = get_errno (); } @@ -3354,7 +3354,7 @@ pthread_sigqueue (pthread_t *thread, int sig, const union sigval value) si.si_value = value; si.si_pid = myself->pid; si.si_uid = myself->uid; - return sig_send (NULL, si, (*thread)->cygtls); + return (int) sig_send (NULL, si, (*thread)->cygtls); } /* ID */ From bae987be12b12b18a4e7952a25dba2101f5da1d6 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Fri, 12 Jul 2019 17:18:48 +0200 Subject: [PATCH 431/475] Cygwin: sigpending: don't report pending signals for other threads The sigpending mechanism failed to check if the pending signal was a process-wide signal, or a signal for the curent thread. Fix that by adding a matching conditional to wait_sig's __SIGPENDING code. Signed-off-by: Corinna Vinschen --- winsup/cygwin/release/3.1.0 | 3 +++ winsup/cygwin/sigproc.cc | 9 +++++++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/winsup/cygwin/release/3.1.0 b/winsup/cygwin/release/3.1.0 index c8fe5556e..3b73a1802 100644 --- a/winsup/cygwin/release/3.1.0 +++ b/winsup/cygwin/release/3.1.0 @@ -37,3 +37,6 @@ Bug Fixes - Fix a timerfd deadlock. Addresses: https://cygwin.com/ml/cygwin/2019-06/msg00096.html + +- Fix sigpending() incorrectly returning signals for unrelated threads. + Addresses: https://cygwin.com/ml/cygwin/2019-07/msg00051.html diff --git a/winsup/cygwin/sigproc.cc b/winsup/cygwin/sigproc.cc index cba1af785..900facd58 100644 --- a/winsup/cygwin/sigproc.cc +++ b/winsup/cygwin/sigproc.cc @@ -1335,8 +1335,13 @@ wait_sig (VOID *) *pack.mask = 0; tl_entry = cygheap->find_tls (pack.sigtls); while ((q = q->next)) - if (pack.sigtls->sigmask & (bit = SIGTOMASK (q->si.si_signo))) - *pack.mask |= bit; + { + /* Skip thread-specific signals for other threads. */ + if (q->sigtls && pack.sigtls != q->sigtls) + continue; + if (pack.sigtls->sigmask & (bit = SIGTOMASK (q->si.si_signo))) + *pack.mask |= bit; + } cygheap->unlock_tls (tl_entry); } break; From f0cf44dc7d98d751483a91869949d58f55531e6f Mon Sep 17 00:00:00 2001 From: Ken Brown Date: Mon, 15 Jul 2019 14:22:07 -0400 Subject: [PATCH 432/475] Cygwin: avoid GCC 8.3 errors with -Werror=class-memaccess --- winsup/cygwin/flock.cc | 2 +- winsup/cygwin/path.cc | 4 ++-- winsup/cygwin/path.h | 2 +- winsup/cygwin/pinfo.cc | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/winsup/cygwin/flock.cc b/winsup/cygwin/flock.cc index 860791d7b..74374d727 100644 --- a/winsup/cygwin/flock.cc +++ b/winsup/cygwin/flock.cc @@ -1736,7 +1736,7 @@ lf_split (lockf_t *lock1, lockf_t *lock2, lockf_t **split) splitlock = *split; assert (splitlock != NULL); *split = splitlock->lf_next; - memcpy (splitlock, lock1, sizeof *splitlock); + memcpy ((void *) splitlock, lock1, sizeof *splitlock); /* We have to unset the obj HANDLE here which has been copied by the above memcpy, so that the calling function recognizes the new object. See post-lf_split handling in lf_setlock and lf_clearlock. */ diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc index 158f1e5fb..8da858da1 100644 --- a/winsup/cygwin/path.cc +++ b/winsup/cygwin/path.cc @@ -1299,7 +1299,7 @@ path_conv::serialize (HANDLE h, unsigned int &n) const n = 0; return NULL; } - memcpy (&pcf->pc, this, sizeof *this); + memcpy ((void *) &pcf->pc, this, sizeof *this); pcf->hdl = h; pcf->name_len = nlen; pcf->posix_len = plen; @@ -1318,7 +1318,7 @@ path_conv::deserialize (void *bufp) char *p; HANDLE ret; - memcpy (this, &pcf->pc, sizeof *this); + memcpy ((void *) this, &pcf->pc, sizeof *this); wide_path = uni_path.Buffer = NULL; uni_path.MaximumLength = uni_path.Length = 0; path = posix_path = NULL; diff --git a/winsup/cygwin/path.h b/winsup/cygwin/path.h index 0c94c6152..69af5a01c 100644 --- a/winsup/cygwin/path.h +++ b/winsup/cygwin/path.h @@ -313,7 +313,7 @@ class path_conv path_conv& eq_worker (const path_conv& pc, const char *in_path) { free_strings (); - memcpy (this, &pc, sizeof pc); + memcpy ((void *) this, &pc, sizeof pc); /* The device info might contain pointers to allocated strings, in contrast to statically allocated strings. Calling device::dup() will duplicate the string if the source was allocated. */ diff --git a/winsup/cygwin/pinfo.cc b/winsup/cygwin/pinfo.cc index d002268ed..cdbd8bd7e 100644 --- a/winsup/cygwin/pinfo.cc +++ b/winsup/cygwin/pinfo.cc @@ -1418,12 +1418,12 @@ winpids::add (DWORD& nelem, bool winpid, DWORD pid) { npidlist += slop_pidlist; pidlist = (DWORD *) realloc (pidlist, size_pidlist (npidlist + 1)); - pinfolist = (pinfo *) realloc (pinfolist, size_pinfolist (npidlist + 1)); + pinfolist = (pinfo *) realloc ((void *) pinfolist, size_pinfolist (npidlist + 1)); } _onreturn onreturn; pinfo& p = pinfolist[nelem]; - memset (&p, 0, sizeof (p)); + memset ((void *) &p, 0, sizeof (p)); bool perform_copy; if (cygpid == myself->pid) From b66dddb56d14a4032969fe8bb92d64baa6e0362e Mon Sep 17 00:00:00 2001 From: Ken Brown Date: Mon, 15 Jul 2019 15:02:00 -0400 Subject: [PATCH 433/475] Cygwin: avoid GCC 8.3 errors with -Werror=stringop-truncation --- winsup/cygwin/environ.cc | 2 +- winsup/cygwin/include/sys/utmp.h | 6 +++--- winsup/cygwin/uname.cc | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/winsup/cygwin/environ.cc b/winsup/cygwin/environ.cc index a47ed72e7..124842734 100644 --- a/winsup/cygwin/environ.cc +++ b/winsup/cygwin/environ.cc @@ -644,7 +644,7 @@ _addenv (const char *name, const char *value, int overwrite) return -1; /* Oops. No more memory. */ /* Put name '=' value into current slot. */ - strncpy (envhere, name, namelen); + memcpy (envhere, name, namelen); envhere[namelen] = '='; strcpy (envhere + namelen + 1, value); } diff --git a/winsup/cygwin/include/sys/utmp.h b/winsup/cygwin/include/sys/utmp.h index d90517cdd..acf804ad0 100644 --- a/winsup/cygwin/include/sys/utmp.h +++ b/winsup/cygwin/include/sys/utmp.h @@ -24,11 +24,11 @@ struct utmp { short ut_type; pid_t ut_pid; - char ut_line[UT_LINESIZE]; + char ut_line[UT_LINESIZE] __attribute__ ((nonstring)); char ut_id[UT_IDLEN]; time_t ut_time; - char ut_user[UT_NAMESIZE]; - char ut_host[UT_HOSTSIZE]; + char ut_user[UT_NAMESIZE] __attribute__ ((nonstring)); + char ut_host[UT_HOSTSIZE] __attribute__ ((nonstring)); long ut_addr; }; diff --git a/winsup/cygwin/uname.cc b/winsup/cygwin/uname.cc index 306cdee4a..e323335b4 100644 --- a/winsup/cygwin/uname.cc +++ b/winsup/cygwin/uname.cc @@ -25,7 +25,7 @@ uname_x (struct utsname *name) { __try { - char buf[NI_MAXHOST + 1]; + char buf[NI_MAXHOST + 1] __attribute__ ((nonstring)); char *snp = strstr (cygwin_version.dll_build_date, "SNP"); memset (name, 0, sizeof (*name)); From d730fa7b9cac901f2a682affefbdf772a170786c Mon Sep 17 00:00:00 2001 From: Ken Brown Date: Mon, 15 Jul 2019 16:50:54 -0400 Subject: [PATCH 434/475] Cygwin: suppress GCC 8.3 errors with -Warray-bounds --- winsup/utils/dumper.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/winsup/utils/dumper.cc b/winsup/utils/dumper.cc index 14b993316..f71bdda8b 100644 --- a/winsup/utils/dumper.cc +++ b/winsup/utils/dumper.cc @@ -417,6 +417,7 @@ dumper::dump_thread (asection * to, process_thread * thread) bfd_putl32 (NT_WIN32PSTATUS, header.elf_note_header.type); #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wstringop-overflow" +#pragma GCC diagnostic ignored "-Warray-bounds" strncpy (header.elf_note_header.name, "win32thread", NOTE_NAME_SIZE); #pragma GCC diagnostic pop @@ -483,6 +484,7 @@ dumper::dump_module (asection * to, process_module * module) bfd_putl32 (NT_WIN32PSTATUS, header.elf_note_header.type); #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wstringop-overflow" +#pragma GCC diagnostic ignored "-Warray-bounds" strncpy (header.elf_note_header.name, "win32module", NOTE_NAME_SIZE); #pragma GCC diagnostic pop From 81421eda7d408fe856319214332120fdbc8879c0 Mon Sep 17 00:00:00 2001 From: Ken Brown Date: Mon, 15 Jul 2019 15:59:41 -0400 Subject: [PATCH 435/475] Cygwin: fix GCC 8.3 'asm volatile' errors Remove the volatile qualifier, which is no longer allowed outside of the function body. See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89585 for discussion. --- winsup/cygwin/miscfuncs.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/winsup/cygwin/miscfuncs.cc b/winsup/cygwin/miscfuncs.cc index e02bc9c1f..0bbf4975d 100644 --- a/winsup/cygwin/miscfuncs.cc +++ b/winsup/cygwin/miscfuncs.cc @@ -724,7 +724,7 @@ err: See FreeBSD src/lib/libc/amd64/string/memset.S and FreeBSD src/lib/libc/amd64/string/bcopy.S */ -asm volatile (" \n\ +asm (" \n\ /* \n\ * Written by J.T. Conklin . \n\ * Public domain. \n\ @@ -791,7 +791,7 @@ L1: rep \n\ .seh_endproc \n\ "); -asm volatile (" \n\ +asm (" \n\ /*- \n\ * Copyright (c) 1990 The Regents of the University of California. \n\ * All rights reserved. \n\ From 3a956a9bc3275f9052c5d97d4955f10341b1277c Mon Sep 17 00:00:00 2001 From: Ken Brown Date: Mon, 15 Jul 2019 17:11:02 -0400 Subject: [PATCH 436/475] Cygwin: fix GCC 8.3 'local external declaration' errors Move external declarations out of function definition. --- winsup/cygserver/bsd_mutex.cc | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/winsup/cygserver/bsd_mutex.cc b/winsup/cygserver/bsd_mutex.cc index 52531bc72..13c5f90e8 100644 --- a/winsup/cygserver/bsd_mutex.cc +++ b/winsup/cygserver/bsd_mutex.cc @@ -275,13 +275,12 @@ public: }; static msleep_sync_array *msleep_sync; +extern struct msginfo msginfo; +extern struct seminfo seminfo; void msleep_init (void) { - extern struct msginfo msginfo; - extern struct seminfo seminfo; - msleep_glob_evt = CreateEvent (NULL, TRUE, FALSE, NULL); if (!msleep_glob_evt) panic ("CreateEvent in msleep_init failed: %u", GetLastError ()); From 6b7723a83032bd355d3c529d957fe209cb35b4d9 Mon Sep 17 00:00:00 2001 From: Ken Brown Date: Fri, 19 Jul 2019 14:14:33 -0400 Subject: [PATCH 437/475] Cygwin: unbreak the build with GCC 7 The recent port to GCC 8 used the 'nonstring' attribute, which is unknown to GCC 7. Define and use an 'ATTRIBUTE_NONSTRING' macro instead. --- winsup/cygwin/include/sys/utmp.h | 11 ++++++++--- winsup/cygwin/uname.cc | 8 +++++++- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/winsup/cygwin/include/sys/utmp.h b/winsup/cygwin/include/sys/utmp.h index acf804ad0..443c44252 100644 --- a/winsup/cygwin/include/sys/utmp.h +++ b/winsup/cygwin/include/sys/utmp.h @@ -19,16 +19,21 @@ extern "C" { #define ut_name ut_user #endif +#if __GNUC__ >= 8 +#define ATTRIBUTE_NONSTRING __attribute__ ((nonstring)) +#else +#define ATTRIBUTE_NONSTRING +#endif struct utmp { short ut_type; pid_t ut_pid; - char ut_line[UT_LINESIZE] __attribute__ ((nonstring)); + char ut_line[UT_LINESIZE] ATTRIBUTE_NONSTRING; char ut_id[UT_IDLEN]; time_t ut_time; - char ut_user[UT_NAMESIZE] __attribute__ ((nonstring)); - char ut_host[UT_HOSTSIZE] __attribute__ ((nonstring)); + char ut_user[UT_NAMESIZE] ATTRIBUTE_NONSTRING; + char ut_host[UT_HOSTSIZE] ATTRIBUTE_NONSTRING; long ut_addr; }; diff --git a/winsup/cygwin/uname.cc b/winsup/cygwin/uname.cc index e323335b4..350216681 100644 --- a/winsup/cygwin/uname.cc +++ b/winsup/cygwin/uname.cc @@ -17,6 +17,12 @@ details. */ extern "C" int cygwin_gethostname (char *__name, size_t __len); extern "C" int getdomainname (char *__name, size_t __len); +#if __GNUC__ >= 8 +#define ATTRIBUTE_NONSTRING __attribute__ ((nonstring)) +#else +#define ATTRIBUTE_NONSTRING +#endif + /* uname: POSIX 4.4.1.1 */ /* New entrypoint for applications since API 335 */ @@ -25,7 +31,7 @@ uname_x (struct utsname *name) { __try { - char buf[NI_MAXHOST + 1] __attribute__ ((nonstring)); + char buf[NI_MAXHOST + 1] ATTRIBUTE_NONSTRING; char *snp = strstr (cygwin_version.dll_build_date, "SNP"); memset (name, 0, sizeof (*name)); From 4beb9da11875b6597629330a344ac679f990ca24 Mon Sep 17 00:00:00 2001 From: Ken Brown Date: Fri, 19 Jul 2019 15:39:35 -0400 Subject: [PATCH 438/475] Cygwin: fhandler_*: remove isdevice() and is_auto_device() isdevice() is used only in the definition of is_auto_device(). And the latter is used only once, in a context where isdevice() always returns true. --- winsup/cygwin/fhandler.h | 3 --- winsup/cygwin/fhandler_raw.cc | 2 +- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h index 7e59d84d0..e28ec81e3 100644 --- a/winsup/cygwin/fhandler.h +++ b/winsup/cygwin/fhandler.h @@ -414,7 +414,6 @@ public: virtual bool is_tty () const { return false; } virtual bool ispipe () const { return false; } virtual pid_t get_popen_pid () const {return 0;} - virtual bool isdevice () const { return true; } virtual bool isfifo () const { return false; } virtual int ptsname_r (char *, size_t); virtual class fhandler_socket *is_socket () { return NULL; } @@ -459,7 +458,6 @@ public: virtual void seekdir (DIR *, long); virtual void rewinddir (DIR *); virtual int closedir (DIR *); - bool is_auto_device () {return isdevice () && !dev ().isfs ();} bool is_fs_special () {return pc.is_fs_special ();} bool issymlink () {return pc.issymlink ();} bool __reg2 device_access_denied (int); @@ -1527,7 +1525,6 @@ class fhandler_disk_file: public fhandler_base int dup (fhandler_base *child, int); void fixup_after_fork (HANDLE parent); int mand_lock (int, struct flock *); - bool isdevice () const { return false; } int __reg2 fstat (struct stat *buf); int __reg1 fchmod (mode_t mode); int __reg2 fchown (uid_t uid, gid_t gid); diff --git a/winsup/cygwin/fhandler_raw.cc b/winsup/cygwin/fhandler_raw.cc index bd47b6010..7c341d895 100644 --- a/winsup/cygwin/fhandler_raw.cc +++ b/winsup/cygwin/fhandler_raw.cc @@ -38,7 +38,7 @@ fhandler_dev_raw::fstat (struct stat *buf) debug_printf ("here"); fhandler_base::fstat (buf); - if (is_auto_device ()) + if (!dev ().isfs ()) { if (get_major () == DEV_TAPE_MAJOR) buf->st_mode = S_IFCHR | STD_RBITS | STD_WBITS | S_IWGRP | S_IWOTH; From fb5ce26cfda0733d63ad7cde79c9e7c922aca57c Mon Sep 17 00:00:00 2001 From: Ken Brown Date: Sat, 20 Jul 2019 16:21:43 -0400 Subject: [PATCH 439/475] Cygwin: remove path_conv::is_auto_device() It is used only once, and the name is supposed to suggest "device that is not based on the filesystem". This intended meaning is clearer if we just replace is_auto_device() by its definition at the place where it's used. --- winsup/cygwin/path.cc | 2 +- winsup/cygwin/path.h | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc index 8da858da1..c13701aa0 100644 --- a/winsup/cygwin/path.cc +++ b/winsup/cygwin/path.cc @@ -1921,7 +1921,7 @@ symlink_worker (const char *oldpath, const char *newpath, bool isdevice) win32_newpath.get_nt_native_path (), wsym_type); if ((!isdevice && win32_newpath.exists ()) - || win32_newpath.is_auto_device ()) + || (win32_newpath.isdevice () && !win32_newpath.is_fs_special ())) { set_errno (EEXIST); __leave; diff --git a/winsup/cygwin/path.h b/winsup/cygwin/path.h index 69af5a01c..0b4a003ad 100644 --- a/winsup/cygwin/path.h +++ b/winsup/cygwin/path.h @@ -183,7 +183,6 @@ class path_conv int isfifo () const {return dev.is_device (FH_FIFO);} int isspecial () const {return dev.not_device (FH_FS);} int iscygdrive () const {return dev.is_device (FH_CYGDRIVE);} - int is_auto_device () const {return isdevice () && !is_fs_special ();} int is_fs_device () const {return isdevice () && is_fs_special ();} int is_fs_special () const {return dev.is_fs_special ();} int is_lnk_special () const {return is_fs_device () || isfifo () || is_lnk_symlink ();} From af4d29e1067cf918d380404a16c76fb2b4b2bc9c Mon Sep 17 00:00:00 2001 From: Ken Brown Date: Sat, 20 Jul 2019 18:35:15 -0400 Subject: [PATCH 440/475] Cygwin: remove path_conv::is_fs_device() It is used only once. --- winsup/cygwin/path.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/winsup/cygwin/path.h b/winsup/cygwin/path.h index 0b4a003ad..95a9dec6f 100644 --- a/winsup/cygwin/path.h +++ b/winsup/cygwin/path.h @@ -183,9 +183,9 @@ class path_conv int isfifo () const {return dev.is_device (FH_FIFO);} int isspecial () const {return dev.not_device (FH_FS);} int iscygdrive () const {return dev.is_device (FH_CYGDRIVE);} - int is_fs_device () const {return isdevice () && is_fs_special ();} int is_fs_special () const {return dev.is_fs_special ();} - int is_lnk_special () const {return is_fs_device () || isfifo () || is_lnk_symlink ();} + int is_lnk_special () const {return (isdevice () && is_fs_special ()) + || isfifo () || is_lnk_symlink ();} #ifdef __WITH_AF_UNIX int issocket () const {return dev.is_device (FH_LOCAL) || dev.is_device (FH_UNIX);} From 73f819534da5e5e78d3266931a895c104436e6b6 Mon Sep 17 00:00:00 2001 From: Ken Brown Date: Sat, 20 Jul 2019 17:55:12 -0400 Subject: [PATCH 441/475] Cygwin: socket files are not lnk special files Change path_conv::is_lnk_special() so that it returns false on socket files. is_lnk_special() is called by rename2() in order to deal with special files (FIFOs and symlinks, for example) whose Win32 names usually have a ".lnk" suffix. Socket files do not fall into this category, and this change prevents ".lnk" from being appended erroneously when such files are renamed. Remove a now redundant !pc.issocket() from fhandler_disk_file::link(). --- winsup/cygwin/fhandler_disk_file.cc | 4 ++-- winsup/cygwin/path.h | 4 +++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/winsup/cygwin/fhandler_disk_file.cc b/winsup/cygwin/fhandler_disk_file.cc index 84d86456b..32381a0b0 100644 --- a/winsup/cygwin/fhandler_disk_file.cc +++ b/winsup/cygwin/fhandler_disk_file.cc @@ -1190,10 +1190,10 @@ fhandler_disk_file::link (const char *newpath) char new_buf[nlen + 5]; if (!newpc.error) { - /* If the original file is a lnk special file (except for sockets), + /* If the original file is a lnk special file, and if the original file has a .lnk suffix, add one to the hardlink as well. */ - if (pc.is_lnk_special () && !pc.issocket () + if (pc.is_lnk_special () && RtlEqualUnicodePathSuffix (pc.get_nt_native_path (), &ro_u_lnk, TRUE)) { diff --git a/winsup/cygwin/path.h b/winsup/cygwin/path.h index 95a9dec6f..e76157bd4 100644 --- a/winsup/cygwin/path.h +++ b/winsup/cygwin/path.h @@ -184,7 +184,9 @@ class path_conv int isspecial () const {return dev.not_device (FH_FS);} int iscygdrive () const {return dev.is_device (FH_CYGDRIVE);} int is_fs_special () const {return dev.is_fs_special ();} - int is_lnk_special () const {return (isdevice () && is_fs_special ()) + + int is_lnk_special () const {return (isdevice () && is_fs_special () + && !issocket ()) || isfifo () || is_lnk_symlink ();} #ifdef __WITH_AF_UNIX int issocket () const {return dev.is_device (FH_LOCAL) From 86817773c575a10d4761977ef12850527b5e04b6 Mon Sep 17 00:00:00 2001 From: Ken Brown Date: Mon, 22 Jul 2019 08:18:16 -0400 Subject: [PATCH 442/475] Cygwin: add release notes for 3.0.8 --- winsup/cygwin/release/3.0.8 | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 winsup/cygwin/release/3.0.8 diff --git a/winsup/cygwin/release/3.0.8 b/winsup/cygwin/release/3.0.8 new file mode 100644 index 000000000..11d11db6f --- /dev/null +++ b/winsup/cygwin/release/3.0.8 @@ -0,0 +1,16 @@ +What's new: +----------- + + +What changed: +------------- + + +Bug Fixes +--------- + +- Fix a hang when opening a FIFO with O_PATH. + Addresses: https://cygwin.com/ml/cygwin-developers/2019-06/msg00001.html + +- Don't append ".lnk" when renaming a socket file. + Addresses: https://cygwin.com/ml/cygwin/2019-07/msg00139.html From e118a605e2911b04ff7e239dcbdb737ab4e96c4b Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Mon, 22 Jul 2019 18:36:38 +0200 Subject: [PATCH 443/475] Cygwin: fix /proc/PID/fd return value in error case commit 2607639992f6 "Improve error handling in /proc/[pid]/ virtual files." changed the return value of the /proc/PID formatting functions to return -1 instead of 0 in the error case to allow a filesize of 0. The patch neglected to change this behaviour for /proc/PID/fd content. This patch fixes that. Signed-off-by: Corinna Vinschen --- winsup/cygwin/fhandler_process.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/winsup/cygwin/fhandler_process.cc b/winsup/cygwin/fhandler_process.cc index 5ee129317..15c0a41e2 100644 --- a/winsup/cygwin/fhandler_process.cc +++ b/winsup/cygwin/fhandler_process.cc @@ -389,13 +389,13 @@ format_process_fd (void *data, char *&destbuf) if (fd < 0 || e == fdp || (*e != '/' && *e != '\0')) { set_errno (ENOENT); - return 0; + return -1; } destbuf = p ? p->fd (fd, fs) : NULL; if (!destbuf || !*destbuf) { set_errno (ENOENT); - return 0; + return -1; } if (*e == '\0') *((process_fd_t *) data)->fd_type = virt_fdsymlink; From dec444bee3667b00d0fbc1a16ddedd96eb9f89c8 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Mon, 22 Jul 2019 18:40:33 +0200 Subject: [PATCH 444/475] Cygwin: change virtual_ftype_t to not rely on negative values So far negative values were denoting files, positive values denoting directories. We should prefer a less error prone method. Redefine virtual_ftype_t to contain only positive values and replace checks for negativ or positive values with inline functions virt_ftype_isfile() and virt_ftype_isdir(). Drop outdcated comments referring to numerical virtual_ftype_t values. Signed-off-by: Corinna Vinschen --- winsup/cygwin/fhandler.h | 37 ++++++++++++++++++--------- winsup/cygwin/fhandler_netdrive.cc | 2 -- winsup/cygwin/fhandler_proc.cc | 2 -- winsup/cygwin/fhandler_process.cc | 2 +- winsup/cygwin/fhandler_procnet.cc | 4 --- winsup/cygwin/fhandler_procsys.cc | 2 -- winsup/cygwin/fhandler_procsysvipc.cc | 3 --- winsup/cygwin/fhandler_registry.cc | 13 +++------- winsup/cygwin/fhandler_virtual.cc | 2 +- 9 files changed, 31 insertions(+), 36 deletions(-) diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h index e28ec81e3..794948dba 100644 --- a/winsup/cygwin/fhandler.h +++ b/winsup/cygwin/fhandler.h @@ -126,20 +126,33 @@ enum del_lock_called_from { }; enum virtual_ftype_t { - virt_fdsymlink = -8, /* Fd symlink (e.g. /proc//fd/0) */ - virt_blk = -7, /* Block special */ - virt_chr = -6, /* Character special */ - virt_fsfile = -5, /* FS-based file via /proc/sys */ - virt_socket = -4, /* Socket */ - virt_pipe = -3, /* Pipe */ - virt_symlink = -2, /* Symlink */ - virt_file = -1, /* Regular file */ - virt_none = 0, /* Invalid, Error */ - virt_directory = 1, /* Directory */ - virt_rootdir = 2, /* Root directory of virtual FS */ - virt_fsdir = 3, /* FS-based directory via /proc/sys */ + virt_none = 0x0000, /* Invalid, Error */ + virt_file = 0x0001, /* Regular file */ + virt_symlink = 0x0002, /* Symlink */ + virt_pipe = 0x0003, /* Pipe */ + virt_socket = 0x0004, /* Socket */ + virt_chr = 0x0005, /* Character special */ + virt_blk = 0x0006, /* Block special */ + virt_fdsymlink = 0x0007, /* Fd symlink (e.g. /proc//fd/0) */ + virt_fsfile = 0x0008, /* FS-based file via /proc/sys */ + virt_dir_type = 0x1000, + virt_directory = 0x1001, /* Directory */ + virt_rootdir = 0x1002, /* Root directory of virtual FS */ + virt_fsdir = 0x1003, /* FS-based directory via /proc/sys */ }; +static inline bool +virt_ftype_isfile (virtual_ftype_t _f) +{ + return _f != virt_none && !(_f & virt_dir_type); +} + +static inline bool +virt_ftype_isdir (virtual_ftype_t _f) +{ + return _f & virt_dir_type; +} + class fhandler_base { friend class dtable; diff --git a/winsup/cygwin/fhandler_netdrive.cc b/winsup/cygwin/fhandler_netdrive.cc index 654360f22..129d9dd86 100644 --- a/winsup/cygwin/fhandler_netdrive.cc +++ b/winsup/cygwin/fhandler_netdrive.cc @@ -145,8 +145,6 @@ create_thread_and_wait (int what, PVOID in, PVOID out, DWORD outsize, return ndi.ret; } -/* Returns 0 if path doesn't exist, >0 if path is a directory, - -1 if path is a file, -2 if it's a symlink. */ virtual_ftype_t fhandler_netdrive::exists () { diff --git a/winsup/cygwin/fhandler_proc.cc b/winsup/cygwin/fhandler_proc.cc index c461bbc75..48476beb8 100644 --- a/winsup/cygwin/fhandler_proc.cc +++ b/winsup/cygwin/fhandler_proc.cc @@ -168,8 +168,6 @@ fhandler_proc::get_proc_fhandler (const char *path) return FH_PROC; } -/* Returns 0 if path doesn't exist, >0 if path is a directory, - -1 if path is a file, -2 if it's a symlink. */ virtual_ftype_t fhandler_proc::exists () { diff --git a/winsup/cygwin/fhandler_process.cc b/winsup/cygwin/fhandler_process.cc index 15c0a41e2..0dafc2f0f 100644 --- a/winsup/cygwin/fhandler_process.cc +++ b/winsup/cygwin/fhandler_process.cc @@ -169,7 +169,7 @@ fhandler_process::fstat (struct stat *buf) buf->st_uid = p->uid; buf->st_gid = p->gid; buf->st_mode |= S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH; - if (file_type == 1) + if (file_type == virt_directory) buf->st_nlink = 2; else buf->st_nlink = 3; diff --git a/winsup/cygwin/fhandler_procnet.cc b/winsup/cygwin/fhandler_procnet.cc index 452f33c57..2ea827c48 100644 --- a/winsup/cygwin/fhandler_procnet.cc +++ b/winsup/cygwin/fhandler_procnet.cc @@ -41,10 +41,6 @@ static const virt_tab_t procnet_tab[] = static const int PROCNET_LINK_COUNT = (sizeof (procnet_tab) / sizeof (virt_tab_t)) - 1; -/* Returns 0 if path doesn't exist, >0 if path is a directory, - * -1 if path is a file, -2 if path is a symlink, -3 if path is a pipe, - * -4 if path is a socket. - */ virtual_ftype_t fhandler_procnet::exists () { diff --git a/winsup/cygwin/fhandler_procsys.cc b/winsup/cygwin/fhandler_procsys.cc index e2aebd5b1..d2540d0a1 100644 --- a/winsup/cygwin/fhandler_procsys.cc +++ b/winsup/cygwin/fhandler_procsys.cc @@ -39,8 +39,6 @@ const size_t procsys_len = sizeof (procsys) - 1; RtlInitUnicodeString ((p), namebuf); \ } -/* Returns 0 if path doesn't exist, >0 if path is a directory, - -1 if path is a file, -2 if it's a symlink. */ virtual_ftype_t fhandler_procsys::exists (struct stat *buf) { diff --git a/winsup/cygwin/fhandler_procsysvipc.cc b/winsup/cygwin/fhandler_procsysvipc.cc index 440771aeb..6b4fd8889 100644 --- a/winsup/cygwin/fhandler_procsysvipc.cc +++ b/winsup/cygwin/fhandler_procsysvipc.cc @@ -52,9 +52,6 @@ static const virt_tab_t procsysvipc_tab[] = static const int PROCSYSVIPC_LINK_COUNT = (sizeof (procsysvipc_tab) / sizeof (virt_tab_t)) - 1; -/* Returns 0 if path doesn't exist, >0 if path is a directory, - * -1 if path is a file. - */ virtual_ftype_t fhandler_procsysvipc::exists () { diff --git a/winsup/cygwin/fhandler_registry.cc b/winsup/cygwin/fhandler_registry.cc index ecaed085c..f7db01b99 100644 --- a/winsup/cygwin/fhandler_registry.cc +++ b/winsup/cygwin/fhandler_registry.cc @@ -306,13 +306,8 @@ multi_wcstombs (char *dst, size_t len, const wchar_t *src, size_t nwc) return sum; } -/* Returns 0 if path doesn't exist, >0 if path is a directory, - * <0 if path is a file. - * - * We open the last key but one and then enum it's sub-keys and values to see if the - * final component is there. This gets round the problem of not having security access - * to the final key in the path. - */ +/* Returns 0 if path doesn't exist, otherwise a virtual_ftype_t value + specifying the exact file type. */ virtual_ftype_t fhandler_registry::exists () { @@ -502,7 +497,7 @@ fhandler_registry::fstat (struct stat *buf) const char *path = get_name () + proc_len + prefix_len + 2; hKey = open_key (path, STANDARD_RIGHTS_READ | KEY_QUERY_VALUE, wow64, - (file_type < virt_none) ? true : false); + virt_ftype_isfile (file_type) ? true : false); if (hKey == HKEY_PERFORMANCE_DATA) /* RegQueryInfoKey () always returns write time 0, @@ -519,7 +514,7 @@ fhandler_registry::fstat (struct stat *buf) to_timestruc_t ((PLARGE_INTEGER) &ftLastWriteTime, &buf->st_mtim); buf->st_ctim = buf->st_birthtim = buf->st_mtim; time_as_timestruc_t (&buf->st_atim); - if (file_type > virt_none) + if (virt_ftype_isdir (file_type)) buf->st_nlink = subkey_count + 2; else { diff --git a/winsup/cygwin/fhandler_virtual.cc b/winsup/cygwin/fhandler_virtual.cc index b6b95f967..6169f3c81 100644 --- a/winsup/cygwin/fhandler_virtual.cc +++ b/winsup/cygwin/fhandler_virtual.cc @@ -45,7 +45,7 @@ fhandler_virtual::opendir (int fd) DIR *res = NULL; size_t len; - if (exists () <= 0) + if (!virt_ftype_isdir (exists ())) set_errno (ENOTDIR); else if ((len = strlen (get_name ())) > PATH_MAX - 3) set_errno (ENAMETOOLONG); From ae59d0930803abf0b2228999d4cdff08679b62cd Mon Sep 17 00:00:00 2001 From: Ken Brown Date: Mon, 22 Jul 2019 14:00:53 -0400 Subject: [PATCH 445/475] Cygwin: fix one more check for positive virtual_ftype_t values Also drop more comments referring to numerical virtual_ftype_t values. --- winsup/cygwin/fhandler_process.cc | 3 --- winsup/cygwin/fhandler_registry.cc | 4 +--- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/winsup/cygwin/fhandler_process.cc b/winsup/cygwin/fhandler_process.cc index 0dafc2f0f..2a0655475 100644 --- a/winsup/cygwin/fhandler_process.cc +++ b/winsup/cygwin/fhandler_process.cc @@ -86,9 +86,6 @@ static bool get_mem_values (DWORD dwProcessId, size_t &vmsize, size_t &vmrss, size_t &vmtext, size_t &vmdata, size_t &vmlib, size_t &vmshare); -/* Returns 0 if path doesn't exist, >0 if path is a directory, - -1 if path is a file, -2 if path is a symlink, -3 if path is a pipe, - -4 if path is a socket. */ virtual_ftype_t fhandler_process::exists () { diff --git a/winsup/cygwin/fhandler_registry.cc b/winsup/cygwin/fhandler_registry.cc index f7db01b99..5fc03fedd 100644 --- a/winsup/cygwin/fhandler_registry.cc +++ b/winsup/cygwin/fhandler_registry.cc @@ -306,8 +306,6 @@ multi_wcstombs (char *dst, size_t len, const wchar_t *src, size_t nwc) return sum; } -/* Returns 0 if path doesn't exist, otherwise a virtual_ftype_t value - specifying the exact file type. */ virtual_ftype_t fhandler_registry::exists () { @@ -562,7 +560,7 @@ fhandler_registry::fstat (struct stat *buf) buf->st_uid = uid; buf->st_gid = gid; buf->st_mode &= ~(S_IWUSR | S_IWGRP | S_IWOTH); - if (file_type > virt_none) + if (virt_ftype_isdir (file_type)) buf->st_mode |= S_IFDIR; else buf->st_mode &= NO_X; From 942f60d714e18cd775dc8b0a661cf70eef162bcc Mon Sep 17 00:00:00 2001 From: Alexander Fedotov Date: Mon, 22 Jul 2019 11:18:53 -0500 Subject: [PATCH 446/475] Stack Pointer and Stack Limit initialization refactored. SP initialization changes: 1. set default value in semihosting case as well 2. moved existing SP & SL init code for processor modes in separate routine and made it as "hook" 3. init SP for processor modes in Thumb mode as well Add new macro FN_RETURN, FN_EH_START and FN_EH_END. --- libgloss/arm/arm.h | 26 ++++ libgloss/arm/crt0.S | 290 +++++++++++++++++++++++++------------ newlib/libc/sys/arm/arm.h | 26 ++++ newlib/libc/sys/arm/crt0.S | 290 +++++++++++++++++++++++++------------ 4 files changed, 454 insertions(+), 178 deletions(-) diff --git a/libgloss/arm/arm.h b/libgloss/arm/arm.h index 0489f2d92..10e5b0509 100644 --- a/libgloss/arm/arm.h +++ b/libgloss/arm/arm.h @@ -61,4 +61,30 @@ # define HAVE_CALL_INDIRECT #endif +/* A and R profiles (and legacy Arm). + Current Program Status Register (CPSR) + M[4:0] Mode bits. M[4] is always 1 for 32-bit modes. + T[5] 1: Thumb, 0: ARM instruction set + F[6] 1: disables FIQ + I[7] 1: disables IRQ + A[8] 1: disables imprecise aborts + E[9] 0: Little-endian, 1: Big-endian + J[24] 1: Jazelle instruction set + */ +#define CPSR_M_USR 0x00 /* User mode. */ +#define CPSR_M_FIQ 0x01 /* Fast Interrupt mode. */ +#define CPSR_M_IRQ 0x02 /* Interrupt mode. */ +#define CPSR_M_SVR 0x03 /* Supervisor mode. */ +#define CPSR_M_MON 0x06 /* Monitor mode. */ +#define CPSR_M_ABT 0x07 /* Abort mode. */ +#define CPSR_M_HYP 0x0A /* Hypervisor mode. */ +#define CPSR_M_UND 0x0B /* Undefined mode. */ +#define CPSR_M_SYS 0x0F /* System mode. */ +#define CPSR_M_32BIT 0x10 /* 32-bit mode. */ +#define CPSR_T_BIT 0x20 /* Thumb bit. */ +#define CPSR_F_MASK 0x40 /* FIQ bit. */ +#define CPSR_I_MASK 0x80 /* IRQ bit. */ + +#define CPSR_M_MASK 0x0F /* Mode mask except M[4]. */ + #endif /* _LIBGLOSS_ARM_H */ diff --git a/libgloss/arm/crt0.S b/libgloss/arm/crt0.S index 1deb73aa5..3e740c654 100644 --- a/libgloss/arm/crt0.S +++ b/libgloss/arm/crt0.S @@ -59,6 +59,21 @@ .endm #endif +/* Annotation for EABI unwinding tables. */ +.macro FN_EH_START +#if defined(__ELF__) && !defined(__USING_SJLJ_EXCEPTIONS__) + .fnstart +#endif +.endm + +.macro FN_EH_END +#if defined(__ELF__) && !defined(__USING_SJLJ_EXCEPTIONS__) + /* Protect against unhandled exceptions. */ + .cantunwind + .fnend +#endif +.endm + .macro indirect_call reg #ifdef HAVE_CALL_INDIRECT blx \reg @@ -68,16 +83,171 @@ #endif .endm +/* For armv4t and newer, toolchains will transparently convert + 'bx lr' to 'mov pc, lr' if needed. GCC has deprecated support + for anything older than armv4t, but this should handle that + corner case in case anyone needs it anyway. */ +.macro FN_RETURN +#if __ARM_ARCH <= 4 && __ARM_ARCH_ISA_THUMB == 0 + mov pc, lr +#else + bx lr +#endif +.endm + + + +/****************************************************************************** +* User mode only: This routine makes default target specific Stack +* +-----+ <- SL_sys, Pointer initialization for different processor modes: +* | | SL_usr FIQ, Abort, IRQ, Undefined, Supervisor, System (User) +* | SYS | and setups a default Stack Limit in-case the code has +* | USR | -=0x10000 been compiled with "-mapcs-stack-check" for FIQ and +* | | System (User) modes. +* | | +* +-----+ <- initial SP, +* becomes SP_sys Hard-wiring SL value is not ideal, since there is +* and SL_usr currently no support for checking that the heap and +* stack have not collided, or that this default 64k is +* All modes: is enough for the program being executed. However, +* +-----+ <- SL_sys, it ensures that this simple crt0 world will not +* | | SL_usr immediately cause an overflow event. +* | SYS | +* | USR | -=0x10000 We go through all execution modes and set up SP +* | | for each of them. +* +-----+ <- SP_sys, +* | | SP_usr Notes: +* | SVC | -= 0x8000 - This code will not work as intended if the system +* | | starts in secure mode. In particular the methods +* +-----+ <- SP_svc of getting in and out of secure state are not as +* | | simple as writing to the CPSR mode bits. +* | IRQ | -= 0x2000 - Mode switch via CPSR is not allowed once in +* | | non-privileged mode, so we take care not to enter +* ^ +-----+ <- SP_und "User" to set up its SP, and also skip most +* s | | operations if already in that mode. +* t | UND | -= 0x1000 +* a | | Input parameters: +* c +-----+ <- SP_und - sp - Initialized SP +* k | | - r2 - May contain SL value from semihosting +* | ABT | -= 0x1000 SYS_HEAPINFO call +* g | | Scratch registers: +* r +-----+ <- SP_abt, - r1 - new value of CPSR +* o | | SL_fiq - r2 - intermediate value (in standalone mode) +* w | FIQ | -= 0x1000 - r3 - new SP value +* t | | - r4 - save/restore CPSR on entry/exit +* h +-----+ <- initial SP, +* becomes SP_fiq Declared as "weak" so that user can write and use +* his own implementation if current doesn't fit. +* +******************************************************************************/ + .align 0 + FUNC_START _stack_init + .weak FUNCTION (_stack_init) + FN_EH_START + + /* M profile doesn't have CPSR register. */ +#if (__ARM_ARCH_PROFILE != 'M') + /* Following code is compatible for both ARM and Thumb ISA. */ + mrs r4, CPSR + /* Test mode bits - in User of all are 0. */ + tst r4, #(CPSR_M_MASK) + /* "eq" means r4 AND #0x0F is 0. */ + beq .Lskip_cpu_modes + + mov r3, sp /* Save input SP value. */ + + /* FIQ mode, interrupts disabled. */ + mov r1, #(CPSR_M_FIQ|CPSR_M_32BIT|CPSR_I_MASK|CPSR_F_MASK) + msr CPSR_c, r1 + mov sp, r3 + sub sl, sp, #0x1000 /* FIQ mode has its own SL. */ + + /* Abort mode, interrupts disabled. */ + mov r3, sl + mov r1, #(CPSR_M_ABT|CPSR_M_32BIT|CPSR_I_MASK|CPSR_F_MASK) + msr CPSR_c, r1 + mov sp, r3 + sub r3, r3, #0x1000 + + /* Undefined mode, interrupts disabled. */ + mov r1, #(CPSR_M_UND|CPSR_M_32BIT|CPSR_I_MASK|CPSR_F_MASK) + msr CPSR_c, r1 + mov sp, r3 + sub r3, r3, #0x1000 + + /* IRQ mode, interrupts disabled. */ + mov r1, #(CPSR_M_IRQ|CPSR_M_32BIT|CPSR_I_MASK|CPSR_F_MASK) + msr CPSR_c, r1 + mov sp, r3 + sub r3, r3, #0x2000 + + /* Supervisory mode, interrupts disabled. */ + mov r1, #(CPSR_M_SVR|CPSR_M_32BIT|CPSR_I_MASK|CPSR_F_MASK) + msr CPSR_c, r1 + mov sp, r3 + + sub r3, r3, #0x8000 /* Min size 32k. */ + bic r3, r3, #0x00FF /* Align with current 64k block. */ + bic r3, r3, #0xFF00 + +# if __ARM_ARCH >= 4 + /* System (shares regs with User) mode, interrupts disabled. */ + mov r1, #(CPSR_M_SYS|CPSR_M_32BIT|CPSR_I_MASK|CPSR_F_MASK) + msr CPSR_c, r1 + mov sp, r3 +# else + /* Keep this for ARMv3, but GCC actually dropped it. */ + /* Move value into user mode SP without changing modes, */ + /* via '^' form of ldm. */ + str r3, [r3, #-4] + ldmdb r3, {sp}^ +# endif + + /* Back to original mode, presumably SVC, with diabled FIQ/IRQ. */ + orr r4, r4, #(CPSR_I_MASK|CPSR_F_MASK) + msr CPSR_c, r4 + +.Lskip_cpu_modes: +#endif + + /* Set SL register. */ +#if defined (ARM_RDI_MONITOR) /* semihosting */ + cmp r2, #0 + beq .Lsl_forced_zero + /* Allow slop for stack overflow handling and small frames. */ +# ifdef THUMB1_ONLY + adds r2, #128 + adds r2, #128 + mov sl, r2 +# else + add sl, r2, #256 +# endif +.Lsl_forced_zero: + +#else /* standalone */ + /* r3 contains SP for System/User mode. Set SL = SP - 0x10000. */ + #ifdef THUMB1_ONLY + movs r2, #64 + lsls r2, r2, #10 + subs r2, r3, r2 + mov sl, r2 + #else + /* Still assumes 256bytes below SL. */ + sub sl, r3, #64 << 10 + #endif +#endif + + FN_RETURN + FN_EH_END + + /******************************************************************************* * Main library startup code. *******************************************************************************/ .align 0 FUNC_START _mainCRTStartup FUNC_START _start -#if defined(__ELF__) && !defined(__USING_SJLJ_EXCEPTIONS__) - /* Annotation for EABI unwinding tables. */ - .fnstart -#endif + FN_EH_START /* __ARM_ARCH_PROFILE is defined from GCC 4.8 onwards, however __ARM_ARCH_7A has been defined since 4.2 onwards, which is when v7-a support was added @@ -144,42 +314,33 @@ .LC32: ldr r1, [r0, #8] ldr r2, [r0, #12] - /* We skip setting sp/sl if 0 returned from semihosting. + /* We skip setting SP/SL if 0 returned from semihosting. - According to semihosting docs, if 0 returned from semihosting, the system was unable to calculate the real value, so it's ok - to skip setting sp/sl to 0 here. + to skip setting SP/SL to 0 here. - Considering M-profile processors, We might want to initialize - sp by the first entry of vector table and return 0 to SYS_HEAPINFO - semihosting call, which will be skipped here. */ + SP by the first entry of vector table and return 0 to SYS_HEAPINFO + semihosting call, which will be skipped here. + - Considering R-profile processors there is no automatic SP init by hardware + so we need to initialize it by default value. */ + ldr r3, .Lstack cmp r1, #0 beq .LC26 - mov sp, r1 + mov r3, r1 .LC26: - cmp r2, #0 - beq .LC27 + mov sp, r3 - /* Allow slop for stack overflow handling and small frames. */ -#ifdef THUMB1_ONLY - adds r2, #128 - adds r2, #128 - mov sl, r2 -#else - add sl, r2, #256 -#endif + /* r2 (SL value) will be used in _stack_init. */ + bl FUNCTION (_stack_init) -.LC27: -#else - /* Set up the stack pointer to a fixed value. */ + +#else /* standalone */ + /* Set up the stack pointer to a fixed value. */ /* Changes by toralf: - Allow linker script to provide stack via __stack symbol - see defintion of .Lstack - Provide "hooks" that may be used by the application to add - custom init code - see .Lhwinit and .Lswinit - - Go through all execution modes and set up stack for each of them. - Loosely based on init.s from ARM/Motorola example code. - Note: Mode switch via CPSR is not allowed once in non-privileged - mode, so we take care not to enter "User" to set up its sp, - and also skip most operations if already in that mode. */ + custom init code - see .Lhwinit and .Lswinit. */ ldr r3, .Lstack cmp r3, #0 @@ -194,61 +355,14 @@ ldreq r3, .LC0 #endif /* Note: This 'mov' is essential when starting in User, and ensures we - always get *some* sp value for the initial mode, even if we + always get *some* SP value for the initial mode, even if we have somehow missed it below (in which case it gets the same value as FIQ - not ideal, but better than nothing). */ mov sp, r3 -#ifdef PREFER_THUMB - /* XXX Fill in stack assignments for interrupt modes. */ -#else - mrs r2, CPSR - tst r2, #0x0F /* Test mode bits - in User of all are 0. */ - beq .LC23 /* "eq" means r2 AND #0x0F is 0. */ - msr CPSR_c, #0xD1 /* FIRQ mode, interrupts disabled. */ - mov sp, r3 - sub sl, sp, #0x1000 /* This mode also has its own sl (see below). */ - - mov r3, sl - msr CPSR_c, #0xD7 /* Abort mode, interrupts disabled. */ - mov sp, r3 - sub r3, r3, #0x1000 - msr CPSR_c, #0xDB /* Undefined mode, interrupts disabled. */ - mov sp, r3 - sub r3, r3, #0x1000 + /* We don't care of r2 value in standalone. */ + bl FUNCTION (_stack_init) - msr CPSR_c, #0xD2 /* IRQ mode, interrupts disabled. */ - mov sp, r3 - sub r3, r3, #0x2000 - - msr CPSR_c, #0xD3 /* Supervisory mode, interrupts disabled. */ - - mov sp, r3 - sub r3, r3, #0x8000 /* Min size 32k. */ - bic r3, r3, #0x00FF /* Align with current 64k block. */ - bic r3, r3, #0xFF00 - - str r3, [r3, #-4] /* Move value into user mode sp without */ - ldmdb r3, {sp}^ /* changing modes, via '^' form of ldm. */ - orr r2, r2, #0xC0 /* Back to original mode, presumably SVC, */ - msr CPSR_c, r2 /* with FIQ/IRQ disable bits forced to 1. */ -#endif -.LC23: - /* Setup a default stack-limit in-case the code has been - compiled with "-mapcs-stack-check". Hard-wiring this value - is not ideal, since there is currently no support for - checking that the heap and stack have not collided, or that - this default 64k is enough for the program being executed. - However, it ensures that this simple crt0 world will not - immediately cause an overflow event: */ -#ifdef THUMB1_ONLY - movs r2, #64 - lsls r2, r2, #10 - subs r2, r3, r2 - mov sl, r2 -#else - sub sl, r3, #64 << 10 /* Still assumes 256bytes below sl. */ -#endif #endif #endif /* Zero the memory in the .bss section. */ @@ -443,10 +557,12 @@ change_back: /* Halt the execution. This code should never be executed. */ /* With no debug monitor, this probably aborts (eventually). With a Demon debug monitor, this halts cleanly. - With an Angel debug monitor, this will report 'Unknown SWI'. */ + With an Angel debug monitor, this will report 'Unknown SWI'. */ swi SWI_Exit #endif + FN_EH_END + /* For Thumb, constants must be after the code since only positive offsets are supported for PC relative addresses. */ .align 0 @@ -464,9 +580,6 @@ change_back: #else .word 0x80000 /* Top of RAM on the PIE board. */ #endif - -.Lstack: - .word __stack .Lhwinit: .word FUNCTION (hardware_init_hook) .Lswinit: @@ -477,19 +590,18 @@ change_back: runtime (meaning "ignore setting") for the variables, when the user does not provide the symbols. (The linker uses a weak symbol if, and only if, a normal version of the same symbol isn't provided - e.g. by a linker script or another object file.) */ + e.g. by a linker script or another object file.) */ - .weak __stack .weak FUNCTION (hardware_init_hook) .weak FUNCTION (software_init_hook) #endif #endif -#if defined(__ELF__) && !defined(__USING_SJLJ_EXCEPTIONS__) - /* Protect against unhandled exceptions. */ - .cantunwind - .fnend -#endif + +.Lstack: + .word __stack + .weak __stack + .LC1: .word __bss_start__ .LC2: diff --git a/newlib/libc/sys/arm/arm.h b/newlib/libc/sys/arm/arm.h index 0489f2d92..dbed81750 100644 --- a/newlib/libc/sys/arm/arm.h +++ b/newlib/libc/sys/arm/arm.h @@ -61,4 +61,30 @@ # define HAVE_CALL_INDIRECT #endif +/* A and R profiles (and legacy Arm). + Current Program Status Register (CPSR) + M[4:0] Mode bits. M[4] is always 1 for 32-bit modes. + T[5] 1: Thumb, 0: ARM instruction set + F[6] 1: disables FIQ + I[7] 1: disables IRQ + A[8] 1: disables imprecise aborts + E[9] 0: Little-endian, 1: Big-endian + J[24] 1: Jazelle instruction set + */ +#define CPSR_M_USR 0x00 /* User mode. */ +#define CPSR_M_FIQ 0x01 /* Fast Interrupt mode. */ +#define CPSR_M_IRQ 0x02 /* Interrupt mode. */ +#define CPSR_M_SVR 0x03 /* Supervisor mode. */ +#define CPSR_M_MON 0x06 /* Monitor mode. */ +#define CPSR_M_ABT 0x07 /* Abort mode. */ +#define CPSR_M_HYP 0x0A /* Hypervisor mode. */ +#define CPSR_M_UND 0x0B /* Undefined mode. */ +#define CPSR_M_SYS 0x0F /* System mode. */ +#define CPSR_M_32BIT 0x10 /* 32-bit mode. */ +#define CPSR_T_BIT 0x20 /* Thumb bit. */ +#define CPSR_F_MASK 0x40 /* FIQ bit. */ +#define CPSR_I_MASK 0x80 /* IRQ bit. */ + +#define CPSR_M_MASK 0x0F /* Mode mask except M[4] */ + #endif /* _LIBGLOSS_ARM_H */ diff --git a/newlib/libc/sys/arm/crt0.S b/newlib/libc/sys/arm/crt0.S index 7a6b40d9a..9c262428d 100644 --- a/newlib/libc/sys/arm/crt0.S +++ b/newlib/libc/sys/arm/crt0.S @@ -59,6 +59,21 @@ .endm #endif +/* Annotation for EABI unwinding tables. */ +.macro FN_EH_START +#if defined(__ELF__) && !defined(__USING_SJLJ_EXCEPTIONS__) + .fnstart +#endif +.endm + +.macro FN_EH_END +#if defined(__ELF__) && !defined(__USING_SJLJ_EXCEPTIONS__) + /* Protect against unhandled exceptions. */ + .cantunwind + .fnend +#endif +.endm + .macro indirect_call reg #ifdef HAVE_CALL_INDIRECT blx \reg @@ -68,16 +83,171 @@ #endif .endm +/* For armv4t and newer, toolchains will transparently convert + 'bx lr' to 'mov pc, lr' if needed. GCC has deprecated support + for anything older than armv4t, but this should handle that + corner case in case anyone needs it anyway. */ +.macro FN_RETURN +#if __ARM_ARCH <= 4 && __ARM_ARCH_ISA_THUMB == 0 + mov pc, lr +#else + bx lr +#endif +.endm + + + +/****************************************************************************** +* User mode only: This routine makes default target specific Stack +* +-----+ <- SL_sys, Pointer initialization for different processor modes: +* | | SL_usr FIQ, Abort, IRQ, Undefined, Supervisor, System (User) +* | SYS | and setups a default Stack Limit in-case the code has +* | USR | -=0x10000 been compiled with "-mapcs-stack-check" for FIQ and +* | | System (User) modes. +* | | +* +-----+ <- initial SP, +* becomes SP_sys Hard-wiring SL value is not ideal, since there is +* and SL_usr currently no support for checking that the heap and +* stack have not collided, or that this default 64k is +* All modes: is enough for the program being executed. However, +* +-----+ <- SL_sys, it ensures that this simple crt0 world will not +* | | SL_usr immediately cause an overflow event. +* | SYS | +* | USR | -=0x10000 We go through all execution modes and set up SP +* | | for each of them. +* +-----+ <- SP_sys, +* | | SP_usr Notes: +* | SVC | -= 0x8000 - This code will not work as intended if the system +* | | starts in secure mode. In particular the methods +* +-----+ <- SP_svc of getting in and out of secure state are not as +* | | simple as writing to the CPSR mode bits. +* | IRQ | -= 0x2000 - Mode switch via CPSR is not allowed once in +* | | non-privileged mode, so we take care not to enter +* ^ +-----+ <- SP_und "User" to set up its SP, and also skip most +* s | | operations if already in that mode. +* t | UND | -= 0x1000 +* a | | Input parameters: +* c +-----+ <- SP_und - sp - Initialized SP +* k | | - r2 - May contain SL value from semihosting +* | ABT | -= 0x1000 SYS_HEAPINFO call +* g | | Scratch registers: +* r +-----+ <- SP_abt, - r1 - new value of CPSR +* o | | SL_fiq - r2 - intermediate value (in standalone mode) +* w | FIQ | -= 0x1000 - r3 - new SP value +* t | | - r4 - save/restore CPSR on entry/exit +* h +-----+ <- initial SP, +* becomes SP_fiq Declared as "weak" so that user can write and use +* his own implementation if current doesn't fit. +* +******************************************************************************/ + .align 0 + FUNC_START _stack_init + .weak FUNCTION (_stack_init) + FN_EH_START + + /* M profile doesn't have CPSR register. */ +#if (__ARM_ARCH_PROFILE != 'M') + /* Following code is compatible for both ARM and Thumb ISA. */ + mrs r4, CPSR + /* Test mode bits - in User of all are 0. */ + tst r4, #(CPSR_M_MASK) + /* "eq" means r4 AND #0x0F is 0. */ + beq .Lskip_cpu_modes + + mov r3, sp /* Save input SP value. */ + + /* FIQ mode, interrupts disabled. */ + mov r1, #(CPSR_M_FIQ|CPSR_M_32BIT|CPSR_I_MASK|CPSR_F_MASK) + msr CPSR_c, r1 + mov sp, r3 + sub sl, sp, #0x1000 /* FIQ mode has its own SL. */ + + /* Abort mode, interrupts disabled. */ + mov r3, sl + mov r1, #(CPSR_M_ABT|CPSR_M_32BIT|CPSR_I_MASK|CPSR_F_MASK) + msr CPSR_c, r1 + mov sp, r3 + sub r3, r3, #0x1000 + + /* Undefined mode, interrupts disabled. */ + mov r1, #(CPSR_M_UND|CPSR_M_32BIT|CPSR_I_MASK|CPSR_F_MASK) + msr CPSR_c, r1 + mov sp, r3 + sub r3, r3, #0x1000 + + /* IRQ mode, interrupts disabled. */ + mov r1, #(CPSR_M_IRQ|CPSR_M_32BIT|CPSR_I_MASK|CPSR_F_MASK) + msr CPSR_c, r1 + mov sp, r3 + sub r3, r3, #0x2000 + + /* Supervisory mode, interrupts disabled. */ + mov r1, #(CPSR_M_SVR|CPSR_M_32BIT|CPSR_I_MASK|CPSR_F_MASK) + msr CPSR_c, r1 + mov sp, r3 + + sub r3, r3, #0x8000 /* Min size 32k. */ + bic r3, r3, #0x00FF /* Align with current 64k block. */ + bic r3, r3, #0xFF00 + +# if __ARM_ARCH >= 4 + /* System (shares regs with User) mode, interrupts disabled. */ + mov r1, #(CPSR_M_SYS|CPSR_M_32BIT|CPSR_I_MASK|CPSR_F_MASK) + msr CPSR_c, r1 + mov sp, r3 +# else + /* Keep this for ARMv3, but GCC actually dropped it. */ + /* Move value into user mode SP without changing modes, */ + /* via '^' form of ldm. */ + str r3, [r3, #-4] + ldmdb r3, {sp}^ +# endif + + /* Back to original mode, presumably SVC, with diabled FIQ/IRQ. */ + orr r4, r4, #(CPSR_I_MASK|CPSR_F_MASK) + msr CPSR_c, r4 + +.Lskip_cpu_modes: +#endif + + /* Set SL register. */ +#if defined (ARM_RDI_MONITOR) /* semihosting */ + cmp r2, #0 + beq .Lsl_forced_zero + /* Allow slop for stack overflow handling and small frames. */ +# ifdef THUMB1_ONLY + adds r2, #128 + adds r2, #128 + mov sl, r2 +# else + add sl, r2, #256 +# endif +.Lsl_forced_zero: + +#else /* standalone */ + /* r3 contains SP for System/User mode. Set SL = SP - 0x10000. */ + #ifdef THUMB1_ONLY + movs r2, #64 + lsls r2, r2, #10 + subs r2, r3, r2 + mov sl, r2 + #else + /* Still assumes 256bytes below SL. */ + sub sl, r3, #64 << 10 + #endif +#endif + + FN_RETURN + FN_EH_END + + /******************************************************************************* * Main library startup code. *******************************************************************************/ .align 0 FUNC_START _mainCRTStartup FUNC_START _start -#if defined(__ELF__) && !defined(__USING_SJLJ_EXCEPTIONS__) - /* Annotation for EABI unwinding tables. */ - .fnstart -#endif + FN_EH_START /* Start by setting up a stack. */ #ifdef ARM_RDP_MONITOR @@ -124,42 +294,33 @@ .LC32: ldr r1, [r0, #8] ldr r2, [r0, #12] - /* We skip setting sp/sl if 0 returned from semihosting. + /* We skip setting SP/SL if 0 returned from semihosting. - According to semihosting docs, if 0 returned from semihosting, the system was unable to calculate the real value, so it's ok - to skip setting sp/sl to 0 here. + to skip setting SP/SL to 0 here. - Considering M-profile processors, We might want to initialize - sp by the first entry of vector table and return 0 to SYS_HEAPINFO - semihosting call, which will be skipped here. */ + SP by the first entry of vector table and return 0 to SYS_HEAPINFO + semihosting call, which will be skipped here. + - Considering R-profile processors there is no automatic SP init by hardware + so we need to initialize it by default value. */ + ldr r3, .Lstack cmp r1, #0 beq .LC26 - mov sp, r1 + mov r3, r1 .LC26: - cmp r2, #0 - beq .LC27 + mov sp, r3 - /* Allow slop for stack overflow handling and small frames. */ -#ifdef THUMB1_ONLY - adds r2, #128 - adds r2, #128 - mov sl, r2 -#else - add sl, r2, #256 -#endif + /* r2 (SL value) will be used in _stack_init. */ + bl FUNCTION (_stack_init) -.LC27: -#else - /* Set up the stack pointer to a fixed value. */ + +#else /* standalone */ + /* Set up the stack pointer to a fixed value. */ /* Changes by toralf: - Allow linker script to provide stack via __stack symbol - see defintion of .Lstack - Provide "hooks" that may be used by the application to add - custom init code - see .Lhwinit and .Lswinit - - Go through all execution modes and set up stack for each of them. - Loosely based on init.s from ARM/Motorola example code. - Note: Mode switch via CPSR is not allowed once in non-privileged - mode, so we take care not to enter "User" to set up its sp, - and also skip most operations if already in that mode. */ + custom init code - see .Lhwinit and .Lswinit. */ ldr r3, .Lstack cmp r3, #0 @@ -174,61 +335,14 @@ ldreq r3, .LC0 #endif /* Note: This 'mov' is essential when starting in User, and ensures we - always get *some* sp value for the initial mode, even if we + always get *some* SP value for the initial mode, even if we have somehow missed it below (in which case it gets the same value as FIQ - not ideal, but better than nothing). */ mov sp, r3 -#ifdef PREFER_THUMB - /* XXX Fill in stack assignments for interrupt modes. */ -#else - mrs r2, CPSR - tst r2, #0x0F /* Test mode bits - in User of all are 0. */ - beq .LC23 /* "eq" means r2 AND #0x0F is 0. */ - msr CPSR_c, #0xD1 /* FIRQ mode, interrupts disabled. */ - mov sp, r3 - sub sl, sp, #0x1000 /* This mode also has its own sl (see below). */ - - mov r3, sl - msr CPSR_c, #0xD7 /* Abort mode, interrupts disabled. */ - mov sp, r3 - sub r3, r3, #0x1000 - msr CPSR_c, #0xDB /* Undefined mode, interrupts disabled. */ - mov sp, r3 - sub r3, r3, #0x1000 + /* We don't care of r2 value in standalone. */ + bl FUNCTION (_stack_init) - msr CPSR_c, #0xD2 /* IRQ mode, interrupts disabled. */ - mov sp, r3 - sub r3, r3, #0x2000 - - msr CPSR_c, #0xD3 /* Supervisory mode, interrupts disabled. */ - - mov sp, r3 - sub r3, r3, #0x8000 /* Min size 32k. */ - bic r3, r3, #0x00FF /* Align with current 64k block. */ - bic r3, r3, #0xFF00 - - str r3, [r3, #-4] /* Move value into user mode sp without */ - ldmdb r3, {sp}^ /* changing modes, via '^' form of ldm. */ - orr r2, r2, #0xC0 /* Back to original mode, presumably SVC, */ - msr CPSR_c, r2 /* with FIQ/IRQ disable bits forced to 1. */ -#endif -.LC23: - /* Setup a default stack-limit in-case the code has been - compiled with "-mapcs-stack-check". Hard-wiring this value - is not ideal, since there is currently no support for - checking that the heap and stack have not collided, or that - this default 64k is enough for the program being executed. - However, it ensures that this simple crt0 world will not - immediately cause an overflow event: */ -#ifdef THUMB1_ONLY - movs r2, #64 - lsls r2, r2, #10 - subs r2, r3, r2 - mov sl, r2 -#else - sub sl, r3, #64 << 10 /* Still assumes 256bytes below sl. */ -#endif #endif #endif /* Zero the memory in the .bss section. */ @@ -417,10 +531,12 @@ change_back: /* Halt the execution. This code should never be executed. */ /* With no debug monitor, this probably aborts (eventually). With a Demon debug monitor, this halts cleanly. - With an Angel debug monitor, this will report 'Unknown SWI'. */ + With an Angel debug monitor, this will report 'Unknown SWI'. */ swi SWI_Exit #endif + FN_EH_END + /* For Thumb, constants must be after the code since only positive offsets are supported for PC relative addresses. */ .align 0 @@ -438,9 +554,6 @@ change_back: #else .word 0x80000 /* Top of RAM on the PIE board. */ #endif - -.Lstack: - .word __stack .Lhwinit: .word FUNCTION (hardware_init_hook) .Lswinit: @@ -451,19 +564,18 @@ change_back: runtime (meaning "ignore setting") for the variables, when the user does not provide the symbols. (The linker uses a weak symbol if, and only if, a normal version of the same symbol isn't provided - e.g. by a linker script or another object file.) */ + e.g. by a linker script or another object file.) */ - .weak __stack .weak FUNCTION (hardware_init_hook) .weak FUNCTION (software_init_hook) #endif #endif -#if defined(__ELF__) && !defined(__USING_SJLJ_EXCEPTIONS__) - /* Protect against unhandled exceptions. */ - .cantunwind - .fnend -#endif + +.Lstack: + .word __stack + .weak __stack + .LC1: .word __bss_start__ .LC2: From e50ad9fbdc5adfb5c13954a2798d1ea0ad53db34 Mon Sep 17 00:00:00 2001 From: Vaibhav Gupta Date: Wed, 10 Jul 2019 14:25:50 +0530 Subject: [PATCH 447/475] Port ndbm --- newlib/libc/include/ndbm.h | 93 ++++++++++++++ newlib/libc/search/Makefile.am | 1 + newlib/libc/search/ndbm.c | 217 +++++++++++++++++++++++++++++++++ 3 files changed, 311 insertions(+) create mode 100644 newlib/libc/include/ndbm.h create mode 100644 newlib/libc/search/ndbm.c diff --git a/newlib/libc/include/ndbm.h b/newlib/libc/include/ndbm.h new file mode 100644 index 000000000..6c803702e --- /dev/null +++ b/newlib/libc/include/ndbm.h @@ -0,0 +1,93 @@ +/*- + * SPDX-License-Identifier: BSD-3-Clause + * + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Margo Seltzer. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)ndbm.h 8.1 (Berkeley) 6/2/93 + * $FreeBSD$ : src/include/ndbm.h + * Nov 20 19:45:28 2017 UTC by pfg + * SVN Revision 326024 + */ + +#ifndef _NDBM_H_ +#define _NDBM_H_ + +/* #include */ + +/* + * The above header-file is directly included in `newlib/libc/search/ndbm.c` + * as `db.h` is present in form of `db_local.h`, inside `newlib/libc/search` + * directory and not in `newlib/libc/include`. + * Necessary data-types are mentioned in form of forward-declarations + */ + +/* Map dbm interface onto db(3). */ +#define DBM_RDONLY O_RDONLY + +/* Flags to dbm_store(). */ +#define DBM_INSERT 0 +#define DBM_REPLACE 1 + +/* + * The db(3) support for ndbm always appends this suffix to the + * file name to avoid overwriting the user's original database. + */ +#define DBM_SUFFIX ".db" + +typedef struct { + void *dptr; + int dsize; /* XXX Should be size_t according to 1003.1-2008. */ +} datum; + +struct __db; /* Forward-declaration */ +typedef struct __db DB; /* Forward-declaration */ +typedef DB DBM; +#define dbm_pagfno(a) DBM_PAGFNO_NOT_AVAILABLE + +__BEGIN_DECLS +int dbm_clearerr(DBM *); +void dbm_close(DBM *); +int dbm_delete(DBM *, datum); +int dbm_error(DBM *); +datum dbm_fetch(DBM *, datum); +datum dbm_firstkey(DBM *); +#if __BSD_VISIBLE +long dbm_forder(DBM *, datum); +#endif +datum dbm_nextkey(DBM *); +DBM *dbm_open(const char *, int, mode_t); +int dbm_store(DBM *, datum, datum, int); +#if __BSD_VISIBLE +int dbm_dirfno(DBM *); +#endif +__END_DECLS + +#endif /* !_NDBM_H_ */ diff --git a/newlib/libc/search/Makefile.am b/newlib/libc/search/Makefile.am index 98920c3f4..a61107fb9 100644 --- a/newlib/libc/search/Makefile.am +++ b/newlib/libc/search/Makefile.am @@ -9,6 +9,7 @@ GENERAL_SOURCES = \ db_local.h \ extern.h \ hash.h \ + ndbm.c \ page.h \ qsort.c diff --git a/newlib/libc/search/ndbm.c b/newlib/libc/search/ndbm.c new file mode 100644 index 000000000..7f3296078 --- /dev/null +++ b/newlib/libc/search/ndbm.c @@ -0,0 +1,217 @@ +/*- + * SPDX-License-Identifier: BSD-3-Clause + * + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Margo Seltzer. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)ndbm.c 8.4 (Berkeley) 7/21/94"; +#endif /* LIBC_SCCS and not lint */ +#include +__FBSDID("$FreeBSD$ : src/lib/libc/db/hash/ndbm.c Nov 20 19:49:47 2017 UTC by pfg - SVN Revision 326025"); + +/* + * This package provides a dbm compatible interface to the new hashing + * package described in db(3). + */ + +#include + +#include +#include +#include + +#include +#include "hash.h" + +#define __DBINTERFACE_PRIVATE /* activate prototypes from db_local.h */ +#include "db_local.h" + +/* + * Returns: + * *DBM on success + * NULL on failure + */ +extern DBM * +dbm_open(const char *file, int flags, mode_t mode) +{ + HASHINFO info; + char path[MAXPATHLEN]; + + info.bsize = 4096; + info.ffactor = 40; + info.nelem = 1; + info.cachesize = 0; + info.hash = NULL; + info.lorder = 0; + + if( strlen(file) >= sizeof(path) - strlen(DBM_SUFFIX)) { + errno = ENAMETOOLONG; + return(NULL); + } + (void)strcpy(path, file); + (void)strcat(path, DBM_SUFFIX); + return ((DBM *)__hash_open(path, flags, mode, 0, &info)); +} + +extern void +dbm_close(DBM *db) +{ + (void)(db->close)(db); +} + +/* + * Returns: + * DATUM on success + * NULL on failure + */ +extern datum +dbm_fetch(DBM *db, datum key) +{ + datum retdata; + int status; + DBT dbtkey, dbtretdata; + + dbtkey.data = key.dptr; + dbtkey.size = key.dsize; + status = (db->get)(db, &dbtkey, &dbtretdata, 0); + if (status) { + dbtretdata.data = NULL; + dbtretdata.size = 0; + } + retdata.dptr = dbtretdata.data; + retdata.dsize = dbtretdata.size; + return (retdata); +} + +/* + * Returns: + * DATUM on success + * NULL on failure + */ +extern datum +dbm_firstkey(DBM *db) +{ + int status; + datum retkey; + DBT dbtretkey, dbtretdata; + + status = (db->seq)(db, &dbtretkey, &dbtretdata, R_FIRST); + if (status) + dbtretkey.data = NULL; + retkey.dptr = dbtretkey.data; + retkey.dsize = dbtretkey.size; + return (retkey); +} + +/* + * Returns: + * DATUM on success + * NULL on failure + */ +extern datum +dbm_nextkey(DBM *db) +{ + int status; + datum retkey; + DBT dbtretkey, dbtretdata; + + status = (db->seq)(db, &dbtretkey, &dbtretdata, R_NEXT); + if (status) + dbtretkey.data = NULL; + retkey.dptr = dbtretkey.data; + retkey.dsize = dbtretkey.size; + return (retkey); +} + +/* + * Returns: + * 0 on success + * <0 failure + */ +extern int +dbm_delete(DBM *db, datum key) +{ + int status; + DBT dbtkey; + + dbtkey.data = key.dptr; + dbtkey.size = key.dsize; + status = (db->del)(db, &dbtkey, 0); + if (status) + return (-1); + else + return (0); +} + +/* + * Returns: + * 0 on success + * <0 failure + * 1 if DBM_INSERT and entry exists + */ +extern int +dbm_store(DBM *db, datum key, datum data, int flags) +{ + DBT dbtkey, dbtdata; + + dbtkey.data = key.dptr; + dbtkey.size = key.dsize; + dbtdata.data = data.dptr; + dbtdata.size = data.dsize; + return ((db->put)(db, &dbtkey, &dbtdata, + (flags == DBM_INSERT) ? R_NOOVERWRITE : 0)); +} + +extern int +dbm_error(DBM *db) +{ + HTAB *hp; + + hp = (HTAB *)db->internal; + return (hp->error); +} + +extern int +dbm_clearerr(DBM *db) +{ + HTAB *hp; + + hp = (HTAB *)db->internal; + hp->error = 0; + return (0); +} + +extern int +dbm_dirfno(DBM *db) +{ + return(((HTAB *)db->internal)->fp); +} From 9cde02051ea528e5f1af1aa2dea50224eec57860 Mon Sep 17 00:00:00 2001 From: uchan-nos Date: Tue, 23 Jul 2019 21:15:48 +0900 Subject: [PATCH 448/475] fix compile errors for efgcvt.c --- newlib/libc/stdlib/efgcvt.c | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/newlib/libc/stdlib/efgcvt.c b/newlib/libc/stdlib/efgcvt.c index 9314bf361..3cdb9c420 100644 --- a/newlib/libc/stdlib/efgcvt.c +++ b/newlib/libc/stdlib/efgcvt.c @@ -102,6 +102,9 @@ Supporting OS subroutines required: <>, <>, <>, #include #include "local.h" +char * ecvtbuf (double, int, int*, int*, char *); +char * fcvtbuf (double, int, int*, int*, char *); + char * fcvt (double d, int ndigit, @@ -121,6 +124,21 @@ fcvtf (float d, } +char * +gcvt (double d, + int ndigit, + char *buf) +{ + char *tbuf = buf; + if (d < 0) { + *buf = '-'; + buf++; + ndigit--; + } + return (_gcvt (_REENT, d, ndigit, buf, 'g', 0) ? tbuf : 0); +} + + char * gcvtf (float d, int ndigit, @@ -148,18 +166,3 @@ ecvtf (float d, { return ecvt ((double) d, ndigit, decpt, sign); } - - -char * -gcvt (double d, - int ndigit, - char *buf) -{ - char *tbuf = buf; - if (d < 0) { - *buf = '-'; - buf++; - ndigit--; - } - return (_gcvt (_REENT, d, ndigit, buf, 'g', 0) ? tbuf : 0); -} From 280b21d373f7029f5cef078740dc1085c8a5e549 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Wed, 24 Jul 2019 18:47:35 +0200 Subject: [PATCH 449/475] Regenerate newlib/libc/search/Makefile.in for ndpm port Signed-off-by: Corinna Vinschen --- newlib/libc/search/Makefile.in | 62 +++++++++++++++++++++++----------- 1 file changed, 42 insertions(+), 20 deletions(-) diff --git a/newlib/libc/search/Makefile.in b/newlib/libc/search/Makefile.in index 54f33e122..8077a5f27 100644 --- a/newlib/libc/search/Makefile.in +++ b/newlib/libc/search/Makefile.in @@ -1,9 +1,8 @@ -# Makefile.in generated by automake 1.11.6 from Makefile.am. +# Makefile.in generated by automake 1.12.2 from Makefile.am. # @configure_input@ -# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software -# Foundation, Inc. +# Copyright (C) 1994-2012 Free Software Foundation, Inc. + # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. @@ -54,15 +53,11 @@ POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ DIST_COMMON = $(srcdir)/../../Makefile.shared $(srcdir)/Makefile.in \ - $(srcdir)/Makefile.am + $(srcdir)/Makefile.am $(top_srcdir)/../../mkinstalldirs subdir = search ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/../../libtool.m4 \ - $(top_srcdir)/../../ltoptions.m4 \ - $(top_srcdir)/../../ltsugar.m4 \ - $(top_srcdir)/../../ltversion.m4 \ - $(top_srcdir)/../../lt~obsolete.m4 \ - $(top_srcdir)/../acinclude.m4 $(top_srcdir)/configure.in +am__aclocal_m4_deps = $(top_srcdir)/../acinclude.m4 \ + $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(SHELL) $(top_srcdir)/../../mkinstalldirs @@ -72,7 +67,8 @@ LIBRARIES = $(noinst_LIBRARIES) ARFLAGS = cru lib_a_AR = $(AR) $(ARFLAGS) lib_a_LIBADD = -am__objects_1 = lib_a-bsearch.$(OBJEXT) lib_a-qsort.$(OBJEXT) +am__objects_1 = lib_a-bsearch.$(OBJEXT) lib_a-ndbm.$(OBJEXT) \ + lib_a-qsort.$(OBJEXT) @ELIX_LEVEL_1_FALSE@am__objects_2 = lib_a-hash.$(OBJEXT) \ @ELIX_LEVEL_1_FALSE@ lib_a-hash_bigkey.$(OBJEXT) \ @ELIX_LEVEL_1_FALSE@ lib_a-hash_buf.$(OBJEXT) \ @@ -93,7 +89,7 @@ am__objects_1 = lib_a-bsearch.$(OBJEXT) lib_a-qsort.$(OBJEXT) lib_a_OBJECTS = $(am_lib_a_OBJECTS) LTLIBRARIES = $(noinst_LTLIBRARIES) libsearch_la_LIBADD = -am__objects_4 = bsearch.lo qsort.lo +am__objects_4 = bsearch.lo ndbm.lo qsort.lo @ELIX_LEVEL_1_FALSE@am__objects_5 = hash.lo hash_bigkey.lo hash_buf.lo \ @ELIX_LEVEL_1_FALSE@ hash_func.lo hash_log2.lo hash_page.lo \ @ELIX_LEVEL_1_FALSE@ hcreate.lo hcreate_r.lo tdelete.lo \ @@ -186,8 +182,10 @@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NEWLIB_CFLAGS = @NEWLIB_CFLAGS@ NM = @NM@ @@ -216,6 +214,7 @@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ aext = @aext@ @@ -279,6 +278,7 @@ GENERAL_SOURCES = \ db_local.h \ extern.h \ hash.h \ + ndbm.c \ page.h \ qsort.c @@ -374,12 +374,14 @@ lib.a: $(lib_a_OBJECTS) $(lib_a_DEPENDENCIES) $(EXTRA_lib_a_DEPENDENCIES) clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) - @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \ - dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ - test "$$dir" != "$$p" || dir=.; \ - echo "rm -f \"$${dir}/so_locations\""; \ - rm -f "$${dir}/so_locations"; \ - done + @list='$(noinst_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } libsearch.la: $(libsearch_la_OBJECTS) $(libsearch_la_DEPENDENCIES) $(EXTRA_libsearch_la_DEPENDENCIES) $(libsearch_la_LINK) $(am_libsearch_la_rpath) $(libsearch_la_OBJECTS) $(libsearch_la_LIBADD) $(LIBS) @@ -404,6 +406,12 @@ lib_a-bsearch.o: bsearch.c lib_a-bsearch.obj: bsearch.c $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-bsearch.obj `if test -f 'bsearch.c'; then $(CYGPATH_W) 'bsearch.c'; else $(CYGPATH_W) '$(srcdir)/bsearch.c'; fi` +lib_a-ndbm.o: ndbm.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-ndbm.o `test -f 'ndbm.c' || echo '$(srcdir)/'`ndbm.c + +lib_a-ndbm.obj: ndbm.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-ndbm.obj `if test -f 'ndbm.c'; then $(CYGPATH_W) 'ndbm.c'; else $(CYGPATH_W) '$(srcdir)/ndbm.c'; fi` + lib_a-qsort.o: qsort.c $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-qsort.o `test -f 'qsort.c' || echo '$(srcdir)/'`qsort.c @@ -555,6 +563,20 @@ GTAGS: && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: $(HEADERS) $(SOURCES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags check-am: @@ -665,7 +687,7 @@ uninstall-am: .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ clean-libtool clean-noinstLIBRARIES clean-noinstLTLIBRARIES \ - ctags distclean distclean-compile distclean-generic \ + cscopelist ctags distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags dvi dvi-am html html-am info \ info-am install install-am install-data install-data-am \ install-dvi install-dvi-am install-exec install-exec-am \ From 8a46b8ede22d707aae2dc2e0e53cbad3f26f029f Mon Sep 17 00:00:00 2001 From: Ken Brown Date: Wed, 24 Jul 2019 11:29:53 -0400 Subject: [PATCH 450/475] Cygwin: fhandler_termios::tcsetpgrp: check that argument is non-negative Return -1 with EINVAL if pgid < 0. Previously tcsetpgrp() would blindly go ahead and set the pgid of the controlling terminal to a negative value, causing later calls to various functions to fail. For example, gdb has code like the following: tcsetpgrp (0, getpgid (inf->pid)); If getpgid (inf->pid) fails (returns -1), then this code would set the pgid of fd 0 to -1, so that some later calls to getpgid() would also return -1. This caused the problem reported here: https://cygwin.com/ml/cygwin/2019-07/msg00166.html. --- winsup/cygwin/fhandler_termios.cc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/winsup/cygwin/fhandler_termios.cc b/winsup/cygwin/fhandler_termios.cc index 4ce53433a..5b0ba5603 100644 --- a/winsup/cygwin/fhandler_termios.cc +++ b/winsup/cygwin/fhandler_termios.cc @@ -69,6 +69,11 @@ fhandler_termios::tcsetpgrp (const pid_t pgid) set_errno (EPERM); return -1; } + else if (pgid < 0) + { + set_errno (EINVAL); + return -1; + } int res; while (1) { From 6b843b82a87b4616ba22712ec27b717f61b72630 Mon Sep 17 00:00:00 2001 From: Ken Brown Date: Wed, 24 Jul 2019 14:52:01 -0400 Subject: [PATCH 451/475] Cygwin: document the last bug fix --- winsup/cygwin/release/3.0.8 | 3 +++ 1 file changed, 3 insertions(+) diff --git a/winsup/cygwin/release/3.0.8 b/winsup/cygwin/release/3.0.8 index 11d11db6f..61e3248be 100644 --- a/winsup/cygwin/release/3.0.8 +++ b/winsup/cygwin/release/3.0.8 @@ -14,3 +14,6 @@ Bug Fixes - Don't append ".lnk" when renaming a socket file. Addresses: https://cygwin.com/ml/cygwin/2019-07/msg00139.html + +- Make tcsetpgrp() return -1 if its argument is negative. + Addresses: https://cygwin.com/ml/cygwin/2019-07/msg00166.html From 884b05b54e4595433c85f8ca9820e88b4c723e38 Mon Sep 17 00:00:00 2001 From: Jozef Lawrynowicz Date: Wed, 24 Jul 2019 10:45:49 +0100 Subject: [PATCH 452/475] MSP430: Remove .init/.fini sections The .init/.fini sections are not required for msp430-elf, and add unnecessary code bloat to the CRT library. These sections are specified as "unused" by the MSP430 EABI. .init existed to call __crt0_run_{init,preinit}_array which run through the functions in .{init,preinit}_array. __crt0_run_{init,preinit}_array are already dynamically included like the other crt0 functions, so these can be placed before the call to main, which ensures they are still called if needed. With these functions moved, .init has no purpose and can be removed. .fini existed to call __crt0_run_fini_array. However, the "__msp430_fini" symbol which marks the start of .fini has never been used, so no termination routines have ever been run for msp430. On returning from main(), _exit() is called which just loops forever. So there is no current expectation that __crt0_run_fini_array will get called by the CRT code. Further work is to ensure functions registered with atexit can be optionally called during program termination, and then __crt0_run_fini_array can be registered with atexit during program initialization. The mechanisms for supporting the "-minrt" option have also been removed. "-minrt" enabled a "minimum runtime environment" by removing calls to functions which run global static initializers and constructors. Since this behaviour is now dynamic, and these functions are only included when needed, the minrt versions of the CRT object files are no longer required. --- libgloss/msp430/Makefile.in | 9 +- libgloss/msp430/crt0.S | 165 ++++++++++++-------------------- libgloss/msp430/crtn.S | 41 -------- libgloss/msp430/msp430-sim.ld | 2 - libgloss/msp430/msp430xl-sim.ld | 2 - 5 files changed, 62 insertions(+), 157 deletions(-) delete mode 100644 libgloss/msp430/crtn.S diff --git a/libgloss/msp430/Makefile.in b/libgloss/msp430/Makefile.in index 77c9b8b21..59c11a9a9 100644 --- a/libgloss/msp430/Makefile.in +++ b/libgloss/msp430/Makefile.in @@ -61,7 +61,7 @@ SCRIPTS = $(srcdir)/msp430-sim.ld SCRIPTS += $(srcdir)/msp430xl-sim.ld SCRIPTS += $(srcdir)/intr_vectors.ld -CRT = gcrt0.o crt0.o crt0-minrt.o crtn.o crtn-minrt.o +CRT = gcrt0.o crt0.o SIM_BSP = libsim.a LIB_NOSYS = libnosys.a LIB_CRT = libcrt.a @@ -85,7 +85,6 @@ CRT_OBJS = \ crt_movedata.o \ crt_move_highdata.o \ crt_main.o \ - crt_main_minrt.o \ crt_callexit.o \ crt_run_init_array.o \ crt_run_preinit_array.o \ @@ -102,12 +101,6 @@ all: $(CRT) $(SIM_BSP) $(LIB_NOSYS) $(LIB_CRT) copy_scripts_to_objdir crt_%.o : crt0.S $(CC) -DL$* -Wa,-gdwarf2 -Wa,-I$(srcdir) $(CFLAGS_FOR_TARGET) $(INCLUDES) $(CFLAGS) -c $< -o $@ -crt0-minrt.o : crt0.S - $(CC) -DL0 -DMINRT -Wa,-gdwarf2 -Wa,-I$(srcdir) $(CFLAGS_FOR_TARGET) $(INCLUDES) $(CFLAGS) -c $< -o $@ - -crtn-minrt.o : crtn.S - $(CC) -DL0 -DMINRT -Wa,-gdwarf2 -Wa,-I$(srcdir) $(CFLAGS_FOR_TARGET) $(INCLUDES) $(CFLAGS) -c $< -o $@ - # Override .S.o rule to pass assembler debugging flags .S.o: $(CC) -DL0 -Wa,-gdwarf2 -Wa,-I$(srcdir) $(CFLAGS_FOR_TARGET) $(INCLUDES) $(CFLAGS) -c $< diff --git a/libgloss/msp430/crt0.S b/libgloss/msp430/crt0.S index 42464ddbe..88876cd48 100644 --- a/libgloss/msp430/crt0.S +++ b/libgloss/msp430/crt0.S @@ -52,28 +52,25 @@ __msp430_resetvec_hook: START_CRT_FUNC 0000 start .refsym __msp430_resetvec_hook -#ifdef MINRT - .refsym __crt0_call_just_main -#else - .refsym __crt0_call_init_then_main -#endif + .refsym __crt0_call_main mov_ #__stack, R1 END_CRT_FUNC start #endif -;; Some of the CRT functions below will only be present in the final linked -;; executable if the assembler decides they are needed. It will only define -;; the symbol necessary to prevent them being garbage collected by the linker -;; if the file being assembled has a specific section. -;; The CRT functions this applies to are: -;; init_bss, movedata, move_highdata, init_highbss, run_init_array, -;; run_preinit_array, run_fini_array and run_array. +;; The CRT functions below will only be present in the final linked +;; executable if the assembler decides they are needed. The assembler will +;; only define the symbol necessary to prevent them being garbage collected +;; by the linker if the file being assembled has a specific section, +;; or some other criteria is met. +;; The exception to this is __crt0_call_exit. GCC will include this function +;; if it detects that main() has an epilogue. For example, if main() has a +;; while(1) loop at the end, GCC will not generate an epilogue (since it won't +;; return) and __crt0_call_exit won't be included. #if Lbss -;; Note - this section is only included in the startup code of the -;; application if it is needed. It is responsible for initializing -;; the contents of the .bss section. +;; This function is responsible for initializing the contents of the +;; .bss section. START_CRT_FUNC 0100 init_bss @@ -91,9 +88,8 @@ END_CRT_FUNC init_bss #ifdef __MSP430X_LARGE__ #if Lhigh_bss -;; Note - this section is only included in the startup code of the -;; application if it is needed. It is responsible for initializing -;; the contents of the .upper.bss section. +;; This function is responsible for initializing the contents of the +;; .upper.bss section. START_CRT_FUNC 0200 init_highbss @@ -112,8 +108,7 @@ END_CRT_FUNC init_highbss #if Lmovedata -;; Note - this section is only included in the startup code of the -;; application if it is needed. It is responsible for copying the +;; This function is responsible for copying the ;; contents of the .data section from its load address (in ROM) to ;; its run-time address (in RAM). @@ -136,8 +131,7 @@ END_CRT_FUNC movedata #ifdef __MSP430X_LARGE__ #if Lmove_highdata -;; Note - this section is only included in the startup code of the application -;; if it is needed. It is responsible either for making sure that the +;; This function is responsible for making sure that the ;; contents of the .upper.data section have their correct startup values. ;; If a copy of the .upper.data section is stored in ROM then this means ;; copying the contents into HIFRAM. If a copy of .upper.data is stored in a @@ -175,44 +169,62 @@ END_CRT_FUNC move_highdata #endif /* Lmove_highdata */ #endif /* __MSP430X_LARGE__ */ +#if Lrun_preinit_array +;; This function is responsible for setting up the arguments +;; required for __crt0_run_array, to run the functions in .preinit_array. +START_CRT_FUNC 0500 run_preinit_array -#if Lmain_minrt -;; Note - this section is only included in the startup code of the -;; application if it is needed. It is responsible for just calling -;; main. No initialization code is called first, and main is not -;; expected to return. + mov_ #__preinit_array_start, R4 + mov_ #__preinit_array_end, R5 + mov_ #PTRsz, R6 + call_ #__crt0_run_array -START_CRT_FUNC 0600 call_just_main +END_CRT_FUNC run_preinit_array +#endif /* Lrun_preinit_array */ - clr.w R12 ; Set argc == 0 - call_ #main -END_CRT_FUNC call_just_main -#endif /* Lmain_minrt */ +#if Lrun_init_array +;; This function is responsible for setting up the arguments +;; required for __crt0_run_array, to run the functions in .init_array. +START_CRT_FUNC 0600 run_init_array + mov_ #__init_array_start, R4 + mov_ #__init_array_end, R5 + mov_ #PTRsz, R6 + call_ #__crt0_run_array + +END_CRT_FUNC run_init_array +#endif /* Lrun_init_array */ + +;; FIXME: There are currently no program termination routines executed for +;; msp430. +#if 0 +#if Lrun_fini_array +;; Ensure global C++ destructors in .fini_array are called on exit +;; by registering __crt0_run_fini_array with atexit. +START_CRT_FUNC 0700 register_fini_array + + mov_ #__crt0_run_fini_array, R12 + call_ #atexit + +END_CRT_FUNC register_fini_array +#endif /* Lrun_fini_array */ +#endif /* 0 */ #if Lmain -;; Note - this section is only included in the startup code of the -;; application if it is needed. It is responsible for calling the -;; initialization code - constructors, etc - and then main. If main -;; returns then the following section should be present to catch it. +;; This function is always included and calls main(). -START_CRT_FUNC 0700 call_init_then_main - - call_ #__msp430_init +START_CRT_FUNC 0800 call_main clr.w R12 ; Set argc == 0 call_ #main -END_CRT_FUNC call_init_then_main +END_CRT_FUNC call_main #endif /* Lmain */ - #if Lcallexit -;; Note - this section is only included in the startup code of the -;; application if it is needed. It is responsible for calling exit -;; once main has finished. +;; This function is responsible for calling exit once main has finished. -START_CRT_FUNC 0800 call_exit +START_CRT_FUNC 0900 call_exit call_ #_exit @@ -221,46 +233,15 @@ END_CRT_FUNC call_exit ;---------------------------------------- -#ifndef MINRT - -#if Lrun_preinit_array -;; Note - this section is only included in the startup code of the application -;; if it is needed. It is responsible for setting up the arguments -;; required for __crt0_run_array, to run the functions in .preinit_array. -START_CRT_FUNC 0910 run_preinit_array - - mov_ #__preinit_array_start, R4 - mov_ #__preinit_array_end, R5 - mov_ #PTRsz, R6 - br_ #__crt0_run_array - -END_CRT_FUNC run_preinit_array -#endif /* Lrun_preinit_array */ - -#if Lrun_init_array -;; Note - this section is only included in the startup code of the application -;; if it is needed. It is responsible for setting up the arguments -;; required for __crt0_run_array, to run the functions in .init_array. -START_CRT_FUNC 0920 run_init_array - - mov_ #__init_array_start, R4 - mov_ #__init_array_end, R5 - mov_ #PTRsz, R6 - br_ #__crt0_run_array - -END_CRT_FUNC run_init_array -#endif /* Lrun_init_array */ - #if Lrun_fini_array -;; Note - this section is only included in the startup code of the application -;; if it is needed. It is responsible for setting up the arguments +;; This function is responsible for setting up the arguments ;; required for __crt0_run_array, to run the functions in .fini_array. -START_CRT_FUNC 0930 run_fini_array +START_CRT_FUNC 1000 run_fini_array mov_ #__fini_array_start, R4 mov_ #__fini_array_end, R5 mov_ #-PTRsz, R6 - br_ #__crt0_run_array + call_ #__crt0_run_array END_CRT_FUNC run_fini_array #endif /* Lrun_fini_array */ @@ -268,7 +249,7 @@ END_CRT_FUNC run_fini_array #if Lrun_array ;; Note - this section is only included in the startup code of the application ;; if it is needed by one of the above run_*_array functions. -START_CRT_FUNC 0980 run_array +START_CRT_FUNC 1100 run_array cmp_ R4, R5 jeq _msp430_run_done @@ -282,27 +263,3 @@ END_CRT_FUNC run_array _msp430_run_done: ret_ #endif /* Lrun_array */ - -;---------------------------------------- -#if L0 - - .section .init,"ax" - - .global __msp430_init -__msp430_init: - - .section .fini,"ax" - - .global __msp430_fini -__msp430_fini: - call_ #__crt0_run_fini_array - -;; If this function is not defined externally, we don't need it to do -;; anything. - .text - .weak __crt0_run_fini_array -__crt0_run_fini_array: - ret_ - -#endif -#endif /* not MINRT */ diff --git a/libgloss/msp430/crtn.S b/libgloss/msp430/crtn.S deleted file mode 100644 index 110fc3090..000000000 --- a/libgloss/msp430/crtn.S +++ /dev/null @@ -1,41 +0,0 @@ -/* Copyright (c) 2013 Red Hat, Inc. All rights reserved. - - This copyrighted material is made available to anyone wishing to use, modify, - copy, or redistribute it subject to the terms and conditions of the BSD - License. This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY expressed or implied, including the implied warranties - of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. A copy of this license - is available at http://www.opensource.org/licenses. Any Red Hat trademarks that - are incorporated in the source code or documentation are not subject to the BSD - License and may only be used or replicated with the express permission of - Red Hat, Inc. -*/ - -#include "memmodel.h" - -#ifndef MINRT - .section .init,"ax" - call_ #__crt0_run_preinit_array - call_ #__crt0_run_init_array - ret_ - .global __msp430_init_end -__msp430_init_end: - - .section .fini,"ax" - - ret_ - .global __msp430_fini_end -__msp430_fini_end: - - .text -;; If these functions are not defined externally, we don't need them to do -;; anything. - .balign 2 - .weak __crt0_run_preinit_array - .weak __crt0_run_init_array -__crt0_run_preinit_array: -__crt0_run_init_array: - ret_ - - -#endif diff --git a/libgloss/msp430/msp430-sim.ld b/libgloss/msp430/msp430-sim.ld index 283127465..fadd137e8 100644 --- a/libgloss/msp430/msp430-sim.ld +++ b/libgloss/msp430/msp430-sim.ld @@ -106,8 +106,6 @@ SECTIONS PROVIDE (_etext = .); PROVIDE (etext = .); . = ALIGN(2); - KEEP (*(.init)) - KEEP (*(.fini)) KEEP (*(.tm_clone_table)) } > RAM diff --git a/libgloss/msp430/msp430xl-sim.ld b/libgloss/msp430/msp430xl-sim.ld index cc451b853..125b7d897 100644 --- a/libgloss/msp430/msp430xl-sim.ld +++ b/libgloss/msp430/msp430xl-sim.ld @@ -387,8 +387,6 @@ SECTIONS PROVIDE (_etext = .); PROVIDE (etext = .); . = ALIGN(2); - KEEP (*(.init)) - KEEP (*(.fini)) KEEP (*(.tm_clone_table)) } > ROM From 279805b20b9bbd1f73c50bf9e81dffb254f99fe8 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Wed, 24 Jul 2019 22:32:18 +0200 Subject: [PATCH 453/475] hash functions: use reentrant stat functions _stat64 and _fstat64 are not exported from Cygwin. Use the reentrant analogues, like everywhere else. Signed-off-by: Corinna Vinschen --- newlib/libc/search/hash.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/newlib/libc/search/hash.c b/newlib/libc/search/hash.c index e409618af..c76b157b3 100644 --- a/newlib/libc/search/hash.c +++ b/newlib/libc/search/hash.c @@ -140,9 +140,9 @@ __hash_open (const char *file, new_table = 0; if (!file || (flags & O_TRUNC) || #ifdef __USE_INTERNAL_STAT64 - (_stat64(file, &statbuf) && (errno == ENOENT))) { + (_stat64_r(_REENT, file, &statbuf) && (errno == ENOENT))) { #else - (stat(file, &statbuf) && (errno == ENOENT))) { + (_stat_r(_REENT, file, &statbuf) && (errno == ENOENT))) { #endif if (errno == ENOENT) errno = 0; /* Just in case someone looks at errno */ @@ -156,9 +156,9 @@ __hash_open (const char *file, a new .db file, then reinitialize the database */ if ((flags & O_CREAT) && #ifdef __USE_INTERNAL_STAT64 - _fstat64(hashp->fp, &statbuf) == 0 && statbuf.st_size == 0) + _fstat64_r(_REENT, hashp->fp, &statbuf) == 0 && statbuf.st_size == 0) #else - fstat(hashp->fp, &statbuf) == 0 && statbuf.st_size == 0) + _fstat_r(_REENT, hashp->fp, &statbuf) == 0 && statbuf.st_size == 0) #endif new_table = 1; @@ -341,9 +341,9 @@ init_hash(hashp, file, info) /* Fix bucket size to be optimal for file system */ if (file != NULL) { #ifdef __USE_INTERNAL_STAT64 - if (_stat64(file, &statbuf)) + if (_stat64_r(_REENT, file, &statbuf)) #else - if (stat(file, &statbuf)) + if (_stat_r(_REENT, file, &statbuf)) #endif return (NULL); hashp->BSIZE = MIN(statbuf.st_blksize, MAX_BSIZE); From a13145a30d5c5e8eaf82cdf65c857a248f9b6765 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Wed, 24 Jul 2019 22:05:00 +0200 Subject: [PATCH 454/475] Cygwin: Export newlib ndbm functions Signed-off-by: Corinna Vinschen --- winsup/cygwin/common.din | 10 ++++++++++ winsup/cygwin/include/cygwin/version.h | 4 +++- winsup/cygwin/release/3.1.0 | 2 ++ winsup/doc/new-features.xml | 10 ++++++++++ 4 files changed, 25 insertions(+), 1 deletion(-) diff --git a/winsup/cygwin/common.din b/winsup/cygwin/common.din index 9cb67992b..a7b4aa2b0 100644 --- a/winsup/cygwin/common.din +++ b/winsup/cygwin/common.din @@ -394,6 +394,16 @@ cygwin_stackdump SIGFE cygwin_umount SIGFE cygwin_winpid_to_pid SIGFE daemon SIGFE +dbm_clearerr SIGFE +dbm_close SIGFE +dbm_delete SIGFE +dbm_dirfno SIGFE +dbm_error SIGFE +dbm_fetch SIGFE +dbm_firstkey SIGFE +dbm_nextkey SIGFE +dbm_open SIGFE +dbm_store SIGFE difftime NOSIGFE dirfd SIGFE dirname NOSIGFE diff --git a/winsup/cygwin/include/cygwin/version.h b/winsup/cygwin/include/cygwin/version.h index f47055d84..73d9c7840 100644 --- a/winsup/cygwin/include/cygwin/version.h +++ b/winsup/cygwin/include/cygwin/version.h @@ -511,12 +511,14 @@ details. */ 338: Export secure_getenv. 339: Export sched_getaffinity, sched_setaffinity, pthread_getaffinity_np, pthread_setaffinity_np, __sched_getaffinity_sys. + 340: Export dbm_clearerr, dbm_close, dbm_delete, dbm_dirfno, dbm_error, + dbm_fetch, dbm_firstkey, dbm_nextkey, dbm_open, dbm_store. Note that we forgot to bump the api for ualarm, strtoll, strtoull, sigaltstack, sethostname. */ #define CYGWIN_VERSION_API_MAJOR 0 -#define CYGWIN_VERSION_API_MINOR 339 +#define CYGWIN_VERSION_API_MINOR 340 /* There is also a compatibity version number associated with the shared memory regions. It is incremented when incompatible changes are made to the shared diff --git a/winsup/cygwin/release/3.1.0 b/winsup/cygwin/release/3.1.0 index 3b73a1802..d5d3129c8 100644 --- a/winsup/cygwin/release/3.1.0 +++ b/winsup/cygwin/release/3.1.0 @@ -8,6 +8,8 @@ What's new: - New APIs: sched_getaffinity, sched_setaffinity, pthread_getaffinity_np, pthread_setaffinity_np. +- New APIs: dbm_clearerr, dbm_close, dbm_delete, dbm_dirfno, dbm_error, + dbm_fetch, dbm_firstkey, dbm_nextkey, dbm_open, dbm_store. What changed: ------------- diff --git a/winsup/doc/new-features.xml b/winsup/doc/new-features.xml index 43ca11fef..a5dcfb576 100644 --- a/winsup/doc/new-features.xml +++ b/winsup/doc/new-features.xml @@ -35,6 +35,16 @@ sched_getaffinity, sched_setaffinity, pthread_getaffinity_np, pthread_setaffinity_np. + +New APIs: sched_getaffinity, sched_setaffinity, pthread_getaffinity_np, +pthread_setaffinity_np. + + + +New APIs: dbm_clearerr, dbm_close, dbm_delete, dbm_dirfno, dbm_error, +dbm_fetch, dbm_firstkey, dbm_nextkey, dbm_open, dbm_store. + + From 2232498c712acc97a38fdc297cbe53ba74d0ec2c Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Thu, 25 Jul 2019 10:40:03 +0200 Subject: [PATCH 455/475] Cygwin: Don't change pgid to ctty pgid under debugger _pinfo::set_ctty sets myself's pgid to the ctty pgid if the process has been started from a non-Cygwin process. This isn't the right thing to do when started from GDB. GDB starts the application via standard Windows means, not via Cygwin fork/exec, so it's treated as being a non-Cygwin parent. But we want the app running in it's own process group. So skip this step when running under a debugger Signed-off-by: Corinna Vinschen --- winsup/cygwin/pinfo.cc | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/winsup/cygwin/pinfo.cc b/winsup/cygwin/pinfo.cc index cdbd8bd7e..123784e67 100644 --- a/winsup/cygwin/pinfo.cc +++ b/winsup/cygwin/pinfo.cc @@ -554,7 +554,11 @@ _pinfo::set_ctty (fhandler_termios *fh, int flags) syscall_printf ("attaching %s sid %d, pid %d, pgid %d, tty->pgid %d, tty->sid %d", __ctty (), sid, pid, pgid, tc.getpgid (), tc.getsid ()); if (!cygwin_finished_initializing && !myself->cygstarted - && pgid == pid && tc.getpgid () && tc.getsid ()) + && pgid == pid && tc.getpgid () && tc.getsid () + /* Even GDB starts app via CreateProcess which changes cygstarted. + This results in setting the wrong pgid here, so just skip this + under debugger. */ + && !being_debugged ()) pgid = tc.getpgid (); /* May actually need to do this: From 3a72edc124e7a459ee8a62ebb74b82fe38b8073e Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Wed, 24 Jul 2019 17:48:57 +0200 Subject: [PATCH 456/475] Cygwin: Fix the address of myself Introducing an independent Cygwin PID introduced a regression: The expectation is that the myself pinfo pointer always points to a specific address right in front of the loaded Cygwin DLL. However, the independent Cygwin PID changes broke this. To create myself at the right address requires to call init with h0 set to INVALID_HANDLE_VALUE or an existing address: void pinfo::init (pid_t n, DWORD flag, HANDLE h0) { [...] if (!h0 || myself.h) [...] else { shloc = SH_MYSELF; if (h0 == INVALID_HANDLE_VALUE) <-- !!! h0 = NULL; } The aforementioned commits changed that so h0 was always NULL, this way creating myself at an arbitrary address. This patch makes sure to set the handle to INVALID_HANDLE_VALUE again when creating a new process, so init knows that myself has to be created in the right spot. While at it, fix a potential uninitialized handle value in child_info_spawn::handle_spawn. Fixes: b5e1003722cb ("Cygwin: processes: use dedicated Cygwin PID rather than Windows PID") Fixes: 88605243a19b ("Cygwin: fix child getting another pid after spawnve") Signed-off-by: Corinna Vinschen --- winsup/cygwin/dcrt0.cc | 2 +- winsup/cygwin/pinfo.cc | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/winsup/cygwin/dcrt0.cc b/winsup/cygwin/dcrt0.cc index fb726a739..86ab72564 100644 --- a/winsup/cygwin/dcrt0.cc +++ b/winsup/cygwin/dcrt0.cc @@ -652,7 +652,7 @@ void child_info_spawn::handle_spawn () { extern void fixup_lockf_after_exec (bool); - HANDLE h; + HANDLE h = INVALID_HANDLE_VALUE; if (!dynamically_loaded || get_parent_handle ()) { cygheap_fixup_in_child (true); diff --git a/winsup/cygwin/pinfo.cc b/winsup/cygwin/pinfo.cc index 123784e67..ffd4c8cd9 100644 --- a/winsup/cygwin/pinfo.cc +++ b/winsup/cygwin/pinfo.cc @@ -62,11 +62,10 @@ pinfo::thisproc (HANDLE h) { cygheap->pid = create_cygwin_pid (); flags |= PID_NEW; + h = INVALID_HANDLE_VALUE; } /* spawnve'd process got pid in parent, cygheap->pid has been set in child_info_spawn::handle_spawn. */ - else if (h == INVALID_HANDLE_VALUE) - h = NULL; init (cygheap->pid, flags, h); procinfo->process_state |= PID_IN_USE; From b39cd00f07e8df11c5446fb35da490ef85f12821 Mon Sep 17 00:00:00 2001 From: Vaibhav Gupta Date: Thu, 25 Jul 2019 18:54:50 +0530 Subject: [PATCH 457/475] Port ndbm - Remove Declaration of dbm_forder --- newlib/libc/include/ndbm.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/newlib/libc/include/ndbm.h b/newlib/libc/include/ndbm.h index 6c803702e..c5084b9c2 100644 --- a/newlib/libc/include/ndbm.h +++ b/newlib/libc/include/ndbm.h @@ -79,9 +79,6 @@ int dbm_delete(DBM *, datum); int dbm_error(DBM *); datum dbm_fetch(DBM *, datum); datum dbm_firstkey(DBM *); -#if __BSD_VISIBLE -long dbm_forder(DBM *, datum); -#endif datum dbm_nextkey(DBM *); DBM *dbm_open(const char *, int, mode_t); int dbm_store(DBM *, datum, datum, int); From 65416cca7eda20f70c88efa594938e4c3a347676 Mon Sep 17 00:00:00 2001 From: Richard Earnshaw Date: Fri, 26 Jul 2019 16:08:55 +0100 Subject: [PATCH 458/475] [arm] remove libc/sys/arm/sys/param.h The Arm sys/param.h does not define anything differently to the generic sys/param.h, but fails to define some things that that file provides. There does not appear to be any reason to keep this version and we should revert to using the common version. --- newlib/libc/sys/arm/sys/param.h | 25 ------------------------- 1 file changed, 25 deletions(-) delete mode 100644 newlib/libc/sys/arm/sys/param.h diff --git a/newlib/libc/sys/arm/sys/param.h b/newlib/libc/sys/arm/sys/param.h deleted file mode 100644 index 5b9464cca..000000000 --- a/newlib/libc/sys/arm/sys/param.h +++ /dev/null @@ -1,25 +0,0 @@ -/* ARM configuration file; HZ is 100 rather than the default 60 */ - -#ifndef _SYS_PARAM_H -# define _SYS_PARAM_H - -#include -#include - -#ifndef NBBY -# define NBBY 8 /* number of bits in a byte */ -#endif -#ifndef HZ -# define HZ (60) -#endif -#ifndef NOFILE -# define NOFILE (60) -#endif -#ifndef PATHSIZE -# define PATHSIZE (1024) -#endif - -#define MAX(a,b) ((a) > (b) ? (a) : (b)) -#define MIN(a,b) ((a) < (b) ? (a) : (b)) - -#endif From dea3d8c73e0c38043b7c839cc7d2431f51a03e16 Mon Sep 17 00:00:00 2001 From: Ken Brown Date: Fri, 26 Jul 2019 10:09:23 -0400 Subject: [PATCH 459/475] hash.c: #include This is needed for the prototypes of _stat64 and _fstat64 on Cygwin. Fixes: commit 279805b2 "hash functions: use reentrant stat functions". --- newlib/libc/search/hash.c | 1 + 1 file changed, 1 insertion(+) diff --git a/newlib/libc/search/hash.c b/newlib/libc/search/hash.c index c76b157b3..60fbeb0fd 100644 --- a/newlib/libc/search/hash.c +++ b/newlib/libc/search/hash.c @@ -43,6 +43,7 @@ static char sccsid[] = "@(#)hash.c 8.9 (Berkeley) 6/16/94"; #include +#include #include #include #include From 3e5302714fae99acc8c439f5870846312d081631 Mon Sep 17 00:00:00 2001 From: Joel Sherrill Date: Fri, 26 Jul 2019 14:37:23 -0500 Subject: [PATCH 460/475] common/math_errf.c: Enable compilation of __math_oflowf This resolved linking errors when using methods such as expm1(). --- newlib/libm/common/math_errf.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/newlib/libm/common/math_errf.c b/newlib/libm/common/math_errf.c index e050cdb44..762fc2799 100644 --- a/newlib/libm/common/math_errf.c +++ b/newlib/libm/common/math_errf.c @@ -27,8 +27,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "fdlibm.h" -#if !__OBSOLETE_MATH - #include "math_config.h" #if WANT_ERRNO @@ -53,6 +51,7 @@ xflowf (uint32_t sign, float y) return with_errnof (y, ERANGE); } +#if !__OBSOLETE_MATH HIDDEN float __math_uflowf (uint32_t sign) { @@ -68,6 +67,7 @@ __math_may_uflowf (uint32_t sign) return xflowf (sign, 0x1.4p-75f); } #endif +#endif /* !__OBSOLETE_MATH */ HIDDEN float __math_oflowf (uint32_t sign) @@ -75,6 +75,7 @@ __math_oflowf (uint32_t sign) return xflowf (sign, 0x1p97f); } +#if !__OBSOLETE_MATH HIDDEN float __math_divzerof (uint32_t sign) { From 6661a67747c14cfa7ac91458914037ee296fcd1e Mon Sep 17 00:00:00 2001 From: Faraz Shahbazker Date: Tue, 30 Jul 2019 00:00:25 +0000 Subject: [PATCH 461/475] Align _end symbol to at least 4 in all MIPS scripts Left-over part of commit 84b2a020daa17d8ee5c9ec979c3d56f95e69573b The _end marker must be aligned to 4-bytes to ensure that the last element written does not reach beyond the address of _end. This is also necessary as the termination condition is an equality test instead of an ordered test so (_end - _fbss) must be a multiple of 4-bytes. The alignment is already correct for mti*.ld files, fix it for all remaining MIPS scripts that don't already align to at least 4. --- libgloss/mips/array.ld | 1 + libgloss/mips/ddb-kseg0.ld | 1 + libgloss/mips/ddb.ld | 1 + libgloss/mips/dve.ld | 1 + libgloss/mips/idt.ld | 1 + libgloss/mips/idt32.ld | 1 + libgloss/mips/idt64.ld | 1 + libgloss/mips/idtecoff.ld | 1 + libgloss/mips/jmr3904app-java.ld | 1 + libgloss/mips/jmr3904app.ld | 1 + libgloss/mips/jmr3904dram-java.ld | 1 + libgloss/mips/jmr3904dram.ld | 1 + libgloss/mips/lsi.ld | 1 + libgloss/mips/pmon.ld | 1 + libgloss/mips/sde32.ld | 1 + libgloss/mips/sde64.ld | 1 + 16 files changed, 16 insertions(+) diff --git a/libgloss/mips/array.ld b/libgloss/mips/array.ld index 0492ae550..5cdcf4009 100644 --- a/libgloss/mips/array.ld +++ b/libgloss/mips/array.ld @@ -182,6 +182,7 @@ SECTIONS *(.gnu.linkonce.b.*) *(COMMON) } + . = ALIGN(4); end = .; _end = .; } diff --git a/libgloss/mips/ddb-kseg0.ld b/libgloss/mips/ddb-kseg0.ld index 8c1f926a1..a8643fd7d 100644 --- a/libgloss/mips/ddb-kseg0.ld +++ b/libgloss/mips/ddb-kseg0.ld @@ -135,6 +135,7 @@ SECTIONS *(COMMON) } + . = ALIGN(4); end = .; _end = .; diff --git a/libgloss/mips/ddb.ld b/libgloss/mips/ddb.ld index 299106fb2..7b899d42f 100644 --- a/libgloss/mips/ddb.ld +++ b/libgloss/mips/ddb.ld @@ -135,6 +135,7 @@ SECTIONS *(COMMON) } + . = ALIGN(4); end = .; _end = .; diff --git a/libgloss/mips/dve.ld b/libgloss/mips/dve.ld index 96abbbe32..e28c9c23f 100644 --- a/libgloss/mips/dve.ld +++ b/libgloss/mips/dve.ld @@ -137,6 +137,7 @@ SECTIONS *(COMMON) } + . = ALIGN(4); end = .; _end = .; diff --git a/libgloss/mips/idt.ld b/libgloss/mips/idt.ld index b4608bfbc..a779569e7 100644 --- a/libgloss/mips/idt.ld +++ b/libgloss/mips/idt.ld @@ -143,6 +143,7 @@ SECTIONS *(COMMON) } + . = ALIGN(4); PROVIDE (end = .); _end = .; diff --git a/libgloss/mips/idt32.ld b/libgloss/mips/idt32.ld index 5084df7a6..8d4e4d67a 100644 --- a/libgloss/mips/idt32.ld +++ b/libgloss/mips/idt32.ld @@ -144,6 +144,7 @@ SECTIONS *(COMMON) } + . = ALIGN(4); PROVIDE (end = .); _end = .; diff --git a/libgloss/mips/idt64.ld b/libgloss/mips/idt64.ld index a1121c663..8d996bc32 100644 --- a/libgloss/mips/idt64.ld +++ b/libgloss/mips/idt64.ld @@ -145,6 +145,7 @@ SECTIONS *(COMMON) } + . = ALIGN(4); PROVIDE (end = .); _end = .; diff --git a/libgloss/mips/idtecoff.ld b/libgloss/mips/idtecoff.ld index 0297c6095..57111e139 100644 --- a/libgloss/mips/idtecoff.ld +++ b/libgloss/mips/idtecoff.ld @@ -95,6 +95,7 @@ SECTIONS *(.gnu.linkonce.b.*) *(COMMON) } + . = ALIGN(4); end = .; _end = .; } diff --git a/libgloss/mips/jmr3904app-java.ld b/libgloss/mips/jmr3904app-java.ld index 92de26d06..c9539fde7 100644 --- a/libgloss/mips/jmr3904app-java.ld +++ b/libgloss/mips/jmr3904app-java.ld @@ -99,6 +99,7 @@ SECTIONS . = __stack ; } + . = ALIGN(4); end = .; _end = .; diff --git a/libgloss/mips/jmr3904app.ld b/libgloss/mips/jmr3904app.ld index 367fc471b..35c2fec87 100644 --- a/libgloss/mips/jmr3904app.ld +++ b/libgloss/mips/jmr3904app.ld @@ -137,6 +137,7 @@ SECTIONS . = __stack ; } + . = ALIGN(4); end = .; _end = .; diff --git a/libgloss/mips/jmr3904dram-java.ld b/libgloss/mips/jmr3904dram-java.ld index 4c0681a4b..aedd4340b 100644 --- a/libgloss/mips/jmr3904dram-java.ld +++ b/libgloss/mips/jmr3904dram-java.ld @@ -98,6 +98,7 @@ SECTIONS *(COMMON) } + . = ALIGN(4); end = .; _end = .; diff --git a/libgloss/mips/jmr3904dram.ld b/libgloss/mips/jmr3904dram.ld index 9e7d25545..168c31867 100644 --- a/libgloss/mips/jmr3904dram.ld +++ b/libgloss/mips/jmr3904dram.ld @@ -95,6 +95,7 @@ SECTIONS *(COMMON) } + . = ALIGN(4); end = .; _end = .; diff --git a/libgloss/mips/lsi.ld b/libgloss/mips/lsi.ld index 780c31cac..e350419e7 100644 --- a/libgloss/mips/lsi.ld +++ b/libgloss/mips/lsi.ld @@ -133,6 +133,7 @@ SECTIONS *(.gnu.linkonce.b.*) *(COMMON) } + . = ALIGN(4); end = .; _end = .; } diff --git a/libgloss/mips/pmon.ld b/libgloss/mips/pmon.ld index fff6f6696..1608cd936 100644 --- a/libgloss/mips/pmon.ld +++ b/libgloss/mips/pmon.ld @@ -137,6 +137,7 @@ SECTIONS *(COMMON) } + . = ALIGN(4); end = .; _end = .; diff --git a/libgloss/mips/sde32.ld b/libgloss/mips/sde32.ld index 7273107c1..4ef3b692e 100644 --- a/libgloss/mips/sde32.ld +++ b/libgloss/mips/sde32.ld @@ -144,6 +144,7 @@ SECTIONS *(COMMON) } + . = ALIGN(4); PROVIDE (end = .); _end = .; diff --git a/libgloss/mips/sde64.ld b/libgloss/mips/sde64.ld index 0bcbe98f3..40338a1da 100644 --- a/libgloss/mips/sde64.ld +++ b/libgloss/mips/sde64.ld @@ -146,6 +146,7 @@ SECTIONS *(COMMON) } + . = ALIGN(4); PROVIDE (end = .); _end = .; From 23a779bf3d7c2afc9eab88f6b8727c1db5544547 Mon Sep 17 00:00:00 2001 From: Michael Haubenwallner Date: Wed, 31 Jul 2019 12:35:31 +0200 Subject: [PATCH 462/475] Cygwin: pinfo: stop remember doing reattach During fork, the child process requires the process table to be initialized for fixup_shms_after_fork, while still allowing subsequent dlls.load_after_fork to fail silently (for when the "forkable" hardlinks are not created yet). pinfo::remember not performing reattach anymore requires explicit pinfo::reattach now where appropriate. Prepares to improve "Cygwin: fork: Remember child not before success." commit f03ea8e1c57bd5cea83f6cd47fa02870bdfeb1c5, which leads to fork problems if cygserver is running: https://cygwin.com/ml/cygwin-patches/2019-q2/msg00155.html --- winsup/cygwin/fork.cc | 8 ++++++++ winsup/cygwin/sigproc.cc | 7 +++---- winsup/cygwin/spawn.cc | 4 +++- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/winsup/cygwin/fork.cc b/winsup/cygwin/fork.cc index 59b13806c..0119581df 100644 --- a/winsup/cygwin/fork.cc +++ b/winsup/cygwin/fork.cc @@ -421,6 +421,14 @@ frok::parent (volatile char * volatile stack_here) this_errno = EAGAIN; #ifdef DEBUGGING0 error ("child remember failed"); +#endif + goto cleanup; + } + if (!child.reattach ()) + { + this_errno = EAGAIN; +#ifdef DEBUGGING0 + error ("child reattach failed"); #endif goto cleanup; } diff --git a/winsup/cygwin/sigproc.cc b/winsup/cygwin/sigproc.cc index 900facd58..8003e2db6 100644 --- a/winsup/cygwin/sigproc.cc +++ b/winsup/cygwin/sigproc.cc @@ -216,9 +216,7 @@ proc_subproc (DWORD what, uintptr_t val) vchild->process_state |= PID_INITIALIZING; vchild->ppid = what == PROC_DETACHED_CHILD ? 1 : myself->pid; /* always set last */ } - if (what == PROC_DETACHED_CHILD) - break; - /* fall through intentionally */ + break; case PROC_REATTACH_CHILD: procs[nprocs] = vchild; @@ -873,7 +871,8 @@ void child_info_spawn::wait_for_myself () { postfork (myself); - myself.remember (false); + if (myself.remember (false)) + myself.reattach (); WaitForSingleObject (ev, INFINITE); } diff --git a/winsup/cygwin/spawn.cc b/winsup/cygwin/spawn.cc index 579b3c9c3..7f7af4449 100644 --- a/winsup/cygwin/spawn.cc +++ b/winsup/cygwin/spawn.cc @@ -779,7 +779,9 @@ child_info_spawn::worker (const char *prog_arg, const char *const *argv, child->start_time = time (NULL); /* Register child's starting time. */ child->nice = myself->nice; postfork (child); - if (!child.remember (mode == _P_DETACH)) + if (mode == _P_DETACH + ? !child.remember (true) + : !(child.remember (false) && child.reattach ())) { /* FIXME: Child in strange state now */ CloseHandle (pi.hProcess); From 2986a524d853ab6d06bf88b65e0e9d60cea51dcc Mon Sep 17 00:00:00 2001 From: Michael Haubenwallner Date: Wed, 31 Jul 2019 12:35:33 +0200 Subject: [PATCH 463/475] Cygwin: fork: attach child not before success Do not attach to the child before it was successfully initialized, or we would need more sophisticated cleanup on child initialization failure, like suppressing SIGCHILD delivery with multiple threads ("waitproc") involved. Improves "Cygwin: fork: Remember child not before success.", commit f03ea8e1c57bd5cea83f6cd47fa02870bdfeb1c5, which leads to fork problems if cygserver is running: https://cygwin.com/ml/cygwin-patches/2019-q2/msg00155.html --- winsup/cygwin/fork.cc | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/winsup/cygwin/fork.cc b/winsup/cygwin/fork.cc index 0119581df..7080144b9 100644 --- a/winsup/cygwin/fork.cc +++ b/winsup/cygwin/fork.cc @@ -421,14 +421,6 @@ frok::parent (volatile char * volatile stack_here) this_errno = EAGAIN; #ifdef DEBUGGING0 error ("child remember failed"); -#endif - goto cleanup; - } - if (!child.reattach ()) - { - this_errno = EAGAIN; -#ifdef DEBUGGING0 - error ("child reattach failed"); #endif goto cleanup; } @@ -516,6 +508,17 @@ frok::parent (volatile char * volatile stack_here) } } + /* Do not attach to the child before it has successfully initialized. + Otherwise we may wait forever, or deliver an orphan SIGCHILD. */ + if (!child.reattach ()) + { + this_errno = EAGAIN; +#ifdef DEBUGGING0 + error ("child reattach failed"); +#endif + goto cleanup; + } + /* Finally start the child up. */ resume_child (forker_finished); From 654398db84c689068476e1f06b08f2093c0cc920 Mon Sep 17 00:00:00 2001 From: Kito Cheng Date: Fri, 2 Aug 2019 11:38:09 +0800 Subject: [PATCH 464/475] RISC-V: Fix header guard for sys/fenv.h --- newlib/libc/machine/riscv/sys/fenv.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/newlib/libc/machine/riscv/sys/fenv.h b/newlib/libc/machine/riscv/sys/fenv.h index 1c4342571..e69978dca 100644 --- a/newlib/libc/machine/riscv/sys/fenv.h +++ b/newlib/libc/machine/riscv/sys/fenv.h @@ -9,8 +9,8 @@ http://www.opensource.org/licenses. */ -#ifndef _FENV_H_ -#define _FENV_H_ +#ifndef _SYS_FENV_H +#define _SYS_FENV_H #include @@ -74,4 +74,4 @@ typedef size_t fexcept_t; extern const fenv_t fe_dfl_env; #define FE_DFL_ENV fe_dfl_env_p -#endif /* _FENV_H_ */ +#endif /* _SYS_FENV_H */ From 362b98b49af53496f07c36a8b946a3be584a370e Mon Sep 17 00:00:00 2001 From: Mark Geisert Date: Sun, 4 Aug 2019 15:45:46 -0700 Subject: [PATCH 465/475] Cygwin: Implement CPU_SET(3) macros This patch supplies an implementation of the CPU_SET(3) processor affinity macros as documented on the relevant Linux man page. There is a mostly superset implementation of cpusets under newlib's libc/sys/RTEMS/include/sys that has Linux and FreeBSD compatibility and is built on top of FreeBSD bitsets. This Cygwin implementation and the RTEMS one could be combined if desired at some future point. --- winsup/cygwin/include/sys/cpuset.h | 64 +++++++++++++++++++++++++++++- winsup/cygwin/release/3.1.0 | 2 +- winsup/doc/new-features.xml | 8 +--- 3 files changed, 64 insertions(+), 10 deletions(-) diff --git a/winsup/cygwin/include/sys/cpuset.h b/winsup/cygwin/include/sys/cpuset.h index 4857b879d..2056f6af7 100644 --- a/winsup/cygwin/include/sys/cpuset.h +++ b/winsup/cygwin/include/sys/cpuset.h @@ -18,8 +18,8 @@ typedef __SIZE_TYPE__ __cpu_mask; #define __NCPUBITS (8 * sizeof (__cpu_mask)) // max size of processor group #define __CPU_GROUPMAX (__CPU_SETSIZE / __NCPUBITS) // maximum group number -#define __CPUELT(cpu) ((cpu) / __NCPUBITS) -#define __CPUMASK(cpu) ((__cpu_mask) 1 << ((cpu) % __NCPUBITS)) +#define __CPUELT(cpu) ((cpu) / __NCPUBITS) +#define __CPUMASK(cpu) ((__cpu_mask) 1 << ((cpu) % __NCPUBITS)) typedef struct { @@ -28,6 +28,66 @@ typedef struct int __sched_getaffinity_sys (pid_t, size_t, cpu_set_t *); +/* These macros alloc or free dynamically-sized cpu sets of size 'num' cpus. + Allocations are padded such that full-word operations can be done easily. */ +#define CPU_ALLOC_SIZE(num) ((num+__NCPUBITS-1) / __NCPUBITS) * sizeof (__cpu_mask) +#define CPU_ALLOC(num) __builtin_malloc (CPU_ALLOC_SIZE(num)) +#define CPU_FREE(set) __builtin_free (set) + +/* These _S macros operate on dynamically-sized cpu sets of size 'siz' bytes */ +#define CPU_ZERO_S(siz, set) __builtin_memset (set, 0, siz) + +#define CPU_SET_S(cpu,siz,set) \ + if (cpu < 8 * siz) \ + (set)->__bits[__CPUELT(cpu)] |= __CPUMASK(cpu); + +#define CPU_CLR_S(cpu,siz,set) \ + if (cpu < 8 * siz) \ + (set)->__bits[__CPUELT(cpu)] &= ~(__CPUMASK(cpu)); + +#define CPU_ISSET_S(cpu,siz,set) \ + ({int res = 0; \ + if (cpu < 8 * siz) \ + res = !!((set)->__bits[__CPUELT(cpu)] & __CPUMASK(cpu)); \ + res;}) + +#define CPU_COUNT_S(siz, set) \ + ({int tot = 0;\ + for (int i = 0; i < siz / sizeof (__cpu_mask); i++) \ + tot += __builtin_popcountl ((set)->__bits[i]); \ + tot;}) + +#define CPU_AND_S(siz, dst, src1, src2) \ + for (int i = 0; i < siz / sizeof (__cpu_mask); i++) \ + (dst)->__bits[i] = (src1)->__bits[i] & (src2)->__bits[i]; + +#define CPU_OR_S(siz, dst, src1, src2) \ + for (int i = 0; i < siz / sizeof (__cpu_mask); i++) \ + (dst)->__bits[i] = (src1)->__bits[i] | (src2)->__bits[i]; + +#define CPU_XOR_S(siz, dst, src1, src2) \ + for (int i = 0; i < siz / sizeof (__cpu_mask); i++) \ + (dst)->__bits[i] = (src1)->__bits[i] ^ (src2)->__bits[i]; + +#define CPU_EQUAL_S(siz, src1, src2) \ + ({int res = 1; \ + for (int i = 0; res && i < siz / sizeof (__cpu_mask); i++) \ + res &= (src1)->__bits[i] == (src2)->__bits[i]; \ + res;}) + +/* These macros operate on fixed-size cpu sets of size __CPU_SETSIZE cpus */ +#define CPU_ZERO(set) CPU_ZERO_S(sizeof (cpu_set_t), set) + +#define CPU_SET(cpu, set) CPU_SET_S(cpu, sizeof (cpu_set_t), set) +#define CPU_CLR(cpu, set) CPU_CLR_S(cpu, sizeof (cpu_set_t), set) +#define CPU_ISSET(cpu, set) CPU_ISSET_S(cpu, sizeof (cpu_set_t), set) + +#define CPU_COUNT(set) CPU_COUNT_S(sizeof (cpu_set_t), set) +#define CPU_AND(dst, src1, src2) CPU_AND_S(sizeof (cpu_set_t), dst, src1, src2) +#define CPU_OR(dst, src1, src2) CPU_OR_S(sizeof (cpu_set_t), dst, src1, src2) +#define CPU_XOR(dst, src1, src2) CPU_XOR_S(sizeof (cpu_set_t), dst, src1, src2) +#define CPU_EQUAL(src1, src2) CPU_EQUAL_S(sizeof (cpu_set_t), src1, src2) + #ifdef __cplusplus } #endif diff --git a/winsup/cygwin/release/3.1.0 b/winsup/cygwin/release/3.1.0 index d5d3129c8..2c1e8d2a8 100644 --- a/winsup/cygwin/release/3.1.0 +++ b/winsup/cygwin/release/3.1.0 @@ -6,7 +6,7 @@ What's new: which uses the nearest color from 16 system colors. - New APIs: sched_getaffinity, sched_setaffinity, pthread_getaffinity_np, - pthread_setaffinity_np. + pthread_setaffinity_np, plus CPU_SET macros. - New APIs: dbm_clearerr, dbm_close, dbm_delete, dbm_dirfno, dbm_error, dbm_fetch, dbm_firstkey, dbm_nextkey, dbm_open, dbm_store. diff --git a/winsup/doc/new-features.xml b/winsup/doc/new-features.xml index a5dcfb576..5fee581e7 100644 --- a/winsup/doc/new-features.xml +++ b/winsup/doc/new-features.xml @@ -29,15 +29,9 @@ If a SA_SIGINFO signal handler changes the ucontext_t pointed to by the third parameter, follow it after returning from the handler. - -Support for getting and setting process and thread affinities. New APIs: -sched_getaffinity, sched_setaffinity, pthread_getaffinity_np, -pthread_setaffinity_np. - - New APIs: sched_getaffinity, sched_setaffinity, pthread_getaffinity_np, -pthread_setaffinity_np. +pthread_setaffinity_np, plus CPU_SET macros. From 37e80fbb1c329ab39d154a78fa6d99f28d220dfe Mon Sep 17 00:00:00 2001 From: Alexander Fedotov Date: Fri, 2 Aug 2019 07:33:43 -0500 Subject: [PATCH 466/475] Align libgloss/arm and libc/sys/arm sources: Fix GetCmdLine semihosting directives Applied changes from the commit 9b11672: When simulating arm code, the target program startup code (crt0) uses semihosting invocations to get the command line from the simulator. The simulator returns the command line and its size into the area passed in parameter. (ARM 32-bit specifications : http://infocenter.arm.com/help/topic/com.arm.doc.dui0058d/DUI0058.pdf chapter "5.4.19 SYS_GET_CMDLINE"). The memory area pointed by the semihosting register argument is located in .text section (usually not writtable (RX)). If we run this code on a simulator that respects this rights properties (qemu user-mode for instance), the command line will not be written to the .text program memory, in particular the length of the string. The program runs with an empty command line. This problem hasn't been seen earlier probably because qemu user-mode is not so much used, but this can happen with another simulator that refuse to write in a read-only segment. With this modification, the command line can be correctly passed to the target program. Changes: - newlib/libc/sys/arm/crt0.S : Arguments passed to the AngelSWI_Reason_GetCmdLine semihosting invocation are placed into .data section instead of .text --- newlib/libc/sys/arm/crt0.S | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/newlib/libc/sys/arm/crt0.S b/newlib/libc/sys/arm/crt0.S index 9c262428d..40bbc3d69 100644 --- a/newlib/libc/sys/arm/crt0.S +++ b/newlib/libc/sys/arm/crt0.S @@ -393,13 +393,14 @@ __change_mode: movs r1, r0 #else movs r0, #AngelSWI_Reason_GetCmdLine - adr r1, .LC30 /* Space for command line. */ + ldr r1, .LC30 /* Space for command line. */ #ifdef THUMB_VXM bkpt AngelSWI #else AngelSWIAsm AngelSWI #endif ldr r1, .LC30 + ldr r1, [r1] #endif /* Parse string at r1. */ movs r0, #0 /* Count of arguments so far. */ @@ -586,8 +587,7 @@ change_back: #endif #ifdef ARM_RDI_MONITOR .LC30: - .word CommandLine - .word 255 + .word AngelSWIArgs .LC31: .word __end__ @@ -600,6 +600,9 @@ HeapLimit: .word 0 __stack_base__: .word 0 StackLimit: .word 0 CommandLine: .space 256,0 /* Maximum length of 255 chars handled. */ +AngelSWIArgs: + .word CommandLine + .word 255 #endif #ifdef __pe__ From dfffe683038357d106893ef1ba30462b31e7b589 Mon Sep 17 00:00:00 2001 From: Alexander Fedotov Date: Fri, 2 Aug 2019 07:33:44 -0500 Subject: [PATCH 467/475] Align libgloss/arm and libc/sys/arm sources: HeapInfo and __heap_limit Applied changes from commit 8d98f95: * arm/crt0.S: Initialise __heap_limit when ARM_RDI_MONITOR is defined. * arm/syscalls.c: define __heap_limit global symbol. * arm/syscalls.c (_sbrk): Honour __heap_limit. Applied changes from commit 8d98f95: Fixed semihosting for ARM when heapinfo not provided by debugger --- libgloss/arm/syscalls.c | 12 ++++++------ newlib/libc/sys/arm/crt0.S | 7 +++++++ newlib/libc/sys/arm/syscalls.c | 9 +++++++-- 3 files changed, 20 insertions(+), 8 deletions(-) diff --git a/libgloss/arm/syscalls.c b/libgloss/arm/syscalls.c index dacd1a9d3..3605e0fd0 100644 --- a/libgloss/arm/syscalls.c +++ b/libgloss/arm/syscalls.c @@ -707,15 +707,15 @@ uint __heap_limit = 0xcafedead; void * __attribute__((weak)) _sbrk (ptrdiff_t incr) { - extern char end asm ("end"); /* Defined by the linker. */ + extern char end asm ("end"); /* Defined by the linker. */ static char * heap_end; - char * prev_heap_end; + char * prev_heap_end; if (heap_end == NULL) heap_end = & end; - + prev_heap_end = heap_end; - + if ((heap_end + incr > stack_ptr) /* Honour heap limit if it's valid. */ || (__heap_limit != 0xcafedead && heap_end + incr > (char *)__heap_limit)) @@ -726,14 +726,14 @@ _sbrk (ptrdiff_t incr) extern void abort (void); _write (1, "_sbrk: Heap and stack collision\n", 32); - + abort (); #else errno = ENOMEM; return (void *) -1; #endif } - + heap_end += incr; return (void *) prev_heap_end; diff --git a/newlib/libc/sys/arm/crt0.S b/newlib/libc/sys/arm/crt0.S index 40bbc3d69..a55aa365b 100644 --- a/newlib/libc/sys/arm/crt0.S +++ b/newlib/libc/sys/arm/crt0.S @@ -282,6 +282,13 @@ #endif ldr r0, .LC0 /* Point at values read. */ + /* Set __heap_limit. */ + ldr r1, [r0, #4] + cmp r1, #0 + beq .LC33 + ldr r2, =__heap_limit + str r1, [r2] +.LC33: ldr r1, [r0, #0] cmp r1, #0 bne .LC32 diff --git a/newlib/libc/sys/arm/syscalls.c b/newlib/libc/sys/arm/syscalls.c index b52107491..a2997b44c 100644 --- a/newlib/libc/sys/arm/syscalls.c +++ b/newlib/libc/sys/arm/syscalls.c @@ -487,10 +487,13 @@ _getpid (void) return (pid_t)1; } +/* Heap limit returned from SYS_HEAPINFO Angel semihost call. */ +uint __heap_limit = 0xcafedead; + void * __attribute__((weak)) _sbrk (ptrdiff_t incr) { - extern char end asm ("end"); /* Defined by the linker. */ + extern char end asm ("end"); /* Defined by the linker. */ static char * heap_end; char * prev_heap_end; @@ -499,7 +502,9 @@ _sbrk (ptrdiff_t incr) prev_heap_end = heap_end; - if (heap_end + incr > stack_ptr) + if ((heap_end + incr > stack_ptr) + /* Honour heap limit if it's valid. */ + || (__heap_limit != 0xcafedead && heap_end + incr > (char *)__heap_limit)) { /* Some of the libstdc++-v3 tests rely upon detecting out of memory errors, so do not abort here. */ From bd5596f4fdd8d08966f03057316c1baea754ae4c Mon Sep 17 00:00:00 2001 From: Alexander Fedotov Date: Fri, 2 Aug 2019 07:33:45 -0500 Subject: [PATCH 468/475] Align libgloss/arm and libc/sys/arm sources: Lite exit support Applied changes from commit 2404223: * arm/crt0.S (_mainCRTStartup): Weak reference to atexit and _fini when lite exit is enabled. --- newlib/libc/sys/arm/crt0.S | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/newlib/libc/sys/arm/crt0.S b/newlib/libc/sys/arm/crt0.S index a55aa365b..5e677a23c 100644 --- a/newlib/libc/sys/arm/crt0.S +++ b/newlib/libc/sys/arm/crt0.S @@ -518,8 +518,17 @@ __change_mode: for _fini to be called at program exit. */ movs r4, r0 movs r5, r1 +#ifdef _LITE_EXIT + /* Make reference to atexit weak to avoid unconditionally pulling in + support code. Refer to comments in __atexit.c for more details. */ + .weak FUNCTION(atexit) + ldr r0, .Latexit + cmp r0, #0 + beq .Lweak_atexit +#endif ldr r0, .Lfini bl FUNCTION (atexit) +.Lweak_atexit: bl FUNCTION (_init) movs r0, r4 movs r1, r5 @@ -589,6 +598,13 @@ change_back: .LC2: .word __bss_end__ #ifdef __USES_INITFINI__ +#ifdef _LITE_EXIT +.Latexit: + .word FUNCTION(atexit) + + /* Weak reference _fini in case of lite exit. */ + .weak FUNCTION(_fini) +#endif .Lfini: .word FUNCTION(_fini) #endif From bf56973edc784e875a258ca5e7797423752f1a72 Mon Sep 17 00:00:00 2001 From: Alexander Fedotov Date: Fri, 2 Aug 2019 07:33:46 -0500 Subject: [PATCH 469/475] Align libgloss/arm and libc/sys/arm sources: miscellaneous fixes 1. Trim trailing spaces 2. Align comments, function declarations and definitions --- libgloss/arm/crt0.S | 2 +- libgloss/arm/syscalls.c | 106 ++++++++++++++------------------- newlib/libc/sys/arm/arm.h | 2 +- newlib/libc/sys/arm/syscalls.c | 50 +++++++++++----- 4 files changed, 82 insertions(+), 78 deletions(-) diff --git a/libgloss/arm/crt0.S b/libgloss/arm/crt0.S index 3e740c654..8490bde2f 100644 --- a/libgloss/arm/crt0.S +++ b/libgloss/arm/crt0.S @@ -440,7 +440,7 @@ __change_mode: beq .LC10 /* See whether we are scanning a string. */ - cmp r3, #'"' + cmp r3, #'\"' #ifdef __thumb__ beq .LC20 cmp r3, #'\'' diff --git a/libgloss/arm/syscalls.c b/libgloss/arm/syscalls.c index 3605e0fd0..fc394f94b 100644 --- a/libgloss/arm/syscalls.c +++ b/libgloss/arm/syscalls.c @@ -18,30 +18,30 @@ #include "swi.h" /* Forward prototypes. */ -int _system (const char *); -int _rename (const char *, const char *); -int _isatty (int); +int _system (const char *); +int _rename (const char *, const char *); +int _isatty (int); clock_t _times (struct tms *); -int _gettimeofday (struct timeval *, void *); -int _unlink (const char *); -int _link (const char *, const char *); -int _stat (const char *, struct stat *); -int _fstat (int, struct stat *); +int _gettimeofday (struct timeval *, void *); +int _unlink (const char *); +int _link (const char *, const char *); +int _stat (const char *, struct stat *); +int _fstat (int, struct stat *); int _swistat (int fd, struct stat * st); -void * _sbrk (ptrdiff_t); -pid_t _getpid (void); -int _close (int); -clock_t _clock (void); -int _swiclose (int); -int _open (const char *, int, ...); -int _swiopen (const char *, int); -int _write (int, const void *, size_t); -int _swiwrite (int, const void *, size_t); -_off_t _lseek (int, _off_t, int); -_off_t _swilseek (int, _off_t, int); -int _read (int, void *, size_t); -int _swiread (int, void *, size_t); -void initialise_monitor_handles (void); +void * _sbrk (ptrdiff_t); +pid_t _getpid (void); +int _close (int); +clock_t _clock (void); +int _swiclose (int); +int _open (const char *, int, ...); +int _swiopen (const char *, int); +int _write (int, const void *, size_t); +int _swiwrite (int, const void *, size_t); +_off_t _lseek (int, _off_t, int); +_off_t _swilseek (int, _off_t, int); +int _read (int, void *, size_t); +int _swiread (int, void *, size_t); +void initialise_monitor_handles (void); static int checkerror (int); static int error (int); @@ -143,7 +143,7 @@ initialise_monitor_handles (void) int i; /* Open the standard file descriptors by opening the special - * teletype device, ":tt", read-only to obtain a descritpor for + * teletype device, ":tt", read-only to obtain a descriptor for * standard input and write-only to obtain a descriptor for standard * output. Finally, open ":tt" in append mode to obtain a descriptor * for standard error. Since this is a write mode, most kernels will @@ -154,7 +154,7 @@ initialise_monitor_handles (void) #ifdef ARM_RDI_MONITOR int volatile block[3]; - + block[0] = (int) ":tt"; block[2] = 3; /* length of filename */ block[1] = 0; /* mode "r" */ @@ -351,17 +351,15 @@ checkerror (int result) len, is the length in bytes to read. Returns the number of bytes *not* written. */ int -_swiread (int fh, - void * ptr, - size_t len) +_swiread (int fh, void * ptr, size_t len) { #ifdef ARM_RDI_MONITOR int block[3]; - + block[0] = fh; block[1] = (int) ptr; block[2] = (int) len; - + return checkerror (do_AngelSWI (AngelSWI_Reason_Read, block)); #else register int r0 asm("r0"); @@ -381,9 +379,7 @@ _swiread (int fh, Translates the return of _swiread into bytes read. */ int __attribute__((weak)) -_read (int fd, - void * ptr, - size_t len) +_read (int fd, void * ptr, size_t len) { int res; struct fdent *pfd; @@ -409,9 +405,7 @@ _read (int fd, /* fd, is a user file descriptor. */ off_t -_swilseek (int fd, - off_t ptr, - int dir) +_swilseek (int fd, off_t ptr, int dir) { off_t res; struct fdent *pfd; @@ -447,7 +441,7 @@ _swilseek (int fd, } dir = SEEK_SET; } - + #ifdef ARM_RDI_MONITOR int block[2]; if (dir == SEEK_END) @@ -458,7 +452,7 @@ _swilseek (int fd, return -1; ptr += res; } - + /* This code only does absolute seeks. */ block[0] = pfd->handle; block[1] = (int) ptr; @@ -494,9 +488,7 @@ _swilseek (int fd, } off_t -_lseek (int fd, - off_t ptr, - int dir) +_lseek (int fd, off_t ptr, int dir) { return _swilseek (fd, ptr, dir); } @@ -504,18 +496,15 @@ _lseek (int fd, /* fh, is a valid internal file handle. Returns the number of bytes *not* written. */ int -_swiwrite ( - int fh, - const void * ptr, - size_t len) +_swiwrite (int fh, const void * ptr, size_t len) { #ifdef ARM_RDI_MONITOR int block[3]; - + block[0] = fh; block[1] = (int) ptr; block[2] = (int) len; - + return checkerror (do_AngelSWI (AngelSWI_Reason_Write, block)); #else register int r0 asm("r0"); @@ -533,9 +522,7 @@ _swiwrite ( /* fd, is a user file descriptor. */ int __attribute__((weak)) -_write (int fd, - const void * ptr, - size_t len) +_write (int fd, const void * ptr, size_t len) { int res; struct fdent *pfd; @@ -593,7 +580,7 @@ _swiopen (const char * path, int flags) } } - /* The flags are Unix-style, so we need to convert them. */ + /* The flags are Unix-style, so we need to convert them. */ #ifdef O_BINARY if (flags & O_BINARY) aflags |= 1; @@ -611,25 +598,24 @@ _swiopen (const char * path, int flags) if (flags & O_APPEND) { - /* Can't ask for w AND a; means just 'a'. */ - aflags &= ~4; + aflags &= ~4; /* Can't ask for w AND a; means just 'a'. */ aflags |= 8; } - + #ifdef ARM_RDI_MONITOR block[0] = (int) path; block[2] = strlen (path); block[1] = aflags; - + fh = do_AngelSWI (AngelSWI_Reason_Open, block); - + #else asm ("mov r0,%2; mov r1, %3; swi %a1; mov %0, r0" : "=r"(fh) : "i" (SWI_Open),"r"(path),"r"(aflags) : "r0","r1"); #endif - + /* Return a user file descriptor or an error. */ if (fh >= 0) { @@ -784,13 +770,13 @@ _stat (const char *fname, struct stat *st) { int fd, res; memset (st, 0, sizeof (* st)); - /* The best we can do is try to open the file readonly. - If it exists, then we can guess a few things about it. */ + /* The best we can do is try to open the file readonly. If it exists, + then we can guess a few things about it. */ if ((fd = _open (fname, O_RDONLY)) == -1) return -1; st->st_mode |= S_IFREG | S_IREAD; res = _swistat (fd, st); - /* Not interested in the error. */ + /* Not interested in the error. */ _close (fd); return res; } @@ -880,7 +866,7 @@ _times (struct tms * tp) tp->tms_cutime = 0; /* user time, children */ tp->tms_cstime = 0; /* system time, children */ } - + return timeval; }; diff --git a/newlib/libc/sys/arm/arm.h b/newlib/libc/sys/arm/arm.h index dbed81750..10e5b0509 100644 --- a/newlib/libc/sys/arm/arm.h +++ b/newlib/libc/sys/arm/arm.h @@ -85,6 +85,6 @@ #define CPSR_F_MASK 0x40 /* FIQ bit. */ #define CPSR_I_MASK 0x80 /* IRQ bit. */ -#define CPSR_M_MASK 0x0F /* Mode mask except M[4] */ +#define CPSR_M_MASK 0x0F /* Mode mask except M[4]. */ #endif /* _LIBGLOSS_ARM_H */ diff --git a/newlib/libc/sys/arm/syscalls.c b/newlib/libc/sys/arm/syscalls.c index a2997b44c..1f7222980 100644 --- a/newlib/libc/sys/arm/syscalls.c +++ b/newlib/libc/sys/arm/syscalls.c @@ -114,6 +114,16 @@ void initialise_monitor_handles (void) { int i; + + /* Open the standard file descriptors by opening the special + * teletype device, ":tt", read-only to obtain a descriptor for + * standard input and write-only to obtain a descriptor for standard + * output. Finally, open ":tt" in append mode to obtain a descriptor + * for standard error. Since this is a write mode, most kernels will + * probably return the same value as for standard output, but the + * kernel can differentiate the two using the mode flag and return a + * different descriptor for standard error. + */ #ifdef ARM_RDI_MONITOR int volatile block[3]; @@ -163,11 +173,12 @@ get_errno (void) return do_AngelSWI (AngelSWI_Reason_Errno, NULL); #else register int r0 asm("r0"); - asm ("swi %a1" : "=r"(r0): "i" (SWI_GetErrno)); + asm ("swi %a1" : "=r"(r0) : "i" (SWI_GetErrno)); return r0; #endif } +/* Set errno and return result. */ static int error (int result) { @@ -183,7 +194,10 @@ wrap (int result) return result; } -/* Returns # chars not! written. */ +/* file, is a valid user file handle. + ptr, is a null terminated string. + len, is the length in bytes to read. + Returns the number of bytes *not* written. */ int _swiread (int file, void * ptr, size_t len) { @@ -207,6 +221,9 @@ _swiread (int file, void * ptr, size_t len) #endif } +/* file, is a valid user file handle. + Translates the return of _swiread into + bytes read. */ int __attribute__((weak)) _read (int file, void * ptr, size_t len) { @@ -223,15 +240,13 @@ _read (int file, void * ptr, size_t len) return len - x; } +/* file, is a user file descriptor. */ off_t _swilseek (int file, off_t ptr, int dir) { _off_t res; int fh = remap_handle (file); int slot = findslot (fh); -#ifdef ARM_RDI_MONITOR - int block[2]; -#endif if (dir == SEEK_CUR) { @@ -249,6 +264,7 @@ _swilseek (int file, off_t ptr, int dir) } #ifdef ARM_RDI_MONITOR + int block[2]; if (dir == SEEK_END) { block[0] = fh; @@ -294,7 +310,8 @@ _lseek (int file, off_t ptr, int dir) return wrap (_swilseek (file, ptr, dir)); } -/* Returns #chars not! written. */ +/* file, is a valid internal file handle. + Returns the number of bytes *not* written. */ int _swiwrite (int file, const void * ptr, size_t len) { @@ -319,6 +336,7 @@ _swiwrite (int file, const void * ptr, size_t len) #endif } +/* file, is a user file descriptor. */ int __attribute__((weak)) _write (int file, const void * ptr, size_t len) { @@ -366,7 +384,7 @@ _swiopen (const char * path, int flags) if (flags & O_APPEND) { - aflags &= ~4; /* Can't ask for w AND a; means just 'a'. */ + aflags &= ~4; /* Can't ask for w AND a; means just 'a'. */ aflags |= 8; } @@ -527,7 +545,7 @@ _sbrk (ptrdiff_t incr) extern void memset (struct stat *, int, unsigned int); -int +int __attribute__((weak)) _fstat (int file, struct stat * st) { memset (st, 0, sizeof (* st)); @@ -537,7 +555,8 @@ _fstat (int file, struct stat * st) file = file; } -int _stat (const char *fname, struct stat *st) +int __attribute__((weak)) +_stat (const char *fname, struct stat *st) { int file; @@ -553,20 +572,19 @@ int _stat (const char *fname, struct stat *st) return 0; } -int -_link (const char *__path1 __attribute__ ((unused)), - const char *__path2 __attribute__ ((unused))) +int __attribute__((weak)) +_link (const char *__path1 __attribute__ ((unused)), const char *__path2 __attribute__ ((unused))) { errno = ENOSYS; return -1; } int -_unlink (const char *path __attribute__ ((unused))) +_unlink (const char *path) { #ifdef ARM_RDI_MONITOR int block[2]; - block[0] = (int) path; + block[0] = (int)path; block[1] = strlen(path); return wrap (do_AngelSWI (AngelSWI_Reason_Remove, block)) ? -1 : 0; #else @@ -659,13 +677,13 @@ _system (const char *s) meaning to its return value. Try to do something reasonable.... */ if (!s) return 1; /* maybe there is a shell available? we can hope. :-P */ - block[0] = (int) s; + block[0] = (int)s; block[1] = strlen (s); e = wrap (do_AngelSWI (AngelSWI_Reason_System, block)); if ((e >= 0) && (e < 256)) { /* We have to convert e, an exit status to the encoded status of - the command. To avoid hard coding the exit status, we simply + the command. To avoid hard coding the exit status, we simply loop until we find the right position. */ int exit_code; From 98669a24760a84bfef498fedeef7fa7ecc518e6c Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Tue, 6 Aug 2019 10:46:31 +0200 Subject: [PATCH 470/475] Cygwin: exec: check execute bit prior to evaluating script When the exec family of functions is called for a script-like file, the av::setup function handles the exec[vl]p case as well. The execve case for files not starting with a she-bang is handled first by returning ENOEXEC. Only after that, the file's executability is checked. This leads to the problem that ENOEXEC is returned for non-executable files as well. A calling shell interprets this as a file it should try to run as script. This is not desired for non-executable files. Fix this problem by checking the file for executability first. Only after that, follow the other potential code paths. Signed-off-by: Corinna Vinschen --- winsup/cygwin/spawn.cc | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/winsup/cygwin/spawn.cc b/winsup/cygwin/spawn.cc index 7f7af4449..d95772802 100644 --- a/winsup/cygwin/spawn.cc +++ b/winsup/cygwin/spawn.cc @@ -1172,6 +1172,12 @@ av::setup (const char *prog_arg, path_conv& real_path, const char *ext, } UnmapViewOfFile (buf); just_shell: + /* Check if script is executable. Otherwise we start non-executable + scripts successfully, which is incorrect behaviour. */ + if (real_path.has_acls () + && check_file_access (real_path, X_OK, true) < 0) + return -1; /* errno is already set. */ + if (!pgm) { if (!p_type_exec) @@ -1188,12 +1194,6 @@ av::setup (const char *prog_arg, path_conv& real_path, const char *ext, arg1 = NULL; } - /* Check if script is executable. Otherwise we start non-executable - scripts successfully, which is incorrect behaviour. */ - if (real_path.has_acls () - && check_file_access (real_path, X_OK, true) < 0) - return -1; /* errno is already set. */ - /* Replace argv[0] with the full path to the script if this is the first time through the loop. */ replace0_maybe (prog_arg); From 472fbb8b97d35fc636be059bf733d390b0671f4d Mon Sep 17 00:00:00 2001 From: Michael Haubenwallner Date: Wed, 7 Aug 2019 10:51:16 +0200 Subject: [PATCH 471/475] Cygwin: build_env: fix off-by-one bug when re-adding PATH Adding default winvar 'PATH=C:\cygwin64\binZ' to an environment that is already allocated for 'SYSTEMROOT=ZWINDIR=Z', we need to count that trailing (Z)ero as well. Otherwise we trigger this assertion failure: $ /bin/env -i SYSTEMROOT= WINDIR= /bin/env assertion "(s - envblock) <= tl" failed: file "/home/corinna/src/cygwin/cygwin-3.0.7/cygwin-3.0.7-1.x86_64/src/newlib-cygwin/winsup/cygwin/environ.cc", line 1302, function: char** build_env(const char* const*, WCHAR*&, int&, bool, HANDLE) Aborted (core dumped) --- winsup/cygwin/environ.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/winsup/cygwin/environ.cc b/winsup/cygwin/environ.cc index 124842734..8fa01b2d5 100644 --- a/winsup/cygwin/environ.cc +++ b/winsup/cygwin/environ.cc @@ -1295,7 +1295,7 @@ build_env (const char * const *envp, PWCHAR &envblock, int &envc, during execve. */ if (!saw_PATH) { - new_tl += cygheap->installation_dir.Length / sizeof (WCHAR) + 5; + new_tl += cygheap->installation_dir.Length / sizeof (WCHAR) + 5 + 1; if (new_tl > tl) tl = raise_envblock (new_tl, envblock, s); s = wcpcpy (wcpcpy (s, L"PATH="), From 5fa9a0e7083448ff02e378981dd9a6646fce45a3 Mon Sep 17 00:00:00 2001 From: "Lavrentiev, Anton" Date: Wed, 7 Aug 2019 19:27:41 +0000 Subject: [PATCH 472/475] Cygwin: getpriority() and top display for priority is inconsistent Fix this by aligning /proc/[PID]/stat to the values returned by getpriority(). --- winsup/cygwin/fhandler_process.cc | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/winsup/cygwin/fhandler_process.cc b/winsup/cygwin/fhandler_process.cc index 2a0655475..9527fea7d 100644 --- a/winsup/cygwin/fhandler_process.cc +++ b/winsup/cygwin/fhandler_process.cc @@ -1076,7 +1076,7 @@ format_process_stat (void *data, char *&destbuf) unsigned long fault_count = 0UL, vmsize = 0UL, vmrss = 0UL, vmmaxrss = 0UL; uint64_t utime = 0ULL, stime = 0ULL, start_time = 0ULL; - int priority = 0; + if (p->process_state & PID_EXITED) strcpy (cmd, ""); else @@ -1105,7 +1105,6 @@ format_process_stat (void *data, char *&destbuf) HANDLE hProcess; VM_COUNTERS vmc = { 0 }; KERNEL_USER_TIMES put = { 0 }; - PROCESS_BASIC_INFORMATION pbi = { 0 }; QUOTA_LIMITS ql = { 0 }; SYSTEM_TIMEOFDAY_INFORMATION stodi = { 0 }; @@ -1134,11 +1133,6 @@ format_process_stat (void *data, char *&destbuf) if (!NT_SUCCESS (status)) debug_printf ("NtQueryInformationProcess(ProcessTimes): status %y", status); - status = NtQueryInformationProcess (hProcess, ProcessBasicInformation, - (PVOID) &pbi, sizeof pbi, NULL); - if (!NT_SUCCESS (status)) - debug_printf ("NtQueryInformationProcess(ProcessBasicInformation): " - "status %y", status); status = NtQueryInformationProcess (hProcess, ProcessQuotaLimits, (PVOID) &ql, sizeof ql, NULL); if (!NT_SUCCESS (status)) @@ -1159,17 +1153,11 @@ format_process_stat (void *data, char *&destbuf) * CLOCKS_PER_SEC / NS100PERSEC; else start_time = (p->start_time - to_time_t (&stodi.BootTime)) * CLOCKS_PER_SEC; - /* The BasePriority returned to a 32 bit process under WOW64 is - apparently broken, for 32 and 64 bit target processes. 64 bit - processes get the correct base priority, even for 32 bit processes. */ - if (wincap.is_wow64 ()) - priority = 8; /* Default value. */ - else - priority = pbi.BasePriority; unsigned page_size = wincap.page_size (); vmsize = vmc.PagefileUsage; vmrss = vmc.WorkingSetSize / page_size; vmmaxrss = ql.MaximumWorkingSetSize / page_size; + int nice = winprio_to_nice(GetPriorityClass(hProcess)); destbuf = (char *) crealloc_abort (destbuf, strlen (cmd) + 320); return __small_sprintf (destbuf, "%d (%s) %c " @@ -1181,7 +1169,7 @@ format_process_stat (void *data, char *&destbuf) p->pid, cmd, state, p->ppid, p->pgid, p->sid, p->ctty, -1, 0, fault_count, fault_count, 0, 0, utime, stime, - utime, stime, priority, 0, 0, 0, + utime, stime, NZERO + nice, nice, 0, 0, start_time, vmsize, vmrss, vmmaxrss ); From 1f34405feab107cc5d7b50a023c9407f71eeca62 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Thu, 8 Aug 2019 10:53:58 +0200 Subject: [PATCH 473/475] Cygwin: shmat: use mmap allocator strategy on 64 bit This avoids collisions of shmat maps with Windows own datastructures when allocating top-down. This patch moves the mmap_allocator class definition into its own files and just uses it from mmap and shmat. --- winsup/cygwin/Makefile.in | 1 + winsup/cygwin/mmap.cc | 89 +------------------------------------ winsup/cygwin/mmap_alloc.cc | 79 ++++++++++++++++++++++++++++++++ winsup/cygwin/mmap_alloc.h | 21 +++++++++ winsup/cygwin/shm.cc | 8 +++- 5 files changed, 109 insertions(+), 89 deletions(-) create mode 100644 winsup/cygwin/mmap_alloc.cc create mode 100644 winsup/cygwin/mmap_alloc.h diff --git a/winsup/cygwin/Makefile.in b/winsup/cygwin/Makefile.in index b687d922d..ca0633eb8 100644 --- a/winsup/cygwin/Makefile.in +++ b/winsup/cygwin/Makefile.in @@ -341,6 +341,7 @@ DLL_OFILES:= \ miscfuncs.o \ mktemp.o \ mmap.o \ + mmap_alloc.o \ msg.o \ msgcat.o \ mount.o \ diff --git a/winsup/cygwin/mmap.cc b/winsup/cygwin/mmap.cc index 797373742..d8ef037f0 100644 --- a/winsup/cygwin/mmap.cc +++ b/winsup/cygwin/mmap.cc @@ -20,6 +20,7 @@ details. */ #include "cygheap.h" #include "ntdll.h" #include +#include "mmap_alloc.h" /* __PROT_ATTACH indicates an anonymous mapping which is supposed to be attached to a file mapping for pages beyond the file's EOF. The idea @@ -798,94 +799,6 @@ mmap_worker (mmap_list *map_list, fhandler_base *fh, caddr_t base, size_t len, return base; } -#ifdef __x86_64__ - -/* The memory region used for memory maps */ -#define MMAP_STORAGE_LOW 0x001000000000L /* Leave 32 Gigs for heap. */ -/* Up to Win 8 only supporting 44 bit address space, starting with Win 8.1 - 48 bit address space. */ -#define MMAP_STORAGE_HIGH wincap.mmap_storage_high () - -/* FIXME? Unfortunately the OS doesn't support a top down allocation with - a ceiling value. The ZeroBits mechanism only works for - NtMapViewOfSection and it only evaluates the high bit of ZeroBits - on 64 bit, so it's pretty much useless for our purposes. - - If the below simple mechanism to perform top-down allocations - turns out to be too dumb, we need something else. One idea is to - dived the space in (3835) 4 Gig chunks and simply store the - available free space per slot. Then we can go top down from slot - to slot and only try slots which are supposed to have enough space. - Bookkeeping would be very simple and fast. */ -class mmap_allocator -{ - caddr_t mmap_current_low; - -public: - mmap_allocator () : mmap_current_low ((caddr_t) MMAP_STORAGE_HIGH) {} - - PVOID alloc (PVOID in_addr, SIZE_T in_size, bool fixed) - { - MEMORY_BASIC_INFORMATION mbi; - - SIZE_T size = roundup2 (in_size, wincap.allocation_granularity ()); - /* First check for the given address. */ - if (in_addr) - { - /* If it points to a free area, big enough to fulfill the request, - return the address. */ - if (VirtualQuery (in_addr, &mbi, sizeof mbi) - && mbi.State == MEM_FREE - && mbi.RegionSize >= size) - return in_addr; - /* Otherwise, if MAP_FIXED was given, give up. */ - if (fixed) - return NULL; - /* Otherwise, fall through to the usual free space search mechanism. */ - } - /* Start with the last allocation start address - requested size. */ - caddr_t addr = mmap_current_low - size; - bool merry_go_round = false; - do - { - /* Did we hit the lower ceiling? If so, restart from the upper - ceiling, but note that we did it. */ - if (addr < (caddr_t) MMAP_STORAGE_LOW) - { - addr = (caddr_t) MMAP_STORAGE_HIGH - size; - merry_go_round = true; - } - /* Shouldn't fail, but better test. */ - if (!VirtualQuery ((PVOID) addr, &mbi, sizeof mbi)) - return NULL; - /* If the region is free... */ - if (mbi.State == MEM_FREE) - { - /* ...and the region is big enough to fulfill the request... */ - if (mbi.RegionSize >= size) - { - /* ...note the address as next start address for our simple - merry-go-round and return the address. */ - mmap_current_low = addr; - return (PVOID) addr; - } - /* Otherwise, subtract what's missing in size and try again. */ - addr -= size - mbi.RegionSize; - } - /* If the region isn't free, skip to address below AllocationBase - and try again. */ - else - addr = (caddr_t) mbi.AllocationBase - size; - } - /* Repeat until we had a full ride on the merry_go_round. */ - while (!merry_go_round || addr >= mmap_current_low); - return NULL; - } -}; - -static mmap_allocator mmap_alloc; /* Inherited by forked child. */ -#endif - extern "C" void * mmap64 (void *addr, size_t len, int prot, int flags, int fd, off_t off) { diff --git a/winsup/cygwin/mmap_alloc.cc b/winsup/cygwin/mmap_alloc.cc new file mode 100644 index 000000000..b42bc16e1 --- /dev/null +++ b/winsup/cygwin/mmap_alloc.cc @@ -0,0 +1,79 @@ +#ifdef __x86_64__ + +#include "winsup.h" +#include "mmap_alloc.h" +#include + +/* FIXME? Unfortunately the OS doesn't support a top down allocation with + a ceiling value. The ZeroBits mechanism only works for + NtMapViewOfSection and it only evaluates the high bit of ZeroBits + on 64 bit, so it's pretty much useless for our purposes. + + If the below simple mechanism to perform top-down allocations + turns out to be too dumb, we need something else. One idea is to + dived the space in (3835) 4 Gig chunks and simply store the + available free space per slot. Then we can go top down from slot + to slot and only try slots which are supposed to have enough space. + Bookkeeping would be very simple and fast. */ +PVOID +mmap_allocator::alloc (PVOID in_addr, SIZE_T in_size, bool fixed) +{ + MEMORY_BASIC_INFORMATION mbi; + + SIZE_T size = roundup2 (in_size, wincap.allocation_granularity ()); + /* First check for the given address. */ + if (in_addr) + { + /* If it points to a free area, big enough to fulfill the request, + return the address. */ + if (VirtualQuery (in_addr, &mbi, sizeof mbi) + && mbi.State == MEM_FREE + && mbi.RegionSize >= size) + return in_addr; + /* Otherwise, if MAP_FIXED was given, give up. */ + if (fixed) + return NULL; + /* Otherwise, fall through to the usual free space search mechanism. */ + } + /* Start with the last allocation start address - requested size. */ + caddr_t addr = mmap_current_low - size; + bool merry_go_round = false; + do + { + /* Did we hit the lower ceiling? If so, restart from the upper + ceiling, but note that we did it. */ + if (addr < (caddr_t) MMAP_STORAGE_LOW) + { + addr = (caddr_t) MMAP_STORAGE_HIGH - size; + merry_go_round = true; + } + /* Shouldn't fail, but better test. */ + if (!VirtualQuery ((PVOID) addr, &mbi, sizeof mbi)) + return NULL; + /* If the region is free... */ + if (mbi.State == MEM_FREE) + { + /* ...and the region is big enough to fulfill the request... */ + if (mbi.RegionSize >= size) + { + /* ...note the address as next start address for our simple + merry-go-round and return the address. */ + mmap_current_low = addr; + return (PVOID) addr; + } + /* Otherwise, subtract what's missing in size and try again. */ + addr -= size - mbi.RegionSize; + } + /* If the region isn't free, skip to address below AllocationBase + and try again. */ + else + addr = (caddr_t) mbi.AllocationBase - size; + } + /* Repeat until we had a full ride on the merry_go_round. */ + while (!merry_go_round || addr >= mmap_current_low); + return NULL; +} + +mmap_allocator mmap_alloc; /* Inherited by forked child. */ + +#endif diff --git a/winsup/cygwin/mmap_alloc.h b/winsup/cygwin/mmap_alloc.h new file mode 100644 index 000000000..01c195d52 --- /dev/null +++ b/winsup/cygwin/mmap_alloc.h @@ -0,0 +1,21 @@ +#ifdef __x86_64__ + +/* The memory region used for memory maps */ +#define MMAP_STORAGE_LOW 0x001000000000L /* Leave 32 Gigs for heap. */ +/* Up to Win 8 only supporting 44 bit address space, starting with Win 8.1 + 48 bit address space. */ +#define MMAP_STORAGE_HIGH wincap.mmap_storage_high () + +class mmap_allocator +{ + caddr_t mmap_current_low; + +public: + mmap_allocator () : mmap_current_low ((caddr_t) MMAP_STORAGE_HIGH) {} + + PVOID alloc (PVOID in_addr, SIZE_T in_size, bool fixed); +}; + +extern mmap_allocator mmap_alloc; + +#endif diff --git a/winsup/cygwin/shm.cc b/winsup/cygwin/shm.cc index 805a24b80..40d8dcb10 100644 --- a/winsup/cygwin/shm.cc +++ b/winsup/cygwin/shm.cc @@ -17,6 +17,7 @@ details. */ #include "cygtls.h" #include "sync.h" #include "ntdll.h" +#include "mmap_alloc.h" /* __getpagesize is only available from libcygwin.a */ #undef SHMLBA @@ -220,8 +221,13 @@ shmat (int shmid, const void *shmaddr, int shmflg) return (void *) -1; } NTSTATUS status; - vm_object_t ptr = NULL; SIZE_T viewsize = ssh_entry->size; +#ifdef __x86_64__ + vm_object_t ptr = mmap_alloc.alloc (NULL, viewsize, false); +#else + vm_object_t ptr = NULL; +#endif + ULONG access = (shmflg & SHM_RDONLY) ? PAGE_READONLY : PAGE_READWRITE; status = NtMapViewOfSection (ssh_entry->hdl, NtCurrentProcess (), &ptr, 0, ssh_entry->size, NULL, &viewsize, ViewShare, From 449e9a73d1e7c821331d36b77ebbdbf1fcef6a92 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Fri, 9 Aug 2019 17:47:32 +0200 Subject: [PATCH 474/475] Cygwin: add missing bugfix release messages for 3.1.0 Signed-off-by: Corinna Vinschen --- winsup/cygwin/release/3.1.0 | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/winsup/cygwin/release/3.1.0 b/winsup/cygwin/release/3.1.0 index 2c1e8d2a8..ccb63c317 100644 --- a/winsup/cygwin/release/3.1.0 +++ b/winsup/cygwin/release/3.1.0 @@ -11,6 +11,7 @@ What's new: - New APIs: dbm_clearerr, dbm_close, dbm_delete, dbm_dirfno, dbm_error, dbm_fetch, dbm_firstkey, dbm_nextkey, dbm_open, dbm_store. + What changed: ------------- @@ -42,3 +43,31 @@ Bug Fixes - Fix sigpending() incorrectly returning signals for unrelated threads. Addresses: https://cygwin.com/ml/cygwin/2019-07/msg00051.html + +- Fix a hang when opening a FIFO with O_PATH. + Addresses: https://cygwin.com/ml/cygwin-developers/2019-06/msg00001.html + +- Don't append ".lnk" when renaming a socket file. + Addresses: https://cygwin.com/ml/cygwin/2019-07/msg00139.html + +- Make tcsetpgrp() return -1 if its argument is negative. + Addresses: https://cygwin.com/ml/cygwin/2019-07/msg00166.html + +- Avoid mistakenly moving a process under debugger control into the + process group of the debugger. + Addresses a problem visible in GDB 8.1.1, related to + https://cygwin.com/ml/cygwin/2019-07/msg00166.html + +- Return ENOEXEC from execve for arbitrary files only if the files are + executable. + Addresses: https://cygwin.com/ml/cygwin/2019-08/msg00054.html + +- Fix off-by-one in environment evaluation leading to an abort. + Addresses: https://cygwin.com/ml/cygwin-patches/2019-q3/msg00069.html + +- Make output of /proc/[PID]/stat consistent with getpriority(). + Addresses: https://cygwin.com/ml/cygwin/2019-08/msg00082.html + +- 64 bit only: Avoid collisions between memory maps created with shmat + and Windows datastructures during fork. + Addresses: https://cygwin.com/ml/cygwin/2019-08/msg00107.html From d59c2c9b8276dfef952a28fead438727ddd27e51 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Fri, 9 Aug 2019 17:49:03 +0200 Subject: [PATCH 475/475] Cygwin: drop preliminary 3.0.8 release file Signed-off-by: Corinna Vinschen --- winsup/cygwin/release/3.0.8 | 19 ------------------- 1 file changed, 19 deletions(-) delete mode 100644 winsup/cygwin/release/3.0.8 diff --git a/winsup/cygwin/release/3.0.8 b/winsup/cygwin/release/3.0.8 deleted file mode 100644 index 61e3248be..000000000 --- a/winsup/cygwin/release/3.0.8 +++ /dev/null @@ -1,19 +0,0 @@ -What's new: ------------ - - -What changed: -------------- - - -Bug Fixes ---------- - -- Fix a hang when opening a FIFO with O_PATH. - Addresses: https://cygwin.com/ml/cygwin-developers/2019-06/msg00001.html - -- Don't append ".lnk" when renaming a socket file. - Addresses: https://cygwin.com/ml/cygwin/2019-07/msg00139.html - -- Make tcsetpgrp() return -1 if its argument is negative. - Addresses: https://cygwin.com/ml/cygwin/2019-07/msg00166.html