[APUE] process relationship (I) and apue process relationship
I. Terminal login 1. 4.3 + BSD terminal Login
The system administrator creates a file named/etc/ttys. Each terminal device has a row, indicating the device name and parameters passed to the getty program. These parameters indicate the baud rate of the terminal. During System bootstrap, the kernel creates process ID 1, that is, the init process. The init process enters the multi-user State. Init reads the file/etc/ttys. For every terminal device that is allowed to log on, init calls fork once, and the child process generated by it executes the program getty. For details about this situation, see:
In the figure, the actual user ID and valid user ID of each process are both 0 (that is, they have root permissions ). Init runs the getty program in an empty environment.
Getty calls the open function on the terminal device to open the terminal in read or write mode. If the device is a modem, open may be stuck in the device driver until the user dials the modem and the line is connected. Once the device is opened, file descriptors 0, 1, and 2 are set to the device. Then, getty outputs information such as "login:" And waits for the user to type the user name. If the terminal supports multiple speeds, getty can test special characters to properly change the speed (baud rate) of the terminal ).
After you type the user name, getty is complete, and then it calls the login program in a way similar to the following:
execle("/usr/bin/login", "login", "-p" username, (char *) 0, envp);
(The gettytab file may have some options for calling other programs, but the default login program is used by the system ). Init calls getty in an empty environment. Getty uses the terminal name (for example, TERM = foo, in which the terminal foo type is taken from the gettytab file) and the Environment string in gettytab to create an environment (envp parameter) for login ). The-p Flag notifies login to retain the Environment passed to it. You can also add other environment strings to the environment, but do not replace it. Displays the status of these processes after login is called.
Because the initial init process has the root permission, all processes in the figure have the root permission. The process IDs of the three processes at the bottom of the figure are the same, because the process IDs do not change due to exec execution. Besides the initial init process, all processes have a parent process ID.
Login can handle multiple tasks. Because it obtains the user name, it can call getpwnam to obtain the login entry of the password file of the corresponding user. Then, call getpass to display the prompt "Password:" and then read the Password entered by the user. It calls crypt to encrypt the password you typed and compares it with the pw_passwd field of the login entry in the user password file. If the password you typed several times is invalid, login calls exit with parameter 1 to indicate that the logon process failed. After the parent process (init) has known the termination of the child process, it will call fork again, and then execute getty. This terminal repeats the above process.
If the user logs on correctly, login changes the current working directory to the user's home directory. It also calls chown to change the ownership of the terminal so that the user becomes the owner and group owner. Change the access permission of the terminal device to: User read, write, and group write. Call setgid and initgroup to set the group ID of the process. Then, call all information obtained by login to initialize the environment: the start directory (HOME), shell (SHELL), USER name (USER and LOGNAME), and a system default PATH (PATH ). Finally, the login process changes to the user ID (setuid) of the login user and calls the login shell of the user. The method is similar:
execl("/bin/sh", "-sh", (char *) 0);
The first character of argv [0] is a flag, indicating that the shell is called as a logon shell. Shell can view this character and modify its startup process accordingly
Login does more.
So far, the login user's login shell starts to run. The parent process ID is the init process ID (process ID 1). When the process is terminated, the init process will receive a notification (receive the SIGGHLD signal ), it will repeat all the above processes on the terminal. Log on to the file descriptors 0, 1 and 2 of the shell and set them to the terminal device. This arrangement is displayed.
Now log on to the shell to read its Startup File. These startup files usually change some environment variables and add some environment variables. After the Startup File is executed, the user finally obtains the shell prompt and can type the command.
2. log on to the SVR4 terminal.
SVR4 supports two logon methods: (a) getty, which is the same as above. (B) ttymon logon, a new feature of SVR4. Getty is usually used in the console, while ttymon is used for logon from other terminals.
Ii. network logon 1. 4.3 + BSD network logon
During terminal logon, init knows which terminal devices can be used to log on and generates a getty process for each device. However, all network logins go through the kernel's network interface driver and do not know how many such logins are there. Instead of waiting for every possible login, a process must wait for the arrival of a network connection request. In 4.3 + BSD, there is a process called inetd, which waits for most network connections.
As part of the system startup, init calls a shell to execute the shell script stc/rc. This shell script starts an inetd sprite process. Once the shell script is terminated, the parent process of inetd becomes init. Inetd waits for the TCP/IP connection request to arrive at the host. When a connection request arrives, it executes the fork once and then the child process executes the appropriate program.
Assume that a TCP connection request is sent to the TELNET server. TELNET is a remote login application using the TCP protocol. Users on another host or on the same host start the TELNET client process to start the logon process:
telnet hostname
The client process opens a TCP connection to the host named hostname. The program started on the host named hostname is called the TELNET server. Then, client processes and server processes exchange data over TCP connections using the TELNET application protocol. What happened was that the user who started the client process now logged on to the host where the server process is located. Displays the process sequence involved in executing the TELNET server process (called telnetd.
Then, the telnetd process opens a pseudo-terminal device and uses fork to generate a sub-process. The parent process processes communications over network connections, and the child process executes the login program. Parent and Child processes are connected through pseudo terminals. Before exec is called, the sub-process connects the file descriptors 0, 1 and 2 to the Pseudo Terminal. If the logon is correct, login will execute: change the current working directory to the starting directory, set the group ID and user ID of the logged-on user, and set the starting environment of the logged-on user. Login uses exec to replace itself with the logon shell of the login user. Displays the process schedule at this point
When logging on through a terminal or network, we get a login shell, which connects to a terminal or Pseudo Terminal Device with standard input, output, and standard errors.
2. SVR4 network logon
The network logon condition in SVR4 is almost the same as that in 4.3 + BSD. The inetd server process is also used, but inetd is called as a Service Access Controller sac in SVR4, and its parent process is not init. The final result is the same.
3. Process Group
In addition to a process ID, each process also belongs to a process group. A process group is a collection of one or more processes. Each process group has a unique process group ID. The process group ID is similar to the process ID. It is a positive integer and can be stored in the pid_t data type. The getpgrp function returns the ID of the Process Group of the calling process.
# Include <sys/types. h> # include <unistd. h> pid_t getpgrp (void); Return Value: ID of the process group that calls the process
Each process group has a leader process. The process ID of the leader is: The Process Group ID equals to the process ID.
A process group leader can create a process group, create a process in the group, and terminate the process. As long as a process exists in a process group, the process group exists and has nothing to do with the termination of the Process leader. The time interval from the creation of a process group to the final exit of the last process (the process can be terminated or joined to another process group) is called the life cycle of the process group.
Processes that call setpgid can join an existing group or create a new process group.
# Include <sys/types. h> # include <unistd. h> int setpgid (pid_t pid, pid_t pgid); Return Value: 0 if successful, error:-1
This sets the pid process's process group ID to pgid. If the two parameters are equal, the process specified by the pid becomes the process group leader.
A process can only set process group IDs for itself or its sub-processes. After its sub-process calls exec, it no longer changes the process group ID of the sub-process.
If the pid is 0, the caller's process ID is used. If the pgid is 0, the process ID specified by the pid is used as the process group ID.
If the system does not support job control, _ POSIX_JOB_CONTROL is not defined. In this case, this function returns an error and errno is set to ENOSYS.
In most job control shells, this function is called after fork to enable the parent process to set the process group ID of its child processes, and then enable the child process to set its own process group ID. One of these calls is redundant, but this ensures that the parent and child processes enter the process group before further operations. If this is not done, an actual state condition is generated because it depends on which process is executed first.
Iv. Dialog Period
A session is a set of one or more Process Groups. For example, there can be an arrangement shown in. There are three process groups in a dialog. Several processes are usually grouped by the shell pipeline. For example, the arrangement in may be formed by the following shell commands:
proc1 | proc2 &proc3 | proc4 | proc5
The process can call the setsid function to create a new dialog period.
# Include <sys/types. h> # include <unistd. h> pid_t setsid (void); Return Value: Process Group ID if successful;-1 if an error occurs
If the process that calls this function is not the leader of a process group, the function creates a new dialog period and the result is:
- This process becomes the first process of the new dialog period (session leader, where the first process is the process that creates the dialog period ). This process is the only process in the new dialog.
- This process becomes the leader process of a new process group. The new process group ID is the process ID of the calling process.
- This process has no control terminal. If this process has a control terminal before setsid is called, the connection is also released.
If the calling process is already the leader of a process group, this function returns an error. To ensure that the process is not in this situation, fork is usually called first, and then the parent process is terminated, while the child process continues. Because the child process inherits the process group ID of the parent process, it cannot be the process group leader.