2010-07-06 9 views
5

Quindi ho un tty (diciamo/dev/tty5) e voglio sapere se attualmente è un tty di controllo di un gruppo di processi o di una sessione, o se è attualmente sconosciuto. POSIX ha due funzioni API che si suggeriscono qui: tcgetpgrp() e tcgetsid(), entrambi funzionano solo se il chiamante ha il tty come controllo tty - che in questo caso li rende per lo più inutili (e infatti io non lo faccio t vedere il punto di tcgetsid() affatto).Come capire se un TTY Linux sta controllando un gruppo di processi

Qualcuno ha un suggerimento su come posso rilevare in modo sano, da C, se un terminale è attualmente un terminale di controllo di un processo? Mi interessa solo Linux, quindi se sono necessarie API specifiche per Linux, per me va bene.

risposta

1

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

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

Linux funziona solo se si dispone delle autorizzazioni per il terminale non di proprietà, vale a dire, si è root. Questa è un'attuazione intenzionale della sicurezza. BSD ioctl() consente a qualsiasi tty di assumere qualsiasi gruppo di processi (o anche gruppi di processi non esistenti) come primo piano tty. POSIX consente l'accesso solo ai gruppi di processi che hanno il tty come tty di controllo. Questa limitazione impedisce alcuni casi ambigui e pericolosi per la sicurezza presenti nell'ioctl di BSD.

Che cosa stai cercando di fare? Dovresti solo preoccuparti del controllo dei processi di tty se sei il kernel che fornisce i segnali.

Edit: Ho dimenticato/proc
Da www.die.net: /proc/[numero]/FD Questa è una sottodirectory che contiene una voce per ogni file che il processo ha aperto, chiamato dal suo descrittore di file e che è un collegamento simbolico al file attuale. Pertanto, 0 è input standard, 1 output standard, 2 errore standard, ecc.

+0

Nella mia domanda iniziale ho già cercato di spiegare il motivo per cui tcgetpgrp() è in gran parte inutile. La ragione per cui voglio questo è semplicemente capire se un getty è già attivo su un terminale. Non mi importa di altri processi con TTY aperto per la scrittura (che può accadere per la registrazione, yadda yadda), voglio sapere se c'è qualcuno che sta leggendo/controllandolo. E passare attraverso/proc a lsof non è quello che io chiamo "sano" ... – user175104

+0

Questo tutto quello che c'è. Se non si accede ai dati in modalità kernel o se si è root, non è possibile eseguire le operazioni descritte con le chiamate in modalità utente. Non in Linux. Il motivo: sicurezza. E mi dispiace se offende la tua definizione di sano. Prendilo con Ulrich Drepper. –

0

Eseguire questa come una chiamata di sistema "ps au> tempfile.txt" e analizzare il file.

0

Non sono sicuro se questo cattura esattamente il vostro bisogno, comunque eccolo:

#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

che il processo 'fuser' probabilmente chiama di nuovo qualche funzione di libreria C. Perché non chiamare quella funzione direttamente nel programma? : p – vdboor

+0

@ 'vbdoor': una funzione di libreria C equivalente a' fuser' non esiste. 'fuser' è un programma Linux che effettua molte chiamate di libreria:' sed -n 's/^ \ (. * \) (. */\ 1/g; p' <<(ltrace fuser/dev/tty1 2 > & 1) | sort -u' uscita sul mio PC è: 'bindtextdomain close closedir fclose fgets fopen64 free __fxstat64 getpid __libc_start_main malloc opendir readdir64 setlocale __snprintf_chk socket sscanf strchr __strdup strtol textdomain __xstat64'. :) –

0

è possibile utilizzare il file system proc per interrogare il terminale di controllo di un processo, se si conosce il PID del processo.

/proc // fd/0 è un collegamento simbolico al tty (ad esempio/dev/pts/4).

Quindi tutto quello che dovete fare è creare un percorso proc con il PID (ad es:/proc/7834/fd/0, dove 7834 è il PID) e quindi chiamare la chiamata di sistema readlink per ottenere il tty

Vedere il codice C frammento di sotto

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