Ch20.9 โ€“ Sending Signals: kill()

 

Ch20.9 โ€“ Sending Signals: kill()
Linux System Programming ยท EmbeddedPathashala
๐Ÿ“ก Topic 9 of 19
๐ŸŽฏ Intermediate
๐Ÿ’ป 3 Code Examples
โ“ Interview Q&A
๐Ÿ”‘ Key Terms
kill() pid argument Process Group Broadcast Signal EPERM ESRCH CAP_KILL Permission Rules
What is kill()?

Despite its name, kill() does not just kill processes โ€” it sends any signal to a process or group of processes. The name comes from early UNIX where most available signals terminated the process.

This is the system call that the kill shell command uses under the hood.

#include <signal.h>
int kill(pid_t pid, int sig);
/* Returns 0 on success, -1 on error */
๐ŸŽฏ How the pid Argument is Interpreted
pid value Who receives the signal?
pid > 0 The specific process with that PID
pid == 0 Every process in the same process group as the caller
pid < -1 Every process in the process group whose ID = abs(pid)
pid == -1 Every process the caller has permission to signal (broadcast), except init and itself
๐Ÿ” Permission Rules for kill()
Sender Can send to?
Privileged process (CAP_KILL) Any process
init (PID 1) Can only receive signals it has a handler for (protected)
Unprivileged process Processes where sender’s real/effective UID matches receiver’s real UID or saved set-user-ID

Errors: EPERM = process exists but no permission. ESRCH = no matching process found.

๐Ÿ’ป Code Example 1 โ€“ Send SIGTERM to a Specific PID
/* Send a signal to a specific process by PID
   Compile: gcc -o send_sig send_sig.c
   Usage:   ./send_sig <PID> <signal_number> */

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>

int main(int argc, char *argv[])
{
    if (argc != 3) {
        fprintf(stderr, "Usage: %s <pid> <signal>\n", argv[0]);
        return 1;
    }

    pid_t pid = (pid_t)atoi(argv[1]);
    int   sig = atoi(argv[2]);

    if (kill(pid, sig) == -1) {
        perror("kill");
        return 1;
    }

    printf("Signal %d sent to PID %d\n", sig, (int)pid);
    return 0;
}
Usage: Start any program, note its PID, then run: ./send_sig 1234 15 to send SIGTERM to PID 1234.
๐Ÿ’ป Code Example 2 โ€“ Send Signal to Entire Process Group
/* Send signal to all processes in the same process group
   kill(0, sig) sends to everyone in caller's process group
   Compile: gcc -o group_sig group_sig.c */

#include <stdio.h>
#include <signal.h>
#include <unistd.h>

int main(void)
{
    printf("My PID=%d, PGID=%d\n", getpid(), getpgrp());

    /* Send SIGUSR1 to every process in our process group */
    if (kill(0, SIGUSR1) == -1)
        perror("kill(0, SIGUSR1)");
    else
        printf("SIGUSR1 sent to entire process group\n");

    return 0;
}
๐Ÿ’ป Code Example 3 โ€“ Check Permission / Handle Errors
/* Demonstrate EPERM and ESRCH error handling
   Compile: gcc -o kill_errors kill_errors.c */

#include <stdio.h>
#include <signal.h>
#include <errno.h>

int main(void)
{
    /* Try to signal init (PID 1) โ€” will fail with EPERM */
    if (kill(1, SIGUSR1) == -1) {
        if (errno == EPERM)
            printf("PID 1 (init) exists but we lack permission.\n");
        else if (errno == ESRCH)
            printf("PID 1 does not exist.\n");
        else
            perror("kill");
    }

    /* Try to signal a non-existent PID */
    if (kill(999999, SIGTERM) == -1) {
        if (errno == ESRCH)
            printf("PID 999999 does not exist (ESRCH).\n");
        else if (errno == EPERM)
            printf("Exists but no permission (EPERM).\n");
        else
            perror("kill");
    }

    return 0;
}
Remember: When kill() fails on a negative pid (process group), it returns -1 only if ALL processes in the group could not be signaled. It succeeds if at least one was signaled.
โ“ Interview Questions
Q1. Why is the system call named kill() when it sends any signal?
Historical reason โ€” in early UNIX, most available signals had the default action of terminating the process. So “sending a signal” and “killing the process” were nearly the same thing. The name stuck even as more signals with different default actions were added.
Q2. What happens when you call kill(-1, SIGTERM)?
It sends SIGTERM to every process that the calling process has permission to signal, except init (PID 1) and the calling process itself. This is called a “broadcast signal.”
Q3. What is the difference between EPERM and ESRCH errors from kill()?
ESRCH means no process matched the specified pid โ€” the process does not exist. EPERM means the process exists but the calling process lacks permission to send it a signal.
Q4. What permission check applies for an unprivileged process using kill()?
An unprivileged process can send a signal if its real or effective user ID matches the real user ID or saved set-user-ID of the target process.
Q5. What is a process group and how is it relevant to kill()?
A process group is a collection of related processes (e.g. a shell pipeline). kill(0, sig) sends to all processes in the caller’s group; kill(-pgid, sig) sends to all in the named group. This is how the shell implements job control.
Next Topic โ†’

Checking Process Existence โ€” The null signal trick

Next: Null Signal / Process Check โ†’ โ† Previous

Leave a Reply

Your email address will not be published. Required fields are marked *