Question

I have c code as such

int childid;
int parentid;
void siginthandler(int param)
{
 // if this is the parent process
 if(getpid() == parentid){
   //handler code which sends SIGINT signal to child process
 kill(childid, SIGINT);
 }
 else // if this is the child process
 exit(0);
}

int main()
{
parentid = getpid(); // store parent id in variable parentid, for the parent as well as child process
int pid = fork();
int breakpid;
if(pid != 0){
childid = pid;
breakpid =  wait();
printf("pid = %d\n", breakpid);
}
else
sleep(1000);
}

Now, when I run this code, the parent process waits, while the child process sleeps. If I now interrupt (by pressing ctrl+c) the parent program, UNIX (POSIX standard) documentation tells me that the wait function should return -1, with errno set to EINTR. My code implementation however, kills the child process since the parent process sends the SIGINT signal to the child process. But, surprisingly,(in the parent process) wait does not return pid = -1 with errno set to EINTR. Instead, it returns the id of the child process, which got killed.

Is there an explanation for this?

Was it helpful?

Solution

When you install a signal handler with signal(), one of 2 things occur

  1. Most system calls get interrupted when a signal occurs, and sets errno to EINTR.
  2. Most system calls gets automatically restarted when a signal occurs (so they don't fail and set errno to EINTR).

Which of these 2 depends on your platform, on yours it's 2 (probably, you don't show any code that installs a signal handler.)

If you instead install a signal handler with sigaction(), you can control which behavior of 1 or 2 you want with the SA_RESTART flag.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top