Linux kill Command principle and source code implementation

When working on Linux, you may see applications or command-line processes get stuck. Then in these cases, terminating it is the only way out.

The Kill Command in Linux (located in / bin/kill) is a built-in command used to manually terminate a process. The kill command is very easy to understand and use. The Kill Command sends a signal to the process that terminates the process. If the user does not specify any signal to be sent with the Kill Command, the default TERM signal is sent to terminate the process.

What is a signal

The official explanation is:

A signal is an asynchronous notification sent to a process or to a
specific thread within the same process in order to notify it of an
event that occurred.

A signal is an asynchronous notification sent to a process or a specific thread within the same process to notify it of events.

Unix and Linux like operating systems processes uses SIGNALS in order to communicate each other. For example If we can to kill a process we need to send a signal to process we want to kill. This signal will be SIGTERM and send by kill or similar commands. In this tutorial we will examine the SIGTERM signal and compare with SIGKILL signal.

Operating system processes such as Unix and Linux use SIGNALS to communicate. For example, if we can terminate a process, we need to send a signal to the process to be terminated. The signal will be SIGTERM and sent by kill or similar command.

The simple understanding is that you send a SIGKILL to a process. The process knows that the user wants to kill it, and then it will terminate the process.

Name and value of the signal

You can use the kill – l command to see what signals are available to the current system.


These names begin with a three character SIG. There is no signal with number 0. Among them, signals 1-31 are called conventional signals (also called ordinary signals or standard signals), and 34-64 are called real-time signals. The driving programming is related to hardware. The names are not different. The first 32 names are different.

Under Linux, you can check the signal(7) man page to see the list of signal names, signal values, default behavior and whether they can be captured. Its commands are as follows:

SIGTERM and SIGKILL

SIGTERM and SIGKILL provide similar functions. Both kill a given process or program. But there are some subtle differences.

1. Sigderm tries to kill each other politely. SIGKILL will kill each other severely
2. SIGTERM can be processed, but SIGKILL cannot be processed
3. SIGTERM is the first way to kill a process, but it doesn't work. SIGKILL can be used.

Recognize the kill Command

The kill command is usually used to kill a process. It sends a signal internally. You can use this tool to send different signals according to what you want to do. The following is the syntax of the command:

kill [options] < pid > [...]

How do I use the kill command to terminate a process?

The Kill Command sends a signal to a running process (SIGTERM signal by default). This default action usually stops the process. If you want to stop the process, use the ps command to get the pid of the application, and then pass it to the kill command to terminate it.

Under normal users, we may need to send SIGTERM signals to root or other user processes. We can use the sudo command in other commands to obtain root privileges, which will enable us to kill all processes in the Linux system.

kill command source code implementation

const char *signm[] = { 0,
"HUP", "INT", "QUIT", "ILL", "TRAP", "IOT", "EMT", "FPE",	/* 1-8 */
"KILL", "BUS", "SEGV", "SYS", "PIPE", "ALRM", "TERM", 0,	/* 9-16 */
"STOP", "TSTP", "CONT", "CHLD", "TTIN", "TTOU", "TINT", "XCPU",	/* 17-24 */
"XFSZ", 0, 0, 0, 0, 0, 0, 0,					/* 25-31 */
};

static void usage(void)
{

	(void)fprintf(stderr, "%s\n%s\n%s\n%s\n",
		"usage: kill [-s signal_name] pid ...",
		"       kill -l [exit_status]",
		"       kill -signal_name pid ...",
		"       kill -signal_number pid ...");
#ifdef SHELL
	error(NULL);
#else
	exit(2);
#endif

}
static void printsignals(FILE *fp)
{
	int n;

	for (n = 1; n < NSIG; n++) {
		(void)fprintf(fp, "%s", signm[n]);
		if (n == (NSIG / 2) || n == (NSIG - 1))
			(void)fprintf(fp, "\n");
		else
			(void)fprintf(fp, " ");
	}
}

static void nosig(const char *name)
{

	warnx("unknown signal %s; valid signals:", name);
	printsignals(stderr);
#ifdef SHELL
	error(NULL);
#else
	exit(2);
#endif
}

static int signame_to_signum(const char *sig)
{
	int n;

	if (strncasecmp(sig, "SIG", 3) == 0)
		sig += 3;
	for (n = 1; n < NSIG; n++) {
		if (!strcasecmp(signm[n], sig))
			return n;
	}
	return -1;
}


int main(int argc, char *argv[])
{
	long pidl;
	pid_t pid;
	int errors, numsig, ret;
	char *ep;

	if (argc < 2)
		usage();

	numsig = SIGTERM;

	argc--, argv++;
	if (!strcmp(*argv, "-l")) {
		argc--, argv++;
		if (argc > 1)
			usage();
		if (argc == 1) {
			if (!isdigit(**argv))
				usage();
			numsig = strtol(*argv, &ep, 10);
			if (!**argv || *ep)
				errx(2, "illegal signal number: %s", *argv);
			if (numsig >= 128)
				numsig -= 128;
			if (numsig <= 0 || numsig >= NSIG)
				nosig(*argv);
			printf("%s\n", signm[numsig]);
			return (0);
		}
		printsignals(stdout);
		return (0);
	}

	if (!strcmp(*argv, "-s")) {
		argc--, argv++;
		if (argc < 1) {
			warnx("option requires an argument -- s");
			usage();
		}
		if (strcmp(*argv, "0")) {
			if ((numsig = signame_to_signum(*argv)) < 0)
				nosig(*argv);
		} else
			numsig = 0;
		argc--, argv++;
	} else if (**argv == '-' && *(*argv + 1) != '-') {
		++*argv;
		if (isalpha(**argv)) {
			if ((numsig = signame_to_signum(*argv)) < 0)
				nosig(*argv);
		} else if (isdigit(**argv)) {
			numsig = strtol(*argv, &ep, 10);
			if (!**argv || *ep)
				errx(2, "illegal signal number: %s", *argv);
			if (numsig < 0)
				nosig(*argv);
		} else
			nosig(*argv);
		argc--, argv++;
	}

	if (argc > 0 && strncmp(*argv, "--", 2) == 0)
		argc--, argv++;

	if (argc == 0)
		usage();

	for (errors = 0; argc; argc--, argv++) {
#ifdef SHELL
		if (**argv == '%')
			ret = killjob(*argv, numsig);
		else
#endif
		{
			pidl = strtol(*argv, &ep, 10);
			/* Check PID_ Tfill overflow */
			pid = (pid_t)pidl;
			if (!**argv || *ep || pid != pidl)
				errx(2, "illegal process id: %s", *argv);
			ret = kill(pid, numsig);
		}
		if (ret == -1) {
			warn("%s", *argv);
			errors = 1;
		}
	}

	return errors;
}

Compile run


The working principle of kill command is to send a system operation signal and the process identification number of a program to the Linux kernel, and then the system kernel can operate the process specified by the process identification number.

Note: the process number can be obtained through tools such as jps/ps/pidof/pstree/top

kill -9 PID

If SIGTERM does not work properly, we can use SIGKILL's harsh method. We can use the kill Command with the - 9 option to send the SIGKILL signal, which specifies the SIGKILL signal.

To stop all processes and log off yourself, enter the following command:

kill -9 0

This will send signal 9, SIGKILL signal, to all processes whose process group ID is equal to the sender process group ID. Since the shell cannot ignore the SIGKILL signal, this command also stops logging into the shell and logs you out

To stop all processes you own, enter the following command:

kill -9 -1

This command sends a signal 9, SIGKILL signal, to all processes owned by a valid user, even those started at other workstations and belonging to other process groups. If you are printing the list you requested, it will also stop.

The signal is set to ignore

When a program is executed, the status of all signals is the system default or ignored. Usually, all signals are set as their default actions unless the process calling exec ignores the signal.

How the shell handles background processing is set to ignore. For a non job control shell, when a process is executed in the background, for example:

./my_kill &

The shell automatically sets the background process's handling of interrupt and exit signals to ignore. When we press the interrupt character, it will not affect the background process.

summary

Signals are used in most complex applications. Understanding the reasons and methods of signal processing is very important for linux programming.

Welcome to WeChat official account encoding program. Welcome to add my micro signal (17865354792) to exchange learning.

Reference: Advanced Programming in UNIX Environment

Keywords: Linux Operation & Maintenance kill TCP/IP

Added by parkej60 on Wed, 15 Dec 2021 09:24:32 +0200