Advanced Programming in UNIX Environment Episode 37

Shell Execution of Programs

This session introudces a program which is talking about the result of the execution of ps. It depends on various kinds of situation, so the better undertanding in this session is executing the program by our own.

Some platforms support an option to have the ps(1) command print the process group ID associated with the session’s controlling terminal. This value would be shown under the TPGID column. Unfortunately, the output of the ps command often differs among versions of the UNIX System. For example, Solaris 10 doesn’t support this option. Under FreeBSD 8.0, Linux 3.2.0, and Mac OS X 10.6.8, the command

ps -o pid,ppid,pgid,sid,tpgid,comm

prints exactly the information we want.

Orphaned Process Groups
#include "apue.h"
#include <errno.h>

static void sig_hup(int signo)
{
    printf("SIGHUP recived, pid=%ld\n",(long)getpid());
}

static void pr_ids(char *name)
{
    printf("%s: pid=%ld, ppid=%ld, pgrp=%ld, tpgrp=%ld\n",
        name, (long)getpid(),(long)getppid(),(long)getpgrp(),
        (long)tcpgetpgrp(STDIN_FILENO));
    fflush(stdout);
}

int main(void)
{
    char c;
    pid_t pid;

    pr_ids("parent");
    if((pid=for())<0)
    {
        err_sys("fork error");
    }
    else if(pid>0)
    {
        sleep(5);
    }
    else
    {
        pr_ids("child");
        signal(SIGHUP,sig_hup);
        kill(getpid(),SIGTSTP);
        pr_ids("child");
        if(read(STDIN_FILENO,&c,1)!=1)
            printf("read error %d on controlling TTY\n",errno);
    }

    return 0;
}

After the fork,

  • The parent sleeps for 5 seconds. This is our (imperfect) way of letting the child execute before the parent terminates.
  • The child establishes a signal handler for the hang-up signal (SIGHUP) so we can see whether it is sent to the child. (We discuss signal handlers in Chapter 10.)
  • The child sends itself the stop signal (SIGTSTP) with the kill function. This stops the child, similar to our stopping a foreground job with our terminal’s suspend character (Control-Z).
  • When the parent terminates, the child is orphaned, so the child’s parent process ID becomes 1, which is the init process ID.
  • At this point, the child is now a member of an orphaned process group. The POSIX.1 definition of an orphaned process group is one in which the parent of every member is either itself a member of the group or is not a member of the group’s session. Another way of saying this is that the process group is not orphaned as long as a process in the group has a parent in a different process group but in the same session.
  • Since the process group is orphaned when the parent terminates, and the process group contains a stopped process, POSIX.1 requires that every process in the newly orphaned process group be sent the hang-up signal (SIGHUP) followed by the continue signal (SIGCONT).
  • This causes the child to be continued, after processing the hang-up signal. The default action for the hang-up signal is to terminate the process, so we have to provide a signal handler to catch the signal. We therefore expect the printf in the sig_hup function to appear before the printf in the pr_ids function.
FreeBSD Implementation

One of these structures is allocated for each session (e.g., each time setsid is called).

  • s_count is the number of process groups in the session. When this counter is decremented to 0, the structure can be freed.
  • s_leader is a pointer to the proc structure of the session leader.
  • s_ttyvp is a pointer to the vnode structure of the controlling terminal.
  • s_ttyp is a pointer to the tty structure of the controlling terminal.
  • s_sid is the session ID. Recall that the concept of a session ID is not part of the Single UNIX Specification.

The kernel contains one of these structures for each terminal device and each pseudo terminal device.

  • t_session points to the session structure that has this terminal as its controlling terminal. (Note that the tty structure points to the session structure, and vice versa.) This pointer is used by the terminal to send a hangup signal to the session leader if the terminal loses carrier (Figure 9.7).
  • t_pgrp points to the pgrp structure of the foreground process group. This field is used by the terminal driver to send signals to the foreground process group. The three signals generated by entering special characters (interrupt, quit, and suspend) are sent to the foreground process group.
  • t_termios is a structure containing all the special characters and related information for this terminal, such as baud rate, whether echo is enabled, and so on.
  • t_winsize is a winsize structure that contains the current size of the terminal window. When the size of the terminal window changes, the SIGWINCH signal is sent to the foreground process group. We show how to set and fetch the terminal’s current window size in Section 18.12.

The pgrp structure contains the information for a particular process group.

  • pg_id is the process group ID.
  • pg_session points to the session structure for the session to which this process group belongs.
  • pg_members is a pointer to the list of proc structures that are members of this process group. The p_pglist structure in that proc structure is a doubly linked list entry that points to both the next process and the previous process in the group, and so on, until a null pointer is encountered in the proc structure of the last process in the group.

The proc structure contains all the information for a single process.

  • p_pid contains the process ID.
  • p_pptr is a pointer to the proc structure of the parent process.
  • p_pgrp points to the pgrp structure of the process group to which this process belongs.
  • p_pglist is a structure containing pointers to the next and previous processes in the process group, as we mentioned earlier.

Finally, we have the vnode structure. This structure is allocated when the controlling terminal device is opened. All references to /dev/tty in a process go through this vnode structure.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值