diff options
| author | Paul Eggert | 2013-08-12 00:12:07 -0700 |
|---|---|---|
| committer | Paul Eggert | 2013-08-12 00:12:07 -0700 |
| commit | 94fcd171894e3a14d3548c028c4229229e32d184 (patch) | |
| tree | 5db95055c61a05f2b4edb6d0d74cb4e2692f6533 /src/callproc.c | |
| parent | 4750fd7bf40585eb3956e86e521a7508eaa0f35f (diff) | |
| download | emacs-94fcd171894e3a14d3548c028c4229229e32d184.tar.gz emacs-94fcd171894e3a14d3548c028c4229229e32d184.zip | |
Fix some fd issues when running subprocesses.
Fix bugs that can leak files or file descriptors on errors.
Don't unlink open temp files, as that's hard for users to diagnose
when things go awry (e.g., temp disk exhausted).
Don't bother to lock temp files. Check for invalid recursion.
* callproc.c (synch_process_fd): Remove. All uses removed.
(synch_process_tempfile): New var or macro.
(CALLPROC_STDOUT, CALLPROC_STDERR, CALLPROC_PIPEREAD, CALLPROC_FDS):
New constants.
(record_kill_process): New arg, the temp name. All callers changed.
(delete_temp_file): Now just a simple wrapper around unlink.
(call_process_kill): New arg, the call_process_fd array.
Close them all. Clear synch_process_pid. Remove the temp file,
or arrange for it to be removed.
(call_process_cleanup) [MSDOS]: Arg no longer contains file name;
that's been moved to synch_process_tempfile. Caller changed.
Do not remove the tempfile; that's now call_process_kill's
responsibility.
(call_process_cleanup) [!MSDOS]: Do not record unwind-protect for
call_process_kill; the caller now does that.
(call_process_cleanup): Do not close the process fd; that's now
call_process_kill's responsibility.
(Fcall_process): Implement via new function call_process, which
has most of the old body of Fcall_process, but with a different API.
(call_process): New function that does not open or close filefd if
it is nonnegative. Record which fds need to be closed, and let
call_process_kill close (and remove the tempfile, on MSDOS) on error.
Signal an error if invoked recursively (could be done via a hook).
Simplify creation of the tempfile in the MSDOS case.
Don't create the output file until after checking for the executable.
Report any failure to open /dev/null.
Don't open /dev/null for writing twice; once is enough.
Don't create pipe if all output is being discarded or sent to file.
Don't worry about setting up the coding system or reading from the
pipe if all output is being discarded.
Hoist fd_error local into top level, to lessen block nesting.
Don't record deleted pid here; now done by Fcall_process_region.
(Fcall_process) [MSDOS]: Report mktemp failure immediately,
and note its success in synch_process_tempfile.
Do not leak resources when child_setup fails.
(Fcall_process) [!MSDOS && !WINDOWSNT]: Remove duplicate assignment
to child_errno. Remove unnecessary close of fd0; it's close-on-exec.
(create_temp_file): Now returns open fd, with an additional
Lisp_Object * argument to return the name. All callers changed.
Do not close the file; rewind it instead, and leave it open for
the caller. Do not lock the temp file. Unwind-protect the file
and the file-descriptor.
(Fcall_process_region): If the input is /dev/null, unwind-protect it.
If an asynchrounous process, record it here, not in call_process.
(syms_of_callproc) [MSDOS]: Initialize synch_process_tempfile.
* eval.c (set_unwind_protect): New function.
* fileio.c (write_region): New function, generalized from the
old Fwrite_region. Do not lock temp files.
(Fwrite_region): Use it.
* lisp.h (set_unwind_protect, write_region): New decls.
* process.c: Include <verify.h>.
(make_process): Mark fds as initially closed.
(deleted_pid_list): Now a list of pid-filename pairs.
All uses changed.
(close_process_fd): New function.
(SUBPROCESS_STDIN, WRITE_TO_SUBPROCESS, READ_FROM_SUBPROCESS)
(SUBPROCESS_STDOUT, READ_FROM_EXEC_MONITOR, EXEC_MONITOR_OUTPUT):
New constants. Verify that their number matches PROCESS_OPEN_FDS.
(create_process, create_pty, Fmake_serial_process)
(server_accept_connection): Record which fds need to be closed,
and let deactivate_process close them.
(Fmake_network_process): Do not discard the unwind-protect
until it's safe to do so.
(deactivate_process): Close the fds opened by create_process etc.
(Fprocess_send_eof): Adjust to new way of recording open fds.
Report an error if /dev/null can't be opened, instead of aborting.
* process.h (PROCESS_OPEN_FDS): New constant.
(struct Lisp_Process): New member open_fds.
(record_kill_process, record_deleted_pid): Adjust signatures.
(record_deleted_pid): Move decl here ...
* syswait.h (record_deleted_pid): ... from here.
Fixes: debbugs:15035
Diffstat (limited to 'src/callproc.c')
| -rw-r--r-- | src/callproc.c | 762 |
1 files changed, 367 insertions, 395 deletions
diff --git a/src/callproc.c b/src/callproc.c index 54bc5cd9dc0..2a9162cb5cc 100644 --- a/src/callproc.c +++ b/src/callproc.c | |||
| @@ -68,9 +68,10 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 68 | /* Pattern used by call-process-region to make temp files. */ | 68 | /* Pattern used by call-process-region to make temp files. */ |
| 69 | static Lisp_Object Vtemp_file_name_pattern; | 69 | static Lisp_Object Vtemp_file_name_pattern; |
| 70 | 70 | ||
| 71 | /* The next two variables are valid only while record-unwind-protect | 71 | /* The next two variables are used while record-unwind-protect is in place |
| 72 | is in place during call-process for a synchronous subprocess. At | 72 | during call-process for a subprocess for which record_deleted_pid has |
| 73 | other times, their contents are irrelevant. Doing this via static | 73 | not yet been called. At other times, synch_process_pid is zero and |
| 74 | synch_process_tempfile's contents are irrelevant. Doing this via static | ||
| 74 | C variables is more convenient than putting them into the arguments | 75 | C variables is more convenient than putting them into the arguments |
| 75 | of record-unwind-protect, as they need to be updated at randomish | 76 | of record-unwind-protect, as they need to be updated at randomish |
| 76 | times in the code, and Lisp cannot always store these values as | 77 | times in the code, and Lisp cannot always store these values as |
| @@ -80,8 +81,28 @@ static Lisp_Object Vtemp_file_name_pattern; | |||
| 80 | /* If nonzero, a process-ID that has not been reaped. */ | 81 | /* If nonzero, a process-ID that has not been reaped. */ |
| 81 | static pid_t synch_process_pid; | 82 | static pid_t synch_process_pid; |
| 82 | 83 | ||
| 83 | /* If nonnegative, a file descriptor that has not been closed. */ | 84 | /* If a string, the name of a temp file that has not been removed. */ |
| 84 | static int synch_process_fd; | 85 | #ifdef MSDOS |
| 86 | static Lisp_Object synch_process_tempfile; | ||
| 87 | #else | ||
| 88 | # define synch_process_tempfile make_number (0) | ||
| 89 | #endif | ||
| 90 | |||
| 91 | /* Indexes of file descriptors that need closing on call_process_kill. */ | ||
| 92 | enum | ||
| 93 | { | ||
| 94 | /* The subsidiary process's stdout and stderr. stdin is handled | ||
| 95 | separately, in either Fcall_process_region or create_temp_file. */ | ||
| 96 | CALLPROC_STDOUT, CALLPROC_STDERR, | ||
| 97 | |||
| 98 | /* How to read from a pipe (or substitute) from the subsidiary process. */ | ||
| 99 | CALLPROC_PIPEREAD, | ||
| 100 | |||
| 101 | /* A bound on the number of file descriptors. */ | ||
| 102 | CALLPROC_FDS | ||
| 103 | }; | ||
| 104 | |||
| 105 | static Lisp_Object call_process (ptrdiff_t, Lisp_Object *, int); | ||
| 85 | 106 | ||
| 86 | /* Block SIGCHLD. */ | 107 | /* Block SIGCHLD. */ |
| 87 | 108 | ||
| @@ -107,80 +128,68 @@ unblock_child_signal (void) | |||
| 107 | reaped on receipt of the first SIGCHLD after the critical section. */ | 128 | reaped on receipt of the first SIGCHLD after the critical section. */ |
| 108 | 129 | ||
| 109 | void | 130 | void |
| 110 | record_kill_process (struct Lisp_Process *p) | 131 | record_kill_process (struct Lisp_Process *p, Lisp_Object tempfile) |
| 111 | { | 132 | { |
| 112 | block_child_signal (); | 133 | block_child_signal (); |
| 113 | 134 | ||
| 114 | if (p->alive) | 135 | if (p->alive) |
| 115 | { | 136 | { |
| 137 | record_deleted_pid (p->pid, tempfile); | ||
| 116 | p->alive = 0; | 138 | p->alive = 0; |
| 117 | record_deleted_pid (p->pid); | ||
| 118 | kill (- p->pid, SIGKILL); | 139 | kill (- p->pid, SIGKILL); |
| 119 | } | 140 | } |
| 120 | 141 | ||
| 121 | unblock_child_signal (); | 142 | unblock_child_signal (); |
| 122 | } | 143 | } |
| 123 | 144 | ||
| 124 | /* Clean up when exiting call_process_cleanup. */ | 145 | /* Clean up files, file descriptors and processes created by Fcall_process. */ |
| 146 | |||
| 147 | static void | ||
| 148 | delete_temp_file (Lisp_Object name) | ||
| 149 | { | ||
| 150 | unlink (SSDATA (name)); | ||
| 151 | } | ||
| 125 | 152 | ||
| 126 | static void | 153 | static void |
| 127 | call_process_kill (void) | 154 | call_process_kill (void *ptr) |
| 128 | { | 155 | { |
| 129 | if (synch_process_fd >= 0) | 156 | int *callproc_fd = ptr; |
| 130 | emacs_close (synch_process_fd); | 157 | int i; |
| 158 | for (i = 0; i < CALLPROC_FDS; i++) | ||
| 159 | if (0 <= callproc_fd[i]) | ||
| 160 | emacs_close (callproc_fd[i]); | ||
| 131 | 161 | ||
| 132 | if (synch_process_pid) | 162 | if (synch_process_pid) |
| 133 | { | 163 | { |
| 134 | struct Lisp_Process proc; | 164 | struct Lisp_Process proc; |
| 135 | proc.alive = 1; | 165 | proc.alive = 1; |
| 136 | proc.pid = synch_process_pid; | 166 | proc.pid = synch_process_pid; |
| 137 | record_kill_process (&proc); | 167 | record_kill_process (&proc, synch_process_tempfile); |
| 168 | synch_process_pid = 0; | ||
| 138 | } | 169 | } |
| 170 | else if (STRINGP (synch_process_tempfile)) | ||
| 171 | delete_temp_file (synch_process_tempfile); | ||
| 139 | } | 172 | } |
| 140 | 173 | ||
| 141 | /* Clean up when exiting Fcall_process. | 174 | /* Clean up when exiting Fcall_process: restore the buffer, and |
| 142 | On MSDOS, delete the temporary file on any kind of termination. | 175 | kill the subsidiary process group if the process still exists. */ |
| 143 | On Unix, kill the process and any children on termination by signal. */ | ||
| 144 | 176 | ||
| 145 | static void | 177 | static void |
| 146 | call_process_cleanup (Lisp_Object arg) | 178 | call_process_cleanup (Lisp_Object buffer) |
| 147 | { | 179 | { |
| 148 | #ifdef MSDOS | ||
| 149 | Lisp_Object buffer = Fcar (arg); | ||
| 150 | Lisp_Object file = Fcdr (arg); | ||
| 151 | #else | ||
| 152 | Lisp_Object buffer = arg; | ||
| 153 | #endif | ||
| 154 | |||
| 155 | Fset_buffer (buffer); | 180 | Fset_buffer (buffer); |
| 156 | 181 | ||
| 157 | #ifndef MSDOS | ||
| 158 | /* If the process still exists, kill its process group. */ | ||
| 159 | if (synch_process_pid) | 182 | if (synch_process_pid) |
| 160 | { | 183 | { |
| 161 | ptrdiff_t count = SPECPDL_INDEX (); | ||
| 162 | kill (-synch_process_pid, SIGINT); | 184 | kill (-synch_process_pid, SIGINT); |
| 163 | record_unwind_protect_void (call_process_kill); | ||
| 164 | message1 ("Waiting for process to die...(type C-g again to kill it instantly)"); | 185 | message1 ("Waiting for process to die...(type C-g again to kill it instantly)"); |
| 165 | immediate_quit = 1; | 186 | immediate_quit = 1; |
| 166 | QUIT; | 187 | QUIT; |
| 167 | wait_for_termination (synch_process_pid, 0, 1); | 188 | wait_for_termination (synch_process_pid, 0, 1); |
| 168 | synch_process_pid = 0; | 189 | synch_process_pid = 0; |
| 169 | immediate_quit = 0; | 190 | immediate_quit = 0; |
| 170 | specpdl_ptr = specpdl + count; /* Discard the unwind protect. */ | ||
| 171 | message1 ("Waiting for process to die...done"); | 191 | message1 ("Waiting for process to die...done"); |
| 172 | } | 192 | } |
| 173 | #endif | ||
| 174 | |||
| 175 | if (synch_process_fd >= 0) | ||
| 176 | emacs_close (synch_process_fd); | ||
| 177 | |||
| 178 | #ifdef MSDOS | ||
| 179 | /* FILE is "" when we didn't actually create a temporary file in | ||
| 180 | call-process. */ | ||
| 181 | if (!(strcmp (SDATA (file), NULL_DEVICE) == 0 || SREF (file, 0) == '\0')) | ||
| 182 | unlink (SDATA (file)); | ||
| 183 | #endif | ||
| 184 | } | 193 | } |
| 185 | 194 | ||
| 186 | #ifdef DOS_NT | 195 | #ifdef DOS_NT |
| @@ -218,10 +227,42 @@ If you quit, the process is killed with SIGINT, or SIGKILL if you quit again. | |||
| 218 | usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) */) | 227 | usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) */) |
| 219 | (ptrdiff_t nargs, Lisp_Object *args) | 228 | (ptrdiff_t nargs, Lisp_Object *args) |
| 220 | { | 229 | { |
| 221 | Lisp_Object infile, buffer, current_dir, path; | 230 | Lisp_Object infile, encoded_infile; |
| 231 | int filefd; | ||
| 232 | struct gcpro gcpro1; | ||
| 233 | ptrdiff_t count = SPECPDL_INDEX (); | ||
| 234 | |||
| 235 | if (nargs >= 2 && ! NILP (args[1])) | ||
| 236 | { | ||
| 237 | infile = Fexpand_file_name (args[1], BVAR (current_buffer, directory)); | ||
| 238 | CHECK_STRING (infile); | ||
| 239 | } | ||
| 240 | else | ||
| 241 | infile = build_string (NULL_DEVICE); | ||
| 242 | |||
| 243 | GCPRO1 (infile); | ||
| 244 | encoded_infile = STRING_MULTIBYTE (infile) ? ENCODE_FILE (infile) : infile; | ||
| 245 | |||
| 246 | filefd = emacs_open (SSDATA (encoded_infile), O_RDONLY, 0); | ||
| 247 | if (filefd < 0) | ||
| 248 | report_file_error ("Opening process input file", infile); | ||
| 249 | record_unwind_protect_int (close_file_unwind, filefd); | ||
| 250 | UNGCPRO; | ||
| 251 | return unbind_to (count, call_process (nargs, args, filefd)); | ||
| 252 | } | ||
| 253 | |||
| 254 | /* Like Fcall_process (NARGS, ARGS), except use FILEFD as the input file. | ||
| 255 | At entry, the specpdl stack top entry must be close_file_unwind (FILEFD). */ | ||
| 256 | |||
| 257 | static Lisp_Object | ||
| 258 | call_process (ptrdiff_t nargs, Lisp_Object *args, int filefd) | ||
| 259 | { | ||
| 260 | Lisp_Object buffer, current_dir, path; | ||
| 222 | bool display_p; | 261 | bool display_p; |
| 223 | int fd0, fd1, filefd; | 262 | int fd0; |
| 263 | int callproc_fd[CALLPROC_FDS]; | ||
| 224 | int status; | 264 | int status; |
| 265 | ptrdiff_t i; | ||
| 225 | ptrdiff_t count = SPECPDL_INDEX (); | 266 | ptrdiff_t count = SPECPDL_INDEX (); |
| 226 | USE_SAFE_ALLOCA; | 267 | USE_SAFE_ALLOCA; |
| 227 | 268 | ||
| @@ -231,19 +272,21 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) * | |||
| 231 | Lisp_Object error_file; | 272 | Lisp_Object error_file; |
| 232 | Lisp_Object output_file = Qnil; | 273 | Lisp_Object output_file = Qnil; |
| 233 | #ifdef MSDOS /* Demacs 1.1.1 91/10/16 HIRANO Satoshi */ | 274 | #ifdef MSDOS /* Demacs 1.1.1 91/10/16 HIRANO Satoshi */ |
| 234 | char *outf, *tempfile = NULL; | 275 | char *tempfile = NULL; |
| 235 | int outfilefd; | ||
| 236 | int pid; | 276 | int pid; |
| 237 | #else | 277 | #else |
| 238 | pid_t pid; | 278 | pid_t pid; |
| 239 | #endif | 279 | #endif |
| 240 | int child_errno; | 280 | int child_errno; |
| 241 | int fd_output = -1; | 281 | int fd_output, fd_error; |
| 242 | struct coding_system process_coding; /* coding-system of process output */ | 282 | struct coding_system process_coding; /* coding-system of process output */ |
| 243 | struct coding_system argument_coding; /* coding-system of arguments */ | 283 | struct coding_system argument_coding; /* coding-system of arguments */ |
| 244 | /* Set to the return value of Ffind_operation_coding_system. */ | 284 | /* Set to the return value of Ffind_operation_coding_system. */ |
| 245 | Lisp_Object coding_systems; | 285 | Lisp_Object coding_systems; |
| 246 | bool output_to_buffer = 1; | 286 | bool discard_output; |
| 287 | |||
| 288 | if (synch_process_pid) | ||
| 289 | error ("call-process invoked recursively"); | ||
| 247 | 290 | ||
| 248 | /* Qt denotes that Ffind_operation_coding_system is not yet called. */ | 291 | /* Qt denotes that Ffind_operation_coding_system is not yet called. */ |
| 249 | coding_systems = Qt; | 292 | coding_systems = Qt; |
| @@ -262,7 +305,6 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) * | |||
| 262 | /* Decide the coding-system for giving arguments. */ | 305 | /* Decide the coding-system for giving arguments. */ |
| 263 | { | 306 | { |
| 264 | Lisp_Object val, *args2; | 307 | Lisp_Object val, *args2; |
| 265 | ptrdiff_t i; | ||
| 266 | 308 | ||
| 267 | /* If arguments are supplied, we may have to encode them. */ | 309 | /* If arguments are supplied, we may have to encode them. */ |
| 268 | if (nargs >= 5) | 310 | if (nargs >= 5) |
| @@ -301,24 +343,16 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) * | |||
| 301 | } | 343 | } |
| 302 | } | 344 | } |
| 303 | 345 | ||
| 304 | if (nargs >= 2 && ! NILP (args[1])) | 346 | if (nargs < 3) |
| 305 | { | 347 | buffer = Qnil; |
| 306 | infile = Fexpand_file_name (args[1], BVAR (current_buffer, directory)); | ||
| 307 | CHECK_STRING (infile); | ||
| 308 | } | ||
| 309 | else | 348 | else |
| 310 | infile = build_string (NULL_DEVICE); | ||
| 311 | |||
| 312 | if (nargs >= 3) | ||
| 313 | { | 349 | { |
| 314 | buffer = args[2]; | 350 | buffer = args[2]; |
| 315 | 351 | ||
| 316 | /* If BUFFER is a list, its meaning is (BUFFER-FOR-STDOUT | 352 | /* If BUFFER is a list, its meaning is (BUFFER-FOR-STDOUT |
| 317 | FILE-FOR-STDERR), unless the first element is :file, in which case see | 353 | FILE-FOR-STDERR), unless the first element is :file, in which case see |
| 318 | the next paragraph. */ | 354 | the next paragraph. */ |
| 319 | if (CONSP (buffer) | 355 | if (CONSP (buffer) && !EQ (XCAR (buffer), QCfile)) |
| 320 | && (! SYMBOLP (XCAR (buffer)) | ||
| 321 | || strcmp (SSDATA (SYMBOL_NAME (XCAR (buffer))), ":file"))) | ||
| 322 | { | 356 | { |
| 323 | if (CONSP (XCDR (buffer))) | 357 | if (CONSP (XCDR (buffer))) |
| 324 | { | 358 | { |
| @@ -335,9 +369,7 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) * | |||
| 335 | } | 369 | } |
| 336 | 370 | ||
| 337 | /* If the buffer is (still) a list, it might be a (:file "file") spec. */ | 371 | /* If the buffer is (still) a list, it might be a (:file "file") spec. */ |
| 338 | if (CONSP (buffer) | 372 | if (CONSP (buffer) && EQ (XCAR (buffer), QCfile)) |
| 339 | && SYMBOLP (XCAR (buffer)) | ||
| 340 | && ! strcmp (SSDATA (SYMBOL_NAME (XCAR (buffer))), ":file")) | ||
| 341 | { | 373 | { |
| 342 | output_file = Fexpand_file_name (XCAR (XCDR (buffer)), | 374 | output_file = Fexpand_file_name (XCAR (XCDR (buffer)), |
| 343 | BVAR (current_buffer, directory)); | 375 | BVAR (current_buffer, directory)); |
| @@ -345,9 +377,7 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) * | |||
| 345 | buffer = Qnil; | 377 | buffer = Qnil; |
| 346 | } | 378 | } |
| 347 | 379 | ||
| 348 | if (!(EQ (buffer, Qnil) | 380 | if (! (NILP (buffer) || EQ (buffer, Qt) || INTEGERP (buffer))) |
| 349 | || EQ (buffer, Qt) | ||
| 350 | || INTEGERP (buffer))) | ||
| 351 | { | 381 | { |
| 352 | Lisp_Object spec_buffer; | 382 | Lisp_Object spec_buffer; |
| 353 | spec_buffer = buffer; | 383 | spec_buffer = buffer; |
| @@ -358,8 +388,6 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) * | |||
| 358 | CHECK_BUFFER (buffer); | 388 | CHECK_BUFFER (buffer); |
| 359 | } | 389 | } |
| 360 | } | 390 | } |
| 361 | else | ||
| 362 | buffer = Qnil; | ||
| 363 | 391 | ||
| 364 | /* Make sure that the child will be able to chdir to the current | 392 | /* Make sure that the child will be able to chdir to the current |
| 365 | buffer's current directory, or its unhandled equivalent. We | 393 | buffer's current directory, or its unhandled equivalent. We |
| @@ -372,11 +400,11 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) * | |||
| 372 | protected by the caller, so all we really have to worry about is | 400 | protected by the caller, so all we really have to worry about is |
| 373 | buffer. */ | 401 | buffer. */ |
| 374 | { | 402 | { |
| 375 | struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5; | 403 | struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; |
| 376 | 404 | ||
| 377 | current_dir = BVAR (current_buffer, directory); | 405 | current_dir = BVAR (current_buffer, directory); |
| 378 | 406 | ||
| 379 | GCPRO5 (infile, buffer, current_dir, error_file, output_file); | 407 | GCPRO4 (buffer, current_dir, error_file, output_file); |
| 380 | 408 | ||
| 381 | current_dir = Funhandled_file_name_directory (current_dir); | 409 | current_dir = Funhandled_file_name_directory (current_dir); |
| 382 | if (NILP (current_dir)) | 410 | if (NILP (current_dir)) |
| @@ -390,8 +418,6 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) * | |||
| 390 | report_file_error ("Setting current directory", | 418 | report_file_error ("Setting current directory", |
| 391 | BVAR (current_buffer, directory)); | 419 | BVAR (current_buffer, directory)); |
| 392 | 420 | ||
| 393 | if (STRING_MULTIBYTE (infile)) | ||
| 394 | infile = ENCODE_FILE (infile); | ||
| 395 | if (STRING_MULTIBYTE (current_dir)) | 421 | if (STRING_MULTIBYTE (current_dir)) |
| 396 | current_dir = ENCODE_FILE (current_dir); | 422 | current_dir = ENCODE_FILE (current_dir); |
| 397 | if (STRINGP (error_file) && STRING_MULTIBYTE (error_file)) | 423 | if (STRINGP (error_file) && STRING_MULTIBYTE (error_file)) |
| @@ -403,44 +429,23 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) * | |||
| 403 | 429 | ||
| 404 | display_p = INTERACTIVE && nargs >= 4 && !NILP (args[3]); | 430 | display_p = INTERACTIVE && nargs >= 4 && !NILP (args[3]); |
| 405 | 431 | ||
| 406 | filefd = emacs_open (SSDATA (infile), O_RDONLY, 0); | 432 | for (i = 0; i < CALLPROC_FDS; i++) |
| 407 | if (filefd < 0) | 433 | callproc_fd[i] = -1; |
| 408 | { | 434 | #ifdef MSDOS |
| 409 | int open_errno = errno; | 435 | synch_process_tempfile = make_number (0); |
| 410 | report_file_errno ("Opening process input file", DECODE_FILE (infile), | 436 | #endif |
| 411 | open_errno); | 437 | record_unwind_protect_ptr (call_process_kill, callproc_fd); |
| 412 | } | ||
| 413 | |||
| 414 | if (STRINGP (output_file)) | ||
| 415 | { | ||
| 416 | fd_output = emacs_open (SSDATA (output_file), | ||
| 417 | O_WRONLY | O_CREAT | O_TRUNC | O_TEXT, | ||
| 418 | default_output_mode); | ||
| 419 | if (fd_output < 0) | ||
| 420 | { | ||
| 421 | int open_errno = errno; | ||
| 422 | output_file = DECODE_FILE (output_file); | ||
| 423 | report_file_errno ("Opening process output file", | ||
| 424 | output_file, open_errno); | ||
| 425 | } | ||
| 426 | if (STRINGP (error_file) || NILP (error_file)) | ||
| 427 | output_to_buffer = 0; | ||
| 428 | } | ||
| 429 | 438 | ||
| 430 | /* Search for program; barf if not found. */ | 439 | /* Search for program; barf if not found. */ |
| 431 | { | 440 | { |
| 432 | struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; | 441 | struct gcpro gcpro1, gcpro2, gcpro3; |
| 433 | int ok; | 442 | int ok; |
| 434 | 443 | ||
| 435 | GCPRO4 (infile, buffer, current_dir, error_file); | 444 | GCPRO3 (buffer, current_dir, error_file); |
| 436 | ok = openp (Vexec_path, args[0], Vexec_suffixes, &path, make_number (X_OK)); | 445 | ok = openp (Vexec_path, args[0], Vexec_suffixes, &path, make_number (X_OK)); |
| 437 | UNGCPRO; | 446 | UNGCPRO; |
| 438 | if (ok < 0) | 447 | if (ok < 0) |
| 439 | { | 448 | report_file_error ("Searching for program", args[0]); |
| 440 | int openp_errno = errno; | ||
| 441 | emacs_close (filefd); | ||
| 442 | report_file_errno ("Searching for program", args[0], openp_errno); | ||
| 443 | } | ||
| 444 | } | 449 | } |
| 445 | 450 | ||
| 446 | /* If program file name starts with /: for quoting a magic name, | 451 | /* If program file name starts with /: for quoting a magic name, |
| @@ -452,9 +457,9 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) * | |||
| 452 | new_argv = SAFE_ALLOCA ((nargs > 4 ? nargs - 2 : 2) * sizeof *new_argv); | 457 | new_argv = SAFE_ALLOCA ((nargs > 4 ? nargs - 2 : 2) * sizeof *new_argv); |
| 453 | 458 | ||
| 454 | { | 459 | { |
| 455 | struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5; | 460 | struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; |
| 456 | 461 | ||
| 457 | GCPRO5 (infile, buffer, current_dir, path, error_file); | 462 | GCPRO4 (buffer, current_dir, path, error_file); |
| 458 | if (nargs > 4) | 463 | if (nargs > 4) |
| 459 | { | 464 | { |
| 460 | ptrdiff_t i; | 465 | ptrdiff_t i; |
| @@ -479,254 +484,213 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) * | |||
| 479 | UNGCPRO; | 484 | UNGCPRO; |
| 480 | } | 485 | } |
| 481 | 486 | ||
| 482 | #ifdef MSDOS /* MW, July 1993 */ | 487 | discard_output = INTEGERP (buffer) || (NILP (buffer) && NILP (output_file)); |
| 483 | 488 | ||
| 484 | /* If we're redirecting STDOUT to a file, that file is already open | 489 | #ifdef MSDOS |
| 485 | on fd_output. */ | 490 | if (! discard_output && ! STRINGP (output_file)) |
| 486 | if (fd_output < 0) | ||
| 487 | { | 491 | { |
| 488 | if ((outf = egetenv ("TMPDIR"))) | 492 | char const *tmpdir = egetenv ("TMPDIR"); |
| 489 | strcpy (tempfile = alloca (strlen (outf) + 20), outf); | 493 | char const *outf = tmpdir ? tmpdir : ""; |
| 490 | else | 494 | tempfile = alloca (strlen (outf) + 20); |
| 491 | { | 495 | strcpy (tempfile, outf); |
| 492 | tempfile = alloca (20); | ||
| 493 | *tempfile = '\0'; | ||
| 494 | } | ||
| 495 | dostounix_filename (tempfile, 0); | 496 | dostounix_filename (tempfile, 0); |
| 496 | if (*tempfile == '\0' || tempfile[strlen (tempfile) - 1] != '/') | 497 | if (*tempfile == '\0' || tempfile[strlen (tempfile) - 1] != '/') |
| 497 | strcat (tempfile, "/"); | 498 | strcat (tempfile, "/"); |
| 498 | strcat (tempfile, "detmp.XXX"); | 499 | strcat (tempfile, "detmp.XXX"); |
| 499 | mktemp (tempfile); | 500 | mktemp (tempfile); |
| 500 | outfilefd = emacs_open (tempfile, O_WRONLY | O_CREAT | O_TRUNC, | 501 | if (!*tempfile) |
| 501 | S_IREAD | S_IWRITE); | 502 | report_file_error ("Opening process output file", Qnil); |
| 502 | if (outfilefd < 0) | 503 | output_file = build_string (tempfile); |
| 504 | synch_process_tempfile = output_file; | ||
| 505 | } | ||
| 506 | #endif | ||
| 507 | |||
| 508 | if (discard_output) | ||
| 509 | { | ||
| 510 | fd_output = emacs_open (NULL_DEVICE, O_WRONLY, 0); | ||
| 511 | if (fd_output < 0) | ||
| 512 | report_file_error ("Opening null device", Qnil); | ||
| 513 | } | ||
| 514 | else if (STRINGP (output_file)) | ||
| 515 | { | ||
| 516 | fd_output = emacs_open (SSDATA (output_file), | ||
| 517 | O_WRONLY | O_CREAT | O_TRUNC | O_TEXT, | ||
| 518 | default_output_mode); | ||
| 519 | if (fd_output < 0) | ||
| 503 | { | 520 | { |
| 504 | int open_errno = errno; | 521 | int open_errno = errno; |
| 505 | emacs_close (filefd); | 522 | output_file = DECODE_FILE (output_file); |
| 506 | report_file_errno ("Opening process output file", | 523 | report_file_errno ("Opening process output file", |
| 507 | build_string (tempfile), open_errno); | 524 | output_file, open_errno); |
| 508 | } | 525 | } |
| 509 | } | 526 | } |
| 510 | else | 527 | else |
| 511 | outfilefd = fd_output; | ||
| 512 | fd0 = filefd; | ||
| 513 | fd1 = outfilefd; | ||
| 514 | #endif /* MSDOS */ | ||
| 515 | |||
| 516 | if (INTEGERP (buffer)) | ||
| 517 | { | ||
| 518 | fd0 = -1; | ||
| 519 | fd1 = emacs_open (NULL_DEVICE, O_WRONLY, 0); | ||
| 520 | } | ||
| 521 | else | ||
| 522 | { | 528 | { |
| 523 | #ifndef MSDOS | ||
| 524 | int fd[2]; | 529 | int fd[2]; |
| 525 | if (emacs_pipe (fd) != 0) | 530 | if (emacs_pipe (fd) != 0) |
| 526 | { | 531 | report_file_error ("Creating process pipe", Qnil); |
| 527 | int pipe_errno = errno; | 532 | callproc_fd[CALLPROC_PIPEREAD] = fd[0]; |
| 528 | emacs_close (filefd); | 533 | fd_output = fd[1]; |
| 529 | report_file_errno ("Creating process pipe", Qnil, pipe_errno); | ||
| 530 | } | ||
| 531 | fd0 = fd[0]; | ||
| 532 | fd1 = fd[1]; | ||
| 533 | #endif | ||
| 534 | } | 534 | } |
| 535 | callproc_fd[CALLPROC_STDOUT] = fd_output; | ||
| 535 | 536 | ||
| 536 | { | 537 | fd_error = fd_output; |
| 537 | int fd_error = fd1; | ||
| 538 | 538 | ||
| 539 | if (fd_output >= 0) | 539 | if (STRINGP (error_file) || (NILP (error_file) && !discard_output)) |
| 540 | fd1 = fd_output; | 540 | { |
| 541 | 541 | fd_error = emacs_open ((STRINGP (error_file) | |
| 542 | if (NILP (error_file)) | 542 | ? SSDATA (error_file) |
| 543 | fd_error = emacs_open (NULL_DEVICE, O_WRONLY, 0); | 543 | : NULL_DEVICE), |
| 544 | else if (STRINGP (error_file)) | ||
| 545 | fd_error = emacs_open (SSDATA (error_file), | ||
| 546 | O_WRONLY | O_CREAT | O_TRUNC | O_TEXT, | 544 | O_WRONLY | O_CREAT | O_TRUNC | O_TEXT, |
| 547 | default_output_mode); | 545 | default_output_mode); |
| 548 | 546 | if (fd_error < 0) | |
| 549 | if (fd_error < 0) | 547 | { |
| 550 | { | 548 | int open_errno = errno; |
| 551 | int open_errno = errno; | 549 | report_file_errno ("Cannot redirect stderr", |
| 552 | emacs_close (filefd); | 550 | (STRINGP (error_file) |
| 553 | if (fd0 != filefd) | 551 | ? DECODE_FILE (error_file) |
| 554 | emacs_close (fd0); | 552 | : build_string (NULL_DEVICE)), |
| 555 | if (fd1 >= 0) | 553 | open_errno); |
| 556 | emacs_close (fd1); | 554 | } |
| 557 | #ifdef MSDOS | 555 | callproc_fd[CALLPROC_STDERR] = fd_error; |
| 558 | unlink (tempfile); | 556 | } |
| 559 | #endif | ||
| 560 | if (NILP (error_file)) | ||
| 561 | error_file = build_string (NULL_DEVICE); | ||
| 562 | else if (STRINGP (error_file)) | ||
| 563 | error_file = DECODE_FILE (error_file); | ||
| 564 | report_file_errno ("Cannot redirect stderr", error_file, open_errno); | ||
| 565 | } | ||
| 566 | 557 | ||
| 567 | #ifdef MSDOS /* MW, July 1993 */ | 558 | #ifdef MSDOS /* MW, July 1993 */ |
| 568 | /* Note that on MSDOS `child_setup' actually returns the child process | 559 | /* Note that on MSDOS `child_setup' actually returns the child process |
| 569 | exit status, not its PID, so assign it to status below. */ | 560 | exit status, not its PID, so assign it to status below. */ |
| 570 | pid = child_setup (filefd, outfilefd, fd_error, new_argv, 0, current_dir); | 561 | pid = child_setup (filefd, fd_output, fd_error, new_argv, 0, current_dir); |
| 571 | child_errno = errno; | 562 | |
| 572 | 563 | if (pid < 0) | |
| 573 | emacs_close (outfilefd); | 564 | { |
| 574 | if (fd_error != outfilefd) | 565 | child_errno = errno; |
| 575 | emacs_close (fd_error); | 566 | unbind_to (count, Qnil); |
| 576 | if (pid < 0) | 567 | synchronize_system_messages_locale (); |
| 577 | { | 568 | return |
| 578 | synchronize_system_messages_locale (); | 569 | code_convert_string_norecord (build_string (strerror (child_errno)), |
| 579 | return | 570 | Vlocale_coding_system, 0); |
| 580 | code_convert_string_norecord (build_string (strerror (child_errno)), | 571 | } |
| 581 | Vlocale_coding_system, 0); | 572 | status = pid; |
| 582 | } | 573 | |
| 583 | status = pid; | 574 | for (i = 0; i < CALLPROC_FDS; i++) |
| 584 | fd1 = -1; /* No harm in closing that one! */ | 575 | if (0 <= callproc_fd[i]) |
| 585 | if (tempfile) | ||
| 586 | { | 576 | { |
| 587 | /* Since CRLF is converted to LF within `decode_coding', we | 577 | emacs_close (callproc_fd[i]); |
| 588 | can always open a file with binary mode. */ | 578 | callproc_fd[i] = -1; |
| 589 | fd0 = emacs_open (tempfile, O_RDONLY | O_BINARY, 0); | ||
| 590 | if (fd0 < 0) | ||
| 591 | { | ||
| 592 | int open_errno = errno; | ||
| 593 | unlink (tempfile); | ||
| 594 | emacs_close (filefd); | ||
| 595 | report_file_errno ("Cannot re-open temporary file", | ||
| 596 | build_string (tempfile), open_errno); | ||
| 597 | } | ||
| 598 | } | 579 | } |
| 599 | else | 580 | emacs_close (filefd); |
| 600 | fd0 = -1; /* We are not going to read from tempfile. */ | 581 | clear_unwind_protect (count - 1); |
| 582 | |||
| 583 | if (tempfile) | ||
| 584 | { | ||
| 585 | /* Since CRLF is converted to LF within `decode_coding', we | ||
| 586 | can always open a file with binary mode. */ | ||
| 587 | callproc_fd[CALLPROC_PIPEREAD] = emacs_open (tempfile, | ||
| 588 | O_RDONLY | O_BINARY, 0); | ||
| 589 | if (callproc_fd[CALLPROC_PIPEREAD] < 0) | ||
| 590 | { | ||
| 591 | int open_errno = errno; | ||
| 592 | report_file_errno ("Cannot re-open temporary file", | ||
| 593 | build_string (tempfile), open_errno); | ||
| 594 | } | ||
| 595 | } | ||
| 596 | |||
| 601 | #endif /* MSDOS */ | 597 | #endif /* MSDOS */ |
| 602 | 598 | ||
| 603 | /* Do the unwind-protect now, even though the pid is not known, so | 599 | /* Do the unwind-protect now, even though the pid is not known, so |
| 604 | that no storage allocation is done in the critical section. | 600 | that no storage allocation is done in the critical section. |
| 605 | The actual PID will be filled in during the critical section. */ | 601 | The actual PID will be filled in during the critical section. */ |
| 606 | synch_process_pid = 0; | 602 | record_unwind_protect (call_process_cleanup, Fcurrent_buffer ()); |
| 607 | synch_process_fd = fd0; | ||
| 608 | 603 | ||
| 609 | #ifdef MSDOS | 604 | #ifndef MSDOS |
| 610 | /* MSDOS needs different cleanup information. */ | ||
| 611 | record_unwind_protect (call_process_cleanup, | ||
| 612 | Fcons (Fcurrent_buffer (), | ||
| 613 | build_string (tempfile ? tempfile : ""))); | ||
| 614 | #else | ||
| 615 | record_unwind_protect (call_process_cleanup, Fcurrent_buffer ()); | ||
| 616 | 605 | ||
| 617 | block_input (); | 606 | block_input (); |
| 618 | block_child_signal (); | 607 | block_child_signal (); |
| 619 | 608 | ||
| 620 | #ifdef WINDOWSNT | 609 | #ifdef WINDOWSNT |
| 621 | pid = child_setup (filefd, fd1, fd_error, new_argv, 0, current_dir); | 610 | pid = child_setup (filefd, fd_output, fd_error, new_argv, 0, current_dir); |
| 622 | /* We need to record the input file of this child, for when we are | ||
| 623 | called from call-process-region to create an async subprocess. | ||
| 624 | That's because call-process-region's unwind procedure will | ||
| 625 | attempt to delete the temporary input file, which will fail | ||
| 626 | because that file is still in use. Recording it with the child | ||
| 627 | will allow us to delete the file when the subprocess exits. | ||
| 628 | The second part of this is in delete_temp_file, q.v. */ | ||
| 629 | if (pid > 0 && INTEGERP (buffer) && nargs >= 2 && !NILP (args[1])) | ||
| 630 | record_infile (pid, xstrdup (SSDATA (infile))); | ||
| 631 | #else /* not WINDOWSNT */ | 611 | #else /* not WINDOWSNT */ |
| 632 | 612 | ||
| 633 | /* vfork, and prevent local vars from being clobbered by the vfork. */ | 613 | /* vfork, and prevent local vars from being clobbered by the vfork. */ |
| 634 | { | 614 | { |
| 635 | Lisp_Object volatile buffer_volatile = buffer; | 615 | Lisp_Object volatile buffer_volatile = buffer; |
| 636 | Lisp_Object volatile coding_systems_volatile = coding_systems; | 616 | Lisp_Object volatile coding_systems_volatile = coding_systems; |
| 637 | Lisp_Object volatile current_dir_volatile = current_dir; | 617 | Lisp_Object volatile current_dir_volatile = current_dir; |
| 638 | bool volatile display_p_volatile = display_p; | 618 | bool volatile display_p_volatile = display_p; |
| 639 | bool volatile output_to_buffer_volatile = output_to_buffer; | 619 | bool volatile sa_must_free_volatile = sa_must_free; |
| 640 | bool volatile sa_must_free_volatile = sa_must_free; | 620 | int volatile fd_error_volatile = fd_error; |
| 641 | int volatile fd1_volatile = fd1; | 621 | int volatile filefd_volatile = filefd; |
| 642 | int volatile fd_error_volatile = fd_error; | 622 | ptrdiff_t volatile count_volatile = count; |
| 643 | int volatile fd_output_volatile = fd_output; | 623 | ptrdiff_t volatile sa_count_volatile = sa_count; |
| 644 | int volatile filefd_volatile = filefd; | 624 | char **volatile new_argv_volatile = new_argv; |
| 645 | ptrdiff_t volatile count_volatile = count; | 625 | int volatile callproc_fd_volatile[CALLPROC_FDS]; |
| 646 | ptrdiff_t volatile sa_count_volatile = sa_count; | 626 | for (i = 0; i < CALLPROC_FDS; i++) |
| 647 | char **volatile new_argv_volatile = new_argv; | 627 | callproc_fd_volatile[i] = callproc_fd[i]; |
| 648 | 628 | ||
| 649 | pid = vfork (); | 629 | pid = vfork (); |
| 650 | child_errno = errno; | 630 | |
| 651 | 631 | buffer = buffer_volatile; | |
| 652 | buffer = buffer_volatile; | 632 | coding_systems = coding_systems_volatile; |
| 653 | coding_systems = coding_systems_volatile; | 633 | current_dir = current_dir_volatile; |
| 654 | current_dir = current_dir_volatile; | 634 | display_p = display_p_volatile; |
| 655 | display_p = display_p_volatile; | 635 | sa_must_free = sa_must_free_volatile; |
| 656 | output_to_buffer = output_to_buffer_volatile; | 636 | fd_error = fd_error_volatile; |
| 657 | sa_must_free = sa_must_free_volatile; | 637 | filefd = filefd_volatile; |
| 658 | fd1 = fd1_volatile; | 638 | count = count_volatile; |
| 659 | fd_error = fd_error_volatile; | 639 | sa_count = sa_count_volatile; |
| 660 | fd_output = fd_output_volatile; | 640 | new_argv = new_argv_volatile; |
| 661 | filefd = filefd_volatile; | 641 | |
| 662 | count = count_volatile; | 642 | for (i = 0; i < CALLPROC_FDS; i++) |
| 663 | sa_count = sa_count_volatile; | 643 | callproc_fd[i] = callproc_fd_volatile[i]; |
| 664 | new_argv = new_argv_volatile; | 644 | fd_output = callproc_fd[CALLPROC_STDOUT]; |
| 665 | 645 | } | |
| 666 | fd0 = synch_process_fd; | ||
| 667 | } | ||
| 668 | |||
| 669 | if (pid == 0) | ||
| 670 | { | ||
| 671 | unblock_child_signal (); | ||
| 672 | 646 | ||
| 673 | if (fd0 >= 0) | 647 | if (pid == 0) |
| 674 | emacs_close (fd0); | 648 | { |
| 649 | unblock_child_signal (); | ||
| 675 | 650 | ||
| 676 | setsid (); | 651 | setsid (); |
| 677 | 652 | ||
| 678 | /* Emacs ignores SIGPIPE, but the child should not. */ | 653 | /* Emacs ignores SIGPIPE, but the child should not. */ |
| 679 | signal (SIGPIPE, SIG_DFL); | 654 | signal (SIGPIPE, SIG_DFL); |
| 680 | 655 | ||
| 681 | child_setup (filefd, fd1, fd_error, new_argv, 0, current_dir); | 656 | child_setup (filefd, fd_output, fd_error, new_argv, 0, current_dir); |
| 682 | } | 657 | } |
| 683 | 658 | ||
| 684 | #endif /* not WINDOWSNT */ | 659 | #endif /* not WINDOWSNT */ |
| 685 | 660 | ||
| 686 | child_errno = errno; | 661 | child_errno = errno; |
| 687 | 662 | ||
| 688 | if (pid > 0) | 663 | if (pid > 0) |
| 689 | { | 664 | synch_process_pid = pid; |
| 690 | if (INTEGERP (buffer)) | ||
| 691 | record_deleted_pid (pid); | ||
| 692 | else | ||
| 693 | synch_process_pid = pid; | ||
| 694 | } | ||
| 695 | 665 | ||
| 696 | unblock_child_signal (); | 666 | unblock_child_signal (); |
| 697 | unblock_input (); | 667 | unblock_input (); |
| 698 | 668 | ||
| 699 | /* The MSDOS case did this already. */ | ||
| 700 | if (fd_error >= 0) | ||
| 701 | emacs_close (fd_error); | ||
| 702 | #endif /* not MSDOS */ | 669 | #endif /* not MSDOS */ |
| 703 | 670 | ||
| 704 | /* Close most of our file descriptors, but not fd0 | ||
| 705 | since we will use that to read input from. */ | ||
| 706 | emacs_close (filefd); | ||
| 707 | if (fd_output >= 0) | ||
| 708 | emacs_close (fd_output); | ||
| 709 | if (fd1 >= 0 && fd1 != fd_error) | ||
| 710 | emacs_close (fd1); | ||
| 711 | } | ||
| 712 | |||
| 713 | if (pid < 0) | 671 | if (pid < 0) |
| 714 | report_file_errno ("Doing vfork", Qnil, child_errno); | 672 | report_file_errno ("Doing vfork", Qnil, child_errno); |
| 715 | 673 | ||
| 674 | /* Close our file descriptors, except for callproc_fd[CALLPROC_PIPEREAD] | ||
| 675 | since we will use that to read input from. */ | ||
| 676 | for (i = 0; i < CALLPROC_FDS; i++) | ||
| 677 | if (i != CALLPROC_PIPEREAD && 0 <= callproc_fd[i]) | ||
| 678 | { | ||
| 679 | emacs_close (callproc_fd[i]); | ||
| 680 | callproc_fd[i] = -1; | ||
| 681 | } | ||
| 682 | emacs_close (filefd); | ||
| 683 | clear_unwind_protect (count - 1); | ||
| 684 | |||
| 716 | if (INTEGERP (buffer)) | 685 | if (INTEGERP (buffer)) |
| 717 | return unbind_to (count, Qnil); | 686 | return unbind_to (count, Qnil); |
| 718 | 687 | ||
| 719 | if (BUFFERP (buffer)) | 688 | if (BUFFERP (buffer)) |
| 720 | Fset_buffer (buffer); | 689 | Fset_buffer (buffer); |
| 721 | 690 | ||
| 722 | if (NILP (buffer)) | 691 | fd0 = callproc_fd[CALLPROC_PIPEREAD]; |
| 723 | { | 692 | |
| 724 | /* If BUFFER is nil, we must read process output once and then | 693 | if (0 <= fd0) |
| 725 | discard it, so setup coding system but with nil. */ | ||
| 726 | setup_coding_system (Qnil, &process_coding); | ||
| 727 | process_coding.dst_multibyte = 0; | ||
| 728 | } | ||
| 729 | else | ||
| 730 | { | 694 | { |
| 731 | Lisp_Object val, *args2; | 695 | Lisp_Object val, *args2; |
| 732 | 696 | ||
| @@ -762,13 +726,13 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) * | |||
| 762 | setup_coding_system (val, &process_coding); | 726 | setup_coding_system (val, &process_coding); |
| 763 | process_coding.dst_multibyte | 727 | process_coding.dst_multibyte |
| 764 | = ! NILP (BVAR (current_buffer, enable_multibyte_characters)); | 728 | = ! NILP (BVAR (current_buffer, enable_multibyte_characters)); |
| 729 | process_coding.src_multibyte = 0; | ||
| 765 | } | 730 | } |
| 766 | process_coding.src_multibyte = 0; | ||
| 767 | 731 | ||
| 768 | immediate_quit = 1; | 732 | immediate_quit = 1; |
| 769 | QUIT; | 733 | QUIT; |
| 770 | 734 | ||
| 771 | if (output_to_buffer) | 735 | if (0 <= fd0) |
| 772 | { | 736 | { |
| 773 | enum { CALLPROC_BUFFER_SIZE_MIN = 16 * 1024 }; | 737 | enum { CALLPROC_BUFFER_SIZE_MIN = 16 * 1024 }; |
| 774 | enum { CALLPROC_BUFFER_SIZE_MAX = 4 * CALLPROC_BUFFER_SIZE_MIN }; | 738 | enum { CALLPROC_BUFFER_SIZE_MAX = 4 * CALLPROC_BUFFER_SIZE_MIN }; |
| @@ -779,9 +743,8 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) * | |||
| 779 | EMACS_INT total_read = 0; | 743 | EMACS_INT total_read = 0; |
| 780 | int carryover = 0; | 744 | int carryover = 0; |
| 781 | bool display_on_the_fly = display_p; | 745 | bool display_on_the_fly = display_p; |
| 782 | struct coding_system saved_coding; | 746 | struct coding_system saved_coding = process_coding; |
| 783 | 747 | ||
| 784 | saved_coding = process_coding; | ||
| 785 | while (1) | 748 | while (1) |
| 786 | { | 749 | { |
| 787 | /* Repeatedly read until we've filled as much as possible | 750 | /* Repeatedly read until we've filled as much as possible |
| @@ -812,58 +775,54 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) * | |||
| 812 | /* Now NREAD is the total amount of data in the buffer. */ | 775 | /* Now NREAD is the total amount of data in the buffer. */ |
| 813 | immediate_quit = 0; | 776 | immediate_quit = 0; |
| 814 | 777 | ||
| 815 | if (!NILP (buffer)) | 778 | if (NILP (BVAR (current_buffer, enable_multibyte_characters)) |
| 816 | { | 779 | && ! CODING_MAY_REQUIRE_DECODING (&process_coding)) |
| 817 | if (NILP (BVAR (current_buffer, enable_multibyte_characters)) | 780 | insert_1_both (buf, nread, nread, 0, 1, 0); |
| 818 | && ! CODING_MAY_REQUIRE_DECODING (&process_coding)) | 781 | else |
| 819 | insert_1_both (buf, nread, nread, 0, 1, 0); | 782 | { /* We have to decode the input. */ |
| 820 | else | 783 | Lisp_Object curbuf; |
| 821 | { /* We have to decode the input. */ | 784 | ptrdiff_t count1 = SPECPDL_INDEX (); |
| 822 | Lisp_Object curbuf; | 785 | |
| 823 | ptrdiff_t count1 = SPECPDL_INDEX (); | 786 | XSETBUFFER (curbuf, current_buffer); |
| 824 | 787 | /* We cannot allow after-change-functions be run | |
| 825 | XSETBUFFER (curbuf, current_buffer); | 788 | during decoding, because that might modify the |
| 826 | /* We cannot allow after-change-functions be run | 789 | buffer, while we rely on process_coding.produced to |
| 827 | during decoding, because that might modify the | 790 | faithfully reflect inserted text until we |
| 828 | buffer, while we rely on process_coding.produced to | 791 | TEMP_SET_PT_BOTH below. */ |
| 829 | faithfully reflect inserted text until we | 792 | specbind (Qinhibit_modification_hooks, Qt); |
| 830 | TEMP_SET_PT_BOTH below. */ | 793 | decode_coding_c_string (&process_coding, |
| 831 | specbind (Qinhibit_modification_hooks, Qt); | 794 | (unsigned char *) buf, nread, curbuf); |
| 832 | decode_coding_c_string (&process_coding, | 795 | unbind_to (count1, Qnil); |
| 833 | (unsigned char *) buf, nread, curbuf); | 796 | if (display_on_the_fly |
| 834 | unbind_to (count1, Qnil); | 797 | && CODING_REQUIRE_DETECTION (&saved_coding) |
| 835 | if (display_on_the_fly | 798 | && ! CODING_REQUIRE_DETECTION (&process_coding)) |
| 836 | && CODING_REQUIRE_DETECTION (&saved_coding) | 799 | { |
| 837 | && ! CODING_REQUIRE_DETECTION (&process_coding)) | 800 | /* We have detected some coding system, but the |
| 838 | { | 801 | detection may have been via insufficient data. |
| 839 | /* We have detected some coding system. But, | 802 | So give up displaying on the fly. */ |
| 840 | there's a possibility that the detection was | 803 | if (process_coding.produced > 0) |
| 841 | done by insufficient data. So, we give up | 804 | del_range_2 (process_coding.dst_pos, |
| 842 | displaying on the fly. */ | 805 | process_coding.dst_pos_byte, |
| 843 | if (process_coding.produced > 0) | 806 | (process_coding.dst_pos |
| 844 | del_range_2 (process_coding.dst_pos, | 807 | + process_coding.produced_char), |
| 845 | process_coding.dst_pos_byte, | 808 | (process_coding.dst_pos_byte |
| 846 | process_coding.dst_pos | 809 | + process_coding.produced), |
| 847 | + process_coding.produced_char, | 810 | 0); |
| 848 | process_coding.dst_pos_byte | 811 | display_on_the_fly = 0; |
| 849 | + process_coding.produced, 0); | 812 | process_coding = saved_coding; |
| 850 | display_on_the_fly = 0; | 813 | carryover = nread; |
| 851 | process_coding = saved_coding; | 814 | /* Make the above condition always fail in the future. */ |
| 852 | carryover = nread; | 815 | saved_coding.common_flags |
| 853 | /* This is to make the above condition always | 816 | &= ~CODING_REQUIRE_DETECTION_MASK; |
| 854 | fails in the future. */ | 817 | continue; |
| 855 | saved_coding.common_flags | ||
| 856 | &= ~CODING_REQUIRE_DETECTION_MASK; | ||
| 857 | continue; | ||
| 858 | } | ||
| 859 | |||
| 860 | TEMP_SET_PT_BOTH (PT + process_coding.produced_char, | ||
| 861 | PT_BYTE + process_coding.produced); | ||
| 862 | carryover = process_coding.carryover_bytes; | ||
| 863 | if (carryover > 0) | ||
| 864 | memcpy (buf, process_coding.carryover, | ||
| 865 | process_coding.carryover_bytes); | ||
| 866 | } | 818 | } |
| 819 | |||
| 820 | TEMP_SET_PT_BOTH (PT + process_coding.produced_char, | ||
| 821 | PT_BYTE + process_coding.produced); | ||
| 822 | carryover = process_coding.carryover_bytes; | ||
| 823 | if (carryover > 0) | ||
| 824 | memcpy (buf, process_coding.carryover, | ||
| 825 | process_coding.carryover_bytes); | ||
| 867 | } | 826 | } |
| 868 | 827 | ||
| 869 | if (process_coding.mode & CODING_MODE_LAST_BLOCK) | 828 | if (process_coding.mode & CODING_MODE_LAST_BLOCK) |
| @@ -882,7 +841,7 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) * | |||
| 882 | first = 0; | 841 | first = 0; |
| 883 | redisplay_preserve_echo_area (1); | 842 | redisplay_preserve_echo_area (1); |
| 884 | /* This variable might have been set to 0 for code | 843 | /* This variable might have been set to 0 for code |
| 885 | detection. In that case, we set it back to 1 because | 844 | detection. In that case, set it back to 1 because |
| 886 | we should have already detected a coding system. */ | 845 | we should have already detected a coding system. */ |
| 887 | display_on_the_fly = 1; | 846 | display_on_the_fly = 1; |
| 888 | } | 847 | } |
| @@ -901,7 +860,7 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) * | |||
| 901 | 860 | ||
| 902 | #ifndef MSDOS | 861 | #ifndef MSDOS |
| 903 | /* Wait for it to terminate, unless it already has. */ | 862 | /* Wait for it to terminate, unless it already has. */ |
| 904 | wait_for_termination (pid, &status, !output_to_buffer); | 863 | wait_for_termination (pid, &status, fd0 < 0); |
| 905 | #endif | 864 | #endif |
| 906 | 865 | ||
| 907 | immediate_quit = 0; | 866 | immediate_quit = 0; |
| @@ -931,37 +890,18 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) * | |||
| 931 | return make_number (WEXITSTATUS (status)); | 890 | return make_number (WEXITSTATUS (status)); |
| 932 | } | 891 | } |
| 933 | 892 | ||
| 934 | static void | ||
| 935 | delete_temp_file (Lisp_Object name) | ||
| 936 | { | ||
| 937 | /* Suppress jka-compr handling, etc. */ | ||
| 938 | ptrdiff_t count = SPECPDL_INDEX (); | ||
| 939 | specbind (intern ("file-name-handler-alist"), Qnil); | ||
| 940 | #ifdef WINDOWSNT | ||
| 941 | /* If this is called when the subprocess didn't exit yet, the | ||
| 942 | attempt to delete its input file will fail. In that case, we | ||
| 943 | schedule the file for deletion when the subprocess exits. This | ||
| 944 | is the 2nd part of handling this situation; see the call to | ||
| 945 | record_infile in call-process above, for the first part. */ | ||
| 946 | if (!internal_delete_file (name)) | ||
| 947 | { | ||
| 948 | Lisp_Object encoded_file = ENCODE_FILE (name); | ||
| 949 | |||
| 950 | record_pending_deletion (SSDATA (encoded_file)); | ||
| 951 | } | ||
| 952 | #else | ||
| 953 | internal_delete_file (name); | ||
| 954 | #endif | ||
| 955 | unbind_to (count, Qnil); | ||
| 956 | } | ||
| 957 | |||
| 958 | /* Create a temporary file suitable for storing the input data of | 893 | /* Create a temporary file suitable for storing the input data of |
| 959 | call-process-region. NARGS and ARGS are the same as for | 894 | call-process-region. NARGS and ARGS are the same as for |
| 960 | call-process-region. */ | 895 | call-process-region. Store into *FILENAME_STRING_PTR a Lisp string |
| 896 | naming the file, and return a file descriptor for reading. | ||
| 897 | Unwind-protect the file, so that the file descriptor will be closed | ||
| 898 | and the file removed when the caller unwinds the specpdl stack. */ | ||
| 961 | 899 | ||
| 962 | static Lisp_Object | 900 | static int |
| 963 | create_temp_file (ptrdiff_t nargs, Lisp_Object *args) | 901 | create_temp_file (ptrdiff_t nargs, Lisp_Object *args, |
| 902 | Lisp_Object *filename_string_ptr) | ||
| 964 | { | 903 | { |
| 904 | int fd; | ||
| 965 | struct gcpro gcpro1; | 905 | struct gcpro gcpro1; |
| 966 | Lisp_Object filename_string; | 906 | Lisp_Object filename_string; |
| 967 | Lisp_Object val, start, end; | 907 | Lisp_Object val, start, end; |
| @@ -988,6 +928,7 @@ create_temp_file (ptrdiff_t nargs, Lisp_Object *args) | |||
| 988 | { | 928 | { |
| 989 | Lisp_Object pattern = Fexpand_file_name (Vtemp_file_name_pattern, tmpdir); | 929 | Lisp_Object pattern = Fexpand_file_name (Vtemp_file_name_pattern, tmpdir); |
| 990 | char *tempfile; | 930 | char *tempfile; |
| 931 | ptrdiff_t count; | ||
| 991 | 932 | ||
| 992 | #ifdef WINDOWSNT | 933 | #ifdef WINDOWSNT |
| 993 | /* Cannot use the result of Fexpand_file_name, because it | 934 | /* Cannot use the result of Fexpand_file_name, because it |
| @@ -1008,15 +949,14 @@ create_temp_file (ptrdiff_t nargs, Lisp_Object *args) | |||
| 1008 | GCPRO1 (filename_string); | 949 | GCPRO1 (filename_string); |
| 1009 | tempfile = SSDATA (filename_string); | 950 | tempfile = SSDATA (filename_string); |
| 1010 | 951 | ||
| 1011 | { | 952 | count = SPECPDL_INDEX (); |
| 1012 | int fd = mkostemp (tempfile, O_CLOEXEC); | 953 | record_unwind_protect_nothing (); |
| 1013 | if (fd < 0) | 954 | fd = mkostemp (tempfile, O_CLOEXEC); |
| 1014 | report_file_error ("Failed to open temporary file using pattern", | 955 | if (fd < 0) |
| 1015 | pattern); | 956 | report_file_error ("Failed to open temporary file using pattern", |
| 1016 | emacs_close (fd); | 957 | pattern); |
| 1017 | } | 958 | set_unwind_protect (count, delete_temp_file, filename_string); |
| 1018 | 959 | record_unwind_protect_int (close_file_unwind, fd); | |
| 1019 | record_unwind_protect (delete_temp_file, filename_string); | ||
| 1020 | } | 960 | } |
| 1021 | 961 | ||
| 1022 | start = args[0]; | 962 | start = args[0]; |
| @@ -1047,15 +987,20 @@ create_temp_file (ptrdiff_t nargs, Lisp_Object *args) | |||
| 1047 | /* POSIX lets mk[s]temp use "."; don't invoke jka-compr if we | 987 | /* POSIX lets mk[s]temp use "."; don't invoke jka-compr if we |
| 1048 | happen to get a ".Z" suffix. */ | 988 | happen to get a ".Z" suffix. */ |
| 1049 | specbind (intern ("file-name-handler-alist"), Qnil); | 989 | specbind (intern ("file-name-handler-alist"), Qnil); |
| 1050 | Fwrite_region (start, end, filename_string, Qnil, Qlambda, Qnil, Qnil); | 990 | write_region (start, end, filename_string, Qnil, Qlambda, Qnil, Qnil, fd); |
| 1051 | 991 | ||
| 1052 | unbind_to (count1, Qnil); | 992 | unbind_to (count1, Qnil); |
| 1053 | } | 993 | } |
| 1054 | 994 | ||
| 995 | if (lseek (fd, 0, SEEK_SET) < 0) | ||
| 996 | report_file_error ("Setting file position", filename_string); | ||
| 997 | |||
| 1055 | /* Note that Fcall_process takes care of binding | 998 | /* Note that Fcall_process takes care of binding |
| 1056 | coding-system-for-read. */ | 999 | coding-system-for-read. */ |
| 1057 | 1000 | ||
| 1058 | RETURN_UNGCPRO (filename_string); | 1001 | *filename_string_ptr = filename_string; |
| 1002 | UNGCPRO; | ||
| 1003 | return fd; | ||
| 1059 | } | 1004 | } |
| 1060 | 1005 | ||
| 1061 | DEFUN ("call-process-region", Fcall_process_region, Scall_process_region, | 1006 | DEFUN ("call-process-region", Fcall_process_region, Scall_process_region, |
| @@ -1085,12 +1030,13 @@ If you quit, the process is killed with SIGINT, or SIGKILL if you quit again. | |||
| 1085 | usage: (call-process-region START END PROGRAM &optional DELETE BUFFER DISPLAY &rest ARGS) */) | 1030 | usage: (call-process-region START END PROGRAM &optional DELETE BUFFER DISPLAY &rest ARGS) */) |
| 1086 | (ptrdiff_t nargs, Lisp_Object *args) | 1031 | (ptrdiff_t nargs, Lisp_Object *args) |
| 1087 | { | 1032 | { |
| 1088 | struct gcpro gcpro1; | 1033 | struct gcpro gcpro1, gcpro2; |
| 1089 | Lisp_Object infile; | 1034 | Lisp_Object infile, val; |
| 1090 | ptrdiff_t count = SPECPDL_INDEX (); | 1035 | ptrdiff_t count = SPECPDL_INDEX (); |
| 1091 | Lisp_Object start = args[0]; | 1036 | Lisp_Object start = args[0]; |
| 1092 | Lisp_Object end = args[1]; | 1037 | Lisp_Object end = args[1]; |
| 1093 | bool empty_input; | 1038 | bool empty_input; |
| 1039 | int fd; | ||
| 1094 | 1040 | ||
| 1095 | if (STRINGP (start)) | 1041 | if (STRINGP (start)) |
| 1096 | empty_input = SCHARS (start) == 0; | 1042 | empty_input = SCHARS (start) == 0; |
| @@ -1104,8 +1050,19 @@ usage: (call-process-region START END PROGRAM &optional DELETE BUFFER DISPLAY &r | |||
| 1104 | empty_input = XINT (start) == XINT (end); | 1050 | empty_input = XINT (start) == XINT (end); |
| 1105 | } | 1051 | } |
| 1106 | 1052 | ||
| 1107 | infile = empty_input ? Qnil : create_temp_file (nargs, args); | 1053 | if (!empty_input) |
| 1108 | GCPRO1 (infile); | 1054 | fd = create_temp_file (nargs, args, &infile); |
| 1055 | else | ||
| 1056 | { | ||
| 1057 | infile = Qnil; | ||
| 1058 | fd = emacs_open (NULL_DEVICE, O_RDONLY, 0); | ||
| 1059 | if (fd < 0) | ||
| 1060 | report_file_error ("Opening null device", Qnil); | ||
| 1061 | record_unwind_protect_int (close_file_unwind, fd); | ||
| 1062 | } | ||
| 1063 | |||
| 1064 | val = infile; | ||
| 1065 | GCPRO2 (infile, val); | ||
| 1109 | 1066 | ||
| 1110 | if (nargs > 3 && !NILP (args[3])) | 1067 | if (nargs > 3 && !NILP (args[3])) |
| 1111 | Fdelete_region (start, end); | 1068 | Fdelete_region (start, end); |
| @@ -1122,7 +1079,17 @@ usage: (call-process-region START END PROGRAM &optional DELETE BUFFER DISPLAY &r | |||
| 1122 | } | 1079 | } |
| 1123 | args[1] = infile; | 1080 | args[1] = infile; |
| 1124 | 1081 | ||
| 1125 | RETURN_UNGCPRO (unbind_to (count, Fcall_process (nargs, args))); | 1082 | val = call_process (nargs, args, fd); |
| 1083 | |||
| 1084 | if (!empty_input && 4 < nargs | ||
| 1085 | && (INTEGERP (CONSP (args[4]) ? XCAR (args[4]) : args[4]))) | ||
| 1086 | { | ||
| 1087 | record_deleted_pid (synch_process_pid, infile); | ||
| 1088 | synch_process_pid = 0; | ||
| 1089 | clear_unwind_protect (count); | ||
| 1090 | } | ||
| 1091 | |||
| 1092 | RETURN_UNGCPRO (unbind_to (count, val)); | ||
| 1126 | } | 1093 | } |
| 1127 | 1094 | ||
| 1128 | #ifndef WINDOWSNT | 1095 | #ifndef WINDOWSNT |
| @@ -1683,6 +1650,11 @@ syms_of_callproc (void) | |||
| 1683 | #endif | 1650 | #endif |
| 1684 | staticpro (&Vtemp_file_name_pattern); | 1651 | staticpro (&Vtemp_file_name_pattern); |
| 1685 | 1652 | ||
| 1653 | #ifdef MSDOS | ||
| 1654 | synch_process_tempfile = make_number (0); | ||
| 1655 | staticpro (&synch_process_tempfile); | ||
| 1656 | #endif | ||
| 1657 | |||
| 1686 | DEFVAR_LISP ("shell-file-name", Vshell_file_name, | 1658 | DEFVAR_LISP ("shell-file-name", Vshell_file_name, |
| 1687 | doc: /* File name to load inferior shells from. | 1659 | doc: /* File name to load inferior shells from. |
| 1688 | Initialized from the SHELL environment variable, or to a system-dependent | 1660 | Initialized from the SHELL environment variable, or to a system-dependent |