9.2. Terminal Logins
The system administrator creates a file, usually /etc/ttys, that has one line per terminal device. Each line specifies the name of the device and other parameters that are passed to the getty program. The init process reads the file /etc/ttys and, for every terminal device that allows a login, does a fork followed by an exec of the program getty.
All the processes shown in Figure 9.1 have a real user ID of 0 and an effective user ID of 0 (i.e., they all have superuser privileges). The init process also execs the getty program with an empty environment.
It is getty that calls open for the terminal device. The terminal is opened for reading and writing.
When we enter our user name, getty's job is complete, and it then invokes the login program, similar to
execle("/bin/login", "login", "-p", username, (char *)0, envp);
init invokes getty with an empty environment; getty creates an environment for login (the envp argument) with the name of the terminal (something like TERM=foo, where the type of terminal foo is taken from the gettytab file).
All the processes shown in Figure 9.2 have superuser privileges, since the original init process has superuser privileges. The process ID of the bottom three processes in Figure 9.2 is the same, since the process ID does not change across an exec. Also, all the processes other than the original init process have a parent process ID of 1.
If we log in correctly, login will
-
Change to our home directory (chdir)
-
Change the ownership of our terminal device (chown) so we own it
-
Change the access permissions for our terminal device so we have permission to read from and write to it
-
Set our group IDs by calling setgid and initgroups
-
Initialize the environment with all the information that login has: our home directory (HOME), shell (SHELL), user name (USER and LOGNAME), and a default path (PATH)
-
Change to our user ID (setuid) and invoke our login shell, as in
execl("/bin/sh", "-sh", (char *)0);
Our login shell now reads its start-up files
These start-up files usually change some of the environment variables and add many additional variables to the environment.
The Linux login procedure is very similar to the BSD procedure. The main difference between the BSD login procedure and the Linux login procedure is in the way the terminal configuration is specified.
On Linux, /etc/inittab contains the configuration information specifying the terminal devices for which init should start a getty process, similar to the way it is done on System V. Depending on the version of getty in use, the terminal characteristics are specified either on the command line (as with agetty) or in the file /etc/gettydefs (as with mgetty).
9.4. Process Groups
#include <unistd.h> pid_t getpgrp(void); pid_t getpgid(pid_t pid);
getpgid(0) == getpgrp()
Each process group can have a process group leader. The leader is identified by its process group ID being equal to its process ID.
This is called the process group lifetimethe period of time that begins when the group is created and ends when the last remaining process leaves the group. The last remaining process in the process group can either terminate or enter some other process group.
#include <unistd.h> int setpgid(pid_t pid, pid_t pgid); A process joins an existing process group or creates a new process group by calling setpgid. (In the next section, we'll see that setsid also creates a new process group.)
If the two arguments are equal, the process specified by pid becomes a process group leader.
A process can set the process group ID of only itself or any of its children. Furthermore, it can't change the process group ID of one of its children after that child has called one of the exec functions.
9.5. Sessions
A session is a collection of one or more process groups.
The processes in a process group are usually placed there by a shell pipeline. For example, the arrangement shown in Figure 9.6 could have been generated by shell commands of the form
proc1 | proc2 & proc3 | proc4 | proc5 #include <unistd.h> pid_t setsid(void);
A process establishes a new session by calling the setsid function. 原进程一定不能是group leader.一般都先fork子进程,让其开session。 After the function, the process become the session leader, group leader and has no controlled terminal.
#include <unistd.h> pid_t getsid(pid_t pid); 返回session leader的process group id
9.6. Controlling Terminal
A session can have a single controlling terminal. This is usually the terminal device (in the case of a terminal login) or pseudo-terminal device (in the case of a network login) on which we log in. The session leader that establishes the connection to the controlling terminal is called the controlling process. If a session has a controlling terminal, it has a single foreground process group, and all other process groups in the session are background process groups. Whenever we type the terminal's interrupt key (often DELETE or Control-C),terminal's quit key (often Control-backslash), this causes the interrupt signal be sent to all processes in the foreground process group. Systems derived from UNIX System V allocate the controlling terminal for a session when the session leader opens the first terminal device that is not already associated with a session. This assumes that the call to open by the session leader does not specify the O_NOCTTY flag (Section 3.3). The way a program guarantees that it is talking to the controlling terminal is to open the file /dev/tty. BSD-based systems allocate the controlling terminal for a session when the session leader calls ioctl with a request argument of TIOCSCTTY (the third argument is a null pointer). The session cannot already have a controlling terminal for this call to succeed. (Normally, this call to ioctl follows a call to setsid, which guarantees that the process is a session leader without a controlling terminal.)
9.7. tcgetpgrp, tcsetpgrp, and tcgetsid Functions
#include <unistd.h> pid_t tcgetpgrp(int filedes); int tcsetpgrp(int filedes, pid_t pgrpid); 9.8 --(?)
9.8. Job Control
The interrupt character (typically DELETE or Control-C) generates SIGINT.
The quit character (typically Control-backslash) generates SIGQUIT.
The suspend character (typically Control-Z) generates SIGTSTP.
When bgprocess need input, the terminal driver send SIGTTIN to the bgprocess. Then it stops. Type fg would send the continue signal (SIGCONT) to the process group. What happens if a background job outputs to the controlling terminal? This is an option that we can allow or disallow. Normally, we use the stty(1) command to change this option. 当向终端的输出被中止时,有了write时,terminal driver会给job发出SIGTTOU
基本悲剧了 以后再看看。