[Top][All Lists]

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

Re: Device 0 is not a termcap terminal device

From: Stefan Monnier
Subject: Re: Device 0 is not a termcap terminal device
Date: Tue, 01 Sep 2009 19:20:01 -0400
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/23.1.50 (gnu/linux)

> A little less that a year ago, I supplied a "me too" to this bug in which
> batch programs would crash with the error message

>     Device 0 is not a termcap terminal device

> I have now tracked this bug down: `send-string-to-terminal' crashes in
> -batch.  To see this, compare the following:

Does the patch below help?

> The documentation of the function in the Elisp manual for Emacs 22
> just said that the string is sent to "the terminal", which presumable
> means stdout.

There's a subtle difference between the two, but yes, they used to be
pretty much the same.  With multi-tty, the difference is made
more significant.

> In Emacs 23's Elisp, it says the string goes to "the selected frame's
> terminal", which is clearly undefined in batch mode.

Actually, it is well defined: when Emacs starts it starts with a special
frame on a special terminal (a dumb terminal), later on, this terminal
is usually deleted and replaced with an X11 or tty terminal, except in
batch mode and in daemon mode.  Look for the `terminal-frame' variable
and its uses in startup.el and frame.el to see it in action.

> This change wasn't in the "incompatible changes" section of NEWS, so it
> would appear to be a bug.

send-string-to-terminal is rarely used, and even more so in batch mode
(where you could argue that it worked by accident).  That's why nobody
noticed the problem (and neither decided to fix it nor to document it).


=== modified file 'src/dispnew.c'
--- src/dispnew.c       2009-08-26 02:42:52 +0000
+++ src/dispnew.c       2009-09-01 23:09:31 +0000
@@ -6090,8 +6090,9 @@
      Lisp_Object string;
      Lisp_Object terminal;
-  struct terminal *t = get_tty_terminal (terminal, 1);
+  struct terminal *t = get_terminal (terminal, 1);
   struct tty_display_info *tty;
+  FILE *out;
   /* ??? Perhaps we should do something special for multibyte strings here.  */
   CHECK_STRING (string);
@@ -6100,6 +6101,12 @@
   if (!t)
     error ("Unknown terminal device");
+  if (t->type == output_initial)
+    out = stdout;
+  else if (t->type != output_termcap && t->type != output_msdos_raw)
+    error ("Device %d is not a termcap terminal device", t->id);
+  else
+    {
   tty = t->display_info.tty;
   if (! tty->output)
@@ -6110,8 +6117,10 @@
       fwrite (SDATA (string), 1, SBYTES (string), tty->termscript);
       fflush (tty->termscript);
-  fwrite (SDATA (string), 1, SBYTES (string), tty->output);
-  fflush (tty->output);
+      out = tty->output;
+    }
+  fwrite (SDATA (string), 1, SBYTES (string), out);
+  fflush (out);
   return Qnil;

reply via email to

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