Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 2 additions & 4 deletions .github/workflows/build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,8 @@ jobs:
shell: msys2 {0}
run: |
# XXX: cygwin still uses gcc v11 so we get new warnings with v13,
# resulting in errors. We can't selectively disable warnigns since our
# cross compiler is also too old and doesn't understand the new
# warning flags, so we need to disable all errors for now.
export CXXFLAGS="-Wno-error -Wno-narrowing"
# resulting in errors due to -Werror. Disable them for now.
export CXXFLAGS="-Wno-error=stringop-truncation -Wno-error=array-bounds -Wno-error=overloaded-virtual -Wno-narrowing -Wno-use-after-free"
(cd winsup && ./autogen.sh)
./configure --disable-dependency-tracking
make -j8
Expand Down
2 changes: 0 additions & 2 deletions winsup/cygwin/fhandler/console.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4344,8 +4344,6 @@ fhandler_console::need_console_handler ()
void
fhandler_console::set_disable_master_thread (bool x, fhandler_console *cons)
{
if (con.disable_master_thread == x)
return;
if (cons == NULL)
{
if (cygheap->ctty && cygheap->ctty->get_major () == DEV_CONS_MAJOR)
Expand Down
120 changes: 76 additions & 44 deletions winsup/cygwin/fhandler/pipe.cc
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ details. */
#include "pinfo.h"
#include "shared_info.h"
#include "tls_pbuf.h"
#include "sigproc.h"
#include <assert.h>

/* This is only to be used for writing. When reading,
Expand Down Expand Up @@ -587,6 +588,17 @@ fhandler_pipe::fixup_after_fork (HANDLE parent)
ReleaseMutex (hdl_cnt_mtx);
}

void
fhandler_pipe::fixup_after_exec ()
{
/* Set read pipe itself always non-blocking for cygwin process.
Blocking/non-blocking is simulated in raw_read(). For write
pipe, follow is_nonblocking(). */
bool mode = get_device () == FH_PIPEW ? is_nonblocking () : true;
set_pipe_non_blocking (mode);
fhandler_base::fixup_after_exec ();
}

int
fhandler_pipe::dup (fhandler_base *child, int flags)
{
Expand Down Expand Up @@ -1207,53 +1219,24 @@ HANDLE
fhandler_pipe::get_query_hdl_per_process (WCHAR *name,
OBJECT_NAME_INFORMATION *ntfn)
{
NTSTATUS status;
ULONG len;
DWORD n_process = 256;
PSYSTEM_PROCESS_INFORMATION spi;
do
{ /* Enumerate processes */
DWORD nbytes = n_process * sizeof (SYSTEM_PROCESS_INFORMATION);
spi = (PSYSTEM_PROCESS_INFORMATION) HeapAlloc (GetProcessHeap (),
0, nbytes);
if (!spi)
return NULL;
status = NtQuerySystemInformation (SystemProcessInformation,
spi, nbytes, &len);
if (NT_SUCCESS (status))
break;
HeapFree (GetProcessHeap (), 0, spi);
n_process *= 2;
}
while (n_process < (1L<<20) && status == STATUS_INFO_LENGTH_MISMATCH);
if (!NT_SUCCESS (status))
return NULL;
winpids pids ((DWORD) 0);

/* In most cases, it is faster to check the processes in reverse order.
To do this, store PIDs into an array. */
DWORD *proc_pids = (DWORD *) HeapAlloc (GetProcessHeap (), 0,
n_process * sizeof (DWORD));
if (!proc_pids)
/* In most cases, it is faster to check the processes in reverse order. */
for (LONG i = (LONG) pids.npids - 1; i >= 0; i--)
{
HeapFree (GetProcessHeap (), 0, spi);
return NULL;
}
PSYSTEM_PROCESS_INFORMATION p = spi;
n_process = 0;
while (true)
{
proc_pids[n_process++] = (DWORD)(intptr_t) p->UniqueProcessId;
if (!p->NextEntryOffset)
break;
p = (PSYSTEM_PROCESS_INFORMATION) ((char *) p + p->NextEntryOffset);
}
HeapFree (GetProcessHeap (), 0, spi);
NTSTATUS status;
ULONG len;

/* Non-cygwin app may call ReadFile() for empty pipe, which makes
NtQueryObject() for ObjectNameInformation block. Therefore, do
not try to get query_hdl for non-cygwin apps. */
_pinfo *p = pids[i];
if (!p || ISSTATE (p, PID_NOTCYGWIN))
continue;

for (LONG i = (LONG) n_process - 1; i >= 0; i--)
{
HANDLE proc = OpenProcess (PROCESS_DUP_HANDLE
| PROCESS_QUERY_INFORMATION,
0, proc_pids[i]);
0, p->dwProcessId);
if (!proc)
continue;

Expand Down Expand Up @@ -1317,7 +1300,6 @@ fhandler_pipe::get_query_hdl_per_process (WCHAR *name,
query_hdl_proc = proc;
query_hdl_value = (HANDLE)(intptr_t) phi->Handles[j].HandleValue;
HeapFree (GetProcessHeap (), 0, phi);
HeapFree (GetProcessHeap (), 0, proc_pids);
return h;
}
close_handle:
Expand All @@ -1327,7 +1309,6 @@ fhandler_pipe::get_query_hdl_per_process (WCHAR *name,
close_proc:
CloseHandle (proc);
}
HeapFree (GetProcessHeap (), 0, proc_pids);
return NULL;
}

Expand Down Expand Up @@ -1401,3 +1382,54 @@ fhandler_pipe::get_query_hdl_per_system (WCHAR *name,
HeapFree (GetProcessHeap (), 0, shi);
return NULL;
}

void
fhandler_pipe::spawn_worker (int fileno_stdin, int fileno_stdout,
int fileno_stderr)
{
bool need_send_noncygchld_sig = false;

/* spawn_worker() is called from spawn.cc only when non-cygwin app
is started. Set pipe mode blocking for the non-cygwin process. */
int fd;
cygheap_fdenum cfd (false);
while ((fd = cfd.next ()) >= 0)
if (cfd->get_dev () == FH_PIPEW
&& (fd == fileno_stdout || fd == fileno_stderr))
{
fhandler_pipe *pipe = (fhandler_pipe *)(fhandler_base *) cfd;
pipe->set_pipe_non_blocking (false);

/* Setup for query_ndl stuff. Read the comment below. */
if (pipe->request_close_query_hdl ())
need_send_noncygchld_sig = true;
}
else if (cfd->get_dev () == FH_PIPER && fd == fileno_stdin)
{
fhandler_pipe *pipe = (fhandler_pipe *)(fhandler_base *) cfd;
pipe->set_pipe_non_blocking (false);
}

/* If multiple writers including non-cygwin app exist, the non-cygwin
app cannot detect pipe closure on the read side when the pipe is
created by system account or the pipe creator is running as service.
This is because query_hdl which is held in write side also is a read
end of the pipe, so the pipe is still alive for the non-cygwin app
even after the reader is closed.

To avoid this problem, let all processes in the same process
group close query_hdl using internal signal __SIGNONCYGCHLD when
non-cygwin app is started. */
if (need_send_noncygchld_sig)
{
tty_min dummy_tty;
dummy_tty.ntty = (fh_devices) myself->ctty;
dummy_tty.pgid = myself->pgid;
tty_min *t = cygwin_shared->tty.get_cttyp ();
if (!t) /* If tty is not allocated, use dummy_tty instead. */
t = &dummy_tty;
/* Emit __SIGNONCYGCHLD to let all processes in the
process group close query_hdl. */
t->kill_pgrp (__SIGNONCYGCHLD);
}
}
3 changes: 3 additions & 0 deletions winsup/cygwin/local_includes/fhandler.h
Original file line number Diff line number Diff line change
Expand Up @@ -1212,6 +1212,7 @@ class fhandler_pipe: public fhandler_pipe_fifo
int open (int flags, mode_t mode = 0);
bool open_setup (int flags);
void fixup_after_fork (HANDLE);
void fixup_after_exec ();
int dup (fhandler_base *child, int);
void set_close_on_exec (bool val);
int close ();
Expand Down Expand Up @@ -1273,6 +1274,8 @@ class fhandler_pipe: public fhandler_pipe_fifo
}
return false;
}
static void spawn_worker (int fileno_stdin, int fileno_stdout,
int fileno_stderr);
};

#define CYGWIN_FIFO_PIPE_NAME_LEN 47
Expand Down
1 change: 0 additions & 1 deletion winsup/cygwin/msys2_path_conv.cc
Original file line number Diff line number Diff line change
Expand Up @@ -366,7 +366,6 @@ path_type find_path_start_and_type(const char** src, int recurse, const char* en
switch (*it) {
case '`':
case '\'':
case '"':
case '*':
case '?':
case '[':
Expand Down
34 changes: 2 additions & 32 deletions winsup/cygwin/spawn.cc
Original file line number Diff line number Diff line change
Expand Up @@ -607,38 +607,8 @@ child_info_spawn::worker (const char *prog_arg, const char *const *argv,
int fileno_stderr = 2;

if (!iscygwin ())
{
bool need_send_sig = false;
int fd;
cygheap_fdenum cfd (false);
while ((fd = cfd.next ()) >= 0)
if (cfd->get_dev () == FH_PIPEW
&& (fd == fileno_stdout || fd == fileno_stderr))
{
fhandler_pipe *pipe = (fhandler_pipe *)(fhandler_base *) cfd;
pipe->set_pipe_non_blocking (false);
if (pipe->request_close_query_hdl ())
need_send_sig = true;
}
else if (cfd->get_dev () == FH_PIPER && fd == fileno_stdin)
{
fhandler_pipe *pipe = (fhandler_pipe *)(fhandler_base *) cfd;
pipe->set_pipe_non_blocking (false);
}

if (need_send_sig)
{
tty_min dummy_tty;
dummy_tty.ntty = (fh_devices) myself->ctty;
dummy_tty.pgid = myself->pgid;
tty_min *t = cygwin_shared->tty.get_cttyp ();
if (!t) /* If tty is not allocated, use dummy_tty instead. */
t = &dummy_tty;
/* Emit __SIGNONCYGCHLD to let all processes in the
process group close query_hdl. */
t->kill_pgrp (__SIGNONCYGCHLD);
}
}
fhandler_pipe::spawn_worker (fileno_stdin, fileno_stdout,
fileno_stderr);

bool no_pcon = mode != _P_OVERLAY && mode != _P_WAIT;
term_spawn_worker.setup (iscygwin (), handle (fileno_stdin, false),
Expand Down