I've got this working!

The proof of concept program is a bit longish to include the source in
this email, and certainly longish for such a seemingly obvious bit of data that an ordinary program would want to know about its file
descriptors. Here is the output:

[nix-shell:~/src/ac_incidental/src]$ cc identifying_tty.c

[nix-shell:~/src/ac_incidental/src]$ ./a.out
/proc/self/stat ctty dev is 136 1
/dev/tty dev is 5 0
0 is the ctty called /dev/pts/1 device ID 136 1
1 is the ctty called /dev/pts/1 device ID 136 1
2 is the ctty called /dev/pts/1 device ID 136 1
3 is the ctty called /dev/tty device ID 5 0

[nix-shell:~/src/ac_incidental/src]$ ./a.out  </dev/tty
/proc/self/stat ctty dev is 136 1
/dev/tty dev is 5 0
0 is the ctty called /dev/tty device ID 5 0
1 is the ctty called /dev/pts/1 device ID 136 1
2 is the ctty called /dev/pts/1 device ID 136 1
3 is the ctty called /dev/tty device ID 5 0

And I also noticed that the linux device list says this about major
numbers 5 and 136:

5 char  Alternate TTY devices
                  0 = /dev/tty          Current TTY device
                  1 = /dev/console      System console
                  2 = /dev/ptmx         PTY master multiplex
                 64 = /dev/cua0         Callout device for ttyS0
                    ...
                255 = /dev/cua191       Callout device for ttyS191

136-143 char    Unix98 PTY slaves
                  0 = /dev/pts/0        First Unix98 pseudo-TTY
                  1 = /dev/pts/1        Second Unix98 pesudo-TTY
                    ...

There are just two ways to determine if a file descriptor might be the controlling terminal on Linux, (/dev/tty, /proc/self/stat field 7), and you need to check both. I consider this puzzle solved, but I'd welcome a simpler solution.

--
Anthony Carrico

Reply via email to