tags:

views:

218

answers:

4

So I have a tty (let's say /dev/tty5) and want to know whether it currently is a controlling tty of a process group or session, or whether it is currently unowned. POSIX has two API functions which suggest themselves here: tcgetpgrp() and tcgetsid(), both of which only work however if the caller has the tty as controlling tty -- which in this case makes them mostly useless (and in fact I don't see the point of tcgetsid() at all).

Anybody has a suggestion how I can detect in a sane way, from C, whether a terminal is currently a controlling terminal of a process? I only care about Linux, so if Linux-specific APIs are necessary that is fine with me.

+1  A: 

BSD: int ioctl(int tty, TIOCGETPGRP, int *foreground_group);

Linux: int tcgetpgrp(int tty, int *foreground_group);

Linux works only if you permissions to the non-owned terminal, i.e., you are root. This is an intentional security implemenation. BSD ioctl() allows any tty to take on any process group (or even nonexistant process groups) as its foreground tty. POSIX allows access only to process groups which have the tty as their controlling tty. This limitation disallows some ambiguous and security-undermining cases present in BSD ioctl.

What are you trying to do? You should only be worrying about process-controlling tty's if you are the kernel delivering signals.

Edit: I forgot /proc
From www.die.net: /proc/[number]/fd This is a subdirectory containing one entry for each file which the process has open, named by its file descriptor, and which is a symbolic link to the actual file. Thus, 0 is standard input, 1 standard output, 2 standard error, etc.

jim mcnamara
In my original question I already tried to explain why tcgetpgrp() is mostly useless.The reason I want this is simply to figure out whether a getty or so is already active on a terminal. I don't care about other processes having the TTY open for write (which can happen for logging, yadda yadda), I want to know whether there is actually somebody reading/controlling it.And going through /proc a la lsof is not what i call "sane"...
This all there is. Unless you access kernel mode data, or you are root you cannot do what you describe with user mode calls. Not in Linux. The reason: security. And I'm sorry if it offends your definition of sane. Take it up with Ulrich Drepper.
jim mcnamara
A: 

Execute this as a system call "ps au >tempfile.txt", and parse the file.

duck
A: 

Not sure if this exactly catches your need, anyway here it is:

#include <stdlib.h>
#include <stdio.h>

int main()
{
  int status = system("fuser /dev/tty1 >/dev/null 2>/dev/null") >> 8;
  printf("%s",
         status ?
           "tty not in use as a text terminal.\n" :
           "tty in use as a text terminal.\n");
  return 0;
}
Vanni Totaro
that `fuser` process probably calls some C library function again.. Why not call that function directly in your program? :p
vdboor
Vanni Totaro
A: 

you can use the proc file system to query the controlling tty of a process, if you know the PID of the process.

/proc//fd/0 is a symbolic link to the tty (say /dev/pts/4).

So all you need to do is create a proc path with the PID (eg: /proc/7834/fd/0, where 7834 is the PID) and then call the readlink system call to get the tty

See the C code snippet below

sprintf(procPath, "/proc/%s/fd/0", pid);
int ret = readlink(procPath, buffer, MAX_LEN);
buffer[ret] = '\0';
agupta666