(U-000221C7): Add `sound@ja/on'; integrate BC-8BD8.
[chise/xemacs-chise.git] / src / process-nt.c
1 /* Asynchronous subprocess implementation for Win32
2    Copyright (C) 1985, 1986, 1987, 1988, 1992, 1993, 1994, 1995
3    Free Software Foundation, Inc.
4    Copyright (C) 1995 Sun Microsystems, Inc.
5    Copyright (C) 1995, 1996, 2000 Ben Wing.
6
7 This file is part of XEmacs.
8
9 XEmacs is free software; you can redistribute it and/or modify it
10 under the terms of the GNU General Public License as published by the
11 Free Software Foundation; either version 2, or (at your option) any
12 later version.
13
14 XEmacs is distributed in the hope that it will be useful, but WITHOUT
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
17 for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with XEmacs; see the file COPYING.  If not, write to
21 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
22 Boston, MA 02111-1307, USA.  */
23
24 /* Written by Kirill M. Katsnelson <kkm@kis.ru>, April 1998 */
25
26 #include <config.h>
27 #include "lisp.h"
28
29 #include "buffer.h"
30 #include "console-msw.h"
31 #include "hash.h"
32 #include "lstream.h"
33 #include "nt.h"
34 #include "process.h"
35 #include "procimpl.h"
36 #include "sysdep.h"
37
38 #include <shellapi.h>
39 #include <errno.h>
40 #include <signal.h>
41 #ifdef HAVE_SOCKETS
42 #include <winsock.h>
43 #endif
44
45 /* Bound by win32-native.el */
46 Lisp_Object Qmswindows_construct_process_command_line;
47
48 /* Arbitrary size limit for code fragments passed to run_in_other_process */
49 #define FRAGMENT_CODE_SIZE 32
50
51 /* Implementation-specific data. Pointed to by Lisp_Process->process_data */
52 struct nt_process_data
53 {
54   HANDLE h_process;
55   DWORD dwProcessId;
56   HWND hwnd; /* console window */
57 };
58
59 /* Control whether create_child causes the process to inherit Emacs'
60    console window, or be given a new one of its own.  The default is
61    nil, to allow multiple DOS programs to run on Win95.  Having separate
62    consoles also allows Emacs to cleanly terminate process groups.  */
63 Lisp_Object Vmswindows_start_process_share_console;
64
65 /* Control whether create_child cause the process to inherit Emacs'
66    error mode setting.  The default is t, to minimize the possibility of
67    subprocesses blocking when accessing unmounted drives.  */
68 Lisp_Object Vmswindows_start_process_inherit_error_mode;
69
70 #define NT_DATA(p) ((struct nt_process_data*)((p)->process_data))
71 \f
72 /*-----------------------------------------------------------------------*/
73 /* Process helpers                                                       */
74 /*-----------------------------------------------------------------------*/
75
76 /* This one breaks process abstraction. Prototype is in console-msw.h,
77    used by select_process method in event-msw.c */
78 HANDLE
79 get_nt_process_handle (Lisp_Process *p)
80 {
81   return (NT_DATA (p)->h_process);
82 }
83
84 static struct Lisp_Process *
85 find_process_from_pid (DWORD pid)
86 {
87   Lisp_Object tail, proc;
88
89   for (tail = Vprocess_list; CONSP (tail); tail = XCDR (tail))
90     {
91       proc = XCAR (tail);
92       if (NT_DATA (XPROCESS (proc))->dwProcessId == pid)
93         return XPROCESS (proc);
94     }
95   return 0;
96 }
97
98 \f
99 /*-----------------------------------------------------------------------*/
100 /* Running remote threads. See Microsoft Systems Journal 1994 Number 5   */
101 /* Jeffrey Richter, Load Your 32-bit DLL into Another Process's Address..*/
102 /*-----------------------------------------------------------------------*/
103
104 typedef struct
105 {
106   HANDLE h_process;
107   HANDLE h_thread;
108   LPVOID address;
109 } process_memory;
110
111 /*
112  * Allocate SIZE bytes in H_PROCESS address space. Fill in PMC used
113  * further by other routines. Return nonzero if successful.
114  *
115  * The memory in other process is allocated by creating a suspended
116  * thread. Initial stack of that thread is used as the memory
117  * block. The thread entry point is the routine ExitThread in
118  * kernel32.dll, so the allocated memory is freed just by resuming the 
119  * thread, which immediately terminates after that.
120  */
121
122 static int 
123 alloc_process_memory (HANDLE h_process, size_t size,
124                       process_memory* pmc)
125 {
126   LPTHREAD_START_ROUTINE adr_ExitThread =
127     (LPTHREAD_START_ROUTINE)
128     GetProcAddress (GetModuleHandle ("kernel32"), "ExitThread");
129   DWORD dw_unused;
130   CONTEXT context;
131   MEMORY_BASIC_INFORMATION mbi;
132
133   pmc->h_process = h_process;
134   pmc->h_thread = CreateRemoteThread (h_process, NULL, size,
135                                      adr_ExitThread, NULL,
136                                      CREATE_SUSPENDED, &dw_unused);
137   if (pmc->h_thread == NULL)
138     return 0;
139
140   /* Get context, for thread's stack pointer */
141   context.ContextFlags = CONTEXT_CONTROL;
142   if (!GetThreadContext (pmc->h_thread, &context))
143     goto failure;
144
145   /* Determine base address of the committed range */
146   if (sizeof(mbi) != VirtualQueryEx (h_process,
147 #if defined (_X86_)
148                                      (LPDWORD)context.Esp - 1,
149 #elif defined (_ALPHA_)
150                                      (LPDWORD)context.IntSp - 1,
151 #else
152 #error Unknown processor architecture
153 #endif
154                                      &mbi, sizeof(mbi)))
155     goto failure;
156
157   /* Change the page protection of the allocated memory to executable,
158      read, and write. */
159   if (!VirtualProtectEx (h_process, mbi.BaseAddress, size,
160                          PAGE_EXECUTE_READWRITE, &dw_unused))
161     goto failure;
162
163   pmc->address = mbi.BaseAddress;
164   return 1;
165
166  failure:
167   ResumeThread (pmc->h_thread);
168   pmc->address = 0;
169   return 0;
170 }
171
172 static void
173 free_process_memory (process_memory* pmc)
174 {
175   ResumeThread (pmc->h_thread);
176 }
177
178 /*
179  * Run ROUTINE in the context of process determined by H_PROCESS. The
180  * routine is passed the address of DATA as parameter. The ROUTINE must
181  * not be longer than ROUTINE_CODE_SIZE bytes. DATA_SIZE is the size of
182  * DATA structure.
183  *
184  * Note that the code must be positionally independent, and compiled
185  * without stack checks (they cause implicit calls into CRT so will
186  * fail). DATA should not refer any data in calling process, as both
187  * routine and its data are copied into remote process. Size of data
188  * and code together should not exceed one page (4K on x86 systems).
189  *
190  * Return the value returned by ROUTINE, or (DWORD)-1 if call failed.
191  */
192 static DWORD
193 run_in_other_process (HANDLE h_process,
194                       LPTHREAD_START_ROUTINE routine,
195                       LPVOID data, size_t data_size)
196 {
197   process_memory pm;
198   const size_t code_size = FRAGMENT_CODE_SIZE;
199   /* Need at most 3 extra bytes of memory, for data alignment */
200   size_t total_size = code_size + data_size + 3;
201   LPVOID remote_data;
202   HANDLE h_thread;
203   DWORD dw_unused;
204
205   /* Allocate memory */
206   if (!alloc_process_memory (h_process, total_size, &pm))
207     return (DWORD)-1;
208
209   /* Copy code */
210   if (!WriteProcessMemory (h_process, pm.address, (LPVOID)routine,
211                            code_size, NULL))
212     goto failure;
213
214   /* Copy data */
215   if (data_size)
216     {
217       remote_data = (LPBYTE)pm.address + ((code_size + 4) & ~3);
218       if (!WriteProcessMemory (h_process, remote_data, data, data_size, NULL))
219         goto failure;
220     }
221   else
222     remote_data = NULL;
223
224   /* Execute the remote copy of code, passing it remote data */
225   h_thread = CreateRemoteThread (h_process, NULL, 0,
226                                  (LPTHREAD_START_ROUTINE) pm.address,
227                                  remote_data, 0, &dw_unused);
228   if (h_thread == NULL)
229     goto failure;
230
231   /* Wait till thread finishes */
232   WaitForSingleObject (h_thread, INFINITE);
233
234   /* Free remote memory */
235   free_process_memory (&pm);
236
237   /* Return thread's exit code */
238   {
239     DWORD exit_code;
240     GetExitCodeThread (h_thread, &exit_code);
241     CloseHandle (h_thread);
242     return exit_code;
243   }
244
245  failure:
246   free_process_memory (&pm);
247   return (DWORD)-1;
248 }
249 \f
250 /*-----------------------------------------------------------------------*/
251 /* Sending signals                                                       */
252 /*-----------------------------------------------------------------------*/
253
254 /* ---------------------------- the NT way ------------------------------- */
255
256 /*
257  * We handle the following signals:
258  *
259  * SIGKILL, SIGTERM, SIGQUIT, SIGHUP - These four translate to ExitProcess
260  *    executed by the remote process
261  * SIGINT - The remote process is sent CTRL_BREAK_EVENT
262  *
263  * The MSVC5.0 compiler feels free to re-order functions within a
264  * compilation unit, so we have no way of finding out the size of the
265  * following functions. Therefore these functions must not be larger than
266  * FRAGMENT_CODE_SIZE.
267  */
268
269 /*
270  * Sending SIGKILL
271  */
272 typedef struct
273 {
274   void (WINAPI *adr_ExitProcess) (UINT);
275 } sigkill_data;
276
277 static DWORD WINAPI
278 sigkill_proc (sigkill_data* data)
279 {
280   (*data->adr_ExitProcess)(255);
281   return 1;
282 }
283
284 /*
285  * Sending break or control c
286  */
287 typedef struct
288 {
289   BOOL (WINAPI *adr_GenerateConsoleCtrlEvent) (DWORD, DWORD);
290   DWORD event;
291 } sigint_data;
292
293 static DWORD WINAPI
294 sigint_proc (sigint_data* data)
295 {
296   return (*data->adr_GenerateConsoleCtrlEvent) (data->event, 0);
297 }
298
299 /*
300  * Enabling signals
301  */
302 typedef struct
303 {
304   BOOL (WINAPI *adr_SetConsoleCtrlHandler) (LPVOID, BOOL);
305 } sig_enable_data;
306
307 static DWORD WINAPI
308 sig_enable_proc (sig_enable_data* data)
309 {
310   (*data->adr_SetConsoleCtrlHandler) (NULL, FALSE);
311   return 1;
312 }
313
314 /*
315  * Send signal SIGNO to process H_PROCESS.
316  * Return nonzero if successful.
317  */
318
319 static int
320 send_signal_the_nt_way (struct nt_process_data *cp, int pid, int signo)
321 {
322   HANDLE h_process;
323   HMODULE h_kernel = GetModuleHandle ("kernel32");
324   int close_process = 0;
325   DWORD retval;
326   
327   assert (h_kernel != NULL);
328   
329   if (cp)
330     {
331       pid = cp->dwProcessId;
332       h_process = cp->h_process;
333     }
334   else
335     {
336       close_process = 1;
337       /* Try to open the process with required privileges */
338       h_process = OpenProcess (PROCESS_CREATE_THREAD
339                                | PROCESS_QUERY_INFORMATION 
340                                | PROCESS_VM_OPERATION
341                                | PROCESS_VM_WRITE,
342                                FALSE, pid);
343       if (!h_process)
344         return 0;
345     }
346
347   switch (signo)
348     {
349     case SIGKILL:
350     case SIGTERM:
351     case SIGQUIT:
352     case SIGHUP:
353       {
354         sigkill_data d;
355
356         d.adr_ExitProcess =
357           (void (WINAPI *) (UINT)) GetProcAddress (h_kernel, "ExitProcess");
358         assert (d.adr_ExitProcess);
359         retval = run_in_other_process (h_process, 
360                                        (LPTHREAD_START_ROUTINE)sigkill_proc,
361                                        &d, sizeof (d));
362         break;
363       }
364     case SIGINT:
365       {
366         sigint_data d;
367         d.adr_GenerateConsoleCtrlEvent =
368           (BOOL (WINAPI *) (DWORD, DWORD))
369           GetProcAddress (h_kernel, "GenerateConsoleCtrlEvent");
370         assert (d.adr_GenerateConsoleCtrlEvent);
371         d.event = CTRL_C_EVENT;
372         retval = run_in_other_process (h_process, 
373                                        (LPTHREAD_START_ROUTINE)sigint_proc,
374                                        &d, sizeof (d));
375         break;
376       }
377     default:
378       assert (0);
379     }
380
381   if (close_process)
382     CloseHandle (h_process);
383   return (int)retval > 0 ? 1 : 0;
384 }
385
386 /*
387  * Enable CTRL_C_EVENT handling in a new child process
388  */
389 static void
390 enable_child_signals (HANDLE h_process)
391 {
392   HMODULE h_kernel = GetModuleHandle ("kernel32");
393   sig_enable_data d;
394   
395   assert (h_kernel != NULL);
396   d.adr_SetConsoleCtrlHandler =
397     (BOOL (WINAPI *) (LPVOID, BOOL))
398     GetProcAddress (h_kernel, "SetConsoleCtrlHandler");
399   assert (d.adr_SetConsoleCtrlHandler);
400   run_in_other_process (h_process, (LPTHREAD_START_ROUTINE)sig_enable_proc,
401                         &d, sizeof (d));
402 }
403   
404 #pragma warning (default : 4113)
405
406 /* ---------------------------- the 95 way ------------------------------- */
407
408 static BOOL CALLBACK
409 find_child_console (HWND hwnd, long putada)
410 {
411   DWORD thread_id;
412   DWORD process_id;
413   struct nt_process_data *cp = (struct nt_process_data *) putada;
414
415   thread_id = GetWindowThreadProcessId (hwnd, &process_id);
416   if (process_id == cp->dwProcessId)
417     {
418       char window_class[32];
419
420       GetClassName (hwnd, window_class, sizeof (window_class));
421       if (strcmp (window_class,
422                   mswindows_windows9x_p ()
423                   ? "tty"
424                   : "ConsoleWindowClass") == 0)
425         {
426           cp->hwnd = hwnd;
427           return FALSE;
428         }
429     }
430   /* keep looking */
431   return TRUE;
432 }
433
434 static int
435 send_signal_the_95_way (struct nt_process_data *cp, int pid, int signo)
436 {
437   HANDLE h_process;
438   int close_process = 0;
439   int rc = 1;
440   
441   if (cp)
442     {
443       pid = cp->dwProcessId;
444       h_process = cp->h_process;
445
446       /* Try to locate console window for process. */
447       EnumWindows (find_child_console, (LPARAM) cp);
448     }
449   else
450     {
451       close_process = 1;
452       /* Try to open the process with required privileges */
453       h_process = OpenProcess (PROCESS_TERMINATE, FALSE, pid);
454       if (!h_process)
455         return 0;
456     }
457     
458   if (signo == SIGINT)
459     {
460       if (NILP (Vmswindows_start_process_share_console) && cp && cp->hwnd)
461         {
462           BYTE control_scan_code = (BYTE) MapVirtualKey (VK_CONTROL, 0);
463           BYTE vk_break_code = VK_CANCEL;
464           BYTE break_scan_code = (BYTE) MapVirtualKey (vk_break_code, 0);
465           HWND foreground_window;
466
467           if (break_scan_code == 0)
468             {
469               /* Fake Ctrl-C if we can't manage Ctrl-Break. */
470               vk_break_code = 'C';
471               break_scan_code = (BYTE) MapVirtualKey (vk_break_code, 0);
472             }
473
474           foreground_window = GetForegroundWindow ();
475           if (foreground_window)
476             {
477               /* NT 5.0, and apparently also Windows 98, will not allow
478                  a Window to be set to foreground directly without the
479                  user's involvement. The workaround is to attach
480                  ourselves to the thread that owns the foreground
481                  window, since that is the only thread that can set the
482                  foreground window.  */
483               DWORD foreground_thread, child_thread;
484               foreground_thread =
485                 GetWindowThreadProcessId (foreground_window, NULL);
486               if (foreground_thread == GetCurrentThreadId ()
487                   || !AttachThreadInput (GetCurrentThreadId (),
488                                          foreground_thread, TRUE))
489                 foreground_thread = 0;
490
491               child_thread = GetWindowThreadProcessId (cp->hwnd, NULL);
492               if (child_thread == GetCurrentThreadId ()
493                   || !AttachThreadInput (GetCurrentThreadId (),
494                                          child_thread, TRUE))
495                 child_thread = 0;
496
497               /* Set the foreground window to the child.  */
498               if (SetForegroundWindow (cp->hwnd))
499                 {
500                   /* Generate keystrokes as if user had typed Ctrl-Break or
501                      Ctrl-C.  */
502                   keybd_event (VK_CONTROL, control_scan_code, 0, 0);
503                   keybd_event (vk_break_code, break_scan_code,
504                     (vk_break_code == 'C' ? 0 : KEYEVENTF_EXTENDEDKEY), 0);
505                   keybd_event (vk_break_code, break_scan_code,
506                     (vk_break_code == 'C' ? 0 : KEYEVENTF_EXTENDEDKEY)
507                     | KEYEVENTF_KEYUP, 0);
508                   keybd_event (VK_CONTROL, control_scan_code,
509                                KEYEVENTF_KEYUP, 0);
510
511                   /* Sleep for a bit to give time for Emacs frame to respond
512                      to focus change events (if Emacs was active app).  */
513                   Sleep (100);
514
515                   SetForegroundWindow (foreground_window);
516                 }
517               /* Detach from the foreground and child threads now that
518                  the foreground switching is over.  */
519               if (foreground_thread)
520                 AttachThreadInput (GetCurrentThreadId (),
521                                    foreground_thread, FALSE);
522               if (child_thread)
523                 AttachThreadInput (GetCurrentThreadId (),
524                                    child_thread, FALSE);
525             }
526         }
527       /* Ctrl-Break is NT equivalent of SIGINT.  */
528       else if (!GenerateConsoleCtrlEvent (CTRL_BREAK_EVENT, pid))
529         {
530 #if 0 /* FSF Emacs */
531           DebPrint (("sys_kill.GenerateConsoleCtrlEvent return %d "
532                      "for pid %lu\n", GetLastError (), pid));
533           errno = EINVAL;
534 #endif
535           rc = 0;
536         }
537     }
538   else
539     {
540       if (NILP (Vmswindows_start_process_share_console) && cp && cp->hwnd)
541         {
542 #if 1
543           if (mswindows_windows9x_p ())
544             {
545 /*
546    Another possibility is to try terminating the VDM out-right by
547    calling the Shell VxD (id 0x17) V86 interface, function #4
548    "SHELL_Destroy_VM", ie.
549
550      mov edx,4
551      mov ebx,vm_handle
552      call shellapi
553
554    First need to determine the current VM handle, and then arrange for
555    the shellapi call to be made from the system vm (by using
556    Switch_VM_and_callback).
557
558    Could try to invoke DestroyVM through CallVxD.
559
560 */
561 #if 0
562               /* On Win95, posting WM_QUIT causes the 16-bit subsystem
563                  to hang when cmdproxy is used in conjunction with
564                  command.com for an interactive shell.  Posting
565                  WM_CLOSE pops up a dialog that, when Yes is selected,
566                  does the same thing.  TerminateProcess is also less
567                  than ideal in that subprocesses tend to stick around
568                  until the machine is shutdown, but at least it
569                  doesn't freeze the 16-bit subsystem.  */
570               PostMessage (cp->hwnd, WM_QUIT, 0xff, 0);
571 #endif
572               if (!TerminateProcess (h_process, 0xff))
573                 {
574 #if 0 /* FSF Emacs */
575                   DebPrint (("sys_kill.TerminateProcess returned %d "
576                              "for pid %lu\n", GetLastError (), pid));
577                   errno = EINVAL;
578 #endif
579                   rc = 0;
580                 }
581             }
582           else
583 #endif
584             PostMessage (cp->hwnd, WM_CLOSE, 0, 0);
585         }
586       /* Kill the process.  On W32 this doesn't kill child processes
587          so it doesn't work very well for shells which is why it's not
588          used in every case.  */
589       else if (!TerminateProcess (h_process, 0xff))
590         {
591 #if 0 /* FSF Emacs */
592           DebPrint (("sys_kill.TerminateProcess returned %d "
593                      "for pid %lu\n", GetLastError (), pid));
594           errno = EINVAL;
595 #endif
596           rc = 0;
597         }
598     }
599
600   if (close_process)
601     CloseHandle (h_process);
602
603   return rc;
604 }
605
606 /* -------------------------- all-OS functions ---------------------------- */
607
608 static int
609 send_signal (struct nt_process_data *cp, int pid, int signo)
610 {
611   return (!mswindows_windows9x_p () && send_signal_the_nt_way (cp, pid, signo))
612     || send_signal_the_95_way (cp, pid, signo);
613 }
614
615 /*
616  * Signal error if SIGNO is not supported
617  */
618 static void
619 validate_signal_number (int signo)
620 {
621   if (signo != SIGKILL && signo != SIGTERM
622       && signo != SIGQUIT && signo != SIGINT
623       && signo != SIGHUP)
624     invalid_argument ("Signal number not supported", make_int (signo));
625 }
626 \f  
627 /*-----------------------------------------------------------------------*/
628 /* Process methods                                                       */
629 /*-----------------------------------------------------------------------*/
630
631 /*
632  * Allocate and initialize Lisp_Process->process_data
633  */
634
635 static void
636 nt_alloc_process_data (Lisp_Process *p)
637 {
638   p->process_data = xnew_and_zero (struct nt_process_data);
639 }
640
641 static void
642 nt_finalize_process_data (Lisp_Process *p, int for_disksave)
643 {
644   assert (!for_disksave);
645   /* If it's still in the list of processes we are waiting on delete
646      it.  */
647   mswindows_unwait_process (p);
648   if (NT_DATA (p)->h_process)
649     CloseHandle (NT_DATA (p)->h_process);
650 }
651
652 /*
653  * Initialize XEmacs process implementation once
654  */
655 static void
656 nt_init_process (void)
657 {
658   /* Initialize winsock */
659   WSADATA wsa_data;
660   /* Request Winsock v1.1 Note the order: (minor=1, major=1) */
661   WSAStartup (MAKEWORD (1,1), &wsa_data);
662 }
663
664 /*
665  * Fork off a subprocess. P is a pointer to newly created subprocess
666  * object. If this function signals, the caller is responsible for
667  * deleting (and finalizing) the process object.
668  *
669  * The method must return PID of the new process, a (positive??? ####) number
670  * which fits into Lisp_Int. No return value indicates an error, the method
671  * must signal an error instead.
672  */
673
674 static void
675 signal_cannot_launch (Lisp_Object image_file, DWORD err)
676 {
677   mswindows_set_errno (err);
678   report_file_error ("Error starting", image_file);
679 }
680
681 static void
682 ensure_console_window_exists (void)
683 {
684   if (mswindows_windows9x_p ())
685     mswindows_hide_console ();
686 }
687
688 int
689 compare_env (const void *strp1, const void *strp2)
690 {
691   const char *str1 = *(const char**)strp1, *str2 = *(const char**)strp2;
692
693   while (*str1 && *str2 && *str1 != '=' && *str2 != '=')
694     {
695       if ((*str1) > (*str2))
696         return 1;
697       else if ((*str1) < (*str2))
698         return -1;
699       str1++, str2++;
700     }
701
702   if (*str1 == '=' && *str2 == '=')
703     return 0;
704   else if (*str1 == '=')
705     return -1;
706   else
707     return 1;
708 }
709
710 static int
711 nt_create_process (Lisp_Process *p,
712                    Lisp_Object *argv, int nargv,
713                    Lisp_Object program, Lisp_Object cur_dir)
714 {
715   /* Synched up with sys_spawnve in FSF 20.6.  Significantly different
716      but still synchable. */
717   HANDLE hmyshove, hmyslurp, hprocin, hprocout, hprocerr;
718   Extbyte *command_line;
719   BOOL do_io, windowed;
720   char *proc_env;
721
722   /* No need to DOS-ize the filename; expand-file-name (called prior)
723      already does this. */
724
725   /* Find out whether the application is windowed or not */
726   if (xSHGetFileInfoA)
727     {
728       /* SHGetFileInfo tends to return ERROR_FILE_NOT_FOUND on most
729          errors. This leads to bogus error message. */
730       DWORD image_type;
731       char *p = strrchr ((char *)XSTRING_DATA (program), '.');
732       if (p != NULL &&
733           (stricmp (p, ".exe") == 0 ||
734            stricmp (p, ".com") == 0 ||
735            stricmp (p, ".bat") == 0 ||
736            stricmp (p, ".cmd") == 0))
737         {
738           image_type = xSHGetFileInfoA ((char *)XSTRING_DATA (program), 0,NULL,
739                                         0, SHGFI_EXETYPE);
740         }
741       else
742         {
743           char progname[MAX_PATH];
744           sprintf (progname, "%s.exe", (char *)XSTRING_DATA (program));
745           image_type = xSHGetFileInfoA (progname, 0, NULL, 0, SHGFI_EXETYPE);
746         }
747       if (image_type == 0)
748         signal_cannot_launch (program, (GetLastError () == ERROR_FILE_NOT_FOUND
749                                         ? ERROR_BAD_FORMAT : GetLastError ()));
750       windowed = HIWORD (image_type) != 0;
751     }
752   else /* NT 3.5; we have no idea so just guess. */
753     windowed = 0;
754
755   /* Decide whether to do I/O on process handles, or just mark the
756      process exited immediately upon successful launching. We do I/O if the
757      process is a console one, or if it is windowed but windowed_process_io
758      is non-zero */
759   do_io = !windowed || windowed_process_io ;
760   
761   if (do_io)
762     {
763       /* Create two unidirectional named pipes */
764       HANDLE htmp;
765       SECURITY_ATTRIBUTES sa;
766
767       sa.nLength = sizeof(sa);
768       sa.bInheritHandle = TRUE;
769       sa.lpSecurityDescriptor = NULL;
770
771       CreatePipe (&hprocin, &hmyshove, &sa, 0);
772       CreatePipe (&hmyslurp, &hprocout, &sa, 0);
773
774       /* Duplicate the stdout handle for use as stderr */
775       DuplicateHandle(GetCurrentProcess(), hprocout, GetCurrentProcess(),
776                       &hprocerr, 0, TRUE, DUPLICATE_SAME_ACCESS);
777
778       /* Stupid Win32 allows to create a pipe with *both* ends either
779          inheritable or not. We need process ends inheritable, and local
780          ends not inheritable. */
781       DuplicateHandle (GetCurrentProcess(), hmyshove, GetCurrentProcess(),
782                        &htmp, 0, FALSE,
783                        DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS);
784       hmyshove = htmp;
785       DuplicateHandle (GetCurrentProcess(), hmyslurp, GetCurrentProcess(),
786                        &htmp, 0, FALSE,
787                        DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS);
788       hmyslurp = htmp;
789     }
790
791   /* Convert an argv vector into Win32 style command line by a call to
792      lisp function `mswindows-construct-process-command-line'
793      (in win32-native.el) */
794   {
795     int i;
796     Lisp_Object args_or_ret = Qnil;
797     struct gcpro gcpro1;
798
799     GCPRO1 (args_or_ret);
800
801     for (i = 0; i < nargv; ++i)
802       args_or_ret = Fcons (*argv++, args_or_ret);
803     args_or_ret = Fnreverse (args_or_ret);
804     args_or_ret = Fcons (program, args_or_ret);
805
806     args_or_ret = call1 (Qmswindows_construct_process_command_line,
807                          args_or_ret);
808
809     if (!STRINGP (args_or_ret))
810       /* Luser wrote his/her own clever version */
811       invalid_argument
812         ("Bogus return value from `mswindows-construct-process-command-line'",
813          args_or_ret);
814
815     LISP_STRING_TO_EXTERNAL (args_or_ret, command_line, Qmswindows_tstr);
816
817     UNGCPRO; /* args_or_ret */
818   }
819
820   /* Set `proc_env' to a nul-separated array of the strings in
821      Vprocess_environment terminated by 2 nuls.  */
822  
823   {
824     char **env;
825     REGISTER Lisp_Object tem;
826     REGISTER char **new_env;
827     REGISTER int new_length = 0, i, new_space;
828     char *penv;
829     
830     for (tem = Vprocess_environment;
831          (CONSP (tem)
832           && STRINGP (XCAR (tem)));
833          tem = XCDR (tem))
834       new_length++;
835
836     /* FSF adds an extra env var to hold the current process ID of the
837        Emacs process.  Apparently this is used only by emacsserver.c,
838        which we have superseded to gnuserv.c. (#### Does it work under
839        MS Windows?)
840
841        sprintf (ppid_env_var_buffer, "EM_PARENT_PROCESS_ID=%d", 
842          GetCurrentProcessId ());
843        arglen += strlen (ppid_env_var_buffer) + 1;
844        numenv++;
845     */
846     
847     /* new_length + 1 to include terminating 0.  */
848     env = new_env = alloca_array (char *, new_length + 1);
849  
850     /* Copy the Vprocess_environment strings into new_env.  */
851     for (tem = Vprocess_environment;
852          (CONSP (tem)
853           && STRINGP (XCAR (tem)));
854          tem = XCDR (tem))
855       {
856         char **ep = env;
857         char *string = (char *) XSTRING_DATA (XCAR (tem));
858         /* See if this string duplicates any string already in the env.
859            If so, don't put it in.
860            When an env var has multiple definitions,
861            we keep the definition that comes first in process-environment.  */
862         for (; ep != new_env; ep++)
863           {
864             char *p = *ep, *q = string;
865             while (1)
866               {
867                 if (*q == 0)
868                   /* The string is malformed; might as well drop it.  */
869                   goto duplicate;
870                 if (*q != *p)
871                   break;
872                 if (*q == '=')
873                   goto duplicate;
874                 p++, q++;
875               }
876           }
877         *new_env++ = string;
878       duplicate: ;
879       }
880     *new_env = 0;
881     
882     /* Sort the environment variables */
883     new_length = new_env - env;
884     qsort (env, new_length, sizeof (char *), compare_env);
885     
886     /* Work out how much space to allocate */
887     new_space = 0;
888     for (i = 0; i < new_length; i++)
889       {
890         new_space += strlen(env[i]) + 1;
891       }
892     new_space++;
893     
894     /* Allocate space and copy variables into it */
895     penv = proc_env = (char*) alloca(new_space);
896     for (i = 0; i < new_length; i++)
897       {
898         strcpy(penv, env[i]);
899         penv += strlen(env[i]) + 1;
900       }
901     *penv = 0;
902   }
903
904 #if 0
905     /* #### we need to port this. */
906     /* On Windows 95, if cmdname is a DOS app, we invoke a helper
907        application to start it by specifying the helper app as cmdname,
908        while leaving the real app name as argv[0].  */
909     if (is_dos_app)
910       {
911         cmdname = (char*) alloca (MAXPATHLEN);
912         if (egetenv ("CMDPROXY"))
913           strcpy ((char*)cmdname, egetenv ("CMDPROXY"));
914         else
915           {
916             strcpy ((char*)cmdname, XSTRING_DATA (Vinvocation_directory));
917             strcat ((char*)cmdname, "cmdproxy.exe");
918           }
919       }
920 #endif
921   
922   /* Create process */
923   {
924     STARTUPINFO si;
925     PROCESS_INFORMATION pi;
926     DWORD err;
927     DWORD flags;
928
929     xzero (si);
930     si.dwFlags = STARTF_USESHOWWINDOW;
931     si.wShowWindow = windowed ? SW_SHOWNORMAL : SW_HIDE;
932     if (do_io)
933       {
934         si.hStdInput = hprocin;
935         si.hStdOutput = hprocout;
936         si.hStdError = hprocerr;
937         si.dwFlags |= STARTF_USESTDHANDLES;
938       }
939
940     flags = CREATE_SUSPENDED;
941     if (mswindows_windows9x_p ())
942       flags |= (!NILP (Vmswindows_start_process_share_console)
943                 ? CREATE_NEW_PROCESS_GROUP
944                 : CREATE_NEW_CONSOLE);
945     else
946       flags |= CREATE_NEW_CONSOLE | CREATE_NEW_PROCESS_GROUP;
947     if (NILP (Vmswindows_start_process_inherit_error_mode))
948       flags |= CREATE_DEFAULT_ERROR_MODE;
949
950     ensure_console_window_exists ();
951
952     err = (CreateProcess (NULL, command_line, NULL, NULL, TRUE, flags,
953                           proc_env, (char *) XSTRING_DATA (cur_dir), &si, &pi)
954            ? 0 : GetLastError ());
955
956     if (do_io)
957       {
958         /* These just have been inherited; we do not need a copy */
959         CloseHandle (hprocin);
960         CloseHandle (hprocout);
961         CloseHandle (hprocerr);
962       }
963     
964     /* Handle process creation failure */
965     if (err)
966       {
967         if (do_io)
968           {
969             CloseHandle (hmyshove);
970             CloseHandle (hmyslurp);
971           }
972         signal_cannot_launch (program, GetLastError ());
973       }
974
975     /* The process started successfully */
976     if (do_io)
977       {
978         NT_DATA(p)->h_process = pi.hProcess;
979         NT_DATA(p)->dwProcessId = pi.dwProcessId;
980         init_process_io_handles (p, (void*)hmyslurp, (void*)hmyshove, 0);
981       }
982     else
983       {
984         /* Indicate as if the process has exited immediately. */
985         p->status_symbol = Qexit;
986         CloseHandle (pi.hProcess);
987       }
988
989     if (!windowed)
990       enable_child_signals (pi.hProcess);
991
992     ResumeThread (pi.hThread);
993     CloseHandle (pi.hThread);
994
995     return ((int)pi.dwProcessId);
996   }
997 }
998
999 /* 
1000  * This method is called to update status fields of the process
1001  * structure. If the process has not existed, this method is expected
1002  * to do nothing.
1003  *
1004  * The method is called only for real child processes.  
1005  */
1006
1007 static void
1008 nt_update_status_if_terminated (Lisp_Process* p)
1009 {
1010   DWORD exit_code;
1011   if (GetExitCodeProcess (NT_DATA(p)->h_process, &exit_code)
1012       && exit_code != STILL_ACTIVE)
1013     {
1014       p->tick++;
1015       p->core_dumped = 0;
1016       /* The exit code can be a code returned by process, or an
1017          NTSTATUS value. We cannot accurately handle the latter since
1018          it is a full 32 bit integer */
1019       if (exit_code & 0xC0000000)
1020         {
1021           p->status_symbol = Qsignal;
1022           p->exit_code = exit_code & 0x1FFFFFFF;
1023         }
1024       else
1025         {
1026           p->status_symbol = Qexit;
1027           p->exit_code = exit_code;
1028         }
1029     }
1030 }
1031
1032 /*
1033  * Stuff the entire contents of LSTREAM to the process output pipe
1034  */
1035
1036 /* #### If only this function could be somehow merged with
1037    unix_send_process... */
1038
1039 static void
1040 nt_send_process (Lisp_Object proc, struct lstream* lstream)
1041 {
1042   volatile Lisp_Object vol_proc = proc;
1043   Lisp_Process *volatile p = XPROCESS (proc);
1044
1045   /* use a reasonable-sized buffer (somewhere around the size of the
1046      stream buffer) so as to avoid inundating the stream with blocked
1047      data. */
1048   Bufbyte chunkbuf[512];
1049   Bytecount chunklen;
1050
1051   while (1)
1052     {
1053       Lstream_data_count writeret;
1054
1055       chunklen = Lstream_read (lstream, chunkbuf, 512);
1056       if (chunklen <= 0)
1057         break; /* perhaps should ABORT() if < 0?
1058                   This should never happen. */
1059
1060       /* Lstream_write() will never successfully write less than the
1061          amount sent in.  In the worst case, it just buffers the
1062          unwritten data. */
1063       writeret = Lstream_write (XLSTREAM (DATA_OUTSTREAM(p)), chunkbuf,
1064                                 chunklen);
1065       Lstream_flush (XLSTREAM (DATA_OUTSTREAM(p)));
1066       if (writeret < 0)
1067         {
1068           p->status_symbol = Qexit;
1069           p->exit_code = ERROR_BROKEN_PIPE;
1070           p->core_dumped = 0;
1071           p->tick++;
1072           process_tick++;
1073           deactivate_process (*((Lisp_Object *) (&vol_proc)));
1074           invalid_operation ("Broken pipe error sending to process; closed it",
1075                              p->name);
1076         }
1077
1078       {
1079         int wait_ms = 25;
1080         while (Lstream_was_blocked_p (XLSTREAM (p->pipe_outstream)))
1081           {
1082             /* Buffer is full.  Wait, accepting input; that may allow
1083                the program to finish doing output and read more.  */
1084             Faccept_process_output (Qnil, Qzero, make_int (wait_ms));
1085             Lstream_flush (XLSTREAM (p->pipe_outstream));
1086             wait_ms = min (1000, 2 * wait_ms);
1087           }
1088       }
1089     }
1090 }
1091
1092 /*
1093  * Send a signal number SIGNO to PROCESS.
1094  * CURRENT_GROUP means send to the process group that currently owns
1095  * the terminal being used to communicate with PROCESS.
1096  * This is used for various commands in shell mode.
1097  * If NOMSG is zero, insert signal-announcements into process's buffers
1098  * right away.
1099  *
1100  * If we can, we try to signal PROCESS by sending control characters
1101  * down the pty.  This allows us to signal inferiors who have changed
1102  * their uid, for which killpg would return an EPERM error.
1103  *
1104  * The method signals an error if the given SIGNO is not valid
1105  */
1106
1107 static void
1108 nt_kill_child_process (Lisp_Object proc, int signo,
1109                        int current_group, int nomsg)
1110 {
1111   Lisp_Process *p = XPROCESS (proc);
1112
1113   /* Signal error if SIGNO cannot be sent */
1114   validate_signal_number (signo);
1115
1116   /* Send signal */
1117   if (!send_signal (NT_DATA (p), 0, signo))
1118     invalid_operation ("Cannot send signal to process", proc);
1119 }
1120
1121 /*
1122  * Kill any process in the system given its PID
1123  *
1124  * Returns zero if a signal successfully sent, or
1125  * negative number upon failure
1126  */
1127 static int
1128 nt_kill_process_by_pid (int pid, int signo)
1129 {
1130   struct Lisp_Process *p;
1131
1132   /* Signal error if SIGNO cannot be sent */
1133   validate_signal_number (signo);
1134
1135   p = find_process_from_pid (pid);
1136   return send_signal (p ? NT_DATA (p) : 0, pid, signo) ? 0 : -1;
1137 }
1138 \f
1139 /*-----------------------------------------------------------------------*/
1140 /* Sockets connections                                                   */
1141 /*-----------------------------------------------------------------------*/
1142 #ifdef HAVE_SOCKETS
1143
1144 /* #### Hey MS, how long Winsock 2 for '95 will be in beta? */
1145
1146 #define SOCK_TIMER_ID 666
1147 #define XM_SOCKREPLY (WM_USER + 666)
1148
1149 static int
1150 get_internet_address (Lisp_Object host, struct sockaddr_in *address,
1151                       Error_behavior errb)
1152 {
1153   char buf [MAXGETHOSTSTRUCT];
1154   HWND hwnd;
1155   HANDLE hasync;
1156   int success = 0;
1157
1158   address->sin_family = AF_INET;
1159
1160   /* First check if HOST is already a numeric address */
1161   {
1162     unsigned long inaddr = inet_addr (XSTRING_DATA (host));
1163     if (inaddr != INADDR_NONE)
1164       {
1165         address->sin_addr.s_addr = inaddr;
1166         return 1;
1167       }
1168   }
1169
1170   /* Create a window which will receive completion messages */
1171   hwnd = CreateWindow ("STATIC", NULL, WS_OVERLAPPED, 0, 0, 1, 1,
1172                        NULL, NULL, NULL, NULL);
1173   assert (hwnd);
1174
1175   /* Post name resolution request */
1176   hasync = WSAAsyncGetHostByName (hwnd, XM_SOCKREPLY, XSTRING_DATA (host),
1177                                   buf, sizeof (buf));
1178   if (hasync == NULL)
1179     goto done;
1180
1181   /* Set a timer to poll for quit every 250 ms */
1182   SetTimer (hwnd, SOCK_TIMER_ID, 250, NULL);
1183
1184   while (1)
1185     {
1186       MSG msg;
1187       GetMessage (&msg, hwnd, 0, 0);
1188       if (msg.message == XM_SOCKREPLY)
1189         {
1190           /* Ok, got an answer */
1191           if (WSAGETASYNCERROR(msg.lParam) == NO_ERROR)
1192             success = 1;
1193           else
1194             {
1195               warn_when_safe(Qstream, Qwarning,
1196                              "cannot get IP address for host \"%s\"",
1197                              XSTRING_DATA (host));
1198             }
1199           goto done;
1200         }
1201       else if (msg.message == WM_TIMER && msg.wParam == SOCK_TIMER_ID)
1202         {
1203           if (QUITP)
1204             {
1205               WSACancelAsyncRequest (hasync);
1206               KillTimer (hwnd, SOCK_TIMER_ID);
1207               DestroyWindow (hwnd);
1208               REALLY_QUIT;
1209             }
1210         }
1211       DispatchMessage (&msg);
1212     }
1213
1214  done:
1215   KillTimer (hwnd, SOCK_TIMER_ID);
1216   DestroyWindow (hwnd);
1217   if (success)
1218     {
1219       /* BUF starts with struct hostent */
1220       struct hostent* he = (struct hostent*) buf;
1221       address->sin_addr.s_addr = *(unsigned long*)he->h_addr_list[0];
1222     }
1223   return success;
1224 }
1225
1226 static Lisp_Object
1227 nt_canonicalize_host_name (Lisp_Object host)
1228 {
1229   struct sockaddr_in address;
1230
1231   if (!get_internet_address (host, &address, ERROR_ME_NOT))
1232     return host;
1233
1234   if (address.sin_family == AF_INET)
1235     return build_string (inet_ntoa (address.sin_addr));
1236   else
1237     return host;
1238 }
1239
1240 /* open a TCP network connection to a given HOST/SERVICE.  Treated
1241    exactly like a normal process when reading and writing.  Only
1242    differences are in status display and process deletion.  A network
1243    connection has no PID; you cannot signal it.  All you can do is
1244    deactivate and close it via delete-process */
1245
1246 static void
1247 nt_open_network_stream (Lisp_Object name, Lisp_Object host,
1248                         Lisp_Object service,
1249                         Lisp_Object protocol, void** vinfd, void** voutfd)
1250 {
1251   /* !!#### not Mule-ized */
1252   struct sockaddr_in address;
1253   SOCKET s;
1254   int port;
1255   int retval;
1256
1257   CHECK_STRING (host);
1258
1259   if (!EQ (protocol, Qtcp))
1260     invalid_argument ("Unsupported protocol", protocol);
1261
1262   if (INTP (service))
1263     port = htons ((unsigned short) XINT (service));
1264   else
1265     {
1266       struct servent *svc_info;
1267       CHECK_STRING (service);
1268       svc_info = getservbyname ((char *) XSTRING_DATA (service), "tcp");
1269       if (svc_info == 0)
1270         invalid_argument ("Unknown service", service);
1271       port = svc_info->s_port;
1272     }
1273
1274   get_internet_address (host, &address, ERROR_ME);
1275   address.sin_port = port;
1276
1277   s = socket (address.sin_family, SOCK_STREAM, 0);
1278   if (s < 0)
1279     report_file_error ("error creating socket", list1 (name));
1280
1281   /* We don't want to be blocked on connect */
1282   {
1283     unsigned long nonblock = 1;
1284     ioctlsocket (s, FIONBIO, &nonblock);
1285   }
1286   
1287   retval = connect (s, (struct sockaddr *) &address, sizeof (address));
1288   if (retval != NO_ERROR && WSAGetLastError() != WSAEWOULDBLOCK)
1289     goto connect_failed;
1290   /* Wait while connection is established */
1291   while (1)
1292     {
1293       fd_set fdset;
1294       struct timeval tv;
1295       int nsel;
1296
1297       if (QUITP)
1298         {
1299           closesocket (s);
1300           REALLY_QUIT;
1301         }
1302
1303       /* Poll for quit every 250 ms */
1304       tv.tv_sec = 0;
1305       tv.tv_usec = 250 * 1000;
1306
1307       FD_ZERO (&fdset);
1308       FD_SET (s, &fdset);
1309       nsel = select (0, NULL, &fdset, &fdset, &tv);
1310
1311       if (nsel > 0)
1312         {
1313           /* Check: was connection successful or not? */
1314           tv.tv_usec = 0;
1315           nsel = select (0, NULL, NULL, &fdset, &tv);
1316           if (nsel > 0)
1317             goto connect_failed;
1318           else
1319             break;
1320         }
1321     }
1322
1323   /* We are connected at this point */
1324   *vinfd = (void*)s;
1325   DuplicateHandle (GetCurrentProcess(), (HANDLE)s,
1326                    GetCurrentProcess(), (LPHANDLE)voutfd,
1327                    0, FALSE, DUPLICATE_SAME_ACCESS);
1328   return;
1329
1330  connect_failed:  
1331   closesocket (s);
1332   if (INTP (service))
1333     {
1334       warn_when_safe (Qstream, Qwarning,
1335                       "failure to open network stream to host \"%s\" for service \"%d\"",
1336                       XSTRING_DATA (host),
1337                       (unsigned short) XINT (service));
1338     }
1339   else
1340     {
1341       warn_when_safe (Qstream, Qwarning,
1342                       "failure to open network stream to host \"%s\" for service \"%s\"",
1343                       XSTRING_DATA (host),
1344                       XSTRING_DATA (service));
1345     }
1346   report_file_error ("connection failed", list2 (host, name));
1347 }
1348
1349 #endif
1350 \f
1351 /*-----------------------------------------------------------------------*/
1352 /* Initialization                                                        */
1353 /*-----------------------------------------------------------------------*/
1354
1355 void
1356 process_type_create_nt (void)
1357 {
1358   PROCESS_HAS_METHOD (nt, alloc_process_data);
1359   PROCESS_HAS_METHOD (nt, finalize_process_data);
1360   PROCESS_HAS_METHOD (nt, init_process);
1361   PROCESS_HAS_METHOD (nt, create_process);
1362   PROCESS_HAS_METHOD (nt, update_status_if_terminated);
1363   PROCESS_HAS_METHOD (nt, send_process);
1364   PROCESS_HAS_METHOD (nt, kill_child_process);
1365   PROCESS_HAS_METHOD (nt, kill_process_by_pid);
1366 #ifdef HAVE_SOCKETS
1367   PROCESS_HAS_METHOD (nt, canonicalize_host_name);
1368   PROCESS_HAS_METHOD (nt, open_network_stream);
1369 #ifdef HAVE_MULTICAST
1370 #error I won't do this until '95 has winsock2
1371   PROCESS_HAS_METHOD (nt, open_multicast_group);
1372 #endif
1373 #endif
1374 }
1375
1376 void
1377 syms_of_process_nt (void)
1378 {
1379   DEFSYMBOL (Qmswindows_construct_process_command_line);
1380 }
1381
1382 void
1383 vars_of_process_nt (void)
1384 {
1385   DEFVAR_LISP ("mswindows-start-process-share-console",
1386                &Vmswindows_start_process_share_console /*
1387 When nil, new child processes are given a new console.
1388 When non-nil, they share the Emacs console; this has the limitation of
1389 allowing only one DOS subprocess to run at a time (whether started directly
1390 or indirectly by Emacs), and preventing Emacs from cleanly terminating the
1391 subprocess group, but may allow Emacs to interrupt a subprocess that doesn't
1392 otherwise respond to interrupts from Emacs.
1393 */ );
1394   Vmswindows_start_process_share_console = Qnil;
1395
1396   DEFVAR_LISP ("mswindows-start-process-inherit-error-mode",
1397                &Vmswindows_start_process_inherit_error_mode /*
1398     "When nil, new child processes revert to the default error mode.
1399 When non-nil, they inherit their error mode setting from Emacs, which stops
1400 them blocking when trying to access unmounted drives etc.
1401 */ );
1402   Vmswindows_start_process_inherit_error_mode = Qt;
1403 }