emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

towards sh-like 1> and 2> emulation: emacs-exit-messages


From: Thien-Thi Nguyen
Subject: towards sh-like 1> and 2> emulation: emacs-exit-messages
Date: Tue, 31 Jul 2012 23:24:40 +0200
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/24.1 (gnu/linux)

On another (explicitly unnamed) mailing list, there is discussion of
replacing the standalone info reader w/ a specially-dumped (purpose
built) Emacs.  Reuben Thomas posted a workable sketch that exposes two
problems (i.e., "code enhancement opportunities" as was known in some
circles):

 - forced async operation of ‘man’
   workaround: zonk ‘start-process’

 - reliance on /bin/sh to display a message to stderr
   
The first can be addressed purely in Lisp, and is not the subject of
this message (i trust someone will DTRT).  The second is part of a more
general infelicity in using Emacs in batch (or "semi-batch") mode.  The
global var ‘noninteractive’ is much too crude a switch for such cases.
So, refinement is indicated.

But where?

At first, i tried mucking w/ src/print.c func ‘strout’, interpreting a
small-integer (file-descriptor-ish) ‘printcharfun’ as a specification
for stdout (1) or stderr (2) in another ‘else if’ clause.  This failed
to produce output, and i didn't investigate.  Was i too hasty?

The second approach is attached (caveat: just a sketch; no multibyte,
locale, bidi awareness; poor error handling) here:

commit bb69d9879f9ff7ed0659a8e7505479275affd9b9
Author: Thien-Thi Nguyen <address@hidden>
Date:   2012-07-31 22:18:28 +0200

    Add var ‘emacs-exit-messages’ and handle it during shutdown.

    * emacs.c (shut_down_emacs): After resetting the tty, display
    any strings specified by ‘emacs-exit-messages’ to stderr/stdout.
    (syms_of_emacs Vemacs_exit_messages): New DEFVAR_LISP.
---
 src/emacs.c |   32 ++++++++++++++++++++++++++++++++
 1 files changed, 32 insertions(+), 0 deletions(-)

diff --git a/src/emacs.c b/src/emacs.c
index 2194cfe..210c5a5 100644
--- a/src/emacs.c
+++ b/src/emacs.c
@@ -2051,6 +2051,30 @@ shut_down_emacs (int sig, int no_x, Lisp_Object stuff)
   reset_all_sys_modes ();
 #endif

+  /* If there are any messages, display them now.
+     Silently ignore ill-formed data, which is a latent bug.  */
+  while (CONSP (Vemacs_exit_messages))
+    {
+      Lisp_Object msg = Fcar (Vemacs_exit_messages);
+      FILE *to = stderr;
+
+      if (CONSP (msg) && INTEGERP (Fcar (msg)))
+        {
+          if (1 == XINT (Fcar (msg)))
+            to = stdout;
+          msg = Fcdr (msg);
+        }
+      if (STRINGP (msg))
+        {
+          size_t expected = SBYTES (msg);
+          size_t actually = fwrite (SDATA (msg), 1, expected, to);
+
+          if (expected > actually)
+            abort ();
+        }
+      Vemacs_exit_messages = Fcdr (Vemacs_exit_messages);
+    }
+
   stuff_buffered_input (stuff);

   inhibit_sentinels = 1;
@@ -2438,6 +2462,14 @@ Before Emacs 24.1, the hook was not run in batch mode, 
i.e., if
 `noninteractive' was non-nil.  */);
   Vkill_emacs_hook = Qnil;

+  DEFVAR_LISP ("emacs-exit-messages", Vemacs_exit_messages,
+               doc: /* List of strings to display to stderr at exit.
+These are output as-is, so you need to include a newline.
+Each element may also have form (FD . STRING), where FD is
+a small integer: 1 for standard output, 2 for standard error.
+All other FD values are taken as 2.  */);
+  Vemacs_exit_messages = Qnil;
+
   DEFVAR_LISP ("path-separator", Vpath_separator,
               doc: /* String containing the character that separates 
directories in
 search paths, such as PATH and other similar environment variables.  */);
OT1H, this is still relatively crude; saving output to the end is both
inelegant and suboptimal (but perhaps i repeat myself).  OTOH, it does
the job: Emacs can effect sh-like ‘1>’ and ‘2>’ control to fellow and
parent processes, finally.

Anyway, w/ that patch applied, the following program, slightly modified
From the original, works fine (look ma, no /bin/sh!) w/ invocations:

$ /tmp/info cat        # interactive, "(coreutils) cat invocation"
$ /tmp/info emacs      # interactive, "(emacs) Top"
$ /tmp/info zow        # noninteractive, exit 1, msg on stderr

To play, save to /tmp/info, chmod +x, and frob "bloody-emacs" to taste.

Attachment: info
Description: Binary data

Now just watch: Someone will tell me this is already doable... :-/

-- 
Thien-Thi Nguyen ..................................... GPG key: 4C807502
.                  NB: ttn at glug dot org is not me                   .
.                 (and has not been since 2007 or so)                  .
.                        ACCEPT NO SUBSTITUTES                         .
........... please send technical questions to mailing lists ...........

Attachment: pgpWPz3WcZ6S5.pgp
Description: PGP signature


reply via email to

[Prev in Thread] Current Thread [Next in Thread]