aboutsummaryrefslogtreecommitdiffstats
path: root/src/callproc.c
diff options
context:
space:
mode:
authorLars Magne Ingebrigtsen2011-05-01 02:04:17 +0200
committerLars Magne Ingebrigtsen2011-05-01 02:04:17 +0200
commit1ef14cb4b0f726a5e6a86e20fed8cfecb22c67d5 (patch)
tree3278d1d473acef1cbac1551f80e9fd815a08fb99 /src/callproc.c
parentdcb79f208ab9e2e1e8e0d4e9810ca25c1a660eaf (diff)
downloademacs-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.c85
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.
157The remaining arguments are optional. 157The remaining arguments are optional.
158The program's input comes from file INFILE (nil means `/dev/null'). 158The program's input comes from file INFILE (nil means `/dev/null').
159Insert output in BUFFER before point; t means current buffer; 159Insert 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.
161BUFFER can also have the form (REAL-BUFFER STDERR-FILE); in that case, 162BUFFER can also have the form (REAL-BUFFER STDERR-FILE); in that case,
162REAL-BUFFER says what to do with standard output, as above, 163REAL-BUFFER says what to do with standard output, as above,
163while STDERR-FILE says what to do with standard error in the child. 164while 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,
850The remaining arguments are optional. 903The remaining arguments are optional.
851Delete the text if fourth arg DELETE is non-nil. 904Delete the text if fourth arg DELETE is non-nil.
852 905
853Insert output in BUFFER before point; t means current buffer; 906Insert 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.
855BUFFER can also have the form (REAL-BUFFER STDERR-FILE); in that case, 910BUFFER can also have the form (REAL-BUFFER STDERR-FILE); in that case,
856REAL-BUFFER says what to do with standard output, as above, 911REAL-BUFFER says what to do with standard output, as above,
857while STDERR-FILE says what to do with standard error in the child. 912while STDERR-FILE says what to do with standard error in the child.