[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Wrong 'baud_rate' initialization
From: |
Matthias Habl t2065 |
Subject: |
Wrong 'baud_rate' initialization |
Date: |
Tue, 19 Jun 2001 09:17:44 +0200 (MET DST) |
In GNU Emacs 20.6.2 (i586-acer-netbsd1.4.2, X toolkit)
of Sat Apr 29 2000 on mhibsd
configured using `configure i586-acer-netbsd1.4.2 --with-pop --with-kerberos'
Please describe exactly what actions triggered the bug
and the precise symptoms of the bug:
I'm using a VT520 at a baud rate of 115200. But the internal variable
'baud-rate' of Emacs claims that it would be only 9600. A detailed
examination of this inconsistency revealed some considerable bugs in
'sysdep.c', especially in the function init_baud_rate(). In the
following, I'm trying to demonstrate the inadequacies:
In file 'sysdep.c', line 244 (all line numbers refer to version 20.7):
extern short ospeed;
This is correct, because the manpage TERMCAP(3) says:
short ospeed;
And really, the program 'nm' yields:
/usr/lib/libtermcap.a:
tputs.o:
U __ctype_ tputs.o:0
00000004 C _PC
00000004 C _ospeed
0000003c T _tputs
But later we will see that a definition like
speed_t ospeed;
would be better, because 'speed_t' (= unsigned) hat usually 32bits.
Let us see what happens in init_baud_rate(), file sysdep.c,
from line 334:
struct termios sg;
sg.c_cflag = B9600;
tcgetattr (input_fd, &sg);
ospeed = cfgetospeed (&sg);
Does the statement 'sg.c_cflag = B9600' make any sense? The member
'c_cflag' of the structure 'termios' is a bit pattern, which contains
information about parity, number of stop bits, word size, method of
handshaking and so on. Something like 'sg.c_ospeed = B9600' would be
more reasonable, but just as useless.
The first problem arises with 'ospeed = cfgetospeed (&sg)'. The
function
speed_t cfgetospeed(const struct termios *t)
returns an unsigned (4 bytes), which is converted to the short int of
'ospeed'. Actually, debugging yielded, that 'ospeed' has the the value
49664 = 0xc200 instead of 115200 = 0x1c200, which is wrong.
Then in line 389 of 'sysdep.c' something happens, which is completely
wrong:
baud_rate = (ospeed < sizeof baud_convert /
sizeof baud_convert[0]
? baud_convert[ospeed] : 9600);
Here 'ospeed', which is already the wanted baud rate, is converted by
a formula, which yields for 'ospeed > 15' allways 9600.
I think the reason for the described bugs is the mixture of different,
partly obsolete mechanisms for describing terminals. There are two
important structures. First (in termios.h):
typedef unsigned int tcflag_t;
typedef unsigned char cc_t;
typedef unsigned int speed_t;
struct termios {
tcflag_t c_iflag; /* input flags */
tcflag_t c_oflag; /* output flags */
tcflag_t c_cflag; /* control flags */
tcflag_t c_lflag; /* local flags */
cc_t c_cc[NCCS]; /* control chars */
int c_ispeed; /* input speed */
int c_ospeed; /* output speed */
};
On the other hand there is a quite obsolete structure:
struct sgttyb {
char sg_ispeed; /* input speed */
char sg_ospeed; /* output speed */
char sg_erase; /* erase character */
char sg_kill; /* kill character */
short sg_flags; /* mode flags */
};
which can be handled with
#include <sgtty.h>
stty(int fd, struct sgttyb *buf);
gtty(int fd, struct sgttyb *buf);
or with 'ioctl (input_fd, TIOCGETP, &sg)'.
I think the conversion with 'baud_convert' was originally written for
'sgttyb.sg_ospeed' and is also used for 'termios.c_ospeed' by mistake.
For my system (and probably many others) something like
struct termios t;
tcgetattr (input_fd, &t);
baud_rate = cfgetospeed (&t);
would be the right thing.
I hope this is a useful contribution for the improvement of the
great Emacs. If you like, I'm willing to design a patch.
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- Wrong 'baud_rate' initialization,
Matthias Habl t2065 <=