diff options
| author | Richard M. Stallman | 1994-11-01 06:49:52 +0000 |
|---|---|---|
| committer | Richard M. Stallman | 1994-11-01 06:49:52 +0000 |
| commit | bad95d8f8d11090f3d3e05709f06d1ef2d7dd288 (patch) | |
| tree | 16c9fc8ae966c061c9628169043944254e21cf04 /src/callproc.c | |
| parent | f7975d0711438a8260199720072a3b8f0ad85325 (diff) | |
| download | emacs-bad95d8f8d11090f3d3e05709f06d1ef2d7dd288.tar.gz emacs-bad95d8f8d11090f3d3e05709f06d1ef2d7dd288.zip | |
(getenv_internal) [WINDOWSNT]: Use strnicmp, not bcmp.
(child_setup): Use IS_DIRECTORY_SEP.
[WINDOWSNT]: Call prepare_standard_handles. Use spawnve.
Use reset_standard_handles.
(Fcall_process_region): Test DOS_NT, not MSDOS.
(Fcall_process) [WINDOWSNT]: Call pipe_with_inherited_out.
Use the return value of child_setup to get the child's pid;
don't call vfork etc. explicitly.
[WINDOWSNT]: Add includes. Defone NOMINMAX, _P_NOWAIT.
(Vbinary_process_input, Vbinary_process_output)
(Qbuffer_file_type): Test DOS_NT, not MSDOS.
(syms_of_callproc): Test DOS_NT, not MSDOS.
(init_callproc): Test DOS_NT, not MSDOS.
Diffstat (limited to 'src/callproc.c')
| -rw-r--r-- | src/callproc.c | 75 |
1 files changed, 57 insertions, 18 deletions
diff --git a/src/callproc.c b/src/callproc.c index 4f1c3913469..04c390a6067 100644 --- a/src/callproc.c +++ b/src/callproc.c | |||
| @@ -41,6 +41,15 @@ extern char *strerror (); | |||
| 41 | #include <fcntl.h> | 41 | #include <fcntl.h> |
| 42 | #endif | 42 | #endif |
| 43 | 43 | ||
| 44 | #ifdef WINDOWSNT | ||
| 45 | #define NOMINMAX | ||
| 46 | #include <windows.h> | ||
| 47 | #include <stdlib.h> /* for proper declaration of environ */ | ||
| 48 | #include <fcntl.h> | ||
| 49 | #include "nt.h" | ||
| 50 | #define _P_NOWAIT 1 /* from process.h */ | ||
| 51 | #endif | ||
| 52 | |||
| 44 | #ifdef MSDOS /* Demacs 1.1.1 91/10/16 HIRANO Satoshi */ | 53 | #ifdef MSDOS /* Demacs 1.1.1 91/10/16 HIRANO Satoshi */ |
| 45 | #include "msdos.h" | 54 | #include "msdos.h" |
| 46 | #define INCLUDED_FCNTL | 55 | #define INCLUDED_FCNTL |
| @@ -74,14 +83,14 @@ extern char **environ; | |||
| 74 | 83 | ||
| 75 | #define max(a, b) ((a) > (b) ? (a) : (b)) | 84 | #define max(a, b) ((a) > (b) ? (a) : (b)) |
| 76 | 85 | ||
| 77 | #ifdef MSDOS | 86 | #ifdef DOS_NT |
| 78 | /* When we are starting external processes we need to know whether they | 87 | /* When we are starting external processes we need to know whether they |
| 79 | take binary input (no conversion) or text input (\n is converted to | 88 | take binary input (no conversion) or text input (\n is converted to |
| 80 | \r\n). Similar for output: if newlines are written as \r\n then it's | 89 | \r\n). Similar for output: if newlines are written as \r\n then it's |
| 81 | text process output, otherwise it's binary. */ | 90 | text process output, otherwise it's binary. */ |
| 82 | Lisp_Object Vbinary_process_input; | 91 | Lisp_Object Vbinary_process_input; |
| 83 | Lisp_Object Vbinary_process_output; | 92 | Lisp_Object Vbinary_process_output; |
| 84 | #endif | 93 | #endif /* DOS_NT */ |
| 85 | 94 | ||
| 86 | Lisp_Object Vexec_path, Vexec_directory, Vdata_directory, Vdoc_directory; | 95 | Lisp_Object Vexec_path, Vexec_directory, Vdata_directory, Vdoc_directory; |
| 87 | Lisp_Object Vconfigure_info_directory; | 96 | Lisp_Object Vconfigure_info_directory; |
| @@ -90,9 +99,9 @@ Lisp_Object Vshell_file_name; | |||
| 90 | 99 | ||
| 91 | Lisp_Object Vprocess_environment; | 100 | Lisp_Object Vprocess_environment; |
| 92 | 101 | ||
| 93 | #ifdef MSDOS | 102 | #ifdef DOS_NT |
| 94 | Lisp_Object Qbuffer_file_type; | 103 | Lisp_Object Qbuffer_file_type; |
| 95 | #endif | 104 | #endif /* DOS_NT */ |
| 96 | 105 | ||
| 97 | /* True iff we are about to fork off a synchronous process or if we | 106 | /* True iff we are about to fork off a synchronous process or if we |
| 98 | are waiting for it. */ | 107 | are waiting for it. */ |
| @@ -319,7 +328,11 @@ If you quit, the process is killed with SIGINT, or SIGKILL if you quit again.") | |||
| 319 | else | 328 | else |
| 320 | { | 329 | { |
| 321 | #ifndef MSDOS | 330 | #ifndef MSDOS |
| 331 | #ifdef WINDOWSNT | ||
| 332 | pipe_with_inherited_out (fd); | ||
| 333 | #else /* not WINDOWSNT */ | ||
| 322 | pipe (fd); | 334 | pipe (fd); |
| 335 | #endif /* not WINDOWSNT */ | ||
| 323 | #endif | 336 | #endif |
| 324 | #if 0 | 337 | #if 0 |
| 325 | /* Replaced by close_process_descs */ | 338 | /* Replaced by close_process_descs */ |
| @@ -360,6 +373,9 @@ If you quit, the process is killed with SIGINT, or SIGKILL if you quit again.") | |||
| 360 | report_file_error ("Cannot re-open temporary file", Qnil); | 373 | report_file_error ("Cannot re-open temporary file", Qnil); |
| 361 | } | 374 | } |
| 362 | #else /* not MSDOS */ | 375 | #else /* not MSDOS */ |
| 376 | #ifdef WINDOWSNT | ||
| 377 | pid = child_setup (filefd, fd1, fd1, new_argv, 0, current_dir); | ||
| 378 | #else /* not WINDOWSNT */ | ||
| 363 | pid = vfork (); | 379 | pid = vfork (); |
| 364 | 380 | ||
| 365 | if (pid == 0) | 381 | if (pid == 0) |
| @@ -374,6 +390,7 @@ If you quit, the process is killed with SIGINT, or SIGKILL if you quit again.") | |||
| 374 | child_setup (filefd, fd1, fd1, new_argv, 0, current_dir); | 390 | child_setup (filefd, fd1, fd1, new_argv, 0, current_dir); |
| 375 | } | 391 | } |
| 376 | #endif /* not MSDOS */ | 392 | #endif /* not MSDOS */ |
| 393 | #endif /* not WINDOWSNT */ | ||
| 377 | 394 | ||
| 378 | environ = save_environ; | 395 | environ = save_environ; |
| 379 | 396 | ||
| @@ -499,13 +516,13 @@ If you quit, the process is killed with SIGINT, or SIGKILL if you quit again.") | |||
| 499 | struct gcpro gcpro1; | 516 | struct gcpro gcpro1; |
| 500 | Lisp_Object filename_string; | 517 | Lisp_Object filename_string; |
| 501 | register Lisp_Object start, end; | 518 | register Lisp_Object start, end; |
| 502 | #ifdef MSDOS | 519 | #ifdef DOS_NT |
| 503 | char *tempfile; | 520 | char *tempfile; |
| 504 | #else | 521 | #else |
| 505 | char tempfile[20]; | 522 | char tempfile[20]; |
| 506 | #endif | 523 | #endif |
| 507 | int count = specpdl_ptr - specpdl; | 524 | int count = specpdl_ptr - specpdl; |
| 508 | #ifdef MSDOS | 525 | #ifdef DOS_NT |
| 509 | char *outf = '\0'; | 526 | char *outf = '\0'; |
| 510 | 527 | ||
| 511 | if ((outf = egetenv ("TMP")) || (outf = egetenv ("TEMP"))) | 528 | if ((outf = egetenv ("TMP")) || (outf = egetenv ("TEMP"))) |
| @@ -519,14 +536,14 @@ If you quit, the process is killed with SIGINT, or SIGKILL if you quit again.") | |||
| 519 | if (tempfile[strlen (tempfile) - 1] != '/') | 536 | if (tempfile[strlen (tempfile) - 1] != '/') |
| 520 | strcat (tempfile, "/"); | 537 | strcat (tempfile, "/"); |
| 521 | strcat (tempfile, "detmp.XXX"); | 538 | strcat (tempfile, "detmp.XXX"); |
| 522 | #else /* not MSDOS */ | 539 | #else /* not DOS_NT */ |
| 523 | 540 | ||
| 524 | #ifdef VMS | 541 | #ifdef VMS |
| 525 | strcpy (tempfile, "tmp:emacsXXXXXX."); | 542 | strcpy (tempfile, "tmp:emacsXXXXXX."); |
| 526 | #else | 543 | #else |
| 527 | strcpy (tempfile, "/tmp/emacsXXXXXX"); | 544 | strcpy (tempfile, "/tmp/emacsXXXXXX"); |
| 528 | #endif | 545 | #endif |
| 529 | #endif /* not MSDOS */ | 546 | #endif /* not DOS_NT */ |
| 530 | 547 | ||
| 531 | mktemp (tempfile); | 548 | mktemp (tempfile); |
| 532 | 549 | ||
| @@ -534,13 +551,13 @@ If you quit, the process is killed with SIGINT, or SIGKILL if you quit again.") | |||
| 534 | GCPRO1 (filename_string); | 551 | GCPRO1 (filename_string); |
| 535 | start = args[0]; | 552 | start = args[0]; |
| 536 | end = args[1]; | 553 | end = args[1]; |
| 537 | #ifdef MSDOS | 554 | #ifdef DOS_NT |
| 538 | specbind (Qbuffer_file_type, Vbinary_process_input); | 555 | specbind (Qbuffer_file_type, Vbinary_process_input); |
| 539 | Fwrite_region (start, end, filename_string, Qnil, Qlambda); | 556 | Fwrite_region (start, end, filename_string, Qnil, Qlambda); |
| 540 | unbind_to (count, Qnil); | 557 | unbind_to (count, Qnil); |
| 541 | #else | 558 | #else /* not DOS_NT */ |
| 542 | Fwrite_region (start, end, filename_string, Qnil, Qlambda); | 559 | Fwrite_region (start, end, filename_string, Qnil, Qlambda); |
| 543 | #endif | 560 | #endif /* not DOS_NT */ |
| 544 | 561 | ||
| 545 | record_unwind_protect (delete_temp_file, filename_string); | 562 | record_unwind_protect (delete_temp_file, filename_string); |
| 546 | 563 | ||
| @@ -586,6 +603,10 @@ child_setup (in, out, err, new_argv, set_pgrp, current_dir) | |||
| 586 | #else /* not MSDOS */ | 603 | #else /* not MSDOS */ |
| 587 | char **env; | 604 | char **env; |
| 588 | char *pwd_var; | 605 | char *pwd_var; |
| 606 | #ifdef WINDOWSNT | ||
| 607 | int cpid; | ||
| 608 | HANDLE handles[4]; | ||
| 609 | #endif /* WINDOWSNT */ | ||
| 589 | 610 | ||
| 590 | int pid = getpid (); | 611 | int pid = getpid (); |
| 591 | 612 | ||
| @@ -618,7 +639,7 @@ child_setup (in, out, err, new_argv, set_pgrp, current_dir) | |||
| 618 | temp = pwd_var + 4; | 639 | temp = pwd_var + 4; |
| 619 | bcopy ("PWD=", pwd_var, 4); | 640 | bcopy ("PWD=", pwd_var, 4); |
| 620 | bcopy (XSTRING (current_dir)->data, temp, i); | 641 | bcopy (XSTRING (current_dir)->data, temp, i); |
| 621 | if (temp[i - 1] != '/') temp[i++] = '/'; | 642 | if (!IS_DIRECTORY_SEP (temp[i - 1])) temp[i++] = DIRECTORY_SEP; |
| 622 | temp[i] = 0; | 643 | temp[i] = 0; |
| 623 | 644 | ||
| 624 | /* We can't signal an Elisp error here; we're in a vfork. Since | 645 | /* We can't signal an Elisp error here; we're in a vfork. Since |
| @@ -630,7 +651,7 @@ child_setup (in, out, err, new_argv, set_pgrp, current_dir) | |||
| 630 | _exit (errno); | 651 | _exit (errno); |
| 631 | 652 | ||
| 632 | /* Strip trailing slashes for PWD, but leave "/" and "//" alone. */ | 653 | /* Strip trailing slashes for PWD, but leave "/" and "//" alone. */ |
| 633 | while (i > 2 && temp[i - 1] == '/') | 654 | while (i > 2 && IS_DIRECTORY_SEP (temp[i - 1])) |
| 634 | temp[--i] = 0; | 655 | temp[--i] = 0; |
| 635 | } | 656 | } |
| 636 | 657 | ||
| @@ -685,7 +706,9 @@ child_setup (in, out, err, new_argv, set_pgrp, current_dir) | |||
| 685 | } | 706 | } |
| 686 | *new_env = 0; | 707 | *new_env = 0; |
| 687 | } | 708 | } |
| 688 | 709 | #ifdef WINDOWSNT | |
| 710 | prepare_standard_handles (in, out, err, handles); | ||
| 711 | #else /* not WINDOWSNT */ | ||
| 689 | /* Make sure that in, out, and err are not actually already in | 712 | /* Make sure that in, out, and err are not actually already in |
| 690 | descriptors zero, one, or two; this could happen if Emacs is | 713 | descriptors zero, one, or two; this could happen if Emacs is |
| 691 | started with its standard in, out, or error closed, as might | 714 | started with its standard in, out, or error closed, as might |
| @@ -709,6 +732,7 @@ child_setup (in, out, err, new_argv, set_pgrp, current_dir) | |||
| 709 | close (in); | 732 | close (in); |
| 710 | close (out); | 733 | close (out); |
| 711 | close (err); | 734 | close (err); |
| 735 | #endif /* not WINDOWSNT */ | ||
| 712 | 736 | ||
| 713 | #ifdef USG | 737 | #ifdef USG |
| 714 | #ifndef SETPGRP_RELEASES_CTTY | 738 | #ifndef SETPGRP_RELEASES_CTTY |
| @@ -724,6 +748,15 @@ child_setup (in, out, err, new_argv, set_pgrp, current_dir) | |||
| 724 | something missing here; | 748 | something missing here; |
| 725 | #endif /* vipc */ | 749 | #endif /* vipc */ |
| 726 | 750 | ||
| 751 | #ifdef WINDOWSNT | ||
| 752 | /* Spawn the child. (See ntproc.c:Spawnve). */ | ||
| 753 | cpid = spawnve (_P_NOWAIT, new_argv[0], new_argv, env); | ||
| 754 | if (cpid == -1) { ???? | ||
| 755 | report_file_error ("Spawning child process", Qnil); | ||
| 756 | } | ||
| 757 | reset_standard_handles (in, out, err, handles); | ||
| 758 | return cpid; | ||
| 759 | #else /* not WINDOWSNT */ | ||
| 727 | /* execvp does not accept an environment arg so the only way | 760 | /* execvp does not accept an environment arg so the only way |
| 728 | to pass this environment is to set environ. Our caller | 761 | to pass this environment is to set environ. Our caller |
| 729 | is responsible for restoring the ambient value of environ. */ | 762 | is responsible for restoring the ambient value of environ. */ |
| @@ -733,6 +766,7 @@ child_setup (in, out, err, new_argv, set_pgrp, current_dir) | |||
| 733 | write (1, "Couldn't exec the program ", 26); | 766 | write (1, "Couldn't exec the program ", 26); |
| 734 | write (1, new_argv[0], strlen (new_argv[0])); | 767 | write (1, new_argv[0], strlen (new_argv[0])); |
| 735 | _exit (1); | 768 | _exit (1); |
| 769 | #endif /* not WINDOWSNT */ | ||
| 736 | #endif /* not MSDOS */ | 770 | #endif /* not MSDOS */ |
| 737 | } | 771 | } |
| 738 | 772 | ||
| @@ -782,7 +816,12 @@ getenv_internal (var, varlen, value, valuelen) | |||
| 782 | if (STRINGP (entry) | 816 | if (STRINGP (entry) |
| 783 | && XSTRING (entry)->size > varlen | 817 | && XSTRING (entry)->size > varlen |
| 784 | && XSTRING (entry)->data[varlen] == '=' | 818 | && XSTRING (entry)->data[varlen] == '=' |
| 819 | #ifdef WINDOWSNT | ||
| 820 | /* NT environment variables are case insensitive. */ | ||
| 821 | && ! strnicmp (XSTRING (entry)->data, var, varlen)) | ||
| 822 | #else /* not WINDOWSNT */ | ||
| 785 | && ! bcmp (XSTRING (entry)->data, var, varlen)) | 823 | && ! bcmp (XSTRING (entry)->data, var, varlen)) |
| 824 | #endif /* not WINDOWSNT */ | ||
| 786 | { | 825 | { |
| 787 | *value = (char *) XSTRING (entry)->data + (varlen + 1); | 826 | *value = (char *) XSTRING (entry)->data + (varlen + 1); |
| 788 | *valuelen = XSTRING (entry)->size - (varlen + 1); | 827 | *valuelen = XSTRING (entry)->size - (varlen + 1); |
| @@ -866,11 +905,11 @@ init_callproc () | |||
| 866 | Vinstallation_directory); | 905 | Vinstallation_directory); |
| 867 | if (NILP (Fmember (tem, Vexec_path))) | 906 | if (NILP (Fmember (tem, Vexec_path))) |
| 868 | { | 907 | { |
| 869 | #ifndef MSDOS | 908 | #ifndef DOS_NT |
| 870 | /* MSDOS uses wrapped binaries, so don't do this. */ | 909 | /* MSDOS uses wrapped binaries, so don't do this. */ |
| 871 | Vexec_path = nconc2 (Vexec_path, Fcons (tem, Qnil)); | 910 | Vexec_path = nconc2 (Vexec_path, Fcons (tem, Qnil)); |
| 872 | Vexec_directory = Ffile_name_as_directory (tem); | 911 | Vexec_directory = Ffile_name_as_directory (tem); |
| 873 | #endif | 912 | #endif /* not DOS_NT */ |
| 874 | 913 | ||
| 875 | /* If we use ../lib-src, maybe use ../etc as well. | 914 | /* If we use ../lib-src, maybe use ../etc as well. |
| 876 | Do so if ../etc exists and has our DOC-... file in it. */ | 915 | Do so if ../etc exists and has our DOC-... file in it. */ |
| @@ -948,7 +987,7 @@ set_process_environment () | |||
| 948 | 987 | ||
| 949 | syms_of_callproc () | 988 | syms_of_callproc () |
| 950 | { | 989 | { |
| 951 | #ifdef MSDOS | 990 | #ifdef DOS_NT |
| 952 | Qbuffer_file_type = intern ("buffer-file-type"); | 991 | Qbuffer_file_type = intern ("buffer-file-type"); |
| 953 | staticpro (&Qbuffer_file_type); | 992 | staticpro (&Qbuffer_file_type); |
| 954 | 993 | ||
| @@ -959,7 +998,7 @@ syms_of_callproc () | |||
| 959 | DEFVAR_LISP ("binary-process-output", &Vbinary_process_output, | 998 | DEFVAR_LISP ("binary-process-output", &Vbinary_process_output, |
| 960 | "*If non-nil then new subprocesses are assumed to produce binary output."); | 999 | "*If non-nil then new subprocesses are assumed to produce binary output."); |
| 961 | Vbinary_process_output = Qnil; | 1000 | Vbinary_process_output = Qnil; |
| 962 | #endif | 1001 | #endif /* DOS_NT */ |
| 963 | 1002 | ||
| 964 | DEFVAR_LISP ("shell-file-name", &Vshell_file_name, | 1003 | DEFVAR_LISP ("shell-file-name", &Vshell_file_name, |
| 965 | "*File name to load inferior shells from.\n\ | 1004 | "*File name to load inferior shells from.\n\ |