Age | Commit message (Collapse) | Author | Files | Lines |
|
Signed-off-by: Jeremy Drake <cygwin@jdrake.com>
|
|
Partially quoting the LINUX man page:
Open file description locks are advisory byte-range locks whose opera‐
tion is in most respects identical to the traditional record locks de‐
scribed above.
The principal difference between the two lock types is that whereas tra‐
ditional record locks are associated with a process, open file descrip‐
tion locks are associated with the open file description on which they
are acquired, much like locks acquired with flock(2). Consequently (and
unlike traditional advisory record locks), open file description locks
are inherited across fork(2) (and clone(2) with CLONE_FILES), and are
only automatically released on the last close of the open file descrip‐
tion, instead of being released on any close of the file.
Conflicting lock combinations (i.e., a read lock and a write lock or two
write locks) where one lock is an open file description lock and the
other is a traditional record lock conflict even when they are acquired
by the same process on the same file descriptor.
Just like traditional advisory record locks, OFD locks do not conflict
with BSD file locks acquired with flock(2).
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
|
|
This will be used by a followup patch to denote OFD locks per POSIX.
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
|
|
This is in preparation for implementing OFD locks per POSIX.
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
|
|
So far, not setting a lock variant (F_POSIX/F_FLOCK) defaulted to
F_POSIX locks. Adding OFD locks in a followup patch may lead to
confusion, so make sure that the lock variant is always set in the
calling functions (fcntl, flock, lockf). Bail out with EINVAL if
no lock variant is set.
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
|
|
This prevents memory corruption if a newer app or dll is used with an
older cygwin dll. This is an unsupported scenario, but it's still a
good idea to avoid corrupting memory if possible.
Fixes: 7d5c55faa1 ("Cygwin: add wrappers for newer new/delete overloads")
Co-authored-by: Corinna Vinschen <corinna@vinschen.de>
Signed-off-by: Jeremy Drake <cygwin@jdrake.com>
|
|
Signed-off-by: Jeremy Drake <cygwin@jdrake.com>
|
|
A sized delete (with a std::size_t parameter) was added in C++14 (but
doesn't combine with nothrow_t)
An aligned new/delete (with a std::align_val_t parameter) was added in
C++17, and combinations with the sized delete and nothrow_t variants.
Signed-off-by: Jeremy Drake <cygwin@jdrake.com>
|
|
Based on https://sourceware.org/pipermail/cygwin-patches/2025q3/014154.html
suggestion, this patch implements +/-4GB relocations for AArch64 in the mkimport
script by using adrp and ldr instructions. This change required update
in winsup/cygwin/mm/malloc_wrapper.cc where those instructions are
decoded to get target import address.
Signed-off-by: Radek Bartoň <radek.barton@microsoft.com>
|
|
Previously, process_fd failed to correctly handle fhandlers using an
archetype. This was due to the missing PATH_OPEN flag in path_conv,
which caused build_fh_pc() to skip archetype initialization. The
root cause was a bug where open() did not set the PATH_OPEN flag
for fhandlers using an archetype.
This patch introduces a new method, path_conv::set_isopen(), to
explicitly set the PATH_OPEN flag in path_flags in fhandler_base::
open_with_arch().
Addresses: https://cygwin.com/pipermail/cygwin/2025-May/258167.html
Fixes: 92ddb7429065 ("(build_pc_pc): Use fh_alloc to create. Set name from fh->dev if appropriate. Generate an archetype or point to one here.")
Reported-by: Christian Franke <Christian.Franke@t-online.de>
Reviewed-by: Corinna Vinschen <corinna@vinschen.de>
Signed-off-by: Takashi Yano <takashi.yano@nifty.ne.jp>
|
|
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
|
|
Add a FIXME comment to the conversion of private use area bytes to
"normal" bytes in _sys_wcstombs detailing the conversion difference
between _sys_wcstombs and standard wcstombs. It might be a good idea
to drop the conversion to gather compatibility with wcstombs.
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
|
|
When a 4 byte utf-8 sequence has an invalid 4th byte, it's actually
an invalid 3 byte sequence. In this case we already generated the
high surrogate and only realize the problem when byte 4 doesn't
match.
At this point _sys_mbstowcs transposes the invalid 4th byte into the
private use area.
This is wrong. The invalid byte sequence here is the 3 byte sequence
already converted to a high surrogate, not the trailing 4th byte.
Fix this by backtracking to the start of the broken sequence and
overwrite the already written high surrogate with a sequence of
the original three bytes transposed to the private use area. Reset
the mbstate and restart normal conversion at the non-matching
4th byte, which might start a new multibyte sequence.
The resulting wide-char string can be converted back to multibyte
and back again to wide-char, and the result will be identical, even
if the multibyte sequence differs from the original sequence.
Fixes: e44b9069cd227 ("* strfuncs.cc (sys_cp_mbstowcs): Treat src as unsigned char *. Convert failure of f_mbtowc into a single malformed utf-16 value.")
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
|
|
|
|
POSIX states system() shall be thread-safe, however, it is not in
current cygwin. This is because ch_spawn is a global and is shared
between threads. With this patch, system() uses ch_spawn_local
instead which is local variable. popen() has the same problem, so
it has been fixed in the same way.
Addresses: https://cygwin.com/pipermail/cygwin/2025-June/258324.html
Fixes: 1fd5e000ace5 ("import winsup-2000-02-17 snapshot")
Reported-by: Takashi Yano <takashi.yano@nifty.ne.jp>
Reviewed-by: Corinna Vinschen <corinna@vinschen.de>
Signed-off-by: Takashi Yano <takashi.yano@nifty.ne.jp>
|
|
...completion in child process because the cygheap should not be
changed to avoid mismatch between child_info::cygheap_max and
::cygheap_max. Otherwise, child_copy() might copy cygheap being
modified by other process.
In addition, to avoid deadlock, move close_all_files() for non-
Cygwin processes after unlocking cygheap, since close_all_files()
calls cfree(), which attempts to lock cygheap even when it's already
locked.
Fixes: 977ad5434cc0 ("* spawn.cc (spawn_guts): Call refresh_cygheap before creating a new process to ensure that cygheap_max is up-to-date.")
Reviewed-by: Corinna Vinschen <corinna@vinschen.de>
Signed-off-by: Takashi Yano <takashi.yano@nifty.ne.jp>
|
|
...so that cygheap can be locked/unlocked from outside of mm/cygheap.cc.
Reviewed-by: Corinna Vinschen <corinna@vinschen.de>
Signed-off-by: Takashi Yano <takashi.yano@nifty.ne.jp>
|
|
Systems prior to W10 1803 don't have the leapsecs registry key
HKLM\SYSTEM\CurrentControlSet\Control\LeapSecondInformation and
don't handle leap seconds at all.
Given that new leap seconds are a rather seldom, irregular event,
drop reading from /usr/share/zoneinfo/leapseconds. Just read the
same leap second records from a file /etc/leapsecs as stored in
the LeapSeconds registry value on newer systems instead.
As a sidenote, the code reading from /usr/share/zoneinfo/leapseconds
was wrong anyway, because it didn't take the timestamps into account.
Given IERS publishes new leap seconds about 6 months before they
occur, CLOCK_TAI would have been one second off for up to 6 months.
/etc/leapsecs doesn't exist yet, so we just default to 37 secs. If
new leap seconds get provided for newer systems, make sure to provide
the /etc/leapsecs file as part of the Cygwin distro with identical
entries.
Fixes: 2abb929f0ad2 ("Cygwin: clocks: Implement CLOCK_TAI")
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
|
|
Long-standing bug in the sys/termios.h file which, for some reason,
has never been encountered before.
STC:
#include <sys/termios.h>
int main()
{
struct winsize win;
tcgetwinsize (0, &win);
}
Result with gcc 12.4.0:
termios-bug.c: In function ‘main’:
termios-bug.c:7:20: warning: passing argument 2 of ‘tcgetwinsize’ from incompatible pointer type [-Wincompatible-pointer-types]
7 | tcgetwinsize (0, &win);
| ^~~~
| |
| struct winsize *
In file included from termios-bug.c:1:
/usr/include/sys/termios.h:304:42: note: expected ‘struct winsize *’ but argument is of type ‘struct winsize *’
304 | int tcgetwinsize(int fd, struct winsize *winsz);
| ~~~~~~~~~~~~~~~~^~~~~
This warning apparently becomes an error with C23.
The reason is that struct winsize is defined in sys/termios.h after
using it as argument type in function declarations. From the compil;er
perspective it's now a different type , regardless of having the same
name.
Move declaration of struct winsize up so it's defined before being used.
Reported-by: Zachary Santer <zsanter@gmail.com>
Suggested-by: Zachary Santer <zsanter@gmail.com>
Addresses: https://cygwin.com/pipermail/cygwin/2025-July/258474.html
Fixes: 1fd5e000ace55 ("import winsup-2000-02-17 snapshot")
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
|
|
Windows 10 1803 introduced leap seconds support in 2018. The OS always
starts at 37 leap secs. Additional leap second timestamps are added to
the registry key HKLM\SYSTEM\CurrentControlSet\Control\LeapSecondInformation,
value LeapSeconds.
If the key exists, read the leap second timestamps from this value,
otherwise fallback to reading /usr/share/zoneinfo/leapseconds.
Note that we might change the file we read from yet, but that's no part
of this patch.
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
|
|
This patch is required for a followup patch fetching the leap seconds
info from the registry starting with Windows 10 1803.
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
|
|
CLOCK_TAI is like CLOCK_REALTIME ignoring leap secs. Right now,
2025, it has a positive 37 secs offset from CLOCK_REALTIME.
Given the unpredictability of adding leap secs by the IERS
(International Earth Rotation and Reference Systems Service),
we also add a mechanism to read the current leap secs offset from
/usr/share/zoneinfo/leapseconds, part of the tzdata package.
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
|
|
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
|
|
Add CLOCK_REALTIME_COARSE and CLOCK_REALTIME_ALARM to the clocks
allowing an absolute timeout value to be used as such in NtSetTimer.
Fixes: c05df02725c59 ("Cygwin: implement extensible clock interface")
Fixes: 013e2bd9ecf85 ("Cygwin: posix timers: Add support for CLOCK_REALTIME_ALARM/CLOCK_BOOTTIME_ALARM")
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
|
|
The clock init functions checked timer ticks/period for 0 and then
called InterlockedExchange64 if the value was still 0. This is not
quite as atomic as it was supposed to be.
Use InterlockedCompareExchange64 instead.
Fixes: 2b72887ac834b ("Cygwin: clocks: fix a hang on pre-Windows 10 machines")
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
|
|
This patch aspires to provide only minimal changes to
`winsup/cygwin/scripts/gendef` allowing to pass the AArch64 build. It does not
provide any implementations of the generated routines.
Signed-off-by: Radek Bartoň <radek.barton@microsoft.com>
|
|
This patch extracts macros from winsup/cygwin/exceptions.cc serving for portable
register access to context structures into a separate local header
winsup/cygwin/local_includes/register.h and implements their AArch64
counterparts.
Then, it adds AArch64 declaration of __mcontext structure based on
mingw-w64-headers/include/winnt.h header to
winsup/cygwin/include/cygwin/singal.h header.
Then, it includes the registers.h header and uses the macros where applicable,
namely at:
- winsup/cygwin/exceptions.cc
- winsup/cygwin/profil.c
- winsup/cygwin/tread.cc
The motivation is to make usage of the context structures portable without
unnecessary #if defined(__x86_64__) while implementations of signal handling
code will be developed later, e.g. implementation of makecontext.
Signed-off-by: Radek Bartoň <radek.barton@microsoft.com>
|
|
Implements import_address function by decoding adr AArch64 instructions to get target address.
Signed-off-by: Radek Bartoň <radek.barton@microsoft.com>
|
|
_fe_nomask_env is exported by cygwin.din but not used at all for AArch64.
Signed-off-by: Radek Bartoň <radek.barton@microsoft.com>
|
|
This patch ports winsup/cygwin/scripts/mkimport script to AArch64, namely
implements relocation to the imp_sym.
Signed-off-by: Radek Bartoň <radek.barton@microsoft.com>
|
|
Previously, TCIFLUSH flushed the pipe to_slave which transfers
input from master to slave. However, this was not sufficiant.
The master side holds input data before accept_input() in the
read-ahead buffer. So, if input data before 'enter' key can be
leaked into slave input after TCIFLUSH.
With this patch, TCIFLUSH requests master to flush read-ahead
buffer via master control pipe. To realize this, add cmd filed
to pipe_request structure so that the flush request can be
distinguished from existing pipe handle request.
Addresses: https://cygwin.com/pipermail/cygwin/2025-July/258442.html
Fixes: 41946df6111b (" (fhandler_tty_slave::tcflush): Implement input queue flushing by calling read with NULL buffer.")
Reported-by: Christoph Reiter <reiter.christoph@gmail.com>
Signed-off-by: Takashi Yano <takashi.yano@nifty.ne.jp>
|
|
Only try to fix the cached DOS attributes if the caller actually
tried to create the file. Otherwise the fixup code is called even
in cases where we open the file with minimal query access bits and
NtQueryInformationFile() could fail with STATUS_ACCESS_DENIED and
the new cached DOS attributes are wrong again.
Fixes: 37c49decc835f ("Cygwin: open: only fix up cached DOS file attributes for on-disk files")
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
|
|
Previously, it was always applied to "myself", which is only appropriate
in the case of _P_OVERLAY (aka exec). Apply the flag to "myself" only
in that case, and apply it to the new child instead in other cases.
Also, clear the flag from "myself" in the case of a failed exec.
Fixes: 8d8724ee1b5a ("Cygwin: pty: Fix Ctrl-C handling further for non-cygwin apps.")
Signed-off-by: Jeremy Drake <cygwin@jdrake.com>
|
|
This patch defines binutils output binary format for AArch64 which is pei-aarch64-little.
Since =/usr/lib/w32api resolves to $SYSROOT/usr/lib/w32api and Fedora cross-build takes libraries from
/usr/aarch64-pc-cygwin/sys-root/usr/lib/w32api, the SEARCH_DIR("/usr/x86_64-pc-cygwin/lib/w32api"); is
redundant and can be removed.
Signed-off-by: Radek Bartoň <radek.barton@microsoft.com>
|
|
Signed-off-by: Radek Bartoň <radek.barton@microsoft.com>
|
|
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
|
|
Signed-off-by: Radek Bartoň <radek.barton@microsoft.com>
|
|
To fetch heap info for a process in our /proc/PID/maps emulation,
we call RtlQueryProcessDebugInformation on this process since
commit b4966f91396b ("(heap_info::heap_info): Rearrange using
RtlQueryProcessDebugInformation").
However, it turns out that this call can crash the targeted
process, if it's called from multiple threads or processes in
parallel.
Worse, the entire code from creating the debug buffer, over
fetching the debug info, subsequent collecting the information
from said debug buffer, up to destroying the buffer, needs to be
guarded against parallel access.
We do this by adding a global mutex object, serializing access to
the debug info of a process.
Reported-by: Christian Franke <Christian.Franke@t-online.de>
Fixes: b4966f91396b ("(heap_info::heap_info): Rearrange using RtlQueryProcessDebugInformation")
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
|
|
We're using RtlQueryProcessDebugInformation from dlsym since
commit 31ddf45dd8694 ("* autoload.cc (EnumProcessModules): Remove.")
Observations on the Cygwin mailing list show that calling
RtlQueryProcessDebugInformation on a process is neither
thread-safe, nor multi-process-safe, see
https://cygwin.com/pipermail/cygwin/2025-July/258403.html
for details.
This patch essentially reverts 31ddf45dd8694. Fetch the list of
loaded modules in the current process by calling EnumProcessModules
again.
Reported-by: Christian Franke <Christian.Franke@t-online.de>
Fixes: 31ddf45dd8694 ("* autoload.cc (EnumProcessModules): Remove.")
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
|
|
Currently, when cygwin app is launched, the console input mode is
set to tty::cygwin, even if the stdin is not a console. However,
it is not necessary because the cygwin app does not use stdin.
This also applies to stdout and stderr.
With this patch, the console mode is set only when std{in,out,err}
is a console for the cygwin app for better coexistence with non-
cygwin apps.
Signed-off-by: Takashi Yano <takashi.yano@nifty.ne.jp>
|
|
With the commit 476135a24506, set_input_mode() reffers to the flag
disable_master_thread in tty::cygwin mode. So it is necessary to call
set_input_mode() after changing disable_master_thread flag. However,
the commit 476135a24506 was missing that.
With this patch, set_input_mode() is called after changing the flag
disable_master_thread, if the console input mode is tty::cygwin.
Fixes: 476135a24506 ("Cygwin: console: Set ENABLE_PROCESSED_INPUT when disable_master_thread");
Signed-off-by: Takashi Yano <takashi.yano@nifty.ne.jp>
|
|
This patch resolves issues related to unsafe access to deallocated
stack memory in the pthread wrapper for AArch64.
Key changes:
- Removed use of x19 by directly loading the thread function and
argument using LDP from [WRAPPER_ARG], freeing one register.
- Stored thread function and argument in x20 and x21 before
VirtualFree to preserve them across calls.
- Used x1 as a temporary register to load the stack base,
subtract CYGTLS, and update SP.
- Moved the thread argument back into x0 after VirtualFree and
before calling the thread function.
Earlier, `wrapper_arg` lived on the stack, which was freed via
`VirtualFree`, risking segfaults on later access. Now, the thread
`func` and `arg` are loaded before the stack is freed, stored in
callee-saved registers, and restored to `x0` before calling the
thread function.
Fixes: f4ba145056db ("Aarch64: Add inline assembly pthread wrapper")
Signed-off-by: Thirumalai Nagalingam <thirumalai.nagalingam@multicorewareinc.com>
|
|
Currently, ENABLE_PROCESSED_INPUT is set in set_input_mode() if
master_thread_suspended is true. This enables Ctrl-C handling when
cons_master_thread is suspended, since Ctrl-C is normally handled
by cons_master_thread.
However, when disable_master_thread is true, ENABLE_PROCESSED_INPUT
is not set, even though this also disables Ctrl-C handling in
cons_master_thread. Due to this bug, the command
C:\cygwin64\bin\sleep 10 < NUL
in the Command Prompt cannot be terminated with Ctrl-C.
This patch addresses the issue by setting ENABLE_PROCESSED_INPUT
when either disable_master_thread or master_thread_suspended is true.
This bug also affects cases where non-Cygwin Git (Git for Windows)
launches Cygwin SSH. In such cases, SSH also cannot be terminated
with Ctrl-C.
Addresses: https://github.com/git-for-windows/git/issues/5682#issuecomment-2995983695
Fixes: 746c8116dd4f ("Cygwin: console: Allow pasting very long text input.")
Reported-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Takashi Yano <takashi.yano@nifty.ne.jp>
|
|
Fixes: 940dbeffa713 ("Cygwin: pipe: Fix unexpected blocking mode change by pipe_data_available()")
Reported by: Andrew Ng <anng.sw@gmail.com>
Signed-off-by: Takashi Yano <takashi.yano@nifty.ne.jp>
|
|
Signed-off-by: Takashi Yano <takashi.yano@nifty.ne.jp>
|
|
There are tree variables for similar purpose in raw_write(), avail,
chunk, and len1. avail is the amount of writable space in the pipe.
len1 is the data length to attempt to NtWriteFile(). And chunk is
intermediate value to calculate len1 from avail which holds
min(avail, len). Here, chunk has no clear role among them. In fact,
it appears to obscure the intent of the code for the reader.
This patch removes the use of chunk and obtains len1 directly from
avail.
Reviewed-by: Johannes Schindelin <Johannes.Schindelin@gmx.de>
Signed-off-by: Takashi Yano <takashi.yano@nifty.ne.jp>
|
|
ipipe_data_available() is called from raw_write(). If the pipe is in
real_non_blocking_mode at that time, calling pipe_data_available()
can, in some cases, inadvertently revert the pipe to blocking mode.
Here is the background: pipe_data_available() checks the amount of
writable space in the pipe by calling NtQueryInformationFile() with
the FilePipeLocalInformation parameter. However, if the read side of
the pipe is simultaneously consuming data with a large buffer,
NtQueryInformationFile() may return 0 for WriteQuotaAvailable.
As a workaround for this behavior, pipe_data_available() temporarily
attempts to change the pipe-mode to blocking. If the pipe contains
data, this operation fails-indicating that the pipe is full. If it
succeeds, the pipe is considered empty. The problem arises from the
assumption that the pipe is always in real blocking mode before
attempting to flip the mode. However, if raw_write() has already set
the pipe to non-blocking mode due to its failure to determine available
space, two issues occur:
1) Changing to non-blocking mode in pipe_data_available() always
succeeds, since the pipe is already in non-blocking mode.
2) After this, pipe_data_available() sets the pipe back to blocking
mode, unintentionally overriding the non-blocking state required
by raw_write().
This patch addresses the issue by having pipe_data_available() check
the current real blocking mode, temporarily flip the pipe-mode and
then restore the pipe-mode to its original state.
Addresses: https://github.com/git-for-windows/git/issues/5682#issuecomment-2997428207
Fixes: 7ed9adb356df ("Cygwin: pipe: Switch pipe mode to blocking mode by default")
Reported-by: Andrew Ng <andrew.ng@sony.com>
Reviewed-by: Johannes Schindelin <Johannes.Schindelin@gmx.de>
Signed-off-by: Takashi Yano <takashi.yano@nifty.ne.jp>
|
|
... rather than 1 when the pipe space estimation fails, so that
select() and raw_wrie() can perform appropriate fallback handling.
In select(), even if pipe space is unknown, return writable to avoid
deadlock. Even with select() returns writable, write() can blocked
anyway, if data is larger than pipe space. In raw_write(), if the
pipe is real non-blocking mode, attempting to write larger data than
pipe space is safe. Otherwise, return error.
For other cases than FH_PIPEW, PDA_UNKNOWN never orrurs. Therefore,
it is not necessary to handle it in that cases.
Reviewed-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Takashi Yano <takashi.yano@nifty.ne.jp>
|
|
The commit "Cygwin: pipe: Fix SSH hang with non-cygwin pipe reader"
modifies how the amount of writable data is evaluated. This patch
updates the source comments to align with that change.
Reviewed-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Takashi Yano <takashi.yano@nifty.ne.jp>
|
|
If ssh is used with non-cygwin pipe reader, ssh some times hangs.
This happens when non-cygwin git (Git for Windows) starts cygwin
ssh. The background of the bug is as follows.
Before attempting to NtWriteFile() in raw_write() in non-blocking
mode, the amount of writable space in the pipe is checked by calling
NtQueryInformationFile with FilePipeLocalInformation parameter.
The same is also done by pipe_data_available() in select.cc.
However, if the read side of the pipe is simultaneously consuming
data, NtQueryInformationFile() returns less value than the amount
of writable space, i.e. the amount of writable space minus the size
of buffer to be read. This does not happen when the reader is a
cygwin app because cygwin read() for the pipe attempts to read
the amount of the data in the pipe at most. This means NtReadFile()
never enters a pending state. However, if the reader is non-cygwin
app, this cannot be expected. As a workaround for this problem,
the code checking the pipe space temporarily attempts to toggle
the pipe-mode. If the pipe contains data, this operation fails
with STATUS_PIPE_BUSY indicating that the pipe is not empty. If
it succeeds, the pipe is considered empty. The current code uses
this technic only when NtQueryInformationFile() retuns zero.
Therefore, if NtQueryInformationFile() returns 1, the amount of
writable space is assumed to be 1 even in the case that e.g. the
pipe size is 8192 bytes and reader is pending to read 8191 bytes.
Even worse, the current code fails to write more than 1 byte
to 1 byte pipe space due to the remnant of the past design.
Then the reader waits for data with 8191 bytes buffer while the
writer continues to fail to write to 1 byte space of the pipe.
This is the cause of the deadlock.
In practice, when using Git for Windows in combination with Cygwin
SSH, it has been observed that a read of 8191 bytes is occasionally
issued against a pipe with 8192 bytes of available space.
With this patch, the blocking-mode-toggling-check is performed
even if NtQueryInformationFile() returns non-zero value so that
the amount of the writable space in the pipe is always estimated
correctly.
Addresses: https://github.com/git-for-windows/git/issues/5682
Fixes: 7ed9adb356df ("Cygwin: pipe: Switch pipe mode to blocking mode by default")
Reported-by: Vincent-Liem (@github), Johannes Schindelin <johannes.schindelin@gmx.de>
Reviewed-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Takashi Yano <takashi.yano@nifty.ne.jp>
|