welche Beziehungen bestehen zwischen meinem aktuellen Steuerterminal und „/dev/tty“?

welche Beziehungen bestehen zwischen meinem aktuellen Steuerterminal und „/dev/tty“?

Unter Lubuntu 18.04 führe ich eine Shell in lxterminal aus. Das steuernde Terminal ist der aktuelle Pseudoterminal-Slave:

$ tty
/dev/pts/2

Ich möchte wissen, welche Beziehungen zwischen meinem aktuellen Steuerterminal /dev/pts/2und bestehen /dev/tty.

  1. /dev/ttyverhält sich wie mein aktuelles Steuerterminal /dev/pts/2:

    $ echo hello > /dev/tty
    hello
    
    $ cat < /dev/tty
    world
    world
    ^C
    
  2. Es scheint sich jedoch um nicht miteinander verbundene Dateien zu handeln, statt dass die eine ein symbolischer oder fester Link zur anderen ist:

    $ ls -lai /dev/tty /dev/pts/2
     5 crw--w---- 1 t    tty 136, 2 May 31 16:38 /dev/pts/2
    13 crw-rw-rw- 1 root tty   5, 0 May 31 16:36 /dev/tty
    

Bei verschiedenen Sitzungen mit unterschiedlichen Steuerterminals /dev/ttyist garantiert, dass es sich um deren Steuerterminals handelt. Wie können es unterschiedliche Steuerterminals sein, ohne dass es sich um einen symbolischen oder festen Link handelt?

Was sind also ihre Beziehungen und Unterschiede? Jede Hilfe ist sehr willkommen!

Dieser Beitrag stammt aus einem früherenBeziehen sich sowohl die Ausgabe des Befehls „tty“ als auch die Datei „/dev/tty“ auf das Steuerterminal des aktuellen Bash-Prozesses?

Antwort1

Die ttyManpage in Abschnitt 4behauptet Folgendes:

Die Datei/Entwickler/ttyist eine Zeichendatei mit der Hauptnummer 5 und der Nebennummer 0, normalerweise im Modus 0666 und der Besitzergruppe root.tty. Es ist ein Synonym für das Steuerterminal eines Prozesses, falls vorhanden.

In Ergänzung zuioctl(2)Anfragen, die von dem Gerät unterstützt werden, auf das sich tty bezieht,ioctl(2)Anfrage TIOCNOTTYwird unterstützt.

TIOCNOTTY

Trennen Sie den aufrufenden Prozess von seinem Steuerterminal.

Wenn der Prozess der Sitzungsleiter ist, werden SIGHUPSignale SIGCONTan die Vordergrundprozessgruppe gesendet und alle Prozesse in der aktuellen Sitzung verlieren ihr steuerndes TTY.

Dasioctl(2)Aufruf funktioniert nur bei Dateideskriptoren, die verbunden sind mit /Entwickler/tty. Es wird von Daemon-Prozessen verwendet, wenn sie von einem Benutzer an einem Terminal aufgerufen werden. Der Prozess versucht,/Entwickler/tty. Wenn das Öffnen erfolgreich ist, wird die Verbindung mithilfe von vom Terminal getrennt TIOCNOTTY. Wenn das Öffnen fehlschlägt, ist die Verbindung offensichtlich nicht an ein Terminal angeschlossen und muss sich nicht trennen.

Dies würde teilweise erklären, warum /dev/ttyes keinen symbolischen Link zum steuernden Terminal gibt: es würde ein zusätzliches unterstützen ioctl, und es könnte kein steuerndes Terminal geben (aber ein Prozess kann immer versuchen, darauf zuzugreifen /dev/tty). Die Dokumentation ist jedoch falsch: Das zusätzliche ioctlist nicht nur zugänglichüber /dev/tty(sehenmosvys Antwort, was auch eine sinnvollere Erklärung für die Natur von liefert /dev/tty).

/dev/ttykann verschiedene Steuerterminals darstellen, ohne eine Verbindung darzustellen, da der Treiber, der es implementiert, bestimmt, welches das Steuerterminal des aufrufenden Prozesses ist (sofern vorhanden).

Sie können sich das als /dev/ttydas Steuerterminal vorstellen, das somit Funktionen bietet, die nur für ein Steuerterminal sinnvoll sind, während /dev/pts/2usw. einfache Terminals sind, von denen eines zufällig das Steuerterminal für einen bestimmten Prozess sein kann.

Antwort2

/dev/ttyist ein „magisches“ Zeichengerät, das beim Öffnen einen Handle zum aktuellen Terminal zurückgibt.

Vorausgesetzt, dass das Steuerterminal ein ist , verweisen ein über und einer über geöffneter /dev/pts/1Dateideskriptor auf dasselbe Gerät; alle Schreib-, Lese- oder anderen Dateivorgänge funktionieren auf beiden gleich./dev/pts/1/dev/tty

Insbesondere akzeptieren sie den gleichen Satz von Ioctls und TIOCNOTTYes gibt keinen zusätzlichen Ioctl, der nur über/dev/tty.

ioctl(fd, TIOCNOTTY)funktioniert bei jedem Dateideskriptor, der auf ein Terminal verweist, gleich, vorausgesetzt, dass es sich um das Steuerterminal des Prozesses handelt, der es aufruft.

/dev/ttyEs spielt keine Rolle, ob der Deskriptor durch Öffnen von , /dev/pts/1, erhalten wurde /dev/ptmx(in diesem Fall wird das ioctl auf sein entsprechendesSklave) oder in jüngerer Zeit durch einen Anruf an ioctl(master, TIOCGPTPEER, flags).

Beispiel:

$ cat <<'EOT' >tiocnotty.c
#include <sys/ioctl.h>
#include <unistd.h>
#include <err.h>

int main(int ac, char **av){
        if(ioctl(0, TIOCNOTTY)) err(1, "io(TIOCNOTTY)");
        if(ac < 2) return 0;
        execvp(av[1], av + 1);
        err(1, "execvp %s", av[1]);
}
EOT
$ cc -W -Wall tiocnotty.c -o tiocnotty
$ ./tiocnotty
$ ./tiocnotty </dev/tty
$ tty
/dev/pts/0
$ ./tiocnotty </dev/pts/0

Außerdem wird der aktuelle Prozess dadurch nicht wirklich vom TTY „getrennt“. Der Prozess kann weiterhin davon lesen, ein Befehl ^Cauf dem Terminal beendet ihn usw. Die einzige Auswirkung auf einen Prozess, der kein Sitzungsleiter ist, besteht darin, dass das TTY nicht mehr über erreichbar ist /dev/ttyund in nicht mehr als steuerndes TTY aufgeführt wird /proc/PID/stat:

$ ./tiocnotty cat
^C
$ ./tiocnotty cat
^Z
[2]+  Stopped                 ./tiocnotty cat
$ ./tiocnotty cat
foo
foo
^D
$ ./tiocnotty cat /dev/tty
cat: /dev/tty: No such device or address
$ ./tiocnotty awk '{print$7}' /proc/self/stat
0

[das 7. Feld /proc/<pid>/statist die Geräte-ID des steuernden TTY, siehe proc(5)]

Wenn der aufrufende Prozess der Sitzungsleiter ist, wird die Sitzung tatsächlich vom TTY getrennt und ein SIGHUP/ SIGCONT-Paar von der Sitzung an die Vordergrundprozessgruppe gesendet. Aber selbst dann wird das Terminalnichtgeschlossen werden, und der Prozess kann immer noch daraus lesen, wenn er Folgendes übersteht SIGHUP:

$ script /dev/null -c 'trap "" HUP; exec ./tiocnotty cat'
Script started, file is /dev/null
lol
lol
^C^C^C^C^C  # no controlling tty anymore

wtf  
wtf
^D   # but still reading fine from it
Script done, file is /dev/null

/dev/ttyist kein symbolischer Link wie /dev/stdin=> /dev/fd/0=> /proc/self/fd/0=>, /dev/pts/0da es lange vor virtuellen dynamischen Dateisystemen wie procfs (und lange vor symbolischen Links im Allgemeinen) erfunden wurde. Und viele Programme sind von seiner besonderen Semantik abhängig geworden (z. B. /dev/ttyschlägt es fehl ENODEV, wenn das Steuerterminal nicht zugänglich ist).

verwandte Informationen