Mercurial > emacs
comparison src/w32proc.c @ 38022:71e8b6ae114f
(create_child): Add new parameter is_gui_app.
(w32_executable_type): Add new parameter is_gui_app.
(sys_spawnve): Use it.
(sys_kill): Fake ^C for SIGINT, and ^Break (if possible) for
SIGQUIT. This matches better how the signals are interpreted by
MSVC compiled programs.
(syms_of_ntproc): Update docstring.
author | Andrew Innes <andrewi@gnu.org> |
---|---|
date | Mon, 11 Jun 2001 11:00:03 +0000 |
parents | d0b43907dca5 |
children | 66e0816837a8 |
comparison
equal
deleted
inserted
replaced
38021:41f655ec596a | 38022:71e8b6ae114f |
---|---|
302 the new process should start in. This is set just before calling | 302 the new process should start in. This is set just before calling |
303 sys_spawnve, and is not generally valid at any other time. */ | 303 sys_spawnve, and is not generally valid at any other time. */ |
304 static char * process_dir; | 304 static char * process_dir; |
305 | 305 |
306 static BOOL | 306 static BOOL |
307 create_child (char *exe, char *cmdline, char *env, | 307 create_child (char *exe, char *cmdline, char *env, int is_gui_app, |
308 int * pPid, child_process *cp) | 308 int * pPid, child_process *cp) |
309 { | 309 { |
310 STARTUPINFO start; | 310 STARTUPINFO start; |
311 SECURITY_ATTRIBUTES sec_attrs; | 311 SECURITY_ATTRIBUTES sec_attrs; |
312 #if 0 | 312 #if 0 |
319 | 319 |
320 memset (&start, 0, sizeof (start)); | 320 memset (&start, 0, sizeof (start)); |
321 start.cb = sizeof (start); | 321 start.cb = sizeof (start); |
322 | 322 |
323 #ifdef HAVE_NTGUI | 323 #ifdef HAVE_NTGUI |
324 if (NILP (Vw32_start_process_show_window)) | 324 if (NILP (Vw32_start_process_show_window) && !is_gui_app) |
325 start.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW; | 325 start.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW; |
326 else | 326 else |
327 start.dwFlags = STARTF_USESTDHANDLES; | 327 start.dwFlags = STARTF_USESTDHANDLES; |
328 start.wShowWindow = SW_HIDE; | 328 start.wShowWindow = SW_HIDE; |
329 | 329 |
569 | 569 |
570 return pid; | 570 return pid; |
571 } | 571 } |
572 | 572 |
573 void | 573 void |
574 w32_executable_type (char * filename, int * is_dos_app, int * is_cygnus_app) | 574 w32_executable_type (char * filename, int * is_dos_app, int * is_cygnus_app, int * is_gui_app) |
575 { | 575 { |
576 file_data executable; | 576 file_data executable; |
577 char * p; | 577 char * p; |
578 | 578 |
579 /* Default values in case we can't tell for sure. */ | 579 /* Default values in case we can't tell for sure. */ |
580 *is_dos_app = FALSE; | 580 *is_dos_app = FALSE; |
581 *is_cygnus_app = FALSE; | 581 *is_cygnus_app = FALSE; |
582 *is_gui_app = FALSE; | |
582 | 583 |
583 if (!open_input_file (&executable, filename)) | 584 if (!open_input_file (&executable, filename)) |
584 return; | 585 return; |
585 | 586 |
586 p = strrchr (filename, '.'); | 587 p = strrchr (filename, '.'); |
597 Therefore, we have to do the same here as well. */ | 598 Therefore, we have to do the same here as well. */ |
598 /* Actually, I think it uses the program association for that | 599 /* Actually, I think it uses the program association for that |
599 extension, which is defined in the registry. */ | 600 extension, which is defined in the registry. */ |
600 p = egetenv ("COMSPEC"); | 601 p = egetenv ("COMSPEC"); |
601 if (p) | 602 if (p) |
602 w32_executable_type (p, is_dos_app, is_cygnus_app); | 603 w32_executable_type (p, is_dos_app, is_cygnus_app, is_gui_app); |
603 } | 604 } |
604 else | 605 else |
605 { | 606 { |
606 /* Look for DOS .exe signature - if found, we must also check that | 607 /* Look for DOS .exe signature - if found, we must also check that |
607 it isn't really a 16- or 32-bit Windows exe, since both formats | 608 it isn't really a 16- or 32-bit Windows exe, since both formats |
649 { | 650 { |
650 *is_cygnus_app = TRUE; | 651 *is_cygnus_app = TRUE; |
651 break; | 652 break; |
652 } | 653 } |
653 } | 654 } |
655 | |
656 /* Check whether app is marked as a console or windowed (aka | |
657 GUI) app. Accept Posix and OS2 subsytem apps as console | |
658 apps. */ | |
659 *is_gui_app = (nt_header->OptionalHeader.Subsystem == IMAGE_SUBSYSTEM_WINDOWS_GUI); | |
654 } | 660 } |
655 } | 661 } |
656 | 662 |
657 unwind: | 663 unwind: |
658 close_file_data (&executable); | 664 close_file_data (&executable); |
712 Lisp_Object program, full; | 718 Lisp_Object program, full; |
713 char *cmdline, *env, *parg, **targ; | 719 char *cmdline, *env, *parg, **targ; |
714 int arglen, numenv; | 720 int arglen, numenv; |
715 int pid; | 721 int pid; |
716 child_process *cp; | 722 child_process *cp; |
717 int is_dos_app, is_cygnus_app; | 723 int is_dos_app, is_cygnus_app, is_gui_app; |
718 int do_quoting = 0; | 724 int do_quoting = 0; |
719 char escape_char; | 725 char escape_char; |
720 /* We pass our process ID to our children by setting up an environment | 726 /* We pass our process ID to our children by setting up an environment |
721 variable in their environment. */ | 727 variable in their environment. */ |
722 char ppid_env_var_buffer[64]; | 728 char ppid_env_var_buffer[64]; |
755 | 761 |
756 /* Determine whether program is a 16-bit DOS executable, or a w32 | 762 /* Determine whether program is a 16-bit DOS executable, or a w32 |
757 executable that is implicitly linked to the Cygnus dll (implying it | 763 executable that is implicitly linked to the Cygnus dll (implying it |
758 was compiled with the Cygnus GNU toolchain and hence relies on | 764 was compiled with the Cygnus GNU toolchain and hence relies on |
759 cygwin.dll to parse the command line - we use this to decide how to | 765 cygwin.dll to parse the command line - we use this to decide how to |
760 escape quote chars in command line args that must be quoted). */ | 766 escape quote chars in command line args that must be quoted). |
761 w32_executable_type (cmdname, &is_dos_app, &is_cygnus_app); | 767 |
768 Also determine whether it is a GUI app, so that we don't hide its | |
769 initial window unless specifically requested. */ | |
770 w32_executable_type (cmdname, &is_dos_app, &is_cygnus_app, &is_gui_app); | |
762 | 771 |
763 /* On Windows 95, if cmdname is a DOS app, we invoke a helper | 772 /* On Windows 95, if cmdname is a DOS app, we invoke a helper |
764 application to start it by specifying the helper app as cmdname, | 773 application to start it by specifying the helper app as cmdname, |
765 while leaving the real app name as argv[0]. */ | 774 while leaving the real app name as argv[0]. */ |
766 if (is_dos_app) | 775 if (is_dos_app) |
990 errno = EAGAIN; | 999 errno = EAGAIN; |
991 return -1; | 1000 return -1; |
992 } | 1001 } |
993 | 1002 |
994 /* Now create the process. */ | 1003 /* Now create the process. */ |
995 if (!create_child (cmdname, cmdline, env, &pid, cp)) | 1004 if (!create_child (cmdname, cmdline, env, is_gui_app, &pid, cp)) |
996 { | 1005 { |
997 delete_child (cp); | 1006 delete_child (cp); |
998 errno = ENOEXEC; | 1007 errno = ENOEXEC; |
999 return -1; | 1008 return -1; |
1000 } | 1009 } |
1381 | 1390 |
1382 /* Try to locate console window for process. */ | 1391 /* Try to locate console window for process. */ |
1383 EnumWindows (find_child_console, (LPARAM) cp); | 1392 EnumWindows (find_child_console, (LPARAM) cp); |
1384 } | 1393 } |
1385 | 1394 |
1386 if (sig == SIGINT) | 1395 if (sig == SIGINT || sig == SIGQUIT) |
1387 { | 1396 { |
1388 if (NILP (Vw32_start_process_share_console) && cp && cp->hwnd) | 1397 if (NILP (Vw32_start_process_share_console) && cp && cp->hwnd) |
1389 { | 1398 { |
1390 BYTE control_scan_code = (BYTE) MapVirtualKey (VK_CONTROL, 0); | 1399 BYTE control_scan_code = (BYTE) MapVirtualKey (VK_CONTROL, 0); |
1391 BYTE vk_break_code = VK_CANCEL; | 1400 /* Fake Ctrl-C for SIGINT, and Ctrl-Break for SIGQUIT. */ |
1401 BYTE vk_break_code = (sig == SIGINT) ? 'C' : VK_CANCEL; | |
1392 BYTE break_scan_code = (BYTE) MapVirtualKey (vk_break_code, 0); | 1402 BYTE break_scan_code = (BYTE) MapVirtualKey (vk_break_code, 0); |
1393 HWND foreground_window; | 1403 HWND foreground_window; |
1394 | 1404 |
1395 if (break_scan_code == 0) | 1405 if (break_scan_code == 0) |
1396 { | 1406 { |
1397 /* Fake Ctrl-C if we can't manage Ctrl-Break. */ | 1407 /* Fake Ctrl-C for SIGQUIT if we can't manage Ctrl-Break. */ |
1398 vk_break_code = 'C'; | 1408 vk_break_code = 'C'; |
1399 break_scan_code = (BYTE) MapVirtualKey (vk_break_code, 0); | 1409 break_scan_code = (BYTE) MapVirtualKey (vk_break_code, 0); |
1400 } | 1410 } |
1401 | 1411 |
1402 foreground_window = GetForegroundWindow (); | 1412 foreground_window = GetForegroundWindow (); |
2152 Vw32_quote_process_args = Qt; | 2162 Vw32_quote_process_args = Qt; |
2153 | 2163 |
2154 DEFVAR_LISP ("w32-start-process-show-window", | 2164 DEFVAR_LISP ("w32-start-process-show-window", |
2155 &Vw32_start_process_show_window, | 2165 &Vw32_start_process_show_window, |
2156 "When nil, new child processes hide their windows.\n\ | 2166 "When nil, new child processes hide their windows.\n\ |
2157 When non-nil, they show their window in the method of their choice."); | 2167 When non-nil, they show their window in the method of their choice.\n\ |
2168 This variable doesn't affect GUI applications, which will never be hidden."); | |
2158 Vw32_start_process_show_window = Qnil; | 2169 Vw32_start_process_show_window = Qnil; |
2159 | 2170 |
2160 DEFVAR_LISP ("w32-start-process-share-console", | 2171 DEFVAR_LISP ("w32-start-process-share-console", |
2161 &Vw32_start_process_share_console, | 2172 &Vw32_start_process_share_console, |
2162 "When nil, new child processes are given a new console.\n\ | 2173 "When nil, new child processes are given a new console.\n\ |