From: stefan@rent-a-guru.de (Stefan Stapelberg)
Newsgroups: de.comp.os.unix
Subject: Re: TIOCNOTTY, wie ist das normal definiert???
Date: 15 Apr 92 16:28:29 GMT
Organization: RENT-A-GURU (TM), Lohr/Germany

In article <3193@huedv.sta.sub.org> thu@huedv.sta.sub.org writes:
>nachdem m.E. bisher noch nich die produktivsten Antworten zu Deinem
>Problem gekommen sind, hier ein kleines Stuecken Kot (?), wie ich das

nomen est omen?

>#ifdef ISC
>	close (0);
>	close (1);
>	close (2);
>	setpgrp();
>#else
[...]
>    if ((s = open("/dev/tty", O_RDWR)) >= 0) {
>	ioctl(s, TIOCNOTTY, 0);
>	close(s);

Vorsicht!  Ein setpgrp macht bei Unix System V etwas mehr als sich nur vom
controlling tty abzukoppeln:  Der den setpgrp ausfuehrende Prozess wird
zum Prozessgruppenfuehrer einer neuen Prozessgruppe (aber nur dann, wenn
er nicht bereits der Prozessgruppenfuehrer war, also wenn er nicht von
einer C-Shell aus als Background-Job gestartet wurde).

Daraus folgt: Wenn der Daemon ein Terminal eroeffnet, dass nicht schon ein
controlling tty fuer irgendeinen anderen Prozess ist (z.B. /dev/console
fuer Logging-Meldungen) wird dieses zum controlling tty des Daemons und
kann dann u.U. Prozesse (z.B. login) stoeren, die sich ebenfalls das tty
als controlling tty einrichten wollen.  Das kann dazu fuehren, dass kein
Zugriff auf /dev/tty mehr moeglich ist und getpass(3) das Passwort nicht
mehr abfragen kann (bei fruehen sendmail-Ports ging nach dem Start des
Daemons deswegen kein su(1) mehr).  Logins ohne Passwort funktionieren
dann zwar noch, aber von der Tastatur generierte Signale gehen an den
Daemon anstatt an die Shell.

Unter System V wird ein tty nur dann zum controlling tty, wenn es von einem
Prozessgruppenfuehrer eroeffnet wird und wenn es nicht schon ein controlling
tty fuer eine andere Prozessgruppe ist.  Selbst wenn ein Daemon ein fuer
Logging-Ausgaben benutztes Terminal schliesst, bleibt es weiter das con-
trolling tty. Ein erneutes setpgrp hat keine Wirkung, wenn es von einem
Prozess aufgerufen wird, der bereits Prozessgruppenfuehrer ist.

Um sich also korrekt und ohne weitere Auswirkungen vom controlling tty zu
entkoppeln, muss ein Daemon unter System V das setpgrp wie folgt ausfuehren:

	if (fork() != 0)
		exit(0);	/* first parent terminates */
				/* child looses controlling tty */
	setpgrp();		/* and becomes pgrp leader */
	signal(SIGHUP, SIG_IGN); /* prepare for pgrp leader death */
	if (fork() != 0)	/* become non-pgrp-leader */
		exit(0);
	/* daemon now runs in the second child */

Der Seiteneffekt, der durch das zweite fork() passiert, ist folgender:
Der erste Kindprozess macht sich zum Prozessgruppenfuehrer, erzeugt ein
zweites Kind und beendet sich.  Das zweite Kind ist immun gegenueber den
Signalen von der Tastatur, da es nun in der pgrp 0 ist, und kann auch
kein controlling tty mehr aquirieren, weil es kein Prozessgruppenfuehrer
ist.  Da bei seinem Ende die Mutter (das erste Kind) dem zweiten ein
SIGHUP zustellt, muss das Signal ignoriert werden.

Einfach Scheisse, die Prozessgruppen, Du hattest schon Recht mit dem "Kot".
:-)

Gruesse, Stefan

-- 
Stefan "Lama Babyatollah Comedownie" Stapelberg		RENT-A-GURU (TM)
<stefan@rent-a-guru.de> or: unido!mikros!stefan		P.O. Box 368
Phone: (+49)-9352-5948     Fax: (+49)-9352-9696		D-8770 Lohr/Main