1

I built a tree of ten processes using fork() in . And my task is that I have to choose a random child process who will kill his brothers. So my idea was that the parent will send to the killer the PIDs of his brothers through a and , and then use the function kill(). But I don't know why the function doesn't work correctly. Do the killer process need any type of permissions to kill other process or what am I doing wrong?

My code: (./pregunta1 10)

#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <time.h>
#include <signal.h>

int main(int nargv,char *argv[]){
    int n,i,numRand,status,stdout_copy;
    pid_t child,padre,*child_pids,selecto, auxPid;
    char cadena[100];
    int fd[2];

    n = atoi(argv[1]);
    child_pids = (pid_t*)malloc(n*sizeof(pid_t));
    pipe(fd);

    srand(time(NULL));
    numRand = rand()%n;

    padre = getpid();

    for (i = 0; i < n; ++i){
        child = fork();
        child_pids[i] = child;

        if((i == numRand)&&(child==0)){ //killer process
            selecto = getpid();
            printf("The killer process will be (PID):  %d\n\n",selecto);
            dup2(fd[0],STDIN_FILENO);
            close(fd[0]);
            close(fd[1]);
            sleep(1);
            //Kill his brothers
            for(i=0;i<(n-1);i++){
                read(STDIN_FILENO, &auxPid, sizeof(auxPid));
                kill(auxPid, SIGKILL);
                printf("The process %d killed: %d\n",getpid(),auxPid);

            }
            break;
            sleep(3);
        }


        if(child==0){  //childs
            close(fd[0]);
            close(fd[1]);
            sleep(10);
            break;  
        }
    }

    if(getpid() == padre){   //parent process
        //using pstree first time
        sprintf(cadena,"pstree -p %d\n",getpid());
        system(cadena);
        //making a conexion with the parent process and the killer
        stdout_copy = dup(1);
        dup2(fd[1],STDOUT_FILENO);
        close(fd[0]);
        close(fd[1]);
        //Sending PIDs to the killer process
        for(i = 0;i<n;i++){
            if(i != numRand){
                auxPid = child_pids[i];
                write(STDOUT_FILENO,&auxPid,sizeof(auxPid));
            }
        }

        sleep(2);
        //using pstree first time
        dup2(stdout_copy, 1);
        system(cadena);
        wait(&status); 

    }
    return 0;
}

My output (wrong):

The killer process will be (PID):  5162

pregunta1(5154)─┬─pregunta1(5155)
                ├─pregunta1(5156)
                ├─pregunta1(5157)
                ├─pregunta1(5158)
                ├─pregunta1(5159)
                ├─pregunta1(5160)
                ├─pregunta1(5161)
                ├─pregunta1(5162)
                ├─pregunta1(5163)
                ├─pregunta1(5164)
                └─sh(5165)───pstree(5166)
The process 5162 killed: 5155
The process 5162 killed: 5156
The process 5162 killed: 5157
The process 5162 killed: 5158
The process 5162 killed: 5159
The process 5162 killed: 5160
The process 5162 killed: 5161
The process 5162 killed: 5163
The process 5162 killed: 5164
pregunta1(5154)─┬─pregunta1(5155)
                ├─pregunta1(5156)
                ├─pregunta1(5157)
                ├─pregunta1(5158)
                ├─pregunta1(5159)
                ├─pregunta1(5160)
                ├─pregunta1(5161)
                ├─pregunta1(5162)
                ├─pregunta1(5163)
                ├─pregunta1(5164)
                └─sh(5167)───pstree(5168)

Expected output:

The killer process will be (PID):  5162

pregunta1(5154)─┬─pregunta1(5155)
                ├─pregunta1(5156)
                ├─pregunta1(5157)
                ├─pregunta1(5158)
                ├─pregunta1(5159)
                ├─pregunta1(5160)
                ├─pregunta1(5161)
                ├─pregunta1(5162)
                ├─pregunta1(5163)
                ├─pregunta1(5164)
                └─sh(5165)───pstree(5166)
The process 5162 killed: 5155
The process 5162 killed: 5156
The process 5162 killed: 5157
The process 5162 killed: 5158
The process 5162 killed: 5159
The process 5162 killed: 5160
The process 5162 killed: 5161
The process 5162 killed: 5163
The process 5162 killed: 5164
pregunta1(5154)─┬─pregunta1(5162)
                └─sh(5167)───pstree(5168)
negar14
  • 41
  • 4
  • `pregunta 10` sounds a lot like homework to me. – ndim Aug 28 '17 at 00:14
  • Note that you can more sensibly have the parent write direct to the pipe's write end file descriptor than going messing around with `dup()` etc to modify the setup so that the pipe is standard output, and then changing back again. Especially as you're using `write(STDOUT_FILENO, …)` to send the message to the child. – Jonathan Leffler Aug 28 '17 at 05:20

1 Answers1

2

It looks like your killed child processes are left in zombie state. You have to call wait() for them all (not just one). And do it before calling pstree. Take a look here: Make parent wait for all child processes

In your code instead of

system(cadena);
wait(&status);

you should have

for (int i = 0; i < n; i++)
    wait(&status);
system(cadena);
algrid
  • 5,600
  • 3
  • 34
  • 37
  • thanks for your answer, I put a `wait(&status)` function just after the function `write()` to wait for killed processes.Then I called pstree (to print a "photo" of the parent and the killer processes). The last `wait()` is for the killer process. I did it, but my output still being **wrong**. In the second pstree print the parent and the last child who was created. – negar14 Aug 28 '17 at 13:17
  • @negar14 I added the code you have to change to the answer. – algrid Aug 28 '17 at 21:18