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