Everything to programatically understand about Zombie processes and Avoiding them under GNU/LINUX

A Zombie is a process which has died but its entry still remains in the process table.This happens in unix and unix-like Operating systems when parent doesnot execute wait() system call for its child processes .

USEFULNESS OF ZOMBIES

*Parent process can fetch the information of the child process from the process table entry even after the child has died by expecting wait() or waitpid() system call .

*The pid of the zombie process will not be allocated to any new process

Disadvantages of Zombie processes

*The presence of a few zombies is not worrisome in itself, but may indicate a problem that would grow serious under heavier loads. Since there is no memory allocated to zombie processes except for the process table entry itself, the primary concern with many zombies is not running out of memory, but rather running out of process ID numbers.

SIGCHLD signal

When a child process exists , it sends a SIGCHLD signal to the parent , by default this signal is not taken into account unless a signal handler is setup

Ways of avoiding creation of Zombie processes

*Execute wait() system call in the sequential code of the parent

  Image

#include<stdio.h>

#include<unistd.h>

#include<time.h>

int main()

{

pid_t pid;

int status;

pid=fork();

if(pid==0) /*child proces exists*/

{

exit(0);

}

printf(“\nThe process Id of the Zombie child process is %d\n\n\n”,pid);

system(“ps -aeo pid,stat | grep Z”);

/*obtain the process list with the status information and grep for Z which indicates that the proces is a Zombie */

printf(“\n\n\nZ+ Indicates that the process with PID=%d is a Zombie running in foreground\n\n”,pid);

sleep(5);

pid=wait(&status);/*wait returns the pid of the child that was terminated */

printf(“\n\nThe Zombie status of the child process pid=%d is removed\n\n”,pid);

system(“ps -aeo pid,stat | grep Z”);/*this call doesnt result in any output since there Zombie status of the child process no more exists, since wait system call is executed in the parent*/

sleep(5);

exit(0);

}

*Execute waitpid() system call in the sequential code of the parent

 Image

#include <sys/wait.h>

#include <stdlib.h>

#include <unistd.h>

 

int main(void)

{

pid_t pids[10];

int i;

char message[]=”\n\nTen Zombie child processes created the shell command inside call to system illustrates this\n\n”;

 

for (i = 9; i >= 0; –i) {

pids[i] = fork();

if (pids[i] == 0) {

 

_exit(0);

}

}

/*for each iteration of the for loop fork() is called and the child process is made to exit without waiting for them in the parent , this results in creation of 10 Zombies , which is clearly illustrated the ps command inside the call to system()*/

write(1,message,sizeof(message));

system(“ps -aeo pid,stat | grep Z”);

for (i = 9; i >= 0; –i)

 waitpid(pids[i], NULL, 0);/*Equivalent of executing wait() call ten times */

return 0;

}

*setup a signal handler using signal() or sigaction() system call use wait() system call inside it

Image 

#include<signal.h>

#include<stdio.h>

#include<unistd.h>

#include<time.h>

void Child_handler(int status)

{

pid_t pid;

printf(“\n\nSIGCHLD generated and caught “);

pid=wait(&status);

printf(“\n\nProcess Id of the Zombie Child = %d\n\n”,pid);

return ;

}

int main()

{

pid_t pid;

int status;

pid=fork();

signal(SIGCHLD,Child_handler);

/*Child_handler is the function where control moves onto when SIGCHLD is generated , that is when the child dies*/

if(pid==0) /*child proces exists*/

{

exit(0);

}

sleep(2);

exit(0);

}

*In modern implementations by explicitly ignoring SIGCHLD by setting its handler to SIG_IGN

#include<signal.h>

#include<stdio.h>

#include<unistd.h>

#include<time.h>

int main()

{

pid_t pid;

int status;

pid=fork();

signal(SIGCHLD,SIG_IGN);

/*In modern implementations of the Linux systems , by explicitly setting the signal handler for the SIGCHLD signal to SIG_IGN zombies can be avoided*/

if(pid==0) /*child proces exists*/

{

exit(0);

}

system(“ps -aeo pid,stat | grep Z”);/*This execution of shell command doesnt give any output since There are no Zombie processes*/

printf(“\n\nNo Zombies created \n\n”);

sleep(2);

 exit(0);

}

*When the parent process dies init becomes parent of all the Child processes including the Zombie child processes

Implementation of Circular Queue

//The code will not run under most of the Compilers in Windows OS
//Many of the declration techniques used the code doesnot work in old complilers like TURBO C
//The code is tested in Code blocks 10.05 and GCC under LINUX operating system
//download link for code blocks compliler http://www.codeblocks.org/downloads
//It would be very easy to download and use code blocks if you are using Ubuntu linux distribution
//Or else GCC can be used which comes along with any GNU/LINUX distributions
#define n 5//Set the size of queue here
#include<stdio.h>
#include<stdbool.h>
#include<stdlib.h>
typedef struct
{
    int key;

}element;
int rear=-1;
int front=-1;

element queue[n];
void queuefull(bool* fulltest)//This function is used to set the flag that the queue is full
{
    *fulltest=false;
}
void queueempty(bool* emptytest)//This function is used to set the flag that the queue is empty
{
    *emptytest=false;
}
void addq(int item,bool *fulltest,bool *emptytest)//This function is used to add elements to the Queue
{
    *emptytest=true;
    rear=(rear+1)%(n);
    if(rear==front)
     queuefull(fulltest);
    else
    {
          queue[rear].key=item;
          if(rear==n-1&&front==-1)//if this line is not present than when no deletions are performed that is when front =-1, the loop runs again and again and overwrites the queue forth and back
            queuefull(fulltest);
          if((rear+1)%(n)==front)
            queuefull(fulltest);
    }
}
int deleteq(bool *emptytest,bool *fulltest)//This function is used to delete the queue elements
{
    *fulltest=true;

    if(front==rear)
     queueempty(emptytest);
    else
 {
     front=(front+1)%(n);
     if(front==rear)
     queueempty(emptytest);

     return queue[front].key;

 }

}

void testfunction()//*This function is used to just print the values of front and rear
{
    printf("**testing the vales front=%d,value=%d\trear=%d,value=%d*********",front,queue[front].key,rear,queue[rear].key);
        printf("\n");

}
void showqueue(bool *emptytest,bool *fulltest)//This function is used to print the queue
{
    int i;

    if(!*emptytest)
    {
        printf("\n*****Queue is empty******\n");
        return ;
    }
    if((front==-1)||(front==-1&&!*fulltest))
    {
        if(front==-1&&!fulltest)
         printf("\nQueue is full");
        printf("\n\tHmmmm...You havent deleted any element yet and total no of elements=%d",rear+1);
        printf("\nThe elements are : ");
        for(i=0;i<=rear;i++)
        {
            printf("queue[%d]=%d",i,queue[i].key);
            printf(" ");
        }
         printf("\n");
         return ;
    }
    if(!*fulltest)
    {
        printf("\nqueue is full and it contains (n-1) elements: ");
        if(rear>front)
        {
            for(i=front+1;i<=rear;i++)
            {
                printf("queue[%d]=%d \t",i,queue[i].key);
            }
            printf("\n");
        }

        if(rear<front)
        {
            printf("\nstack is full and it contains (n-1) elements: ");
            for(i=front+1;i<n;i++)
             printf("queue[%d]=%d\t",i,queue[i].key);
            for(i=0;i<front;i++)
             printf("queue[%d]=%d\t",i,queue[i].key);
            printf("\n");
        }
        return ;
    }
        if(1)
        {
            if(rear>front)
            {
                printf("\nThe total no.of.elements in the queue is: %d\n",rear-front);
                printf("\nHmmmm...There is still some space left in queue..its elements are : ");
                for(i=front+1;i<=rear;i++)
                {
                    printf("queue[%d]=%d",i,queue[i].key);
                    printf(" ");
                }
                printf("\n");
            }
            if(rear<front)
            {
                printf("\nThe total no.of.elements in the queue is : %d\n ",((n-1)-front)+(front-rear));
                for(i=front+1;i<n;i++)
                   printf("queue[%d]=%d\t",i,queue[i].key);
                for(i=0;i<front;i++)
                   printf("queue[%d]=%d\t",i,queue[i].key);
            }
            printf("\n");
       }

    }

int main()
{

    int choice,item;
    bool fulltest=true;//the values true =1 and false =0 are defined in stdbool.h
    bool emptytest=false;

    for(;;)
    {
        testfunction();
        if(fulltest&&emptytest)
        {
            printf("\n*****************Enter the operation you want to perform on the QUEUE************\n");
            printf("1.ADD\n2.DELETE\n3.SHOW \n4.EXIT\n:  ");

             scanf("%d",&choice);
             switch(choice)
             {
                  case 1: printf("\nEnter the item to be added to the queue: ");
                        scanf("%d",&item);
                        addq(item,&fulltest,&emptytest);
                        break;
                  case 2:deleteq(&emptytest,&fulltest);
                        break;
                  case 3:showqueue(&emptytest,&fulltest);
                        break;
                  default:exit(0);

             }
        }

        if(!fulltest)
        {
             testfunction();
             printf("\n***QUEUE is full , you can perform only these following operations****");
             printf("\n1.DELETE \n2.SHOW\n 3.EXIT\n: ");
             scanf("%d",&choice);
             switch(choice)
             {
                 case 1:deleteq(&emptytest,&fulltest);
                  break;
                 case 2:showqueue(&emptytest,&fulltest);
                  break;
                 default:exit(0);

             }
        }
        if(!emptytest)
        {
            testfunction();
            printf("\n******Queue is empty, only following operations are possible*********\n ");
            printf("1.ADD\n2.SHOW\n3.EXIT\n:");
            scanf("%d",&choice);
            switch(choice)
            {
                case 1: printf("\nEnter the item to be added to the queue: ");
                        scanf("%d",&item);
                        addq(item,&fulltest,&emptytest);
                        break;
                case 2:showqueue(&emptytest,&fulltest);
                        break;
                default :
                        exit(0) ;

            }
        }
    }
}

Macros for true=1 and false=0

#include<stdio.h>

int main()
{

printf(“%d %d “,true , false );

}
This piece of code gives an error as “true” and “false” ,which we are trying to print are undeclared.

 

#include<stdio.h>
#include<stdbool.h>
int main()
{

printf(“%d %d “,true , false );

}

but by adding the header <stdbool.h> and running the code gives you can output of 1 0 , as the macros for true=1 and false =0 is defined in <stdbool.h>.

 

Executing a shell script

(NOTE:Make sure the path where you have saved the file and your current working directory in the terminal are same )Let XYZ be the name of the shell script you have created .By executing the command , “/bin/sh XYZ” in the terminal the script can be executed .The script can be invoked like any other executable , to do it first the script has to be given a executable permission .Use “chmod +x XYZ” , to give executable permission . Then use “./XYZ”  on the terminal to invoke the script.If you want to invoke the script just by calling its name , just use this command “PATH=$PATH:” to set the shell environment variable to look into the current path too.Now just execute the script from the terminal by using its name , “XYZ”, and script works !!Specifying the path prepended with ./ does have one other advantage: It ensures that you don’t accidentally execute another command on the system with the same name as your script file.

Metaploit penetration tool

Metasploit is must need tool for any hacker …This tool can be used to check whether a vulnerability exists on your computer or network …. a Exploit for a vulnerability is a not a easy task ..This requires skills like Assembly language , reverse engineering , socket programming , Shell coding(writing shell codes) and much much more .But metasploit has made it very easy by providing you with the Database of exploits which can be directly tested to hack a computer either on LAN or on internet ….For more information on using metasploit please refer to “Gray hat hacking 3 rd edition”

Simple C++ Code clearly illustrating flow of control when Object is passed to a function and constructors and distructors are used …

//Tested in GCC and Code BLocks COmpilers
#include <iostream>
using namespace std;
 class r
{
    int i;
    public :
     r(int n);
     ~r();
     void seti(int n)
     {
         i=n;
     }
     int geti()
     {
         return i;
     }

};
r::r(int n)
{
    i=n;
    cout <<"\nconstructor in action : "<<i <<"\n";
}
r::~r()
{
    cout << " \ndestructor in action: " << i << " \n ";
}
int pass(r s );//This is the function to which object of a function can be passed as parameter
void another();
void first();
void second();
int main()
{
    cout <<"\nStarting point main";
    r k(3);
    cout<<"\n"<<pass(k)<<"\t";
    another();
    cout <<"\n end of  main : " <<k.geti() << "\n " ;
    return 0;
}
int pass(r s )//This is the function to which object of a function can be passed as parameter

{
    cout <<"\nStarting point of pass function ";
    s.seti(222);
    cout << " \n this end of pass function i: "<<s.geti();
    return s.geti();

}
void another ()
{
    cout <<"\nConstructor call from another";
    r ls(77);
    cout <<"\nCalling pass from another";
    pass(ls);
    void second();
    cout<<"\nBack in another ";
}
void second()
{
    cout <<"\nInside second";
    void first();
    cout <<"back in second ";
}
void first()
{
    cout <<"\nConstructor call from first";
    r fir(30);
    cout<<"\nPass call from first";
    pass(fir);
    cout<<"\nBack in first";
}