From: al@escom.com (Al Donaldson)
Subject: Re: (none given) was Re: Signal handling
Reply-To: al@escom.COM (Al Donaldson)
Organization: ESCOM Corp., Oakton VA (USA)
Date: Mon, 28 Sep 1992 16:38:22 GMT

djk@bby.com.au (David James Keegel) writes:
>Even if you hack at the FS so that you can control the tty again after
>you log out, I would have thought it would be undesirable for a daemon
>to have access to the console for both input and output, when someone
>else (or nobody) might be logged in.

This contributes to the problem.  If my daemon were well-behaved and
didn't keep the console open I never would have seen this problem.
However, I don't think that changing the daemon to open stderr only
when necessary would fix the problem.

Consider a race condition where the daemon opens stderr to write
a nasty message to the console followed immediately by init kicking
off a login on the console.  Because the entire write cycle by the
daemon is not atomic (at minimum, an open, write, and close) it can
be interleaved with system calls from other processes (e.g., init).
So if this happens (a login session starting while the daemon has
a tty open to print an error) the login session will start without
a control tty and signals will not work.

Repeatedly opening and closing stderr makes it _less_likely that
this problem will occur, but does not prevent it from occuring.
The easiest way to prevent it from occuring, without hacking FS,
is to move the daemon code into init.  Because init has a flow of
control that is defined by its program, I can then guarantee that
init will never start a login session while it has stderr open.

>Most daemons I know of will close their stdin, stdout and stderr before
>fork()ing.  In the absense of a syslog(), perhaps the daemon's output/
>errors could end up in a file or be mailed to root.

The daemon is fork'ed by init, and does close stdin, stdout, and
stderr immediately after it starts.  It then opens /dev/null as stdin,
and /dev/tty0 as stdout and stderr.  Upon further checking, it doesn't
appear to need stdout, so that could also be /dev/null.  But it does
need stderr occasionally, usually for fairly serious error situations,
but sometimes during routine operation (e.g., warning messages).

As far as writing these messages to the screen while a user is logged
on to the system, how is this different from init or fs or the kernel
writing error messages to the screen while a user is logged on?
The only difference seems to be that having the daemon write directly
to the screen causes problems, not that there is something inherently
wrong with a system program writing to the screen.

Someone else suggested adding a TIOCNOTTY ioctl call that would clear
the daemon's control terminal while still allowing it be kept open
by the daemon.  This seems to be the solution that larger UNIX
systems use for daemons, but is not realistic for me right now.

Someone else suggested a separate mechanism for daemons to write
to the console, but I'm not sure I understand what that means.
Eventually it all comes down to writes to a device, and there is
only one screen on the console without adding windows or multiple
screens.

Finally, J F Martinez pointed me in the right direction regarding
the signal problem (Thanks!), but I have some problems understanding
how this would address my problem (a daemon that needs to use stderr).
The actual patches would be instructive.

Anyway, I haven't invested the time to go back clean up the daemon
to open stderr only when needed.  The main reason is that it does
not fix the problem.  Second, I expect this to be a fairly complex
thing to do, because the daemon may have other files open when
it needs to write a message.  As I understand it, you can't open
stderr (file descriptor 2) if you have other files (fd > 2) open.

Al