Don't raise SIGTTIN from poll/select
SIGTTIN should be raised when read() is made on a tty in a backgrounded process, but not when it's tested with poll()/select(). I guess poll()/select() does need to call bg_check(), in order to detect the error conditions that notices (that is, if bg_check() returns bg_eof or bg_error, then fd is ready as an error condition exists) so add an optional parameter to fhandler_base::bg_select() to indicate that signals aren't desired. See https://cygwin.com/ml/cygwin-developers/2016-07/msg00004.html
This commit is contained in:
parent
10a30e7a25
commit
32b668d966
|
@ -427,7 +427,7 @@ public:
|
||||||
{
|
{
|
||||||
return dev ().native ();
|
return dev ().native ();
|
||||||
}
|
}
|
||||||
virtual bg_check_types bg_check (int) {return bg_ok;}
|
virtual bg_check_types bg_check (int, bool = false) {return bg_ok;}
|
||||||
void clear_readahead ()
|
void clear_readahead ()
|
||||||
{
|
{
|
||||||
raixput = raixget = ralen = rabuflen = 0;
|
raixput = raixget = ralen = rabuflen = 0;
|
||||||
|
@ -1233,7 +1233,7 @@ class fhandler_termios: public fhandler_base
|
||||||
void sigflush ();
|
void sigflush ();
|
||||||
int tcgetpgrp ();
|
int tcgetpgrp ();
|
||||||
int tcsetpgrp (int pid);
|
int tcsetpgrp (int pid);
|
||||||
bg_check_types bg_check (int sig);
|
bg_check_types bg_check (int sig, bool dontsignal = false);
|
||||||
virtual DWORD __acquire_output_mutex (const char *fn, int ln, DWORD ms) {return 1;}
|
virtual DWORD __acquire_output_mutex (const char *fn, int ln, DWORD ms) {return 1;}
|
||||||
virtual void __release_output_mutex (const char *fn, int ln) {}
|
virtual void __release_output_mutex (const char *fn, int ln) {}
|
||||||
void echo_erase (int force = 0);
|
void echo_erase (int force = 0);
|
||||||
|
|
|
@ -166,14 +166,43 @@ tty_min::is_orphaned_process_group (int pgid)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
bg_check: check that this process is either in the foreground process group,
|
||||||
|
or if the terminal operation is allowed for processes which are in a
|
||||||
|
background process group.
|
||||||
|
|
||||||
|
If the operation is not permitted by the terminal configuration for processes
|
||||||
|
which are a member of a background process group, return an error or raise a
|
||||||
|
signal as appropriate.
|
||||||
|
|
||||||
|
This handles the following terminal operations:
|
||||||
|
|
||||||
|
write: sig = SIGTTOU
|
||||||
|
read: sig = SIGTTIN
|
||||||
|
change terminal settings: sig = -SIGTTOU
|
||||||
|
(tcsetattr, tcsetpgrp, etc.)
|
||||||
|
peek (poll, select): sig = SIGTTIN, dontsignal = TRUE
|
||||||
|
*/
|
||||||
bg_check_types
|
bg_check_types
|
||||||
fhandler_termios::bg_check (int sig)
|
fhandler_termios::bg_check (int sig, bool dontsignal)
|
||||||
{
|
{
|
||||||
|
/* Ignore errors:
|
||||||
|
- this process isn't in a process group
|
||||||
|
- tty is invalid
|
||||||
|
|
||||||
|
Everything is ok if:
|
||||||
|
- this process is in the foreground process group, or
|
||||||
|
- this tty is not the controlling tty for this process (???), or
|
||||||
|
- writing, when TOSTOP TTY mode is not set on this tty
|
||||||
|
*/
|
||||||
if (!myself->pgid || !tc () || tc ()->getpgid () == myself->pgid ||
|
if (!myself->pgid || !tc () || tc ()->getpgid () == myself->pgid ||
|
||||||
myself->ctty != tc ()->ntty ||
|
myself->ctty != tc ()->ntty ||
|
||||||
((sig == SIGTTOU) && !(tc ()->ti.c_lflag & TOSTOP)))
|
((sig == SIGTTOU) && !(tc ()->ti.c_lflag & TOSTOP)))
|
||||||
return bg_ok;
|
return bg_ok;
|
||||||
|
|
||||||
|
/* sig -SIGTTOU is used to indicate a change to terminal settings, where
|
||||||
|
TOSTOP TTY mode isn't considered when determining if we need to send a
|
||||||
|
signal. */
|
||||||
if (sig < 0)
|
if (sig < 0)
|
||||||
sig = -sig;
|
sig = -sig;
|
||||||
|
|
||||||
|
@ -197,19 +226,20 @@ fhandler_termios::bg_check (int sig)
|
||||||
(_main_tls->sigmask & SIGTOMASK (sig));
|
(_main_tls->sigmask & SIGTOMASK (sig));
|
||||||
cygheap->unlock_tls (tl_entry);
|
cygheap->unlock_tls (tl_entry);
|
||||||
|
|
||||||
/* If the process is ignoring SIGTT*, then background IO is OK. If
|
/* If the process is blocking or ignoring SIGTT*, then signals are not sent
|
||||||
the process is not ignoring SIGTT*, then the sig is to be sent to
|
and background IO is allowed */
|
||||||
all processes in the process group (unless the process group of the
|
|
||||||
process is orphaned, in which case we return EIO). */
|
|
||||||
if (sigs_ignored)
|
if (sigs_ignored)
|
||||||
return bg_ok; /* Just allow the IO */
|
return bg_ok; /* Just allow the IO */
|
||||||
|
/* If the process group of the process is orphaned, return EIO */
|
||||||
else if (tc ()->is_orphaned_process_group (myself->pgid))
|
else if (tc ()->is_orphaned_process_group (myself->pgid))
|
||||||
{
|
{
|
||||||
termios_printf ("process group is orphaned");
|
termios_printf ("process group is orphaned");
|
||||||
set_errno (EIO); /* This is an IO error */
|
set_errno (EIO); /* This is an IO error */
|
||||||
return bg_error;
|
return bg_error;
|
||||||
}
|
}
|
||||||
else
|
/* Otherwise, if signalling is desired, the signal is sent to all processes in
|
||||||
|
the process group */
|
||||||
|
else if (!dontsignal)
|
||||||
{
|
{
|
||||||
/* Don't raise a SIGTT* signal if we have already been
|
/* Don't raise a SIGTT* signal if we have already been
|
||||||
interrupted by another signal. */
|
interrupted by another signal. */
|
||||||
|
@ -222,6 +252,7 @@ fhandler_termios::bg_check (int sig)
|
||||||
}
|
}
|
||||||
return bg_signalled;
|
return bg_signalled;
|
||||||
}
|
}
|
||||||
|
return bg_ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define set_input_done(x) input_done = input_done || (x)
|
#define set_input_done(x) input_done = input_done || (x)
|
||||||
|
|
|
@ -645,7 +645,7 @@ peek_pipe (select_record *s, bool from_select)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fh->bg_check (SIGTTIN) <= bg_eof)
|
if (fh->bg_check (SIGTTIN, true) <= bg_eof)
|
||||||
{
|
{
|
||||||
gotone = s->read_ready = true;
|
gotone = s->read_ready = true;
|
||||||
goto out;
|
goto out;
|
||||||
|
@ -884,7 +884,7 @@ peek_console (select_record *me, bool)
|
||||||
set_handle_or_return_if_not_open (h, me);
|
set_handle_or_return_if_not_open (h, me);
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
if (fh->bg_check (SIGTTIN) <= bg_eof)
|
if (fh->bg_check (SIGTTIN, true) <= bg_eof)
|
||||||
return me->read_ready = true;
|
return me->read_ready = true;
|
||||||
else if (!PeekConsoleInput (h, &irec, 1, &events_read) || !events_read)
|
else if (!PeekConsoleInput (h, &irec, 1, &events_read) || !events_read)
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in New Issue