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