2

This is a problem I've been trying to solve on my own for some time without any luck. I'm trying to write a script that (amongst other things) can take an arbitrary PID and map it to TTY device's path (the function I'm writing will return "(notty)" if there isn't an associated TTY).

In my attempt to do the above I've been trying to use the the tty_nr in /proc/[pid]/stat:

tty_nr %d   (7) The controlling terminal of the process.  (The
                          minor device number is contained in the
                          combination of bits 31 to 20 and 7 to 0; the major
                          device number is in bits 15 to 8.)

I can extract the major and minor numbers, no problem. My issue comes into play when I try to translate that into a device path: Do I just do a find under /dev for a match and accept the first one? Is there a more elegant way of doing this?

I did find this and it seems that the python script has some sort of mapping of tty_nr numbers to physical paths but I can't find any other part of the script that actually populates this list to see where they're getting their data from to see if I can create a Linux analog. It's also possible that it depends on some BSD-ism but I ran into a brick wall.

Basically, I'm trying to not kick off another process if I can help it. Also, the whole "kick off a process with an unknown number of results but only take the first result" approach seems kind of...kludgy. Since I have to show this code to other people I'd like to have a more or less deterministic way of accomplishing this. I would like some guarantee that if (for any reason) there are multiple device files underneath /dev with that major/minor (kind of a corner case, I know, but it'll bug me) that my code will default to whatever the "official" path to the TTY is.

Of course if my concerns about non-determinism of the extract-then-search method are unfounded, that would be good news, I would just want to understand why they're unfounded. All else fails I guess I could just try restricted searches for common paths (/dev/pts* /dev/tty* etc) before moving onto a sweep of all /dev.

2 Answers 2

2

You could create the "official" tty name from the minor number and check for its existence (and major / minor number, of course). If the minor number is 5 then you first check whether tty5 exists and has the correct mapping. If either fails then you have to search (and make a policy what to return if multiple matches exist).

Edit 1:

From Documentation/devices.txt:

3 char Pseudo-TTY slaves
      0 = /dev/ttyp0    First PTY slave
      1 = /dev/ttyp1    Second PTY slave
        ...
    255 = /dev/ttyef    256th PTY slave

    These are the old-style (BSD) PTY devices; Unix98
    devices are on major 136 and above.


4 char  TTY devices
      0 = /dev/tty0     Current virtual console

      1 = /dev/tty1     First virtual console
        ...
     63 = /dev/tty63    63rd virtual console
     64 = /dev/ttyS0    First UART serial port
        ...
    255 = /dev/ttyS191  192nd UART serial port
2
  • Excellent idea! I am noticing, though, that the minor number doesn't always match up with the tty number (for instance ttyS0 has a minor number of 64 on my system). Are these standardized (will 64 always be the first serial tty)?
    – Bratchley
    Jun 21, 2013 at 13:21
  • nm the question, I did some googling and found it thanks again.
    – Bratchley
    Jun 21, 2013 at 13:27
1

I might be missing something here, but could you not just use ps?

tty="/dev/`ps --no-headers -o tty -p pid`"
2
  • I might end up doing something like that, but my motivation of avoiding that is part of the same reason I'm hesitant to kind of a find I'm trying to not call other binaries much as possible. I also don't know what the behavior of ps is in regards to the multiple tty thing
    – Bratchley
    Jun 21, 2013 at 13:09
  • Given who I'm going to show this to, basically I feel like I'm going to have to answer for whatever I'm creating and cover any questions that may come up ("What if x..." sort of thing). Not that this is a huge part of the script, but it may come up.
    – Bratchley
    Jun 21, 2013 at 13:11

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .