2

According to this page, this field describes the "line discipline", which determines what happens when a user presses backspace or ^C. Essentially, what happens when a program calls read(2).

However, setting it seems to have no effect. On my Linux machine, I have two line disciplines:

$ cat /proc/tty/ldiscs
n_tty       0
n_null     27

but $ stty line 27 doesn't seems to affect anything. Backspace still works as normal.

If I do $ stty -icanon, however, I do see a change---backspace no longer works normally, and programs read things character by character (read(2) seems to always return just 1 character).

What's going on here?

2

Line disciplines are a layer between the tty driver and the tty core (see this picture, from here): enter image description here

If you set it to 27 (tty_null) your date goes through the left side of the diagram (skipping the line discipline). If you set it to 0 then it goes through the default line discipline, that can handle both raw input, and cooked input.

TTY(0)
    The default line discipline, providing transparent operation (raw mode)
    as well as the habitual terminal line editing capabilities (cooked mode).

A list of other disciplines is here.

You can write your own, or use one an existing one. I you have the slip module and you insert it modprobe slip, you will notice this:

$ cat /proc/tty/ldiscs 
n_tty       0
slip        1
n_null     27

When you did $ stty line 27 you removed the line discipline (you set it to the null line discipline), when you did $ stty -icanon you set the default line discipline, in raw mode.

  • Right so what will be different when I set the ldisc to 27? How can I notice the difference? – extremeaxe5 Nov 12 at 16:55
  • The difference between no filter at all and a passthrough filter (raw mode) is just the number of layers the data traverses. I you sent huge amounts of data, you could expect more resources to be used. Anyway, the things I think you want to notice are all set at the tty core level (icanon, brk, ...), on top of the tty discipline. If you see the source code for the default line discipline you will find how icanon or echo are read and used. – Eduardo Trápani Nov 12 at 18:12
2

stty line N is not doing much of anything.

To change the line discipline on Linux, it should call ioctl(TIOCSETD), but it's not doing that; stty line N is just changing the (non-standard) c_line field of the termios struct, and then calling tcsetattr(3) -> ioctl(TCSETS*), which will simply change the c_line field that will be returned by subsequent tcgetattr(3) -> ioctl(TCGETS) calls.

At the end of this answer is small C example program which should really change the line discipline on its stdin fd.

This is not the only way stty(1) is inadequate; stty is also not able to set "non-standard" baud rates (which could be easily done on Linux with the TCSETS2/TCSETSW2/TCSETSF2 ioctls, but which unfortunately are not exposed in the standard C library, and are not used by stty).

$ cat > tiocsetd.c <<'EOT'
#include <sys/ioctl.h>
#include <stdio.h>
#include <stdlib.h>
#include <termios.h>
#include <err.h>

int main(int ac, char **av){
        int o;
        if(ioctl(0, TIOCGETD, &o)) err(1, "io(TIOCGETD)");
        if(ac > 1){
                int n, d = atoi(av[1]);
                if(ioctl(0, TIOCSETD, &d)) err(1, "io(TIOCSETD)");
                if(ioctl(0, TIOCGETD, &n)) err(1, "io(TIOCGETD)");
                printf("%d -> %d => %d\n", o, d, n);
        }else
                printf("%d\n", o);
        return 0;
}
EOT
$ cc -Wall tiocsetd.c -o tiocsetd
$ ./tiocsetd
0

$ tty
/dev/pts/4 ## << make a note of this
$ cat /proc/tty/ldiscs
n_tty       0
n_null     27
$ ./tiocsetd 27
<your tty is hugged ;-)>

To restore it, run ./tiocsetd 0 </dev/pts/4 from another terminal (replace /dev/pts/4 with the actual tty), then press ^C.

  • Wait so it just changes the value returned when querying the ldisc? It doesn't otherwise change the tty's line processing? – extremeaxe5 Nov 12 at 16:56
  • Trying this just killed my bash process. – extremeaxe5 Nov 12 at 17:01
  • 1. Yes. 2. No, it did not. – mosvy Nov 12 at 22:22
  • btw, "querying the ldisc" is done with TIOCGETD as already shown in my example. – mosvy Nov 12 at 22:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.