Reputation: 41
I built a tree of ten processes using fork() in c. 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 pipe and file-descriptor, 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)
Upvotes: 1
Views: 518
Reputation: 5964
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);
Upvotes: 2