From: Lars Magne Ingebrigtsen <larsi@gnus.org>
To: emacs-devel@gnu.org
Subject: Re: Redirecting standard output
Date: Thu, 21 Apr 2011 16:25:13 +0200 [thread overview]
Message-ID: <m3zknjlm0m.fsf@quimbies.gnus.org> (raw)
In-Reply-To: m3hb9rn661.fsf@quimbies.gnus.org
[-- Attachment #1: Type: text/plain, Size: 636 bytes --]
Here's a quick stab at it. There's some cargo-cult programming in
there, and I have to go over the error cases again to make sure there's
no FD leaks, but it'll probably look something like the patch included.
Usage is:
(call-process "echo" nil '(:file "/tmp/hello") nil "thing")
or
(call-process "echo" nil '((:file "/tmp/hello") "/tmp/error") nil "thing")
So with this, `call-process' can do all the combinations of
STDERR/STDOUT to file/buffers, except that you can't put STDERR in one
buffer and STDOUT in a different buffer.
But you can get STDERR in a buffer by itself, and STDOUT in a file, so
it's progress of a kind...
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: callproc.patch --]
[-- Type: text/x-diff, Size: 5445 bytes --]
=== modified file 'src/callproc.c'
*** src/callproc.c 2011-04-14 19:34:42 +0000
--- src/callproc.c 2011-04-21 14:17:44 +0000
***************
*** 96,101 ****
--- 96,103 ----
/* Nonzero if this is termination due to exit. */
static int call_process_exited;
+ static Lisp_Object Qcallproc_file_symbol;
+
static Lisp_Object Fgetenv_internal (Lisp_Object, Lisp_Object);
static Lisp_Object
***************
*** 196,205 ****
--- 198,209 ----
/* File to use for stderr in the child.
t means use same as standard output. */
Lisp_Object error_file;
+ Lisp_Object output_file = Qnil;
#ifdef MSDOS /* Demacs 1.1.1 91/10/16 HIRANO Satoshi */
char *outf, *tempfile;
int outfilefd;
#endif
+ int fd_output = 0;
struct coding_system process_coding; /* coding-system of process output */
struct coding_system argument_coding; /* coding-system of arguments */
/* Set to the return value of Ffind_operation_coding_system. */
***************
*** 275,281 ****
/* If BUFFER is a list, its meaning is
(BUFFER-FOR-STDOUT FILE-FOR-STDERR). */
! if (CONSP (buffer))
{
if (CONSP (XCDR (buffer)))
{
--- 279,286 ----
/* If BUFFER is a list, its meaning is
(BUFFER-FOR-STDOUT FILE-FOR-STDERR). */
! if (CONSP (buffer) &&
! ! EQ (Qcallproc_file_symbol, XCAR (buffer)))
{
if (CONSP (XCDR (buffer)))
{
***************
*** 291,296 ****
--- 296,312 ----
buffer = XCAR (buffer);
}
+ /* If the buffer is (still) a list, it might be a (:file "file") spec. */
+ if (CONSP (buffer) &&
+ CONSP (XCDR (buffer)) &&
+ EQ (Qcallproc_file_symbol, XCAR (buffer)))
+ {
+ output_file = Fexpand_file_name (XCAR (XCDR (buffer)),
+ BVAR (current_buffer, directory));
+ CHECK_STRING (output_file);
+ buffer = Qnil;
+ }
+
if (!(EQ (buffer, Qnil)
|| EQ (buffer, Qt)
|| INTEGERP (buffer)))
***************
*** 318,328 ****
protected by the caller, so all we really have to worry about is
buffer. */
{
! struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
current_dir = BVAR (current_buffer, directory);
! GCPRO4 (infile, buffer, current_dir, error_file);
current_dir = Funhandled_file_name_directory (current_dir);
if (NILP (current_dir))
--- 334,344 ----
protected by the caller, so all we really have to worry about is
buffer. */
{
! struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5;
current_dir = BVAR (current_buffer, directory);
! GCPRO5 (infile, buffer, current_dir, error_file, output_file);
current_dir = Funhandled_file_name_directory (current_dir);
if (NILP (current_dir))
***************
*** 342,347 ****
--- 358,365 ----
current_dir = ENCODE_FILE (current_dir);
if (STRINGP (error_file) && STRING_MULTIBYTE (error_file))
error_file = ENCODE_FILE (error_file);
+ if (STRINGP (output_file) && STRING_MULTIBYTE (output_file))
+ output_file = ENCODE_FILE (output_file);
UNGCPRO;
}
***************
*** 353,358 ****
--- 371,394 ----
infile = DECODE_FILE (infile);
report_file_error ("Opening process input file", Fcons (infile, Qnil));
}
+
+ if (STRINGP (output_file))
+ {
+ #ifdef DOS_NT
+ fd_output = emacs_open (SSDATA (output_file),
+ O_WRONLY | O_TRUNC | O_CREAT | O_TEXT,
+ S_IREAD | S_IWRITE);
+ #else /* not DOS_NT */
+ fd_output = creat (SSDATA (output_file), 0666);
+ #endif /* not DOS_NT */
+ if (fd_output < 0)
+ {
+ output_file = DECODE_FILE (output_file);
+ report_file_error ("Opening process output file",
+ Fcons (output_file, Qnil));
+ }
+ }
+
/* Search for program; barf if not found. */
{
struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
***************
*** 413,425 ****
strcat (tempfile, "detmp.XXX");
mktemp (tempfile);
! outfilefd = creat (tempfile, S_IREAD | S_IWRITE);
! if (outfilefd < 0)
{
emacs_close (filefd);
report_file_error ("Opening process output file",
! Fcons (build_string (tempfile), Qnil));
}
fd[0] = filefd;
fd[1] = outfilefd;
#endif /* MSDOS */
--- 449,467 ----
strcat (tempfile, "detmp.XXX");
mktemp (tempfile);
! /* If we're redirecting STDOUT to a file, this is already opened. */
! if (fd_output == 0)
{
+ outfilefd = creat (tempfile, S_IREAD | S_IWRITE);
+ if (outfilefd < 0)
+ {
emacs_close (filefd);
report_file_error ("Opening process output file",
! Fcons (build_string (tempfile), Qnil));
! }
}
+ else
+ outfilefd = fd_output;
fd[0] = filefd;
fd[1] = outfilefd;
#endif /* MSDOS */
***************
*** 450,455 ****
--- 492,499 ----
struct sigaction sigpipe_action;
#endif
+ if (fd_output > 0)
+ fd1 = fd_output;
#if 0 /* Some systems don't have sigblock. */
mask = sigblock (sigmask (SIGCHLD));
#endif
***************
*** 1554,1559 ****
--- 1598,1606 ----
#endif
staticpro (&Vtemp_file_name_pattern);
+ Qcallproc_file_symbol = intern_c_string (":file");
+ staticpro (&Qcallproc_file_symbol);
+
DEFVAR_LISP ("shell-file-name", Vshell_file_name,
doc: /* *File name to load inferior shells from.
Initialized from the SHELL environment variable, or to a system-dependent
[-- Attachment #3: Type: text/plain, Size: 182 bytes --]
(Note! Not thoroughly tested. I'll go through all the possibilities
now...)
--
(domestic pets only, the antidote for overdose, milk.)
bloggy blog http://lars.ingebrigtsen.no/
prev parent reply other threads:[~2011-04-21 14:25 UTC|newest]
Thread overview: 37+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-04-20 21:19 Redirecting standard output Lars Magne Ingebrigtsen
2011-04-20 22:54 ` Stefan Monnier
2011-04-21 1:54 ` Lars Magne Ingebrigtsen
2011-04-21 6:10 ` Eli Zaretskii
2011-04-21 11:45 ` Lars Magne Ingebrigtsen
2011-04-21 13:25 ` Lars Magne Ingebrigtsen
2011-04-21 14:10 ` Eli Zaretskii
2011-04-21 15:15 ` Lars Magne Ingebrigtsen
2011-04-21 15:46 ` Lars Magne Ingebrigtsen
2011-04-21 16:15 ` Eli Zaretskii
2011-04-21 16:22 ` Lars Magne Ingebrigtsen
2011-04-21 16:24 ` Lars Magne Ingebrigtsen
2011-04-21 16:55 ` Eli Zaretskii
2011-04-21 17:05 ` Jan Djärv
2011-04-21 19:15 ` Eli Zaretskii
2011-04-21 19:19 ` Davis Herring
2011-04-21 19:31 ` Lars Magne Ingebrigtsen
2011-04-22 5:50 ` Eli Zaretskii
2011-04-23 18:46 ` Lars Magne Ingebrigtsen
2011-04-23 20:10 ` Eli Zaretskii
2011-04-24 8:30 ` Jan Djärv
2011-04-30 23:58 ` Lars Magne Ingebrigtsen
2011-05-01 0:06 ` Lars Magne Ingebrigtsen
2011-05-01 17:56 ` Andy Moreton
2011-05-07 11:34 ` Eli Zaretskii
2011-05-07 12:10 ` Eli Zaretskii
2011-05-30 17:39 ` Lars Magne Ingebrigtsen
2011-04-21 16:29 ` Glenn Morris
2011-04-21 8:27 ` Michael Albinus
2011-04-21 5:57 ` Eli Zaretskii
2011-04-21 6:28 ` Thierry Volpiatto
2011-04-21 6:41 ` Eli Zaretskii
2011-04-21 7:33 ` Thierry Volpiatto
2011-04-21 11:40 ` Lars Magne Ingebrigtsen
2011-04-21 11:58 ` Eli Zaretskii
2011-04-21 12:24 ` Lars Magne Ingebrigtsen
2011-04-21 14:25 ` Lars Magne Ingebrigtsen [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=m3zknjlm0m.fsf@quimbies.gnus.org \
--to=larsi@gnus.org \
--cc=emacs-devel@gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this external index
https://git.savannah.gnu.org/cgit/emacs.git
https://git.savannah.gnu.org/cgit/emacs/org-mode.git
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.