(HAVE_LANGINFO_CODESET): Define.
[bpt/emacs.git] / src / w32proc.c
CommitLineData
e9e23e23 1/* Process support for GNU Emacs on the Microsoft W32 API.
0b5538bd 2 Copyright (C) 1992, 1995, 1999, 2000, 2001, 2002, 2003, 2004,
f9125cde 3 2005, 2006 Free Software Foundation, Inc.
6cdfb6e6 4
3b7ad313
EN
5This file is part of GNU Emacs.
6
7GNU Emacs is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 2, or (at your option)
10any later version.
11
12GNU Emacs is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with GNU Emacs; see the file COPYING. If not, write to
4fc5845f
LK
19the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20Boston, MA 02110-1301, USA.
6cdfb6e6
RS
21
22 Drew Bliss Oct 14, 1993
23 Adapted from alarm.c by Tim Fleehart
24*/
25
26#include <stdio.h>
27#include <stdlib.h>
28#include <errno.h>
29#include <io.h>
c519b5e1 30#include <fcntl.h>
6cdfb6e6 31#include <signal.h>
51f635c4 32#include <sys/file.h>
6cdfb6e6 33
c519b5e1 34/* must include CRT headers *before* config.h */
4838e624
PJ
35
36#ifdef HAVE_CONFIG_H
37#include <config.h>
38#endif
39
c519b5e1
GV
40#undef signal
41#undef wait
42#undef spawnve
43#undef select
44#undef kill
45
6cdfb6e6 46#include <windows.h>
42c95ffb
AI
47#ifdef __GNUC__
48/* This definition is missing from mingw32 headers. */
49extern BOOL WINAPI IsValidLocale(LCID, DWORD);
50#endif
6cdfb6e6
RS
51
52#include "lisp.h"
489f9371 53#include "w32.h"
b2fc9f3d 54#include "w32heap.h"
6cdfb6e6 55#include "systime.h"
3d7eead0
GV
56#include "syswait.h"
57#include "process.h"
e7c15bba 58#include "syssignal.h"
ef79fbba 59#include "w32term.h"
3d7eead0 60
8747ac3f
EZ
61#define RVA_TO_PTR(var,section,filedata) \
62 ((void *)((section)->PointerToRawData \
63 + ((DWORD)(var) - (section)->VirtualAddress) \
64 + (filedata).file_base))
65
93fdf2f8
RS
66/* Control whether spawnve quotes arguments as necessary to ensure
67 correct parsing by child process. Because not all uses of spawnve
68 are careful about constructing argv arrays, we make this behaviour
69 conditional (off by default). */
fbd6baed 70Lisp_Object Vw32_quote_process_args;
93fdf2f8 71
0ecf7d36
RS
72/* Control whether create_child causes the process' window to be
73 hidden. The default is nil. */
fbd6baed 74Lisp_Object Vw32_start_process_show_window;
0ecf7d36 75
b2fc9f3d
GV
76/* Control whether create_child causes the process to inherit Emacs'
77 console window, or be given a new one of its own. The default is
78 nil, to allow multiple DOS programs to run on Win95. Having separate
79 consoles also allows Emacs to cleanly terminate process groups. */
80Lisp_Object Vw32_start_process_share_console;
81
82e7c0a9
AI
82/* Control whether create_child cause the process to inherit Emacs'
83 error mode setting. The default is t, to minimize the possibility of
84 subprocesses blocking when accessing unmounted drives. */
85Lisp_Object Vw32_start_process_inherit_error_mode;
86
817abdf6
KH
87/* Time to sleep before reading from a subprocess output pipe - this
88 avoids the inefficiency of frequently reading small amounts of data.
89 This is primarily necessary for handling DOS processes on Windows 95,
e9e23e23 90 but is useful for W32 processes on both Windows 95 and NT as well. */
5322f50b 91int w32_pipe_read_delay;
817abdf6 92
0c04091e
RS
93/* Control conversion of upper case file names to lower case.
94 nil means no, t means yes. */
fbd6baed 95Lisp_Object Vw32_downcase_file_names;
0c04091e 96
b2fc9f3d
GV
97/* Control whether stat() attempts to generate fake but hopefully
98 "accurate" inode values, by hashing the absolute truenames of files.
99 This should detect aliasing between long and short names, but still
100 allows the possibility of hash collisions. */
101Lisp_Object Vw32_generate_fake_inodes;
102
103/* Control whether stat() attempts to determine file type and link count
104 exactly, at the expense of slower operation. Since true hard links
105 are supported on NTFS volumes, this is only relevant on NT. */
106Lisp_Object Vw32_get_true_file_attributes;
107
108Lisp_Object Qhigh, Qlow;
817abdf6 109
6cdfb6e6 110#ifdef EMACSDEBUG
c519b5e1 111void _DebPrint (const char *fmt, ...)
6cdfb6e6 112{
c519b5e1 113 char buf[1024];
6cdfb6e6
RS
114 va_list args;
115
116 va_start (args, fmt);
117 vsprintf (buf, fmt, args);
118 va_end (args);
119 OutputDebugString (buf);
120}
121#endif
122
c519b5e1 123typedef void (_CALLBACK_ *signal_handler)(int);
6cdfb6e6
RS
124
125/* Signal handlers...SIG_DFL == 0 so this is initialized correctly. */
126static signal_handler sig_handlers[NSIG];
127
128/* Fake signal implementation to record the SIGCHLD handler. */
177c0ea7 129signal_handler
c519b5e1 130sys_signal (int sig, signal_handler handler)
6cdfb6e6
RS
131{
132 signal_handler old;
177c0ea7 133
6cdfb6e6
RS
134 if (sig != SIGCHLD)
135 {
136 errno = EINVAL;
137 return SIG_ERR;
138 }
139 old = sig_handlers[sig];
140 sig_handlers[sig] = handler;
141 return old;
142}
143
c519b5e1
GV
144/* Defined in <process.h> which conflicts with the local copy */
145#define _P_NOWAIT 1
146
147/* Child process management list. */
148int child_proc_count = 0;
149child_process child_procs[ MAX_CHILDREN ];
150child_process *dead_child = NULL;
151
152DWORD WINAPI reader_thread (void *arg);
153
6cdfb6e6 154/* Find an unused process slot. */
c519b5e1 155child_process *
6cdfb6e6
RS
156new_child (void)
157{
158 child_process *cp;
c519b5e1 159 DWORD id;
177c0ea7 160
6cdfb6e6
RS
161 for (cp = child_procs+(child_proc_count-1); cp >= child_procs; cp--)
162 if (!CHILD_ACTIVE (cp))
c519b5e1
GV
163 goto Initialise;
164 if (child_proc_count == MAX_CHILDREN)
165 return NULL;
166 cp = &child_procs[child_proc_count++];
167
168 Initialise:
169 memset (cp, 0, sizeof(*cp));
170 cp->fd = -1;
171 cp->pid = -1;
172 cp->procinfo.hProcess = NULL;
173 cp->status = STATUS_READ_ERROR;
174
175 /* use manual reset event so that select() will function properly */
176 cp->char_avail = CreateEvent (NULL, TRUE, FALSE, NULL);
177 if (cp->char_avail)
178 {
179 cp->char_consumed = CreateEvent (NULL, FALSE, FALSE, NULL);
180 if (cp->char_consumed)
181 {
182 cp->thrd = CreateThread (NULL, 1024, reader_thread, cp, 0, &id);
183 if (cp->thrd)
184 return cp;
185 }
186 }
187 delete_child (cp);
188 return NULL;
189}
190
177c0ea7 191void
c519b5e1
GV
192delete_child (child_process *cp)
193{
194 int i;
195
196 /* Should not be deleting a child that is still needed. */
197 for (i = 0; i < MAXDESC; i++)
198 if (fd_info[i].cp == cp)
199 abort ();
200
201 if (!CHILD_ACTIVE (cp))
202 return;
203
204 /* reap thread if necessary */
205 if (cp->thrd)
206 {
207 DWORD rc;
208
209 if (GetExitCodeThread (cp->thrd, &rc) && rc == STILL_ACTIVE)
210 {
211 /* let the thread exit cleanly if possible */
212 cp->status = STATUS_READ_ERROR;
213 SetEvent (cp->char_consumed);
214 if (WaitForSingleObject (cp->thrd, 1000) != WAIT_OBJECT_0)
215 {
216 DebPrint (("delete_child.WaitForSingleObject (thread) failed "
217 "with %lu for fd %ld\n", GetLastError (), cp->fd));
218 TerminateThread (cp->thrd, 0);
219 }
220 }
221 CloseHandle (cp->thrd);
222 cp->thrd = NULL;
223 }
224 if (cp->char_avail)
225 {
226 CloseHandle (cp->char_avail);
227 cp->char_avail = NULL;
228 }
229 if (cp->char_consumed)
230 {
231 CloseHandle (cp->char_consumed);
232 cp->char_consumed = NULL;
233 }
234
235 /* update child_proc_count (highest numbered slot in use plus one) */
236 if (cp == child_procs + child_proc_count - 1)
237 {
238 for (i = child_proc_count-1; i >= 0; i--)
239 if (CHILD_ACTIVE (&child_procs[i]))
240 {
241 child_proc_count = i + 1;
242 break;
243 }
244 }
245 if (i < 0)
246 child_proc_count = 0;
6cdfb6e6
RS
247}
248
249/* Find a child by pid. */
250static child_process *
251find_child_pid (DWORD pid)
252{
253 child_process *cp;
c519b5e1 254
6cdfb6e6
RS
255 for (cp = child_procs+(child_proc_count-1); cp >= child_procs; cp--)
256 if (CHILD_ACTIVE (cp) && pid == cp->pid)
257 return cp;
258 return NULL;
259}
260
6cdfb6e6 261
c519b5e1
GV
262/* Thread proc for child process and socket reader threads. Each thread
263 is normally blocked until woken by select() to check for input by
264 reading one char. When the read completes, char_avail is signalled
265 to wake up the select emulator and the thread blocks itself again. */
177c0ea7 266DWORD WINAPI
6cdfb6e6
RS
267reader_thread (void *arg)
268{
269 child_process *cp;
177c0ea7 270
6cdfb6e6
RS
271 /* Our identity */
272 cp = (child_process *)arg;
177c0ea7 273
6cdfb6e6 274 /* We have to wait for the go-ahead before we can start */
b2fc9f3d
GV
275 if (cp == NULL
276 || WaitForSingleObject (cp->char_consumed, INFINITE) != WAIT_OBJECT_0)
c519b5e1
GV
277 return 1;
278
6cdfb6e6
RS
279 for (;;)
280 {
c519b5e1
GV
281 int rc;
282
f9125cde
KS
283 if (fd_info[cp->fd].flags & FILE_LISTEN)
284 rc = _sys_wait_accept (cp->fd);
285 else
286 rc = _sys_read_ahead (cp->fd);
c519b5e1
GV
287
288 /* The name char_avail is a misnomer - it really just means the
289 read-ahead has completed, whether successfully or not. */
6cdfb6e6
RS
290 if (!SetEvent (cp->char_avail))
291 {
292 DebPrint (("reader_thread.SetEvent failed with %lu for fd %ld\n",
293 GetLastError (), cp->fd));
c519b5e1
GV
294 return 1;
295 }
296
297 if (rc == STATUS_READ_ERROR)
298 return 1;
177c0ea7 299
6cdfb6e6 300 /* If the read died, the child has died so let the thread die */
c519b5e1 301 if (rc == STATUS_READ_FAILED)
6cdfb6e6 302 break;
177c0ea7 303
6cdfb6e6
RS
304 /* Wait until our input is acknowledged before reading again */
305 if (WaitForSingleObject (cp->char_consumed, INFINITE) != WAIT_OBJECT_0)
306 {
307 DebPrint (("reader_thread.WaitForSingleObject failed with "
308 "%lu for fd %ld\n", GetLastError (), cp->fd));
309 break;
310 }
311 }
312 return 0;
313}
314
b2fc9f3d
GV
315/* To avoid Emacs changing directory, we just record here the directory
316 the new process should start in. This is set just before calling
317 sys_spawnve, and is not generally valid at any other time. */
318static char * process_dir;
319
177c0ea7 320static BOOL
a55a5f3c 321create_child (char *exe, char *cmdline, char *env, int is_gui_app,
c519b5e1 322 int * pPid, child_process *cp)
6cdfb6e6 323{
6cdfb6e6
RS
324 STARTUPINFO start;
325 SECURITY_ATTRIBUTES sec_attrs;
42c95ffb 326#if 0
6cdfb6e6 327 SECURITY_DESCRIPTOR sec_desc;
42c95ffb 328#endif
82e7c0a9 329 DWORD flags;
b2fc9f3d 330 char dir[ MAXPATHLEN ];
177c0ea7 331
c519b5e1 332 if (cp == NULL) abort ();
177c0ea7 333
6cdfb6e6
RS
334 memset (&start, 0, sizeof (start));
335 start.cb = sizeof (start);
177c0ea7 336
58d4e829 337#ifdef HAVE_NTGUI
a55a5f3c 338 if (NILP (Vw32_start_process_show_window) && !is_gui_app)
0ecf7d36
RS
339 start.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
340 else
341 start.dwFlags = STARTF_USESTDHANDLES;
58d4e829
GV
342 start.wShowWindow = SW_HIDE;
343
344 start.hStdInput = GetStdHandle (STD_INPUT_HANDLE);
345 start.hStdOutput = GetStdHandle (STD_OUTPUT_HANDLE);
346 start.hStdError = GetStdHandle (STD_ERROR_HANDLE);
347#endif /* HAVE_NTGUI */
348
42c95ffb 349#if 0
6cdfb6e6
RS
350 /* Explicitly specify no security */
351 if (!InitializeSecurityDescriptor (&sec_desc, SECURITY_DESCRIPTOR_REVISION))
c519b5e1 352 goto EH_Fail;
6cdfb6e6 353 if (!SetSecurityDescriptorDacl (&sec_desc, TRUE, NULL, FALSE))
c519b5e1 354 goto EH_Fail;
42c95ffb 355#endif
6cdfb6e6 356 sec_attrs.nLength = sizeof (sec_attrs);
42c95ffb 357 sec_attrs.lpSecurityDescriptor = NULL /* &sec_desc */;
6cdfb6e6 358 sec_attrs.bInheritHandle = FALSE;
177c0ea7 359
b2fc9f3d
GV
360 strcpy (dir, process_dir);
361 unixtodos_filename (dir);
82e7c0a9
AI
362
363 flags = (!NILP (Vw32_start_process_share_console)
364 ? CREATE_NEW_PROCESS_GROUP
365 : CREATE_NEW_CONSOLE);
366 if (NILP (Vw32_start_process_inherit_error_mode))
367 flags |= CREATE_DEFAULT_ERROR_MODE;
6cdfb6e6 368 if (!CreateProcess (exe, cmdline, &sec_attrs, NULL, TRUE,
82e7c0a9 369 flags, env, dir, &start, &cp->procinfo))
c519b5e1
GV
370 goto EH_Fail;
371
372 cp->pid = (int) cp->procinfo.dwProcessId;
373
374 /* Hack for Windows 95, which assigns large (ie negative) pids */
375 if (cp->pid < 0)
376 cp->pid = -cp->pid;
377
378 /* pid must fit in a Lisp_Int */
acba5cae 379 cp->pid = cp->pid & INTMASK;
c519b5e1 380
c519b5e1 381 *pPid = cp->pid;
b2fc9f3d 382
6cdfb6e6 383 return TRUE;
b2fc9f3d 384
6cdfb6e6 385 EH_Fail:
c519b5e1 386 DebPrint (("create_child.CreateProcess failed: %ld\n", GetLastError()););
6cdfb6e6
RS
387 return FALSE;
388}
389
390/* create_child doesn't know what emacs' file handle will be for waiting
391 on output from the child, so we need to make this additional call
392 to register the handle with the process
393 This way the select emulator knows how to match file handles with
394 entries in child_procs. */
177c0ea7 395void
6cdfb6e6
RS
396register_child (int pid, int fd)
397{
398 child_process *cp;
177c0ea7 399
6cdfb6e6
RS
400 cp = find_child_pid (pid);
401 if (cp == NULL)
402 {
403 DebPrint (("register_child unable to find pid %lu\n", pid));
404 return;
405 }
177c0ea7 406
6cdfb6e6
RS
407#ifdef FULL_DEBUG
408 DebPrint (("register_child registered fd %d with pid %lu\n", fd, pid));
409#endif
177c0ea7 410
6cdfb6e6 411 cp->fd = fd;
6cdfb6e6 412
c519b5e1
GV
413 /* thread is initially blocked until select is called; set status so
414 that select will release thread */
415 cp->status = STATUS_READ_ACKNOWLEDGED;
416
417 /* attach child_process to fd_info */
418 if (fd_info[fd].cp != NULL)
6cdfb6e6 419 {
c519b5e1
GV
420 DebPrint (("register_child: fd_info[%d] apparently in use!\n", fd));
421 abort ();
6cdfb6e6 422 }
c519b5e1
GV
423
424 fd_info[fd].cp = cp;
6cdfb6e6
RS
425}
426
427/* When a process dies its pipe will break so the reader thread will
428 signal failure to the select emulator.
429 The select emulator then calls this routine to clean up.
430 Since the thread signaled failure we can assume it is exiting. */
177c0ea7 431static void
c519b5e1 432reap_subprocess (child_process *cp)
6cdfb6e6 433{
c519b5e1 434 if (cp->procinfo.hProcess)
6cdfb6e6 435 {
c519b5e1 436 /* Reap the process */
b2fc9f3d
GV
437#ifdef FULL_DEBUG
438 /* Process should have already died before we are called. */
439 if (WaitForSingleObject (cp->procinfo.hProcess, 0) != WAIT_OBJECT_0)
440 DebPrint (("reap_subprocess: child fpr fd %d has not died yet!", cp->fd));
441#endif
c519b5e1
GV
442 CloseHandle (cp->procinfo.hProcess);
443 cp->procinfo.hProcess = NULL;
444 CloseHandle (cp->procinfo.hThread);
445 cp->procinfo.hThread = NULL;
6cdfb6e6 446 }
c519b5e1
GV
447
448 /* For asynchronous children, the child_proc resources will be freed
449 when the last pipe read descriptor is closed; for synchronous
450 children, we must explicitly free the resources now because
451 register_child has not been called. */
452 if (cp->fd == -1)
453 delete_child (cp);
6cdfb6e6
RS
454}
455
456/* Wait for any of our existing child processes to die
457 When it does, close its handle
458 Return the pid and fill in the status if non-NULL. */
22759c72 459
177c0ea7 460int
c519b5e1 461sys_wait (int *status)
6cdfb6e6
RS
462{
463 DWORD active, retval;
464 int nh;
c519b5e1 465 int pid;
6cdfb6e6
RS
466 child_process *cp, *cps[MAX_CHILDREN];
467 HANDLE wait_hnd[MAX_CHILDREN];
177c0ea7 468
6cdfb6e6
RS
469 nh = 0;
470 if (dead_child != NULL)
471 {
472 /* We want to wait for a specific child */
c519b5e1 473 wait_hnd[nh] = dead_child->procinfo.hProcess;
6cdfb6e6 474 cps[nh] = dead_child;
c519b5e1 475 if (!wait_hnd[nh]) abort ();
6cdfb6e6 476 nh++;
b2fc9f3d
GV
477 active = 0;
478 goto get_result;
6cdfb6e6
RS
479 }
480 else
481 {
482 for (cp = child_procs+(child_proc_count-1); cp >= child_procs; cp--)
c519b5e1
GV
483 /* some child_procs might be sockets; ignore them */
484 if (CHILD_ACTIVE (cp) && cp->procinfo.hProcess)
6cdfb6e6 485 {
c519b5e1 486 wait_hnd[nh] = cp->procinfo.hProcess;
6cdfb6e6
RS
487 cps[nh] = cp;
488 nh++;
489 }
490 }
177c0ea7 491
6cdfb6e6
RS
492 if (nh == 0)
493 {
494 /* Nothing to wait on, so fail */
495 errno = ECHILD;
496 return -1;
497 }
b2fc9f3d
GV
498
499 do
500 {
501 /* Check for quit about once a second. */
502 QUIT;
503 active = WaitForMultipleObjects (nh, wait_hnd, FALSE, 1000);
504 } while (active == WAIT_TIMEOUT);
505
6cdfb6e6
RS
506 if (active == WAIT_FAILED)
507 {
508 errno = EBADF;
509 return -1;
510 }
b2fc9f3d
GV
511 else if (active >= WAIT_OBJECT_0
512 && active < WAIT_OBJECT_0+MAXIMUM_WAIT_OBJECTS)
6cdfb6e6
RS
513 {
514 active -= WAIT_OBJECT_0;
515 }
b2fc9f3d
GV
516 else if (active >= WAIT_ABANDONED_0
517 && active < WAIT_ABANDONED_0+MAXIMUM_WAIT_OBJECTS)
6cdfb6e6
RS
518 {
519 active -= WAIT_ABANDONED_0;
520 }
b2fc9f3d
GV
521 else
522 abort ();
523
524get_result:
6cdfb6e6
RS
525 if (!GetExitCodeProcess (wait_hnd[active], &retval))
526 {
527 DebPrint (("Wait.GetExitCodeProcess failed with %lu\n",
528 GetLastError ()));
529 retval = 1;
530 }
531 if (retval == STILL_ACTIVE)
532 {
533 /* Should never happen */
534 DebPrint (("Wait.WaitForMultipleObjects returned an active process\n"));
535 errno = EINVAL;
536 return -1;
537 }
bc69349b
RS
538
539 /* Massage the exit code from the process to match the format expected
8e6208c5 540 by the WIFSTOPPED et al macros in syswait.h. Only WIFSIGNALED and
bc69349b
RS
541 WIFEXITED are supported; WIFSTOPPED doesn't make sense under NT. */
542
543 if (retval == STATUS_CONTROL_C_EXIT)
544 retval = SIGINT;
545 else
546 retval <<= 8;
177c0ea7 547
6cdfb6e6 548 cp = cps[active];
c519b5e1
GV
549 pid = cp->pid;
550#ifdef FULL_DEBUG
551 DebPrint (("Wait signaled with process pid %d\n", cp->pid));
552#endif
22759c72 553
6cdfb6e6
RS
554 if (status)
555 {
22759c72
KH
556 *status = retval;
557 }
558 else if (synch_process_alive)
559 {
560 synch_process_alive = 0;
22759c72 561
3d7eead0
GV
562 /* Report the status of the synchronous process. */
563 if (WIFEXITED (retval))
564 synch_process_retcode = WRETCODE (retval);
565 else if (WIFSIGNALED (retval))
566 {
567 int code = WTERMSIG (retval);
68c45bf0
PE
568 char *signame;
569
ca9c0567 570 synchronize_system_messages_locale ();
68c45bf0
PE
571 signame = strsignal (code);
572
3d7eead0
GV
573 if (signame == 0)
574 signame = "unknown";
575
576 synch_process_death = signame;
577 }
c519b5e1
GV
578
579 reap_subprocess (cp);
6cdfb6e6 580 }
b2fc9f3d
GV
581
582 reap_subprocess (cp);
177c0ea7 583
c519b5e1 584 return pid;
6cdfb6e6
RS
585}
586
b2fc9f3d 587void
a55a5f3c 588w32_executable_type (char * filename, int * is_dos_app, int * is_cygnus_app, int * is_gui_app)
817abdf6 589{
b2fc9f3d
GV
590 file_data executable;
591 char * p;
177c0ea7 592
b2fc9f3d
GV
593 /* Default values in case we can't tell for sure. */
594 *is_dos_app = FALSE;
595 *is_cygnus_app = FALSE;
a55a5f3c 596 *is_gui_app = FALSE;
b2fc9f3d
GV
597
598 if (!open_input_file (&executable, filename))
599 return;
817abdf6 600
b2fc9f3d 601 p = strrchr (filename, '.');
177c0ea7 602
b2fc9f3d
GV
603 /* We can only identify DOS .com programs from the extension. */
604 if (p && stricmp (p, ".com") == 0)
605 *is_dos_app = TRUE;
606 else if (p && (stricmp (p, ".bat") == 0
607 || stricmp (p, ".cmd") == 0))
608 {
609 /* A DOS shell script - it appears that CreateProcess is happy to
610 accept this (somewhat surprisingly); presumably it looks at
611 COMSPEC to determine what executable to actually invoke.
612 Therefore, we have to do the same here as well. */
613 /* Actually, I think it uses the program association for that
614 extension, which is defined in the registry. */
615 p = egetenv ("COMSPEC");
616 if (p)
a55a5f3c 617 w32_executable_type (p, is_dos_app, is_cygnus_app, is_gui_app);
b2fc9f3d
GV
618 }
619 else
817abdf6 620 {
b2fc9f3d
GV
621 /* Look for DOS .exe signature - if found, we must also check that
622 it isn't really a 16- or 32-bit Windows exe, since both formats
623 start with a DOS program stub. Note that 16-bit Windows
624 executables use the OS/2 1.x format. */
817abdf6 625
b2fc9f3d
GV
626 IMAGE_DOS_HEADER * dos_header;
627 IMAGE_NT_HEADERS * nt_header;
628
629 dos_header = (PIMAGE_DOS_HEADER) executable.file_base;
630 if (dos_header->e_magic != IMAGE_DOS_SIGNATURE)
631 goto unwind;
632
633 nt_header = (PIMAGE_NT_HEADERS) ((char *) dos_header + dos_header->e_lfanew);
634
177c0ea7 635 if ((char *) nt_header > (char *) dos_header + executable.size)
817abdf6 636 {
b2fc9f3d
GV
637 /* Some dos headers (pkunzip) have bogus e_lfanew fields. */
638 *is_dos_app = TRUE;
177c0ea7 639 }
b2fc9f3d
GV
640 else if (nt_header->Signature != IMAGE_NT_SIGNATURE
641 && LOWORD (nt_header->Signature) != IMAGE_OS2_SIGNATURE)
642 {
643 *is_dos_app = TRUE;
644 }
645 else if (nt_header->Signature == IMAGE_NT_SIGNATURE)
646 {
647 /* Look for cygwin.dll in DLL import list. */
648 IMAGE_DATA_DIRECTORY import_dir =
649 nt_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT];
650 IMAGE_IMPORT_DESCRIPTOR * imports;
651 IMAGE_SECTION_HEADER * section;
652
653 section = rva_to_section (import_dir.VirtualAddress, nt_header);
654 imports = RVA_TO_PTR (import_dir.VirtualAddress, section, executable);
655
656 for ( ; imports->Name; imports++)
657 {
658 char * dllname = RVA_TO_PTR (imports->Name, section, executable);
659
a7325b56
AI
660 /* The exact name of the cygwin dll has changed with
661 various releases, but hopefully this will be reasonably
662 future proof. */
663 if (strncmp (dllname, "cygwin", 6) == 0)
b2fc9f3d
GV
664 {
665 *is_cygnus_app = TRUE;
666 break;
667 }
668 }
a55a5f3c
AI
669
670 /* Check whether app is marked as a console or windowed (aka
671 GUI) app. Accept Posix and OS2 subsytem apps as console
672 apps. */
673 *is_gui_app = (nt_header->OptionalHeader.Subsystem == IMAGE_SUBSYSTEM_WINDOWS_GUI);
b2fc9f3d 674 }
817abdf6 675 }
177c0ea7 676
b2fc9f3d
GV
677unwind:
678 close_file_data (&executable);
817abdf6
KH
679}
680
d9709fde 681int
42c95ffb 682compare_env (const void *strp1, const void *strp2)
d9709fde 683{
42c95ffb 684 const char *str1 = *(const char **)strp1, *str2 = *(const char **)strp2;
d9709fde
GV
685
686 while (*str1 && *str2 && *str1 != '=' && *str2 != '=')
687 {
11c22fff
AI
688 /* Sort order in command.com/cmd.exe is based on uppercasing
689 names, so do the same here. */
690 if (toupper (*str1) > toupper (*str2))
d9709fde 691 return 1;
11c22fff 692 else if (toupper (*str1) < toupper (*str2))
d9709fde
GV
693 return -1;
694 str1++, str2++;
695 }
696
697 if (*str1 == '=' && *str2 == '=')
698 return 0;
699 else if (*str1 == '=')
700 return -1;
701 else
702 return 1;
703}
704
705void
706merge_and_sort_env (char **envp1, char **envp2, char **new_envp)
707{
708 char **optr, **nptr;
709 int num;
710
711 nptr = new_envp;
712 optr = envp1;
713 while (*optr)
714 *nptr++ = *optr++;
715 num = optr - envp1;
716
717 optr = envp2;
718 while (*optr)
719 *nptr++ = *optr++;
720 num += optr - envp2;
721
722 qsort (new_envp, num, sizeof (char *), compare_env);
723
724 *nptr = NULL;
725}
6cdfb6e6
RS
726
727/* When a new child process is created we need to register it in our list,
728 so intercept spawn requests. */
177c0ea7 729int
c519b5e1 730sys_spawnve (int mode, char *cmdname, char **argv, char **envp)
6cdfb6e6 731{
0a4de642 732 Lisp_Object program, full;
6cdfb6e6 733 char *cmdline, *env, *parg, **targ;
d9709fde 734 int arglen, numenv;
c519b5e1
GV
735 int pid;
736 child_process *cp;
a55a5f3c 737 int is_dos_app, is_cygnus_app, is_gui_app;
b2fc9f3d
GV
738 int do_quoting = 0;
739 char escape_char;
d9709fde
GV
740 /* We pass our process ID to our children by setting up an environment
741 variable in their environment. */
742 char ppid_env_var_buffer[64];
743 char *extra_env[] = {ppid_env_var_buffer, NULL};
dbb70029 744 char *sepchars = " \t";
d9709fde 745
c519b5e1
GV
746 /* We don't care about the other modes */
747 if (mode != _P_NOWAIT)
748 {
749 errno = EINVAL;
750 return -1;
751 }
0a4de642
RS
752
753 /* Handle executable names without an executable suffix. */
754 program = make_string (cmdname, strlen (cmdname));
755 if (NILP (Ffile_executable_p (program)))
756 {
757 struct gcpro gcpro1;
177c0ea7 758
0a4de642
RS
759 full = Qnil;
760 GCPRO1 (program);
44c7a526 761 openp (Vexec_path, program, Vexec_suffixes, &full, make_number (X_OK));
0a4de642
RS
762 UNGCPRO;
763 if (NILP (full))
764 {
765 errno = EINVAL;
766 return -1;
767 }
b2fc9f3d 768 program = full;
0a4de642
RS
769 }
770
b2fc9f3d 771 /* make sure argv[0] and cmdname are both in DOS format */
d5db4077 772 cmdname = SDATA (program);
c519b5e1
GV
773 unixtodos_filename (cmdname);
774 argv[0] = cmdname;
817abdf6 775
ef79fbba 776 /* Determine whether program is a 16-bit DOS executable, or a w32
b2fc9f3d
GV
777 executable that is implicitly linked to the Cygnus dll (implying it
778 was compiled with the Cygnus GNU toolchain and hence relies on
779 cygwin.dll to parse the command line - we use this to decide how to
a55a5f3c
AI
780 escape quote chars in command line args that must be quoted).
781
782 Also determine whether it is a GUI app, so that we don't hide its
783 initial window unless specifically requested. */
784 w32_executable_type (cmdname, &is_dos_app, &is_cygnus_app, &is_gui_app);
b2fc9f3d
GV
785
786 /* On Windows 95, if cmdname is a DOS app, we invoke a helper
787 application to start it by specifying the helper app as cmdname,
788 while leaving the real app name as argv[0]. */
789 if (is_dos_app)
817abdf6 790 {
b2fc9f3d
GV
791 cmdname = alloca (MAXPATHLEN);
792 if (egetenv ("CMDPROXY"))
793 strcpy (cmdname, egetenv ("CMDPROXY"));
794 else
795 {
d5db4077 796 strcpy (cmdname, SDATA (Vinvocation_directory));
b2fc9f3d
GV
797 strcat (cmdname, "cmdproxy.exe");
798 }
799 unixtodos_filename (cmdname);
817abdf6 800 }
177c0ea7 801
6cdfb6e6
RS
802 /* we have to do some conjuring here to put argv and envp into the
803 form CreateProcess wants... argv needs to be a space separated/null
804 terminated list of parameters, and envp is a null
805 separated/double-null terminated list of parameters.
c519b5e1 806
b2fc9f3d
GV
807 Additionally, zero-length args and args containing whitespace or
808 quote chars need to be wrapped in double quotes - for this to work,
809 embedded quotes need to be escaped as well. The aim is to ensure
810 the child process reconstructs the argv array we start with
811 exactly, so we treat quotes at the beginning and end of arguments
812 as embedded quotes.
813
ef79fbba 814 The w32 GNU-based library from Cygnus doubles quotes to escape
b2fc9f3d
GV
815 them, while MSVC uses backslash for escaping. (Actually the MSVC
816 startup code does attempt to recognise doubled quotes and accept
817 them, but gets it wrong and ends up requiring three quotes to get a
818 single embedded quote!) So by default we decide whether to use
819 quote or backslash as the escape character based on whether the
820 binary is apparently a Cygnus compiled app.
821
822 Note that using backslash to escape embedded quotes requires
823 additional special handling if an embedded quote is already
824 preceeded by backslash, or if an arg requiring quoting ends with
825 backslash. In such cases, the run of escape characters needs to be
826 doubled. For consistency, we apply this special handling as long
827 as the escape character is not quote.
828
829 Since we have no idea how large argv and envp are likely to be we
830 figure out list lengths on the fly and allocate them. */
831
832 if (!NILP (Vw32_quote_process_args))
833 {
834 do_quoting = 1;
835 /* Override escape char by binding w32-quote-process-args to
836 desired character, or use t for auto-selection. */
837 if (INTEGERP (Vw32_quote_process_args))
838 escape_char = XINT (Vw32_quote_process_args);
839 else
840 escape_char = is_cygnus_app ? '"' : '\\';
841 }
177c0ea7
JB
842
843 /* Cygwin apps needs quoting a bit more often */
dbb70029
GM
844 if (escape_char == '"')
845 sepchars = "\r\n\t\f '";
846
6cdfb6e6
RS
847 /* do argv... */
848 arglen = 0;
849 targ = argv;
850 while (*targ)
851 {
c519b5e1 852 char * p = *targ;
b2fc9f3d
GV
853 int need_quotes = 0;
854 int escape_char_run = 0;
c519b5e1
GV
855
856 if (*p == 0)
b2fc9f3d
GV
857 need_quotes = 1;
858 for ( ; *p; p++)
859 {
dbb70029
GM
860 if (escape_char == '"' && *p == '\\')
861 /* If it's a Cygwin app, \ needs to be escaped. */
862 arglen++;
863 else if (*p == '"')
b2fc9f3d
GV
864 {
865 /* allow for embedded quotes to be escaped */
866 arglen++;
867 need_quotes = 1;
868 /* handle the case where the embedded quote is already escaped */
869 if (escape_char_run > 0)
870 {
871 /* To preserve the arg exactly, we need to double the
872 preceding escape characters (plus adding one to
873 escape the quote character itself). */
874 arglen += escape_char_run;
875 }
876 }
dbb70029 877 else if (strchr (sepchars, *p) != NULL)
b2fc9f3d
GV
878 {
879 need_quotes = 1;
880 }
881
882 if (*p == escape_char && escape_char != '"')
883 escape_char_run++;
884 else
885 escape_char_run = 0;
886 }
887 if (need_quotes)
888 {
889 arglen += 2;
890 /* handle the case where the arg ends with an escape char - we
891 must not let the enclosing quote be escaped. */
892 if (escape_char_run > 0)
893 arglen += escape_char_run;
894 }
6cdfb6e6
RS
895 arglen += strlen (*targ++) + 1;
896 }
c519b5e1 897 cmdline = alloca (arglen);
6cdfb6e6
RS
898 targ = argv;
899 parg = cmdline;
900 while (*targ)
901 {
c519b5e1 902 char * p = *targ;
b2fc9f3d 903 int need_quotes = 0;
c519b5e1
GV
904
905 if (*p == 0)
b2fc9f3d 906 need_quotes = 1;
93fdf2f8 907
b2fc9f3d 908 if (do_quoting)
93fdf2f8 909 {
93fdf2f8 910 for ( ; *p; p++)
dbb70029 911 if ((strchr (sepchars, *p) != NULL) || *p == '"')
b2fc9f3d 912 need_quotes = 1;
93fdf2f8 913 }
b2fc9f3d 914 if (need_quotes)
c519b5e1 915 {
b2fc9f3d 916 int escape_char_run = 0;
c519b5e1
GV
917 char * first;
918 char * last;
919
920 p = *targ;
921 first = p;
922 last = p + strlen (p) - 1;
923 *parg++ = '"';
b2fc9f3d
GV
924#if 0
925 /* This version does not escape quotes if they occur at the
926 beginning or end of the arg - this could lead to incorrect
927 behaviour when the arg itself represents a command line
928 containing quoted args. I believe this was originally done
929 as a hack to make some things work, before
930 `w32-quote-process-args' was added. */
c519b5e1
GV
931 while (*p)
932 {
933 if (*p == '"' && p > first && p < last)
b2fc9f3d 934 *parg++ = escape_char; /* escape embedded quotes */
c519b5e1
GV
935 *parg++ = *p++;
936 }
b2fc9f3d
GV
937#else
938 for ( ; *p; p++)
939 {
940 if (*p == '"')
941 {
942 /* double preceding escape chars if any */
943 while (escape_char_run > 0)
944 {
945 *parg++ = escape_char;
946 escape_char_run--;
947 }
948 /* escape all quote chars, even at beginning or end */
949 *parg++ = escape_char;
950 }
dbb70029
GM
951 else if (escape_char == '"' && *p == '\\')
952 *parg++ = '\\';
b2fc9f3d
GV
953 *parg++ = *p;
954
955 if (*p == escape_char && escape_char != '"')
956 escape_char_run++;
957 else
958 escape_char_run = 0;
959 }
960 /* double escape chars before enclosing quote */
961 while (escape_char_run > 0)
962 {
963 *parg++ = escape_char;
964 escape_char_run--;
965 }
966#endif
c519b5e1
GV
967 *parg++ = '"';
968 }
969 else
970 {
971 strcpy (parg, *targ);
972 parg += strlen (*targ);
973 }
6cdfb6e6 974 *parg++ = ' ';
c519b5e1 975 targ++;
6cdfb6e6
RS
976 }
977 *--parg = '\0';
177c0ea7 978
6cdfb6e6
RS
979 /* and envp... */
980 arglen = 1;
981 targ = envp;
d9709fde 982 numenv = 1; /* for end null */
6cdfb6e6
RS
983 while (*targ)
984 {
985 arglen += strlen (*targ++) + 1;
d9709fde 986 numenv++;
6cdfb6e6 987 }
d9709fde 988 /* extra env vars... */
177c0ea7 989 sprintf (ppid_env_var_buffer, "EM_PARENT_PROCESS_ID=%d",
6cdfb6e6
RS
990 GetCurrentProcessId ());
991 arglen += strlen (ppid_env_var_buffer) + 1;
d9709fde 992 numenv++;
6cdfb6e6 993
d9709fde
GV
994 /* merge env passed in and extra env into one, and sort it. */
995 targ = (char **) alloca (numenv * sizeof (char *));
996 merge_and_sort_env (envp, extra_env, targ);
997
998 /* concatenate env entries. */
c519b5e1 999 env = alloca (arglen);
6cdfb6e6
RS
1000 parg = env;
1001 while (*targ)
1002 {
1003 strcpy (parg, *targ);
1004 parg += strlen (*targ++);
1005 *parg++ = '\0';
1006 }
6cdfb6e6
RS
1007 *parg++ = '\0';
1008 *parg = '\0';
c519b5e1
GV
1009
1010 cp = new_child ();
1011 if (cp == NULL)
1012 {
1013 errno = EAGAIN;
1014 return -1;
1015 }
177c0ea7 1016
6cdfb6e6 1017 /* Now create the process. */
a55a5f3c 1018 if (!create_child (cmdname, cmdline, env, is_gui_app, &pid, cp))
6cdfb6e6 1019 {
c519b5e1 1020 delete_child (cp);
6cdfb6e6 1021 errno = ENOEXEC;
c519b5e1 1022 return -1;
6cdfb6e6 1023 }
177c0ea7 1024
c519b5e1 1025 return pid;
6cdfb6e6
RS
1026}
1027
1028/* Emulate the select call
1029 Wait for available input on any of the given rfds, or timeout if
1030 a timeout is given and no input is detected
b2fc9f3d
GV
1031 wfds and efds are not supported and must be NULL.
1032
1033 For simplicity, we detect the death of child processes here and
1034 synchronously call the SIGCHLD handler. Since it is possible for
1035 children to be created without a corresponding pipe handle from which
1036 to read output, we wait separately on the process handles as well as
1037 the char_avail events for each process pipe. We only call
86143765
RS
1038 wait/reap_process when the process actually terminates.
1039
1040 To reduce the number of places in which Emacs can be hung such that
1041 C-g is not able to interrupt it, we always wait on interrupt_handle
1042 (which is signalled by the input thread when C-g is detected). If we
1043 detect that we were woken up by C-g, we return -1 with errno set to
1044 EINTR as on Unix. */
6cdfb6e6
RS
1045
1046/* From ntterm.c */
1047extern HANDLE keyboard_handle;
86143765
RS
1048
1049/* From w32xfns.c */
1050extern HANDLE interrupt_handle;
1051
6cdfb6e6
RS
1052/* From process.c */
1053extern int proc_buffered_char[];
1054
177c0ea7 1055int
22759c72
KH
1056sys_select (int nfds, SELECT_TYPE *rfds, SELECT_TYPE *wfds, SELECT_TYPE *efds,
1057 EMACS_TIME *timeout)
6cdfb6e6
RS
1058{
1059 SELECT_TYPE orfds;
b2fc9f3d
GV
1060 DWORD timeout_ms, start_time;
1061 int i, nh, nc, nr;
6cdfb6e6 1062 DWORD active;
b2fc9f3d
GV
1063 child_process *cp, *cps[MAX_CHILDREN];
1064 HANDLE wait_hnd[MAXDESC + MAX_CHILDREN];
c519b5e1 1065 int fdindex[MAXDESC]; /* mapping from wait handles back to descriptors */
177c0ea7 1066
b2fc9f3d
GV
1067 timeout_ms = timeout ? (timeout->tv_sec * 1000 + timeout->tv_usec / 1000) : INFINITE;
1068
6cdfb6e6 1069 /* If the descriptor sets are NULL but timeout isn't, then just Sleep. */
177c0ea7 1070 if (rfds == NULL && wfds == NULL && efds == NULL && timeout != NULL)
6cdfb6e6 1071 {
b2fc9f3d 1072 Sleep (timeout_ms);
6cdfb6e6
RS
1073 return 0;
1074 }
1075
1076 /* Otherwise, we only handle rfds, so fail otherwise. */
1077 if (rfds == NULL || wfds != NULL || efds != NULL)
1078 {
1079 errno = EINVAL;
1080 return -1;
1081 }
177c0ea7 1082
6cdfb6e6
RS
1083 orfds = *rfds;
1084 FD_ZERO (rfds);
1085 nr = 0;
86143765
RS
1086
1087 /* Always wait on interrupt_handle, to detect C-g (quit). */
1088 wait_hnd[0] = interrupt_handle;
1089 fdindex[0] = -1;
177c0ea7 1090
b2fc9f3d 1091 /* Build a list of pipe handles to wait on. */
86143765 1092 nh = 1;
6cdfb6e6
RS
1093 for (i = 0; i < nfds; i++)
1094 if (FD_ISSET (i, &orfds))
1095 {
1096 if (i == 0)
1097 {
c519b5e1
GV
1098 if (keyboard_handle)
1099 {
1100 /* Handle stdin specially */
1101 wait_hnd[nh] = keyboard_handle;
1102 fdindex[nh] = i;
1103 nh++;
1104 }
6cdfb6e6
RS
1105
1106 /* Check for any emacs-generated input in the queue since
1107 it won't be detected in the wait */
1108 if (detect_input_pending ())
1109 {
1110 FD_SET (i, rfds);
c519b5e1 1111 return 1;
6cdfb6e6
RS
1112 }
1113 }
1114 else
1115 {
c519b5e1
GV
1116 /* Child process and socket input */
1117 cp = fd_info[i].cp;
6cdfb6e6
RS
1118 if (cp)
1119 {
c519b5e1
GV
1120 int current_status = cp->status;
1121
1122 if (current_status == STATUS_READ_ACKNOWLEDGED)
1123 {
1124 /* Tell reader thread which file handle to use. */
1125 cp->fd = i;
1126 /* Wake up the reader thread for this process */
1127 cp->status = STATUS_READ_READY;
1128 if (!SetEvent (cp->char_consumed))
1129 DebPrint (("nt_select.SetEvent failed with "
1130 "%lu for fd %ld\n", GetLastError (), i));
1131 }
1132
1133#ifdef CHECK_INTERLOCK
1134 /* slightly crude cross-checking of interlock between threads */
1135
1136 current_status = cp->status;
1137 if (WaitForSingleObject (cp->char_avail, 0) == WAIT_OBJECT_0)
1138 {
1139 /* char_avail has been signalled, so status (which may
1140 have changed) should indicate read has completed
1141 but has not been acknowledged. */
1142 current_status = cp->status;
b2fc9f3d
GV
1143 if (current_status != STATUS_READ_SUCCEEDED
1144 && current_status != STATUS_READ_FAILED)
c519b5e1
GV
1145 DebPrint (("char_avail set, but read not completed: status %d\n",
1146 current_status));
1147 }
1148 else
1149 {
1150 /* char_avail has not been signalled, so status should
1151 indicate that read is in progress; small possibility
1152 that read has completed but event wasn't yet signalled
1153 when we tested it (because a context switch occurred
1154 or if running on separate CPUs). */
b2fc9f3d
GV
1155 if (current_status != STATUS_READ_READY
1156 && current_status != STATUS_READ_IN_PROGRESS
1157 && current_status != STATUS_READ_SUCCEEDED
1158 && current_status != STATUS_READ_FAILED)
c519b5e1
GV
1159 DebPrint (("char_avail reset, but read status is bad: %d\n",
1160 current_status));
1161 }
1162#endif
1163 wait_hnd[nh] = cp->char_avail;
1164 fdindex[nh] = i;
1165 if (!wait_hnd[nh]) abort ();
1166 nh++;
6cdfb6e6
RS
1167#ifdef FULL_DEBUG
1168 DebPrint (("select waiting on child %d fd %d\n",
1169 cp-child_procs, i));
1170#endif
6cdfb6e6
RS
1171 }
1172 else
1173 {
c519b5e1 1174 /* Unable to find something to wait on for this fd, skip */
ef79fbba
GV
1175
1176 /* Note that this is not a fatal error, and can in fact
1177 happen in unusual circumstances. Specifically, if
1178 sys_spawnve fails, eg. because the program doesn't
1179 exist, and debug-on-error is t so Fsignal invokes a
1180 nested input loop, then the process output pipe is
1181 still included in input_wait_mask with no child_proc
1182 associated with it. (It is removed when the debugger
1183 exits the nested input loop and the error is thrown.) */
1184
c519b5e1 1185 DebPrint (("sys_select: fd %ld is invalid! ignoring\n", i));
6cdfb6e6
RS
1186 }
1187 }
1188 }
b2fc9f3d
GV
1189
1190count_children:
1191 /* Add handles of child processes. */
1192 nc = 0;
1193 for (cp = child_procs+(child_proc_count-1); cp >= child_procs; cp--)
ef79fbba
GV
1194 /* Some child_procs might be sockets; ignore them. Also some
1195 children may have died already, but we haven't finished reading
1196 the process output; ignore them too. */
1197 if (CHILD_ACTIVE (cp) && cp->procinfo.hProcess
1198 && (cp->fd < 0
1199 || (fd_info[cp->fd].flags & FILE_SEND_SIGCHLD) == 0
1200 || (fd_info[cp->fd].flags & FILE_AT_EOF) != 0)
1201 )
b2fc9f3d
GV
1202 {
1203 wait_hnd[nh + nc] = cp->procinfo.hProcess;
1204 cps[nc] = cp;
1205 nc++;
1206 }
177c0ea7 1207
6cdfb6e6 1208 /* Nothing to look for, so we didn't find anything */
177c0ea7 1209 if (nh + nc == 0)
6cdfb6e6 1210 {
22759c72 1211 if (timeout)
b2fc9f3d 1212 Sleep (timeout_ms);
6cdfb6e6
RS
1213 return 0;
1214 }
177c0ea7 1215
b2fc9f3d 1216 start_time = GetTickCount ();
8b031dcc
AI
1217
1218 /* Wait for input or child death to be signalled. If user input is
1219 allowed, then also accept window messages. */
1220 if (FD_ISSET (0, &orfds))
1221 active = MsgWaitForMultipleObjects (nh + nc, wait_hnd, FALSE, timeout_ms,
1222 QS_ALLINPUT);
1223 else
1224 active = WaitForMultipleObjects (nh + nc, wait_hnd, FALSE, timeout_ms);
c519b5e1 1225
6cdfb6e6
RS
1226 if (active == WAIT_FAILED)
1227 {
1228 DebPrint (("select.WaitForMultipleObjects (%d, %lu) failed with %lu\n",
b2fc9f3d 1229 nh + nc, timeout_ms, GetLastError ()));
d64b707c 1230 /* don't return EBADF - this causes wait_reading_process_output to
c519b5e1
GV
1231 abort; WAIT_FAILED is returned when single-stepping under
1232 Windows 95 after switching thread focus in debugger, and
1233 possibly at other times. */
1234 errno = EINTR;
6cdfb6e6
RS
1235 return -1;
1236 }
1237 else if (active == WAIT_TIMEOUT)
1238 {
1239 return 0;
1240 }
b2fc9f3d
GV
1241 else if (active >= WAIT_OBJECT_0
1242 && active < WAIT_OBJECT_0+MAXIMUM_WAIT_OBJECTS)
6cdfb6e6
RS
1243 {
1244 active -= WAIT_OBJECT_0;
1245 }
b2fc9f3d
GV
1246 else if (active >= WAIT_ABANDONED_0
1247 && active < WAIT_ABANDONED_0+MAXIMUM_WAIT_OBJECTS)
6cdfb6e6
RS
1248 {
1249 active -= WAIT_ABANDONED_0;
1250 }
b2fc9f3d
GV
1251 else
1252 abort ();
6cdfb6e6 1253
c519b5e1
GV
1254 /* Loop over all handles after active (now officially documented as
1255 being the first signalled handle in the array). We do this to
1256 ensure fairness, so that all channels with data available will be
1257 processed - otherwise higher numbered channels could be starved. */
1258 do
6cdfb6e6 1259 {
8b031dcc
AI
1260 if (active == nh + nc)
1261 {
1262 /* There are messages in the lisp thread's queue; we must
1263 drain the queue now to ensure they are processed promptly,
1264 because if we don't do so, we will not be woken again until
1265 further messages arrive.
1266
1267 NB. If ever we allow window message procedures to callback
1268 into lisp, we will need to ensure messages are dispatched
1269 at a safe time for lisp code to be run (*), and we may also
1270 want to provide some hooks in the dispatch loop to cater
1271 for modeless dialogs created by lisp (ie. to register
1272 window handles to pass to IsDialogMessage).
1273
1274 (*) Note that MsgWaitForMultipleObjects above is an
1275 internal dispatch point for messages that are sent to
1276 windows created by this thread. */
1277 drain_message_queue ();
1278 }
1279 else if (active >= nh)
b2fc9f3d
GV
1280 {
1281 cp = cps[active - nh];
ef79fbba
GV
1282
1283 /* We cannot always signal SIGCHLD immediately; if we have not
1284 finished reading the process output, we must delay sending
1285 SIGCHLD until we do. */
1286
1287 if (cp->fd >= 0 && (fd_info[cp->fd].flags & FILE_AT_EOF) == 0)
1288 fd_info[cp->fd].flags |= FILE_SEND_SIGCHLD;
b2fc9f3d 1289 /* SIG_DFL for SIGCHLD is ignore */
ef79fbba
GV
1290 else if (sig_handlers[SIGCHLD] != SIG_DFL &&
1291 sig_handlers[SIGCHLD] != SIG_IGN)
b2fc9f3d
GV
1292 {
1293#ifdef FULL_DEBUG
1294 DebPrint (("select calling SIGCHLD handler for pid %d\n",
1295 cp->pid));
1296#endif
1297 dead_child = cp;
1298 sig_handlers[SIGCHLD] (SIGCHLD);
1299 dead_child = NULL;
1300 }
1301 }
86143765
RS
1302 else if (fdindex[active] == -1)
1303 {
1304 /* Quit (C-g) was detected. */
1305 errno = EINTR;
1306 return -1;
1307 }
b2fc9f3d 1308 else if (fdindex[active] == 0)
c519b5e1
GV
1309 {
1310 /* Keyboard input available */
1311 FD_SET (0, rfds);
6cdfb6e6 1312 nr++;
c519b5e1 1313 }
6cdfb6e6 1314 else
c519b5e1 1315 {
b2fc9f3d
GV
1316 /* must be a socket or pipe - read ahead should have
1317 completed, either succeeding or failing. */
c519b5e1
GV
1318 FD_SET (fdindex[active], rfds);
1319 nr++;
c519b5e1
GV
1320 }
1321
b2fc9f3d
GV
1322 /* Even though wait_reading_process_output only reads from at most
1323 one channel, we must process all channels here so that we reap
1324 all children that have died. */
1325 while (++active < nh + nc)
c519b5e1
GV
1326 if (WaitForSingleObject (wait_hnd[active], 0) == WAIT_OBJECT_0)
1327 break;
b2fc9f3d
GV
1328 } while (active < nh + nc);
1329
1330 /* If no input has arrived and timeout hasn't expired, wait again. */
1331 if (nr == 0)
1332 {
1333 DWORD elapsed = GetTickCount () - start_time;
1334
1335 if (timeout_ms > elapsed) /* INFINITE is MAX_UINT */
1336 {
1337 if (timeout_ms != INFINITE)
1338 timeout_ms -= elapsed;
1339 goto count_children;
1340 }
1341 }
c519b5e1 1342
6cdfb6e6
RS
1343 return nr;
1344}
1345
c519b5e1 1346/* Substitute for certain kill () operations */
b2fc9f3d
GV
1347
1348static BOOL CALLBACK
42c95ffb 1349find_child_console (HWND hwnd, LPARAM arg)
b2fc9f3d 1350{
42c95ffb 1351 child_process * cp = (child_process *) arg;
b2fc9f3d
GV
1352 DWORD thread_id;
1353 DWORD process_id;
1354
1355 thread_id = GetWindowThreadProcessId (hwnd, &process_id);
1356 if (process_id == cp->procinfo.dwProcessId)
1357 {
1358 char window_class[32];
1359
1360 GetClassName (hwnd, window_class, sizeof (window_class));
1361 if (strcmp (window_class,
1362 (os_subtype == OS_WIN95)
1363 ? "tty"
1364 : "ConsoleWindowClass") == 0)
1365 {
1366 cp->hwnd = hwnd;
1367 return FALSE;
1368 }
1369 }
1370 /* keep looking */
1371 return TRUE;
1372}
1373
177c0ea7 1374int
c519b5e1 1375sys_kill (int pid, int sig)
6cdfb6e6
RS
1376{
1377 child_process *cp;
c519b5e1
GV
1378 HANDLE proc_hand;
1379 int need_to_free = 0;
1380 int rc = 0;
177c0ea7 1381
6cdfb6e6
RS
1382 /* Only handle signals that will result in the process dying */
1383 if (sig != SIGINT && sig != SIGKILL && sig != SIGQUIT && sig != SIGHUP)
1384 {
1385 errno = EINVAL;
1386 return -1;
1387 }
c519b5e1 1388
6cdfb6e6
RS
1389 cp = find_child_pid (pid);
1390 if (cp == NULL)
1391 {
c519b5e1
GV
1392 proc_hand = OpenProcess (PROCESS_TERMINATE, 0, pid);
1393 if (proc_hand == NULL)
1394 {
1395 errno = EPERM;
1396 return -1;
1397 }
1398 need_to_free = 1;
1399 }
1400 else
1401 {
1402 proc_hand = cp->procinfo.hProcess;
1403 pid = cp->procinfo.dwProcessId;
b2fc9f3d
GV
1404
1405 /* Try to locate console window for process. */
1406 EnumWindows (find_child_console, (LPARAM) cp);
6cdfb6e6 1407 }
177c0ea7 1408
a55a5f3c 1409 if (sig == SIGINT || sig == SIGQUIT)
6cdfb6e6 1410 {
b2fc9f3d
GV
1411 if (NILP (Vw32_start_process_share_console) && cp && cp->hwnd)
1412 {
1413 BYTE control_scan_code = (BYTE) MapVirtualKey (VK_CONTROL, 0);
a55a5f3c
AI
1414 /* Fake Ctrl-C for SIGINT, and Ctrl-Break for SIGQUIT. */
1415 BYTE vk_break_code = (sig == SIGINT) ? 'C' : VK_CANCEL;
b2fc9f3d
GV
1416 BYTE break_scan_code = (BYTE) MapVirtualKey (vk_break_code, 0);
1417 HWND foreground_window;
1418
1419 if (break_scan_code == 0)
1420 {
a55a5f3c 1421 /* Fake Ctrl-C for SIGQUIT if we can't manage Ctrl-Break. */
b2fc9f3d
GV
1422 vk_break_code = 'C';
1423 break_scan_code = (BYTE) MapVirtualKey (vk_break_code, 0);
1424 }
1425
1426 foreground_window = GetForegroundWindow ();
f446016f 1427 if (foreground_window)
b2fc9f3d 1428 {
f446016f
AI
1429 /* NT 5.0, and apparently also Windows 98, will not allow
1430 a Window to be set to foreground directly without the
1431 user's involvement. The workaround is to attach
1432 ourselves to the thread that owns the foreground
1433 window, since that is the only thread that can set the
1434 foreground window. */
1435 DWORD foreground_thread, child_thread;
1436 foreground_thread =
1437 GetWindowThreadProcessId (foreground_window, NULL);
1438 if (foreground_thread == GetCurrentThreadId ()
1439 || !AttachThreadInput (GetCurrentThreadId (),
1440 foreground_thread, TRUE))
1441 foreground_thread = 0;
1442
1443 child_thread = GetWindowThreadProcessId (cp->hwnd, NULL);
1444 if (child_thread == GetCurrentThreadId ()
1445 || !AttachThreadInput (GetCurrentThreadId (),
1446 child_thread, TRUE))
1447 child_thread = 0;
1448
1449 /* Set the foreground window to the child. */
1450 if (SetForegroundWindow (cp->hwnd))
1451 {
1452 /* Generate keystrokes as if user had typed Ctrl-Break or
1453 Ctrl-C. */
1454 keybd_event (VK_CONTROL, control_scan_code, 0, 0);
1455 keybd_event (vk_break_code, break_scan_code,
1456 (vk_break_code == 'C' ? 0 : KEYEVENTF_EXTENDEDKEY), 0);
1457 keybd_event (vk_break_code, break_scan_code,
1458 (vk_break_code == 'C' ? 0 : KEYEVENTF_EXTENDEDKEY)
1459 | KEYEVENTF_KEYUP, 0);
1460 keybd_event (VK_CONTROL, control_scan_code,
1461 KEYEVENTF_KEYUP, 0);
1462
1463 /* Sleep for a bit to give time for Emacs frame to respond
1464 to focus change events (if Emacs was active app). */
1465 Sleep (100);
1466
1467 SetForegroundWindow (foreground_window);
1468 }
1469 /* Detach from the foreground and child threads now that
1470 the foreground switching is over. */
1471 if (foreground_thread)
1472 AttachThreadInput (GetCurrentThreadId (),
1473 foreground_thread, FALSE);
1474 if (child_thread)
1475 AttachThreadInput (GetCurrentThreadId (),
1476 child_thread, FALSE);
1477 }
1478 }
c519b5e1 1479 /* Ctrl-Break is NT equivalent of SIGINT. */
b2fc9f3d 1480 else if (!GenerateConsoleCtrlEvent (CTRL_BREAK_EVENT, pid))
6cdfb6e6 1481 {
c519b5e1 1482 DebPrint (("sys_kill.GenerateConsoleCtrlEvent return %d "
6cdfb6e6
RS
1483 "for pid %lu\n", GetLastError (), pid));
1484 errno = EINVAL;
c519b5e1 1485 rc = -1;
80874ef7 1486 }
6cdfb6e6
RS
1487 }
1488 else
1489 {
b2fc9f3d
GV
1490 if (NILP (Vw32_start_process_share_console) && cp && cp->hwnd)
1491 {
1492#if 1
1493 if (os_subtype == OS_WIN95)
1494 {
1495/*
1496 Another possibility is to try terminating the VDM out-right by
1497 calling the Shell VxD (id 0x17) V86 interface, function #4
1498 "SHELL_Destroy_VM", ie.
1499
1500 mov edx,4
1501 mov ebx,vm_handle
1502 call shellapi
1503
1504 First need to determine the current VM handle, and then arrange for
1505 the shellapi call to be made from the system vm (by using
1506 Switch_VM_and_callback).
1507
1508 Could try to invoke DestroyVM through CallVxD.
1509
1510*/
ef79fbba
GV
1511#if 0
1512 /* On Win95, posting WM_QUIT causes the 16-bit subsystem
1513 to hang when cmdproxy is used in conjunction with
1514 command.com for an interactive shell. Posting
1515 WM_CLOSE pops up a dialog that, when Yes is selected,
1516 does the same thing. TerminateProcess is also less
1517 than ideal in that subprocesses tend to stick around
1518 until the machine is shutdown, but at least it
1519 doesn't freeze the 16-bit subsystem. */
b2fc9f3d 1520 PostMessage (cp->hwnd, WM_QUIT, 0xff, 0);
ef79fbba
GV
1521#endif
1522 if (!TerminateProcess (proc_hand, 0xff))
1523 {
1524 DebPrint (("sys_kill.TerminateProcess returned %d "
1525 "for pid %lu\n", GetLastError (), pid));
1526 errno = EINVAL;
1527 rc = -1;
1528 }
b2fc9f3d
GV
1529 }
1530 else
1531#endif
1532 PostMessage (cp->hwnd, WM_CLOSE, 0, 0);
1533 }
fbd6baed 1534 /* Kill the process. On W32 this doesn't kill child processes
8eae7766 1535 so it doesn't work very well for shells which is why it's not
b2fc9f3d
GV
1536 used in every case. */
1537 else if (!TerminateProcess (proc_hand, 0xff))
6cdfb6e6 1538 {
c519b5e1 1539 DebPrint (("sys_kill.TerminateProcess returned %d "
6cdfb6e6
RS
1540 "for pid %lu\n", GetLastError (), pid));
1541 errno = EINVAL;
c519b5e1 1542 rc = -1;
6cdfb6e6
RS
1543 }
1544 }
c519b5e1
GV
1545
1546 if (need_to_free)
1547 CloseHandle (proc_hand);
1548
1549 return rc;
6cdfb6e6
RS
1550}
1551
09522567 1552/* extern int report_file_error (char *, Lisp_Object); */
c519b5e1
GV
1553
1554/* The following two routines are used to manipulate stdin, stdout, and
1555 stderr of our child processes.
1556
1557 Assuming that in, out, and err are *not* inheritable, we make them
1558 stdin, stdout, and stderr of the child as follows:
1559
1560 - Save the parent's current standard handles.
1561 - Set the std handles to inheritable duplicates of the ones being passed in.
1562 (Note that _get_osfhandle() is an io.h procedure that retrieves the
1563 NT file handle for a crt file descriptor.)
1564 - Spawn the child, which inherits in, out, and err as stdin,
1565 stdout, and stderr. (see Spawnve)
1566 - Close the std handles passed to the child.
1567 - Reset the parent's standard handles to the saved handles.
1568 (see reset_standard_handles)
1569 We assume that the caller closes in, out, and err after calling us. */
1570
1571void
1572prepare_standard_handles (int in, int out, int err, HANDLE handles[3])
6cdfb6e6 1573{
c519b5e1
GV
1574 HANDLE parent;
1575 HANDLE newstdin, newstdout, newstderr;
1576
1577 parent = GetCurrentProcess ();
1578
1579 handles[0] = GetStdHandle (STD_INPUT_HANDLE);
1580 handles[1] = GetStdHandle (STD_OUTPUT_HANDLE);
1581 handles[2] = GetStdHandle (STD_ERROR_HANDLE);
1582
1583 /* make inheritable copies of the new handles */
177c0ea7 1584 if (!DuplicateHandle (parent,
c519b5e1
GV
1585 (HANDLE) _get_osfhandle (in),
1586 parent,
177c0ea7
JB
1587 &newstdin,
1588 0,
1589 TRUE,
c519b5e1
GV
1590 DUPLICATE_SAME_ACCESS))
1591 report_file_error ("Duplicating input handle for child", Qnil);
177c0ea7 1592
c519b5e1
GV
1593 if (!DuplicateHandle (parent,
1594 (HANDLE) _get_osfhandle (out),
1595 parent,
1596 &newstdout,
1597 0,
1598 TRUE,
1599 DUPLICATE_SAME_ACCESS))
1600 report_file_error ("Duplicating output handle for child", Qnil);
177c0ea7 1601
c519b5e1
GV
1602 if (!DuplicateHandle (parent,
1603 (HANDLE) _get_osfhandle (err),
1604 parent,
1605 &newstderr,
1606 0,
1607 TRUE,
1608 DUPLICATE_SAME_ACCESS))
1609 report_file_error ("Duplicating error handle for child", Qnil);
1610
1611 /* and store them as our std handles */
1612 if (!SetStdHandle (STD_INPUT_HANDLE, newstdin))
1613 report_file_error ("Changing stdin handle", Qnil);
177c0ea7 1614
c519b5e1
GV
1615 if (!SetStdHandle (STD_OUTPUT_HANDLE, newstdout))
1616 report_file_error ("Changing stdout handle", Qnil);
1617
1618 if (!SetStdHandle (STD_ERROR_HANDLE, newstderr))
1619 report_file_error ("Changing stderr handle", Qnil);
1620}
1621
1622void
1623reset_standard_handles (int in, int out, int err, HANDLE handles[3])
1624{
1625 /* close the duplicated handles passed to the child */
1626 CloseHandle (GetStdHandle (STD_INPUT_HANDLE));
1627 CloseHandle (GetStdHandle (STD_OUTPUT_HANDLE));
1628 CloseHandle (GetStdHandle (STD_ERROR_HANDLE));
1629
1630 /* now restore parent's saved std handles */
1631 SetStdHandle (STD_INPUT_HANDLE, handles[0]);
1632 SetStdHandle (STD_OUTPUT_HANDLE, handles[1]);
1633 SetStdHandle (STD_ERROR_HANDLE, handles[2]);
6cdfb6e6 1634}
c519b5e1 1635
b2fc9f3d
GV
1636void
1637set_process_dir (char * dir)
1638{
1639 process_dir = dir;
1640}
1641
a11e68d0
RS
1642#ifdef HAVE_SOCKETS
1643
1644/* To avoid problems with winsock implementations that work over dial-up
1645 connections causing or requiring a connection to exist while Emacs is
1646 running, Emacs no longer automatically loads winsock on startup if it
1647 is present. Instead, it will be loaded when open-network-stream is
1648 first called.
1649
1650 To allow full control over when winsock is loaded, we provide these
1651 two functions to dynamically load and unload winsock. This allows
1652 dial-up users to only be connected when they actually need to use
1653 socket services. */
1654
1655/* From nt.c */
1656extern HANDLE winsock_lib;
1657extern BOOL term_winsock (void);
1658extern BOOL init_winsock (int load_now);
1659
1660extern Lisp_Object Vsystem_name;
1661
fbd6baed 1662DEFUN ("w32-has-winsock", Fw32_has_winsock, Sw32_has_winsock, 0, 1, 0,
33f09670
JR
1663 doc: /* Test for presence of the Windows socket library `winsock'.
1664Returns non-nil if winsock support is present, nil otherwise.
1665
1666If the optional argument LOAD-NOW is non-nil, the winsock library is
1667also loaded immediately if not already loaded. If winsock is loaded,
1668the winsock local hostname is returned (since this may be different from
1669the value of `system-name' and should supplant it), otherwise t is
1670returned to indicate winsock support is present. */)
a11e68d0
RS
1671 (load_now)
1672 Lisp_Object load_now;
1673{
1674 int have_winsock;
1675
1676 have_winsock = init_winsock (!NILP (load_now));
1677 if (have_winsock)
1678 {
1679 if (winsock_lib != NULL)
1680 {
1681 /* Return new value for system-name. The best way to do this
1682 is to call init_system_name, saving and restoring the
1683 original value to avoid side-effects. */
1684 Lisp_Object orig_hostname = Vsystem_name;
1685 Lisp_Object hostname;
1686
1687 init_system_name ();
1688 hostname = Vsystem_name;
1689 Vsystem_name = orig_hostname;
1690 return hostname;
1691 }
1692 return Qt;
1693 }
1694 return Qnil;
1695}
1696
fbd6baed 1697DEFUN ("w32-unload-winsock", Fw32_unload_winsock, Sw32_unload_winsock,
a11e68d0 1698 0, 0, 0,
33f09670
JR
1699 doc: /* Unload the Windows socket library `winsock' if loaded.
1700This is provided to allow dial-up socket connections to be disconnected
1701when no longer needed. Returns nil without unloading winsock if any
1702socket connections still exist. */)
a11e68d0
RS
1703 ()
1704{
1705 return term_winsock () ? Qt : Qnil;
1706}
1707
1708#endif /* HAVE_SOCKETS */
1709
93fdf2f8 1710\f
b2fc9f3d
GV
1711/* Some miscellaneous functions that are Windows specific, but not GUI
1712 specific (ie. are applicable in terminal or batch mode as well). */
1713
1714/* lifted from fileio.c */
1715#define CORRECT_DIR_SEPS(s) \
1716 do { if ('/' == DIRECTORY_SEP) dostounix_filename (s); \
1717 else unixtodos_filename (s); \
1718 } while (0)
1719
1720DEFUN ("w32-short-file-name", Fw32_short_file_name, Sw32_short_file_name, 1, 1, 0,
33f09670
JR
1721 doc: /* Return the short file name version (8.3) of the full path of FILENAME.
1722If FILENAME does not exist, return nil.
1723All path elements in FILENAME are converted to their short names. */)
b2fc9f3d
GV
1724 (filename)
1725 Lisp_Object filename;
1726{
1727 char shortname[MAX_PATH];
1728
b7826503 1729 CHECK_STRING (filename);
b2fc9f3d
GV
1730
1731 /* first expand it. */
1732 filename = Fexpand_file_name (filename, Qnil);
1733
1734 /* luckily, this returns the short version of each element in the path. */
d5db4077 1735 if (GetShortPathName (SDATA (filename), shortname, MAX_PATH) == 0)
b2fc9f3d
GV
1736 return Qnil;
1737
1738 CORRECT_DIR_SEPS (shortname);
1739
1740 return build_string (shortname);
1741}
1742
1743
1744DEFUN ("w32-long-file-name", Fw32_long_file_name, Sw32_long_file_name,
1745 1, 1, 0,
33f09670
JR
1746 doc: /* Return the long file name version of the full path of FILENAME.
1747If FILENAME does not exist, return nil.
1748All path elements in FILENAME are converted to their long names. */)
b2fc9f3d
GV
1749 (filename)
1750 Lisp_Object filename;
1751{
1752 char longname[ MAX_PATH ];
1753
b7826503 1754 CHECK_STRING (filename);
b2fc9f3d
GV
1755
1756 /* first expand it. */
1757 filename = Fexpand_file_name (filename, Qnil);
1758
d5db4077 1759 if (!w32_get_long_filename (SDATA (filename), longname, MAX_PATH))
b2fc9f3d
GV
1760 return Qnil;
1761
1762 CORRECT_DIR_SEPS (longname);
1763
1764 return build_string (longname);
1765}
1766
33f09670
JR
1767DEFUN ("w32-set-process-priority", Fw32_set_process_priority,
1768 Sw32_set_process_priority, 2, 2, 0,
1769 doc: /* Set the priority of PROCESS to PRIORITY.
1770If PROCESS is nil, the priority of Emacs is changed, otherwise the
1771priority of the process whose pid is PROCESS is changed.
1772PRIORITY should be one of the symbols high, normal, or low;
1773any other symbol will be interpreted as normal.
1774
1775If successful, the return value is t, otherwise nil. */)
b2fc9f3d
GV
1776 (process, priority)
1777 Lisp_Object process, priority;
1778{
1779 HANDLE proc_handle = GetCurrentProcess ();
1780 DWORD priority_class = NORMAL_PRIORITY_CLASS;
1781 Lisp_Object result = Qnil;
1782
b7826503 1783 CHECK_SYMBOL (priority);
b2fc9f3d
GV
1784
1785 if (!NILP (process))
1786 {
1787 DWORD pid;
1788 child_process *cp;
1789
b7826503 1790 CHECK_NUMBER (process);
b2fc9f3d
GV
1791
1792 /* Allow pid to be an internally generated one, or one obtained
1793 externally. This is necessary because real pids on Win95 are
1794 negative. */
1795
1796 pid = XINT (process);
1797 cp = find_child_pid (pid);
1798 if (cp != NULL)
1799 pid = cp->procinfo.dwProcessId;
1800
1801 proc_handle = OpenProcess (PROCESS_SET_INFORMATION, FALSE, pid);
1802 }
1803
1804 if (EQ (priority, Qhigh))
1805 priority_class = HIGH_PRIORITY_CLASS;
1806 else if (EQ (priority, Qlow))
1807 priority_class = IDLE_PRIORITY_CLASS;
1808
1809 if (proc_handle != NULL)
1810 {
1811 if (SetPriorityClass (proc_handle, priority_class))
1812 result = Qt;
1813 if (!NILP (process))
1814 CloseHandle (proc_handle);
1815 }
1816
1817 return result;
1818}
1819
1820
33f09670
JR
1821DEFUN ("w32-get-locale-info", Fw32_get_locale_info,
1822 Sw32_get_locale_info, 1, 2, 0,
1823 doc: /* Return information about the Windows locale LCID.
1824By default, return a three letter locale code which encodes the default
1825language as the first two characters, and the country or regionial variant
1826as the third letter. For example, ENU refers to `English (United States)',
1827while ENC means `English (Canadian)'.
1828
1829If the optional argument LONGFORM is t, the long form of the locale
1830name is returned, e.g. `English (United States)' instead; if LONGFORM
1831is a number, it is interpreted as an LCTYPE constant and the corresponding
1832locale information is returned.
1833
1834If LCID (a 16-bit number) is not a valid locale, the result is nil. */)
b2fc9f3d
GV
1835 (lcid, longform)
1836 Lisp_Object lcid, longform;
1837{
1838 int got_abbrev;
1839 int got_full;
1840 char abbrev_name[32] = { 0 };
1841 char full_name[256] = { 0 };
1842
b7826503 1843 CHECK_NUMBER (lcid);
b2fc9f3d
GV
1844
1845 if (!IsValidLocale (XINT (lcid), LCID_SUPPORTED))
1846 return Qnil;
1847
1848 if (NILP (longform))
1849 {
1850 got_abbrev = GetLocaleInfo (XINT (lcid),
1851 LOCALE_SABBREVLANGNAME | LOCALE_USE_CP_ACP,
1852 abbrev_name, sizeof (abbrev_name));
1853 if (got_abbrev)
1854 return build_string (abbrev_name);
1855 }
0eaf5926 1856 else if (EQ (longform, Qt))
b2fc9f3d
GV
1857 {
1858 got_full = GetLocaleInfo (XINT (lcid),
1859 LOCALE_SLANGUAGE | LOCALE_USE_CP_ACP,
1860 full_name, sizeof (full_name));
1861 if (got_full)
1862 return build_string (full_name);
1863 }
0eaf5926
GV
1864 else if (NUMBERP (longform))
1865 {
1866 got_full = GetLocaleInfo (XINT (lcid),
1867 XINT (longform),
1868 full_name, sizeof (full_name));
1869 if (got_full)
1870 return make_unibyte_string (full_name, got_full);
1871 }
b2fc9f3d
GV
1872
1873 return Qnil;
1874}
1875
1876
33f09670
JR
1877DEFUN ("w32-get-current-locale-id", Fw32_get_current_locale_id,
1878 Sw32_get_current_locale_id, 0, 0, 0,
1879 doc: /* Return Windows locale id for current locale setting.
1880This is a numerical value; use `w32-get-locale-info' to convert to a
1881human-readable form. */)
b2fc9f3d
GV
1882 ()
1883{
1884 return make_number (GetThreadLocale ());
1885}
1886
ef79fbba
GV
1887DWORD int_from_hex (char * s)
1888{
1889 DWORD val = 0;
1890 static char hex[] = "0123456789abcdefABCDEF";
1891 char * p;
1892
1893 while (*s && (p = strchr(hex, *s)) != NULL)
1894 {
1895 unsigned digit = p - hex;
1896 if (digit > 15)
1897 digit -= 6;
1898 val = val * 16 + digit;
1899 s++;
1900 }
1901 return val;
1902}
1903
1904/* We need to build a global list, since the EnumSystemLocale callback
1905 function isn't given a context pointer. */
1906Lisp_Object Vw32_valid_locale_ids;
1907
1908BOOL CALLBACK enum_locale_fn (LPTSTR localeNum)
1909{
1910 DWORD id = int_from_hex (localeNum);
1911 Vw32_valid_locale_ids = Fcons (make_number (id), Vw32_valid_locale_ids);
1912 return TRUE;
1913}
1914
33f09670
JR
1915DEFUN ("w32-get-valid-locale-ids", Fw32_get_valid_locale_ids,
1916 Sw32_get_valid_locale_ids, 0, 0, 0,
1917 doc: /* Return list of all valid Windows locale ids.
1918Each id is a numerical value; use `w32-get-locale-info' to convert to a
1919human-readable form. */)
ef79fbba
GV
1920 ()
1921{
1922 Vw32_valid_locale_ids = Qnil;
1923
1924 EnumSystemLocales (enum_locale_fn, LCID_SUPPORTED);
1925
1926 Vw32_valid_locale_ids = Fnreverse (Vw32_valid_locale_ids);
1927 return Vw32_valid_locale_ids;
1928}
1929
b2fc9f3d
GV
1930
1931DEFUN ("w32-get-default-locale-id", Fw32_get_default_locale_id, Sw32_get_default_locale_id, 0, 1, 0,
33f09670
JR
1932 doc: /* Return Windows locale id for default locale setting.
1933By default, the system default locale setting is returned; if the optional
1934parameter USERP is non-nil, the user default locale setting is returned.
1935This is a numerical value; use `w32-get-locale-info' to convert to a
1936human-readable form. */)
b2fc9f3d
GV
1937 (userp)
1938 Lisp_Object userp;
1939{
1940 if (NILP (userp))
1941 return make_number (GetSystemDefaultLCID ());
1942 return make_number (GetUserDefaultLCID ());
1943}
1944
177c0ea7 1945
b2fc9f3d 1946DEFUN ("w32-set-current-locale", Fw32_set_current_locale, Sw32_set_current_locale, 1, 1, 0,
33f09670
JR
1947 doc: /* Make Windows locale LCID be the current locale setting for Emacs.
1948If successful, the new locale id is returned, otherwise nil. */)
b2fc9f3d
GV
1949 (lcid)
1950 Lisp_Object lcid;
1951{
b7826503 1952 CHECK_NUMBER (lcid);
b2fc9f3d
GV
1953
1954 if (!IsValidLocale (XINT (lcid), LCID_SUPPORTED))
1955 return Qnil;
1956
1957 if (!SetThreadLocale (XINT (lcid)))
1958 return Qnil;
1959
ef79fbba
GV
1960 /* Need to set input thread locale if present. */
1961 if (dwWindowsThreadId)
1962 /* Reply is not needed. */
1963 PostThreadMessage (dwWindowsThreadId, WM_EMACS_SETLOCALE, XINT (lcid), 0);
1964
b2fc9f3d
GV
1965 return make_number (GetThreadLocale ());
1966}
1967
0eaf5926
GV
1968
1969/* We need to build a global list, since the EnumCodePages callback
1970 function isn't given a context pointer. */
1971Lisp_Object Vw32_valid_codepages;
1972
1973BOOL CALLBACK enum_codepage_fn (LPTSTR codepageNum)
1974{
1975 DWORD id = atoi (codepageNum);
1976 Vw32_valid_codepages = Fcons (make_number (id), Vw32_valid_codepages);
1977 return TRUE;
1978}
1979
33f09670
JR
1980DEFUN ("w32-get-valid-codepages", Fw32_get_valid_codepages,
1981 Sw32_get_valid_codepages, 0, 0, 0,
1982 doc: /* Return list of all valid Windows codepages. */)
0eaf5926
GV
1983 ()
1984{
1985 Vw32_valid_codepages = Qnil;
1986
1987 EnumSystemCodePages (enum_codepage_fn, CP_SUPPORTED);
1988
1989 Vw32_valid_codepages = Fnreverse (Vw32_valid_codepages);
1990 return Vw32_valid_codepages;
1991}
1992
1993
33f09670
JR
1994DEFUN ("w32-get-console-codepage", Fw32_get_console_codepage,
1995 Sw32_get_console_codepage, 0, 0, 0,
1996 doc: /* Return current Windows codepage for console input. */)
0eaf5926
GV
1997 ()
1998{
1999 return make_number (GetConsoleCP ());
2000}
2001
177c0ea7 2002
33f09670
JR
2003DEFUN ("w32-set-console-codepage", Fw32_set_console_codepage,
2004 Sw32_set_console_codepage, 1, 1, 0,
2005 doc: /* Make Windows codepage CP be the current codepage setting for Emacs.
2006The codepage setting affects keyboard input and display in tty mode.
2007If successful, the new CP is returned, otherwise nil. */)
0eaf5926
GV
2008 (cp)
2009 Lisp_Object cp;
2010{
b7826503 2011 CHECK_NUMBER (cp);
0eaf5926
GV
2012
2013 if (!IsValidCodePage (XINT (cp)))
2014 return Qnil;
2015
2016 if (!SetConsoleCP (XINT (cp)))
2017 return Qnil;
2018
2019 return make_number (GetConsoleCP ());
2020}
2021
2022
33f09670
JR
2023DEFUN ("w32-get-console-output-codepage", Fw32_get_console_output_codepage,
2024 Sw32_get_console_output_codepage, 0, 0, 0,
2025 doc: /* Return current Windows codepage for console output. */)
0eaf5926
GV
2026 ()
2027{
2028 return make_number (GetConsoleOutputCP ());
2029}
2030
177c0ea7 2031
33f09670
JR
2032DEFUN ("w32-set-console-output-codepage", Fw32_set_console_output_codepage,
2033 Sw32_set_console_output_codepage, 1, 1, 0,
2034 doc: /* Make Windows codepage CP be the current codepage setting for Emacs.
2035The codepage setting affects keyboard input and display in tty mode.
2036If successful, the new CP is returned, otherwise nil. */)
0eaf5926
GV
2037 (cp)
2038 Lisp_Object cp;
2039{
b7826503 2040 CHECK_NUMBER (cp);
0eaf5926
GV
2041
2042 if (!IsValidCodePage (XINT (cp)))
2043 return Qnil;
2044
2045 if (!SetConsoleOutputCP (XINT (cp)))
2046 return Qnil;
2047
2048 return make_number (GetConsoleOutputCP ());
2049}
2050
2051
33f09670
JR
2052DEFUN ("w32-get-codepage-charset", Fw32_get_codepage_charset,
2053 Sw32_get_codepage_charset, 1, 1, 0,
2054 doc: /* Return charset of codepage CP.
2055Returns nil if the codepage is not valid. */)
0eaf5926
GV
2056 (cp)
2057 Lisp_Object cp;
2058{
2059 CHARSETINFO info;
2060
b7826503 2061 CHECK_NUMBER (cp);
0eaf5926
GV
2062
2063 if (!IsValidCodePage (XINT (cp)))
2064 return Qnil;
2065
2066 if (TranslateCharsetInfo ((DWORD *) XINT (cp), &info, TCI_SRCCODEPAGE))
2067 return make_number (info.ciCharset);
2068
2069 return Qnil;
2070}
2071
2072
33f09670
JR
2073DEFUN ("w32-get-valid-keyboard-layouts", Fw32_get_valid_keyboard_layouts,
2074 Sw32_get_valid_keyboard_layouts, 0, 0, 0,
2075 doc: /* Return list of Windows keyboard languages and layouts.
2076The return value is a list of pairs of language id and layout id. */)
0eaf5926
GV
2077 ()
2078{
2079 int num_layouts = GetKeyboardLayoutList (0, NULL);
2080 HKL * layouts = (HKL *) alloca (num_layouts * sizeof (HKL));
2081 Lisp_Object obj = Qnil;
2082
2083 if (GetKeyboardLayoutList (num_layouts, layouts) == num_layouts)
2084 {
2085 while (--num_layouts >= 0)
2086 {
2087 DWORD kl = (DWORD) layouts[num_layouts];
2088
2089 obj = Fcons (Fcons (make_number (kl & 0xffff),
2090 make_number ((kl >> 16) & 0xffff)),
2091 obj);
2092 }
2093 }
2094
2095 return obj;
2096}
2097
2098
33f09670
JR
2099DEFUN ("w32-get-keyboard-layout", Fw32_get_keyboard_layout,
2100 Sw32_get_keyboard_layout, 0, 0, 0,
2101 doc: /* Return current Windows keyboard language and layout.
2102The return value is the cons of the language id and the layout id. */)
0eaf5926
GV
2103 ()
2104{
2105 DWORD kl = (DWORD) GetKeyboardLayout (dwWindowsThreadId);
2106
2107 return Fcons (make_number (kl & 0xffff),
2108 make_number ((kl >> 16) & 0xffff));
2109}
2110
177c0ea7 2111
33f09670
JR
2112DEFUN ("w32-set-keyboard-layout", Fw32_set_keyboard_layout,
2113 Sw32_set_keyboard_layout, 1, 1, 0,
2114 doc: /* Make LAYOUT be the current keyboard layout for Emacs.
2115The keyboard layout setting affects interpretation of keyboard input.
2116If successful, the new layout id is returned, otherwise nil. */)
0eaf5926
GV
2117 (layout)
2118 Lisp_Object layout;
2119{
2120 DWORD kl;
2121
b7826503 2122 CHECK_CONS (layout);
f4532092
AI
2123 CHECK_NUMBER_CAR (layout);
2124 CHECK_NUMBER_CDR (layout);
0eaf5926 2125
8e713be6
KR
2126 kl = (XINT (XCAR (layout)) & 0xffff)
2127 | (XINT (XCDR (layout)) << 16);
0eaf5926
GV
2128
2129 /* Synchronize layout with input thread. */
2130 if (dwWindowsThreadId)
2131 {
2132 if (PostThreadMessage (dwWindowsThreadId, WM_EMACS_SETKEYBOARDLAYOUT,
2133 (WPARAM) kl, 0))
2134 {
2135 MSG msg;
2136 GetMessage (&msg, NULL, WM_EMACS_DONE, WM_EMACS_DONE);
2137
2138 if (msg.wParam == 0)
2139 return Qnil;
2140 }
2141 }
2142 else if (!ActivateKeyboardLayout ((HKL) kl, 0))
2143 return Qnil;
2144
2145 return Fw32_get_keyboard_layout ();
2146}
2147
b2fc9f3d 2148\f
93fdf2f8
RS
2149syms_of_ntproc ()
2150{
b2fc9f3d
GV
2151 Qhigh = intern ("high");
2152 Qlow = intern ("low");
af621bc3
EZ
2153 staticpro (&Qhigh);
2154 staticpro (&Qlow);
b2fc9f3d 2155
a11e68d0 2156#ifdef HAVE_SOCKETS
fbd6baed
GV
2157 defsubr (&Sw32_has_winsock);
2158 defsubr (&Sw32_unload_winsock);
a11e68d0 2159#endif
b2fc9f3d
GV
2160 defsubr (&Sw32_short_file_name);
2161 defsubr (&Sw32_long_file_name);
2162 defsubr (&Sw32_set_process_priority);
2163 defsubr (&Sw32_get_locale_info);
2164 defsubr (&Sw32_get_current_locale_id);
2165 defsubr (&Sw32_get_default_locale_id);
ef79fbba 2166 defsubr (&Sw32_get_valid_locale_ids);
b2fc9f3d 2167 defsubr (&Sw32_set_current_locale);
a11e68d0 2168
0eaf5926
GV
2169 defsubr (&Sw32_get_console_codepage);
2170 defsubr (&Sw32_set_console_codepage);
2171 defsubr (&Sw32_get_console_output_codepage);
2172 defsubr (&Sw32_set_console_output_codepage);
2173 defsubr (&Sw32_get_valid_codepages);
2174 defsubr (&Sw32_get_codepage_charset);
2175
2176 defsubr (&Sw32_get_valid_keyboard_layouts);
2177 defsubr (&Sw32_get_keyboard_layout);
2178 defsubr (&Sw32_set_keyboard_layout);
2179
fbd6baed 2180 DEFVAR_LISP ("w32-quote-process-args", &Vw32_quote_process_args,
33f09670
JR
2181 doc: /* Non-nil enables quoting of process arguments to ensure correct parsing.
2182Because Windows does not directly pass argv arrays to child processes,
2183programs have to reconstruct the argv array by parsing the command
2184line string. For an argument to contain a space, it must be enclosed
2185in double quotes or it will be parsed as multiple arguments.
2186
2187If the value is a character, that character will be used to escape any
2188quote characters that appear, otherwise a suitable escape character
2189will be chosen based on the type of the program. */);
b2fc9f3d 2190 Vw32_quote_process_args = Qt;
817abdf6 2191
fbd6baed
GV
2192 DEFVAR_LISP ("w32-start-process-show-window",
2193 &Vw32_start_process_show_window,
33f09670
JR
2194 doc: /* When nil, new child processes hide their windows.
2195When non-nil, they show their window in the method of their choice.
2196This variable doesn't affect GUI applications, which will never be hidden. */);
fbd6baed 2197 Vw32_start_process_show_window = Qnil;
0ecf7d36 2198
b2fc9f3d
GV
2199 DEFVAR_LISP ("w32-start-process-share-console",
2200 &Vw32_start_process_share_console,
33f09670
JR
2201 doc: /* When nil, new child processes are given a new console.
2202When non-nil, they share the Emacs console; this has the limitation of
804d894a 2203allowing only one DOS subprocess to run at a time (whether started directly
33f09670
JR
2204or indirectly by Emacs), and preventing Emacs from cleanly terminating the
2205subprocess group, but may allow Emacs to interrupt a subprocess that doesn't
2206otherwise respond to interrupts from Emacs. */);
b2fc9f3d
GV
2207 Vw32_start_process_share_console = Qnil;
2208
82e7c0a9
AI
2209 DEFVAR_LISP ("w32-start-process-inherit-error-mode",
2210 &Vw32_start_process_inherit_error_mode,
33f09670
JR
2211 doc: /* When nil, new child processes revert to the default error mode.
2212When non-nil, they inherit their error mode setting from Emacs, which stops
2213them blocking when trying to access unmounted drives etc. */);
82e7c0a9
AI
2214 Vw32_start_process_inherit_error_mode = Qt;
2215
5322f50b 2216 DEFVAR_INT ("w32-pipe-read-delay", &w32_pipe_read_delay,
33f09670
JR
2217 doc: /* Forced delay before reading subprocess output.
2218This is done to improve the buffering of subprocess output, by
2219avoiding the inefficiency of frequently reading small amounts of data.
2220
2221If positive, the value is the number of milliseconds to sleep before
2222reading the subprocess output. If negative, the magnitude is the number
2223of time slices to wait (effectively boosting the priority of the child
2224process temporarily). A value of zero disables waiting entirely. */);
5322f50b 2225 w32_pipe_read_delay = 50;
0c04091e 2226
fbd6baed 2227 DEFVAR_LISP ("w32-downcase-file-names", &Vw32_downcase_file_names,
33f09670
JR
2228 doc: /* Non-nil means convert all-upper case file names to lower case.
2229This applies when performing completions and file name expansion.
2230Note that the value of this setting also affects remote file names,
2231so you probably don't want to set to non-nil if you use case-sensitive
177c0ea7 2232filesystems via ange-ftp. */);
fbd6baed 2233 Vw32_downcase_file_names = Qnil;
b2fc9f3d
GV
2234
2235#if 0
2236 DEFVAR_LISP ("w32-generate-fake-inodes", &Vw32_generate_fake_inodes,
33f09670
JR
2237 doc: /* Non-nil means attempt to fake realistic inode values.
2238This works by hashing the truename of files, and should detect
2239aliasing between long and short (8.3 DOS) names, but can have
2240false positives because of hash collisions. Note that determing
2241the truename of a file can be slow. */);
b2fc9f3d
GV
2242 Vw32_generate_fake_inodes = Qnil;
2243#endif
2244
2245 DEFVAR_LISP ("w32-get-true-file-attributes", &Vw32_get_true_file_attributes,
45de4a6f
JB
2246 doc: /* Non-nil means determine accurate link count in `file-attributes'.
2247Note that this option is only useful for files on NTFS volumes, where hard links
c7a1aae9 2248are supported. Moreover, it slows down `file-attributes' noticeably. */);
09ed9d88 2249 Vw32_get_true_file_attributes = Qt;
af621bc3
EZ
2250
2251 staticpro (&Vw32_valid_locale_ids);
2252 staticpro (&Vw32_valid_codepages);
93fdf2f8 2253}
c519b5e1 2254/* end of ntproc.c */
ab5796a9
MB
2255
2256/* arch-tag: 23d3a34c-06d2-48a1-833b-ac7609aa5250
2257 (do not change this comment) */