11558SrgrimesPOSIX and init:
21558Srgrimes--------------
31558Srgrimes
41558SrgrimesPOSIX.1 does not define 'init' but it mentions it in a few places.
51558Srgrimes
61558SrgrimesB.2.2.2, p205 line 873:
71558Srgrimes
81558Srgrimes	This is part of the extensive 'job control' glossary entry.
91558Srgrimes	This specific reference says that 'init' must by default provide
101558Srgrimes	protection from job control signals to jobs it starts --
111558Srgrimes	it sets SIGTSTP, SIGTTIN and SIGTTOU to SIG_IGN.
121558Srgrimes
131558SrgrimesB.2.2.2, p206 line 889:
141558Srgrimes
151558Srgrimes	Here is a reference to 'vhangup'.  It says, 'POSIX.1 does
161558Srgrimes	not specify how controlling terminal access is affected by
171558Srgrimes	a user logging out (that is, by a controlling process
181558Srgrimes	terminating).'  vhangup() is recognized as one way to handle
191558Srgrimes	the problem.  I'm not clear what happens in Reno; I have
201558Srgrimes	the impression that when the controlling process terminates,
211558Srgrimes	references to the controlling terminal are converted to
221558Srgrimes	references to a 'dead' vnode.  I don't know whether vhangup()
231558Srgrimes	is required.
241558Srgrimes
251558SrgrimesB.2.2.2, p206 line 921:
261558Srgrimes
271558Srgrimes	Orphaned process groups bear indirectly on this issue.  A
281558Srgrimes	session leader's process group is considered to be orphaned;
291558Srgrimes	that is, it's immune to job control signals from the terminal.
301558Srgrimes
311558SrgrimesB.2.2.2, p233 line 2055:
321558Srgrimes
331558Srgrimes	'Historically, the implementation-dependent process that
341558Srgrimes	inherits children whose parents have terminated without
351558Srgrimes	waiting on them is called "init" and has a process ID of 1.'
361558Srgrimes
371558Srgrimes	It goes on to note that it used to be the case that 'init'
381558Srgrimes	was responsible for sending SIGHUP to the foreground process
391558Srgrimes	group of a tty whose controlling process has exited, using
401558Srgrimes	vhangup().  It is now the responsibility of the kernel to
411558Srgrimes	do this when the controlling process calls _exit().  The
421558Srgrimes	kernel is also responsible for sending SIGCONT to stopped
431558Srgrimes	process groups that become orphaned.  This is like old BSD
441558Srgrimes	but entire process groups are signaled instead of individual
451558Srgrimes	processes.
461558Srgrimes
471558Srgrimes	In general it appears that the kernel now automatically
481558Srgrimes	takes care of orphans, relieving 'init' of any responsibility.
491558Srgrimes	Specifics are listed on the _exit() page (p50).
501558Srgrimes
511558SrgrimesOn setsid():
521558Srgrimes-----------
531558Srgrimes
541558SrgrimesIt appears that neither getty nor login call setsid(), so init must
551558Srgrimesdo this -- seems reasonable.  B.4.3.2 p 248 implies that this is the
561558Srgrimesway that 'init' should work; it says that setsid() should be called
571558Srgrimesafter forking.
581558Srgrimes
591558SrgrimesProcess group leaders cannot call setsid() -- another reason to
601558Srgrimesfork!  Of course setsid() causes the current process to become a
611558Srgrimesprocess group leader, so we can only call setsid() once.  Note that
621558Srgrimesthe controlling terminal acquires the session leader's process
631558Srgrimesgroup when opened.
641558Srgrimes
651558SrgrimesControlling terminals:
661558Srgrimes---------------------
671558Srgrimes
681558SrgrimesB.7.1.1.3 p276: 'POSIX.1 does not specify a mechanism by which to
691558Srgrimesallocate a controlling terminal.  This is normally done by a system
701558Srgrimesutility (such as 'getty') and is considered ... outside the scope
711558Srgrimesof POSIX.1.'  It goes on to say that historically the first open()
721558Srgrimesof a tty in a session sets the controlling terminal.  P130 has the
731558Srgrimesfull details; nothing particularly surprising.
741558Srgrimes
751558SrgrimesThe glossary p12 describes a 'controlling process' as the first
761558Srgrimesprocess in a session that acquires a controlling terminal.  Access
771558Srgrimesto the terminal from the session is revoked if the controlling
781558Srgrimesprocess exits (see p50, in the discussion of process termination).
791558Srgrimes
801558SrgrimesDesign notes:
811558Srgrimes------------
821558Srgrimes
831558Srgrimesyour generic finite state machine
841558Srgrimeswe are fascist about which signals we elect to receive,
851558Srgrimes	even signals purportedly generated by hardware
861558Srgrimeshandle fatal errors gracefully if possible (we reboot if we goof!!)
871558Srgrimes	if we get a segmentation fault etc., print a message on the console
881558Srgrimes	and spin for a while before rebooting
891558Srgrimes	(this at least decreases the amount of paper consumed :-)
901558Srgrimesapply hysteresis to rapidly exiting gettys
911558Srgrimescheck wait status of children we reap
921558Srgrimes	don't wait for stopped children
931558Srgrimesdon't use SIGCHILD, it's too expensive
941558Srgrimes	but it may close windows and avoid races, sigh
951558Srgrimeslook for EINTR in case we need to change state
961558Srgrimesinit is responsible for utmp and wtmp maintenance (ick)
971558Srgrimes	maybe now we can consider replacements?  maintain them in parallel
981558Srgrimes	init only removes utmp and closes out wtmp entries...
991558Srgrimes
1001558Srgrimesnecessary states and state transitions (gleaned from the man page):
1011558Srgrimes	1: single user shell (with password checking?); on exit, go to 2
1021558Srgrimes	2: rc script: on exit 0, go to 3; on exit N (error), go to 1
1031558Srgrimes	3: read ttys file: on completion, go to 4
1041558Srgrimes	4: multi-user operation: on SIGTERM, go to 7; on SIGHUP, go to 5;
1051558Srgrimes		on SIGTSTP, go to 6
1061558Srgrimes	5: clean up mode (re-read ttys file, killing off controlling processes
1071558Srgrimes		on lines that are now 'off', starting them on lines newly 'on')
1081558Srgrimes		on completion, go to 4
1091558Srgrimes	6: boring mode (no new sessions); signals as in 4
1101558Srgrimes	7: death: send SIGHUP to all controlling processes, reap for 30 seconds,
1111558Srgrimes		then go to 1 (warn if not all processes died, i.e. wait blocks)
1121558SrgrimesGiven the -s flag, we start at state 1; otherwise state 2
113