John.Tytgat at aaug.net
Tue Dec 30 09:04:38 PST 2003
Currently the getpass() function in UnixLib does not work properly, i.e. it
displays the characters you're typing. This can be traced back to
__ttyioctl(TIOCGETP) call which doesn't fill in gtty->sg_ospeed (instead
it fills in gtty->sg_ispeed twice) and this makes tcsetattr() fail when
it loops over the __bsd_speeds array (BTW, the end-loop detection is
wrong there but that doesn't matter for this discussion).
Fixing this, makes getpass() work again. A CVS update is in the pipeline.
However, there is IMHO another problem which I don't know if (and how) this
needs fixing. The __ttyioctl(TIOCGETP) call transfers term->__ispeed value
into gtty->sg_ispeed. Note that the type of term->__ispeed is 'speed_t'
(or 'long int') and the type of gtty->sg_ispeed is 'char'. My understanding
is that in both variables the used is supposed to fill in the 'B' #defines
specified in termios.h :
/* Input and output baud rates. */
#define B0 0 /* Hang up. */
#define B50 50 /* 50 baud. */
#define B75 75 /* 75 baud. */
#define B110 110 /* 110 baud. */
#define B134 134 /* 134.5 baud. */
#define B150 150 /* 150 baud. */
#define B200 200 /* 200 baud. */
#define B300 300 /* 300 baud. */
#define B600 600 /* 600 baud. */
#define B1200 1200 /* 1200 baud. */
#define B1800 1800 /* 1800 baud. */
#define B2400 2400 /* 2400 baud. */
#define B4800 4800 /* 4800 baud. */
#define B9600 9600 /* 9600 baud. */
#define B19200 19200 /* 19200 baud. */
#define B38400 38400 /* 38400 baud. */
#define B7200 7200
#define B14400 14400
#define B28800 28800
#define B57600 57600
#define B76800 76800
#define B115200 115200
#define B230400 230400
#define EXTA 19200
#define EXTB 38400
I don't think I need to say that this gives trouble when assigning these B
values to a 'char' type variable.
BTW, the current baud value is set to 38400 which is in hex 0x9600 so
the gtty->sg_ispeed (and gtty->sg_ospeed too after the above mentioned
fix) becomes 0 which would mean 'Hang up' so more or less by accident
the tcgetattr() and tcsetattr() work.
The story isn't finished yet : it looks like this was somewhat forseen in
the past and there is a mapping from 'char' values to read baud values in
tcgetattr() and tcsetattr().
So the questions are:
1. I suppose this needs fixing, right ?
2. If so, I see two obvious ways to fix this but I don't know which one
is preferred :
a. Either change the type of sg_ispeed and sg_ospeed to 'speed_t' but
as this makes the sgttyb struct bigger and this struct gets used in
ioctl(), so I'm not sure if this is a good solution. It is also
incompatible with the sgttyb struct in TCPIPLibs (see below).
b. Another possibility for a fix would be that a similar mapping between
real baud values and 'char' compatible baud speed indications like done
in tcgetattr() & tcsetattr(), is also done in __ttyioctl(TIOCGETP /
TIOCSETP). [Aside: why not (re)using convert_baud_rate() in
unix/tty.c for this ?]
This would mean that the above mentioned #define B values need to be
changed as well.
3. Other possibilities to fix this ?
Out of curiosity, I looked at the TCPIPLibs headers of the Norcroft C
distribution. In sys/termios.h I see the same #define B values defined
(with the 2nd block only defined when _POSIX_SOURCE is defined). However
in its sys/ttydef.h I see:
/* COMPATABILITY HEADER FILE */
#define B0 0
#define B50 1
#define B75 2
#define B110 3
#define B134 4
#define B150 5
#define B200 6
#define B300 7
#define B600 8
#define B1200 9
#define B1800 10
#define B2400 11
#define B4800 12
#define B9600 13
#define EXTA 14
#define EXTB 15
#define B57600 16
#define B115200 17
#endif /* USE_OLD_TTY */
#endif /* !_SYS_TTYDEV_H_ */
Which is more or less the 2nd proposal for fixing this (but this header
is marked as "compatability header" so shouldn't act as an example ?).
Note that the TCPIPLibs distribution has the same sgttyb struct as UnixLib
does (i.e. still the 'char' type for sg_ispeed and sg_ospeed).
Any suggestions on this please ?
John Tytgat, in his comfy chair at home BASS
John.Tytgat at aaug.net ARM powered, RISC OS driven
More information about the gcc