I'm a bit riddled by the convention in creation of linux daemons. People mostly agree that what makes a daemon is no associated terminal. Also, in sample codes usually the processe's parent gets killed and the daemon reparents to init. I have no problem understanding this is the way to do it, BUT WHY? How is it beneficient that the process has no associated terminal and is a direct child to init?
1. How is it beneficient that the process has no associated terminal?
On POSIX-compliant platforms, SIGHUP ("signal hang up") is a signal sent to a process when its controlling terminal is closed. (It was originally designed to notify the process of a serial line drop.)
The default action [of SIGHUP] on POSIX-compliant systems is an abnormal termination.
If I understand the situation correctly, there are two different cases.
The obvious case is that if you close e.g. a terminal emulator like GNOME Terminal or
mc, that closes the master end of a pseudo-terminal device. And this closure generates a hangup on the pseudo-terminal. This affects the slave device. All the processes which are controlled by this terminal will receive SIGHUP. This is not the case described above.
@JDePB points out the second case: if you close all the file descriptors referencing a terminal device, it will also generate a hangup. That is, if your daemon closes its FD for its tty (which it should), and later on the other processes which have open FDs of the tty exit, your daemon will receive SIGHUP, even if your terminal emulator doesn't respond and leaves the master end of the pseudo-terminal open. This functionality can be disabled for the whole terminal device by clearing HUPCL.
vhangup(). It seems
login calls this to try and make sure the previous session can't interfere with it. Or something. I'm not entirely clear, since this call is Linux-specific and the manual page is very very short.
2. and is a direct child to init?
If the process receiving SIGHUP is a Unix shell, then as part of job control it will often intercept the signal and ensure that all stopped processes are continued before sending the signal to child processes (more precisely, process groups, represented internally by the shell as a "job"), which by default terminates them.