Add support for external html docs
[maxima.git] / interfaces / xmaxima / win32 / winkill.c
blobc514ca55a0c048d4d7d0cb55427ef214581aa48c
1 // Written by William Schelter.
2 // Additional work from Davind Billinghurst and Andrej Vopodivec.
3 //
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.
8 //
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.
24 //
26 #include <signal.h>
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <windows.h>
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
41 eg:
42 C:> winkill -INT 243232
46 static struct {
47 HANDLE handle;
48 LPVOID address;
49 DWORD length ;
50 char name[20] ;
51 } sharedMemory = {0,0,0x10000} ;
55 typedef struct {int signumber; char *name ;} sigNameStruct;
56 sigNameStruct sigNames[]=
58 #ifdef SIGHUP
59 { SIGHUP, "HUP" }, /* Hangup (POSIX). */
60 #endif
61 #ifdef SIGINT
62 { SIGINT, "INT" }, /* Interrupt (ANSI). */
63 #endif
64 #ifdef SIGQUIT
65 { SIGQUIT, "QUIT" }, /* Quit (POSIX). */
66 #endif
67 #ifdef SIGILL
68 { SIGILL, "ILL" }, /* Illegal instruction (ANSI). */
69 #endif
70 #ifdef SIGTRAP
71 { SIGTRAP, "TRAP" }, /* Trace trap (POSIX). */
72 #endif
73 #ifdef SIGABRT
74 { SIGABRT, "ABRT" }, /* Abort (ANSI). */
75 #endif
76 #ifdef SIGIOT
77 { SIGIOT, "IOT" }, /* IOT trap (4.2 BSD). */
78 #endif
79 #ifdef SIGBUS
80 { SIGBUS, "BUS" }, /* BUS error (4.2 BSD). */
81 #endif
82 #ifdef SIGFPE
83 { SIGFPE, "FPE" }, /* Floating-point exception (ANSI). */
84 #endif
85 #ifdef SIGKILL
86 { SIGKILL, "KILL" }, /* Kill, unblockable (POSIX). */
87 #endif
88 #ifdef SIGUSR1
89 { SIGUSR1, "USR1" }, /* User-defined signal 1 (POSIX). */
90 #endif
91 #ifdef SIGSEGV
92 { SIGSEGV, "SEGV" }, /* Segmentation violation (ANSI). */
93 #endif
94 #ifdef SIGUSR2
95 { SIGUSR2, "USR2" }, /* User-defined signal 2 (POSIX). */
96 #endif
97 #ifdef SIGPIPE
98 { SIGPIPE, "PIPE" }, /* Broken pipe (POSIX). */
99 #endif
100 #ifdef SIGALRM
101 { SIGALRM, "ALRM" }, /* Alarm clock (POSIX). */
102 #endif
103 #ifdef SIGTERM
104 { SIGTERM, "TERM" }, /* Termination (ANSI). */
105 #endif
106 #ifdef SIGSTKFLT
107 { SIGSTKFLT, "STKFLT" }, /* Stack fault. */
108 #endif
109 #ifdef SIGCLD
110 { SIGCLD, "CLD" }, /* Same as SIGCHLD (System V). */
111 #endif
112 #ifdef SIGCHLD
113 { SIGCHLD, "CHLD" }, /* Child status has changed (POSIX). */
114 #endif
115 #ifdef SIGCONT
116 { SIGCONT, "CONT" }, /* Continue (POSIX). */
117 #endif
118 #ifdef SIGSTOP
119 { SIGSTOP, "STOP" }, /* Stop, unblockable (POSIX). */
120 #endif
121 #ifdef SIGTSTP
122 { SIGTSTP, "TSTP" }, /* Keyboard stop (POSIX). */
123 #endif
124 #ifdef SIGTTIN
125 { SIGTTIN, "TTIN" }, /* Background read from tty (POSIX). */
126 #endif
127 #ifdef SIGTTOU
128 { SIGTTOU, "TTOU" }, /* Background write to tty (POSIX). */
129 #endif
130 #ifdef SIGURG
131 { SIGURG, "URG" }, /* Urgent condition on socket (4.2 BSD). */
132 #endif
133 #ifdef SIGXCPU
134 { SIGXCPU, "XCPU" }, /* CPU limit exceeded (4.2 BSD). */
135 #endif
136 #ifdef SIGXFSZ
137 { SIGXFSZ, "XFSZ" }, /* File size limit exceeded (4.2 BSD). */
138 #endif
139 #ifdef SIGVTALRM
140 { SIGVTALRM, "VTALRM" }, /* Virtual alarm clock (4.2 BSD). */
141 #endif
142 #ifdef SIGPROF
143 { SIGPROF, "PROF" }, /* Profiling alarm clock (4.2 BSD). */
144 #endif
145 #ifdef SIGWINCH
146 { SIGWINCH, "WINCH" }, /* Window size change (4.3 BSD, Sun). */
147 #endif
148 #ifdef SIGPOLL
149 { SIGPOLL, "POLL" }, /* Pollable event occurred (System V). */
150 #endif
151 #ifdef SIGIO
152 { SIGIO, "IO" }, /* I/O now possible (4.2 BSD). */
153 #endif
154 #ifdef SIGPWR
155 { SIGPWR, "PWR" }, /* Power failure restart (System V). */
156 #endif
157 #ifdef SIGSYS
158 { SIGSYS, "SYS" },
159 #endif
160 { 0,0}
163 int ErrorHandler(char *s)
165 fprintf(stderr,s);
166 fflush(stderr);
167 exit(1);
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[])
184 int sig=-1;
185 int pid=-1;
186 int value;
187 int *at;
188 char *in;
189 sigNameStruct *sigNamePtr = sigNames;
191 if (argc < 3 || argv[1][0] != '-') {
192 USAGE:
193 fprintf(stderr,"Sample usage: winkill -INT 232423, to interrupt the process 232423 ");
195 int i = 0;
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");
201 exit(1);
204 /* Find which signal to send. */
205 in = &(argv[1][1]);
206 if (sscanf(&(argv[1][1]),"%d",&sig)==0) {
207 while(sigNamePtr->name) {
208 if (strcmp(sigNamePtr->name,in)==0) {
209 sig = sigNamePtr->signumber;
210 break;
212 sigNamePtr++;
215 if (sig<0) {
216 fprintf(stderr,"winkill: Bad signal %s.", in);
217 goto USAGE;
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]);
224 goto USAGE;
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);
258 *at |= value;
259 close_shared_memory();
261 return 0;