2
#include<stdlib.h>
#include<unistd.h>
#include<signal.h>

int main(){

    pid_t pid = fork();

    if(pid==0){
            system("watch ls");
    }
    else{
            sleep(5);
            killpg(getpid(),SIGTERM);  //to kill the complete process tree.
    }
    return 0;
}

Terminal:

anirudh@anirudh-Aspire-5920:~/Desktop/testing$ gcc test.c
anirudh@anirudh-Aspire-5920:~/Desktop/testing$ ./a.out
Terminated

for the first 5 secs the output of the "watch ls" is shown and then it terminates because I send a SIGTERM.

Question: How can a process kills itself ? I have done kill(getpid(),SIGTERM);

My hypothesis: so during the kill() call the process switches to kernel mode. The kill call sends the SIGTERM to the process and copies it in the process's process table. when the process comes back to user mode it sees the signal in its table and it terminates itself (HOW ? I REALLY DO NOT KNOW ) (I think I am going wrong (may be a blunder) somewhere in my hypothesis ... so Please enlighten me)

This code is actually a stub which I am using to test my other modules of the Project. Its doing the job for me and I am happy with it but there lies a question in my mind how actually a process kills itself. I want to know the step by step hypothesis.

Thanks in advance

Anirudh Tomer

hexacyanide
  • 88,222
  • 31
  • 159
  • 162
Durin
  • 2,070
  • 5
  • 23
  • 37
  • 5
    Why would a process want to kill itself? If it decides to terminate, won't it just call `exit()`? – 341008 Jan 08 '11 at 07:06
  • 1
    How do you kill that which has no life??? – ta.speot.is Jan 08 '11 at 07:08
  • The reason is in the above case if u call exit() instead of kill then only the parent process gets killed. The child process becomes orphan and init becomes its new parent and it still keeps running. – Durin Jan 08 '11 at 07:09
  • I want that the whole process tree is terminated. if I use killpg(pid,SIGTERM) it does not work out for me and it kills only child and again "system()" function's process keeps running. I tried doing killpg(getpid(),SIGTERM) and it did the job for me. But again the question is how is that possible ? – Durin Jan 08 '11 at 07:17
  • 2
    Perhaps you should edit your question to ask how to kill the entire process tree, since that seems to be what you really want. – dthorpe Jan 08 '11 at 07:22
  • ah! but then people won't answer me "how is it possible that a process kills itself using kill() function". I may get answer to the question "how to kill a complete process tree" by going through some books/man pages or Googling but I want to know the hypothesis behind this behavior by the code I wrote – Durin Jan 08 '11 at 07:27
  • It calls the secret system call seppuku(2). ;-) But really, I don't think control returns to the process if you don't add a SIGTERM handler with signal(2). – Keith Jan 08 '11 at 11:30

5 Answers5

4

Your process dies because you are using killpg(), that sends a signal to a process group, not to a process.

When you fork(), the children inherits from the father, among the other things, the process group. From man fork:

   *  The child's parent process ID is the same as the parent's process ID.

So you kill the parent along with the child.

If you do a simple kill(getpid(), SIGTERM) then the father will kill the child (that is watching ls) and then will peacefully exit.

Andrea Spadaccini
  • 12,378
  • 5
  • 40
  • 54
  • No that's not correct. In my above code just replace `killpg` by `kill` and you will see after 5 secs the parent dies and the child is inherited by init process. Do ps -a at that time. Also another thing that I am doing wrong is `killpg(getpid(),SIGTERM);` but since the pgid and pid of the parent process is same it works here. Also the child process has the same pgid. it should have been `killpg(getpgid(getpid()),SIGTERM);` when BASH forks and execs a child process it changes it `pgid` and makes that equal to its `pid` so that even if the child does killpg bash remains safe. – Durin Feb 20 '11 at 12:21
2

so during the kill() call the process switches to kernel mode. The kill call sends the SIGTERM to the process and copies it in the process's process table. when the process comes back to user mode it sees the signal in its table and it terminates itself (HOW ? I REALLY DO NOT KNOW )

In Linux, when returning from the kernel mode to the user-space mode the kernel checks if there are any pending signals that can be delivered. If there are some it delivers the signals just before returning to the user-space mode. It can also deliver signals at other times, for example, if a process was blocked on select() and then killed, or when a thread accesses an unmapped memory location.

Maxim Egorushkin
  • 131,725
  • 17
  • 180
  • 271
0
kill(getpid(), SIGKILL);  // itself I think

I tested it after a fork with case 0: and it quit regular from separate parent process.

I don't know if this is a standard certification method ....

(I can see from my psensor tool that CPU usage return in 34% like a normal program code with a counter stopped ) .

msrd0
  • 7,816
  • 9
  • 47
  • 82
ivan
  • 1
0

I think it when it sees the SIGTERM signal in its process tables it first kills its child processes( complete tree since I have called killpg() ) and then it calls exit().

I am still looking for a better answer to this question.

Durin
  • 2,070
  • 5
  • 23
  • 37
-4

This is super-easy in Perl:

   { 
        local $SIG{TERM} = "IGNORE";
        kill TERM => -$$;
   }

Conversion into C is left as an exercise for the reader.

tchrist
  • 78,834
  • 30
  • 123
  • 180
  • from where did came Perl in between?? However thanks for sharing the info. I don't know perl so may be when I start working with it, I'll see this thing, – Durin Feb 20 '11 at 12:26