diff options
Diffstat (limited to 'src/callproc.c')
| -rw-r--r-- | src/callproc.c | 211 |
1 files changed, 111 insertions, 100 deletions
diff --git a/src/callproc.c b/src/callproc.c index 30f9dc58d46..91f29bd589b 100644 --- a/src/callproc.c +++ b/src/callproc.c | |||
| @@ -123,8 +123,8 @@ record_kill_process (struct Lisp_Process *p) | |||
| 123 | 123 | ||
| 124 | /* Clean up when exiting call_process_cleanup. */ | 124 | /* Clean up when exiting call_process_cleanup. */ |
| 125 | 125 | ||
| 126 | static Lisp_Object | 126 | static void |
| 127 | call_process_kill (Lisp_Object ignored) | 127 | call_process_kill (void) |
| 128 | { | 128 | { |
| 129 | if (synch_process_fd >= 0) | 129 | if (synch_process_fd >= 0) |
| 130 | emacs_close (synch_process_fd); | 130 | emacs_close (synch_process_fd); |
| @@ -136,15 +136,13 @@ call_process_kill (Lisp_Object ignored) | |||
| 136 | proc.pid = synch_process_pid; | 136 | proc.pid = synch_process_pid; |
| 137 | record_kill_process (&proc); | 137 | record_kill_process (&proc); |
| 138 | } | 138 | } |
| 139 | |||
| 140 | return Qnil; | ||
| 141 | } | 139 | } |
| 142 | 140 | ||
| 143 | /* Clean up when exiting Fcall_process. | 141 | /* Clean up when exiting Fcall_process. |
| 144 | On MSDOS, delete the temporary file on any kind of termination. | 142 | On MSDOS, delete the temporary file on any kind of termination. |
| 145 | On Unix, kill the process and any children on termination by signal. */ | 143 | On Unix, kill the process and any children on termination by signal. */ |
| 146 | 144 | ||
| 147 | static Lisp_Object | 145 | static void |
| 148 | call_process_cleanup (Lisp_Object arg) | 146 | call_process_cleanup (Lisp_Object arg) |
| 149 | { | 147 | { |
| 150 | #ifdef MSDOS | 148 | #ifdef MSDOS |
| @@ -162,7 +160,7 @@ call_process_cleanup (Lisp_Object arg) | |||
| 162 | { | 160 | { |
| 163 | ptrdiff_t count = SPECPDL_INDEX (); | 161 | ptrdiff_t count = SPECPDL_INDEX (); |
| 164 | kill (-synch_process_pid, SIGINT); | 162 | kill (-synch_process_pid, SIGINT); |
| 165 | record_unwind_protect (call_process_kill, make_number (0)); | 163 | record_unwind_protect_void (call_process_kill); |
| 166 | message1 ("Waiting for process to die...(type C-g again to kill it instantly)"); | 164 | message1 ("Waiting for process to die...(type C-g again to kill it instantly)"); |
| 167 | immediate_quit = 1; | 165 | immediate_quit = 1; |
| 168 | QUIT; | 166 | QUIT; |
| @@ -183,8 +181,6 @@ call_process_cleanup (Lisp_Object arg) | |||
| 183 | if (!(strcmp (SDATA (file), NULL_DEVICE) == 0 || SREF (file, 0) == '\0')) | 181 | if (!(strcmp (SDATA (file), NULL_DEVICE) == 0 || SREF (file, 0) == '\0')) |
| 184 | unlink (SDATA (file)); | 182 | unlink (SDATA (file)); |
| 185 | #endif | 183 | #endif |
| 186 | |||
| 187 | return Qnil; | ||
| 188 | } | 184 | } |
| 189 | 185 | ||
| 190 | #ifdef DOS_NT | 186 | #ifdef DOS_NT |
| @@ -392,7 +388,7 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) * | |||
| 392 | 388 | ||
| 393 | if (NILP (Ffile_accessible_directory_p (current_dir))) | 389 | if (NILP (Ffile_accessible_directory_p (current_dir))) |
| 394 | report_file_error ("Setting current directory", | 390 | report_file_error ("Setting current directory", |
| 395 | Fcons (BVAR (current_buffer, directory), Qnil)); | 391 | BVAR (current_buffer, directory)); |
| 396 | 392 | ||
| 397 | if (STRING_MULTIBYTE (infile)) | 393 | if (STRING_MULTIBYTE (infile)) |
| 398 | infile = ENCODE_FILE (infile); | 394 | infile = ENCODE_FILE (infile); |
| @@ -409,8 +405,11 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) * | |||
| 409 | 405 | ||
| 410 | filefd = emacs_open (SSDATA (infile), O_RDONLY, 0); | 406 | filefd = emacs_open (SSDATA (infile), O_RDONLY, 0); |
| 411 | if (filefd < 0) | 407 | if (filefd < 0) |
| 412 | report_file_error ("Opening process input file", | 408 | { |
| 413 | Fcons (DECODE_FILE (infile), Qnil)); | 409 | int open_errno = errno; |
| 410 | report_file_errno ("Opening process input file", DECODE_FILE (infile), | ||
| 411 | open_errno); | ||
| 412 | } | ||
| 414 | 413 | ||
| 415 | if (STRINGP (output_file)) | 414 | if (STRINGP (output_file)) |
| 416 | { | 415 | { |
| @@ -422,7 +421,7 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) * | |||
| 422 | int open_errno = errno; | 421 | int open_errno = errno; |
| 423 | output_file = DECODE_FILE (output_file); | 422 | output_file = DECODE_FILE (output_file); |
| 424 | report_file_errno ("Opening process output file", | 423 | report_file_errno ("Opening process output file", |
| 425 | Fcons (output_file, Qnil), open_errno); | 424 | output_file, open_errno); |
| 426 | } | 425 | } |
| 427 | if (STRINGP (error_file) || NILP (error_file)) | 426 | if (STRINGP (error_file) || NILP (error_file)) |
| 428 | output_to_buffer = 0; | 427 | output_to_buffer = 0; |
| @@ -440,8 +439,7 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) * | |||
| 440 | { | 439 | { |
| 441 | int openp_errno = errno; | 440 | int openp_errno = errno; |
| 442 | emacs_close (filefd); | 441 | emacs_close (filefd); |
| 443 | report_file_errno ("Searching for program", | 442 | report_file_errno ("Searching for program", args[0], openp_errno); |
| 444 | Fcons (args[0], Qnil), openp_errno); | ||
| 445 | } | 443 | } |
| 446 | } | 444 | } |
| 447 | 445 | ||
| @@ -506,7 +504,7 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) * | |||
| 506 | int open_errno = errno; | 504 | int open_errno = errno; |
| 507 | emacs_close (filefd); | 505 | emacs_close (filefd); |
| 508 | report_file_errno ("Opening process output file", | 506 | report_file_errno ("Opening process output file", |
| 509 | Fcons (build_string (tempfile), Qnil), open_errno); | 507 | build_string (tempfile), open_errno); |
| 510 | } | 508 | } |
| 511 | } | 509 | } |
| 512 | else | 510 | else |
| @@ -524,7 +522,7 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) * | |||
| 524 | { | 522 | { |
| 525 | #ifndef MSDOS | 523 | #ifndef MSDOS |
| 526 | int fd[2]; | 524 | int fd[2]; |
| 527 | if (pipe2 (fd, O_CLOEXEC) != 0) | 525 | if (emacs_pipe (fd) != 0) |
| 528 | { | 526 | { |
| 529 | int pipe_errno = errno; | 527 | int pipe_errno = errno; |
| 530 | emacs_close (filefd); | 528 | emacs_close (filefd); |
| @@ -563,8 +561,7 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) * | |||
| 563 | error_file = build_string (NULL_DEVICE); | 561 | error_file = build_string (NULL_DEVICE); |
| 564 | else if (STRINGP (error_file)) | 562 | else if (STRINGP (error_file)) |
| 565 | error_file = DECODE_FILE (error_file); | 563 | error_file = DECODE_FILE (error_file); |
| 566 | report_file_errno ("Cannot redirect stderr", | 564 | report_file_errno ("Cannot redirect stderr", error_file, open_errno); |
| 567 | Fcons (error_file, Qnil), open_errno); | ||
| 568 | } | 565 | } |
| 569 | 566 | ||
| 570 | #ifdef MSDOS /* MW, July 1993 */ | 567 | #ifdef MSDOS /* MW, July 1993 */ |
| @@ -596,8 +593,7 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) * | |||
| 596 | unlink (tempfile); | 593 | unlink (tempfile); |
| 597 | emacs_close (filefd); | 594 | emacs_close (filefd); |
| 598 | report_file_errno ("Cannot re-open temporary file", | 595 | report_file_errno ("Cannot re-open temporary file", |
| 599 | Fcons (build_string (tempfile), Qnil), | 596 | build_string (tempfile), open_errno); |
| 600 | open_errno); | ||
| 601 | } | 597 | } |
| 602 | } | 598 | } |
| 603 | else | 599 | else |
| @@ -935,7 +931,7 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) * | |||
| 935 | return make_number (WEXITSTATUS (status)); | 931 | return make_number (WEXITSTATUS (status)); |
| 936 | } | 932 | } |
| 937 | 933 | ||
| 938 | static Lisp_Object | 934 | static void |
| 939 | delete_temp_file (Lisp_Object name) | 935 | delete_temp_file (Lisp_Object name) |
| 940 | { | 936 | { |
| 941 | /* Suppress jka-compr handling, etc. */ | 937 | /* Suppress jka-compr handling, etc. */ |
| @@ -957,44 +953,18 @@ delete_temp_file (Lisp_Object name) | |||
| 957 | internal_delete_file (name); | 953 | internal_delete_file (name); |
| 958 | #endif | 954 | #endif |
| 959 | unbind_to (count, Qnil); | 955 | unbind_to (count, Qnil); |
| 960 | return Qnil; | ||
| 961 | } | 956 | } |
| 962 | 957 | ||
| 963 | DEFUN ("call-process-region", Fcall_process_region, Scall_process_region, | 958 | /* Create a temporary file suitable for storing the input data of |
| 964 | 3, MANY, 0, | 959 | call-process-region. NARGS and ARGS are the same as for |
| 965 | doc: /* Send text from START to END to a synchronous process running PROGRAM. | 960 | call-process-region. */ |
| 966 | The remaining arguments are optional. | ||
| 967 | Delete the text if fourth arg DELETE is non-nil. | ||
| 968 | |||
| 969 | Insert output in BUFFER before point; t means current buffer; nil for | ||
| 970 | BUFFER means discard it; 0 means discard and don't wait; and `(:file | ||
| 971 | FILE)', where FILE is a file name string, means that it should be | ||
| 972 | written to that file (if the file already exists it is overwritten). | ||
| 973 | BUFFER can also have the form (REAL-BUFFER STDERR-FILE); in that case, | ||
| 974 | REAL-BUFFER says what to do with standard output, as above, | ||
| 975 | while STDERR-FILE says what to do with standard error in the child. | ||
| 976 | STDERR-FILE may be nil (discard standard error output), | ||
| 977 | t (mix it with ordinary output), or a file name string. | ||
| 978 | |||
| 979 | Sixth arg DISPLAY non-nil means redisplay buffer as output is inserted. | ||
| 980 | Remaining args are passed to PROGRAM at startup as command args. | ||
| 981 | 961 | ||
| 982 | If BUFFER is 0, `call-process-region' returns immediately with value nil. | 962 | static Lisp_Object |
| 983 | Otherwise it waits for PROGRAM to terminate | 963 | create_temp_file (ptrdiff_t nargs, Lisp_Object *args) |
| 984 | and returns a numeric exit status or a signal description string. | ||
| 985 | If you quit, the process is killed with SIGINT, or SIGKILL if you quit again. | ||
| 986 | |||
| 987 | usage: (call-process-region START END PROGRAM &optional DELETE BUFFER DISPLAY &rest ARGS) */) | ||
| 988 | (ptrdiff_t nargs, Lisp_Object *args) | ||
| 989 | { | 964 | { |
| 990 | struct gcpro gcpro1; | 965 | struct gcpro gcpro1; |
| 991 | Lisp_Object filename_string; | 966 | Lisp_Object filename_string; |
| 992 | register Lisp_Object start, end; | 967 | Lisp_Object val, start, end; |
| 993 | ptrdiff_t count = SPECPDL_INDEX (); | ||
| 994 | /* Qt denotes we have not yet called Ffind_operation_coding_system. */ | ||
| 995 | Lisp_Object coding_systems; | ||
| 996 | Lisp_Object val, *args2; | ||
| 997 | ptrdiff_t i; | ||
| 998 | Lisp_Object tmpdir; | 968 | Lisp_Object tmpdir; |
| 999 | 969 | ||
| 1000 | if (STRINGP (Vtemporary_file_directory)) | 970 | if (STRINGP (Vtemporary_file_directory)) |
| @@ -1016,9 +986,7 @@ usage: (call-process-region START END PROGRAM &optional DELETE BUFFER DISPLAY &r | |||
| 1016 | } | 986 | } |
| 1017 | 987 | ||
| 1018 | { | 988 | { |
| 1019 | USE_SAFE_ALLOCA; | ||
| 1020 | Lisp_Object pattern = Fexpand_file_name (Vtemp_file_name_pattern, tmpdir); | 989 | Lisp_Object pattern = Fexpand_file_name (Vtemp_file_name_pattern, tmpdir); |
| 1021 | Lisp_Object encoded_tem; | ||
| 1022 | char *tempfile; | 990 | char *tempfile; |
| 1023 | 991 | ||
| 1024 | #ifdef WINDOWSNT | 992 | #ifdef WINDOWSNT |
| @@ -1036,39 +1004,30 @@ usage: (call-process-region START END PROGRAM &optional DELETE BUFFER DISPLAY &r | |||
| 1036 | } | 1004 | } |
| 1037 | #endif | 1005 | #endif |
| 1038 | 1006 | ||
| 1039 | encoded_tem = ENCODE_FILE (pattern); | 1007 | filename_string = Fcopy_sequence (ENCODE_FILE (pattern)); |
| 1040 | tempfile = SAFE_ALLOCA (SBYTES (encoded_tem) + 1); | 1008 | GCPRO1 (filename_string); |
| 1041 | memcpy (tempfile, SDATA (encoded_tem), SBYTES (encoded_tem) + 1); | 1009 | tempfile = SSDATA (filename_string); |
| 1042 | coding_systems = Qt; | ||
| 1043 | 1010 | ||
| 1044 | #if defined HAVE_MKOSTEMP || defined HAVE_MKSTEMP | ||
| 1045 | { | 1011 | { |
| 1046 | int fd, open_errno; | 1012 | int fd; |
| 1047 | 1013 | ||
| 1048 | block_input (); | 1014 | #ifdef HAVE_MKOSTEMP |
| 1049 | # ifdef HAVE_MKOSTEMP | ||
| 1050 | fd = mkostemp (tempfile, O_CLOEXEC); | 1015 | fd = mkostemp (tempfile, O_CLOEXEC); |
| 1051 | # else | 1016 | #elif defined HAVE_MKSTEMP |
| 1052 | fd = mkstemp (tempfile); | 1017 | fd = mkstemp (tempfile); |
| 1053 | # endif | 1018 | #else |
| 1054 | open_errno = errno; | 1019 | errno = EEXIST; |
| 1055 | unblock_input (); | 1020 | mktemp (tempfile); |
| 1021 | /* INT_MAX denotes success, because close (INT_MAX) does nothing. */ | ||
| 1022 | fd = *tempfile ? INT_MAX : -1; | ||
| 1023 | #endif | ||
| 1056 | if (fd < 0) | 1024 | if (fd < 0) |
| 1057 | report_file_errno ("Failed to open temporary file", | 1025 | report_file_error ("Failed to open temporary file using pattern", |
| 1058 | Fcons (build_string (tempfile), Qnil), open_errno); | 1026 | pattern); |
| 1059 | emacs_close (fd); | 1027 | emacs_close (fd); |
| 1060 | } | 1028 | } |
| 1061 | #else | ||
| 1062 | errno = EEXIST; | ||
| 1063 | mktemp (tempfile); | ||
| 1064 | if (!*tempfile) | ||
| 1065 | report_file_error ("Failed to open temporary file using pattern", | ||
| 1066 | Fcons (pattern, Qnil)); | ||
| 1067 | #endif | ||
| 1068 | 1029 | ||
| 1069 | filename_string = build_string (tempfile); | 1030 | record_unwind_protect (delete_temp_file, filename_string); |
| 1070 | GCPRO1 (filename_string); | ||
| 1071 | SAFE_FREE (); | ||
| 1072 | } | 1031 | } |
| 1073 | 1032 | ||
| 1074 | start = args[0]; | 1033 | start = args[0]; |
| @@ -1080,10 +1039,12 @@ usage: (call-process-region START END PROGRAM &optional DELETE BUFFER DISPLAY &r | |||
| 1080 | val = Qraw_text; | 1039 | val = Qraw_text; |
| 1081 | else | 1040 | else |
| 1082 | { | 1041 | { |
| 1042 | Lisp_Object coding_systems; | ||
| 1043 | Lisp_Object *args2; | ||
| 1083 | USE_SAFE_ALLOCA; | 1044 | USE_SAFE_ALLOCA; |
| 1084 | SAFE_NALLOCA (args2, 1, nargs + 1); | 1045 | SAFE_NALLOCA (args2, 1, nargs + 1); |
| 1085 | args2[0] = Qcall_process_region; | 1046 | args2[0] = Qcall_process_region; |
| 1086 | for (i = 0; i < nargs; i++) args2[i + 1] = args[i]; | 1047 | memcpy (args2 + 1, args, nargs * sizeof *args); |
| 1087 | coding_systems = Ffind_operation_coding_system (nargs + 1, args2); | 1048 | coding_systems = Ffind_operation_coding_system (nargs + 1, args2); |
| 1088 | val = CONSP (coding_systems) ? XCDR (coding_systems) : Qnil; | 1049 | val = CONSP (coding_systems) ? XCDR (coding_systems) : Qnil; |
| 1089 | SAFE_FREE (); | 1050 | SAFE_FREE (); |
| @@ -1105,7 +1066,57 @@ usage: (call-process-region START END PROGRAM &optional DELETE BUFFER DISPLAY &r | |||
| 1105 | /* Note that Fcall_process takes care of binding | 1066 | /* Note that Fcall_process takes care of binding |
| 1106 | coding-system-for-read. */ | 1067 | coding-system-for-read. */ |
| 1107 | 1068 | ||
| 1108 | record_unwind_protect (delete_temp_file, filename_string); | 1069 | RETURN_UNGCPRO (filename_string); |
| 1070 | } | ||
| 1071 | |||
| 1072 | DEFUN ("call-process-region", Fcall_process_region, Scall_process_region, | ||
| 1073 | 3, MANY, 0, | ||
| 1074 | doc: /* Send text from START to END to a synchronous process running PROGRAM. | ||
| 1075 | The remaining arguments are optional. | ||
| 1076 | Delete the text if fourth arg DELETE is non-nil. | ||
| 1077 | |||
| 1078 | Insert output in BUFFER before point; t means current buffer; nil for | ||
| 1079 | BUFFER means discard it; 0 means discard and don't wait; and `(:file | ||
| 1080 | FILE)', where FILE is a file name string, means that it should be | ||
| 1081 | written to that file (if the file already exists it is overwritten). | ||
| 1082 | BUFFER can also have the form (REAL-BUFFER STDERR-FILE); in that case, | ||
| 1083 | REAL-BUFFER says what to do with standard output, as above, | ||
| 1084 | while STDERR-FILE says what to do with standard error in the child. | ||
| 1085 | STDERR-FILE may be nil (discard standard error output), | ||
| 1086 | t (mix it with ordinary output), or a file name string. | ||
| 1087 | |||
| 1088 | Sixth arg DISPLAY non-nil means redisplay buffer as output is inserted. | ||
| 1089 | Remaining args are passed to PROGRAM at startup as command args. | ||
| 1090 | |||
| 1091 | If BUFFER is 0, `call-process-region' returns immediately with value nil. | ||
| 1092 | Otherwise it waits for PROGRAM to terminate | ||
| 1093 | and returns a numeric exit status or a signal description string. | ||
| 1094 | If you quit, the process is killed with SIGINT, or SIGKILL if you quit again. | ||
| 1095 | |||
| 1096 | usage: (call-process-region START END PROGRAM &optional DELETE BUFFER DISPLAY &rest ARGS) */) | ||
| 1097 | (ptrdiff_t nargs, Lisp_Object *args) | ||
| 1098 | { | ||
| 1099 | struct gcpro gcpro1; | ||
| 1100 | Lisp_Object infile; | ||
| 1101 | ptrdiff_t count = SPECPDL_INDEX (); | ||
| 1102 | Lisp_Object start = args[0]; | ||
| 1103 | Lisp_Object end = args[1]; | ||
| 1104 | bool empty_input; | ||
| 1105 | |||
| 1106 | if (STRINGP (start)) | ||
| 1107 | empty_input = SCHARS (start) == 0; | ||
| 1108 | else if (NILP (start)) | ||
| 1109 | empty_input = BEG == Z; | ||
| 1110 | else | ||
| 1111 | { | ||
| 1112 | validate_region (&args[0], &args[1]); | ||
| 1113 | start = args[0]; | ||
| 1114 | end = args[1]; | ||
| 1115 | empty_input = XINT (start) == XINT (end); | ||
| 1116 | } | ||
| 1117 | |||
| 1118 | infile = empty_input ? Qnil : create_temp_file (nargs, args); | ||
| 1119 | GCPRO1 (infile); | ||
| 1109 | 1120 | ||
| 1110 | if (nargs > 3 && !NILP (args[3])) | 1121 | if (nargs > 3 && !NILP (args[3])) |
| 1111 | Fdelete_region (start, end); | 1122 | Fdelete_region (start, end); |
| @@ -1120,7 +1131,7 @@ usage: (call-process-region START END PROGRAM &optional DELETE BUFFER DISPLAY &r | |||
| 1120 | args[0] = args[2]; | 1131 | args[0] = args[2]; |
| 1121 | nargs = 2; | 1132 | nargs = 2; |
| 1122 | } | 1133 | } |
| 1123 | args[1] = filename_string; | 1134 | args[1] = infile; |
| 1124 | 1135 | ||
| 1125 | RETURN_UNGCPRO (unbind_to (count, Fcall_process (nargs, args))); | 1136 | RETURN_UNGCPRO (unbind_to (count, Fcall_process (nargs, args))); |
| 1126 | } | 1137 | } |
| @@ -1185,9 +1196,11 @@ child_setup (int in, int out, int err, char **new_argv, bool set_pgrp, | |||
| 1185 | #ifdef WINDOWSNT | 1196 | #ifdef WINDOWSNT |
| 1186 | int cpid; | 1197 | int cpid; |
| 1187 | HANDLE handles[3]; | 1198 | HANDLE handles[3]; |
| 1188 | #endif /* WINDOWSNT */ | 1199 | #else |
| 1200 | int exec_errno; | ||
| 1189 | 1201 | ||
| 1190 | pid_t pid = getpid (); | 1202 | pid_t pid = getpid (); |
| 1203 | #endif /* WINDOWSNT */ | ||
| 1191 | 1204 | ||
| 1192 | /* Note that use of alloca is always safe here. It's obvious for systems | 1205 | /* Note that use of alloca is always safe here. It's obvious for systems |
| 1193 | that do not have true vfork or that have true (stack) alloca. | 1206 | that do not have true vfork or that have true (stack) alloca. |
| @@ -1346,32 +1359,27 @@ child_setup (int in, int out, int err, char **new_argv, bool set_pgrp, | |||
| 1346 | } | 1359 | } |
| 1347 | 1360 | ||
| 1348 | #ifndef MSDOS | 1361 | #ifndef MSDOS |
| 1349 | emacs_close (0); | 1362 | /* Redirect file descriptors and clear the close-on-exec flag on the |
| 1350 | emacs_close (1); | 1363 | redirected ones. IN, OUT, and ERR are close-on-exec so they |
| 1351 | emacs_close (2); | 1364 | need not be closed explicitly. */ |
| 1352 | |||
| 1353 | /* Redirect file descriptors and clear FD_CLOEXEC on the redirected ones. */ | ||
| 1354 | dup2 (in, 0); | 1365 | dup2 (in, 0); |
| 1355 | dup2 (out, 1); | 1366 | dup2 (out, 1); |
| 1356 | dup2 (err, 2); | 1367 | dup2 (err, 2); |
| 1357 | 1368 | ||
| 1358 | emacs_close (in); | ||
| 1359 | if (out != in) | ||
| 1360 | emacs_close (out); | ||
| 1361 | if (err != in && err != out) | ||
| 1362 | emacs_close (err); | ||
| 1363 | |||
| 1364 | setpgid (0, 0); | 1369 | setpgid (0, 0); |
| 1365 | tcsetpgrp (0, pid); | 1370 | tcsetpgrp (0, pid); |
| 1366 | 1371 | ||
| 1367 | execve (new_argv[0], new_argv, env); | 1372 | execve (new_argv[0], new_argv, env); |
| 1373 | exec_errno = errno; | ||
| 1368 | 1374 | ||
| 1369 | /* Don't output the program name here, as it can be arbitrarily long, | 1375 | /* Avoid deadlock if the child's perror writes to a full pipe; the |
| 1370 | and a long write from a vforked child to its parent can cause a | 1376 | pipe's reader is the parent, but with vfork the parent can't |
| 1371 | deadlock. */ | 1377 | run until the child exits. Truncate the diagnostic instead. */ |
| 1372 | emacs_perror ("child process"); | 1378 | fcntl (STDERR_FILENO, F_SETFL, O_NONBLOCK); |
| 1373 | 1379 | ||
| 1374 | _exit (errno == ENOENT ? EXIT_ENOENT : EXIT_CANNOT_INVOKE); | 1380 | errno = exec_errno; |
| 1381 | emacs_perror (new_argv[0]); | ||
| 1382 | _exit (exec_errno == ENOENT ? EXIT_ENOENT : EXIT_CANNOT_INVOKE); | ||
| 1375 | 1383 | ||
| 1376 | #else /* MSDOS */ | 1384 | #else /* MSDOS */ |
| 1377 | pid = run_msdos_command (new_argv, pwd_var + 4, in, out, err, env); | 1385 | pid = run_msdos_command (new_argv, pwd_var + 4, in, out, err, env); |
| @@ -1386,7 +1394,8 @@ child_setup (int in, int out, int err, char **new_argv, bool set_pgrp, | |||
| 1386 | 1394 | ||
| 1387 | #ifndef WINDOWSNT | 1395 | #ifndef WINDOWSNT |
| 1388 | /* Move the file descriptor FD so that its number is not less than MINFD. | 1396 | /* Move the file descriptor FD so that its number is not less than MINFD. |
| 1389 | If the file descriptor is moved at all, the original is freed. */ | 1397 | If the file descriptor is moved at all, the original is closed on MSDOS, |
| 1398 | but not elsewhere as the caller will close it anyway. */ | ||
| 1390 | static int | 1399 | static int |
| 1391 | relocate_fd (int fd, int minfd) | 1400 | relocate_fd (int fd, int minfd) |
| 1392 | { | 1401 | { |
| @@ -1400,7 +1409,9 @@ relocate_fd (int fd, int minfd) | |||
| 1400 | emacs_perror ("while setting up child"); | 1409 | emacs_perror ("while setting up child"); |
| 1401 | _exit (EXIT_CANCELED); | 1410 | _exit (EXIT_CANCELED); |
| 1402 | } | 1411 | } |
| 1412 | #ifdef MSDOS | ||
| 1403 | emacs_close (fd); | 1413 | emacs_close (fd); |
| 1414 | #endif | ||
| 1404 | return new; | 1415 | return new; |
| 1405 | } | 1416 | } |
| 1406 | } | 1417 | } |