I am studying C and I have been trying to make a simple test program. The problem is that I have a problem that is solved by a way that I dont understand. This is My program:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <signal.h>
void trat1(int s){
signal(SIGALRM, trat1);
}
void trat2(int s){
signal(SIGALRM, trat2);
}
int main( void ) {
int statusHijo1, statusHijo2;
int hijo1, hijo2;
int hijoFinalizado, status;
statusHijo1 =0;
statusHijo2 = 0;
if((hijo1 = fork()) == 0){
/* Hijo 1 */
printf("-- Hijo1 PID:%d | Parent PID:%d", getpid(), getppid());
printf("\n -- Hijo1 Lanzando SIGTERM -- \n");
while(1){
signal(SIGALRM, trat2);
alarm(1);
pause();
printf(" -- Hijo1 awaitting 1 sec.. \n");
}
}
else{
if ( (hijo2=fork()) == 0 ) {
/* Hijo 2 */
printf("++ Hijo2 PID:%d | Parent PID:%d \n", getpid(), getppid());
signal(SIGALRM, trat2);
alarm(5);
pause();
kill(hijo1, SIGKILL);
printf("++ Hijo2 Sending Kill signal to Hijo1\n");
printf("++ Proceso Hijo2 terminado\n");
}
else{
/* Padre */
do{
hijoFinalizado = wait(&status); //El hijo finalizado es el que cambia el estado del programa
if(hijoFinalizado == hijo1) statusHijo1 = 1;
else if(hijoFinalizado == hijo2) statusHijo2 = 1;
}while(!statusHijo1 || !statusHijo2);
printf("\n** Soy el padre con PID: %d y he terminado \n", getpid());
}
}
}
This program is very simple, The father is waitting for his two childs, 1 will be waitting for 5 seconds until the second one kills it.
Here the output from console:
-- Hijo1 PID:29793 | Parent PID:29792
-- Hijo1 Lanzando SIGTERM --
++ Hijo2 PID:29794 | Parent PID:29792
-- Hijo1 awaitting 1 sec..
-- Hijo1 awaitting 1 sec..
-- Hijo1 awaitting 1 sec..
-- Hijo1 awaitting 1 sec..
++ Hijo2 Sending Kill signal to Hijo1
++ Proceso Hijo2 terminado
** Soy el padre con PID: 29792 y he terminado
The problem is that I dont know how hijoFinalizado = wait(&status);
works, becouse without it the program doesnt funct.
This is what occurs without it:
-- Hijo1 PID:1547 | Parent PID:1546
-- Hijo1 Lanzando SIGTERM --
++ Hijo2 PID:1548 | Parent PID:1546
-- Hijo1 awaitting 1 sec..
-- Hijo1 awaitting 1 sec..
-- Hijo1 awaitting 1 sec..
-- Hijo1 awaitting 1 sec..
++ Hijo2 Sending Kill signal to Hijo1
++ Proceso Hijo2 terminado
And gets stuck here.
¿Why a variable that I dont declare is the one who decides if a process has finished?
¿Why doing while( (wait(&statusHijo1)!=hijo1)&& (wait(&statusHijo2)!=hijo2) ) ;
instead isnnt correct?
This is what occurs doing this:
-- Hijo1 PID:1148 | Parent PID:1147
++ Hijo2 PID:1149 | Parent PID:1147
-- Hijo1 Lanzando SIGTERM --
-- Hijo1 awaitting 1 sec..
-- Hijo1 awaitting 1 sec..
-- Hijo1 awaitting 1 sec..
-- Hijo1 awaitting 1 sec..
++ Hijo2 Sending Kill signal to Hijo1
++ Proceso Hijo2 terminado
And gets stuck here.
[Addition]
¿What is the real function of trat1 and trat2? I know that they are important but I dont know why.
Sorry for my English, and thanks very much.
Why a variable that I dont declare is the one who decides if a process has finished?
You mean status
? You do declare it; you simply don't initialize it. And that's fine, because wait
doesn't read it; wait
populates it. In other words, it's not an input; it's an output.
wait
waits for a child to finish. It returns the PID of the process, and it sets status
to the child's exit status.
You can use the status as follows:
if (WIFSTOPPED(status)) {
printf("Child killed by signal %d\.n", WSTOPSIG(status));
}
else if (WEXITSTATUS(status)) {
printf("Child exited with error %d.\n", WEXITSTATUS(status));
}
else {
printf("Child completed successfully.\n", WEXITSTATUS(status));
}