job control signal

    POSIX.1 considers the following six signals related to job control.
    * SIGCHLD: The child process has stopped or terminated.
    * SIGCONT: If the process has stopped, keep it running, otherwise ignore.
    * SIGSTOP: stop signal (cannot be caught or ignored).
    * SIGTSTP: Interactive stop signal.
    * SIGTTIN: background process group members read the control terminal.
    * SIGTTOU: The background process group member writes the controlling terminal.
    With the exception of SIGCHLD, most applications do not handle these signals, and the interactive shell usually handles all the work of these signals. When the suspend character (usually Ctrl+Z) is typed, SIGTSTP is sent to all processes in the foreground process group; when the shell is told to resume running a job in the foreground or background, the shell sends SIGCONT to all processes in the job Signal. When a SIGCONT signal is generated for a stopped process, the process continues, even if the signal is blocked or ignored.
    The following program demonstrates the canonical code sequence typically used when a program handles job control. The program simply copies its standard input to standard output, and in the signal handler the typical actions performed by a program that manages the screen (such as a VI) are given in the form of comments.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>

#define BUFFER	1024

static void sig_tstp(int signo){	// signal handler for SIGTSTP
	/* ... move cursor to lower left corner, reset tty mode ... */

	/* Unblock SIGTSTP, since it's blocked while we're handling it */
	sigset_t mask;
	sigemptyset(&mask);
	sigaddset(&mask, SIGTSTP);
	sigprocmask(SIG_UNBLOCK, &mask, NULL);

	signal(SIGTSTP, SIG_DFL);		// reset disposition to default
	printf("send SIGTSTP\n");
	kill(getpid(), SIGTSTP);		// and send the signal to ourself
	printf("received SIGCONT\n");

	/* We won't return from the kill untill we're continued */

	signal (SIGTSTP, sig_tstp); // reestablish signal handler

	/* ... reset tty mode, redraw screen ... */
}

int main(void){
	ssize_t	n;
	char buf[BUFFER];

	/* Only catch SIGTSTP if we're running with a job-control shell */
	if(signal(SIGTSTP, SIG_IGN) == SIG_DFL)
		signal (SIGTSTP, sig_tstp);
	while((n=read(STDIN_FILENO, buf, BUFFER)) > 0){
		if(write(STDOUT_FILENO, buf, n) != n)
			printf("write error\n");
	}
	if(n < 0)
		printf("read error\n");
	exit(0);
}

    The reason for arranging to catch the SIGTSTP signal here only if its configuration is SIG_DFL is that init will set SIGTSTP, SIGTTIN, and SIGTTOU to SIG_IGN, which will be inherited by all login shells. So when this program is started by a shell that does not support job control (such as /bin/sh), the configuration for this signal will be set to SIG_IGN. Only the job control shell should reset these 3 signals to SIG_DFL.
    The program results are as follows.
$ ./jobCtrlDemo.out
abcde # read input
abcde # output
^Zsend SIGTSTP # Ctrl-Z send SIGTSTP signal to suspend process
[1]+  Stopped                 ./jobCtrlDemo.out
$ ps # View process ID
   PID TTY          TIME CMD
 23893 pts/1    00:00:00 jobCtrlDemo.out
 23914 pts/1 00:00:00 ps
 82002 pts/1    00:00:05 bash
$
$ kill -SIGCONT 23893 # Send the SIGCONT signal to keep the process running
received SIGCONT
[1]+  Stopped                 ./jobCtrlDemo.out

    When the suspend character is typed, the process receives the SIGTSTP signal and then calls the signal handler. At this time, terminal-related processing (such as moving the cursor to the lower left corner, restoring the terminal working mode, etc.) should be performed. After resetting SIGTSTP to its default value (stopping the process), and unblocking this signal (because the system automatically blocks while a signal is being caught), the process sends the same signal SIGTSTP to itself, causing the system to stop the process. Only when the process receives the SIGCONT signal will it continue to run as if it had returned from the kill function. Finally reset SIGTSTP to capture and do some terminal processing (like repainting the screen).

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326119755&siteId=291194637