Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 11 Oct 2009 13:51:09 +0300
From:      Mikolaj Golub <to.my.trociny@gmail.com>
To:        freebsd-stable@freebsd.org
Subject:   can't change tty speed and buffer size on 8.0
Message-ID:  <861vla2ogy.fsf@kopusha.onet>

next in thread | raw e-mail | index | archive | help
Hi,

On 8.0-RC1 if you run this command:

cat > /dev/null

and try to input a long line, the maximum length you can input is 1920
characters.

I have investigated a bit how I can increase a tty buffer as this is a problem
for me (I have logs with very long lines and I used to copy&past a particular
line into input of some script to structure it).

According to kern/tty.c:tty_watermarks() the input buffer size is set as
ispeed / 5. The default speed is 9600 that is rather low:

/usr/include/sys/ttydefaults.h:#define  TTYDEF_SPEED    (B9600)

So to increase the buffer size I need to decrease tty speed. But this does not
work:

zhuzha:/tmp% stty                    
speed 9600 baud;
lflags: echoe echok echoke echoctl
iflags: -ixany -imaxbel
oflags: tab0
cflags: cs8 parenb
eol2    erase   status  
^@      ^H      <undef> 
zhuzha:/tmp% stty ispeed 38400
zhuzha:/tmp% stty             
speed 9600 baud;
lflags: echoe echok echoke echoctl
iflags: -ixany -imaxbel
oflags: tab0
cflags: cs8 parenb
eol2    erase   status  
^@      ^H      <undef> 

I can change tty speed on 7.X but can't on 8.0. I ran this simple dtrace
program to see what is going on:

tty*:entry
/execname == "stty"/
{
        printf("%s entered; args0-4: %d %d %d %d %d\n",
               probefunc, arg0, arg1, arg2, arg3, arg4);
}

tty*:return
/execname == "stty"/
{
        printf("%s returned %d\n", probefunc, arg1);
}

And here is the relevant part of the output:

ttydev_ioctl entered; arguments: 3313875456 2150396948 3363021248 3 3357835264
tty_wait_background entered; arguments: 3354367492 0 3234498062 158 0
tty_wait_background returned 0
tty_ioctl entered; arguments: 3354367488 2150396948 3363021248 3357835264 0
ttydevsw_defioctl entered; arguments: 3354367488 2150396948 3363021248 3357835264 0
ttydevsw_defioctl returned 4294967293
ttydevsw_defparam entered; arguments: 3354367488 3363021248 3363021248 3357835264 0
ttydevsw_defparam returned 0
tty_watermarks entered; arguments: 3354367488 3363021248 3363021248 3357835264 0
ttyinq_setsize entered; arguments: 3354367528 3354367488 1920 0 3875601352
ttyinq_setsize returned 15
ttyoutq_setsize entered; arguments: 3354367572 3354367488 1920 0 3875601352
ttyoutq_setsize returned 3545052638
tty_watermarks returned 858997088
ttydisc_optimize entered; arguments: 3354367488 3363021264 20 3357835264 0
ttydisc_optimize returned 0
tty_ioctl returned 0
ttydev_ioctl returned 0

As you can see, before calling tty_watermarks() and ttyinq_setsize(),
ttydevsw_defparam() is called that do only this thing:

        /* Use a fake baud rate, we're not a real device. */
        t->c_ispeed = t->c_ospeed = TTYDEF_SPEED;

As a result the speed of terminal is always set to TTYDEF_SPEED and
ttyinq_setsize() is always called with size=1920 (TTYDEF_SPEED/5).

This all happens in tty_generic_ioctl() in this part:

                /*
                 * Only call param() when the flags really change.
                 */
                if ((t->c_cflag & CIGNORE) == 0 &&
                    (tp->t_termios.c_cflag != t->c_cflag ||
                    tp->t_termios.c_ispeed != t->c_ispeed ||
                    tp->t_termios.c_ospeed != t->c_ospeed)) {
                        error = ttydevsw_param(tp, t);
                        if (error)
                                return (error);

                        /* XXX: CLOCAL? */

                        tp->t_termios.c_cflag = t->c_cflag & ~CIGNORE;
                        tp->t_termios.c_ispeed = t->c_ispeed;
                        tp->t_termios.c_ospeed = t->c_ospeed;

                        /* Baud rate has changed - update watermarks. */
                        tty_watermarks(tp);
                }

AFAIR ttydevsw_param() runs tty hooks and ttydevsw_defparam() among them.

So you can't change the speed of terminal and the size of input buffer on
running system. Only by recompiling the kernel with updated TTYDEF_SPEED.

Is this intentional or does it look rather like a bug?

-- 
Mikolaj Golub



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?861vla2ogy.fsf>