Mercurial > hg > xemacs-beta
comparison src/process-nt.c @ 373:6240c7796c7a r21-2b2
Import from CVS: tag r21-2b2
author | cvs |
---|---|
date | Mon, 13 Aug 2007 11:04:06 +0200 |
parents | cc15677e0335 |
children | 8626e4521993 |
comparison
equal
deleted
inserted
replaced
372:49e1ed2d7ed8 | 373:6240c7796c7a |
---|---|
36 #include <shellapi.h> | 36 #include <shellapi.h> |
37 #include <signal.h> | 37 #include <signal.h> |
38 #ifdef HAVE_SOCKETS | 38 #ifdef HAVE_SOCKETS |
39 #include <winsock.h> | 39 #include <winsock.h> |
40 #endif | 40 #endif |
41 | |
42 /* Arbitrary size limit for code fragments passed to run_in_other_process */ | |
43 #define FRAGMENT_CODE_SIZE 32 | |
41 | 44 |
42 /* Bound by winnt.el */ | 45 /* Bound by winnt.el */ |
43 Lisp_Object Qnt_quote_process_args; | 46 Lisp_Object Qnt_quote_process_args; |
44 | 47 |
45 /* Implemenation-specific data. Pointed to by Lisp_Process->process_data */ | 48 /* Implemenation-specific data. Pointed to by Lisp_Process->process_data */ |
141 ResumeThread (pmc->h_thread); | 144 ResumeThread (pmc->h_thread); |
142 } | 145 } |
143 | 146 |
144 /* | 147 /* |
145 * Run ROUTINE in the context of process determined by H_PROCESS. The | 148 * Run ROUTINE in the context of process determined by H_PROCESS. The |
146 * routine is passed the address of DATA as parameter. CODE_END is the | 149 * routine is passed the address of DATA as parameter. The ROUTINE must |
147 * address immediately after ROUTINE's code. DATA_SIZE is the size of | 150 * not be longer than ROUTINE_CODE_SIZE bytes. DATA_SIZE is the size of |
148 * DATA structure. | 151 * DATA structure. |
149 * | 152 * |
150 * Note that the code must be positionally independent, and compiled | 153 * Note that the code must be positionally independent, and compiled |
151 * without stack checks (they cause implicit calls into CRT so will | 154 * without stack checks (they cause implicit calls into CRT so will |
152 * fail). DATA should not refer any data in calling process, as both | 155 * fail). DATA should not refer any data in calling process, as both |
155 * | 158 * |
156 * Return the value returned by ROUTINE, or (DWORD)-1 if call failed. | 159 * Return the value returned by ROUTINE, or (DWORD)-1 if call failed. |
157 */ | 160 */ |
158 static DWORD | 161 static DWORD |
159 run_in_other_process (HANDLE h_process, | 162 run_in_other_process (HANDLE h_process, |
160 LPTHREAD_START_ROUTINE routine, LPVOID code_end, | 163 LPTHREAD_START_ROUTINE routine, |
161 LPVOID data, size_t data_size) | 164 LPVOID data, size_t data_size) |
162 { | 165 { |
163 process_memory pm; | 166 process_memory pm; |
164 size_t code_size = (LPBYTE)code_end - (LPBYTE)routine; | 167 CONST size_t code_size = FRAGMENT_CODE_SIZE; |
165 /* Need at most 3 extra bytes of memory, for data alignment */ | 168 /* Need at most 3 extra bytes of memory, for data alignment */ |
166 size_t total_size = code_size + data_size + 3; | 169 size_t total_size = code_size + data_size + 3; |
167 LPVOID remote_data; | 170 LPVOID remote_data; |
168 HANDLE h_thread; | 171 HANDLE h_thread; |
169 DWORD dw_unused; | 172 DWORD dw_unused; |
221 * We handle the following signals: | 224 * We handle the following signals: |
222 * | 225 * |
223 * SIGKILL, SIGTERM, SIGQUIT, SIGHUP - These four translate to ExitProcess | 226 * SIGKILL, SIGTERM, SIGQUIT, SIGHUP - These four translate to ExitProcess |
224 * executed by the remote process | 227 * executed by the remote process |
225 * SIGINT - The remote process is sent CTRL_BREAK_EVENT | 228 * SIGINT - The remote process is sent CTRL_BREAK_EVENT |
229 * | |
230 * The MSVC5.0 compiler feels free to re-order functions within a | |
231 * compilation unit, so we have no way of finding out the size of the | |
232 * following functions. Therefore these functions must not be larger than | |
233 * FRAGMENT_CODE_SIZE. | |
226 */ | 234 */ |
227 | 235 |
228 /* | 236 /* |
229 * Sending SIGKILL | 237 * Sending SIGKILL |
230 */ | 238 */ |
236 static DWORD WINAPI | 244 static DWORD WINAPI |
237 sigkill_proc (sigkill_data* data) | 245 sigkill_proc (sigkill_data* data) |
238 { | 246 { |
239 (*data->adr_ExitProcess)(255); | 247 (*data->adr_ExitProcess)(255); |
240 return 1; | 248 return 1; |
241 } | |
242 | |
243 /* Watermark in code space */ | |
244 static void | |
245 sigkill_code_end (void) | |
246 { | |
247 } | 249 } |
248 | 250 |
249 /* | 251 /* |
250 * Sending break or control c | 252 * Sending break or control c |
251 */ | 253 */ |
259 sigint_proc (sigint_data* data) | 261 sigint_proc (sigint_data* data) |
260 { | 262 { |
261 return (*data->adr_GenerateConsoleCtrlEvent) (data->event, 0); | 263 return (*data->adr_GenerateConsoleCtrlEvent) (data->event, 0); |
262 } | 264 } |
263 | 265 |
264 /* Watermark in code space */ | |
265 static void | |
266 sigint_code_end (void) | |
267 { | |
268 } | |
269 | |
270 /* | 266 /* |
271 * Enabling signals | 267 * Enabling signals |
272 */ | 268 */ |
273 typedef struct | 269 typedef struct |
274 { | 270 { |
278 static DWORD WINAPI | 274 static DWORD WINAPI |
279 sig_enable_proc (sig_enable_data* data) | 275 sig_enable_proc (sig_enable_data* data) |
280 { | 276 { |
281 (*data->adr_SetConsoleCtrlHandler) (NULL, FALSE); | 277 (*data->adr_SetConsoleCtrlHandler) (NULL, FALSE); |
282 return 1; | 278 return 1; |
283 } | |
284 | |
285 /* Watermark in code space */ | |
286 static void | |
287 sig_enable_code_end (void) | |
288 { | |
289 } | 279 } |
290 | 280 |
291 /* | 281 /* |
292 * Send signal SIGNO to process H_PROCESS. | 282 * Send signal SIGNO to process H_PROCESS. |
293 * Return nonzero if successful. | 283 * Return nonzero if successful. |
314 case SIGHUP: | 304 case SIGHUP: |
315 { | 305 { |
316 sigkill_data d; | 306 sigkill_data d; |
317 d.adr_ExitProcess = GetProcAddress (h_kernel, "ExitProcess"); | 307 d.adr_ExitProcess = GetProcAddress (h_kernel, "ExitProcess"); |
318 assert (d.adr_ExitProcess); | 308 assert (d.adr_ExitProcess); |
319 retval = run_in_other_process (h_process, | 309 retval = run_in_other_process (h_process, sigkill_proc, |
320 sigkill_proc, sigkill_code_end, | |
321 &d, sizeof (d)); | 310 &d, sizeof (d)); |
322 break; | 311 break; |
323 } | 312 } |
324 case SIGINT: | 313 case SIGINT: |
325 { | 314 { |
326 sigint_data d; | 315 sigint_data d; |
327 d.adr_GenerateConsoleCtrlEvent = | 316 d.adr_GenerateConsoleCtrlEvent = |
328 GetProcAddress (h_kernel, "GenerateConsoleCtrlEvent"); | 317 GetProcAddress (h_kernel, "GenerateConsoleCtrlEvent"); |
329 assert (d.adr_GenerateConsoleCtrlEvent); | 318 assert (d.adr_GenerateConsoleCtrlEvent); |
330 d.event = CTRL_C_EVENT; | 319 d.event = CTRL_C_EVENT; |
331 retval = run_in_other_process (h_process, | 320 retval = run_in_other_process (h_process, sigint_proc, |
332 sigint_proc, sigint_code_end, | |
333 &d, sizeof (d)); | 321 &d, sizeof (d)); |
334 break; | 322 break; |
335 } | 323 } |
336 default: | 324 default: |
337 assert (0); | 325 assert (0); |
351 | 339 |
352 assert (h_kernel != NULL); | 340 assert (h_kernel != NULL); |
353 d.adr_SetConsoleCtrlHandler = | 341 d.adr_SetConsoleCtrlHandler = |
354 GetProcAddress (h_kernel, "SetConsoleCtrlHandler"); | 342 GetProcAddress (h_kernel, "SetConsoleCtrlHandler"); |
355 assert (d.adr_SetConsoleCtrlHandler); | 343 assert (d.adr_SetConsoleCtrlHandler); |
356 run_in_other_process (h_process, | 344 run_in_other_process (h_process, sig_enable_proc, |
357 sig_enable_proc, sig_enable_code_end, | |
358 &d, sizeof (d)); | 345 &d, sizeof (d)); |
359 } | 346 } |
360 | 347 |
361 #pragma warning (default : 4113) | 348 #pragma warning (default : 4113) |
362 | 349 |