1 // Written by William Schelter.
2 // Additional work from Davind Billinghurst and Andrej Vopodivec.
4 // This program is free software; you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation; either version 2 of the License, or
7 // (at your option) any later version.
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software
17 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
19 // SPDX-License-Identifier: GPL-2.0+
22 // Winkill is a program that tries to find the shared memory location maxima
23 // offers on MS Windows in order to receive interrupt signals from a GUI.
31 #define signal_mask(n) (1 << (n))
35 Meant to resemble kill under unix. Basic idea is that the
36 process we want to kill, has a shared memory segment, and
37 we write into it the flag of the signal we want to send. That
38 process has to frequently check that memory location.
40 Sample USAGE: winkill -SIGNAL ProcessID
42 C:> winkill -INT 243232
51 } sharedMemory
= {0,0,0x10000} ;
55 typedef struct {int signumber
; char *name
;} sigNameStruct
;
56 sigNameStruct sigNames
[]=
59 { SIGHUP
, "HUP" }, /* Hangup (POSIX). */
62 { SIGINT
, "INT" }, /* Interrupt (ANSI). */
65 { SIGQUIT
, "QUIT" }, /* Quit (POSIX). */
68 { SIGILL
, "ILL" }, /* Illegal instruction (ANSI). */
71 { SIGTRAP
, "TRAP" }, /* Trace trap (POSIX). */
74 { SIGABRT
, "ABRT" }, /* Abort (ANSI). */
77 { SIGIOT
, "IOT" }, /* IOT trap (4.2 BSD). */
80 { SIGBUS
, "BUS" }, /* BUS error (4.2 BSD). */
83 { SIGFPE
, "FPE" }, /* Floating-point exception (ANSI). */
86 { SIGKILL
, "KILL" }, /* Kill, unblockable (POSIX). */
89 { SIGUSR1
, "USR1" }, /* User-defined signal 1 (POSIX). */
92 { SIGSEGV
, "SEGV" }, /* Segmentation violation (ANSI). */
95 { SIGUSR2
, "USR2" }, /* User-defined signal 2 (POSIX). */
98 { SIGPIPE
, "PIPE" }, /* Broken pipe (POSIX). */
101 { SIGALRM
, "ALRM" }, /* Alarm clock (POSIX). */
104 { SIGTERM
, "TERM" }, /* Termination (ANSI). */
107 { SIGSTKFLT
, "STKFLT" }, /* Stack fault. */
110 { SIGCLD
, "CLD" }, /* Same as SIGCHLD (System V). */
113 { SIGCHLD
, "CHLD" }, /* Child status has changed (POSIX). */
116 { SIGCONT
, "CONT" }, /* Continue (POSIX). */
119 { SIGSTOP
, "STOP" }, /* Stop, unblockable (POSIX). */
122 { SIGTSTP
, "TSTP" }, /* Keyboard stop (POSIX). */
125 { SIGTTIN
, "TTIN" }, /* Background read from tty (POSIX). */
128 { SIGTTOU
, "TTOU" }, /* Background write to tty (POSIX). */
131 { SIGURG
, "URG" }, /* Urgent condition on socket (4.2 BSD). */
134 { SIGXCPU
, "XCPU" }, /* CPU limit exceeded (4.2 BSD). */
137 { SIGXFSZ
, "XFSZ" }, /* File size limit exceeded (4.2 BSD). */
140 { SIGVTALRM
, "VTALRM" }, /* Virtual alarm clock (4.2 BSD). */
143 { SIGPROF
, "PROF" }, /* Profiling alarm clock (4.2 BSD). */
146 { SIGWINCH
, "WINCH" }, /* Window size change (4.3 BSD, Sun). */
149 { SIGPOLL
, "POLL" }, /* Pollable event occurred (System V). */
152 { SIGIO
, "IO" }, /* I/O now possible (4.2 BSD). */
155 { SIGPWR
, "PWR" }, /* Power failure restart (System V). */
163 int ErrorHandler(char *s
)
170 void close_shared_memory()
172 if (sharedMemory
.handle
)
173 CloseHandle(sharedMemory
.handle
);
174 sharedMemory
.handle
= NULL
;
175 if (sharedMemory
.address
)
176 UnmapViewOfFile(sharedMemory
.address
);
177 sharedMemory
.address
= NULL
;
182 int main(int argc
, char *argv
[])
189 sigNameStruct
*sigNamePtr
= sigNames
;
191 if (argc
< 3 || argv
[1][0] != '-') {
193 fprintf(stderr
,"Sample usage: winkill -INT 232423, to interrupt the process 232423 ");
196 fprintf(stderr
,"\nargv[1][0]=%c,%d",argv
[1][0],argv
[1][0]);
197 fprintf(stderr
,"\nCalled with: argc=%d <",argc
);
198 while (i
< argc
) fprintf(stderr
, " %s",argv
[i
++]);
199 fprintf(stderr
,">\n");
204 /* Find which signal to send. */
206 if (sscanf(&(argv
[1][1]),"%d",&sig
)==0) {
207 while(sigNamePtr
->name
) {
208 if (strcmp(sigNamePtr
->name
,in
)==0) {
209 sig
= sigNamePtr
->signumber
;
216 fprintf(stderr
,"winkill: Bad signal %s.", in
);
219 value
= signal_mask(sig
);
221 /* Find the process pid. */
222 if (sscanf(argv
[2],"%d",&pid
)!=1 ) {
223 fprintf(stderr
,"winkill: Bad pid %s.", argv
[2]);
227 /* First try to send the signal to gcl. */
228 sprintf(sharedMemory
.name
,"gcl-%d", pid
);
229 sharedMemory
.handle
= OpenFileMapping(FILE_MAP_WRITE
, /* Read/write permission. */
230 FALSE
, /* Do not inherit the name */
231 sharedMemory
.name
); /* of the mapping object. */
234 /* If gcl is not running, send to maxima. */
235 if (sharedMemory
.handle
== NULL
) {
236 sprintf(sharedMemory
.name
,"maxima-%d", pid
);
237 sharedMemory
.handle
= OpenFileMapping(FILE_MAP_WRITE
, /* Read/write permission. */
238 FALSE
, /* Do not inherit the name */
239 sharedMemory
.name
); /* of the mapping object. */
242 if (sharedMemory
.handle
== NULL
) {
243 printf("MEMORY: %s\n", sharedMemory
.name
);
244 ErrorHandler("winkill: Could not open file-mapping object.");
247 sharedMemory
.address
= MapViewOfFile(sharedMemory
.handle
, /* Handle to mapping object. */
248 FILE_MAP_WRITE
, /* Read/write permission. */
249 0, /* Max. object size. */
250 0, /* Size of hFile. */
251 0); /* Map entire file. */
253 if (sharedMemory
.address
== NULL
) {
254 ErrorHandler("winkill: Could not map view of file.");
257 at
= (int *)(sharedMemory
.address
);
259 close_shared_memory();