Warum MUSS beim Schreiben eines Linux-Daemons von tty getrennt werden?

Lesezeit: 3 Minuten

Benutzer-Avatar
OriginalHolz

Als ich versuchte, einen Daemon unter Linux mit C zu schreiben, wurde mir gesagt, ich solle danach folgenden Code hinzufügen Gabel Codeblock:

/* Preparations */
...

/* Fork a new process */
pid_t cpid = fork();
if (cpid == -1){perror("fork");exit(1);}
if (cpid > 0){exit(0);}

/* WHY detach from tty ? */
int fd = open("/dev/tty", O_RDWR);
ioctl(fd, TIOCNOTTY, NULL);

/* Why set PGID as current PID ? */
setpgid(getpid(), 0);

Meine Frage ist: Müssen die oben genannten Operationen durchgeführt werden?

  • Ich denke, ein Grund dafür ist, dass von einem Daemon nicht erwartet wird, dass er Ausgaben schreibt oder Eingaben liest. Wenn Sie beispielsweise einen HTTP-Server in einer SSH-Sitzung starten würden, würden Sie später in der Sitzung keine zufällige Warnausgabe erwarten.

    – John Chadwick

    8. Januar 2012 um 12:48 Uhr

  • @JohnChadwick Was Sie sagen, ist in der Tat eines der Dinge, die Sie tun möchten, während Sie sich in einen Daemon verwandeln, aber Sie erreichen dies, indem Sie stdin, stdout und stderr schließen. Sie trennen sich vom Terminal, um bestimmte Signale zu vermeiden (siehe Antworten unten).

    – Adam Zalcman

    8. Januar 2012 um 13:01 Uhr

  • Können Sie meine Antwort “nicht akzeptieren” und stattdessen die von @AdamZalcman akzeptieren? Er macht einen viel besseren Job als ich. Und er hat vollkommen Recht mit setsid(), das sollten Sie verwenden.

    – fg

    8. Januar 2012 um 13:05 Uhr

  • @ AdamZalcman Oh, richtig, ich habe tatsächlich vergessen, std * zu schließen. Ich dachte, dass das Ändern der Prozessgruppen-ID alle relevanten Signale verhindert, aber das wäre viel weniger sinnvoll, zumindest im Fall von SIGHUP.

    – John Chadwick

    8. Januar 2012 um 13:06 Uhr


Benutzer-Avatar
Adam Zalcman

Sie müssen Ihren Daemon-Prozess vom Terminal trennen, um zu vermeiden, dass Signale im Zusammenhang mit dem Betrieb des Terminals gesendet werden (wie SIGHUP, wenn die Terminalsitzung endet, sowie möglicherweise SIGTTIN und SIGTTOU).

Beachten Sie jedoch, dass die Art der Trennung vom Terminal mit TIOCNOTTY ioctl ist weitgehend veraltet. Du solltest benutzen setsid() stattdessen.

Der Grund dafür, dass ein Daemon seine ursprüngliche Prozessgruppe verlässt, besteht darin, keine an diese Gruppe gesendeten Signale zu empfangen. Beachten Sie, dass setsid() platziert Ihren Prozess auch in einer eigenen Prozessgruppe.

  • +1. Achtung: Selbst nach setsid(2) kann es möglich sein, ein steuerndes Terminal zu erlangen, wenn man nicht aufpasst (fork() wieder oder O_NOCTTY).

    – Pilkrähe

    8. Januar 2012 um 16:34 Uhr

  • Können Sie darauf eingehen? Warum kann der Hintergrundprozess diese Signale nicht einfach ignorieren?

    – Sergej Ponomarew

    31. Januar 2019 um 0:46 Uhr

Benutzer-Avatar
Pilkrähe

Die andere Antwort ist klar und technisch korrekt (und deshalb habe ich entsprechend positiv gestimmt).

Eine andere Antwort lautet: “Nein, schreiben Sie keinen Code, der sich selbst dämonisiert.”

Verwenden Sie stattdessen ein Prozessüberwachungs-Framework (wie z Dämonenwerkzeuge oder starte es oder launchd), die das für Sie erledigt.

Der traditionelle UNIX-Server ist selbst-dämonisierend und macht sich daher viele Dinge zunutze: aktuelles Arbeitsverzeichnis, Prozessgruppen- und Sitzungsunabhängigkeit, Signalmasken und -disposition, Dateisystemstamm, Berechtigungen, umask, offene Dateideskriptoren usw.

Die meisten oder alle dieser Prozessattribute werden jedoch über eine vererbt exec()was bedeutet, dass ein Serverprozess normalerweise mit der gewünschten Prozessgruppe, dem Arbeitsverzeichnis, dem Stamm usw. “geboren” werden kann. Es besteht kaum Bedarf, alles selbst zu tun, obwohl Sie privilegierte Operationen und den Widerruf von Privilegien oft selbst verwalten müssen.

(In der Tat würde ich argumentieren, dass es ein langfristiges Risiko darstellt, sich selbst dämonisierende Programme zu schreiben. Boilerplate-“Hintergrund”-Routinen werden kopiert und eingefügt und hastig portiert und erweitert, und der Programmierer verbringt Zeit mit Hilfscode und nicht mit dem Hauptzweck des Programms. )

  • Gute Antwort! Das Daemonisieren sollte die Wahl des Aufrufers sein und nicht von der Anwendung selbst erzwungen werden. Und für den Anrufer gibt es viele vorhandene Tools, die in der Anwendung nicht neu erfunden werden müssen.

    – Erki Aring

    16. Februar 2017 um 10:50 Uhr

1365550cookie-checkWarum MUSS beim Schreiben eines Linux-Daemons von tty getrennt werden?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy