2010-07-06 21 views
5

Tengo un tty (digamos/dev/tty5) y quiero saber si actualmente es un tty controlador de un grupo o sesión de proceso, o si es actualmente sin dueño. POSIX tiene dos funciones de API que se sugieren a sí mismas aquí: tcgetpgrp() y tcgetsid(), las cuales solo funcionan si la persona que llama tiene el tty como control tty, lo que en este caso las hace casi inútiles (y de hecho, yo no t ver el punto de tcgetsid() en absoluto).Cómo saber si un TTY de Linux está controlando un grupo de proceso

Alguien tiene una sugerencia de cómo puedo detectar de una manera sensata, desde C, si un terminal es actualmente un terminal de control de un proceso. Solo me importa Linux, así que si las API específicas de Linux son necesarias, eso está bien conmigo.

Respuesta

1

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

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

Linux funciona solo si tiene permisos para el terminal no propietario, es decir, usted es root. Esta es una implementación de seguridad intencional. BSD ioctl() permite a cualquier tty tomar cualquier grupo de procesos (o incluso grupos de procesos no inexistentes) como su primer plano tty. POSIX permite el acceso solo a grupos de proceso que tienen el tty como su tty de control. Esta limitación impide algunos casos ambiguos y de socavación de la seguridad presentes en BSD ioctl.

¿Qué estás tratando de hacer? Solo debería preocuparse por el control del proceso de tty si usted es el núcleo que entrega las señales.

Editar: Olvidé/proc
De www.die.net: /proc/[número]/FD Este es un subdirectorio que contiene una entrada para cada fichero que tiene abierto el proceso, llamado así por su descriptor de archivo y que es un enlace simbólico al archivo real. Por lo tanto, 0 es entrada estándar, 1 salida estándar, 2 error estándar, etc.

+0

En mi pregunta original ya he intentado explicar por qué tcgetpgrp() es sobre todo inútil. La razón por la que quiero esto es simplemente para averiguar si un getty o algo así ya está activo en un terminal. No me interesan otros procesos que tengan el TTY abierto para escritura (que puede suceder para el registro, yadda yadda), quiero saber si hay alguien que realmente lo lea/controle. Y pasando por/proc a la lsof no es lo que llamo "sano" ... – user175104

+0

Todo lo que hay. A menos que acceda a los datos del modo kernel, o que sea root, no podrá hacer lo que describe con las llamadas en modo usuario. No en Linux. La razón: seguridad. Y lo siento si ofende tu definición de cuerdo. Tómalo con Ulrich Drepper. –

0

Ejecute esto como una llamada al sistema "ps au> tempfile.txt", y analice el archivo.

0

No estoy seguro si esto capta exactamente su necesidad, de todos modos aquí está:

#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; 
} 
+0

que 'proceso fuser' probablemente llama a algunos función de biblioteca C de nuevo .. ¿Por qué no llamar a esa función directamente en su programa? : P – vdboor

+0

@ 'vbdoor': no existe una función de biblioteca C equivalente a' fuser'. 'Fuser' es un programa de Linux que hace un montón de llamadas de biblioteca:' sed -n 's/^ \ (. * \) (*/\ 1/g; p' <<(ltrace fusor/dev/2 tty1 > & 1) | especie de salida -u' en mi PC es: 'bindtextdomain cerca closedir fclose fgets fopen64 libre __fxstat64 getpid __libc_start_main malloc opendir readdir64 setlocale __snprintf_chk toma sscanf strchr __strdup strtol textdomain __xstat64' :). –

0

puede utilizar el sistema de archivos proc para consultar el terminal controlada de un proceso, si se conoce el PID del proceso.

/proc // fd/0 es un enlace simbólico al tty (digamos/dev/pts/4).

Así que todo lo que necesita hacer es crear un camino proc con el PID (por ejemplo:/proc/7834/fd/0, donde 7834 es el PID) y luego llamar a la llamada al sistema readlink para obtener el TTY

Ver el fragmento de código C por debajo de

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