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;