Search code examples
shellprocessoperating-systemsignalsinterrupt

How tty interrupts are sent from pid 0?


This code prints the pid and uid of a caught signal:

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


static void my_handler(int signum, siginfo_t *siginfo, void *context) {
    FILE *f = fopen("sig_clog.txt", "a");
    fprintf(f, "Got signal '%d' from process '%d' of user '%d'\n",
        signum, siginfo->si_pid, siginfo->si_uid);
    fclose(f);
}

int main(void) {
    FILE *f = fopen("sig_clog.txt", "w");
    fclose(f);

    struct sigaction act;
    memset(&act, '\0', sizeof(act));
    act.sa_sigaction = &my_handler;
    act.sa_flags = SA_SIGINFO;
    sigaction(SIGINT, &act, NULL);
    sigaction(SIGTSTP, &act, NULL);
    sigaction(SIGCONT, &act, NULL);
    sigaction(SIGHUP, &act, NULL);

    printf("Hi, my pid is %d\n", getpid());
    printf("my parent pid is %d\n", getppid());
    while(1)
        sleep(1000);
    return 0;
}

After running this, if I open a different terminal and use kill command to send signal to this process, it writes a pid and an uid (they are some random numbers and I'm not sure if it is correct). But instead, if I interrupt using Ctrl+C, then it writes pid and uid as 0. Isn't the process with pid 0 is the kernel process? I was expecting the pid to be that of the shell. How the shell is making kernel to send signal to the process and why?

Also, apart from int, tstp and quit, is there any way to generate signals through shell itself? or to add custom signal keycodes? like making Ctrl+K to send kill signal? I saw stty command options, I didn't find any.


Solution

  • There is no PID 0. The first PID is 1, which is a special daemon.

    If a PID 0 process existed, it would not be possible to send it signals because kill(0, signal) means to send a signal to every member of the process group of the calling process.

    In other words, a pid_t value of 0, as well as negative values, have a reserved meaning in process-related interfaces.

    It looks like in this situation, the zero value of sig_pid indicates that the signal wasn't generated by a process.

    TTY signals are generated by the TTY subsystem (code in the kernel), not by a specific process.