[comp.unix.wizards] Got a process struct / need a tty.

english@uncw.UUCP (Warren R. English Jr.) (02/25/90)

	How would one go about finding the control terminal
of a process? After reading all the process structures from /dev/kmem
into any array, I can't seem to figure out how to get the filename
of the controlling tty. It seemed to me that after you have
access to each and every process on the machine, it would be easy
to find the tty. So far, I have tried looking at the user structure and
the vnode structure that the process structure points to, but still,
no /dev/ttyxx can I find. The machine is a Sequent Balance Series,
running Dynix. 
Thanks.

/*****************************************************************************
Warren Ray English Jr.                          University of NC at Wilmington
Mathematical Sciences
{...,mcnc}!ecsvax!uncw!english
english@ecsvax!uncw
(Of course if I had the money I would buy a "real" computer)
*****************************************************************************/

allbery@NCoast.ORG (Brandon S. Allbery) (02/26/90)

As quoted from <598@uncw.UUCP> by english@uncw.UUCP (Warren R. English Jr.):
+---------------
| 	How would one go about finding the control terminal
| of a process? After reading all the process structures from /dev/kmem
| into any array, I can't seem to figure out how to get the filename
| of the controlling tty. It seemed to me that after you have
| access to each and every process on the machine, it would be easy
| to find the tty. So far, I have tried looking at the user structure and
| the vnode structure that the process structure points to, but still,
| no /dev/ttyxx can I find. The machine is a Sequent Balance Series,
| running Dynix. 
+---------------

Unix kernels do not use pathnames; they use <device, inumber> pairs.  System
calls like open(), creat(), chdir(), chroot(), etc. spend most of their time
(modulo slow device I/O or block on no carrier, of course) decoding a pathname
into the much faster <device, inumber> format.

In the case of controlling ttys, it goes on step farther:  since a controlling
tty is *always* a device, the <device, inumber> is further decoded into a
device number by looking in the *node (vnode, I assume, in your case) table.
This produces a <major, minor> pair; the major device number specifies the
driver, the minor number specifies the specific device handled by the driver.
The only way to go from these back to pathnames is to stat() every entry in
the /dev directory (convention) for character devices with the correct major
and minor device numbers.

The major/minor device numbers are stored in the user struct, in u.u_ttyd on
USG Unix; I don't know if this was changed in BSD-based Unixes like Dynix.
They are stored together; macros exist to extract them, but you want to
compare both.  The stat struct has the device major/minor numbers in the
st_rdev element; it is only valid if, for a (struct stat statbuf) set by a
successful call to stat(), (statbuf.st_mode & S_IFMT) is equal to S_IFCHR or
S_IFBLK.  (TTY devices are always S_IFCHR.)  (The S_* macros are defined in
<sys/stat.h> on both USG and AT&T.)

++Brandon
-- 
Brandon S. Allbery (human), allbery@NCoast.ORG (Inet), BALLBERY (MCI Mail)
ALLBERY (Delphi), uunet!cwjcc.cwru.edu!ncoast!allbery (UUCP), B.ALLBERY (GEnie)
BrandonA (A-Online) ("...and a partridge in a pear tree!" ;-)

cpcahil@virtech.uucp (Conor P. Cahill) (02/26/90)

In article <598@uncw.UUCP> english@uncw.UUCP (Warren R. English Jr.) writes:
>	How would one go about finding the control terminal
>of a process? After reading all the process structures from /dev/kmem
>into any array, I can't seem to figure out how to get the filename
>of the controlling tty.

This is usually stored in the user structure as a pointer to the inode (or
probably vnode for vnode systems) associated with the controlling terminal.

Since the name itself is not stored in the kernel anywhere, you
must then act like ttyname() and look up the correct /dev entry for
the device.

PS-> Getting to the user structure for a process other than the currently
running process is not a simple feat, since the user structure can be
swapped out to disk somewhere.  
-- 
+-----------------------------------------------------------------------+
| Conor P. Cahill     uunet!virtech!cpcahil      	703-430-9247	!
| Virtual Technologies Inc.,    P. O. Box 876,   Sterling, VA 22170     |
+-----------------------------------------------------------------------+

guy@auspex.auspex.com (Guy Harris) (02/27/90)

>The major/minor device numbers are stored in the user struct, in u.u_ttyd on
>USG Unix; I don't know if this was changed in BSD-based Unixes like Dynix.

It hasn't changed in BSD, and I suspect it hasn't changed in most
BSD-based systems.

Note also that "/dev" may have subdirectories, and that they may contain
tty devices, so you should check them too.