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