Monday, April 23, 2018

Catching SIGALRM Signal: Self-driven using alarm function

What makes SIGALRM signal something special?  It is generally used with alarm function.
It is similar to raise function, except for 2 things
  1. SIGALRM is the only signal generated out of alarm function
  2. The signal is not raised immediately.  It is raised after some delay, that is specified by user.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <stdio.h>
#include <signal.h>
#include <unistd.h>

void alarm_catch(int signum)
{
 printf("\tCaught the signal %d\n",signum);
}

void main()
{
 //Registering SIGALRM signal
 signal(SIGALRM,alarm_catch);

 //Raise SIGALRM signal to same process after 3 seconds
 alarm(3);

 //Timer loop for 5 seconds: Each print message denotes one second passed
 for(int i=0;i<5;i++)
 {
  printf("TIME\n");
  fflush(stdout);
  sleep(1);
 }
 
}
Steps will be like this
  1. Registering the signal 
  2. Raising alarm.(To raise SIGALRM after 3 seconds)
  3. Timer Loop for 5 seconds
After alarm function is executed, next line of code will be executed without any delay. In the background, after 3 seconds SIGALRM would have been raised.
When we execute the program


root@kali:~# ./a.out
TIME
TIME
TIME
 Caught the signal 14
TIME
TIME

 We got 'Caught the signal 14'(alarm_catch function is executed) after 3 TIME messages (3 seconds, argument of alarm).

Catching Signal, Self-driven with raise function

Till now, we were trying to send signals from one process to another.  Today, we will self-generate the signal within its own function using raise.

Here is the sample program.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
#include <stdio.h>
#include <signal.h>

void signal_catch(int signum)
{
 printf("\tCaught the signal %d\n",signum);
}

void main()
{
 signal(SIGINT,signal_catch);
 
 printf("Issuing SIGINT signal to itself\n"); 
 raise (SIGINT);
 printf("Exiting\n");
}

As usual, we are registering signal function 'signal_catch' for SIGINT signal.  Using raise function, we are generating signal to its own function.

When we run the program, it is observed that signal_catch function will be executed because it caught the signal SIGINT because of 'raise'.


root@kali:~# ./a.out
Issuing SIGINT signal to itself
 Caught the signal 2
Exiting


Sunday, April 22, 2018

Catching Signal, Child to Parent

Now, I am sending a signal(Ctrl+C) from Child to Parent, using 'kill' command. 'Kill' needs pid of the process & Signal to be sent.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <sys/wait.h>

// Function telling what to do when we catch CTRL+C
void catch_signal (int sig_num)
{
 printf("SIGNAL FUNCTION>> Caught the signal %d by process with PID=%d\n",sig_num,getpid());
 fflush(stdout);
}

int main()
{
 pid_t child_pid;
 int status;

 child_pid=fork();
 
 if (child_pid == 0)
 {
  //This is Child Section
  //Registering the Signal Handler
  signal(SIGINT,catch_signal);
  
  printf("CHILD>>pid=%d Ppid=%d Waiting for Ctrl+C\n",getpid(),getppid());
  fflush(stdout);
  pause();
  
  printf("CHILD>>Caught the signal\n");
 }
 else
 {
  //This is Parent Section
  printf("PARENT>>Waiting couple of seconds to make sure, child waits for SIGINT\n");
  sleep(2);
  kill(child_pid,SIGINT);
  printf("PARENT>>Sent the SIGINT signal to child with pid=%d\n",child_pid); 
  wait(&status);
 }

 return 0;
}

Steps can be defined as:
  1. Process is forked
  2. Child registers signal handler
  3. Child waits for Ctrl+C
  4. Parent sleeps.
  5. Parent sends Ctrl+C using Kill command.
  6. Parent waits for Child to complete
In step 4, if Parent did not sleep, sometimes parents will send Ctrl+C, even before Child executes 'pause'.  Then by the time Child needs Ctrl+C, parent will not be in a position to send Ctrl+C because Parent had already sent it.
When we execute the program

root@kali:/media/root/persistence# ./a.out
PARENT>>Waiting couple of seconds to make sure, child waits for SIGINT
CHILD>>pid=3722 Ppid=3721 Waiting for Ctrl+C

Child waits for Ctrl+C, as Parent is sleeping.  Within moments, the rest of the program executes


root@kali:/media/root/persistence# ./a.out
PARENT>>Waiting couple of seconds to make sure, child waits for SIGINT
CHILD>>pid=3722 Ppid=3721 Waiting for Ctrl+C
SIGNAL FUNCTION>> Caught the signal 2 by process with PID=3722
PARENT>>Sent the SIGINT signal to child with pid=3722
CHILD>>Caught the signal

Sunday, April 15, 2018

Catching Signal, with fork

Today, I will demonstrate signals, by forking a child. 

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <sys/wait.h>

// Function telling what to do when we catch CTRL+C
void catch_signal (int sig_num)
{
 printf("Inside the signal function %d PID=%d\n", sig_num,getpid());
 fflush(stdout);
}

int main()
{
 pid_t child_pid;
 int status;

 // Registering the Signal Handler
 signal(SIGINT,catch_signal);

 child_pid=fork();
 
 if (child_pid == 0)
 {
  //This is Child Section
  printf("CHILD>>pid=%d Ppid=%d Waiting for Ctrl+C\n",getpid(),getppid());
  fflush(stdout);
  pause();
  printf("CHILD>>Caught the signal\n");
 }
 else
 {
  //This is Parent Section
  printf("PARENT>>pid=%d Ppid=%d Waiting for Ctrl+C\n",getpid(),getppid());
  fflush(stdout);
  pause();
  printf("PARENT>>Caught the signal\n");
  
  wait(&status);
 }

 return 0;
}

Summary of what I did:
  1.  Created a signal handling function
  2. Registered signal
  3. Forked the process
  4. Child, waits for the signal Ctrl+C
  5. parent also waits for the signal Ctrl+C
 After I executed

root@kali:/media/root/persistence# ./a.out
PARENT>>pid=2869 Ppid=2344 Waiting for Ctrl+C
CHILD>>pid=2870 Ppid=2869 Waiting for Ctrl+C

Execution 1:

When I hit Ctrl+C in the terminal, Parent and Child got terminated at the same time.

root@kali:/media/root/persistence# ./a.out
PARENT>>pid=2869 Ppid=2344 Waiting for Ctrl+C
CHILD>>pid=2870 Ppid=2869 Waiting for Ctrl+C
Inside the signal function 2 PID=2870
CHILD>>Caught the signal
Inside the signal function 2 PID=2869
PARENT>>Caught the signal

Execution 2:

From another terminal if I pass SIGINT individually to parent and child. They catch signal


root@kali:/media/root/persistence# ./a.out
PARENT>>pid=3119 Ppid=2344 Waiting for Ctrl+C
CHILD>>pid=3120 Ppid=3119 Waiting for Ctrl+C

From another terminal, I issue 'kill -s 2 3119' to the parent process. Parent executes the signal handling function.


root@kali:/media/root/persistence# ./a.out
PARENT>>pid=3119 Ppid=2344 Waiting for Ctrl+C
CHILD>>pid=3120 Ppid=3119 Waiting for Ctrl+C
Inside the signal function 2 PID=3119
PARENT>>Caught the signal
 
Then I issue 'kill -s 2 3120'


root@kali:/media/root/persistence# ./a.out
PARENT>>pid=3119 Ppid=2344 Waiting for Ctrl+C
CHILD>>pid=3120 Ppid=3119 Waiting for Ctrl+C
Inside the signal function 2 PID=3119
PARENT>>Caught the signal
Inside the signal function 2 PID=3120
CHILD>>Caught the signal

Saturday, April 14, 2018

Catching signal , Basic one

Today, I will write a basic program that will catch CTRL+C.  I will demonstrate it by sending CTRL+C from another terminal.


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <stdio.h>
#include <unistd.h>
#include <signal.h>

// Function telling what to do when we catch CTRL+C
void catch_signal (int sig_num)
{
 printf("Caught the signal %d\n", sig_num);
 fflush(stdout);
}

int main()
{
 // Registering the Signal Handler
 signal(SIGINT,catch_signal);

 printf("Waiting for the user to send CTRL+C\n");
 fflush(stdout);

 // Waiting for signal
 pause();
 printf("Finished handling the signal\n");

 return 0;
}

Steps involved in signal programming
  • Writing a Function that tells what to do when signal is caught
  • Registering the Signal, that tells what signal to catch and what corresponding function to be called
  • Waiting for the signal
I execute the program

root@kali:/media/root/persistence# ./a.out
Waiting for the user to send CTRL+C

Execution 1:
 
Now I hit Ctrl+C at this moment. The program continues

^CCaught the signal 2
Finished handling the signal

Execution 2:

In another terminal, I see the process ID and send signal '2' via kill command.


root@kali:/media/root/persistence# ps -aux | grep a.out
root      3620  0.0  0.0   4188   640 pts/0    S+   22:56   0:00 ./a.out
root      3622  0.0  0.0  12728   928 pts/1    S+   22:56   0:00 grep a.out
root@kali:/media/root/persistence# kill -s 2 3620

Program ends like this

root@kali:/media/root/persistence# ./a.out
Waiting for the user to send CTRL+C
Caught the signal 2
Finished handling the signal

How in this world, did I know the signal is 2. 'kill -l' provides the list of signals.


root@kali:/media/root/persistence# kill -l
 1) SIGHUP  2) SIGINT  3) SIGQUIT  4) SIGILL  5) SIGTRAP
 6) SIGABRT  7) SIGBUS  8) SIGFPE  9) SIGKILL 10) SIGUSR1
11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM
16) SIGSTKFLT 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP
21) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ
26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO 30) SIGPWR
31) SIGSYS 34) SIGRTMIN 35) SIGRTMIN+1 36) SIGRTMIN+2 37) SIGRTMIN+3
38) SIGRTMIN+4 39) SIGRTMIN+5 40) SIGRTMIN+6 41) SIGRTMIN+7 42) SIGRTMIN+8
43) SIGRTMIN+9 44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13
48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12
53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9 56) SIGRTMAX-8 57) SIGRTMAX-7
58) SIGRTMAX-6 59) SIGRTMAX-5 60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-2
63) SIGRTMAX-1 64) SIGRTMAX 

Thursday, April 12, 2018

waitpid waiting for pids to terminate

Last time, we used 'wait' to wait for any forked process to finish.  Now, using waitpid we can dictate what process to catch.   Here's the code:


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>

int main()
{
 pid_t child_pid1,child_pid2;
 
 printf ("This is the print before Fork\n");
 child_pid1=fork();
 
 if (child_pid1 == 0) {
  //This is Child 1
  printf("\tCHILD1 >> pid=%d----parentpid=%d\n",getpid(),getppid());
 
  printf("\tCHILD1 >> Child 1 starts sleeping\n");
  sleep(10);
  printf("\tCHILD1 >> Child 1 stops sleeping\n");
 } else {
  child_pid2=fork();
  if (child_pid2 == 0) {
   //This is Child 2
   printf("\tCHILD2 >> pid=%d----parentpid=%d\n",getpid(),getppid());

   printf("\tCHILD2 >> child 2 starts sleeping\n");
   sleep(3);
   printf("\tCHILD2 >> Child 2 stops sleeping\n");
  } else {
   //This is parent
   int status=0,ret;
   printf("Waiting for any Child to terminate\n");
   ret = waitpid(child_pid1,&status,0);
   printf("Caught first one %d with status %d\n\n",ret,status);

   printf("Waiting for any Child to terminate\n");
   ret = waitpid(child_pid2,&status,0);
   printf("Caught second one %d with status %d\n\n",ret,status);

   printf("Waiting for any Child to terminate\n");
   ret = wait(&status);
   printf("Caught third one %d\n",ret);
  }
 }
}

When the program is executed, after the following lines are print there will be a pause

root@kali:/media/root/persistence# ./a.out 
This is the print before Fork
Waiting for any Child to terminate
 CHILD1 >> pid=3196----parentpid=3195
 CHILD2 >> pid=3197----parentpid=3195
 CHILD1 >> Child 1 starts sleeping
 CHILD2 >> child 2 starts sleeping

Then the pause after the following line:

CHILD2 >> Child 2 stops sleeping

Then rest of the lines follows

 CHILD1 >> Child 1 stops sleeping
Caught first one 3205 with status 0

Waiting for any Child to terminate
Caught second one 3206 with status 0

Waiting for any Child to terminate
Caught third one -1

'Caught first one.......'. This line is executed as a result of wait_pid function call, in which we entered child_pid1 as the first argument.  I am ignoring the second and third arguments to reduce the complexity of understanding.  Even though child2 stops earlier than child1, as we mentioned specifically child_pid1 in wait_pid this happened.

The second wait_pid had child_pid2.  By the time, the program started executing this line, the second process has already been terminated.  So without any delay, things continued.

Saturday, April 7, 2018

Fork and Wait Example

Here is a little experimental programming.  Forked two processes and caught those processes.


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>

int main()
{
 pid_t child_pid1,child_pid2;
 
 printf ("This is the print before Fork\n");
 child_pid1=fork();
 
 if (child_pid1 == 0) {
  //This is Child 1
  printf("\tCHILD1 >> pid=%d----parentpid=%d\n",getpid(),getppid());
 
  printf("\tCHILD1 >> Child 1 is sleeping\n");
  sleep(10);
  printf("\tCHILD1 >> Child 1 wokeup and is terminated\n\n");
 } else {
  child_pid2=fork();
  if (child_pid2 == 0) {
   //This is Child 2
   printf("\tCHILD2 >> pid=%d----parentpid=%d\n",getpid(),getppid());

   printf("\tCHILD2 >> child 2 is sleeping\n");
   sleep(3);
   printf("\tCHILD2 >> Child 2 wokeup and is terminated\n\n");
  } else {
   //This is parent
   int status=0,ret;
   printf("Waiting for any Child to terminate\n");
   ret = wait(&status);
   printf("Caught first one %d\n\n",ret);

   printf("Waiting for any Child to terminate\n");
   ret = wait(&status);
   printf("Caught second one %d\n\n",ret);

   printf("Waiting for any Child to terminate\n");
   ret = wait(&status);
   printf("Caught third one %d\n",ret);
  }
 }
}

We forked two processes,
  • Child 1 will sleep for 10 secs
  • Child 2 will sleep for 3 secs
  • Child 2 will exit before Child 1
  • 2 Wait commands to catch watever child exists first
  • A wait more to see what happens if there are no more childs left
The output of the program is

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
root@kali:/media/root/persistence# ./a.out
This is the print before Fork
Waiting for any Child to terminate
 CHILD1 >> pid=2835----parentpid=2834
 CHILD1 >> Child 1 is sleeping
 CHILD2 >> pid=2836----parentpid=2834
 CHILD2 >> child 2 is sleeping
 CHILD2 >> Child 2 wokeup and is terminated

Caught first one 2836

Waiting for any Child to terminate
 CHILD1 >> Child 1 wokeup and is terminated

Caught second one 2835

Waiting for any Child to terminate
Caught third one -1

The second child, child2 (2836) will exit first.  Then the first child, child1(2385) will exit next.  The third wait, as it had no child to wait for returns -1.



Thursday, April 5, 2018

Avoiding Zombie Child Process

Refreshing your memory by picking few points from Zombie Process

once the exit status is read via the wait system call, the zombie's entry is removed from the process table and it is said to be "reaped"

I included few things in my program, and started observing.

In the child section,
  • I included sleep to verify if the child process is created.
In the parent section,
  • I am waiting to for the child to exit using ret 
  • Sleeping to verify if the child remained defunct process
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>

int main()
{
 pid_t child_pid;
 
 printf ("This is the print before Fork\n");
 child_pid=fork();
 
 if (child_pid == 0) {
  //This is Child
  printf("\tpid=%d\n",getpid());
  printf("\tparentpid=%d\n",getppid());
  printf("\tChild ID=%d\n",child_pid);
 
  printf("\tChild is sleeping. Verify ps for child process list\n");
  sleep(10);
  printf("\tChild wokeup and is terminated\n");
 } else {
  //This is Parent
  printf("pid=%d\n",getpid());
  printf("parentpid=%d\n",getppid());
  printf("Child ID=%d\n",child_pid);
  
  int status=0,ret;
  printf("Waiting for the Child to terminate\n");
  ret = wait(&status);
  printf("Wait is over. Return value ret=%d\n",ret);
  
  printf("Parent Sleeping.  Verify ps for child defunc status\n");
  sleep(20);
  printf("Parent Terminated\n");
 }
}

When the child is sleeping, 'ps' as usual shows parent and child process.

1
2
3
4
5
6
7
8
9
root@kali:/media/root/persistence# ./a.out 
This is the print before Fork
pid=3088
 pid=3089
 parentpid=3088
parentpid=2797
 Child ID=0
Child ID=3089
 Child is sleeping. Verify ps for child process list

1
2
3
4
5
6
root@kali:/media/root/persistence# ps -e -o pid,ppid,cmd | tail -5
 3080     2 [kworker/0:2]
 3088  2797 ./a.out
 3089  3088 ./a.out
 3090  3020 ps -e -o pid,ppid,cmd
 3091  3020 tail -5

After child process is terminated and if we look at ps. Child would have been terminated and only parent process remains.  There is no defunct process.  We avoided zombie process as wait was called to retrieve the status of process.


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
root@kali:/media/root/persistence# ./a.out 
This is the print before Fork
pid=3088
 pid=3089
 parentpid=3088
parentpid=2797
 Child ID=0
Child ID=3089
 Child is sleeping. Verify ps for child process list
Waiting for the Child to terminate
 Child wokeup and is terminated
Wait is over. Return value ret=3089
Parent Sleeping.  Verify ps for child defunc status

1
2
3
4
5
6
root@kali:/media/root/persistence# ps -e -o pid,ppid,cmd | tail -5
 3043     2 [kworker/u8:3]
 3080     2 [kworker/0:2]
 3088  2797 ./a.out
 3092  3020 ps -e -o pid,ppid,cmd
 3093  3020 tail -5

At the end, here is the output of the program.


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
root@kali:/media/root/persistence# ./a.out 
This is the print before Fork
pid=3088
 pid=3089
 parentpid=3088
parentpid=2797
 Child ID=0
Child ID=3089
 Child is sleeping. Verify ps for child process list
Waiting for the Child to terminate
 Child wokeup and is terminated
Wait is over. Return value ret=3089
Parent Sleeping.  Verify ps for child defunc status
Parent Terminated

Observe the return value at line 12. Wait function returns the process ID of the child that got terminated.

Sunday, April 1, 2018

Look for Zombie Child Process

After forking a process, child and parent processes will execute and die.  If Child dies first, it will become a zombie process, unless it is handled.  Right now, I am not handling anything. Just doing a small extension to my previous program.


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>

int main()
{
 pid_t child_pid;
 
 printf ("This is the print before Fork\n");
 child_pid=fork();
 
 if (child_pid == 0) {
  //This is Child
  printf("\tpid=%d\n",getpid());
  printf("\tparentpid=%d\n",getppid());
  printf("\tChild ID=%d\n",child_pid);
  
  printf("\tChild Dying\n");
 } else {
  //This is Parent
  printf("pid=%d\n",getpid());
  printf("parentpid=%d\n",getppid());
  printf("Child ID=%d\n",child_pid);
  
  sleep(20);
 }
}

Note the sleep command in line 26. When the parent is sleeping (that is still processing), child is dead.


1
2
3
4
5
6
7
8
9
root@kali:/media/root/persistence# ./a.out 
This is the print before Fork
pid=5185
parentpid=3594
Child ID=5186
 pid=5186
 parentpid=5185
 Child ID=0
 Child Dying


1
2
3
4
5
6
7
root@kali:/media/root/persistence# ps -e -o pid,ppid,command
  PID  PPID COMMAND
.......
 4761     2 [kworker/3:0]
 4769  3594 ./a.out
 4770  4769 [a.out] <defunct>
 4771  2558 ps -e -o pid,ppid,command



In the process list, we see that the child process(pid # 4770) is listed as <defunct>.  It means it is Zombie Process.

According to Wikipedia, a zombie process or defunct process is a process that has completed execution (via the exit system call) but still has an entry in the process table: it is a process in the "Terminated state". This occurs for child processes, where the entry is still needed to allow the parent process to read its child's exit status: once the exit status is read via the wait system call, the zombie's entry is removed from the process table and it is said to be "reaped".