diff options
| author | Xue Fuqiao | 2013-09-04 08:39:34 +0800 |
|---|---|---|
| committer | Xue Fuqiao | 2013-09-04 08:39:34 +0800 |
| commit | adf2fc4a01efe77d73cd52bc9173914ed56ff531 (patch) | |
| tree | a5a280a5554a7bffeaf94fccae29fa3ac1a5d066 /src/callproc.c | |
| parent | 63191d9f2043d2e67657e85a7b3842805dd1dad6 (diff) | |
| parent | 38726039b77db432989fed106c88e9f1aa463281 (diff) | |
| download | emacs-adf2fc4a01efe77d73cd52bc9173914ed56ff531.tar.gz emacs-adf2fc4a01efe77d73cd52bc9173914ed56ff531.zip | |
Merge from mainline.
Diffstat (limited to 'src/callproc.c')
| -rw-r--r-- | src/callproc.c | 840 |
1 files changed, 413 insertions, 427 deletions
diff --git a/src/callproc.c b/src/callproc.c index 450fc57f929..d4b4a26ec3a 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, ptrdiff_t); | ||
| 85 | 106 | ||
| 86 | /* Block SIGCHLD. */ | 107 | /* Block SIGCHLD. */ |
| 87 | 108 | ||
| @@ -102,85 +123,104 @@ unblock_child_signal (void) | |||
| 102 | pthread_sigmask (SIG_SETMASK, &empty_mask, 0); | 123 | pthread_sigmask (SIG_SETMASK, &empty_mask, 0); |
| 103 | } | 124 | } |
| 104 | 125 | ||
| 126 | /* Return the current buffer's working directory, or the home | ||
| 127 | directory if it's unreachable, as a string suitable for a system call. | ||
| 128 | Signal an error if the result would not be an accessible directory. */ | ||
| 129 | |||
| 130 | Lisp_Object | ||
| 131 | encode_current_directory (void) | ||
| 132 | { | ||
| 133 | Lisp_Object dir; | ||
| 134 | struct gcpro gcpro1; | ||
| 135 | |||
| 136 | dir = BVAR (current_buffer, directory); | ||
| 137 | GCPRO1 (dir); | ||
| 138 | |||
| 139 | dir = Funhandled_file_name_directory (dir); | ||
| 140 | |||
| 141 | /* If the file name handler says that dir is unreachable, use | ||
| 142 | a sensible default. */ | ||
| 143 | if (NILP (dir)) | ||
| 144 | dir = build_string ("~"); | ||
| 145 | |||
| 146 | dir = expand_and_dir_to_file (dir, Qnil); | ||
| 147 | |||
| 148 | if (STRING_MULTIBYTE (dir)) | ||
| 149 | dir = ENCODE_FILE (dir); | ||
| 150 | if (! file_accessible_directory_p (SSDATA (dir))) | ||
| 151 | report_file_error ("Setting current directory", | ||
| 152 | BVAR (current_buffer, directory)); | ||
| 153 | |||
| 154 | RETURN_UNGCPRO (dir); | ||
| 155 | } | ||
| 156 | |||
| 105 | /* If P is reapable, record it as a deleted process and kill it. | 157 | /* If P is reapable, record it as a deleted process and kill it. |
| 106 | Do this in a critical section. Unless PID is wedged it will be | 158 | Do this in a critical section. Unless PID is wedged it will be |
| 107 | reaped on receipt of the first SIGCHLD after the critical section. */ | 159 | reaped on receipt of the first SIGCHLD after the critical section. */ |
| 108 | 160 | ||
| 109 | void | 161 | void |
| 110 | record_kill_process (struct Lisp_Process *p) | 162 | record_kill_process (struct Lisp_Process *p, Lisp_Object tempfile) |
| 111 | { | 163 | { |
| 112 | block_child_signal (); | 164 | block_child_signal (); |
| 113 | 165 | ||
| 114 | if (p->alive) | 166 | if (p->alive) |
| 115 | { | 167 | { |
| 168 | record_deleted_pid (p->pid, tempfile); | ||
| 116 | p->alive = 0; | 169 | p->alive = 0; |
| 117 | record_deleted_pid (p->pid); | ||
| 118 | kill (- p->pid, SIGKILL); | 170 | kill (- p->pid, SIGKILL); |
| 119 | } | 171 | } |
| 120 | 172 | ||
| 121 | unblock_child_signal (); | 173 | unblock_child_signal (); |
| 122 | } | 174 | } |
| 123 | 175 | ||
| 124 | /* Clean up when exiting call_process_cleanup. */ | 176 | /* Clean up files, file descriptors and processes created by Fcall_process. */ |
| 177 | |||
| 178 | static void | ||
| 179 | delete_temp_file (Lisp_Object name) | ||
| 180 | { | ||
| 181 | unlink (SSDATA (name)); | ||
| 182 | } | ||
| 125 | 183 | ||
| 126 | static void | 184 | static void |
| 127 | call_process_kill (void) | 185 | call_process_kill (void *ptr) |
| 128 | { | 186 | { |
| 129 | if (synch_process_fd >= 0) | 187 | int *callproc_fd = ptr; |
| 130 | emacs_close (synch_process_fd); | 188 | int i; |
| 189 | for (i = 0; i < CALLPROC_FDS; i++) | ||
| 190 | if (0 <= callproc_fd[i]) | ||
| 191 | emacs_close (callproc_fd[i]); | ||
| 131 | 192 | ||
| 132 | if (synch_process_pid) | 193 | if (synch_process_pid) |
| 133 | { | 194 | { |
| 134 | struct Lisp_Process proc; | 195 | struct Lisp_Process proc; |
| 135 | proc.alive = 1; | 196 | proc.alive = 1; |
| 136 | proc.pid = synch_process_pid; | 197 | proc.pid = synch_process_pid; |
| 137 | record_kill_process (&proc); | 198 | record_kill_process (&proc, synch_process_tempfile); |
| 199 | synch_process_pid = 0; | ||
| 138 | } | 200 | } |
| 201 | else if (STRINGP (synch_process_tempfile)) | ||
| 202 | delete_temp_file (synch_process_tempfile); | ||
| 139 | } | 203 | } |
| 140 | 204 | ||
| 141 | /* Clean up when exiting Fcall_process. | 205 | /* Clean up when exiting Fcall_process: restore the buffer, and |
| 142 | On MSDOS, delete the temporary file on any kind of termination. | 206 | kill the subsidiary process group if the process still exists. */ |
| 143 | On Unix, kill the process and any children on termination by signal. */ | ||
| 144 | 207 | ||
| 145 | static void | 208 | static void |
| 146 | call_process_cleanup (Lisp_Object arg) | 209 | call_process_cleanup (Lisp_Object buffer) |
| 147 | { | 210 | { |
| 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); | 211 | Fset_buffer (buffer); |
| 156 | 212 | ||
| 157 | #ifndef MSDOS | ||
| 158 | /* If the process still exists, kill its process group. */ | ||
| 159 | if (synch_process_pid) | 213 | if (synch_process_pid) |
| 160 | { | 214 | { |
| 161 | ptrdiff_t count = SPECPDL_INDEX (); | ||
| 162 | kill (-synch_process_pid, SIGINT); | 215 | 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)"); | 216 | message1 ("Waiting for process to die...(type C-g again to kill it instantly)"); |
| 165 | immediate_quit = 1; | 217 | immediate_quit = 1; |
| 166 | QUIT; | 218 | QUIT; |
| 167 | wait_for_termination (synch_process_pid, 0, 1); | 219 | wait_for_termination (synch_process_pid, 0, 1); |
| 168 | synch_process_pid = 0; | 220 | synch_process_pid = 0; |
| 169 | immediate_quit = 0; | 221 | immediate_quit = 0; |
| 170 | specpdl_ptr = specpdl + count; /* Discard the unwind protect. */ | ||
| 171 | message1 ("Waiting for process to die...done"); | 222 | message1 ("Waiting for process to die...done"); |
| 172 | } | 223 | } |
| 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 | } | 224 | } |
| 185 | 225 | ||
| 186 | #ifdef DOS_NT | 226 | #ifdef DOS_NT |
| @@ -218,10 +258,48 @@ 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) */) | 258 | usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) */) |
| 219 | (ptrdiff_t nargs, Lisp_Object *args) | 259 | (ptrdiff_t nargs, Lisp_Object *args) |
| 220 | { | 260 | { |
| 221 | Lisp_Object infile, buffer, current_dir, path; | 261 | Lisp_Object infile, encoded_infile; |
| 262 | int filefd; | ||
| 263 | struct gcpro gcpro1; | ||
| 264 | ptrdiff_t count = SPECPDL_INDEX (); | ||
| 265 | |||
| 266 | if (nargs >= 2 && ! NILP (args[1])) | ||
| 267 | { | ||
| 268 | infile = Fexpand_file_name (args[1], BVAR (current_buffer, directory)); | ||
| 269 | CHECK_STRING (infile); | ||
| 270 | } | ||
| 271 | else | ||
| 272 | infile = build_string (NULL_DEVICE); | ||
| 273 | |||
| 274 | GCPRO1 (infile); | ||
| 275 | encoded_infile = STRING_MULTIBYTE (infile) ? ENCODE_FILE (infile) : infile; | ||
| 276 | |||
| 277 | filefd = emacs_open (SSDATA (encoded_infile), O_RDONLY, 0); | ||
| 278 | if (filefd < 0) | ||
| 279 | report_file_error ("Opening process input file", infile); | ||
| 280 | record_unwind_protect_int (close_file_unwind, filefd); | ||
| 281 | UNGCPRO; | ||
| 282 | return unbind_to (count, call_process (nargs, args, filefd, -1)); | ||
| 283 | } | ||
| 284 | |||
| 285 | /* Like Fcall_process (NARGS, ARGS), except use FILEFD as the input file. | ||
| 286 | |||
| 287 | If TEMPFILE_INDEX is nonnegative, it is the specpdl index of an | ||
| 288 | unwinder that is intended to remove the input temporary file; in | ||
| 289 | this case NARGS must be at least 2 and ARGS[1] is the file's name. | ||
| 290 | |||
| 291 | At entry, the specpdl stack top entry must be close_file_unwind (FILEFD). */ | ||
| 292 | |||
| 293 | static Lisp_Object | ||
| 294 | call_process (ptrdiff_t nargs, Lisp_Object *args, int filefd, | ||
| 295 | ptrdiff_t tempfile_index) | ||
| 296 | { | ||
| 297 | Lisp_Object buffer, current_dir, path; | ||
| 222 | bool display_p; | 298 | bool display_p; |
| 223 | int fd0, fd1, filefd; | 299 | int fd0; |
| 300 | int callproc_fd[CALLPROC_FDS]; | ||
| 224 | int status; | 301 | int status; |
| 302 | ptrdiff_t i; | ||
| 225 | ptrdiff_t count = SPECPDL_INDEX (); | 303 | ptrdiff_t count = SPECPDL_INDEX (); |
| 226 | USE_SAFE_ALLOCA; | 304 | USE_SAFE_ALLOCA; |
| 227 | 305 | ||
| @@ -231,19 +309,21 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) * | |||
| 231 | Lisp_Object error_file; | 309 | Lisp_Object error_file; |
| 232 | Lisp_Object output_file = Qnil; | 310 | Lisp_Object output_file = Qnil; |
| 233 | #ifdef MSDOS /* Demacs 1.1.1 91/10/16 HIRANO Satoshi */ | 311 | #ifdef MSDOS /* Demacs 1.1.1 91/10/16 HIRANO Satoshi */ |
| 234 | char *outf, *tempfile = NULL; | 312 | char *tempfile = NULL; |
| 235 | int outfilefd; | ||
| 236 | int pid; | 313 | int pid; |
| 237 | #else | 314 | #else |
| 238 | pid_t pid; | 315 | pid_t pid; |
| 239 | #endif | 316 | #endif |
| 240 | int child_errno; | 317 | int child_errno; |
| 241 | int fd_output = -1; | 318 | int fd_output, fd_error; |
| 242 | struct coding_system process_coding; /* coding-system of process output */ | 319 | struct coding_system process_coding; /* coding-system of process output */ |
| 243 | struct coding_system argument_coding; /* coding-system of arguments */ | 320 | struct coding_system argument_coding; /* coding-system of arguments */ |
| 244 | /* Set to the return value of Ffind_operation_coding_system. */ | 321 | /* Set to the return value of Ffind_operation_coding_system. */ |
| 245 | Lisp_Object coding_systems; | 322 | Lisp_Object coding_systems; |
| 246 | bool output_to_buffer = 1; | 323 | bool discard_output; |
| 324 | |||
| 325 | if (synch_process_pid) | ||
| 326 | error ("call-process invoked recursively"); | ||
| 247 | 327 | ||
| 248 | /* Qt denotes that Ffind_operation_coding_system is not yet called. */ | 328 | /* Qt denotes that Ffind_operation_coding_system is not yet called. */ |
| 249 | coding_systems = Qt; | 329 | coding_systems = Qt; |
| @@ -262,7 +342,6 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) * | |||
| 262 | /* Decide the coding-system for giving arguments. */ | 342 | /* Decide the coding-system for giving arguments. */ |
| 263 | { | 343 | { |
| 264 | Lisp_Object val, *args2; | 344 | Lisp_Object val, *args2; |
| 265 | ptrdiff_t i; | ||
| 266 | 345 | ||
| 267 | /* If arguments are supplied, we may have to encode them. */ | 346 | /* If arguments are supplied, we may have to encode them. */ |
| 268 | if (nargs >= 5) | 347 | if (nargs >= 5) |
| @@ -301,24 +380,16 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) * | |||
| 301 | } | 380 | } |
| 302 | } | 381 | } |
| 303 | 382 | ||
| 304 | if (nargs >= 2 && ! NILP (args[1])) | 383 | if (nargs < 3) |
| 305 | { | 384 | buffer = Qnil; |
| 306 | infile = Fexpand_file_name (args[1], BVAR (current_buffer, directory)); | ||
| 307 | CHECK_STRING (infile); | ||
| 308 | } | ||
| 309 | else | 385 | else |
| 310 | infile = build_string (NULL_DEVICE); | ||
| 311 | |||
| 312 | if (nargs >= 3) | ||
| 313 | { | 386 | { |
| 314 | buffer = args[2]; | 387 | buffer = args[2]; |
| 315 | 388 | ||
| 316 | /* If BUFFER is a list, its meaning is (BUFFER-FOR-STDOUT | 389 | /* 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 | 390 | FILE-FOR-STDERR), unless the first element is :file, in which case see |
| 318 | the next paragraph. */ | 391 | the next paragraph. */ |
| 319 | if (CONSP (buffer) | 392 | if (CONSP (buffer) && !EQ (XCAR (buffer), QCfile)) |
| 320 | && (! SYMBOLP (XCAR (buffer)) | ||
| 321 | || strcmp (SSDATA (SYMBOL_NAME (XCAR (buffer))), ":file"))) | ||
| 322 | { | 393 | { |
| 323 | if (CONSP (XCDR (buffer))) | 394 | if (CONSP (XCDR (buffer))) |
| 324 | { | 395 | { |
| @@ -335,9 +406,7 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) * | |||
| 335 | } | 406 | } |
| 336 | 407 | ||
| 337 | /* If the buffer is (still) a list, it might be a (:file "file") spec. */ | 408 | /* If the buffer is (still) a list, it might be a (:file "file") spec. */ |
| 338 | if (CONSP (buffer) | 409 | if (CONSP (buffer) && EQ (XCAR (buffer), QCfile)) |
| 339 | && SYMBOLP (XCAR (buffer)) | ||
| 340 | && ! strcmp (SSDATA (SYMBOL_NAME (XCAR (buffer))), ":file")) | ||
| 341 | { | 410 | { |
| 342 | output_file = Fexpand_file_name (XCAR (XCDR (buffer)), | 411 | output_file = Fexpand_file_name (XCAR (XCDR (buffer)), |
| 343 | BVAR (current_buffer, directory)); | 412 | BVAR (current_buffer, directory)); |
| @@ -345,9 +414,7 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) * | |||
| 345 | buffer = Qnil; | 414 | buffer = Qnil; |
| 346 | } | 415 | } |
| 347 | 416 | ||
| 348 | if (!(EQ (buffer, Qnil) | 417 | if (! (NILP (buffer) || EQ (buffer, Qt) || INTEGERP (buffer))) |
| 349 | || EQ (buffer, Qt) | ||
| 350 | || INTEGERP (buffer))) | ||
| 351 | { | 418 | { |
| 352 | Lisp_Object spec_buffer; | 419 | Lisp_Object spec_buffer; |
| 353 | spec_buffer = buffer; | 420 | spec_buffer = buffer; |
| @@ -358,8 +425,6 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) * | |||
| 358 | CHECK_BUFFER (buffer); | 425 | CHECK_BUFFER (buffer); |
| 359 | } | 426 | } |
| 360 | } | 427 | } |
| 361 | else | ||
| 362 | buffer = Qnil; | ||
| 363 | 428 | ||
| 364 | /* Make sure that the child will be able to chdir to the current | 429 | /* Make sure that the child will be able to chdir to the current |
| 365 | buffer's current directory, or its unhandled equivalent. We | 430 | buffer's current directory, or its unhandled equivalent. We |
| @@ -372,28 +437,12 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) * | |||
| 372 | protected by the caller, so all we really have to worry about is | 437 | protected by the caller, so all we really have to worry about is |
| 373 | buffer. */ | 438 | buffer. */ |
| 374 | { | 439 | { |
| 375 | struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5; | 440 | struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; |
| 376 | |||
| 377 | current_dir = BVAR (current_buffer, directory); | ||
| 378 | |||
| 379 | GCPRO5 (infile, buffer, current_dir, error_file, output_file); | ||
| 380 | 441 | ||
| 381 | current_dir = Funhandled_file_name_directory (current_dir); | 442 | current_dir = encode_current_directory (); |
| 382 | if (NILP (current_dir)) | ||
| 383 | /* If the file name handler says that current_dir is unreachable, use | ||
| 384 | a sensible default. */ | ||
| 385 | current_dir = build_string ("~/"); | ||
| 386 | current_dir = expand_and_dir_to_file (current_dir, Qnil); | ||
| 387 | current_dir = Ffile_name_as_directory (current_dir); | ||
| 388 | 443 | ||
| 389 | if (NILP (Ffile_accessible_directory_p (current_dir))) | 444 | GCPRO4 (buffer, current_dir, error_file, output_file); |
| 390 | report_file_error ("Setting current directory", | ||
| 391 | BVAR (current_buffer, directory)); | ||
| 392 | 445 | ||
| 393 | if (STRING_MULTIBYTE (infile)) | ||
| 394 | infile = ENCODE_FILE (infile); | ||
| 395 | if (STRING_MULTIBYTE (current_dir)) | ||
| 396 | current_dir = ENCODE_FILE (current_dir); | ||
| 397 | if (STRINGP (error_file) && STRING_MULTIBYTE (error_file)) | 446 | if (STRINGP (error_file) && STRING_MULTIBYTE (error_file)) |
| 398 | error_file = ENCODE_FILE (error_file); | 447 | error_file = ENCODE_FILE (error_file); |
| 399 | if (STRINGP (output_file) && STRING_MULTIBYTE (output_file)) | 448 | if (STRINGP (output_file) && STRING_MULTIBYTE (output_file)) |
| @@ -403,44 +452,23 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) * | |||
| 403 | 452 | ||
| 404 | display_p = INTERACTIVE && nargs >= 4 && !NILP (args[3]); | 453 | display_p = INTERACTIVE && nargs >= 4 && !NILP (args[3]); |
| 405 | 454 | ||
| 406 | filefd = emacs_open (SSDATA (infile), O_RDONLY, 0); | 455 | for (i = 0; i < CALLPROC_FDS; i++) |
| 407 | if (filefd < 0) | 456 | callproc_fd[i] = -1; |
| 408 | { | 457 | #ifdef MSDOS |
| 409 | int open_errno = errno; | 458 | synch_process_tempfile = make_number (0); |
| 410 | report_file_errno ("Opening process input file", DECODE_FILE (infile), | 459 | #endif |
| 411 | open_errno); | 460 | 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 | 461 | ||
| 430 | /* Search for program; barf if not found. */ | 462 | /* Search for program; barf if not found. */ |
| 431 | { | 463 | { |
| 432 | struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; | 464 | struct gcpro gcpro1, gcpro2, gcpro3; |
| 433 | int ok; | 465 | int ok; |
| 434 | 466 | ||
| 435 | GCPRO4 (infile, buffer, current_dir, error_file); | 467 | GCPRO3 (buffer, current_dir, error_file); |
| 436 | ok = openp (Vexec_path, args[0], Vexec_suffixes, &path, make_number (X_OK)); | 468 | ok = openp (Vexec_path, args[0], Vexec_suffixes, &path, make_number (X_OK)); |
| 437 | UNGCPRO; | 469 | UNGCPRO; |
| 438 | if (ok < 0) | 470 | if (ok < 0) |
| 439 | { | 471 | 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 | } | 472 | } |
| 445 | 473 | ||
| 446 | /* If program file name starts with /: for quoting a magic name, | 474 | /* If program file name starts with /: for quoting a magic name, |
| @@ -452,9 +480,9 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) * | |||
| 452 | new_argv = SAFE_ALLOCA ((nargs > 4 ? nargs - 2 : 2) * sizeof *new_argv); | 480 | new_argv = SAFE_ALLOCA ((nargs > 4 ? nargs - 2 : 2) * sizeof *new_argv); |
| 453 | 481 | ||
| 454 | { | 482 | { |
| 455 | struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5; | 483 | struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; |
| 456 | 484 | ||
| 457 | GCPRO5 (infile, buffer, current_dir, path, error_file); | 485 | GCPRO4 (buffer, current_dir, path, error_file); |
| 458 | if (nargs > 4) | 486 | if (nargs > 4) |
| 459 | { | 487 | { |
| 460 | ptrdiff_t i; | 488 | ptrdiff_t i; |
| @@ -479,254 +507,228 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) * | |||
| 479 | UNGCPRO; | 507 | UNGCPRO; |
| 480 | } | 508 | } |
| 481 | 509 | ||
| 482 | #ifdef MSDOS /* MW, July 1993 */ | 510 | discard_output = INTEGERP (buffer) || (NILP (buffer) && NILP (output_file)); |
| 483 | 511 | ||
| 484 | /* If we're redirecting STDOUT to a file, that file is already open | 512 | #ifdef MSDOS |
| 485 | on fd_output. */ | 513 | if (! discard_output && ! STRINGP (output_file)) |
| 486 | if (fd_output < 0) | ||
| 487 | { | 514 | { |
| 488 | if ((outf = egetenv ("TMPDIR"))) | 515 | char const *tmpdir = egetenv ("TMPDIR"); |
| 489 | strcpy (tempfile = alloca (strlen (outf) + 20), outf); | 516 | char const *outf = tmpdir ? tmpdir : ""; |
| 490 | else | 517 | tempfile = alloca (strlen (outf) + 20); |
| 491 | { | 518 | strcpy (tempfile, outf); |
| 492 | tempfile = alloca (20); | ||
| 493 | *tempfile = '\0'; | ||
| 494 | } | ||
| 495 | dostounix_filename (tempfile, 0); | 519 | dostounix_filename (tempfile, 0); |
| 496 | if (*tempfile == '\0' || tempfile[strlen (tempfile) - 1] != '/') | 520 | if (*tempfile == '\0' || tempfile[strlen (tempfile) - 1] != '/') |
| 497 | strcat (tempfile, "/"); | 521 | strcat (tempfile, "/"); |
| 498 | strcat (tempfile, "detmp.XXX"); | 522 | strcat (tempfile, "detmp.XXX"); |
| 499 | mktemp (tempfile); | 523 | mktemp (tempfile); |
| 500 | outfilefd = emacs_open (tempfile, O_WRONLY | O_CREAT | O_TRUNC, | 524 | if (!*tempfile) |
| 501 | S_IREAD | S_IWRITE); | 525 | report_file_error ("Opening process output file", Qnil); |
| 502 | if (outfilefd < 0) | 526 | output_file = build_string (tempfile); |
| 527 | synch_process_tempfile = output_file; | ||
| 528 | } | ||
| 529 | #endif | ||
| 530 | |||
| 531 | if (discard_output) | ||
| 532 | { | ||
| 533 | fd_output = emacs_open (NULL_DEVICE, O_WRONLY, 0); | ||
| 534 | if (fd_output < 0) | ||
| 535 | report_file_error ("Opening null device", Qnil); | ||
| 536 | } | ||
| 537 | else if (STRINGP (output_file)) | ||
| 538 | { | ||
| 539 | fd_output = emacs_open (SSDATA (output_file), | ||
| 540 | O_WRONLY | O_CREAT | O_TRUNC | O_TEXT, | ||
| 541 | default_output_mode); | ||
| 542 | if (fd_output < 0) | ||
| 503 | { | 543 | { |
| 504 | int open_errno = errno; | 544 | int open_errno = errno; |
| 505 | emacs_close (filefd); | 545 | output_file = DECODE_FILE (output_file); |
| 506 | report_file_errno ("Opening process output file", | 546 | report_file_errno ("Opening process output file", |
| 507 | build_string (tempfile), open_errno); | 547 | output_file, open_errno); |
| 508 | } | 548 | } |
| 509 | } | 549 | } |
| 510 | else | 550 | else |
| 511 | outfilefd = fd_output; | ||
| 512 | fd0 = filefd; | ||
| 513 | fd1 = outfilefd; | ||
| 514 | #endif /* MSDOS */ | ||
| 515 | |||
| 516 | if (INTEGERP (buffer)) | ||
| 517 | { | 551 | { |
| 518 | fd0 = -1; | ||
| 519 | fd1 = emacs_open (NULL_DEVICE, O_WRONLY, 0); | ||
| 520 | } | ||
| 521 | else | ||
| 522 | { | ||
| 523 | #ifndef MSDOS | ||
| 524 | int fd[2]; | 552 | int fd[2]; |
| 525 | if (emacs_pipe (fd) != 0) | 553 | if (emacs_pipe (fd) != 0) |
| 526 | { | 554 | report_file_error ("Creating process pipe", Qnil); |
| 527 | int pipe_errno = errno; | 555 | callproc_fd[CALLPROC_PIPEREAD] = fd[0]; |
| 528 | emacs_close (filefd); | 556 | 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 | } | 557 | } |
| 558 | callproc_fd[CALLPROC_STDOUT] = fd_output; | ||
| 535 | 559 | ||
| 536 | { | 560 | fd_error = fd_output; |
| 537 | int fd_error = fd1; | ||
| 538 | 561 | ||
| 539 | if (fd_output >= 0) | 562 | if (STRINGP (error_file) || (NILP (error_file) && !discard_output)) |
| 540 | fd1 = fd_output; | 563 | { |
| 541 | 564 | fd_error = emacs_open ((STRINGP (error_file) | |
| 542 | if (NILP (error_file)) | 565 | ? SSDATA (error_file) |
| 543 | fd_error = emacs_open (NULL_DEVICE, O_WRONLY, 0); | 566 | : 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, | 567 | O_WRONLY | O_CREAT | O_TRUNC | O_TEXT, |
| 547 | default_output_mode); | 568 | default_output_mode); |
| 548 | 569 | if (fd_error < 0) | |
| 549 | if (fd_error < 0) | 570 | { |
| 550 | { | 571 | int open_errno = errno; |
| 551 | int open_errno = errno; | 572 | report_file_errno ("Cannot redirect stderr", |
| 552 | emacs_close (filefd); | 573 | (STRINGP (error_file) |
| 553 | if (fd0 != filefd) | 574 | ? DECODE_FILE (error_file) |
| 554 | emacs_close (fd0); | 575 | : build_string (NULL_DEVICE)), |
| 555 | if (fd1 >= 0) | 576 | open_errno); |
| 556 | emacs_close (fd1); | 577 | } |
| 557 | #ifdef MSDOS | 578 | callproc_fd[CALLPROC_STDERR] = fd_error; |
| 558 | unlink (tempfile); | 579 | } |
| 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 | 580 | ||
| 567 | #ifdef MSDOS /* MW, July 1993 */ | 581 | #ifdef MSDOS /* MW, July 1993 */ |
| 568 | /* Note that on MSDOS `child_setup' actually returns the child process | 582 | /* Note that on MSDOS `child_setup' actually returns the child process |
| 569 | exit status, not its PID, so assign it to status below. */ | 583 | exit status, not its PID, so assign it to status below. */ |
| 570 | pid = child_setup (filefd, outfilefd, fd_error, new_argv, 0, current_dir); | 584 | pid = child_setup (filefd, fd_output, fd_error, new_argv, 0, current_dir); |
| 571 | child_errno = errno; | 585 | |
| 572 | 586 | if (pid < 0) | |
| 573 | emacs_close (outfilefd); | 587 | { |
| 574 | if (fd_error != outfilefd) | 588 | child_errno = errno; |
| 575 | emacs_close (fd_error); | 589 | unbind_to (count, Qnil); |
| 576 | if (pid < 0) | 590 | synchronize_system_messages_locale (); |
| 577 | { | 591 | return |
| 578 | synchronize_system_messages_locale (); | 592 | code_convert_string_norecord (build_string (strerror (child_errno)), |
| 579 | return | 593 | Vlocale_coding_system, 0); |
| 580 | code_convert_string_norecord (build_string (strerror (child_errno)), | 594 | } |
| 581 | Vlocale_coding_system, 0); | 595 | status = pid; |
| 582 | } | 596 | |
| 583 | status = pid; | 597 | for (i = 0; i < CALLPROC_FDS; i++) |
| 584 | fd1 = -1; /* No harm in closing that one! */ | 598 | if (0 <= callproc_fd[i]) |
| 585 | if (tempfile) | ||
| 586 | { | 599 | { |
| 587 | /* Since CRLF is converted to LF within `decode_coding', we | 600 | emacs_close (callproc_fd[i]); |
| 588 | can always open a file with binary mode. */ | 601 | 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 | } | 602 | } |
| 599 | else | 603 | emacs_close (filefd); |
| 600 | fd0 = -1; /* We are not going to read from tempfile. */ | 604 | clear_unwind_protect (count - 1); |
| 605 | |||
| 606 | if (tempfile) | ||
| 607 | { | ||
| 608 | /* Since CRLF is converted to LF within `decode_coding', we | ||
| 609 | can always open a file with binary mode. */ | ||
| 610 | callproc_fd[CALLPROC_PIPEREAD] = emacs_open (tempfile, | ||
| 611 | O_RDONLY | O_BINARY, 0); | ||
| 612 | if (callproc_fd[CALLPROC_PIPEREAD] < 0) | ||
| 613 | { | ||
| 614 | int open_errno = errno; | ||
| 615 | report_file_errno ("Cannot re-open temporary file", | ||
| 616 | build_string (tempfile), open_errno); | ||
| 617 | } | ||
| 618 | } | ||
| 619 | |||
| 601 | #endif /* MSDOS */ | 620 | #endif /* MSDOS */ |
| 602 | 621 | ||
| 603 | /* Do the unwind-protect now, even though the pid is not known, so | 622 | /* Do the unwind-protect now, even though the pid is not known, so |
| 604 | that no storage allocation is done in the critical section. | 623 | that no storage allocation is done in the critical section. |
| 605 | The actual PID will be filled in during the critical section. */ | 624 | The actual PID will be filled in during the critical section. */ |
| 606 | synch_process_pid = 0; | 625 | record_unwind_protect (call_process_cleanup, Fcurrent_buffer ()); |
| 607 | synch_process_fd = fd0; | ||
| 608 | 626 | ||
| 609 | #ifdef MSDOS | 627 | #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 | 628 | ||
| 617 | block_input (); | 629 | block_input (); |
| 618 | block_child_signal (); | 630 | block_child_signal (); |
| 619 | 631 | ||
| 620 | #ifdef WINDOWSNT | 632 | #ifdef WINDOWSNT |
| 621 | pid = child_setup (filefd, fd1, fd_error, new_argv, 0, current_dir); | 633 | 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 */ | 634 | #else /* not WINDOWSNT */ |
| 632 | 635 | ||
| 633 | /* vfork, and prevent local vars from being clobbered by the vfork. */ | 636 | /* vfork, and prevent local vars from being clobbered by the vfork. */ |
| 634 | { | 637 | { |
| 635 | Lisp_Object volatile buffer_volatile = buffer; | 638 | Lisp_Object volatile buffer_volatile = buffer; |
| 636 | Lisp_Object volatile coding_systems_volatile = coding_systems; | 639 | Lisp_Object volatile coding_systems_volatile = coding_systems; |
| 637 | Lisp_Object volatile current_dir_volatile = current_dir; | 640 | Lisp_Object volatile current_dir_volatile = current_dir; |
| 638 | bool volatile display_p_volatile = display_p; | 641 | bool volatile display_p_volatile = display_p; |
| 639 | bool volatile output_to_buffer_volatile = output_to_buffer; | 642 | bool volatile sa_must_free_volatile = sa_must_free; |
| 640 | bool volatile sa_must_free_volatile = sa_must_free; | 643 | int volatile fd_error_volatile = fd_error; |
| 641 | int volatile fd1_volatile = fd1; | 644 | int volatile filefd_volatile = filefd; |
| 642 | int volatile fd_error_volatile = fd_error; | 645 | ptrdiff_t volatile count_volatile = count; |
| 643 | int volatile fd_output_volatile = fd_output; | 646 | ptrdiff_t volatile sa_count_volatile = sa_count; |
| 644 | int volatile filefd_volatile = filefd; | 647 | char **volatile new_argv_volatile = new_argv; |
| 645 | ptrdiff_t volatile count_volatile = count; | 648 | int volatile callproc_fd_volatile[CALLPROC_FDS]; |
| 646 | ptrdiff_t volatile sa_count_volatile = sa_count; | 649 | for (i = 0; i < CALLPROC_FDS; i++) |
| 647 | char **volatile new_argv_volatile = new_argv; | 650 | callproc_fd_volatile[i] = callproc_fd[i]; |
| 648 | 651 | ||
| 649 | pid = vfork (); | 652 | pid = vfork (); |
| 650 | child_errno = errno; | 653 | |
| 651 | 654 | buffer = buffer_volatile; | |
| 652 | buffer = buffer_volatile; | 655 | coding_systems = coding_systems_volatile; |
| 653 | coding_systems = coding_systems_volatile; | 656 | current_dir = current_dir_volatile; |
| 654 | current_dir = current_dir_volatile; | 657 | display_p = display_p_volatile; |
| 655 | display_p = display_p_volatile; | 658 | sa_must_free = sa_must_free_volatile; |
| 656 | output_to_buffer = output_to_buffer_volatile; | 659 | fd_error = fd_error_volatile; |
| 657 | sa_must_free = sa_must_free_volatile; | 660 | filefd = filefd_volatile; |
| 658 | fd1 = fd1_volatile; | 661 | count = count_volatile; |
| 659 | fd_error = fd_error_volatile; | 662 | sa_count = sa_count_volatile; |
| 660 | fd_output = fd_output_volatile; | 663 | new_argv = new_argv_volatile; |
| 661 | filefd = filefd_volatile; | 664 | |
| 662 | count = count_volatile; | 665 | for (i = 0; i < CALLPROC_FDS; i++) |
| 663 | sa_count = sa_count_volatile; | 666 | callproc_fd[i] = callproc_fd_volatile[i]; |
| 664 | new_argv = new_argv_volatile; | 667 | fd_output = callproc_fd[CALLPROC_STDOUT]; |
| 665 | 668 | } | |
| 666 | fd0 = synch_process_fd; | ||
| 667 | } | ||
| 668 | |||
| 669 | if (pid == 0) | ||
| 670 | { | ||
| 671 | unblock_child_signal (); | ||
| 672 | 669 | ||
| 673 | if (fd0 >= 0) | 670 | if (pid == 0) |
| 674 | emacs_close (fd0); | 671 | { |
| 672 | unblock_child_signal (); | ||
| 675 | 673 | ||
| 676 | setsid (); | 674 | setsid (); |
| 677 | 675 | ||
| 678 | /* Emacs ignores SIGPIPE, but the child should not. */ | 676 | /* Emacs ignores SIGPIPE, but the child should not. */ |
| 679 | signal (SIGPIPE, SIG_DFL); | 677 | signal (SIGPIPE, SIG_DFL); |
| 680 | 678 | ||
| 681 | child_setup (filefd, fd1, fd_error, new_argv, 0, current_dir); | 679 | child_setup (filefd, fd_output, fd_error, new_argv, 0, current_dir); |
| 682 | } | 680 | } |
| 683 | 681 | ||
| 684 | #endif /* not WINDOWSNT */ | 682 | #endif /* not WINDOWSNT */ |
| 685 | 683 | ||
| 686 | child_errno = errno; | 684 | child_errno = errno; |
| 687 | 685 | ||
| 688 | if (pid > 0) | 686 | if (pid > 0) |
| 689 | { | 687 | { |
| 690 | if (INTEGERP (buffer)) | 688 | synch_process_pid = pid; |
| 691 | record_deleted_pid (pid); | ||
| 692 | else | ||
| 693 | synch_process_pid = pid; | ||
| 694 | } | ||
| 695 | 689 | ||
| 696 | unblock_child_signal (); | 690 | if (INTEGERP (buffer)) |
| 697 | unblock_input (); | 691 | { |
| 692 | if (tempfile_index < 0) | ||
| 693 | record_deleted_pid (pid, Qnil); | ||
| 694 | else | ||
| 695 | { | ||
| 696 | eassert (1 < nargs); | ||
| 697 | record_deleted_pid (pid, args[1]); | ||
| 698 | clear_unwind_protect (tempfile_index); | ||
| 699 | } | ||
| 700 | synch_process_pid = 0; | ||
| 701 | } | ||
| 702 | } | ||
| 698 | 703 | ||
| 699 | /* The MSDOS case did this already. */ | 704 | unblock_child_signal (); |
| 700 | if (fd_error >= 0) | 705 | unblock_input (); |
| 701 | emacs_close (fd_error); | ||
| 702 | #endif /* not MSDOS */ | ||
| 703 | 706 | ||
| 704 | /* Close most of our file descriptors, but not fd0 | 707 | #endif /* not MSDOS */ |
| 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 | 708 | ||
| 713 | if (pid < 0) | 709 | if (pid < 0) |
| 714 | report_file_errno ("Doing vfork", Qnil, child_errno); | 710 | report_file_errno ("Doing vfork", Qnil, child_errno); |
| 715 | 711 | ||
| 712 | /* Close our file descriptors, except for callproc_fd[CALLPROC_PIPEREAD] | ||
| 713 | since we will use that to read input from. */ | ||
| 714 | for (i = 0; i < CALLPROC_FDS; i++) | ||
| 715 | if (i != CALLPROC_PIPEREAD && 0 <= callproc_fd[i]) | ||
| 716 | { | ||
| 717 | emacs_close (callproc_fd[i]); | ||
| 718 | callproc_fd[i] = -1; | ||
| 719 | } | ||
| 720 | emacs_close (filefd); | ||
| 721 | clear_unwind_protect (count - 1); | ||
| 722 | |||
| 716 | if (INTEGERP (buffer)) | 723 | if (INTEGERP (buffer)) |
| 717 | return unbind_to (count, Qnil); | 724 | return unbind_to (count, Qnil); |
| 718 | 725 | ||
| 719 | if (BUFFERP (buffer)) | 726 | if (BUFFERP (buffer)) |
| 720 | Fset_buffer (buffer); | 727 | Fset_buffer (buffer); |
| 721 | 728 | ||
| 722 | if (NILP (buffer)) | 729 | fd0 = callproc_fd[CALLPROC_PIPEREAD]; |
| 723 | { | 730 | |
| 724 | /* If BUFFER is nil, we must read process output once and then | 731 | 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 | { | 732 | { |
| 731 | Lisp_Object val, *args2; | 733 | Lisp_Object val, *args2; |
| 732 | 734 | ||
| @@ -762,13 +764,13 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) * | |||
| 762 | setup_coding_system (val, &process_coding); | 764 | setup_coding_system (val, &process_coding); |
| 763 | process_coding.dst_multibyte | 765 | process_coding.dst_multibyte |
| 764 | = ! NILP (BVAR (current_buffer, enable_multibyte_characters)); | 766 | = ! NILP (BVAR (current_buffer, enable_multibyte_characters)); |
| 767 | process_coding.src_multibyte = 0; | ||
| 765 | } | 768 | } |
| 766 | process_coding.src_multibyte = 0; | ||
| 767 | 769 | ||
| 768 | immediate_quit = 1; | 770 | immediate_quit = 1; |
| 769 | QUIT; | 771 | QUIT; |
| 770 | 772 | ||
| 771 | if (output_to_buffer) | 773 | if (0 <= fd0) |
| 772 | { | 774 | { |
| 773 | enum { CALLPROC_BUFFER_SIZE_MIN = 16 * 1024 }; | 775 | enum { CALLPROC_BUFFER_SIZE_MIN = 16 * 1024 }; |
| 774 | enum { CALLPROC_BUFFER_SIZE_MAX = 4 * CALLPROC_BUFFER_SIZE_MIN }; | 776 | enum { CALLPROC_BUFFER_SIZE_MAX = 4 * CALLPROC_BUFFER_SIZE_MIN }; |
| @@ -779,9 +781,8 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) * | |||
| 779 | EMACS_INT total_read = 0; | 781 | EMACS_INT total_read = 0; |
| 780 | int carryover = 0; | 782 | int carryover = 0; |
| 781 | bool display_on_the_fly = display_p; | 783 | bool display_on_the_fly = display_p; |
| 782 | struct coding_system saved_coding; | 784 | struct coding_system saved_coding = process_coding; |
| 783 | 785 | ||
| 784 | saved_coding = process_coding; | ||
| 785 | while (1) | 786 | while (1) |
| 786 | { | 787 | { |
| 787 | /* Repeatedly read until we've filled as much as possible | 788 | /* Repeatedly read until we've filled as much as possible |
| @@ -812,58 +813,54 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) * | |||
| 812 | /* Now NREAD is the total amount of data in the buffer. */ | 813 | /* Now NREAD is the total amount of data in the buffer. */ |
| 813 | immediate_quit = 0; | 814 | immediate_quit = 0; |
| 814 | 815 | ||
| 815 | if (!NILP (buffer)) | 816 | if (NILP (BVAR (current_buffer, enable_multibyte_characters)) |
| 816 | { | 817 | && ! CODING_MAY_REQUIRE_DECODING (&process_coding)) |
| 817 | if (NILP (BVAR (current_buffer, enable_multibyte_characters)) | 818 | insert_1_both (buf, nread, nread, 0, 1, 0); |
| 818 | && ! CODING_MAY_REQUIRE_DECODING (&process_coding)) | 819 | else |
| 819 | insert_1_both (buf, nread, nread, 0, 1, 0); | 820 | { /* We have to decode the input. */ |
| 820 | else | 821 | Lisp_Object curbuf; |
| 821 | { /* We have to decode the input. */ | 822 | ptrdiff_t count1 = SPECPDL_INDEX (); |
| 822 | Lisp_Object curbuf; | 823 | |
| 823 | ptrdiff_t count1 = SPECPDL_INDEX (); | 824 | XSETBUFFER (curbuf, current_buffer); |
| 824 | 825 | /* We cannot allow after-change-functions be run | |
| 825 | XSETBUFFER (curbuf, current_buffer); | 826 | during decoding, because that might modify the |
| 826 | /* We cannot allow after-change-functions be run | 827 | buffer, while we rely on process_coding.produced to |
| 827 | during decoding, because that might modify the | 828 | faithfully reflect inserted text until we |
| 828 | buffer, while we rely on process_coding.produced to | 829 | TEMP_SET_PT_BOTH below. */ |
| 829 | faithfully reflect inserted text until we | 830 | specbind (Qinhibit_modification_hooks, Qt); |
| 830 | TEMP_SET_PT_BOTH below. */ | 831 | decode_coding_c_string (&process_coding, |
| 831 | specbind (Qinhibit_modification_hooks, Qt); | 832 | (unsigned char *) buf, nread, curbuf); |
| 832 | decode_coding_c_string (&process_coding, | 833 | unbind_to (count1, Qnil); |
| 833 | (unsigned char *) buf, nread, curbuf); | 834 | if (display_on_the_fly |
| 834 | unbind_to (count1, Qnil); | 835 | && CODING_REQUIRE_DETECTION (&saved_coding) |
| 835 | if (display_on_the_fly | 836 | && ! CODING_REQUIRE_DETECTION (&process_coding)) |
| 836 | && CODING_REQUIRE_DETECTION (&saved_coding) | 837 | { |
| 837 | && ! CODING_REQUIRE_DETECTION (&process_coding)) | 838 | /* We have detected some coding system, but the |
| 838 | { | 839 | detection may have been via insufficient data. |
| 839 | /* We have detected some coding system. But, | 840 | So give up displaying on the fly. */ |
| 840 | there's a possibility that the detection was | 841 | if (process_coding.produced > 0) |
| 841 | done by insufficient data. So, we give up | 842 | del_range_2 (process_coding.dst_pos, |
| 842 | displaying on the fly. */ | 843 | process_coding.dst_pos_byte, |
| 843 | if (process_coding.produced > 0) | 844 | (process_coding.dst_pos |
| 844 | del_range_2 (process_coding.dst_pos, | 845 | + process_coding.produced_char), |
| 845 | process_coding.dst_pos_byte, | 846 | (process_coding.dst_pos_byte |
| 846 | process_coding.dst_pos | 847 | + process_coding.produced), |
| 847 | + process_coding.produced_char, | 848 | 0); |
| 848 | process_coding.dst_pos_byte | 849 | display_on_the_fly = 0; |
| 849 | + process_coding.produced, 0); | 850 | process_coding = saved_coding; |
| 850 | display_on_the_fly = 0; | 851 | carryover = nread; |
| 851 | process_coding = saved_coding; | 852 | /* Make the above condition always fail in the future. */ |
| 852 | carryover = nread; | 853 | saved_coding.common_flags |
| 853 | /* This is to make the above condition always | 854 | &= ~CODING_REQUIRE_DETECTION_MASK; |
| 854 | fails in the future. */ | 855 | 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 | } | 856 | } |
| 857 | |||
| 858 | TEMP_SET_PT_BOTH (PT + process_coding.produced_char, | ||
| 859 | PT_BYTE + process_coding.produced); | ||
| 860 | carryover = process_coding.carryover_bytes; | ||
| 861 | if (carryover > 0) | ||
| 862 | memcpy (buf, process_coding.carryover, | ||
| 863 | process_coding.carryover_bytes); | ||
| 867 | } | 864 | } |
| 868 | 865 | ||
| 869 | if (process_coding.mode & CODING_MODE_LAST_BLOCK) | 866 | if (process_coding.mode & CODING_MODE_LAST_BLOCK) |
| @@ -882,7 +879,7 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) * | |||
| 882 | first = 0; | 879 | first = 0; |
| 883 | redisplay_preserve_echo_area (1); | 880 | redisplay_preserve_echo_area (1); |
| 884 | /* This variable might have been set to 0 for code | 881 | /* This variable might have been set to 0 for code |
| 885 | detection. In that case, we set it back to 1 because | 882 | detection. In that case, set it back to 1 because |
| 886 | we should have already detected a coding system. */ | 883 | we should have already detected a coding system. */ |
| 887 | display_on_the_fly = 1; | 884 | display_on_the_fly = 1; |
| 888 | } | 885 | } |
| @@ -901,7 +898,7 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) * | |||
| 901 | 898 | ||
| 902 | #ifndef MSDOS | 899 | #ifndef MSDOS |
| 903 | /* Wait for it to terminate, unless it already has. */ | 900 | /* Wait for it to terminate, unless it already has. */ |
| 904 | wait_for_termination (pid, &status, !output_to_buffer); | 901 | wait_for_termination (pid, &status, fd0 < 0); |
| 905 | #endif | 902 | #endif |
| 906 | 903 | ||
| 907 | immediate_quit = 0; | 904 | immediate_quit = 0; |
| @@ -931,37 +928,18 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) * | |||
| 931 | return make_number (WEXITSTATUS (status)); | 928 | return make_number (WEXITSTATUS (status)); |
| 932 | } | 929 | } |
| 933 | 930 | ||
| 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 | 931 | /* Create a temporary file suitable for storing the input data of |
| 959 | call-process-region. NARGS and ARGS are the same as for | 932 | call-process-region. NARGS and ARGS are the same as for |
| 960 | call-process-region. */ | 933 | call-process-region. Store into *FILENAME_STRING_PTR a Lisp string |
| 934 | naming the file, and return a file descriptor for reading. | ||
| 935 | Unwind-protect the file, so that the file descriptor will be closed | ||
| 936 | and the file removed when the caller unwinds the specpdl stack. */ | ||
| 961 | 937 | ||
| 962 | static Lisp_Object | 938 | static int |
| 963 | create_temp_file (ptrdiff_t nargs, Lisp_Object *args) | 939 | create_temp_file (ptrdiff_t nargs, Lisp_Object *args, |
| 940 | Lisp_Object *filename_string_ptr) | ||
| 964 | { | 941 | { |
| 942 | int fd; | ||
| 965 | struct gcpro gcpro1; | 943 | struct gcpro gcpro1; |
| 966 | Lisp_Object filename_string; | 944 | Lisp_Object filename_string; |
| 967 | Lisp_Object val, start, end; | 945 | Lisp_Object val, start, end; |
| @@ -988,6 +966,7 @@ create_temp_file (ptrdiff_t nargs, Lisp_Object *args) | |||
| 988 | { | 966 | { |
| 989 | Lisp_Object pattern = Fexpand_file_name (Vtemp_file_name_pattern, tmpdir); | 967 | Lisp_Object pattern = Fexpand_file_name (Vtemp_file_name_pattern, tmpdir); |
| 990 | char *tempfile; | 968 | char *tempfile; |
| 969 | ptrdiff_t count; | ||
| 991 | 970 | ||
| 992 | #ifdef WINDOWSNT | 971 | #ifdef WINDOWSNT |
| 993 | /* Cannot use the result of Fexpand_file_name, because it | 972 | /* Cannot use the result of Fexpand_file_name, because it |
| @@ -1008,27 +987,14 @@ create_temp_file (ptrdiff_t nargs, Lisp_Object *args) | |||
| 1008 | GCPRO1 (filename_string); | 987 | GCPRO1 (filename_string); |
| 1009 | tempfile = SSDATA (filename_string); | 988 | tempfile = SSDATA (filename_string); |
| 1010 | 989 | ||
| 1011 | { | 990 | count = SPECPDL_INDEX (); |
| 1012 | int fd; | 991 | record_unwind_protect_nothing (); |
| 1013 | 992 | fd = mkostemp (tempfile, O_CLOEXEC); | |
| 1014 | #ifdef HAVE_MKOSTEMP | 993 | if (fd < 0) |
| 1015 | fd = mkostemp (tempfile, O_CLOEXEC); | 994 | report_file_error ("Failed to open temporary file using pattern", |
| 1016 | #elif defined HAVE_MKSTEMP | 995 | pattern); |
| 1017 | fd = mkstemp (tempfile); | 996 | set_unwind_protect (count, delete_temp_file, filename_string); |
| 1018 | #else | 997 | record_unwind_protect_int (close_file_unwind, fd); |
| 1019 | errno = EEXIST; | ||
| 1020 | mktemp (tempfile); | ||
| 1021 | fd = *tempfile ? 0 : -1; | ||
| 1022 | #endif | ||
| 1023 | if (fd < 0) | ||
| 1024 | report_file_error ("Failed to open temporary file using pattern", | ||
| 1025 | pattern); | ||
| 1026 | #if defined HAVE_MKOSTEMP || defined HAVE_MKSTEMP | ||
| 1027 | emacs_close (fd); | ||
| 1028 | #endif | ||
| 1029 | } | ||
| 1030 | |||
| 1031 | record_unwind_protect (delete_temp_file, filename_string); | ||
| 1032 | } | 998 | } |
| 1033 | 999 | ||
| 1034 | start = args[0]; | 1000 | start = args[0]; |
| @@ -1059,15 +1025,20 @@ create_temp_file (ptrdiff_t nargs, Lisp_Object *args) | |||
| 1059 | /* POSIX lets mk[s]temp use "."; don't invoke jka-compr if we | 1025 | /* POSIX lets mk[s]temp use "."; don't invoke jka-compr if we |
| 1060 | happen to get a ".Z" suffix. */ | 1026 | happen to get a ".Z" suffix. */ |
| 1061 | specbind (intern ("file-name-handler-alist"), Qnil); | 1027 | specbind (intern ("file-name-handler-alist"), Qnil); |
| 1062 | Fwrite_region (start, end, filename_string, Qnil, Qlambda, Qnil, Qnil); | 1028 | write_region (start, end, filename_string, Qnil, Qlambda, Qnil, Qnil, fd); |
| 1063 | 1029 | ||
| 1064 | unbind_to (count1, Qnil); | 1030 | unbind_to (count1, Qnil); |
| 1065 | } | 1031 | } |
| 1066 | 1032 | ||
| 1033 | if (lseek (fd, 0, SEEK_SET) < 0) | ||
| 1034 | report_file_error ("Setting file position", filename_string); | ||
| 1035 | |||
| 1067 | /* Note that Fcall_process takes care of binding | 1036 | /* Note that Fcall_process takes care of binding |
| 1068 | coding-system-for-read. */ | 1037 | coding-system-for-read. */ |
| 1069 | 1038 | ||
| 1070 | RETURN_UNGCPRO (filename_string); | 1039 | *filename_string_ptr = filename_string; |
| 1040 | UNGCPRO; | ||
| 1041 | return fd; | ||
| 1071 | } | 1042 | } |
| 1072 | 1043 | ||
| 1073 | DEFUN ("call-process-region", Fcall_process_region, Scall_process_region, | 1044 | DEFUN ("call-process-region", Fcall_process_region, Scall_process_region, |
| @@ -1098,11 +1069,12 @@ usage: (call-process-region START END PROGRAM &optional DELETE BUFFER DISPLAY &r | |||
| 1098 | (ptrdiff_t nargs, Lisp_Object *args) | 1069 | (ptrdiff_t nargs, Lisp_Object *args) |
| 1099 | { | 1070 | { |
| 1100 | struct gcpro gcpro1; | 1071 | struct gcpro gcpro1; |
| 1101 | Lisp_Object infile; | 1072 | Lisp_Object infile, val; |
| 1102 | ptrdiff_t count = SPECPDL_INDEX (); | 1073 | ptrdiff_t count = SPECPDL_INDEX (); |
| 1103 | Lisp_Object start = args[0]; | 1074 | Lisp_Object start = args[0]; |
| 1104 | Lisp_Object end = args[1]; | 1075 | Lisp_Object end = args[1]; |
| 1105 | bool empty_input; | 1076 | bool empty_input; |
| 1077 | int fd; | ||
| 1106 | 1078 | ||
| 1107 | if (STRINGP (start)) | 1079 | if (STRINGP (start)) |
| 1108 | empty_input = SCHARS (start) == 0; | 1080 | empty_input = SCHARS (start) == 0; |
| @@ -1116,7 +1088,17 @@ usage: (call-process-region START END PROGRAM &optional DELETE BUFFER DISPLAY &r | |||
| 1116 | empty_input = XINT (start) == XINT (end); | 1088 | empty_input = XINT (start) == XINT (end); |
| 1117 | } | 1089 | } |
| 1118 | 1090 | ||
| 1119 | infile = empty_input ? Qnil : create_temp_file (nargs, args); | 1091 | if (!empty_input) |
| 1092 | fd = create_temp_file (nargs, args, &infile); | ||
| 1093 | else | ||
| 1094 | { | ||
| 1095 | infile = Qnil; | ||
| 1096 | fd = emacs_open (NULL_DEVICE, O_RDONLY, 0); | ||
| 1097 | if (fd < 0) | ||
| 1098 | report_file_error ("Opening null device", Qnil); | ||
| 1099 | record_unwind_protect_int (close_file_unwind, fd); | ||
| 1100 | } | ||
| 1101 | |||
| 1120 | GCPRO1 (infile); | 1102 | GCPRO1 (infile); |
| 1121 | 1103 | ||
| 1122 | if (nargs > 3 && !NILP (args[3])) | 1104 | if (nargs > 3 && !NILP (args[3])) |
| @@ -1134,7 +1116,8 @@ usage: (call-process-region START END PROGRAM &optional DELETE BUFFER DISPLAY &r | |||
| 1134 | } | 1116 | } |
| 1135 | args[1] = infile; | 1117 | args[1] = infile; |
| 1136 | 1118 | ||
| 1137 | RETURN_UNGCPRO (unbind_to (count, Fcall_process (nargs, args))); | 1119 | val = call_process (nargs, args, fd, empty_input ? -1 : count); |
| 1120 | RETURN_UNGCPRO (unbind_to (count, val)); | ||
| 1138 | } | 1121 | } |
| 1139 | 1122 | ||
| 1140 | #ifndef WINDOWSNT | 1123 | #ifndef WINDOWSNT |
| @@ -1210,23 +1193,21 @@ child_setup (int in, int out, int err, char **new_argv, bool set_pgrp, | |||
| 1210 | static variables as if the superior had done alloca and will be | 1193 | static variables as if the superior had done alloca and will be |
| 1211 | cleaned up in the usual way. */ | 1194 | cleaned up in the usual way. */ |
| 1212 | { | 1195 | { |
| 1213 | register char *temp; | 1196 | char *temp; |
| 1214 | size_t i; /* size_t, because ptrdiff_t might overflow here! */ | 1197 | ptrdiff_t i; |
| 1215 | 1198 | ||
| 1216 | i = SBYTES (current_dir); | 1199 | i = SBYTES (current_dir); |
| 1217 | #ifdef MSDOS | 1200 | #ifdef MSDOS |
| 1218 | /* MSDOS must have all environment variables malloc'ed, because | 1201 | /* MSDOS must have all environment variables malloc'ed, because |
| 1219 | low-level libc functions that launch subsidiary processes rely | 1202 | low-level libc functions that launch subsidiary processes rely |
| 1220 | on that. */ | 1203 | on that. */ |
| 1221 | pwd_var = xmalloc (i + 6); | 1204 | pwd_var = xmalloc (i + 5); |
| 1222 | #else | 1205 | #else |
| 1223 | pwd_var = alloca (i + 6); | 1206 | pwd_var = alloca (i + 5); |
| 1224 | #endif | 1207 | #endif |
| 1225 | temp = pwd_var + 4; | 1208 | temp = pwd_var + 4; |
| 1226 | memcpy (pwd_var, "PWD=", 4); | 1209 | memcpy (pwd_var, "PWD=", 4); |
| 1227 | memcpy (temp, SDATA (current_dir), i); | 1210 | strcpy (temp, SSDATA (current_dir)); |
| 1228 | if (!IS_DIRECTORY_SEP (temp[i - 1])) temp[i++] = DIRECTORY_SEP; | ||
| 1229 | temp[i] = 0; | ||
| 1230 | 1211 | ||
| 1231 | #ifndef DOS_NT | 1212 | #ifndef DOS_NT |
| 1232 | /* We can't signal an Elisp error here; we're in a vfork. Since | 1213 | /* We can't signal an Elisp error here; we're in a vfork. Since |
| @@ -1695,6 +1676,11 @@ syms_of_callproc (void) | |||
| 1695 | #endif | 1676 | #endif |
| 1696 | staticpro (&Vtemp_file_name_pattern); | 1677 | staticpro (&Vtemp_file_name_pattern); |
| 1697 | 1678 | ||
| 1679 | #ifdef MSDOS | ||
| 1680 | synch_process_tempfile = make_number (0); | ||
| 1681 | staticpro (&synch_process_tempfile); | ||
| 1682 | #endif | ||
| 1683 | |||
| 1698 | DEFVAR_LISP ("shell-file-name", Vshell_file_name, | 1684 | DEFVAR_LISP ("shell-file-name", Vshell_file_name, |
| 1699 | doc: /* File name to load inferior shells from. | 1685 | doc: /* File name to load inferior shells from. |
| 1700 | Initialized from the SHELL environment variable, or to a system-dependent | 1686 | Initialized from the SHELL environment variable, or to a system-dependent |