* autoload.cc (LoadDLLinitfunc): Remove debugging statement.

* exceptions.cc (sig_handle_tty_stop): Move setting of PID_STOPPED to earlier
in interrupt.
((interrupt_setup): i.e., here.
(sig_handle): Don't queue multiple SIGSTOPS.
* fhandler.h (bg_check_types): Enumerate return value of bg_check for clarity.
* signal.cc (kill_pgrp): Minor cleanup.
* fhandler_termios.cc (fhandler_termios::bg_check): Use enumerated type for
function return.  Don't raise signal if a signal is already queued.
* fhandler_console.cc (fhandler_console::read): Use enumerated return type for
bg_check.
* select.cc: Ditto, throughout.
* read.cc: Ditto, throughout.
* termios.cc: Ditto, throughout.
(_read): YA interrupt detect simplification.
* wait.cc (wait4): Ditto.
This commit is contained in:
Christopher Faylor 2001-01-17 14:57:09 +00:00
parent cb503978ab
commit a7cde2b98a
13 changed files with 109 additions and 65 deletions

View File

@ -1,3 +1,24 @@
Wed Jan 17 09:47:13 2001 Christopher Faylor <cgf@cygnus.com>
* autoload.cc (LoadDLLinitfunc): Remove debugging statement.
* exceptions.cc (sig_handle_tty_stop): Move setting of PID_STOPPED to
earlier in interrupt.
((interrupt_setup): i.e., here.
(sig_handle): Don't queue multiple SIGSTOPS.
* fhandler.h (bg_check_types): Enumerate return value of bg_check for
clarity.
* signal.cc (kill_pgrp): Minor cleanup.
* fhandler_termios.cc (fhandler_termios::bg_check): Use enumerated type
for function return. Don't raise signal if a signal is already queued.
* fhandler_console.cc (fhandler_console::read): Use enumerated return
type for bg_check.
* select.cc: Ditto, throughout.
* read.cc: Ditto, throughout.
* termios.cc: Ditto, throughout.
(_read): YA interrupt detect simplification.
* wait.cc (wait4): Ditto.
Wed Jan 17 10:56:00 2001 Corinna Vinschen <corinna@vinschen.de> Wed Jan 17 10:56:00 2001 Corinna Vinschen <corinna@vinschen.de>
* cygheap.cc (cygheap_user::~cygheap_user): Temporarily * cygheap.cc (cygheap_user::~cygheap_user): Temporarily

View File

@ -106,7 +106,6 @@ LoadDLLinitfunc (ntdll)
while (InterlockedIncrement (&here)) while (InterlockedIncrement (&here))
{ {
InterlockedDecrement (&here); InterlockedDecrement (&here);
small_printf ("Multiple tries to read ntdll.dll\n");
Sleep (0); Sleep (0);
} }

View File

@ -53,7 +53,8 @@ public:
const char *path () const { return root; } const char *path () const { return root; }
}; };
class cygheap_user { class cygheap_user
{
/* Extendend user information. /* Extendend user information.
The information is derived from the internal_getlogin call The information is derived from the internal_getlogin call
when on a NT system. */ when on a NT system. */
@ -88,12 +89,12 @@ public:
PSID sid () const { return psid; } PSID sid () const { return psid; }
void operator =(cygheap_user &user) void operator =(cygheap_user &user)
{ {
set_name (user.name ()); set_name (user.name ());
set_logsrv (user.logsrv ()); set_logsrv (user.logsrv ());
set_domain (user.domain ()); set_domain (user.domain ());
set_sid (user.sid ()); set_sid (user.sid ());
} }
}; };
struct init_cygheap struct init_cygheap

View File

@ -585,6 +585,27 @@ handle_sigsuspend (sigset_t tempmask)
extern DWORD exec_exit; // Possible exit value for exec extern DWORD exec_exit; // Possible exit value for exec
extern int pending_signals; extern int pending_signals;
extern "C" {
static void
sig_handle_tty_stop (int sig)
{
myself->stopsig = sig;
/* See if we have a living parent. If so, send it a special signal.
* It will figure out exactly which pid has stopped by scanning
* its list of subprocesses.
*/
if (my_parent_is_alive ())
{
pinfo parent (myself->ppid);
sig_send (parent, __SIGCHILDSTOPPED);
}
sigproc_printf ("process %d stopped by signal %d, myself->ppid_handle %p",
myself->pid, sig, myself->ppid_handle);
SuspendThread (hMainThread);
return;
}
}
int int
interruptible (DWORD pc, int testvalid = 0) interruptible (DWORD pc, int testvalid = 0)
{ {
@ -639,6 +660,11 @@ interrupt_setup (int sig, void *handler, DWORD retaddr, DWORD *retaddr_on_stack,
sigsave.func = (void (*)(int)) handler; sigsave.func = (void (*)(int)) handler;
sigsave.sig = sig; sigsave.sig = sig;
sigsave.saved_errno = -1; // Flag: no errno to save sigsave.saved_errno = -1; // Flag: no errno to save
if (handler == sig_handle_tty_stop)
{
myself->stopsig = 0;
myself->process_state |= PID_STOPPED;
}
} }
static bool interrupt_now (CONTEXT *, int, void *, struct sigaction&) __attribute__((regparm(3))); static bool interrupt_now (CONTEXT *, int, void *, struct sigaction&) __attribute__((regparm(3)));
@ -890,29 +916,6 @@ set_process_mask (sigset_t newmask)
return; return;
} }
extern "C" {
static void
sig_handle_tty_stop (int sig)
{
myself->stopsig = sig;
myself->process_state |= PID_STOPPED;
/* See if we have a living parent. If so, send it a special signal.
* It will figure out exactly which pid has stopped by scanning
* its list of subprocesses.
*/
if (my_parent_is_alive ())
{
pinfo parent (myself->ppid);
sig_send (parent, __SIGCHILDSTOPPED);
}
sigproc_printf ("process %d stopped by signal %d, myself->ppid_handle %p",
myself->pid, sig, myself->ppid_handle);
/* There is a small race here with the above two mutexes */
SuspendThread (hMainThread);
return;
}
}
int __stdcall int __stdcall
sig_handle (int sig) sig_handle (int sig)
{ {
@ -988,12 +991,15 @@ sig_handle (int sig)
goto dosig; goto dosig;
stop: stop:
/* Eat multiple attempts to STOP */
if (ISSTATE (myself, PID_STOPPED))
goto done;
handler = (void *) sig_handle_tty_stop; handler = (void *) sig_handle_tty_stop;
thissig = myself->getsig (SIGSTOP); thissig = myself->getsig (SIGSTOP);
dosig: dosig:
/* Dispatch to the appropriate function. */ /* Dispatch to the appropriate function. */
sigproc_printf ("signal %d, about to call %p", sig, thissig.sa_handler); sigproc_printf ("signal %d, about to call %p", sig, handler);
rc = call_handler (sig, handler, thissig); rc = call_handler (sig, handler, thissig);
done: done:

View File

@ -122,6 +122,14 @@ class select_record;
class path_conv; class path_conv;
class fhandler_disk_file; class fhandler_disk_file;
enum bg_check_types
{
bg_error = -1,
bg_eof = 0,
bg_ok = 1,
bg_signalled = 2
};
class fhandler_base class fhandler_base
{ {
private: private:
@ -310,7 +318,7 @@ public:
{ {
return windows_device_names[FHDEVN (status)]; return windows_device_names[FHDEVN (status)];
} }
virtual int bg_check (int) {return 1;} virtual bg_check_types bg_check (int) {return bg_ok;}
void clear_readahead () void clear_readahead ()
{ {
raixput = raixget = ralen = rabuflen = 0; raixput = raixget = ralen = rabuflen = 0;
@ -562,7 +570,7 @@ public:
int tcgetpgrp (); int tcgetpgrp ();
int tcsetpgrp (int pid); int tcsetpgrp (int pid);
void set_ctty (int ttynum, int flags); void set_ctty (int ttynum, int flags);
int bg_check (int sig); bg_check_types bg_check (int sig);
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) {}
}; };

View File

@ -168,7 +168,7 @@ fhandler_console::read (void *pv, size_t buflen)
for (;;) for (;;)
{ {
int bgres; int bgres;
if ((bgres = bg_check (SIGTTIN)) <= 0) if ((bgres = bg_check (SIGTTIN)) <= bg_eof)
return bgres; return bgres;
set_cursor_maybe (); /* to make cursor appear on the screen immediately */ set_cursor_maybe (); /* to make cursor appear on the screen immediately */

View File

@ -1,6 +1,6 @@
/* fhandler_termios.cc /* fhandler_termios.cc
Copyright 1996, 1997, 1998 Cygnus Solutions. Copyright 1999, 2000, 2001 Red Hat, Inc.
This file is part of Cygwin. This file is part of Cygwin.
@ -107,13 +107,13 @@ fhandler_termios::set_ctty (int ttynum, int flags)
} }
} }
int bg_check_types
fhandler_termios::bg_check (int sig) fhandler_termios::bg_check (int sig)
{ {
if (!myself->pgid || tc->getpgid () == myself->pgid || if (!myself->pgid || 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 1; return bg_ok;
if (sig < 0) if (sig < 0)
sig = -sig; sig = -sig;
@ -128,7 +128,7 @@ fhandler_termios::bg_check (int sig)
from reallocating this pty. I think this is the case from reallocating this pty. I think this is the case
which is handled by unlockpt on a Unix system. */ which is handled by unlockpt on a Unix system. */
termios_printf ("closed by master"); termios_printf ("closed by master");
return 0; return bg_eof;
} }
/* If the process group is no more or if process is ignoring or blocks 'sig', /* If the process group is no more or if process is ignoring or blocks 'sig',
@ -143,16 +143,19 @@ fhandler_termios::bg_check (int sig)
else if (!sigs_ignored) else if (!sigs_ignored)
/* nothing */; /* nothing */;
else if (sig == SIGTTOU) else if (sig == SIGTTOU)
return 1; /* Just allow the output */ return bg_ok; /* Just allow the output */
else else
goto setEIO; /* This is an output error */ goto setEIO; /* This is an output error */
_raise (sig); /* Don't raise a SIGTT* signal if we have already been interrupted
return 1; by another signal. */
if (WaitForSingleObject (signal_arrived, 0) != WAIT_OBJECT_0)
_raise (sig);
return bg_signalled;
setEIO: setEIO:
set_errno (EIO); set_errno (EIO);
return -1; return bg_error;
} }
#define set_input_done(x) input_done = input_done || (x) #define set_input_done(x) input_done = input_done || (x)

View File

@ -412,7 +412,7 @@ peek_pipe (select_record *s, int ignra)
gotone = 1; gotone = 1;
goto out; goto out;
} }
if (fh->bg_check (SIGTTIN) <= 0) if (fh->bg_check (SIGTTIN) <= bg_eof)
{ {
gotone = s->read_ready = 1; gotone = s->read_ready = 1;
goto out; goto out;
@ -627,7 +627,7 @@ peek_console (select_record *me, int ignra)
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) <= 0) if (fh->bg_check (SIGTTIN) <= bg_eof)
return me->read_ready = 1; return me->read_ready = 1;
else if (!PeekConsoleInput (h, &irec, 1, &events_read) || !events_read) else if (!PeekConsoleInput (h, &irec, 1, &events_read) || !events_read)
break; break;

View File

@ -213,11 +213,9 @@ kill_pgrp (pid_t pid, int sig)
continue; continue;
/* Is it a process we want to kill? */ /* Is it a process we want to kill? */
if (pid == 0 && (p->pgid != myself->pgid || p->ctty != myself->ctty)) if ((pid == 0 && (p->pgid != myself->pgid || p->ctty != myself->ctty)) ||
continue; (pid > 1 && p->pgid != pid) ||
if (pid > 1 && p->pgid != pid) (sig < 0 && NOTSTATE(p, PID_STOPPED)))
continue;
if (sig < 0 && NOTSTATE(p, PID_STOPPED))
continue; continue;
sigproc_printf ("killing pid %d, pgrp %d, p->ctty %d, myself->ctty %d", sigproc_printf ("killing pid %d, pgrp %d, p->ctty %d, myself->ctty %d",
p->pid, p->pgid, p->ctty, myself->ctty); p->pid, p->pgid, p->ctty, myself->ctty);

View File

@ -1150,8 +1150,8 @@ wait_sig (VOID *)
saw_sigchld = 1; saw_sigchld = 1;
if (sig > 0 && sig != SIGKILL && sig != SIGSTOP && if (sig > 0 && sig != SIGKILL && sig != SIGSTOP &&
(sigismember (& myself->getsigmask (), sig) || (sigismember (&myself->getsigmask (), sig) ||
(sig != SIGCONT && myself->process_state & PID_STOPPED))) (sig != SIGCONT && ISSTATE (myself, PID_STOPPED))))
{ {
sigproc_printf ("sig %d blocked", sig); sigproc_printf ("sig %d blocked", sig);
break; break;

View File

@ -1,6 +1,6 @@
/* syscalls.cc: syscalls /* syscalls.cc: syscalls
Copyright 1996, 1997, 1998, 1999, 2000 Cygnus Solutions. Copyright 1996, 1997, 1998, 1999, 2000, 2001 Red Hat, Inc.
This file is part of Cygwin. This file is part of Cygwin.
@ -220,8 +220,10 @@ _read (int fd, void *ptr, size_t len)
{ {
sigframe thisframe (mainthread); sigframe thisframe (mainthread);
extern int sigcatchers; extern int sigcatchers;
bool sawsig;
beg: beg:
sawsig = 0;
if (fdtab.not_open (fd)) if (fdtab.not_open (fd))
{ {
set_errno (EBADF); set_errno (EBADF);
@ -243,7 +245,10 @@ beg:
if (!wait) if (!wait)
set_sig_errno (EAGAIN); /* Don't really need 'set_sig_errno' here, but... */ set_sig_errno (EAGAIN); /* Don't really need 'set_sig_errno' here, but... */
else else
set_sig_errno (EINTR); {
set_sig_errno (EINTR);
sawsig = 1;
}
res = -1; res = -1;
goto out; goto out;
} }
@ -251,7 +256,7 @@ beg:
/* Check to see if this is a background read from a "tty", /* Check to see if this is a background read from a "tty",
sending a SIGTTIN, if appropriate */ sending a SIGTTIN, if appropriate */
res = fh->bg_check (SIGTTIN); res = fh->bg_check (SIGTTIN);
if (res > 0) if (res > bg_eof)
{ {
myself->process_state |= PID_TTYIN; myself->process_state |= PID_TTYIN;
res = fh->read (ptr, len); res = fh->read (ptr, len);
@ -259,7 +264,7 @@ beg:
} }
out: out:
if (res < 0 && get_errno () == EINTR && call_signal_handler ()) if (sawsig && call_signal_handler ())
goto beg; goto beg;
syscall_printf ("%d = read (%d<%s>, %p, %d), bin %d, errno %d", res, fd, fh->get_name (), syscall_printf ("%d = read (%d<%s>, %p, %d), bin %d, errno %d", res, fd, fh->get_name (),
ptr, len, fh->get_r_binary (), get_errno ()); ptr, len, fh->get_r_binary (), get_errno ());
@ -289,7 +294,7 @@ _write (int fd, const void *ptr, size_t len)
fh = fdtab[fd]; fh = fdtab[fd];
res = fh->bg_check (SIGTTOU); res = fh->bg_check (SIGTTOU);
if (res > 0) if (res > bg_eof)
{ {
myself->process_state |= PID_TTYOU; myself->process_state |= PID_TTYOU;
res = fh->write (ptr, len); res = fh->write (ptr, len);

View File

@ -1,6 +1,6 @@
/* termios.cc: termios for WIN32. /* termios.cc: termios for WIN32.
Copyright 1996, 1997, 1998, 2000 Cygnus Solutions. Copyright 1996, 1997, 1998, 2000, 2001 Red Hat, Inc.
Written by Doug Evans and Steve Chamberlain of Cygnus Support Written by Doug Evans and Steve Chamberlain of Cygnus Support
dje@cygnus.com, sac@cygnus.com dje@cygnus.com, sac@cygnus.com
@ -40,7 +40,7 @@ tcsendbreak (int fd, int duration)
set_errno (ENOTTY); set_errno (ENOTTY);
else else
{ {
if ((res = fh->bg_check (-SIGTTOU)) > 0) if ((res = fh->bg_check (-SIGTTOU)) > bg_eof)
res = fh->tcsendbreak (duration); res = fh->tcsendbreak (duration);
} }
@ -70,7 +70,7 @@ tcdrain (int fd)
set_errno (ENOTTY); set_errno (ENOTTY);
else else
{ {
if ((res = fh->bg_check (-SIGTTOU)) > 0) if ((res = fh->bg_check (-SIGTTOU)) > bg_eof)
res = fh->tcdrain (); res = fh->tcdrain ();
} }
@ -98,7 +98,7 @@ tcflush (int fd, int queue)
set_errno (ENOTTY); set_errno (ENOTTY);
else else
{ {
if ((res = fh->bg_check (-SIGTTOU)) > 0) if ((res = fh->bg_check (-SIGTTOU)) > bg_eof)
res = fh->tcflush (queue); res = fh->tcflush (queue);
} }
@ -126,7 +126,7 @@ tcflow (int fd, int action)
set_errno (ENOTTY); set_errno (ENOTTY);
else else
{ {
if ((res = fh->bg_check (-SIGTTOU)) > 0) if ((res = fh->bg_check (-SIGTTOU)) > bg_eof)
res = fh->tcflow (action); res = fh->tcflow (action);
} }
@ -155,7 +155,7 @@ tcsetattr (int fd, int a, const struct termios *t)
set_errno (ENOTTY); set_errno (ENOTTY);
else else
{ {
if ((res = fh->bg_check (-SIGTTOU)) > 0) if ((res = fh->bg_check (-SIGTTOU)) > bg_eof)
res = fh->tcsetattr (a, t); res = fh->tcsetattr (a, t);
} }

View File

@ -51,9 +51,11 @@ wait4 (int intpid, int *status, int options, struct rusage *r)
waitq *w; waitq *w;
HANDLE waitfor; HANDLE waitfor;
sigframe thisframe (mainthread); sigframe thisframe (mainthread);
bool sawsig;
beg: beg:
if (options & ~(WNOHANG | WUNTRACED)) sawsig = 0;
if (options & ~(WNOHANG | WUNTRACED))
{ {
set_errno (EINVAL); set_errno (EINVAL);
return -1; return -1;
@ -97,6 +99,7 @@ beg:
if (w->status == -1) if (w->status == -1)
{ {
set_sig_errno (EINTR); set_sig_errno (EINTR);
sawsig = 1;
res = -1; res = -1;
} }
else if (res != WAIT_OBJECT_0) else if (res != WAIT_OBJECT_0)
@ -110,7 +113,7 @@ beg:
*status = w->status; *status = w->status;
done: done:
if (res < 0 && get_errno () == EINTR && call_signal_handler ()) if (sawsig && call_signal_handler ())
goto beg; goto beg;
sigproc_printf ("intpid %d, status %p, w->status %d, options %d, res %d", sigproc_printf ("intpid %d, status %p, w->status %d, options %d, res %d",
intpid, status, w->status, options, res); intpid, status, w->status, options, res);