aboutsummaryrefslogtreecommitdiffstats
path: root/src/w32proc.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/w32proc.c')
-rw-r--r--src/w32proc.c47
1 files changed, 34 insertions, 13 deletions
diff --git a/src/w32proc.c b/src/w32proc.c
index 26a0925ad87..b367b42d8c6 100644
--- a/src/w32proc.c
+++ b/src/w32proc.c
@@ -86,19 +86,34 @@ typedef void (_CALLBACK_ *signal_handler) (int);
86/* Signal handlers...SIG_DFL == 0 so this is initialized correctly. */ 86/* Signal handlers...SIG_DFL == 0 so this is initialized correctly. */
87static signal_handler sig_handlers[NSIG]; 87static signal_handler sig_handlers[NSIG];
88 88
89/* Fake signal implementation to record the SIGCHLD handler. */ 89/* Improve on the CRT 'signal' implementation so that we could record
90 the SIGCHLD handler. */
90signal_handler 91signal_handler
91sys_signal (int sig, signal_handler handler) 92sys_signal (int sig, signal_handler handler)
92{ 93{
93 signal_handler old; 94 signal_handler old;
94 95
95 if (sig != SIGCHLD) 96 /* SIGCHLD is needed for supporting subprocesses, see sys_kill
97 below. All the others are the only ones supported by the MS
98 runtime. */
99 if (!(sig == SIGCHLD || sig == SIGSEGV || sig == SIGILL
100 || sig == SIGFPE || sig == SIGABRT || sig == SIGTERM))
96 { 101 {
97 errno = EINVAL; 102 errno = EINVAL;
98 return SIG_ERR; 103 return SIG_ERR;
99 } 104 }
100 old = sig_handlers[sig]; 105 old = sig_handlers[sig];
101 sig_handlers[sig] = handler; 106 /* SIGABRT is treated specially because w32.c installs term_ntproc
107 as its handler, so we don't want to override that afterwards.
108 Aborting Emacs works specially anyway: either by calling
109 emacs_abort directly or through terminate_due_to_signal, which
110 calls emacs_abort through emacs_raise. */
111 if (!(sig == SIGABRT && old == term_ntproc))
112 {
113 sig_handlers[sig] = handler;
114 if (sig != SIGCHLD)
115 signal (sig, handler);
116 }
102 return old; 117 return old;
103} 118}
104 119
@@ -106,23 +121,26 @@ sys_signal (int sig, signal_handler handler)
106int 121int
107sigaction (int sig, const struct sigaction *act, struct sigaction *oact) 122sigaction (int sig, const struct sigaction *act, struct sigaction *oact)
108{ 123{
109 signal_handler old; 124 signal_handler old = SIG_DFL;
125 int retval = 0;
110 126
111 if (sig != SIGCHLD) 127 if (act)
128 old = sys_signal (sig, act->sa_handler);
129 else if (oact)
130 old = sig_handlers[sig];
131
132 if (old == SIG_ERR)
112 { 133 {
113 errno = EINVAL; 134 errno = EINVAL;
114 return -1; 135 retval = -1;
115 } 136 }
116 old = sig_handlers[sig];
117 if (act)
118 sig_handlers[sig] = act->sa_handler;
119 if (oact) 137 if (oact)
120 { 138 {
121 oact->sa_handler = old; 139 oact->sa_handler = old;
122 oact->sa_flags = 0; 140 oact->sa_flags = 0;
123 oact->sa_mask = empty_mask; 141 oact->sa_mask = empty_mask;
124 } 142 }
125 return 0; 143 return retval;
126} 144}
127 145
128/* Defined in <process.h> which conflicts with the local copy */ 146/* Defined in <process.h> which conflicts with the local copy */
@@ -1420,6 +1438,7 @@ find_child_console (HWND hwnd, LPARAM arg)
1420 return TRUE; 1438 return TRUE;
1421} 1439}
1422 1440
1441/* Emulate 'kill', but only for other processes. */
1423int 1442int
1424sys_kill (int pid, int sig) 1443sys_kill (int pid, int sig)
1425{ 1444{
@@ -1428,9 +1447,6 @@ sys_kill (int pid, int sig)
1428 int need_to_free = 0; 1447 int need_to_free = 0;
1429 int rc = 0; 1448 int rc = 0;
1430 1449
1431 if (pid == getpid () && sig == SIGABRT)
1432 emacs_abort ();
1433
1434 /* Only handle signals that will result in the process dying */ 1450 /* Only handle signals that will result in the process dying */
1435 if (sig != SIGINT && sig != SIGKILL && sig != SIGQUIT && sig != SIGHUP) 1451 if (sig != SIGINT && sig != SIGKILL && sig != SIGQUIT && sig != SIGHUP)
1436 { 1452 {
@@ -1441,6 +1457,11 @@ sys_kill (int pid, int sig)
1441 cp = find_child_pid (pid); 1457 cp = find_child_pid (pid);
1442 if (cp == NULL) 1458 if (cp == NULL)
1443 { 1459 {
1460 /* We were passed a PID of something other than our subprocess.
1461 If that is our own PID, we will send to ourself a message to
1462 close the selected frame, which does not necessarily
1463 terminates Emacs. But then we are not supposed to call
1464 sys_kill with our own PID. */
1444 proc_hand = OpenProcess (PROCESS_TERMINATE, 0, pid); 1465 proc_hand = OpenProcess (PROCESS_TERMINATE, 0, pid);
1445 if (proc_hand == NULL) 1466 if (proc_hand == NULL)
1446 { 1467 {