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.
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.