Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristopher Faylor <me@cgf.cx>2001-01-17 17:57:09 +0300
committerChristopher Faylor <me@cgf.cx>2001-01-17 17:57:09 +0300
commita7cde2b98a658522f552a7ac7ae0a9ef07981e0a (patch)
tree09134d68cc17eab1ebd6c4d81363c189f70ddf7c
parentcb503978ab5119740bc5e796344db6a5d0e6bcb5 (diff)
* 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.
-rw-r--r--winsup/cygwin/ChangeLog21
-rw-r--r--winsup/cygwin/autoload.cc1
-rw-r--r--winsup/cygwin/cygheap.h15
-rw-r--r--winsup/cygwin/exceptions.cc54
-rw-r--r--winsup/cygwin/fhandler.h12
-rw-r--r--winsup/cygwin/fhandler_console.cc2
-rw-r--r--winsup/cygwin/fhandler_termios.cc19
-rw-r--r--winsup/cygwin/select.cc4
-rw-r--r--winsup/cygwin/signal.cc8
-rw-r--r--winsup/cygwin/sigproc.cc4
-rw-r--r--winsup/cygwin/syscalls.cc15
-rw-r--r--winsup/cygwin/termios.cc12
-rw-r--r--winsup/cygwin/wait.cc7
13 files changed, 109 insertions, 65 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index 6db1d52dd..f90265ddd 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -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>
* cygheap.cc (cygheap_user::~cygheap_user): Temporarily
diff --git a/winsup/cygwin/autoload.cc b/winsup/cygwin/autoload.cc
index 7e3dfe414..f7b0a62ef 100644
--- a/winsup/cygwin/autoload.cc
+++ b/winsup/cygwin/autoload.cc
@@ -106,7 +106,6 @@ LoadDLLinitfunc (ntdll)
while (InterlockedIncrement (&here))
{
InterlockedDecrement (&here);
-small_printf ("Multiple tries to read ntdll.dll\n");
Sleep (0);
}
diff --git a/winsup/cygwin/cygheap.h b/winsup/cygwin/cygheap.h
index c39438ab1..69d62d2d9 100644
--- a/winsup/cygwin/cygheap.h
+++ b/winsup/cygwin/cygheap.h
@@ -53,7 +53,8 @@ public:
const char *path () const { return root; }
};
-class cygheap_user {
+class cygheap_user
+{
/* Extendend user information.
The information is derived from the internal_getlogin call
when on a NT system. */
@@ -88,12 +89,12 @@ public:
PSID sid () const { return psid; }
void operator =(cygheap_user &user)
- {
- set_name (user.name ());
- set_logsrv (user.logsrv ());
- set_domain (user.domain ());
- set_sid (user.sid ());
- }
+ {
+ set_name (user.name ());
+ set_logsrv (user.logsrv ());
+ set_domain (user.domain ());
+ set_sid (user.sid ());
+ }
};
struct init_cygheap
diff --git a/winsup/cygwin/exceptions.cc b/winsup/cygwin/exceptions.cc
index fd7de95fb..9a51f49f1 100644
--- a/winsup/cygwin/exceptions.cc
+++ b/winsup/cygwin/exceptions.cc
@@ -585,6 +585,27 @@ handle_sigsuspend (sigset_t tempmask)
extern DWORD exec_exit; // Possible exit value for exec
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
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.sig = sig;
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)));
@@ -890,29 +916,6 @@ set_process_mask (sigset_t newmask)
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
sig_handle (int sig)
{
@@ -988,12 +991,15 @@ sig_handle (int sig)
goto dosig;
stop:
+ /* Eat multiple attempts to STOP */
+ if (ISSTATE (myself, PID_STOPPED))
+ goto done;
handler = (void *) sig_handle_tty_stop;
thissig = myself->getsig (SIGSTOP);
dosig:
/* 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);
done:
diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h
index 356eb6beb..92cf8c300 100644
--- a/winsup/cygwin/fhandler.h
+++ b/winsup/cygwin/fhandler.h
@@ -122,6 +122,14 @@ class select_record;
class path_conv;
class fhandler_disk_file;
+enum bg_check_types
+{
+ bg_error = -1,
+ bg_eof = 0,
+ bg_ok = 1,
+ bg_signalled = 2
+};
+
class fhandler_base
{
private:
@@ -310,7 +318,7 @@ public:
{
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 ()
{
raixput = raixget = ralen = rabuflen = 0;
@@ -562,7 +570,7 @@ public:
int tcgetpgrp ();
int tcsetpgrp (int pid);
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 void __release_output_mutex (const char *fn, int ln) {}
};
diff --git a/winsup/cygwin/fhandler_console.cc b/winsup/cygwin/fhandler_console.cc
index 9030ccbe4..3af96d74a 100644
--- a/winsup/cygwin/fhandler_console.cc
+++ b/winsup/cygwin/fhandler_console.cc
@@ -168,7 +168,7 @@ fhandler_console::read (void *pv, size_t buflen)
for (;;)
{
int bgres;
- if ((bgres = bg_check (SIGTTIN)) <= 0)
+ if ((bgres = bg_check (SIGTTIN)) <= bg_eof)
return bgres;
set_cursor_maybe (); /* to make cursor appear on the screen immediately */
diff --git a/winsup/cygwin/fhandler_termios.cc b/winsup/cygwin/fhandler_termios.cc
index 014e7d104..1d0491379 100644
--- a/winsup/cygwin/fhandler_termios.cc
+++ b/winsup/cygwin/fhandler_termios.cc
@@ -1,6 +1,6 @@
/* fhandler_termios.cc
- Copyright 1996, 1997, 1998 Cygnus Solutions.
+ Copyright 1999, 2000, 2001 Red Hat, Inc.
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)
{
if (!myself->pgid || tc->getpgid () == myself->pgid ||
myself->ctty != tc->ntty ||
((sig == SIGTTOU) && !(tc->ti.c_lflag & TOSTOP)))
- return 1;
+ return bg_ok;
if (sig < 0)
sig = -sig;
@@ -128,7 +128,7 @@ fhandler_termios::bg_check (int sig)
from reallocating this pty. I think this is the case
which is handled by unlockpt on a Unix system. */
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',
@@ -143,16 +143,19 @@ fhandler_termios::bg_check (int sig)
else if (!sigs_ignored)
/* nothing */;
else if (sig == SIGTTOU)
- return 1; /* Just allow the output */
+ return bg_ok; /* Just allow the output */
else
goto setEIO; /* This is an output error */
- _raise (sig);
- return 1;
+ /* Don't raise a SIGTT* signal if we have already been interrupted
+ by another signal. */
+ if (WaitForSingleObject (signal_arrived, 0) != WAIT_OBJECT_0)
+ _raise (sig);
+ return bg_signalled;
setEIO:
set_errno (EIO);
- return -1;
+ return bg_error;
}
#define set_input_done(x) input_done = input_done || (x)
diff --git a/winsup/cygwin/select.cc b/winsup/cygwin/select.cc
index 168f92c8e..b68161dc4 100644
--- a/winsup/cygwin/select.cc
+++ b/winsup/cygwin/select.cc
@@ -412,7 +412,7 @@ peek_pipe (select_record *s, int ignra)
gotone = 1;
goto out;
}
- if (fh->bg_check (SIGTTIN) <= 0)
+ if (fh->bg_check (SIGTTIN) <= bg_eof)
{
gotone = s->read_ready = 1;
goto out;
@@ -627,7 +627,7 @@ peek_console (select_record *me, int ignra)
set_handle_or_return_if_not_open (h, me);
for (;;)
- if (fh->bg_check (SIGTTIN) <= 0)
+ if (fh->bg_check (SIGTTIN) <= bg_eof)
return me->read_ready = 1;
else if (!PeekConsoleInput (h, &irec, 1, &events_read) || !events_read)
break;
diff --git a/winsup/cygwin/signal.cc b/winsup/cygwin/signal.cc
index 23bc9f470..c90ae6abb 100644
--- a/winsup/cygwin/signal.cc
+++ b/winsup/cygwin/signal.cc
@@ -213,11 +213,9 @@ kill_pgrp (pid_t pid, int sig)
continue;
/* Is it a process we want to kill? */
- if (pid == 0 && (p->pgid != myself->pgid || p->ctty != myself->ctty))
- continue;
- if (pid > 1 && p->pgid != pid)
- continue;
- if (sig < 0 && NOTSTATE(p, PID_STOPPED))
+ if ((pid == 0 && (p->pgid != myself->pgid || p->ctty != myself->ctty)) ||
+ (pid > 1 && p->pgid != pid) ||
+ (sig < 0 && NOTSTATE(p, PID_STOPPED)))
continue;
sigproc_printf ("killing pid %d, pgrp %d, p->ctty %d, myself->ctty %d",
p->pid, p->pgid, p->ctty, myself->ctty);
diff --git a/winsup/cygwin/sigproc.cc b/winsup/cygwin/sigproc.cc
index 21b325dde..d7493d1be 100644
--- a/winsup/cygwin/sigproc.cc
+++ b/winsup/cygwin/sigproc.cc
@@ -1150,8 +1150,8 @@ wait_sig (VOID *)
saw_sigchld = 1;
if (sig > 0 && sig != SIGKILL && sig != SIGSTOP &&
- (sigismember (& myself->getsigmask (), sig) ||
- (sig != SIGCONT && myself->process_state & PID_STOPPED)))
+ (sigismember (&myself->getsigmask (), sig) ||
+ (sig != SIGCONT && ISSTATE (myself, PID_STOPPED))))
{
sigproc_printf ("sig %d blocked", sig);
break;
diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc
index 71869cfc5..08e99cd1b 100644
--- a/winsup/cygwin/syscalls.cc
+++ b/winsup/cygwin/syscalls.cc
@@ -1,6 +1,6 @@
/* 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.
@@ -220,8 +220,10 @@ _read (int fd, void *ptr, size_t len)
{
sigframe thisframe (mainthread);
extern int sigcatchers;
+ bool sawsig;
beg:
+ sawsig = 0;
if (fdtab.not_open (fd))
{
set_errno (EBADF);
@@ -243,7 +245,10 @@ beg:
if (!wait)
set_sig_errno (EAGAIN); /* Don't really need 'set_sig_errno' here, but... */
else
- set_sig_errno (EINTR);
+ {
+ set_sig_errno (EINTR);
+ sawsig = 1;
+ }
res = -1;
goto out;
}
@@ -251,7 +256,7 @@ beg:
/* Check to see if this is a background read from a "tty",
sending a SIGTTIN, if appropriate */
res = fh->bg_check (SIGTTIN);
- if (res > 0)
+ if (res > bg_eof)
{
myself->process_state |= PID_TTYIN;
res = fh->read (ptr, len);
@@ -259,7 +264,7 @@ beg:
}
out:
- if (res < 0 && get_errno () == EINTR && call_signal_handler ())
+ if (sawsig && call_signal_handler ())
goto beg;
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 ());
@@ -289,7 +294,7 @@ _write (int fd, const void *ptr, size_t len)
fh = fdtab[fd];
res = fh->bg_check (SIGTTOU);
- if (res > 0)
+ if (res > bg_eof)
{
myself->process_state |= PID_TTYOU;
res = fh->write (ptr, len);
diff --git a/winsup/cygwin/termios.cc b/winsup/cygwin/termios.cc
index c72a49414..b1fd12aa8 100644
--- a/winsup/cygwin/termios.cc
+++ b/winsup/cygwin/termios.cc
@@ -1,6 +1,6 @@
/* 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
dje@cygnus.com, sac@cygnus.com
@@ -40,7 +40,7 @@ tcsendbreak (int fd, int duration)
set_errno (ENOTTY);
else
{
- if ((res = fh->bg_check (-SIGTTOU)) > 0)
+ if ((res = fh->bg_check (-SIGTTOU)) > bg_eof)
res = fh->tcsendbreak (duration);
}
@@ -70,7 +70,7 @@ tcdrain (int fd)
set_errno (ENOTTY);
else
{
- if ((res = fh->bg_check (-SIGTTOU)) > 0)
+ if ((res = fh->bg_check (-SIGTTOU)) > bg_eof)
res = fh->tcdrain ();
}
@@ -98,7 +98,7 @@ tcflush (int fd, int queue)
set_errno (ENOTTY);
else
{
- if ((res = fh->bg_check (-SIGTTOU)) > 0)
+ if ((res = fh->bg_check (-SIGTTOU)) > bg_eof)
res = fh->tcflush (queue);
}
@@ -126,7 +126,7 @@ tcflow (int fd, int action)
set_errno (ENOTTY);
else
{
- if ((res = fh->bg_check (-SIGTTOU)) > 0)
+ if ((res = fh->bg_check (-SIGTTOU)) > bg_eof)
res = fh->tcflow (action);
}
@@ -155,7 +155,7 @@ tcsetattr (int fd, int a, const struct termios *t)
set_errno (ENOTTY);
else
{
- if ((res = fh->bg_check (-SIGTTOU)) > 0)
+ if ((res = fh->bg_check (-SIGTTOU)) > bg_eof)
res = fh->tcsetattr (a, t);
}
diff --git a/winsup/cygwin/wait.cc b/winsup/cygwin/wait.cc
index 852c7f453..7a106f970 100644
--- a/winsup/cygwin/wait.cc
+++ b/winsup/cygwin/wait.cc
@@ -51,9 +51,11 @@ wait4 (int intpid, int *status, int options, struct rusage *r)
waitq *w;
HANDLE waitfor;
sigframe thisframe (mainthread);
+ bool sawsig;
beg:
- if (options & ~(WNOHANG | WUNTRACED))
+ sawsig = 0;
+ if (options & ~(WNOHANG | WUNTRACED))
{
set_errno (EINVAL);
return -1;
@@ -97,6 +99,7 @@ beg:
if (w->status == -1)
{
set_sig_errno (EINTR);
+ sawsig = 1;
res = -1;
}
else if (res != WAIT_OBJECT_0)
@@ -110,7 +113,7 @@ beg:
*status = w->status;
done:
- if (res < 0 && get_errno () == EINTR && call_signal_handler ())
+ if (sawsig && call_signal_handler ())
goto beg;
sigproc_printf ("intpid %d, status %p, w->status %d, options %d, res %d",
intpid, status, w->status, options, res);