diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index 390201085..754549914 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,3 +1,13 @@
+2002-01-10  Christopher Faylor  <cgf@redhat.com>
+
+	* exceptions.cc (sig_handle): Accept a second argument indicating
+	whether the signal came from this process or not.
+	* sigproc.h: Reflect sig_handle arg change.
+	* signal.cc (kill_pgrp): Add sigframe info.
+	(abort): New function.  Eliminates newlib function of same name.
+	* sigproc.cc (wait_sig): Pass "signal from this process" value as arg
+	2.
+
 2002-01-10  Corinna Vinschen  <corinna@vinschen.de>
 
 	* syscalls.cc (pathconf): Guard _PC_PATH_MAX branch against invalid
diff --git a/winsup/cygwin/exceptions.cc b/winsup/cygwin/exceptions.cc
index a3107e8b3..98bb75960 100644
--- a/winsup/cygwin/exceptions.cc
+++ b/winsup/cygwin/exceptions.cc
@@ -893,7 +893,7 @@ setup_handler (int sig, void *handler, struct sigaction& siga)
 #error "Need to supply machine dependent setup_handler"
 #endif
 
-/* CGF Keyboard interrupt handler.  */
+/* Keyboard interrupt handler.  */
 static BOOL WINAPI
 ctrl_c_handler (DWORD type)
 {
@@ -963,7 +963,7 @@ set_process_mask (sigset_t newmask)
 }
 
 int __stdcall
-sig_handle (int sig)
+sig_handle (int sig, bool thisproc)
 {
   int rc = 0;
 
@@ -1011,7 +1011,7 @@ sig_handle (int sig)
   if (handler == (void *) SIG_DFL)
     {
       if (sig == SIGCHLD || sig == SIGIO || sig == SIGCONT || sig == SIGWINCH
-          || sig == SIGURG || (hExeced && sig == SIGINT))
+          || sig == SIGURG || (thisproc && hExeced && sig == SIGINT))
 	{
 	  sigproc_printf ("default signal %d ignored", sig);
 	  goto done;
diff --git a/winsup/cygwin/signal.cc b/winsup/cygwin/signal.cc
index 652348302..3d9789d8c 100644
--- a/winsup/cygwin/signal.cc
+++ b/winsup/cygwin/signal.cc
@@ -13,6 +13,7 @@ details. */
 
 #include "winsup.h"
 #include <errno.h>
+#include <stdlib.h>
 #include "cygerrno.h"
 #include <sys/cygwin.h>
 #include "sync.h"
@@ -190,6 +191,7 @@ _raise (int sig)
 int
 _kill (pid_t pid, int sig)
 {
+  sigframe thisframe (mainthread);
   syscall_printf ("kill (%d, %d)", pid, sig);
   /* check that sig is in right range */
   if (sig < 0 || sig >= NSIG)
@@ -214,6 +216,7 @@ kill_pgrp (pid_t pid, int sig)
   int res = 0;
   int found = 0;
   int killself = 0;
+  sigframe thisframe (mainthread);
 
   sigproc_printf ("pid %d, signal %d", pid, sig);
 
@@ -257,6 +260,31 @@ killpg (pid_t pgrp, int sig)
   return _kill (-pgrp, sig);
 }
 
+extern "C" void
+abort (void)
+{
+  sigframe thisframe (mainthread);
+  /* Flush all streams as per SUSv2.
+     From my reading of this document, this isn't strictly correct.
+     The streams are supposed to be flushed prior to exit.  However,
+     if there is I/O in any signal handler that will not necessarily
+     be flushed.
+     However this is the way FreeBSD does it, and it is much easier to
+     do things this way, so... */
+  if (_reent_clib ()->__cleanup)
+    _reent_clib ()->__cleanup (_reent_clib ());
+
+  /* Ensure that SIGABRT can be caught regardless of blockage. */
+  sigset_t sig_mask;
+  sigfillset (&sig_mask);
+  sigdelset (&sig_mask, SIGABRT);
+  set_process_mask (sig_mask);
+
+  _raise (SIGABRT);
+  (void) thisframe.call_signal_handler (); /* Call any signal handler */
+  do_exit (1);	/* signal handler didn't exit.  Goodbye. */
+}
+
 extern "C" int
 sigaction (int sig, const struct sigaction *newact, struct sigaction *oldact)
 {
diff --git a/winsup/cygwin/sigproc.cc b/winsup/cygwin/sigproc.cc
index 159c3bd69..80b618c32 100644
--- a/winsup/cygwin/sigproc.cc
+++ b/winsup/cygwin/sigproc.cc
@@ -1190,7 +1190,7 @@ wait_sig (VOID *)
 		/* A normal UNIX signal */
 		default:
 		  sigproc_printf ("Got signal %d", sig);
-		  int wasdispatched = sig_handle (sig);
+		  int wasdispatched = sig_handle (sig, rc != 2);
 		  if (sig == SIGCHLD && wasdispatched)
 		    dispatched_sigchld = 1;
 		  /* Need to decrement again to offset increment below since
diff --git a/winsup/cygwin/sigproc.h b/winsup/cygwin/sigproc.h
index dc67b6b08..41fee5fb7 100644
--- a/winsup/cygwin/sigproc.h
+++ b/winsup/cygwin/sigproc.h
@@ -98,7 +98,7 @@ BOOL __stdcall my_parent_is_alive ();
 extern "C" int __stdcall sig_dispatch_pending (int force = FALSE);
 extern "C" void __stdcall set_process_mask (sigset_t newmask);
 extern "C" void __stdcall reset_signal_arrived ();
-int __stdcall sig_handle (int);
+int __stdcall sig_handle (int, bool);
 void __stdcall sig_clear (int);
 void __stdcall sig_set_pending (int);
 int __stdcall handle_sigsuspend (sigset_t);