w32proc.c 67.4 KB
Newer Older
1
/* Process support for GNU Emacs on the Microsoft W32 API.
2
   Copyright (C) 1992, 1995, 1999-2011  Free Software Foundation, Inc.
Richard M. Stallman's avatar
Richard M. Stallman committed
3

4 5
This file is part of GNU Emacs.

6
GNU Emacs is free software: you can redistribute it and/or modify
7
it under the terms of the GNU General Public License as published by
8 9
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
10 11 12 13 14 15 16

GNU Emacs is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
17
along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
Richard M. Stallman's avatar
Richard M. Stallman committed
18

19
/*
Richard M. Stallman's avatar
Richard M. Stallman committed
20 21 22 23 24 25 26 27
   Drew Bliss                   Oct 14, 1993
     Adapted from alarm.c by Tim Fleehart
*/

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <io.h>
28
#include <fcntl.h>
Richard M. Stallman's avatar
Richard M. Stallman committed
29
#include <signal.h>
Jason Rumney's avatar
Jason Rumney committed
30
#include <sys/file.h>
31
#include <setjmp.h>
Richard M. Stallman's avatar
Richard M. Stallman committed
32

33
/* must include CRT headers *before* config.h */
Pavel Janík's avatar
Pavel Janík committed
34 35
#include <config.h>

36 37 38 39 40 41
#undef signal
#undef wait
#undef spawnve
#undef select
#undef kill

Richard M. Stallman's avatar
Richard M. Stallman committed
42
#include <windows.h>
43 44
#ifdef __GNUC__
/* This definition is missing from mingw32 headers. */
45
extern BOOL WINAPI IsValidLocale (LCID, DWORD);
46
#endif
Richard M. Stallman's avatar
Richard M. Stallman committed
47

Eli Zaretskii's avatar
Eli Zaretskii committed
48 49 50 51 52
#ifdef HAVE_LANGINFO_CODESET
#include <nl_types.h>
#include <langinfo.h>
#endif

Richard M. Stallman's avatar
Richard M. Stallman committed
53
#include "lisp.h"
Jason Rumney's avatar
Jason Rumney committed
54
#include "character.h"
Geoff Voelker's avatar
Geoff Voelker committed
55
#include "w32.h"
Geoff Voelker's avatar
Geoff Voelker committed
56
#include "w32heap.h"
Richard M. Stallman's avatar
Richard M. Stallman committed
57
#include "systime.h"
58 59
#include "syswait.h"
#include "process.h"
60
#include "syssignal.h"
61
#include "w32term.h"
Eli Zaretskii's avatar
Eli Zaretskii committed
62
#include "dispextern.h"		/* for xstrcasecmp */
63
#include "coding.h"
64

Eli Zaretskii's avatar
Eli Zaretskii committed
65 66 67 68 69
#define RVA_TO_PTR(var,section,filedata) \
  ((void *)((section)->PointerToRawData					\
	    + ((DWORD)(var) - (section)->VirtualAddress)		\
	    + (filedata).file_base))

Geoff Voelker's avatar
Geoff Voelker committed
70
Lisp_Object Qhigh, Qlow;
71

Richard M. Stallman's avatar
Richard M. Stallman committed
72
#ifdef EMACSDEBUG
73 74
void
_DebPrint (const char *fmt, ...)
Richard M. Stallman's avatar
Richard M. Stallman committed
75
{
76
  char buf[1024];
Richard M. Stallman's avatar
Richard M. Stallman committed
77 78 79 80 81 82 83 84 85
  va_list args;

  va_start (args, fmt);
  vsprintf (buf, fmt, args);
  va_end (args);
  OutputDebugString (buf);
}
#endif

86
typedef void (_CALLBACK_ *signal_handler) (int);
Richard M. Stallman's avatar
Richard M. Stallman committed
87 88 89 90 91

/* Signal handlers...SIG_DFL == 0 so this is initialized correctly.  */
static signal_handler sig_handlers[NSIG];

/* Fake signal implementation to record the SIGCHLD handler.  */
92
signal_handler
93
sys_signal (int sig, signal_handler handler)
Richard M. Stallman's avatar
Richard M. Stallman committed
94 95
{
  signal_handler old;
96

Richard M. Stallman's avatar
Richard M. Stallman committed
97 98 99 100 101 102 103 104 105 106
  if (sig != SIGCHLD)
    {
      errno = EINVAL;
      return SIG_ERR;
    }
  old = sig_handlers[sig];
  sig_handlers[sig] = handler;
  return old;
}

107 108 109 110 111 112 113 114
/* Defined in <process.h> which conflicts with the local copy */
#define _P_NOWAIT 1

/* Child process management list.  */
int child_proc_count = 0;
child_process child_procs[ MAX_CHILDREN ];
child_process *dead_child = NULL;

115
static DWORD WINAPI reader_thread (void *arg);
116

Richard M. Stallman's avatar
Richard M. Stallman committed
117
/* Find an unused process slot.  */
118
child_process *
Richard M. Stallman's avatar
Richard M. Stallman committed
119 120 121
new_child (void)
{
  child_process *cp;
122
  DWORD id;
123

124
  for (cp = child_procs + (child_proc_count-1); cp >= child_procs; cp--)
Richard M. Stallman's avatar
Richard M. Stallman committed
125
    if (!CHILD_ACTIVE (cp))
126 127 128 129 130 131
      goto Initialise;
  if (child_proc_count == MAX_CHILDREN)
    return NULL;
  cp = &child_procs[child_proc_count++];

 Initialise:
132
  memset (cp, 0, sizeof (*cp));
133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153
  cp->fd = -1;
  cp->pid = -1;
  cp->procinfo.hProcess = NULL;
  cp->status = STATUS_READ_ERROR;

  /* use manual reset event so that select() will function properly */
  cp->char_avail = CreateEvent (NULL, TRUE, FALSE, NULL);
  if (cp->char_avail)
    {
      cp->char_consumed = CreateEvent (NULL, FALSE, FALSE, NULL);
      if (cp->char_consumed)
        {
	  cp->thrd = CreateThread (NULL, 1024, reader_thread, cp, 0, &id);
	  if (cp->thrd)
	    return cp;
	}
    }
  delete_child (cp);
  return NULL;
}

154
void
155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176
delete_child (child_process *cp)
{
  int i;

  /* Should not be deleting a child that is still needed. */
  for (i = 0; i < MAXDESC; i++)
    if (fd_info[i].cp == cp)
      abort ();

  if (!CHILD_ACTIVE (cp))
    return;

  /* reap thread if necessary */
  if (cp->thrd)
    {
      DWORD rc;

      if (GetExitCodeThread (cp->thrd, &rc) && rc == STILL_ACTIVE)
        {
	  /* let the thread exit cleanly if possible */
	  cp->status = STATUS_READ_ERROR;
	  SetEvent (cp->char_consumed);
177 178 179 180 181
#if 0
          /* We used to forceably terminate the thread here, but it
             is normally unnecessary, and in abnormal cases, the worst that
             will happen is we have an extra idle thread hanging around
             waiting for the zombie process.  */
182 183 184 185 186 187
	  if (WaitForSingleObject (cp->thrd, 1000) != WAIT_OBJECT_0)
	    {
	      DebPrint (("delete_child.WaitForSingleObject (thread) failed "
			 "with %lu for fd %ld\n", GetLastError (), cp->fd));
	      TerminateThread (cp->thrd, 0);
	    }
188
#endif
189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215
	}
      CloseHandle (cp->thrd);
      cp->thrd = NULL;
    }
  if (cp->char_avail)
    {
      CloseHandle (cp->char_avail);
      cp->char_avail = NULL;
    }
  if (cp->char_consumed)
    {
      CloseHandle (cp->char_consumed);
      cp->char_consumed = NULL;
    }

  /* update child_proc_count (highest numbered slot in use plus one) */
  if (cp == child_procs + child_proc_count - 1)
    {
      for (i = child_proc_count-1; i >= 0; i--)
	if (CHILD_ACTIVE (&child_procs[i]))
	  {
	    child_proc_count = i + 1;
	    break;
	  }
    }
  if (i < 0)
    child_proc_count = 0;
Richard M. Stallman's avatar
Richard M. Stallman committed
216 217 218 219 220 221 222
}

/* Find a child by pid.  */
static child_process *
find_child_pid (DWORD pid)
{
  child_process *cp;
223

224
  for (cp = child_procs + (child_proc_count-1); cp >= child_procs; cp--)
Richard M. Stallman's avatar
Richard M. Stallman committed
225 226 227 228 229 230
    if (CHILD_ACTIVE (cp) && pid == cp->pid)
      return cp;
  return NULL;
}


231 232
/* Thread proc for child process and socket reader threads. Each thread
   is normally blocked until woken by select() to check for input by
Glenn Morris's avatar
Glenn Morris committed
233
   reading one char.  When the read completes, char_avail is signaled
234
   to wake up the select emulator and the thread blocks itself again. */
235
static DWORD WINAPI
Richard M. Stallman's avatar
Richard M. Stallman committed
236 237 238
reader_thread (void *arg)
{
  child_process *cp;
239

Richard M. Stallman's avatar
Richard M. Stallman committed
240 241
  /* Our identity */
  cp = (child_process *)arg;
242

Richard M. Stallman's avatar
Richard M. Stallman committed
243
  /* We have to wait for the go-ahead before we can start */
Geoff Voelker's avatar
Geoff Voelker committed
244 245
  if (cp == NULL
      || WaitForSingleObject (cp->char_consumed, INFINITE) != WAIT_OBJECT_0)
246 247
    return 1;

Richard M. Stallman's avatar
Richard M. Stallman committed
248 249
  for (;;)
    {
250 251
      int rc;

252 253 254 255
      if (fd_info[cp->fd].flags & FILE_LISTEN)
	rc = _sys_wait_accept (cp->fd);
      else
	rc = _sys_read_ahead (cp->fd);
256 257 258

      /* The name char_avail is a misnomer - it really just means the
	 read-ahead has completed, whether successfully or not. */
Richard M. Stallman's avatar
Richard M. Stallman committed
259 260 261 262
      if (!SetEvent (cp->char_avail))
        {
	  DebPrint (("reader_thread.SetEvent failed with %lu for fd %ld\n",
		     GetLastError (), cp->fd));
263 264 265 266 267
	  return 1;
	}

      if (rc == STATUS_READ_ERROR)
	return 1;
268

Richard M. Stallman's avatar
Richard M. Stallman committed
269
      /* If the read died, the child has died so let the thread die */
270
      if (rc == STATUS_READ_FAILED)
Richard M. Stallman's avatar
Richard M. Stallman committed
271
	break;
272

Richard M. Stallman's avatar
Richard M. Stallman committed
273 274 275 276 277 278 279 280 281 282 283
      /* Wait until our input is acknowledged before reading again */
      if (WaitForSingleObject (cp->char_consumed, INFINITE) != WAIT_OBJECT_0)
        {
	  DebPrint (("reader_thread.WaitForSingleObject failed with "
		     "%lu for fd %ld\n", GetLastError (), cp->fd));
	  break;
        }
    }
  return 0;
}

Geoff Voelker's avatar
Geoff Voelker committed
284 285 286 287 288
/* To avoid Emacs changing directory, we just record here the directory
   the new process should start in.  This is set just before calling
   sys_spawnve, and is not generally valid at any other time.  */
static char * process_dir;

289
static BOOL
290
create_child (char *exe, char *cmdline, char *env, int is_gui_app,
291
	      int * pPid, child_process *cp)
Richard M. Stallman's avatar
Richard M. Stallman committed
292 293 294
{
  STARTUPINFO start;
  SECURITY_ATTRIBUTES sec_attrs;
295
#if 0
Richard M. Stallman's avatar
Richard M. Stallman committed
296
  SECURITY_DESCRIPTOR sec_desc;
297
#endif
298
  DWORD flags;
Geoff Voelker's avatar
Geoff Voelker committed
299
  char dir[ MAXPATHLEN ];
300

301
  if (cp == NULL) abort ();
302

Richard M. Stallman's avatar
Richard M. Stallman committed
303 304
  memset (&start, 0, sizeof (start));
  start.cb = sizeof (start);
305

306
#ifdef HAVE_NTGUI
307
  if (NILP (Vw32_start_process_show_window) && !is_gui_app)
308 309 310
    start.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
  else
    start.dwFlags = STARTF_USESTDHANDLES;
311 312 313 314 315 316 317
  start.wShowWindow = SW_HIDE;

  start.hStdInput = GetStdHandle (STD_INPUT_HANDLE);
  start.hStdOutput = GetStdHandle (STD_OUTPUT_HANDLE);
  start.hStdError = GetStdHandle (STD_ERROR_HANDLE);
#endif /* HAVE_NTGUI */

318
#if 0
Richard M. Stallman's avatar
Richard M. Stallman committed
319 320
  /* Explicitly specify no security */
  if (!InitializeSecurityDescriptor (&sec_desc, SECURITY_DESCRIPTOR_REVISION))
321
    goto EH_Fail;
Richard M. Stallman's avatar
Richard M. Stallman committed
322
  if (!SetSecurityDescriptorDacl (&sec_desc, TRUE, NULL, FALSE))
323
    goto EH_Fail;
324
#endif
Richard M. Stallman's avatar
Richard M. Stallman committed
325
  sec_attrs.nLength = sizeof (sec_attrs);
326
  sec_attrs.lpSecurityDescriptor = NULL /* &sec_desc */;
Richard M. Stallman's avatar
Richard M. Stallman committed
327
  sec_attrs.bInheritHandle = FALSE;
328

Geoff Voelker's avatar
Geoff Voelker committed
329 330
  strcpy (dir, process_dir);
  unixtodos_filename (dir);
331 332 333 334 335 336

  flags = (!NILP (Vw32_start_process_share_console)
	   ? CREATE_NEW_PROCESS_GROUP
	   : CREATE_NEW_CONSOLE);
  if (NILP (Vw32_start_process_inherit_error_mode))
    flags |= CREATE_DEFAULT_ERROR_MODE;
Richard M. Stallman's avatar
Richard M. Stallman committed
337
  if (!CreateProcess (exe, cmdline, &sec_attrs, NULL, TRUE,
338
		      flags, env, dir, &start, &cp->procinfo))
339 340 341 342 343 344 345 346 347
    goto EH_Fail;

  cp->pid = (int) cp->procinfo.dwProcessId;

  /* Hack for Windows 95, which assigns large (ie negative) pids */
  if (cp->pid < 0)
    cp->pid = -cp->pid;

  /* pid must fit in a Lisp_Int */
Stefan Monnier's avatar
Stefan Monnier committed
348
  cp->pid = cp->pid & INTMASK;
349 350

  *pPid = cp->pid;
Geoff Voelker's avatar
Geoff Voelker committed
351

Richard M. Stallman's avatar
Richard M. Stallman committed
352
  return TRUE;
Geoff Voelker's avatar
Geoff Voelker committed
353

Richard M. Stallman's avatar
Richard M. Stallman committed
354
 EH_Fail:
355
  DebPrint (("create_child.CreateProcess failed: %ld\n", GetLastError ()););
Richard M. Stallman's avatar
Richard M. Stallman committed
356 357 358 359 360 361 362 363
  return FALSE;
}

/* create_child doesn't know what emacs' file handle will be for waiting
   on output from the child, so we need to make this additional call
   to register the handle with the process
   This way the select emulator knows how to match file handles with
   entries in child_procs.  */
364
void
Richard M. Stallman's avatar
Richard M. Stallman committed
365 366 367
register_child (int pid, int fd)
{
  child_process *cp;
368

Richard M. Stallman's avatar
Richard M. Stallman committed
369 370 371 372 373 374
  cp = find_child_pid (pid);
  if (cp == NULL)
    {
      DebPrint (("register_child unable to find pid %lu\n", pid));
      return;
    }
375

Richard M. Stallman's avatar
Richard M. Stallman committed
376 377 378
#ifdef FULL_DEBUG
  DebPrint (("register_child registered fd %d with pid %lu\n", fd, pid));
#endif
379

Richard M. Stallman's avatar
Richard M. Stallman committed
380 381
  cp->fd = fd;

382 383 384 385 386 387
  /* thread is initially blocked until select is called; set status so
     that select will release thread */
  cp->status = STATUS_READ_ACKNOWLEDGED;

  /* attach child_process to fd_info */
  if (fd_info[fd].cp != NULL)
Richard M. Stallman's avatar
Richard M. Stallman committed
388
    {
389 390
      DebPrint (("register_child: fd_info[%d] apparently in use!\n", fd));
      abort ();
Richard M. Stallman's avatar
Richard M. Stallman committed
391
    }
392 393

  fd_info[fd].cp = cp;
Richard M. Stallman's avatar
Richard M. Stallman committed
394 395 396 397 398 399
}

/* When a process dies its pipe will break so the reader thread will
   signal failure to the select emulator.
   The select emulator then calls this routine to clean up.
   Since the thread signaled failure we can assume it is exiting.  */
400
static void
401
reap_subprocess (child_process *cp)
Richard M. Stallman's avatar
Richard M. Stallman committed
402
{
403
  if (cp->procinfo.hProcess)
Richard M. Stallman's avatar
Richard M. Stallman committed
404
    {
405
      /* Reap the process */
Geoff Voelker's avatar
Geoff Voelker committed
406 407 408 409 410
#ifdef FULL_DEBUG
      /* Process should have already died before we are called.  */
      if (WaitForSingleObject (cp->procinfo.hProcess, 0) != WAIT_OBJECT_0)
	DebPrint (("reap_subprocess: child fpr fd %d has not died yet!", cp->fd));
#endif
411 412 413 414
      CloseHandle (cp->procinfo.hProcess);
      cp->procinfo.hProcess = NULL;
      CloseHandle (cp->procinfo.hThread);
      cp->procinfo.hThread = NULL;
Richard M. Stallman's avatar
Richard M. Stallman committed
415
    }
416 417 418 419 420 421 422

  /* For asynchronous children, the child_proc resources will be freed
     when the last pipe read descriptor is closed; for synchronous
     children, we must explicitly free the resources now because
     register_child has not been called. */
  if (cp->fd == -1)
    delete_child (cp);
Richard M. Stallman's avatar
Richard M. Stallman committed
423 424 425 426 427
}

/* Wait for any of our existing child processes to die
   When it does, close its handle
   Return the pid and fill in the status if non-NULL.  */
428

429
int
430
sys_wait (int *status)
Richard M. Stallman's avatar
Richard M. Stallman committed
431 432 433
{
  DWORD active, retval;
  int nh;
434
  int pid;
Richard M. Stallman's avatar
Richard M. Stallman committed
435 436
  child_process *cp, *cps[MAX_CHILDREN];
  HANDLE wait_hnd[MAX_CHILDREN];
437

Richard M. Stallman's avatar
Richard M. Stallman committed
438 439 440 441
  nh = 0;
  if (dead_child != NULL)
    {
      /* We want to wait for a specific child */
442
      wait_hnd[nh] = dead_child->procinfo.hProcess;
Richard M. Stallman's avatar
Richard M. Stallman committed
443
      cps[nh] = dead_child;
444
      if (!wait_hnd[nh]) abort ();
Richard M. Stallman's avatar
Richard M. Stallman committed
445
      nh++;
Geoff Voelker's avatar
Geoff Voelker committed
446 447
      active = 0;
      goto get_result;
Richard M. Stallman's avatar
Richard M. Stallman committed
448 449 450
    }
  else
    {
451
      for (cp = child_procs + (child_proc_count-1); cp >= child_procs; cp--)
452
	/* some child_procs might be sockets; ignore them */
453 454
	if (CHILD_ACTIVE (cp) && cp->procinfo.hProcess
	    && (cp->fd < 0 || (fd_info[cp->fd].flags & FILE_AT_EOF) != 0))
Richard M. Stallman's avatar
Richard M. Stallman committed
455
	  {
456
	    wait_hnd[nh] = cp->procinfo.hProcess;
Richard M. Stallman's avatar
Richard M. Stallman committed
457 458 459 460
	    cps[nh] = cp;
	    nh++;
	  }
    }
461

Richard M. Stallman's avatar
Richard M. Stallman committed
462 463 464 465 466 467
  if (nh == 0)
    {
      /* Nothing to wait on, so fail */
      errno = ECHILD;
      return -1;
    }
Geoff Voelker's avatar
Geoff Voelker committed
468 469 470 471 472 473 474 475

  do
    {
      /* Check for quit about once a second. */
      QUIT;
      active = WaitForMultipleObjects (nh, wait_hnd, FALSE, 1000);
    } while (active == WAIT_TIMEOUT);

Richard M. Stallman's avatar
Richard M. Stallman committed
476 477 478 479 480
  if (active == WAIT_FAILED)
    {
      errno = EBADF;
      return -1;
    }
Geoff Voelker's avatar
Geoff Voelker committed
481 482
  else if (active >= WAIT_OBJECT_0
	   && active < WAIT_OBJECT_0+MAXIMUM_WAIT_OBJECTS)
Richard M. Stallman's avatar
Richard M. Stallman committed
483 484 485
    {
      active -= WAIT_OBJECT_0;
    }
Geoff Voelker's avatar
Geoff Voelker committed
486 487
  else if (active >= WAIT_ABANDONED_0
	   && active < WAIT_ABANDONED_0+MAXIMUM_WAIT_OBJECTS)
Richard M. Stallman's avatar
Richard M. Stallman committed
488 489 490
    {
      active -= WAIT_ABANDONED_0;
    }
Geoff Voelker's avatar
Geoff Voelker committed
491 492 493 494
  else
    abort ();

get_result:
Richard M. Stallman's avatar
Richard M. Stallman committed
495 496 497 498 499 500 501 502 503 504 505 506 507
  if (!GetExitCodeProcess (wait_hnd[active], &retval))
    {
      DebPrint (("Wait.GetExitCodeProcess failed with %lu\n",
		 GetLastError ()));
      retval = 1;
    }
  if (retval == STILL_ACTIVE)
    {
      /* Should never happen */
      DebPrint (("Wait.WaitForMultipleObjects returned an active process\n"));
      errno = EINVAL;
      return -1;
    }
508 509

  /* Massage the exit code from the process to match the format expected
Karl Heuer's avatar
Karl Heuer committed
510
     by the WIFSTOPPED et al macros in syswait.h.  Only WIFSIGNALED and
511 512 513 514 515 516
     WIFEXITED are supported; WIFSTOPPED doesn't make sense under NT.  */

  if (retval == STATUS_CONTROL_C_EXIT)
    retval = SIGINT;
  else
    retval <<= 8;
517

Richard M. Stallman's avatar
Richard M. Stallman committed
518
  cp = cps[active];
519 520 521 522
  pid = cp->pid;
#ifdef FULL_DEBUG
  DebPrint (("Wait signaled with process pid %d\n", cp->pid));
#endif
523

Richard M. Stallman's avatar
Richard M. Stallman committed
524 525
  if (status)
    {
526 527 528 529 530 531
      *status = retval;
    }
  else if (synch_process_alive)
    {
      synch_process_alive = 0;

532 533 534 535 536 537
      /* Report the status of the synchronous process.  */
      if (WIFEXITED (retval))
	synch_process_retcode = WRETCODE (retval);
      else if (WIFSIGNALED (retval))
	{
	  int code = WTERMSIG (retval);
538 539
	  char *signame;

540
	  synchronize_system_messages_locale ();
541 542
	  signame = strsignal (code);

543 544 545 546 547
	  if (signame == 0)
	    signame = "unknown";

	  synch_process_death = signame;
	}
548 549

      reap_subprocess (cp);
Richard M. Stallman's avatar
Richard M. Stallman committed
550
    }
Geoff Voelker's avatar
Geoff Voelker committed
551 552

  reap_subprocess (cp);
553

554
  return pid;
Richard M. Stallman's avatar
Richard M. Stallman committed
555 556
}

557 558 559 560 561 562 563
/* Old versions of w32api headers don't have separate 32-bit and
   64-bit defines, but the one they have matches the 32-bit variety.  */
#ifndef IMAGE_NT_OPTIONAL_HDR32_MAGIC
# define IMAGE_NT_OPTIONAL_HDR32_MAGIC IMAGE_NT_OPTIONAL_HDR_MAGIC
# define IMAGE_OPTIONAL_HEADER32 IMAGE_OPTIONAL_HEADER
#endif

564
static void
565 566 567 568
w32_executable_type (char * filename,
		     int * is_dos_app,
		     int * is_cygnus_app,
		     int * is_gui_app)
569
{
Geoff Voelker's avatar
Geoff Voelker committed
570 571
  file_data executable;
  char * p;
572

Geoff Voelker's avatar
Geoff Voelker committed
573 574 575
  /* Default values in case we can't tell for sure.  */
  *is_dos_app = FALSE;
  *is_cygnus_app = FALSE;
576
  *is_gui_app = FALSE;
Geoff Voelker's avatar
Geoff Voelker committed
577 578 579

  if (!open_input_file (&executable, filename))
    return;
580

Geoff Voelker's avatar
Geoff Voelker committed
581
  p = strrchr (filename, '.');
582

Geoff Voelker's avatar
Geoff Voelker committed
583
  /* We can only identify DOS .com programs from the extension. */
584
  if (p && xstrcasecmp (p, ".com") == 0)
Geoff Voelker's avatar
Geoff Voelker committed
585
    *is_dos_app = TRUE;
586 587
  else if (p && (xstrcasecmp (p, ".bat") == 0
		 || xstrcasecmp (p, ".cmd") == 0))
Geoff Voelker's avatar
Geoff Voelker committed
588 589 590 591 592 593 594 595 596
    {
      /* A DOS shell script - it appears that CreateProcess is happy to
	 accept this (somewhat surprisingly); presumably it looks at
	 COMSPEC to determine what executable to actually invoke.
	 Therefore, we have to do the same here as well. */
      /* Actually, I think it uses the program association for that
	 extension, which is defined in the registry.  */
      p = egetenv ("COMSPEC");
      if (p)
597
	w32_executable_type (p, is_dos_app, is_cygnus_app, is_gui_app);
Geoff Voelker's avatar
Geoff Voelker committed
598 599
    }
  else
600
    {
Geoff Voelker's avatar
Geoff Voelker committed
601 602 603 604
      /* Look for DOS .exe signature - if found, we must also check that
	 it isn't really a 16- or 32-bit Windows exe, since both formats
	 start with a DOS program stub.  Note that 16-bit Windows
	 executables use the OS/2 1.x format. */
605

Geoff Voelker's avatar
Geoff Voelker committed
606 607 608 609 610 611 612 613 614
      IMAGE_DOS_HEADER * dos_header;
      IMAGE_NT_HEADERS * nt_header;

      dos_header = (PIMAGE_DOS_HEADER) executable.file_base;
      if (dos_header->e_magic != IMAGE_DOS_SIGNATURE)
	goto unwind;

      nt_header = (PIMAGE_NT_HEADERS) ((char *) dos_header + dos_header->e_lfanew);

615
      if ((char *) nt_header > (char *) dos_header + executable.size)
616
	{
Geoff Voelker's avatar
Geoff Voelker committed
617 618
	  /* Some dos headers (pkunzip) have bogus e_lfanew fields.  */
	  *is_dos_app = TRUE;
619
	}
Geoff Voelker's avatar
Geoff Voelker committed
620 621 622 623 624 625 626
      else if (nt_header->Signature != IMAGE_NT_SIGNATURE
	       && LOWORD (nt_header->Signature) != IMAGE_OS2_SIGNATURE)
  	{
	  *is_dos_app = TRUE;
  	}
      else if (nt_header->Signature == IMAGE_NT_SIGNATURE)
  	{
627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663
          IMAGE_DATA_DIRECTORY *data_dir = NULL;
          if (nt_header->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC)
            {
              /* Ensure we are using the 32 bit structure.  */
              IMAGE_OPTIONAL_HEADER32 *opt
                = (IMAGE_OPTIONAL_HEADER32*) &(nt_header->OptionalHeader);
              data_dir = opt->DataDirectory;
              *is_gui_app = (opt->Subsystem == IMAGE_SUBSYSTEM_WINDOWS_GUI);
            }
          /* MingW 3.12 has the required 64 bit structs, but in case older
             versions don't, only check 64 bit exes if we know how.  */
#ifdef IMAGE_NT_OPTIONAL_HDR64_MAGIC
          else if (nt_header->OptionalHeader.Magic
                   == IMAGE_NT_OPTIONAL_HDR64_MAGIC)
            {
              IMAGE_OPTIONAL_HEADER64 *opt
                = (IMAGE_OPTIONAL_HEADER64*) &(nt_header->OptionalHeader);
              data_dir = opt->DataDirectory;
              *is_gui_app = (opt->Subsystem == IMAGE_SUBSYSTEM_WINDOWS_GUI);
            }
#endif
          if (data_dir)
            {
              /* Look for cygwin.dll in DLL import list. */
              IMAGE_DATA_DIRECTORY import_dir =
                data_dir[IMAGE_DIRECTORY_ENTRY_IMPORT];
              IMAGE_IMPORT_DESCRIPTOR * imports;
              IMAGE_SECTION_HEADER * section;

              section = rva_to_section (import_dir.VirtualAddress, nt_header);
              imports = RVA_TO_PTR (import_dir.VirtualAddress, section,
                                    executable);

              for ( ; imports->Name; imports++)
                {
                  char * dllname = RVA_TO_PTR (imports->Name, section,
                                               executable);
664

665 666 667 668 669 670 671 672 673 674
                  /* The exact name of the cygwin dll has changed with
                     various releases, but hopefully this will be reasonably
                     future proof.  */
                  if (strncmp (dllname, "cygwin", 6) == 0)
                    {
                      *is_cygnus_app = TRUE;
                      break;
                    }
                }
            }
Geoff Voelker's avatar
Geoff Voelker committed
675
  	}
676
    }
677

Geoff Voelker's avatar
Geoff Voelker committed
678 679
unwind:
  close_file_data (&executable);
680 681
}

682
static int
683
compare_env (const void *strp1, const void *strp2)
684
{
685
  const char *str1 = *(const char **)strp1, *str2 = *(const char **)strp2;
686 687 688

  while (*str1 && *str2 && *str1 != '=' && *str2 != '=')
    {
689 690 691
      /* Sort order in command.com/cmd.exe is based on uppercasing
         names, so do the same here.  */
      if (toupper (*str1) > toupper (*str2))
692
	return 1;
693
      else if (toupper (*str1) < toupper (*str2))
694 695 696 697 698 699 700 701 702 703 704 705
	return -1;
      str1++, str2++;
    }

  if (*str1 == '=' && *str2 == '=')
    return 0;
  else if (*str1 == '=')
    return -1;
  else
    return 1;
}

706
static void
707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726
merge_and_sort_env (char **envp1, char **envp2, char **new_envp)
{
  char **optr, **nptr;
  int num;

  nptr = new_envp;
  optr = envp1;
  while (*optr)
    *nptr++ = *optr++;
  num = optr - envp1;

  optr = envp2;
  while (*optr)
    *nptr++ = *optr++;
  num += optr - envp2;

  qsort (new_envp, num, sizeof (char *), compare_env);

  *nptr = NULL;
}
Richard M. Stallman's avatar
Richard M. Stallman committed
727 728 729

/* When a new child process is created we need to register it in our list,
   so intercept spawn requests.  */
730
int
731
sys_spawnve (int mode, char *cmdname, char **argv, char **envp)
Richard M. Stallman's avatar
Richard M. Stallman committed
732
{
733
  Lisp_Object program, full;
Richard M. Stallman's avatar
Richard M. Stallman committed
734
  char *cmdline, *env, *parg, **targ;
735
  int arglen, numenv;
736 737
  int pid;
  child_process *cp;
738
  int is_dos_app, is_cygnus_app, is_gui_app;
Geoff Voelker's avatar
Geoff Voelker committed
739 740
  int do_quoting = 0;
  char escape_char;
741 742 743 744
  /* We pass our process ID to our children by setting up an environment
     variable in their environment.  */
  char ppid_env_var_buffer[64];
  char *extra_env[] = {ppid_env_var_buffer, NULL};
745 746 747 748 749 750 751 752
  /* These are the characters that cause an argument to need quoting.
     Arguments with whitespace characters need quoting to prevent the
     argument being split into two or more. Arguments with wildcards
     are also quoted, for consistency with posix platforms, where wildcards
     are not expanded if we run the program directly without a shell.
     Some extra whitespace characters need quoting in Cygwin programs,
     so this list is conditionally modified below.  */
  char *sepchars = " \t*?";
753

754 755 756 757 758 759
  /* We don't care about the other modes */
  if (mode != _P_NOWAIT)
    {
      errno = EINVAL;
      return -1;
    }
760 761 762 763 764 765

  /* Handle executable names without an executable suffix.  */
  program = make_string (cmdname, strlen (cmdname));
  if (NILP (Ffile_executable_p (program)))
    {
      struct gcpro gcpro1;
766

767 768
      full = Qnil;
      GCPRO1 (program);
769
      openp (Vexec_path, program, Vexec_suffixes, &full, make_number (X_OK));
770 771 772 773 774 775
      UNGCPRO;
      if (NILP (full))
	{
	  errno = EINVAL;
	  return -1;
	}
Geoff Voelker's avatar
Geoff Voelker committed
776
      program = full;
777 778
    }

Geoff Voelker's avatar
Geoff Voelker committed
779
  /* make sure argv[0] and cmdname are both in DOS format */
780
  cmdname = SDATA (program);
781 782
  unixtodos_filename (cmdname);
  argv[0] = cmdname;
783

784
  /* Determine whether program is a 16-bit DOS executable, or a w32
Geoff Voelker's avatar
Geoff Voelker committed
785 786 787
     executable that is implicitly linked to the Cygnus dll (implying it
     was compiled with the Cygnus GNU toolchain and hence relies on
     cygwin.dll to parse the command line - we use this to decide how to
788 789 790 791 792
     escape quote chars in command line args that must be quoted).

     Also determine whether it is a GUI app, so that we don't hide its
     initial window unless specifically requested.  */
  w32_executable_type (cmdname, &is_dos_app, &is_cygnus_app, &is_gui_app);
Geoff Voelker's avatar
Geoff Voelker committed
793 794 795 796 797

  /* On Windows 95, if cmdname is a DOS app, we invoke a helper
     application to start it by specifying the helper app as cmdname,
     while leaving the real app name as argv[0].  */
  if (is_dos_app)
798
    {
Geoff Voelker's avatar
Geoff Voelker committed
799 800 801 802 803
      cmdname = alloca (MAXPATHLEN);
      if (egetenv ("CMDPROXY"))
	strcpy (cmdname, egetenv ("CMDPROXY"));
      else
	{
804
	  strcpy (cmdname, SDATA (Vinvocation_directory));
Geoff Voelker's avatar
Geoff Voelker committed
805 806 807
	  strcat (cmdname, "cmdproxy.exe");
	}
      unixtodos_filename (cmdname);
808
    }
809

Richard M. Stallman's avatar
Richard M. Stallman committed
810 811 812 813
  /* we have to do some conjuring here to put argv and envp into the
     form CreateProcess wants...  argv needs to be a space separated/null
     terminated list of parameters, and envp is a null
     separated/double-null terminated list of parameters.
814

Geoff Voelker's avatar
Geoff Voelker committed
815 816 817 818 819 820 821
     Additionally, zero-length args and args containing whitespace or
     quote chars need to be wrapped in double quotes - for this to work,
     embedded quotes need to be escaped as well.  The aim is to ensure
     the child process reconstructs the argv array we start with
     exactly, so we treat quotes at the beginning and end of arguments
     as embedded quotes.

822
     The w32 GNU-based library from Cygnus doubles quotes to escape
Geoff Voelker's avatar
Geoff Voelker committed
823 824 825 826 827 828 829 830 831
     them, while MSVC uses backslash for escaping.  (Actually the MSVC
     startup code does attempt to recognise doubled quotes and accept
     them, but gets it wrong and ends up requiring three quotes to get a
     single embedded quote!)  So by default we decide whether to use
     quote or backslash as the escape character based on whether the
     binary is apparently a Cygnus compiled app.

     Note that using backslash to escape embedded quotes requires
     additional special handling if an embedded quote is already
Glenn Morris's avatar
Glenn Morris committed
832
     preceded by backslash, or if an arg requiring quoting ends with
Geoff Voelker's avatar
Geoff Voelker committed
833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849
     backslash.  In such cases, the run of escape characters needs to be
     doubled.  For consistency, we apply this special handling as long
     as the escape character is not quote.

     Since we have no idea how large argv and envp are likely to be we
     figure out list lengths on the fly and allocate them.  */

  if (!NILP (Vw32_quote_process_args))
    {
      do_quoting = 1;
      /* Override escape char by binding w32-quote-process-args to
	 desired character, or use t for auto-selection.  */
      if (INTEGERP (Vw32_quote_process_args))
	escape_char = XINT (Vw32_quote_process_args);
      else
	escape_char = is_cygnus_app ? '"' : '\\';
    }
850

851
  /* Cygwin apps needs quoting a bit more often.  */
852 853 854
  if (escape_char == '"')
    sepchars = "\r\n\t\f '";

Richard M. Stallman's avatar
Richard M. Stallman committed
855 856 857 858 859
  /* do argv...  */
  arglen = 0;
  targ = argv;
  while (*targ)
    {
860
      char * p = *targ;
Geoff Voelker's avatar
Geoff Voelker committed
861 862
      int need_quotes = 0;
      int escape_char_run = 0;
863 864

      if (*p == 0)
Geoff Voelker's avatar
Geoff Voelker committed
865 866 867
	need_quotes = 1;
      for ( ; *p; p++)
	{
868 869 870 871
	  if (escape_char == '"' && *p == '\\')
	    /* If it's a Cygwin app, \ needs to be escaped.  */
	    arglen++;
	  else if (*p == '"')
Geoff Voelker's avatar
Geoff Voelker committed
872 873 874 875 876 877 878 879 880 881 882 883 884
	    {
	      /* allow for embedded quotes to be escaped */
	      arglen++;
	      need_quotes = 1;
	      /* handle the case where the embedded quote is already escaped */
	      if (escape_char_run > 0)
		{
		  /* To preserve the arg exactly, we need to double the
		     preceding escape characters (plus adding one to
		     escape the quote character itself).  */
		  arglen += escape_char_run;
		}
	    }
885
	  else if (strchr (sepchars, *p) != NULL)
Geoff Voelker's avatar
Geoff Voelker committed
886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902
	    {
	      need_quotes = 1;
	    }

	  if (*p == escape_char && escape_char != '"')
	    escape_char_run++;
	  else
	    escape_char_run = 0;
	}
      if (need_quotes)
	{
	  arglen += 2;
	  /* handle the case where the arg ends with an escape char - we
	     must not let the enclosing quote be escaped.  */
	  if (escape_char_run > 0)
	    arglen += escape_char_run;
	}
Richard M. Stallman's avatar
Richard M. Stallman committed
903 904
      arglen += strlen (*targ++) + 1;
    }
905
  cmdline = alloca (arglen);
Richard M. Stallman's avatar
Richard M. Stallman committed
906 907 908 909
  targ = argv;
  parg = cmdline;
  while (*targ)
    {
910
      char * p = *targ;
Geoff Voelker's avatar
Geoff Voelker committed
911
      int need_quotes = 0;
912 913

      if (*p == 0)
Geoff Voelker's avatar
Geoff Voelker committed
914
	need_quotes = 1;
915

Geoff Voelker's avatar
Geoff Voelker committed
916
      if (do_quoting)
917 918
	{
	  for ( ; *p; p++)
919
	    if ((strchr (sepchars, *p) != NULL) || *p == '"')
Geoff Voelker's avatar
Geoff Voelker committed
920
	      need_quotes = 1;
921
	}
Geoff Voelker's avatar
Geoff Voelker committed
922
      if (need_quotes)
923
	{
Geoff Voelker's avatar
Geoff Voelker committed
924
	  int escape_char_run = 0;
925 926 927 928 929 930 931
	  char * first;
	  char * last;

	  p = *targ;
	  first = p;
	  last = p + strlen (p) - 1;
	  *parg++ = '"';
Geoff Voelker's avatar
Geoff Voelker committed
932 933 934
#if 0
	  /* This version does not escape quotes if they occur at the
	     beginning or end of the arg - this could lead to incorrect
Glenn Morris's avatar
Glenn Morris committed
935
	     behavior when the arg itself represents a command line
Geoff Voelker's avatar
Geoff Voelker committed
936 937 938
	     containing quoted args.  I believe this was originally done
	     as a hack to make some things work, before
	     `w32-quote-process-args' was added.  */
939 940 941
	  while (*p)
	    {
	      if (*p == '"' && p > first && p < last)
Geoff Voelker's avatar
Geoff Voelker committed
942
		*parg++ = escape_char;	/* escape embedded quotes */
943 944
	      *parg++ = *p++;
	    }
Geoff Voelker's avatar
Geoff Voelker committed
945 946 947 948 949 950 951 952 953 954 955 956 957 958
#else
	  for ( ; *p; p++)
	    {
	      if (*p == '"')
		{
		  /* double preceding escape chars if any */
		  while (escape_char_run > 0)
		    {
		      *parg++ = escape_char;
		      escape_char_run--;
		    }
		  /* escape all quote chars, even at beginning or end */
		  *parg++ = escape_char;
		}
959 960
	      else if (escape_char == '"' && *p == '\\')
		*parg++ = '\\';
Geoff Voelker's avatar
Geoff Voelker committed
961 962 963 964 965 966 967 968 969 970 971 972 973 974
	      *parg++ = *p;

	      if (*p == escape_char && escape_char != '"')
		escape_char_run++;
	      else
		escape_char_run = 0;
	    }
	  /* double escape chars before enclosing quote */
	  while (escape_char_run > 0)
	    {
	      *parg++ = escape_char;
	      escape_char_run--;
	    }
#endif
975 976 977 978 979 980 981
	  *parg++ = '"';
	}
      else
	{
	  strcpy (parg, *targ);
	  parg += strlen (*targ);
	}
Richard M. Stallman's avatar
Richard M. Stallman committed
982
      *parg++ = ' ';
983
      targ++;
Richard M. Stallman's avatar
Richard M. Stallman committed
984 985
    }
  *--parg = '\0';
986

Richard M. Stallman's avatar
Richard M. Stallman committed
987 988 989
  /* and envp...  */
  arglen = 1;
  targ = envp;
990
  numenv = 1; /* for end null */
Richard M. Stallman's avatar
Richard M. Stallman committed
991 992 993
  while (*targ)
    {
      arglen += strlen (*targ++) + 1;
994
      numenv++;
Richard M. Stallman's avatar
Richard M. Stallman committed
995
    }
996
  /* extra env vars... */
997
  sprintf (ppid_env_var_buffer, "EM_PARENT_PROCESS_ID=%d",
Richard M. Stallman's avatar
Richard M. Stallman committed
998 999
	   GetCurrentProcessId ());
  arglen += strlen (ppid_env_var_buffer) + 1;
1000
  numenv++;
Richard M. Stallman's avatar
Richard M. Stallman committed
1001

1002 1003 1004 1005 1006
  /* merge env passed in and extra env into one, and sort it.  */
  targ = (char **) alloca (numenv * sizeof (char *));
  merge_and_sort_env (envp, extra_env, targ);

  /* concatenate env entries.  */
1007
  env = alloca (arglen);
Richard M. Stallman's avatar
Richard M. Stallman committed
1008 1009 1010 1011 1012 1013 1014 1015 1016
  parg = env;
  while (*targ)
    {
      strcpy (parg, *targ);
      parg += strlen (*targ++);
      *parg++ = '\0';
    }
  *parg++ = '\0';
  *parg = '\0';
1017 1018 1019 1020 1021 1022 1023

  cp = new_child ();
  if (cp == NULL)
    {
      errno = EAGAIN;
      return -1;
    }
1024

Richard M. Stallman's avatar
Richard M. Stallman committed
1025
  /* Now create the process.  */
1026
  if (!create_child (cmdname, cmdline, env, is_gui_app, &pid, cp))
Richard M. Stallman's avatar
Richard M. Stallman committed
1027
    {
1028
      delete_child (cp);
Richard M. Stallman's avatar
Richard M. Stallman committed
1029
      errno = ENOEXEC;
1030
      return -1;
Richard M. Stallman's avatar
Richard M. Stallman committed
1031
    }
1032

1033
  return pid;
Richard M. Stallman's avatar
Richard M. Stallman committed
1034 1035 1036 1037 1038
}

/* Emulate the select call
   Wait for available input on any of the given rfds, or timeout if
   a timeout is given and no input is detected
Geoff Voelker's avatar
Geoff Voelker committed
1039 1040 1041 1042 1043 1044 1045
   wfds and efds are not supported and must be NULL.

   For simplicity, we detect the death of child processes here and
   synchronously call the SIGCHLD handler.  Since it is possible for
   children to be created without a corresponding pipe handle from which
   to read output, we wait separately on the process handles as well as
   the char_avail events for each process pipe.  We only call
1046 1047 1048 1049
   wait/reap_process when the process actually terminates.

   To reduce the number of places in which Emacs can be hung such that
   C-g is not able to interrupt it, we always wait on interrupt_handle
Glenn Morris's avatar
Glenn Morris committed
1050
   (which is signaled by the input thread when C-g is detected).  If we
1051 1052
   detect that we were woken up by C-g, we return -1 with errno set to
   EINTR as on Unix.  */
Richard M. Stallman's avatar
Richard M. Stallman committed
1053

1054
/* From w32console.c */
Richard M. Stallman's avatar
Richard M. Stallman committed
1055
extern HANDLE keyboard_handle;
1056 1057 1058 1059

/* From w32xfns.c */
extern HANDLE interrupt_handle;

Richard M. Stallman's avatar
Richard M. Stallman committed
1060 1061 1062
/* From process.c */
extern int proc_buffered_char[];

1063
int
1064 1065
sys_select (int nfds, SELECT_TYPE *rfds, SELECT_TYPE *wfds, SELECT_TYPE *efds,
	    EMACS_TIME *timeout)
Richard M. Stallman's avatar
Richard M. Stallman committed
1066 1067
{
  SELECT_TYPE orfds;
Geoff Voelker's avatar
Geoff Voelker committed
1068 1069
  DWORD timeout_ms, start_time;
  int i, nh, nc, nr;
Richard M. Stallman's avatar
Richard M. Stallman committed
1070
  DWORD active;
Geoff Voelker's avatar
Geoff Voelker committed
1071 1072
  child_process *cp, *cps[MAX_CHILDREN];
  HANDLE wait_hnd[MAXDESC + MAX_CHILDREN];
1073
  int fdindex[MAXDESC];   /* mapping from wait handles back to descriptors */
1074

Geoff Voelker's avatar
Geoff Voelker committed
1075 1076
  timeout_ms = timeout ? (timeout->tv_sec * 1000 + timeout->tv_usec / 1000) : INFINITE;

Richard M. Stallman's avatar
Richard M. Stallman committed
1077
  /* If the descriptor sets are NULL but timeout isn't, then just Sleep.  */
1078
  if (rfds == NULL && wfds == NULL && efds == NULL && timeout != NULL)
Richard M. Stallman's avatar
Richard M. Stallman committed
1079
    {
Geoff Voelker's avatar
Geoff Voelker committed
1080
      Sleep (timeout_ms);
Richard M. Stallman's avatar
Richard M. Stallman committed
1081 1082 1083 1084 1085 1086 1087 1088 1089
      return 0;
    }

  /* Otherwise, we only handle rfds, so fail otherwise.  */
  if (rfds == NULL || wfds != NULL || efds != NULL)
    {
      errno = EINVAL;
      return -1;
    }
1090

Richard M. Stallman's avatar
Richard M. Stallman committed
1091 1092 1093
  orfds = *rfds;
  FD_ZERO (rfds);
  nr = 0;
1094 1095 1096 1097

  /* Always wait on interrupt_handle, to detect C-g (quit).  */
  wait_hnd[0] = interrupt_handle;
  fdindex[0] = -1;
1098

Geoff Voelker's avatar
Geoff Voelker committed
1099
  /* Build a list of pipe handles to wait on.  */
1100
  nh = 1;
Richard M. Stallman's avatar
Richard M. Stallman committed