Send Signal to a Process in C

  1. Use the kill Function to Send Signal to a Process in C
  2. Use the kill Function and Null Signal to Check the Existence of the Process in C

This article will explain several methods of how to send a signal to a process in C.

Use the kill Function to Send Signal to a Process in C

Signals are interrupt-style notifications that may denote the specific event and can be sent to a process. One process can send a signal to another one if the first has the right permissions. Signals are a type of inter-process communication that can be utilized to interact with different programs, with child processes, or with threads. The kill function can be used to send various signals to a process. It takes two arguments - a process ID and signal number to be delivered. Note that, signal numbers are constant integers that are defined as SIG___ type macros.

In the following example, we demonstrate a program that creates a child process with the fork call and then executes the infinite loop incrementing an integer. Meanwhile, the parent process issues a SIGTERM signal, which terminates the child process, and the main function exits after receiving the child status code using the waitpid call.

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <signal.h>

int main(int argc, char *argv[]) {
    int wstatus;

    pid_t c_pid = fork();
    if (c_pid == -1) {
        perror("fork");
        exit(EXIT_FAILURE);
    }

    if (c_pid == 0) {
        printf("printed from child process - %d\n", getpid());

        int count = 0;

        while (1) {
            count += 1;
        }

        exit(EXIT_SUCCESS);
    } else {
        printf("printed from parent process - %d\n", getpid());
        int ret;

        ret = kill(c_pid, SIGTERM);
        if (ret == -1) {
            perror("kill");
            exit(EXIT_FAILURE);
        }

        if (waitpid(c_pid, &wstatus, WUNTRACED | WCONTINUED) == -1) {
            perror("waitpid");
            exit(EXIT_FAILURE);
        }
    }

    exit(EXIT_SUCCESS);
}

Use the kill Function and Null Signal to Check the Existence of the Process in C

Another use case for the kill function is to check for the process’s existence. Even when you try to verify the existence of some process with this method, there may be a scenario when the retrieved status is incorrect. That may be caused when the observed process is already terminated, and a different program is using the same ID since the operating system allows the reuse of identification numbers.

kill needs to be passed a signal number - zero, and the return code of the function should be tested for errno codes. Namely, if the kill returns -1 error code and errno is set to ESRCH, the given process does not exist. If the error code is returned with EPERM value of errno - program exists, but the caller process does not have the permission to send a signal. In case the zero is returned the process exists, and the caller process can send it other signals.

The following code sample implements the above status checking statements and prints the corresponding message.

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <signal.h>
#include <errno.h>
#include <stdbool.h>

int main(int argc, char *argv[]) {
    int wstatus;

    pid_t c_pid = fork();
    if (c_pid == -1) {
        perror("fork");
        exit(EXIT_FAILURE);
    }

    if (c_pid == 0) {
        printf("printed from child process - %d\n", getpid());

        int count = 10;

        while (count >= 0) {
            count -= 1;
            sleep(1);
        }

        exit(EXIT_SUCCESS);
    } else {
        printf("printed from parent process - %d\n", getpid());
        int ret;

        errno = 0;
        ret = kill(c_pid, 0);
        if (ret == -1) {
            if (errno == EPERM)
                printf("Process exists, but we don't have "
                       "permission to send it a signal\n");
            else if (errno == ESRCH)
                printf("Process does not exist\n");
            else
                perror("kill");
            exit(EXIT_FAILURE);
        } else {
            printf("Process exists and we can send it a signal\n");
        }


        if (waitpid(c_pid, &wstatus, WUNTRACED | WCONTINUED) == -1) {
            perror("waitpid");
            exit(EXIT_FAILURE);
        }
    }

    exit(EXIT_SUCCESS);
}
Write for us
DelftStack articles are written by software geeks like you. If you also would like to contribute to DelftStack by writing paid articles, you can check the write for us page.

Related Article - C Signal

  • Handle SIGINT Signal in C