Rename fhandler_pipe_and_fifo::max_atomic_write to pipe_buf_size.
This reflect its actual meaning better. The fhandler_pipe_and_fifo
constructor initializes it to DEFAULT_PIPEBUFSIZE (== 64K), which is
the buffer size for the windows pipes created by fhandler_pipe and
fhandler_fifo. But if we inherit a stdio pipe handle from a
non-Cygwin process, the buffer size could be different.
To remedy this, add a method fhandler_pipe::set_pipe_buf_size that
queries the OS for the pipe buffer size, and use it in
dtable::init_std_file_from_handle.
This is a parent of fhandler_pipe and fhandler_fifo for code that is
common between the two classes. Currently it just contains
max_atomic_write and raw_write(). The latter is identical to what
used to be fhandler_pipe::raw_write().
FILE_PIPE_LOCAL_INFORMATION::WriteQuotaAvailable is unreliable.
Usually WriteQuotaAvailable on the write side reflects the space
available in the inbound buffer on the read side. However, if a
pipe read is currently pending, WriteQuotaAvailable on the write side
is decremented by the number of bytes the read side is requesting.
So it's possible (even likely) that WriteQuotaAvailable is 0, even
if the inbound buffer on the read side is not full. This can lead to
a deadlock situation: The reader is waiting for data, but select
on the writer side assumes that no space is available in the read
side inbound buffer.
This patch implements a workaround by never trying to read more than
half the buffer size blocking if the read buffer is empty. This first
cut tries to take the number of open readers into account by reducing
the amount of requested bytes accordingly.
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
The read handles of pipes created by CreateNamedPipe don't have
FILE_WRITE_ATTRIBUTES access unless the pipe is created with
PIPE_ACCESS_DUPLEX. This causes set_pipe_non_blocking to fail on such
handles. To fix this, add a helper function nt_create, which uses
NtCreateNamedPipeFile instead of CreateNamedPipe and gives us more
flexibility in setting access rights.
Use this helper function in fhandler_pipe::create (fhandler_pipe *[2],
unsigned, int), which is the version of fhandler_pipe::create used by
the pipe and pipe2 system calls.
For convenience, also add a static member function
fhandler_pipe::npfs_handle similar to those used by fhandler_fifo and
fhandler_socket_unix.
Add methods 'set_pipe_non_blocking' and 'fcntl' to keep the blocking
mode of the Windows pipe in sync with that of the fhandler_pipe
object. This applies to pipes created with the 'pipe' and 'pipe2'
system calls.
Previously fhandler_pipe was derived from fhandler_base_overlapped,
which we are going to remove in a future commit. Make minimal changes
so that the build still succeeds.
The check for a file or dir within /dev/mqueue is accidentally using
the incoming path, which could be a relative path. Make sure to
restore the absolute POSIX path in path_copy and only then test the
path.
Also, move the actual check for a valid path below /dev/mqueue into
the fhandler_mqueue class.
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
reuse fhandler_virtual implementation to implement read and lseek.
The output from read(2) is modelled after the output when reading
from an mq file on Linux.
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
The POSIX entry points are just wrappers now, calling into
fhandler_mqueue. While at it, eliminate mqi_flags, replace with
standard fhandler nonblocking flag.
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
The mq_open call is just a framework now. This patch moves the
entire functionality into fhandler_mqueue. To support standard
OS calls (as on Linux), make fhandler_mqueue a derived class from
fhandler_disk_file and keep the base handle the handle to the
default stream, to allow implementing O_PATH functionlaity as well
as reading from the file and NOT reading binary message queue data.
Implement a standard fhandler_mqueue::open method, allowing, for
instance, to touch a file under /dev/mqueue and if it doesn't exist,
to create a message queue file.
FIXME: This introduces a BAD HACK into path_conv::check, which needs
reviewing.
Keep the posix path intact in the fhandler, and change get_proc_fd_name
accordingly to return only the basename plus leading slash for
/proc/<PID>/fd.
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
This encapsulated creation, duplication, and closing of all
Windows objects connected to the message queue in the fhandler.
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
build_fh_dev can take the POSIX object name as parameter anyway,
so use that and drop from mqinfo call.
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
So far, the mqd_t type returned a pointer to an allocated
area under the hood. The mutex and event objects attached
to the message queue were implemented as inheritable types.
As unfortunate side effect the HANDLEs to these objects
were inherited by exec'd child processes, even though all
other message queue properties are not inherted, per POSIX.
Fix this by converting an mqd_t to a descriptor, and create a
matching fhandler_mqueue object to handle various aspects of
the message queues inside the fhandler. Especially, create the
IPC objects as non-inheritable and duplicate the HANDLEs as
part of the fixup_after_fork mechanism.
Drop using mmap and create the memory map with NT functions.
This allows to control duplication of handle and mapping in the
forked child process, without the requirement to regenerate the
map in the same spot. It also allows to dup() the descriptor,
as on Linux, albeit this isn't implemented yet.
This patch is the first cut. There's a bit more to do, like
moving more functionality from the POSIX functions into the
fhandler and making sure the mqd_t type can't be used in other
descriptor-related functions willy-nilly.
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
- Currently, functions/variables regarding the handles for cygwin
apps are with "_cyg", and those of handles for non-cygwin apps
are without "_cyg", such as get_handle_cyg() and get_handle().
This patch renames these to the names without "_nat" and with
"_nat" respectively, such as get_handle() and get_handle_nat().
This was done for the fhandler_socket_local class in commits
3a2191653a, 141437d374, and 477121317d, but the fhandler_socket_unix
class was overlooked.
Previously fstat on a FIFO would call fhandler_base::fstat.
The latter is not appropriate if fhandler_fifo::open has already been
called (and O_PATH is not set), for the following reason. If a FIFO
has been opened as a writer or duplexer, then it has an io_handle that
is a pipe handle rather than a file handle. fhandler_base::fstat will
use this handle and potentially return incorrect results. If the FIFO
has been opened as a reader, then it has no io_handle, and a call to
fhandler_base::fstat will lead to a call to fhandler_base::open.
Opening the fhandler a second time can change it in undesired ways;
for example, it can modify the flags and status_flags.
The new fhandler_fifo::fstat avoids these problems by creating an
fhandler_disk_file and calling its fstat method in case
fhandler_fifo::open has already been called and O_PATH is not set.
This only affects the very seldom bordercase of apps calling setmode(fd,
0) on fhandlers not calling fhandler_base::set_open_status(). All
fhandlers not calling set_open_status() are binary mode only, but the
way reset_to_open_binmode worked, calling setmode(fd, 0) would have
"reset" their open flags to O_TEXT accidentally.
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
- If ENABLE_LINE_INPUT is set, Ctrl-S is handled by Windows if the
OS is Windows 7. This conflicts with Ctrl-S handling in cygwin
console code. This patch unsets ENABLE_LINE_INPUT flag in cygwin
and set it when native app is executed.
- Currently, Ctrl-Z, Ctrl-\ and SIGWINCH does not work in console
if the process does not call read() or select(). This is because
these are processed in process_input_message() which is called
from read() or select(). This is a long standing issue of console.
Addresses:
https://cygwin.com/pipermail/cygwin/2020-May/244898.htmlhttps://cygwin.com/pipermail/cygwin/2021-February/247779.html
With this patch, new thread which handles only input signals is
introduced so that Crtl-Z, etc. work without calling read() or
select(). Ctrl-S and Ctrl-Q are also handled in this thread.
- Currently, input transfer is performed every time one line is read(),
if the non-cygwin app is running in the background. With this patch,
transfer is triggered by setpgid() rather than read() so that the
unnecessary input transfer can be reduced much in that situation.
Analyzing the fhandler::copyto logic shows that the fhandler_base::reset
method was only called from copyto anyway.
Trying to convert reset to a protected method uncovered that the copyto
method is actually thought upside down from an object oriented POV.
Rather than calling copyto, manipulating the object given as parameter,
rename the method to copy_from, which manipulates the calling object
itself with data from the object given as parameter.
Eventually make reset a protected method and rename it to
_copy_from_reset_helper to clarify it's only called from copy_from.
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
- After commit bb428520, there has been the disadvantage:
7) Pseudo console cannot be activated if it is already activated for
another process on same pty.
This patch clears this disadvantage.
- After commit bb428520, there has been the disadvantage:
2) The apps which use console API cannot be debugged with gdb. This
is because pseudo console is not activated since gdb uses
CreateProcess() rather than exec(). Even with this limitation,
attaching gdb to native app, in which pseudo console is already
activated, works.
This patch clears this disadvantage.
- PTY has a problem that the key input, which is typed during windows
native app is running, disappears when it returns to shell. This is
beacuse pty has two input pipes, one is for cygwin apps and the other
one is for native windows apps. The key input during windows native
program is running is sent to the second input pipe while cygwin
shell reads input from the first input pipe. This issue had been
fixed once by commit 29431fcb, however, the new implementation of
pseudo console support by commit bb428520 could not inherit this
feature. This patch realize transfering input data between these
two pipes bidirectionally by utilizing cygwin-console-helper process.
The helper process is launched prior to starting the non-cygwin app,
however, exits immediately unlike previous implementation.
The isdev_dev check in rmdir is unclean. Create a virtual method
fhandler_dev::rmdir to handle this transparently.
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
- The functions pty_master_thread() and pty_master_fwd_thread()
should be static (i.e. should not access class member) because
the instance is deleted if the master is dup()'ed and the first
master is closed. In this case, because the dup()'ed instance
still exists, these master threads are also still alive even
though the instance has been deleted. As a result, accesing
class members in these functions causes accessi violation.
Addresses:
https://cygwin.com/pipermail/cygwin-developers/2021-January/012030.html
- After commit 232fde0e, pty changes console code page when the first
non-cygwin app is executed. If pty is started in real console device,
pty changes the code page of root console. This causes very annoying
result because changing code page changes the font of command prompt
if console is in legacy mode. This patch avoids this by creating a
new invisible console for the first pty started in console device.
- The function close_pseudoconsole() should be static so that it
can be safely called in spawn.cc even after the fhandler_pty_slave
instance has been deleted. That is, there is a problem with the
current code. This patch fixes the issue.
- If application changes the console mode, mode management introduced
by commit 10d8c278 will be corrupted. For example, stdout of jansi
v2.0.1 or later is piped to less, jansi resets the xterm mode flag
ENABLE_VIRTUAL_TERMINA_PROCESSING when jansi is terminated. This
causes garbled output in less because less needs this flag enabled.
This patch fixes the issue.
Replace the 'WCHAR pipe_name_buf[48]' class member by 'PWCHAR
pipe_name_buf', and allocate space for the latter as needed.
Change the default constructor to accommodate this change, and add a
destructor that frees the allocated space.
Also change get_pipe_name and clone to accommodate this change.
Both flags are outdated and collide with official flags in
sys/_default_fcntl.h, which may result in weird misbehaviour
of file functions.
O_NOSYMLINK is not used anyway.
O_DIROPEN is used in fhandler_virtual and derived classes.
The collision with O_NOFOLLOW results in spurious EISDIR
errors when, e. g., reading files in the registry.
fhandler_base::open_fs uses O_DIROPEN in the call to
fhandler_base::open, but it's not used in this context
further down the road.
Drop both flags and create an alternative "diropen" bool
flag in fhandler_virtual.
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
- Pseudo console internally sends escape sequence CSI6n (query cursor
position) on startup of non-cygwin apps. If the terminal does not
support CSI6n, CreateProcess() hangs waiting for response. To prevent
hang, this patch disables pseudo console if the terminal does not
have CSI6n. This is checked on the first execution of non-cygwin
app using the following steps.
1) Check if the terminal support ANSI escape sequences by looking
into terminfo database. If terminfo has cursor_home (ESC [H),
the terminal is supposed to support ANSI escape sequences.
2) If the terminal supports ANSI escape sequneces, send CSI6n for
a test and wait for a responce for 40ms.
3) If there is a responce within 40ms, CSI6n is supposed to be
supported.
Also set-title capability is checked, and removes escape sequence
for setting window title if the terminal does not have the set-
title capability.
- In this implementation, pseudo console is created for each native
console app. Advantages and disadvantages of this implementation
over the previous implementation are as follows.
Advantages:
1) No performance degradation in pty output for cygwin process.
https://cygwin.com/pipermail/cygwin/2020-February/243858.html
2) Free from the problem caused by difference of behaviour of control
sequences between real terminal and pseudo console.
https://cygwin.com/pipermail/cygwin/2019-December/243281.htmlhttps://cygwin.com/pipermail/cygwin/2020-February/243855.html
3) Free from the problem in cgdb and emacs gud.
https://cygwin.com/pipermail/cygwin/2020-January/243601.htmlhttps://cygwin.com/pipermail/cygwin/2020-March/244146.html
4) Redrawing screen on executing native console apps is not necessary.
5) cygwin-console-helper is not necessary for the pseudo console
support.
6) The codes for pseudo console support are much simpler than that
of the previous one.
Disadvantages:
1) The cygwin program which calls console API directly does not work.
2) The apps which use console API cannot be debugged with gdb. This
is because pseudo console is not activated since gdb uses
CreateProcess() rather than exec(). Even with this limitation,
attaching gdb to native apps, in which pseudo console is already
activated, works.
3) Typeahead key inputs are discarded while native console app is
executed. Simirally, typeahead key inputs while cygwin app is
executed are not inherited to native console app.
4) Code page cannot be changed by chcp.com. Acctually, chcp works
itself and changes code page of its own pseudo console. However,
since pseudo console is recreated for another process, it cannot
inherit the code page.
5) system_printf() does not work after stderr is closed. (Same with
cygwin 3.0.7)
6) Startup time of native console apps is about 3 times slower than
previous implemenation.
7) Pseudo console cannot be activated if it is already activated for
another process on same pty.