* fhandler_termios.cc (fhandler_termios::bg_check): Do not return EIO when a
process group has no leader as this is allowed and does not imply an orphaned process group. Add a test for orphaned process groups. (tty_min::is_orphaned_process_group): Define new function. * tty.h (tty_min::is_orphaned_process_group): Define new function.
This commit is contained in:
parent
977ad5434c
commit
7123c8b1fd
|
@ -1,3 +1,12 @@
|
||||||
|
2011-05-30 Tor Perkins <cygwin@noid.net>
|
||||||
|
|
||||||
|
* fhandler_termios.cc (fhandler_termios::bg_check): Do not return EIO
|
||||||
|
when a process group has no leader as this is allowed and does not
|
||||||
|
imply an orphaned process group. Add a test for orphaned process
|
||||||
|
groups.
|
||||||
|
(tty_min::is_orphaned_process_group): Define new function.
|
||||||
|
* tty.h (tty_min::is_orphaned_process_group): Define new function.
|
||||||
|
|
||||||
2011-05-30 Ryan Johnson <ryan.johnson@cs.utoronto.ca>
|
2011-05-30 Ryan Johnson <ryan.johnson@cs.utoronto.ca>
|
||||||
|
|
||||||
* dll_init.cc (dll_list::find_by_modname): New function to search the
|
* dll_init.cc (dll_list::find_by_modname): New function to search the
|
||||||
|
|
|
@ -112,6 +112,26 @@ fhandler_pty_master::tcgetpgrp ()
|
||||||
return tc->pgid;
|
return tc->pgid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
tty_min::is_orphaned_process_group (int pgid)
|
||||||
|
{
|
||||||
|
/* An orphaned process group is a process group in which the parent
|
||||||
|
of every member is either itself a member of the group or is not
|
||||||
|
a member of the group's session. */
|
||||||
|
winpids pids ((DWORD) PID_MAP_RW);
|
||||||
|
for (unsigned i = 0; i < pids.npids; i++)
|
||||||
|
{
|
||||||
|
_pinfo *p = pids[i];
|
||||||
|
if (!p->exists () || p->pgid != pgid)
|
||||||
|
continue;
|
||||||
|
pinfo ppid (p->ppid);
|
||||||
|
if (ppid->pgid != pgid &&
|
||||||
|
ppid->sid == myself->sid)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
tty_min::kill_pgrp (int sig)
|
tty_min::kill_pgrp (int sig)
|
||||||
{
|
{
|
||||||
|
@ -158,36 +178,35 @@ fhandler_termios::bg_check (int sig)
|
||||||
return bg_eof;
|
return bg_eof;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If the process group is no more or if process is ignoring or blocks 'sig',
|
|
||||||
return with error */
|
|
||||||
int pgid_gone = !pid_exists (myself->pgid);
|
|
||||||
int sigs_ignored =
|
int sigs_ignored =
|
||||||
((void *) global_sigs[sig].sa_handler == (void *) SIG_IGN) ||
|
((void *) global_sigs[sig].sa_handler == (void *) SIG_IGN) ||
|
||||||
(_main_tls->sigmask & SIGTOMASK (sig));
|
(_main_tls->sigmask & SIGTOMASK (sig));
|
||||||
|
|
||||||
if (pgid_gone)
|
/* If the process is ignoring SIGTT*, then background IO is OK. If
|
||||||
goto setEIO;
|
the process is not ignoring SIGTT*, then the sig is to be sent to
|
||||||
else if (!sigs_ignored)
|
all processes in the process group (unless the process group of the
|
||||||
/* nothing */;
|
process is orphaned, in which case we return EIO). */
|
||||||
else if (sig == SIGTTOU)
|
if (sigs_ignored)
|
||||||
return bg_ok; /* Just allow the output */
|
return bg_ok; /* Just allow the IO */
|
||||||
else
|
else if ( tc->is_orphaned_process_group (myself->pgid) )
|
||||||
goto setEIO; /* This is an output error */
|
|
||||||
|
|
||||||
/* Don't raise a SIGTT* signal if we have already been interrupted
|
|
||||||
by another signal. */
|
|
||||||
if (!IsEventSignalled (signal_arrived))
|
|
||||||
{
|
{
|
||||||
siginfo_t si = {0};
|
termios_printf ("process group is orphaned");
|
||||||
si.si_signo = sig;
|
set_errno (EIO); /* This is an IO error */
|
||||||
si.si_code = SI_KERNEL;
|
return bg_error;
|
||||||
kill_pgrp (myself->pgid, si);
|
|
||||||
}
|
}
|
||||||
return bg_signalled;
|
else
|
||||||
|
{
|
||||||
setEIO:
|
/* Don't raise a SIGTT* signal if we have already been
|
||||||
set_errno (EIO);
|
interrupted by another signal. */
|
||||||
return bg_error;
|
if (WaitForSingleObject (signal_arrived, 0) != WAIT_OBJECT_0)
|
||||||
|
{
|
||||||
|
siginfo_t si = {0};
|
||||||
|
si.si_signo = sig;
|
||||||
|
si.si_code = SI_KERNEL;
|
||||||
|
kill_pgrp (myself->pgid, si);
|
||||||
|
}
|
||||||
|
return bg_signalled;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#define set_input_done(x) input_done = input_done || (x)
|
#define set_input_done(x) input_done = input_done || (x)
|
||||||
|
|
|
@ -78,7 +78,8 @@ public:
|
||||||
void setpgid (int pid) {pgid = pid;}
|
void setpgid (int pid) {pgid = pid;}
|
||||||
int getsid () const {return sid;}
|
int getsid () const {return sid;}
|
||||||
void setsid (pid_t tsid) {sid = tsid;}
|
void setsid (pid_t tsid) {sid = tsid;}
|
||||||
void kill_pgrp (int sig);
|
void kill_pgrp (int);
|
||||||
|
int is_orphaned_process_group (int);
|
||||||
HWND gethwnd () const {return hwnd;}
|
HWND gethwnd () const {return hwnd;}
|
||||||
void sethwnd (HWND wnd) {hwnd = wnd;}
|
void sethwnd (HWND wnd) {hwnd = wnd;}
|
||||||
const char *ttyname () __attribute ((regparm (1)));
|
const char *ttyname () __attribute ((regparm (1)));
|
||||||
|
|
Loading…
Reference in New Issue