diff options
| author | Lars Magne Ingebrigtsen | 2011-05-01 02:04:17 +0200 |
|---|---|---|
| committer | Lars Magne Ingebrigtsen | 2011-05-01 02:04:17 +0200 |
| commit | 1ef14cb4b0f726a5e6a86e20fed8cfecb22c67d5 (patch) | |
| tree | 3278d1d473acef1cbac1551f80e9fd815a08fb99 /src/callproc.c | |
| parent | dcb79f208ab9e2e1e8e0d4e9810ca25c1a660eaf (diff) | |
| download | emacs-1ef14cb4b0f726a5e6a86e20fed8cfecb22c67d5.tar.gz emacs-1ef14cb4b0f726a5e6a86e20fed8cfecb22c67d5.zip | |
Extend `call-process' to take the `(:file "file")' syntax to redirect
STDOUT to a file.
Diffstat (limited to 'src/callproc.c')
| -rw-r--r-- | src/callproc.c | 85 |
1 files changed, 70 insertions, 15 deletions
diff --git a/src/callproc.c b/src/callproc.c index 3726eb3cc7f..84b463d2f3d 100644 --- a/src/callproc.c +++ b/src/callproc.c | |||
| @@ -156,8 +156,9 @@ DEFUN ("call-process", Fcall_process, Scall_process, 1, MANY, 0, | |||
| 156 | doc: /* Call PROGRAM synchronously in separate process. | 156 | doc: /* Call PROGRAM synchronously in separate process. |
| 157 | The remaining arguments are optional. | 157 | The remaining arguments are optional. |
| 158 | The program's input comes from file INFILE (nil means `/dev/null'). | 158 | The program's input comes from file INFILE (nil means `/dev/null'). |
| 159 | Insert output in BUFFER before point; t means current buffer; | 159 | Insert output in BUFFER before point; t means current buffer; nil for BUFFER |
| 160 | nil for BUFFER means discard it; 0 means discard and don't wait. | 160 | means discard it; 0 means discard and don't wait; and `(:file FILE)', where |
| 161 | FILE is a file name string, means that it should be written to that file. | ||
| 161 | BUFFER can also have the form (REAL-BUFFER STDERR-FILE); in that case, | 162 | BUFFER can also have the form (REAL-BUFFER STDERR-FILE); in that case, |
| 162 | REAL-BUFFER says what to do with standard output, as above, | 163 | REAL-BUFFER says what to do with standard output, as above, |
| 163 | while STDERR-FILE says what to do with standard error in the child. | 164 | while STDERR-FILE says what to do with standard error in the child. |
| @@ -196,14 +197,17 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) | |||
| 196 | /* File to use for stderr in the child. | 197 | /* File to use for stderr in the child. |
| 197 | t means use same as standard output. */ | 198 | t means use same as standard output. */ |
| 198 | Lisp_Object error_file; | 199 | Lisp_Object error_file; |
| 200 | Lisp_Object output_file = Qnil; | ||
| 199 | #ifdef MSDOS /* Demacs 1.1.1 91/10/16 HIRANO Satoshi */ | 201 | #ifdef MSDOS /* Demacs 1.1.1 91/10/16 HIRANO Satoshi */ |
| 200 | char *outf, *tempfile; | 202 | char *outf, *tempfile; |
| 201 | int outfilefd; | 203 | int outfilefd; |
| 202 | #endif | 204 | #endif |
| 205 | int fd_output = -1; | ||
| 203 | struct coding_system process_coding; /* coding-system of process output */ | 206 | struct coding_system process_coding; /* coding-system of process output */ |
| 204 | struct coding_system argument_coding; /* coding-system of arguments */ | 207 | struct coding_system argument_coding; /* coding-system of arguments */ |
| 205 | /* Set to the return value of Ffind_operation_coding_system. */ | 208 | /* Set to the return value of Ffind_operation_coding_system. */ |
| 206 | Lisp_Object coding_systems; | 209 | Lisp_Object coding_systems; |
| 210 | int output_to_buffer = 1; | ||
| 207 | 211 | ||
| 208 | /* Qt denotes that Ffind_operation_coding_system is not yet called. */ | 212 | /* Qt denotes that Ffind_operation_coding_system is not yet called. */ |
| 209 | coding_systems = Qt; | 213 | coding_systems = Qt; |
| @@ -273,9 +277,12 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) | |||
| 273 | { | 277 | { |
| 274 | buffer = args[2]; | 278 | buffer = args[2]; |
| 275 | 279 | ||
| 276 | /* If BUFFER is a list, its meaning is | 280 | /* If BUFFER is a list, its meaning is (BUFFER-FOR-STDOUT |
| 277 | (BUFFER-FOR-STDOUT FILE-FOR-STDERR). */ | 281 | FILE-FOR-STDERR), unless the first element is :file, in which case see |
| 278 | if (CONSP (buffer)) | 282 | the next paragraph. */ |
| 283 | if (CONSP (buffer) && | ||
| 284 | (! SYMBOLP (XCAR (buffer)) || | ||
| 285 | strcmp (SSDATA (SYMBOL_NAME (XCAR (buffer))), ":file"))) | ||
| 279 | { | 286 | { |
| 280 | if (CONSP (XCDR (buffer))) | 287 | if (CONSP (XCDR (buffer))) |
| 281 | { | 288 | { |
| @@ -291,6 +298,17 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) | |||
| 291 | buffer = XCAR (buffer); | 298 | buffer = XCAR (buffer); |
| 292 | } | 299 | } |
| 293 | 300 | ||
| 301 | /* If the buffer is (still) a list, it might be a (:file "file") spec. */ | ||
| 302 | if (CONSP (buffer) && | ||
| 303 | SYMBOLP (XCAR (buffer)) && | ||
| 304 | ! strcmp (SSDATA (SYMBOL_NAME (XCAR (buffer))), ":file")) | ||
| 305 | { | ||
| 306 | output_file = Fexpand_file_name (XCAR (XCDR (buffer)), | ||
| 307 | BVAR (current_buffer, directory)); | ||
| 308 | CHECK_STRING (output_file); | ||
| 309 | buffer = Qnil; | ||
| 310 | } | ||
| 311 | |||
| 294 | if (!(EQ (buffer, Qnil) | 312 | if (!(EQ (buffer, Qnil) |
| 295 | || EQ (buffer, Qt) | 313 | || EQ (buffer, Qt) |
| 296 | || INTEGERP (buffer))) | 314 | || INTEGERP (buffer))) |
| @@ -318,11 +336,11 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) | |||
| 318 | protected by the caller, so all we really have to worry about is | 336 | protected by the caller, so all we really have to worry about is |
| 319 | buffer. */ | 337 | buffer. */ |
| 320 | { | 338 | { |
| 321 | struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; | 339 | struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5; |
| 322 | 340 | ||
| 323 | current_dir = BVAR (current_buffer, directory); | 341 | current_dir = BVAR (current_buffer, directory); |
| 324 | 342 | ||
| 325 | GCPRO4 (infile, buffer, current_dir, error_file); | 343 | GCPRO5 (infile, buffer, current_dir, error_file, output_file); |
| 326 | 344 | ||
| 327 | current_dir = Funhandled_file_name_directory (current_dir); | 345 | current_dir = Funhandled_file_name_directory (current_dir); |
| 328 | if (NILP (current_dir)) | 346 | if (NILP (current_dir)) |
| @@ -342,6 +360,8 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) | |||
| 342 | current_dir = ENCODE_FILE (current_dir); | 360 | current_dir = ENCODE_FILE (current_dir); |
| 343 | if (STRINGP (error_file) && STRING_MULTIBYTE (error_file)) | 361 | if (STRINGP (error_file) && STRING_MULTIBYTE (error_file)) |
| 344 | error_file = ENCODE_FILE (error_file); | 362 | error_file = ENCODE_FILE (error_file); |
| 363 | if (STRINGP (output_file) && STRING_MULTIBYTE (output_file)) | ||
| 364 | output_file = ENCODE_FILE (output_file); | ||
| 345 | UNGCPRO; | 365 | UNGCPRO; |
| 346 | } | 366 | } |
| 347 | 367 | ||
| @@ -353,6 +373,26 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) | |||
| 353 | infile = DECODE_FILE (infile); | 373 | infile = DECODE_FILE (infile); |
| 354 | report_file_error ("Opening process input file", Fcons (infile, Qnil)); | 374 | report_file_error ("Opening process input file", Fcons (infile, Qnil)); |
| 355 | } | 375 | } |
| 376 | |||
| 377 | if (STRINGP (output_file)) | ||
| 378 | { | ||
| 379 | #ifdef DOS_NT | ||
| 380 | fd_output = emacs_open (SSDATA (output_file), | ||
| 381 | O_WRONLY | O_TRUNC | O_CREAT | O_TEXT, | ||
| 382 | S_IREAD | S_IWRITE); | ||
| 383 | #else /* not DOS_NT */ | ||
| 384 | fd_output = creat (SSDATA (output_file), 0666); | ||
| 385 | #endif /* not DOS_NT */ | ||
| 386 | if (fd_output < 0) | ||
| 387 | { | ||
| 388 | output_file = DECODE_FILE (output_file); | ||
| 389 | report_file_error ("Opening process output file", | ||
| 390 | Fcons (output_file, Qnil)); | ||
| 391 | } | ||
| 392 | if (STRINGP (error_file) || NILP (error_file)) | ||
| 393 | output_to_buffer = 0; | ||
| 394 | } | ||
| 395 | |||
| 356 | /* Search for program; barf if not found. */ | 396 | /* Search for program; barf if not found. */ |
| 357 | { | 397 | { |
| 358 | struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; | 398 | struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; |
| @@ -413,13 +453,18 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) | |||
| 413 | strcat (tempfile, "detmp.XXX"); | 453 | strcat (tempfile, "detmp.XXX"); |
| 414 | mktemp (tempfile); | 454 | mktemp (tempfile); |
| 415 | 455 | ||
| 416 | outfilefd = creat (tempfile, S_IREAD | S_IWRITE); | 456 | /* If we're redirecting STDOUT to a file, this is already opened. */ |
| 417 | if (outfilefd < 0) | 457 | if (fd_output < 0) |
| 418 | { | 458 | { |
| 419 | emacs_close (filefd); | 459 | outfilefd = creat (tempfile, S_IREAD | S_IWRITE); |
| 420 | report_file_error ("Opening process output file", | 460 | if (outfilefd < 0) { |
| 421 | Fcons (build_string (tempfile), Qnil)); | 461 | emacs_close (filefd); |
| 462 | report_file_error ("Opening process output file", | ||
| 463 | Fcons (build_string (tempfile), Qnil)); | ||
| 464 | } | ||
| 422 | } | 465 | } |
| 466 | else | ||
| 467 | outfilefd = fd_output; | ||
| 423 | fd[0] = filefd; | 468 | fd[0] = filefd; |
| 424 | fd[1] = outfilefd; | 469 | fd[1] = outfilefd; |
| 425 | #endif /* MSDOS */ | 470 | #endif /* MSDOS */ |
| @@ -450,6 +495,8 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) | |||
| 450 | struct sigaction sigpipe_action; | 495 | struct sigaction sigpipe_action; |
| 451 | #endif | 496 | #endif |
| 452 | 497 | ||
| 498 | if (fd_output >= 0) | ||
| 499 | fd1 = fd_output; | ||
| 453 | #if 0 /* Some systems don't have sigblock. */ | 500 | #if 0 /* Some systems don't have sigblock. */ |
| 454 | mask = sigblock (sigmask (SIGCHLD)); | 501 | mask = sigblock (sigmask (SIGCHLD)); |
| 455 | #endif | 502 | #endif |
| @@ -591,6 +638,8 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) | |||
| 591 | /* Close most of our fd's, but not fd[0] | 638 | /* Close most of our fd's, but not fd[0] |
| 592 | since we will use that to read input from. */ | 639 | since we will use that to read input from. */ |
| 593 | emacs_close (filefd); | 640 | emacs_close (filefd); |
| 641 | if (fd_output >= 0) | ||
| 642 | emacs_close (fd_output); | ||
| 594 | if (fd1 >= 0 && fd1 != fd_error) | 643 | if (fd1 >= 0 && fd1 != fd_error) |
| 595 | emacs_close (fd1); | 644 | emacs_close (fd1); |
| 596 | } | 645 | } |
| @@ -673,6 +722,7 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) | |||
| 673 | immediate_quit = 1; | 722 | immediate_quit = 1; |
| 674 | QUIT; | 723 | QUIT; |
| 675 | 724 | ||
| 725 | if (output_to_buffer) | ||
| 676 | { | 726 | { |
| 677 | register EMACS_INT nread; | 727 | register EMACS_INT nread; |
| 678 | int first = 1; | 728 | int first = 1; |
| @@ -802,7 +852,10 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) | |||
| 802 | 852 | ||
| 803 | #ifndef MSDOS | 853 | #ifndef MSDOS |
| 804 | /* Wait for it to terminate, unless it already has. */ | 854 | /* Wait for it to terminate, unless it already has. */ |
| 805 | wait_for_termination (pid); | 855 | if (output_to_buffer) |
| 856 | wait_for_termination (pid); | ||
| 857 | else | ||
| 858 | interruptible_wait_for_termination (pid); | ||
| 806 | #endif | 859 | #endif |
| 807 | 860 | ||
| 808 | immediate_quit = 0; | 861 | immediate_quit = 0; |
| @@ -850,8 +903,10 @@ DEFUN ("call-process-region", Fcall_process_region, Scall_process_region, | |||
| 850 | The remaining arguments are optional. | 903 | The remaining arguments are optional. |
| 851 | Delete the text if fourth arg DELETE is non-nil. | 904 | Delete the text if fourth arg DELETE is non-nil. |
| 852 | 905 | ||
| 853 | Insert output in BUFFER before point; t means current buffer; | 906 | Insert output in BUFFER before point; t means current buffer; nil for |
| 854 | nil for BUFFER means discard it; 0 means discard and don't wait. | 907 | BUFFER means discard it; 0 means discard and don't wait; and `(:file |
| 908 | FILE)', where FILE is a file name string, means that it should be | ||
| 909 | written to that file. | ||
| 855 | BUFFER can also have the form (REAL-BUFFER STDERR-FILE); in that case, | 910 | BUFFER can also have the form (REAL-BUFFER STDERR-FILE); in that case, |
| 856 | REAL-BUFFER says what to do with standard output, as above, | 911 | REAL-BUFFER says what to do with standard output, as above, |
| 857 | while STDERR-FILE says what to do with standard error in the child. | 912 | while STDERR-FILE says what to do with standard error in the child. |