Mercurial > emacs
comparison src/callproc.c @ 10839:2e3eae2280eb
(Fcall_process): Extend BUFFER arg so it can specify
a separate output file for stderr output.
(Fcall_process_region): Doc fix.
author | Richard M. Stallman <rms@gnu.org> |
---|---|
date | Sun, 26 Feb 1995 07:58:52 +0000 |
parents | 2d7a561cc92c |
children | e6bdaaa6ce1b |
comparison
equal
deleted
inserted
replaced
10838:6c0dc7a8a07a | 10839:2e3eae2280eb |
---|---|
177 DEFUN ("call-process", Fcall_process, Scall_process, 1, MANY, 0, | 177 DEFUN ("call-process", Fcall_process, Scall_process, 1, MANY, 0, |
178 "Call PROGRAM synchronously in separate process.\n\ | 178 "Call PROGRAM synchronously in separate process.\n\ |
179 The program's input comes from file INFILE (nil means `/dev/null').\n\ | 179 The program's input comes from file INFILE (nil means `/dev/null').\n\ |
180 Insert output in BUFFER before point; t means current buffer;\n\ | 180 Insert output in BUFFER before point; t means current buffer;\n\ |
181 nil for BUFFER means discard it; 0 means discard and don't wait.\n\ | 181 nil for BUFFER means discard it; 0 means discard and don't wait.\n\ |
182 BUFFER can also have the form (REAL-BUFFER STDERR-FILE); in that case,\n\ | |
183 REAL-BUFFER says what to do with standard output, as above,\n\ | |
184 while STDERR-FILE says what to do with standard error in the child.\n\ | |
185 STDERR-FILE may be nil (discard standard error output),\n\ | |
186 t (mix it with ordinary output), or a file name string.\n\ | |
187 \n\ | |
182 Fourth arg DISPLAY non-nil means redisplay buffer as output is inserted.\n\ | 188 Fourth arg DISPLAY non-nil means redisplay buffer as output is inserted.\n\ |
183 Remaining arguments are strings passed as command arguments to PROGRAM.\n\ | 189 Remaining arguments are strings passed as command arguments to PROGRAM.\n\ |
184 If BUFFER is 0, returns immediately with value nil.\n\ | 190 \n\ |
185 Otherwise waits for PROGRAM to terminate\n\ | 191 If BUFFER is 0, `call-process' returns immediately with value nil.\n\ |
192 Otherwise it waits for PROGRAM to terminate\n\ | |
186 and returns a numeric exit status or a signal description string.\n\ | 193 and returns a numeric exit status or a signal description string.\n\ |
187 If you quit, the process is killed with SIGINT, or SIGKILL if you quit again.") | 194 If you quit, the process is killed with SIGINT, or SIGKILL if you quit again.") |
188 (nargs, args) | 195 (nargs, args) |
189 int nargs; | 196 int nargs; |
190 register Lisp_Object *args; | 197 register Lisp_Object *args; |
196 char buf[1024]; | 203 char buf[1024]; |
197 int count = specpdl_ptr - specpdl; | 204 int count = specpdl_ptr - specpdl; |
198 register unsigned char **new_argv | 205 register unsigned char **new_argv |
199 = (unsigned char **) alloca ((max (2, nargs - 2)) * sizeof (char *)); | 206 = (unsigned char **) alloca ((max (2, nargs - 2)) * sizeof (char *)); |
200 struct buffer *old = current_buffer; | 207 struct buffer *old = current_buffer; |
208 /* File to use for stderr in the child. | |
209 t means use same as standard output. */ | |
210 Lisp_Object error_file; | |
201 #ifdef MSDOS /* Demacs 1.1.1 91/10/16 HIRANO Satoshi */ | 211 #ifdef MSDOS /* Demacs 1.1.1 91/10/16 HIRANO Satoshi */ |
202 char *outf, *tempfile; | 212 char *outf, *tempfile; |
203 int outfilefd; | 213 int outfilefd; |
204 #endif | 214 #endif |
205 #if 0 | 215 #if 0 |
206 int mask; | 216 int mask; |
207 #endif | 217 #endif |
208 CHECK_STRING (args[0], 0); | 218 CHECK_STRING (args[0], 0); |
219 | |
220 error_file = Qt; | |
209 | 221 |
210 #ifndef subprocesses | 222 #ifndef subprocesses |
211 /* Without asynchronous processes we cannot have BUFFER == 0. */ | 223 /* Without asynchronous processes we cannot have BUFFER == 0. */ |
212 if (nargs >= 3 && INTEGERP (args[2])) | 224 if (nargs >= 3 && INTEGERP (args[2])) |
213 error ("Operating system cannot handle asynchronous subprocesses"); | 225 error ("Operating system cannot handle asynchronous subprocesses"); |
221 else | 233 else |
222 infile = build_string (NULL_DEVICE); | 234 infile = build_string (NULL_DEVICE); |
223 | 235 |
224 if (nargs >= 3) | 236 if (nargs >= 3) |
225 { | 237 { |
226 register Lisp_Object tem; | 238 buffer = args[2]; |
227 | 239 |
228 buffer = tem = args[2]; | 240 /* If BUFFER is a list, its meaning is |
229 if (!(EQ (tem, Qnil) | 241 (BUFFER-FOR-STDOUT FILE-FOR-STDERR). */ |
230 || EQ (tem, Qt) | 242 if (CONSP (buffer)) |
231 || XFASTINT (tem) == 0)) | |
232 { | 243 { |
233 buffer = Fget_buffer (tem); | 244 if (CONSP (XCONS (buffer)->cdr)) |
245 error_file = XCONS (XCONS (buffer)->cdr)->car; | |
246 buffer = XCONS (buffer)->car; | |
247 } | |
248 | |
249 if (!(EQ (buffer, Qnil) | |
250 || EQ (buffer, Qt) | |
251 || XFASTINT (buffer) == 0)) | |
252 { | |
253 Lisp_Object spec_buffer; | |
254 spec_buffer = buffer; | |
255 buffer = Fget_buffer (buffer); | |
256 /* Mention the buffer name for a better error message. */ | |
257 if (NILP (buffer)) | |
258 CHECK_BUFFER (spec_buffer, 2); | |
234 CHECK_BUFFER (buffer, 2); | 259 CHECK_BUFFER (buffer, 2); |
235 } | 260 } |
236 } | 261 } |
237 else | 262 else |
238 buffer = Qnil; | 263 buffer = Qnil; |
343 { | 368 { |
344 /* child_setup must clobber environ in systems with true vfork. | 369 /* child_setup must clobber environ in systems with true vfork. |
345 Protect it from permanent change. */ | 370 Protect it from permanent change. */ |
346 register char **save_environ = environ; | 371 register char **save_environ = environ; |
347 register int fd1 = fd[1]; | 372 register int fd1 = fd[1]; |
373 int fd_error = fd1; | |
348 | 374 |
349 #if 0 /* Some systems don't have sigblock. */ | 375 #if 0 /* Some systems don't have sigblock. */ |
350 mask = sigblock (sigmask (SIGCHLD)); | 376 mask = sigblock (sigmask (SIGCHLD)); |
351 #endif | 377 #endif |
352 | 378 |
371 unlink (tempfile); | 397 unlink (tempfile); |
372 close (filefd); | 398 close (filefd); |
373 report_file_error ("Cannot re-open temporary file", Qnil); | 399 report_file_error ("Cannot re-open temporary file", Qnil); |
374 } | 400 } |
375 #else /* not MSDOS */ | 401 #else /* not MSDOS */ |
402 | |
403 if (NILP (error_file)) | |
404 fd_error = open (NULL_DEVICE, O_WRONLY); | |
405 else if (STRINGP (error_file)) | |
406 { | |
407 #ifdef DOS_NT | |
408 fd_error = open (XSTRING (error_file)->data, | |
409 O_WRONLY | O_TRUNC | O_CREAT | O_TEXT, | |
410 S_IREAD | S_IWRITE); | |
411 #else /* not DOS_NT */ | |
412 fd_error = creat (XSTRING (error_file)->data, 0666); | |
413 #endif /* not DOS_NT */ | |
414 } | |
415 | |
416 if (fd_error < 0) | |
417 { | |
418 close (filefd); | |
419 close (fd[0]); | |
420 if (fd1 >= 0) | |
421 close (fd1); | |
422 report_file_error ("Cannot open", error_file); | |
423 } | |
424 | |
376 #ifdef WINDOWSNT | 425 #ifdef WINDOWSNT |
377 pid = child_setup (filefd, fd1, fd1, new_argv, 0, current_dir); | 426 pid = child_setup (filefd, fd1, fd_error, new_argv, 0, current_dir); |
378 #else /* not WINDOWSNT */ | 427 #else /* not WINDOWSNT */ |
379 pid = vfork (); | 428 pid = vfork (); |
380 | 429 |
381 if (pid == 0) | 430 if (pid == 0) |
382 { | 431 { |
385 #ifdef USG | 434 #ifdef USG |
386 setpgrp (); | 435 setpgrp (); |
387 #else | 436 #else |
388 setpgrp (pid, pid); | 437 setpgrp (pid, pid); |
389 #endif /* USG */ | 438 #endif /* USG */ |
390 child_setup (filefd, fd1, fd1, new_argv, 0, current_dir); | 439 child_setup (filefd, fd1, fd_error, new_argv, 0, current_dir); |
391 } | 440 } |
392 #endif /* not MSDOS */ | 441 #endif /* not MSDOS */ |
393 #endif /* not WINDOWSNT */ | 442 #endif /* not WINDOWSNT */ |
394 | 443 |
395 environ = save_environ; | 444 environ = save_environ; |
499 | 548 |
500 DEFUN ("call-process-region", Fcall_process_region, Scall_process_region, | 549 DEFUN ("call-process-region", Fcall_process_region, Scall_process_region, |
501 3, MANY, 0, | 550 3, MANY, 0, |
502 "Send text from START to END to a synchronous process running PROGRAM.\n\ | 551 "Send text from START to END to a synchronous process running PROGRAM.\n\ |
503 Delete the text if fourth arg DELETE is non-nil.\n\ | 552 Delete the text if fourth arg DELETE is non-nil.\n\ |
553 \n\ | |
504 Insert output in BUFFER before point; t means current buffer;\n\ | 554 Insert output in BUFFER before point; t means current buffer;\n\ |
505 nil for BUFFER means discard it; 0 means discard and don't wait.\n\ | 555 nil for BUFFER means discard it; 0 means discard and don't wait.\n\ |
556 BUFFER can also have the form (REAL-BUFFER STDERR-FILE); in that case,\n\ | |
557 REAL-BUFFER says what to do with standard output, as above,\n\ | |
558 while STDERR-FILE says what to do with standard error in the child.\n\ | |
559 STDERR-FILE may be nil (discard standard error output),\n\ | |
560 t (mix it with ordinary output), or a file name string.\n\ | |
561 \n\ | |
506 Sixth arg DISPLAY non-nil means redisplay buffer as output is inserted.\n\ | 562 Sixth arg DISPLAY non-nil means redisplay buffer as output is inserted.\n\ |
507 Remaining args are passed to PROGRAM at startup as command args.\n\ | 563 Remaining args are passed to PROGRAM at startup as command args.\n\ |
508 If BUFFER is nil, returns immediately with value nil.\n\ | 564 \n\ |
509 Otherwise waits for PROGRAM to terminate\n\ | 565 If BUFFER is nil, `call-process-region' returns immediately with value nil.\n\ |
566 Otherwise it waits for PROGRAM to terminate\n\ | |
510 and returns a numeric exit status or a signal description string.\n\ | 567 and returns a numeric exit status or a signal description string.\n\ |
511 If you quit, the process is killed with SIGINT, or SIGKILL if you quit again.") | 568 If you quit, the process is killed with SIGINT, or SIGKILL if you quit again.") |
512 (nargs, args) | 569 (nargs, args) |
513 int nargs; | 570 int nargs; |
514 register Lisp_Object *args; | 571 register Lisp_Object *args; |