Finding the terminal your script is running in - Programming On Unix
Users browsing this thread: 1 Guest(s)
|
|||
I recently dived a bit more into this.
This SO thread has a lot of good stuff, along with man(7) pty, and man(4) ptmx, pts, and this lwn article. While on classic BSD systems, making the link between master and slave pair is much easier as they map to ptyXY and ttyXY with the same XY numbers, on Linux it's not as straight forward. Initially, I couldn't find any tool to display clearly the link between the process linked to the pseudoterminal master end (/dev/ptmx) and the pseudoterminal slave (/dev/pts/<num>). Yet, after digging more I could find the following methods: You can type tty(1) in the shell to get the /dev/pts number. Then interrogating /dev/ptmx give us more info about the parent process. lsof(8) has the +E allows to display the pseudoterminal info. For example, if the tty is /dev/pts/13, you can do: Code: lsof +E /dev/ptmx | awk '/pts\/13/ && /dev\/ptmx/' Code: urxvtd 783 vnm 11u CHR 5,2 0t0 99 /dev/ptmx ->/dev/pts/13 794279,zsh,0u 794279,zsh,1u 794279,zsh,2u 794279,zsh,10u 795200,lsof,0u 795200,lsof,2u 795201,awk,2u 795202,xsel,1u 795202,xsel,2u Another way to query the info is to perform ptsname(3) on /dev/ptmx, passing it the file descriptors of the linked terminals, to get the corresponding of pseudoterminal slave ends attached to it. Manually doing this goes like this, first listing the current master ends and the file descriptors attached. Code: lsof -F pcf /dev/ptmx Code: p783 Yet another listing method for the master end is to use fuser(1): Code: $ fuser -v /dev/ptmx After this, there are multiple ways to find the slave pseudoterminal end. The easiest way, is to rely on a recent patch (2017) in the Linux kernel has added an entry to /proc/[pid]/fdinfo/<FD> called tty-index. Though this field is not documented in man 5 proc. The value of tty-index is the associated pts number. Thus we can now do: Code: $ < /proc/783/fdinfo/9 Code: lsof /dev/pts/1 Another method, if tty-index isn't present, is to rely on the ptsname(3) to get the name of the slave pseudoterminal. That's a bit clunky as you'd need to rely on gdb to access the file descriptor of the running process, which might need higher privileges. There's two ways I've found, the simple one is to do: Code: # gdb -batch -p 986 -ex 'p (char *)ptsname(8)' 2>/dev/null | grep 'dev\/pts' I've seen other answers online that directly do the ioctl that ptsname does in the background (source ioctl request TIOCGPTN = 0x80045430, which I can't find in man 2 ioctl_tty). Something like: Code: # gdb -batch -p 986 -ex 'p (int)ioctl(8, 0x80045430, &errno)?-1: (int)errno' 2>/dev/null | grep '\$1' Now that we got both ends, master and slave then we can print the processes on both ends. For example: Code: # Master This can be automated in a script, someone has posted one on SO: Code: use strict; Or you can simply rely on lsof: Code: lsof +E /dev/ptmx | awk '/dev\/ptmx/' Wow, it turned out to be a much deeper dive than I thought! I hope that clarifies things for at least someone. As for the initial question, you can then simply execute one of these and grep for the PID of the process to find the terminal it is running on. Yet, it still doesn't answer "what is actually considered a terminal". |
|||
Messages In This Thread |
Finding the terminal your script is running in - by movq - 02-07-2016, 02:23 PM
RE: Finding the terminal your script is running in - by venam - 03-07-2016, 01:56 AM
RE: Finding the terminal your script is running in - by movq - 03-07-2016, 12:41 PM
RE: Finding the terminal your script is running in - by venam - 03-07-2016, 01:12 PM
RE: Finding the terminal your script is running in - by venam - 12-08-2020, 08:11 AM
RE: Finding the terminal your script is running in - by z3bra - 12-08-2020, 08:43 AM
RE: Finding the terminal your script is running in - by movq - 13-08-2020, 06:45 AM
RE: Finding the terminal your script is running in - by venam - 05-06-2021, 05:26 AM
|