Advanced Programming in UNIX Environment Episode 36

Sessions

A session is a collection of one or more process groups.

A process establishes a new session by calling the setsid function.

#include <unistd.h>

pid_t setsid(void);

If the calling process is not a process group leader, this function creates a new session. Three things happen.

1.The process becomes the session leader of this new session. (A session leader is the process that creates a session.) The process is the only process in this new session.
2.The process becomes the process group leader of a new process group. The new process group ID is the process ID of the calling process.
3.The process has no controlling terminal. (We’ll discuss controlling terminals in the next section.) If the process had a controlling terminal before calling setsid, that association is broken.

Some implementations, such as Solaris, join with the Single UNIX Specification in the practice of avoiding the use of the phrase ‘‘session ID,’’ opting instead to refer to this as the ‘‘process group ID of the session leader.’’ The two are equivalent, since the session leader is always the leader of a process group.

#include <unistd.h>

pid_t getsid(pid_t pid);
Controlling Terminal

Sessions and process groups have a few other characteristics.

  • 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.
  • The process groups within a session can be divided into a single foreground process group and one or more background process groups.
  • 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 press the terminal’s interrupt key (often DELETE or Control-C), the interrupt signal is sent to all processes in the foreground process group.
  • Whenever we press the terminal’s quit key (often Control-backslash), the quit signal is sent to all processes in the foreground process group.
  • If a modem (or network) disconnect is detected by the terminal interface, the hang-up signal is sent to the controlling process (the session leader).

POSIX.1 leaves the choice of the mechanism used to allocate a controlling terminal up to each individual implementation. We’ll show the actual steps in Section 19.4.
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, as long as the call to open does not specify the O_NOCTTY flag (Section 3.3).
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.) The POSIX.1 O_NOCTTY flag to open is not used by BSD-based systems, except in compatibility-mode support for other systems.

tcgetpgrp, tcsetpgrp, and tcgetsid Functions

We need a way to tell the kernel which process group is the foreground process group, so that the terminal device driver knows where to send the terminal input and the terminal-generated signals (Figure 9.7).

#include <unistd.h>
pid_t tcgetpgrp(int fd);

int tcsetpgrp(int fd, pid_t pgrpid);

The function tcgetpgrp returns the process group ID of the foreground process group associated with the terminal open on fd.

The tcgetsid function allows an application to obtain the process group ID for the session leader given a file descriptor for the controlling TTY.

#include <termios.h>
pid_t tcgetsid(int fd);

Applications that need to manage controlling terminals can use tcgetsid to identify the session ID of the controlling terminal’s session leader (which is equivalent to the session leader’s process group ID).

Job Control

Job control is a feature that was added to BSD around 1980. This feature allows us to start multiple jobs (groups of processes) from a single terminal and to control which jobs can access the terminal and which jobs are run in the background. Job control requires three forms of support:

1.A shell that supports job control
2.The terminal driver in the kernel must support job control
3.The kernel must support certain job-control signals

SVR3 provided a different form of job control called shell layers. The BSD form of job control, however, was selected by POSIX.1 and is what we describe here. In earlier versions of the standard, job control support was optional, but POSIX.1 now requires platforms to support it.

The C shell supported job control, the Bourne shell didn’t, and it was an option with the Korn shell, depending on whether the host supported job control. But the C shell has been ported to systems (e.g., earlier versions of System V) that don’t support job control, and the SVR4 Bourne shell, when invoked by the name jsh instead of sh, supports job control. The Korn shell continues to support job control if the host does. The Bourne-again shell also supports job control.

The interaction with the terminal driver arises because a special terminal character affects the foreground job: the suspend key (typically Control-Z). Entering this character causes the terminal driver to send the SIGTSTP signal to all processes in the foreground process group. The jobs in any background process groups aren’t affected. The terminal driver looks for three special characters, which generate signals to the foreground process group.

  • 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.

Note that this example doesn’t work on Mac OS X 10.6.8. When we try to bring the cat command into the foreground, the read fails with errno set to EINTR. Since Mac OS X is based on FreeBSD, and FreeBSD works as expected, this must be a bug in Mac OS X.
I search for Stackoverflow, and it may be a kind of solution for this problem:
https://stackoverflow.com/questions/33064854/ctrlz-signal-handling-in-c
Obviously, macOS didn’t fix this problem and won’t fix it in the future.

Job control was originally designed and implemented before windowing terminals were widespread. Some people claim that a well-designed windowing system removes any need for job control. Some complain that the implementation of job control — requiring support from the kernel, the terminal driver, the shell, and some applications—is a hack. Some use job control with a windowing system, claiming a need for both. Regardless of your opinion, job control is a required feature of POSIX.1.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值