diff options
| author | Joakim Verona | 2013-08-12 12:29:06 +0200 |
|---|---|---|
| committer | Joakim Verona | 2013-08-12 12:29:06 +0200 |
| commit | 5ff84f8a17c73bf63cc7532e14149380d9f83b3f (patch) | |
| tree | 501ac3b99a49aaa25adedc516bb4ea7a34c22a5c /src/callproc.c | |
| parent | c39e73975f7371a6458cd63967d39ba77a1e871a (diff) | |
| parent | 7a67e06b99a85ae700a7ccc75468397d53af59ed (diff) | |
| download | emacs-5ff84f8a17c73bf63cc7532e14149380d9f83b3f.tar.gz emacs-5ff84f8a17c73bf63cc7532e14149380d9f83b3f.zip | |
merge from trunk
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 |