After this, we will end up dumping memory regions where:
- state is MEM_COMMIT (i.e. is not MEM_RESERVE or MEM_FREE), and
-- type is MEM_PRIVATE and protection allows reads (i.e. not a guardpage), or
-- type is MEM_IMAGE and protection allows writes
Making this decision based on the current protection isn't 100% correct,
because it may have been changed using VirtualProtect(). But we don't
know how to determine if a region is shareable.
(As a practical matter, anything which gets us the stack (MEM_PRIVATE)
and .data/.bss (RW MEM_IMAGE) is going to be enough for 99% of cases)
Commit 605bdcd410 enabled mapping beyond
EOF in 64 bit environments. But the variable 'orig_len' did not get
rounded up to a multiple of 64K. This rounding was done on 32 bit
only. Fix this by rounding up orig_len on 64 bit, in the same place
where 'len' is rounded up.
Rounding up is needed to make sigbus_page_len a multiple of the
allocation granularity.
In addition, failing to round up could cause orig_len to be smaller
than len. Since these are both unsigned values, the statement
'orig_len -= len' could then cause orig_len to be huge, and mmap would
fail with errno EFBIG.
I observed this failure while debugging the problem reported in
https://sourceware.org/pipermail/cygwin/2020-July/245557.html.
The failure can be seen by running the test case in that report under
gdb or strace.
- After commit 0365031ce1, key input
becomes not working by following steps.
1) Start cmd.exe in mintty.
2) Open another mintty.
3) Execute "echo AAA > /dev/pty*" (pty* is the pty opened in 1.)
This patch fixes the issue.
Use cygwait in take_ownership to allow interruption while waiting to
become owner. Return the cygwait return value or a suitable value to
indicate an error.
raw_read now checks the return value and acts accordingly.
If update_my_handlers fails to duplicate one or more handles, just
mark the corresponding handlers as being in an error state.
But if update_my_handlers is unable to open the process of the
previous owner, it's likely that something serious has gone wrong, so
we continue to make that a fatal error.
When a reader takes ownership in fifo_reader_thread, it now goes
directly to the part of the main loop that listens for a connection.
Previously it went back to the beginning of the loop.
Also, if the reader has to delay taking ownership because the previous
owner has not finished updating the shared fifo_client handlers, it
now checks to see if cancel_evt has been set. Previously it might
have had to spin its wheels unnecessarily only to eventually find that
its thread had been canceled.
Add a bool member 'last_read' to the fifo_client_handler structure,
which is set to true on a successful read. This is used by raw_read
as follows.
When raw_read is called, it first locates the writer (if any) for
which last_read is true. raw_read tries to read from that writer and
returns if there is input available. Otherwise, it proceeds to poll
all the writers, as before.
The effect of this is that if a writer writes some data that is only
partially read, the next attempt to read will continue to read from
the same writer. This should reduce the interleaving of output from
different writers.
When a reader opens, it needs to block if there are no writers open
(unless is is opened with O_NONBLOCK). This is easy for the first
reader to test, since it can just wait for a writer to signal that it
is open (via the write_ready event). But when a second reader wants
to open, all writers might have closed.
To check this, use a new '_nwriters' member of struct fifo_shmem_t,
which keeps track of the number of open writers. This should be more
reliable than the previous method.
Add nwriters_lock to control access to shmem->_nwriters, and remove
reader_opening_lock, which is no longer needed.
Previously only readers had access to the shared memory, but now
writers access it too so that they can increment _nwriters during
open/dup/fork/exec and decrement it during close.
Add an optional 'only_open' argument to create_shmem for use by
writers, which only open the shared memory rather than first trying to
create it. Since writers don't need to access the shared memory until
they have successfully connected to a pipe instance, they can safely
assume that a reader has already created the shared memory.
For debugging purposes, change create_shmem to return 1 instead of 0
when a reader successfully opens the shared memory after finding that
it had already been created.
Remove check_write_ready_evt, write_ready_ok_evt, and
check_write_ready(), which are no longer needed.
When opening a writer and looping to try to get a connection, recheck
read_ready at the top of the loop since the number of readers might
have changed.
To slightly speed up the process of opening the first reader, take
ownership immediately rather than waiting for the fifo_reader_thread
to handle it.
When the owning reader closes and there are still readers open, the
owner needs to wait for a new owner to be found before closing its
fifo_client handlers. This involves a loop in which dec_nreaders is
called at the beginning and inc_nreaders is called at the end. Any
other reader that tries to access shmem->_nreaders during this loop
will therefore get an inaccurate answer.
Fix this by adding an nreaders method and using it instead of
dec_nreaders and inc_nreaders. Also add nreaders_lock to control
access to the shmem->_nreaders.
Make various other changes to improve the reliability of finding a new
owner.
If __HAVE_LOCALE_INFO__ is not defined, then the locale in the
locale-specific ctype functions is ignored. In the previous
implementation this resulted in compiler warnings. For example:
int main()
{
locale_t locale;
locale = duplocale(uselocale((locale_t)0));
isspace_l('x', locale);
return 0;
}
gcc -Wall main.c
main.c: In function 'main':
main.c:6:11: warning: variable 'locale' set but not used [-Wunused-but-set-variable]
6 | locale_t locale;
| ^~~~~~
Since FD_CONNECT is only given once, we manually need to set
FD_WRITE for connection failed sockets to have consistent
behaviour in programs calling poll/select multiple times.
Example test to non-listening port: curl -v 127.0.0.1:47
_ICONV_CONVERTER -> ICONV_FROM_ENCODING. It's not perfect, as the
library can support different from/to encodings now, but at least in
the default configurations the tests now work.
Signed-off-by: Keith Packard <keithp@keithp.com>
This caused the strnstr to walk off the end of the alias array and
fetch invalid data. Instead of attempting to update 'len', just
re-compute it based on the table end pointer that is already known.
Signed-off-by: Keith Packard <keithp@keithp.com>
The pointer value for the iconv alias data never changes, so get rid
of the pointer and make it an array instead.
Signed-off-by: Keith Packard <keithp@keithp.com>
Fix the code checking for character set loading failure so that
it checks the return value from the init function.
Signed-off-by: Keith Packard <keithp@keithp.com>
If the acl_t struct was at or above 0x80000000 then the pointer was
sign-extended to 0xffff_ffff_8000_0000 and so the index was lost.
Signed-off-by: David Allsopp <david.allsopp@metastack.com>
This should slightly speed up especially path conversions,
given there's one less function call rearranging all function
arguments in registers/stack (and less stack pressure).
For clarity, rename overloaded sys_wcstombs to _sys_wcstombs
and sys_cp_mbstowcs to _sys_mbstowcs.
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
Re: CPU microcode reported wrong in /proc/cpuinfo
https://sourceware.org/pipermail/cygwin/2020-May/245063.html
earlier Windows releases used different registry values to store microcode
revisions depending on the MSR name being used to get microcode revisions:
add these alternative registry values to the cpuinfo registry value lookup;
iterate thru the registry data until a valid microcode revision is found;
some revision values are in the high bits, so if the low bits are all clear,
shift the revision value down into the low bits
sys_mbstowcs is called with the destination buffer length
set to MaximumLength from the receiving UNICODE_STRING buffer.
This is twice as much as the actual size of the buffer in
wchar_t units, which is the unit expected by sys_mbstowcs.
sys_mbstowcs always attaches a NUL, within the destination
buffersize given. But if the string is exactly one wchar_t
less than the actual buffer, and the buffersize is given too
large, sys_mbstowcs writes a NUL one wchar_t beyond the buffer.
This has only been exposed with Cygwin 3.1.5 because alloca
on newer gcc 9 apparently allocates more tightly. The alloca
buffer here is requested with 16 bytes, which is exactly the
number of bytes required for the string L"cmd.exe". Older gcc
apparently allocated a few more bytes on the stack, while gcc 9
allocates in 16 byte granularity...
Fix this by giving the correct destination buffer size to
sys_mbstowcs.
Fixes: https://cygwin.com/pipermail/cygwin/2020-June/245226.html
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
In the initial code I missed one level of pointer indirection. Instead
of storing errno in impure_data, _impure_ptr was corrupted.
Only simulator is impacted. Real targets have no OS and no syscalls.
This resolves a bunch of stdio cases from the GCC testsuite:
FAIL->PASS: gcc.c-torture/execute/printf-2.c -O0 execution test
Signed-off-by: Dimitar Dimitrov <dimitar@dinux.eu>