Search code examples
cparentpidkillchild-process

Control processes from terminal in C


I have a function bomb() that should kill a child process.

void bomb(id){
    kill(id, SIGKILL);
    printf("%d is ruined!", id);
}

It should be invoked by the users input in Terminal like "bomb 2355" (where 2355 is pid of the child process). HOW TO DO THAT?

I'm also stuck with another thing. How do I add all the child process PIDs to an array launched[10]? So, that it could be accessed if command == "status"?

I am new to C.. Searched the Internet all over :( The full code if below. Would appreciate any help! Thank you!

char planes();
void plane_function();
void refuel();
void bomb(int id);
void handle_signal(int signo);   

char command[12];
int launched[10];

int main ()
{   
    planes();
    return 0;
}

char planes(){

    printf("Enter a command: ");
    scanf("%s", command);

    pid_t main_process; //main process created

    //struct sigaction sa;  //handling signals
    //printf("My pid is: %d\n", getpid());

    if (strcmp(command, "launch") == 0){
        main_process = fork();
        if (main_process == 0){
            printf ("the main process ID is %d\n", getppid());  // main_process ID
            printf ("the new plane ID is %d\n", getpid());  // child ID
            //printf("launched: %d", launched[n]);
            launched[0] = getpid();
            plane_function(launched[0], main_process);
        } 
        else 
        {
            //printf("Parent");
        }
    } 

    else if (strcmp(command, ("bomb")) == 0){ // how to access a PID
            printf("Bomb N\n");
            bomb(plane_id);  
    }

    else if (strcmp(command, "refuel") == 0){
        printf("Refuel N\n");
    }

    else if (strcmp(command, "status") == 0){
        printf("STATUS: \n");
        printf("Planes launched: \n");

        printf("%d\n ", launched[0]);


    }

    else if (strcmp(command, "quit") == 0){
        printf("Quit\n");
    }

    else {
        printf("Error! Wrong command!\n");
    }
    planes();
    return 0;
}

void plane_function(id) {
    int fuel = 100;
    while (fuel >= 15){
        sleep(3);
        fuel = fuel - 15;
        printf("Bomber %d to base. Fuel left: %d\n", id, fuel);
        if(fuel == 10){
            printf("%d, you're done kid\n", id);
            kill(id, SIGKILL);
        }
    }
}

void bomb(id){
    kill(id, SIGKILL);
    printf("%d is ruined!", id);
}



void handle_signal(int signo){
    const char *signal_name;
    sigset_t pending;
    printf("SIGNAL!!!!");

    if (signo == SIGUSR1)
        printf("received SIGUSR1\n");
    else if (signo == SIGKILL)
        printf("received SIGKILL\n");
}

Solution

  • You need to catch and process the command line arguments like below.

        #include <stdio.h>
        #include <signal.h>
        #include <stdlib.h>
    
        /* This program demonstrates killing a process using a c program
         */
    
        int main(int argc,char* argv[]) // Here the char* catches command line arguments and argc is total number of arguments
        {
         int pid; // for extracting the process id from the command line argument
         char** end;
                if (argc<2)
                {
                        printf("Usage : bomb pid\n");
                                exit(1); // Exiting with 0 usually means a command ran successfully in Linux
                }
                else
                {
                        pid=(int)strtol(argv[1],end,10);
                        kill(pid,SIGTERM);
                        printf("Process %d terminated\n",pid);
                }
    
                return 0;
        }
    

    If you don't understand pointers - as you are new to C - you might need to do some homework on C Pointers before trying to decipher the above program.

    The idea is :

    1. capture the command line arguments
    2. do some processing to convert the process ID from string to number
    3. kill the process using kill command (remember pid must be a number)

    Usage:

    If you save the output as bomb,then run it like

    ./bomb pid

    Here char* argv[] automatically stores all the command line arguments and so you could enter multiple pids and then use a loop to kill all the processes. In effect, this serves a replacement for your launched array. If you make some changes, then it is perfectly possible to do something like

    ./bomb pid1 pid2

    References :

    1. PID type

    2. Kill Syntax

    3. strtol

    Note:

    I suggest reading Stephen Prata's C Primer Plus (latest edition is 6) which is an excellent investment for C starters.