diff options
| author | Richard M. Stallman | 1995-02-26 07:58:52 +0000 |
|---|---|---|
| committer | Richard M. Stallman | 1995-02-26 07:58:52 +0000 |
| commit | 39eaa782753bacb4cfa03f64c2ba4120edc5dc5f (patch) | |
| tree | 560cf44b18935714038145207f583d469ec91978 /src | |
| parent | 9dfab550e65080dfbea91da014ff7a78ceea22df (diff) | |
| download | emacs-39eaa782753bacb4cfa03f64c2ba4120edc5dc5f.tar.gz emacs-39eaa782753bacb4cfa03f64c2ba4120edc5dc5f.zip | |
(Fcall_process): Extend BUFFER arg so it can specify
a separate output file for stderr output.
(Fcall_process_region): Doc fix.
Diffstat (limited to 'src')
| -rw-r--r-- | src/callproc.c | 81 |
1 files changed, 69 insertions, 12 deletions
diff --git a/src/callproc.c b/src/callproc.c index 4ef634e4180..563bc5d5de6 100644 --- a/src/callproc.c +++ b/src/callproc.c | |||
| @@ -179,10 +179,17 @@ DEFUN ("call-process", Fcall_process, Scall_process, 1, MANY, 0, | |||
| 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) |
| @@ -198,6 +205,9 @@ If you quit, the process is killed with SIGINT, or SIGKILL if you quit again.") | |||
| 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; |
| @@ -207,6 +217,8 @@ If you quit, the process is killed with SIGINT, or SIGKILL if you quit again.") | |||
| 207 | #endif | 217 | #endif |
| 208 | CHECK_STRING (args[0], 0); | 218 | CHECK_STRING (args[0], 0); |
| 209 | 219 | ||
| 220 | error_file = Qt; | ||
| 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])) |
| @@ -223,14 +235,27 @@ If you quit, the process is killed with SIGINT, or SIGKILL if you quit again.") | |||
| 223 | 235 | ||
| 224 | if (nargs >= 3) | 236 | if (nargs >= 3) |
| 225 | { | 237 | { |
| 226 | register Lisp_Object tem; | 238 | buffer = args[2]; |
| 239 | |||
| 240 | /* If BUFFER is a list, its meaning is | ||
| 241 | (BUFFER-FOR-STDOUT FILE-FOR-STDERR). */ | ||
| 242 | if (CONSP (buffer)) | ||
| 243 | { | ||
| 244 | if (CONSP (XCONS (buffer)->cdr)) | ||
| 245 | error_file = XCONS (XCONS (buffer)->cdr)->car; | ||
| 246 | buffer = XCONS (buffer)->car; | ||
| 247 | } | ||
| 227 | 248 | ||
| 228 | buffer = tem = args[2]; | 249 | if (!(EQ (buffer, Qnil) |
| 229 | if (!(EQ (tem, Qnil) | 250 | || EQ (buffer, Qt) |
| 230 | || EQ (tem, Qt) | 251 | || XFASTINT (buffer) == 0)) |
| 231 | || XFASTINT (tem) == 0)) | ||
| 232 | { | 252 | { |
| 233 | buffer = Fget_buffer (tem); | 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 | } |
| @@ -345,6 +370,7 @@ If you quit, the process is killed with SIGINT, or SIGKILL if you quit again.") | |||
| 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)); |
| @@ -373,8 +399,31 @@ If you quit, the process is killed with SIGINT, or SIGKILL if you quit again.") | |||
| 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 | ||
| @@ -387,7 +436,7 @@ If you quit, the process is killed with SIGINT, or SIGKILL if you quit again.") | |||
| 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 */ |
| @@ -501,12 +550,20 @@ 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) |