Jamie Zawinski wrote:
I reported this bug to Red Hat on the assumption that this was a bug
in
tcsh or readline, but I suppose it's equally likely that it's a bug in
how xemacs is dealing with ptys (since the bug does not occur when
running tcsh in gnome-terminal.) I also assume they will completely
ignore my report without even looking at it, since emacs is involved.
So I'll report it to you guys as well:
http://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=82610
Since upgrading from RH 7.2 to RH 8.0, I can no longer compose long
command lines in tcsh when running in an XEmacs *shell* buffer. I don't
know whether this is a bug in tcsh, or in readline, or what, but it does
not happen with bash.
It's not merely truncating the command line -- it's also apparently
leaving the un-read characters on the input buffer, and then
interpreting them as commands afterward! This is potentially
disasterous, and could easily lead to loss of files, if there were
redirections or something on the command line.
This looks suspiciously like a problem which I've experienced over the
years; I never definitively tracked it down before, but your post
inspired me to have another try, and I think that I've nailed it (my
problem at least; maybe yours too, maybe not). It very much appears to
be a bash/readline issue. My test case is to put stdin into
non-blocking mode, with:
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
int main(void)
{
int f = fcntl(STDIN_FILENO, F_GETFL);
f |= O_NONBLOCK;
if (fcntl(STDIN_FILENO, F_SETFL, f) < 0)
return 0;
}
If I run this from bash within an xterm, bash gets EAGAIN from read(),
and (sensibly) clears the O_NONBLOCK flag:
write(2, "[glynn@cerise glynn]$ ", 22) = 22
read(0, 0xbffff0db, 1) = -1 EAGAIN (Resource temporarily unavailable)
fcntl(0, F_GETFL) = 0x802 (flags O_RDWR|O_NONBLOCK)
fcntl(0, F_SETFL, O_RDWR) = 0
If I do exactly the same thing in a shell-mode buffer, bash just
ignores the failure (and appears to execute whatever garbage happened
to be in its input buffer):
read(0, 0x8095b20, 128) = -1 EAGAIN (Resource temporarily unavailable)
rt_sigprocmask(SIG_BLOCK, [INT CHLD], [], 8) = 0
fork() = 2476
setpgid(2476, 2476) = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
--- SIGCHLD (Child exited) ---
HOWEVER:
1. If I run "bash -nolineediting" in an xterm, I get exactly the same
nonsense as with shell-mode.
2. If, in a shell-mode buffer, I do:
export TERM=ansi
bash
~/src/c/misc/nonblock
then I don't get the problem.
3. If I use "TERM=dumb" instead, I don't get it either, but:
4. If I use "TERM=emacs" I do.
5. Setting TERM to an empty string or a bogus value doesn't trigger
the bug either.
FWIW, these are the definitions of "dumb" and "emacs" (according to
infocmp):
# Reconstructed via infocmp from file: /usr/share/terminfo/d/dumb
dumb|80-column dumb tty,
am,
cols#80,
bel=^G, cr=^M, cud1=^J, ind=^J,
# Reconstructed via infocmp from file: /usr/share/terminfo/e/emacs
emacs|80-column dumb tty,
am,
cols#80,
cud1=^J, ind=^J,
BTW, I don't have a ~/.inputrc file, and /etc/inputrc doesn't include
any mention of "emacs".
So: it appears that
a) the "dumb" version of the read-a-line-of-input function doesn't
bother to check for a read failure (and presumably thinks that it got
2^32-1 bytes of input), and
b) bash automatically selects "dumb mode" if $TERM == "emacs".
Now, if this is in readline, then a similar problem could apply to any
other command-line interactive GNU program. And even if it isn't in
readline, there's a reasonable chance that anyone writing a GPL'd
shell will just lift the code from bash.
--
Glynn Clements <glynn.clements(a)virgin.net>