Add support for external html docs
[maxima.git] / interfaces / xmaxima / win32 / tclwinkill.c
blobb3249c371f97be1e1f1cf26c20a349c59ac8be14
1 /*
2 gcc -fPIC -c -g -O2 testload.c
3 gcc -shared tclWinkill.o -ltclstub -o winkill.dll
4 and then load winkill.dll
5 winkill -pid 23423 -signal INT
6 # should rewrite this all to make more general utilitity:
7 sharedmem init name length
8 sharedmem set name ind value
9 sharedmem get name ind length
15 to just init the shared memory..
16 winkill -pid 23423
19 #define USE_TCL_STUBS
21 #include "windows.h"
23 #include "tcl.h"
26 #undef TCL_STORAGE_CLASS
27 #define TCL_STORAGE_CLASS DLLEXPORT
29 #include <stdlib.h>
30 #include <signal.h>
32 #define signal_mask(n) (1 << (n))
35 typedef struct _sharedMemory sharedMemory;
36 struct _sharedMemory {
37 HANDLE handle;
38 LPVOID address;
39 DWORD length ;
40 char name[20] ;
41 int pid;
42 sharedMemory *next;
45 static sharedMemory *sharedMemoryPtr;
47 #define MEMSIZE 0x10000
51 typedef struct {int signumber; char *name ;} sigNameStruct;
52 sigNameStruct sigNames[]=
54 #ifdef SIGHUP
55 { SIGHUP, "HUP" }, /* Hangup (POSIX). */
56 #endif
57 #ifdef SIGINT
58 { SIGINT, "INT" }, /* Interrupt (ANSI). */
59 #endif
60 #ifdef SIGQUIT
61 { SIGQUIT, "QUIT" }, /* Quit (POSIX). */
62 #endif
63 #ifdef SIGILL
64 { SIGILL, "ILL" }, /* Illegal instruction (ANSI). */
65 #endif
66 #ifdef SIGTRAP
67 { SIGTRAP, "TRAP" }, /* Trace trap (POSIX). */
68 #endif
69 #ifdef SIGABRT
70 { SIGABRT, "ABRT" }, /* Abort (ANSI). */
71 #endif
72 #ifdef SIGIOT
73 { SIGIOT, "IOT" }, /* IOT trap (4.2 BSD). */
74 #endif
75 #ifdef SIGBUS
76 { SIGBUS, "BUS" }, /* BUS error (4.2 BSD). */
77 #endif
78 #ifdef SIGFPE
79 { SIGFPE, "FPE" }, /* Floating-point exception (ANSI). */
80 #endif
81 #ifdef SIGKILL
82 { SIGKILL, "KILL" }, /* Kill, unblockable (POSIX). */
83 #endif
84 #ifdef SIGUSR1
85 { SIGUSR1, "USR1" }, /* User-defined signal 1 (POSIX). */
86 #endif
87 #ifdef SIGSEGV
88 { SIGSEGV, "SEGV" }, /* Segmentation violation (ANSI). */
89 #endif
90 #ifdef SIGUSR2
91 { SIGUSR2, "USR2" }, /* User-defined signal 2 (POSIX). */
92 #endif
93 #ifdef SIGPIPE
94 { SIGPIPE, "PIPE" }, /* Broken pipe (POSIX). */
95 #endif
96 #ifdef SIGALRM
97 { SIGALRM, "ALRM" }, /* Alarm clock (POSIX). */
98 #endif
99 #ifdef SIGTERM
100 { SIGTERM, "TERM" }, /* Termination (ANSI). */
101 #endif
102 #ifdef SIGSTKFLT
103 { SIGSTKFLT, "STKFLT" }, /* Stack fault. */
104 #endif
105 #ifdef SIGCLD
106 { SIGCLD, "CLD" }, /* Same as SIGCHLD (System V). */
107 #endif
108 #ifdef SIGCHLD
109 { SIGCHLD, "CHLD" }, /* Child status has changed (POSIX). */
110 #endif
111 #ifdef SIGCONT
112 { SIGCONT, "CONT" }, /* Continue (POSIX). */
113 #endif
114 #ifdef SIGSTOP
115 { SIGSTOP, "STOP" }, /* Stop, unblockable (POSIX). */
116 #endif
117 #ifdef SIGTSTP
118 { SIGTSTP, "TSTP" }, /* Keyboard stop (POSIX). */
119 #endif
120 #ifdef SIGTTIN
121 { SIGTTIN, "TTIN" }, /* Background read from tty (POSIX). */
122 #endif
123 #ifdef SIGTTOU
124 { SIGTTOU, "TTOU" }, /* Background write to tty (POSIX). */
125 #endif
126 #ifdef SIGURG
127 { SIGURG, "URG" }, /* Urgent condition on socket (4.2 BSD). */
128 #endif
129 #ifdef SIGXCPU
130 { SIGXCPU, "XCPU" }, /* CPU limit exceeded (4.2 BSD). */
131 #endif
132 #ifdef SIGXFSZ
133 { SIGXFSZ, "XFSZ" }, /* File size limit exceeded (4.2 BSD). */
134 #endif
135 #ifdef SIGVTALRM
136 { SIGVTALRM, "VTALRM" }, /* Virtual alarm clock (4.2 BSD). */
137 #endif
138 #ifdef SIGPROF
139 { SIGPROF, "PROF" }, /* Profiling alarm clock (4.2 BSD). */
140 #endif
141 #ifdef SIGWINCH
142 { SIGWINCH, "WINCH" }, /* Window size change (4.3 BSD, Sun). */
143 #endif
144 #ifdef SIGPOLL
145 { SIGPOLL, "POLL" }, /* Pollable event occurred (System V). */
146 #endif
147 #ifdef SIGIO
148 { SIGIO, "IO" }, /* I/O now possible (4.2 BSD). */
149 #endif
150 #ifdef SIGPWR
151 { SIGPWR, "PWR" }, /* Power failure restart (System V). */
152 #endif
153 #ifdef SIGSYS
154 { SIGSYS, "SYS" },
155 #endif
156 { 0,0}
160 Tcl_WinKillCmd(ClientData clientData,
161 Tcl_Interp *interp,
162 int argc,
163 char *argv[]);
166 void close_shared_memory1();
167 void close_shared_memory(ClientData clientData);
169 EXTERN int Tclwinkill_Init( Tcl_Interp *interp);
171 static int refcount;
175 Tclwinkill_Init( Tcl_Interp *interp)
177 if (!Tcl_InitStubs(interp, "8.0", 0)) {
178 return TCL_ERROR;
180 if (refcount==0)
181 atexit(close_shared_memory1);
182 refcount++;
183 Tcl_CreateCommand(interp, "winkill" ,Tcl_WinKillCmd ,NULL,close_shared_memory);
184 return TCL_OK;
190 void close_shared_memory(ClientData data)
192 if (--refcount <= 0) {
193 sharedMemory *p,*old = sharedMemoryPtr;
194 p = old;
195 while (p) {
196 if (p->handle) CloseHandle(p->handle);
197 p->handle = NULL;
198 if (p->address) UnmapViewOfFile(p->address);
199 p->address = NULL;
200 old = p;
201 p = p->next;
202 free(old);
205 sharedMemoryPtr=NULL;
208 #define ErrorHandler(x) do {Tcl_AppendResult(interp,x,0); return NULL;} while(0)
210 sharedMemory *
211 getSharedMemoryPtr(Tcl_Interp *interp,int pid)
213 sharedMemory shm;
214 sharedMemory * shmPtr = sharedMemoryPtr;
215 while (shmPtr) {
216 if (shmPtr->pid == pid) {
217 return shmPtr;
219 shmPtr=shmPtr->next;
222 shmPtr = &shm;
223 memset(&shm,0,sizeof(sharedMemory));
224 shmPtr->pid = pid;
225 shmPtr->next = NULL;
226 shmPtr->handle = NULL;
227 sprintf(shmPtr->name,"gcl-%d",pid);
229 int value;
230 int *at;
232 shmPtr->handle =
233 OpenFileMapping(FILE_MAP_WRITE, /* Read/write permission. */
234 FALSE, /* Do not inherit the name */
235 shmPtr->name); /* of the mapping object. */
237 if (shmPtr->handle == NULL)
239 ErrorHandler("winkill: Could not open file-mapping object.");
242 shmPtr->address =
243 MapViewOfFile(shmPtr->handle, /* Handle to mapping object. */
244 FILE_MAP_WRITE, /* Read/write permission. */
245 0, /* Max. object size. */
246 0, /* Size of hFile. */
247 0); /* Map entire file. */
249 if (shmPtr->address == NULL)
251 ErrorHandler("winkill: Could not map view of file.");
253 { sharedMemory *newPtr = malloc(sizeof(sharedMemory));
254 *newPtr = *shmPtr;
255 newPtr->next = sharedMemoryPtr;
256 sharedMemoryPtr = newPtr;
263 Tcl_WinKillCmd(ClientData clientData,
264 Tcl_Interp *interp,
265 int argc,
266 char *argv[])
267 {int sig=-1;
268 int pid=-1;
269 int i = 0;
270 int value = 0;
271 char *dosig = NULL;
272 char *in;
273 char *pidPtr = NULL;
274 sharedMemory *shmPtr;
275 sigNameStruct *sigNamePtr = sigNames;
277 if (argc < 3 || argv[1][0] != '-') {
279 USAGE:
280 Tcl_AppendResult(interp,"winkill -pid pid -signal SIG",0);
281 return TCL_ERROR;
284 for (i = 1 ; i < argc ; i+=2) {
285 if (argv[i][0]!='-') { goto USAGE;}
286 if (argv[i][1]=='s' && strcmp(&argv[i][1],"signal")==0) {
287 in = &(argv[i+1][1]);
288 if (sscanf(in,"%d",&sig)==0) {
289 while(sigNamePtr->name) {
290 if (strcmp(sigNamePtr->name,in)==0) {
291 sig = sigNamePtr->signumber;
292 break;
294 sigNamePtr++;
297 if (sig<0)
299 Tcl_AppendResult(interp,"Bad Signal",0);
300 goto USAGE;
302 value |= signal_mask(sig);
303 } else
304 if (argv[i][1]=='p' && strcmp(&argv[i][1],"pid")==0) {
305 pidPtr = argv[i+1];
306 if (1 != sscanf(argv[i+1],"%d",&pid)) {
307 Tcl_AppendResult(interp,"Bad pid arg:",argv[2],".",0);
308 goto USAGE;
311 else goto USAGE;
313 if (pidPtr== NULL || (shmPtr = getSharedMemoryPtr(interp,pid))==NULL) {
314 Tcl_AppendResult(interp,"Could not open shared memory for pid ",
315 pidPtr,0);
316 return TCL_ERROR;
318 { int *at;
319 at = (int *)(shmPtr->address);
320 *at |= value;
322 return TCL_OK;
326 void close_shared_memory1()
328 refcount=0;
329 close_shared_memory(NULL);