# TD2 : Unix
###### tags: `unix` `2022`
## Exercice 2.2
### 1.
```c
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
int main(int argc, char *argv[]) {
int n = 3;
int i = 0;
pid_t pid;
fprintf(stdout, "Avant le fork\n");
// création des 3 fils
while(i < n) {
fprintf(stdout, "i=%d\n", i);
if((pid = fork()) == 0) {
fprintf(stdout, "Je suis un processus fils... : %d\n", getpid());
break;
} else {
waitpid(pid, 0, 0);
i++;
}
}
return 0;
}
```

### 2. Écrire un programme C qui crée un nombre aléatoire de processus, chaque processus fils devra attendre un temps aléatoire compris entre 1 et 100 secondes (fonction sleep(int nb_sec)) avant de se terminer.
```c
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <time.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
srand(time(NULL));
int n = (rand() % 20) + 1;
int i = 0;
pid_t pid;
// création des n processus
while(i < n) {
if((pid = fork()) == 0) {
break;
} else {
i++;
}
}
if(pid == 0) {
srand(time(NULL) ^ (getpid()<<16));
int slp_tm = (rand() % 100) + 1;
// sleep avec un temps aléatoire
sleep(slp_tm);
printf("fils : je suis mort après %d secondes.\n", slp_tm);
} else {
printf("père : je suis mort.\n");
}
return 0;
}
```

### 3. Faire évoluer le programme de façon à ce qu’à chaque mort, le processus père devra afficher le PID du défunt fils, jusqu’à ce que tous ses fils soient morts.
```c
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <time.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
int n = (rand() % 20) + 1;
int i = 0;
pid_t pid;
while(i < n) {
if((pid = fork()) == 0) {
break;
} else {
i++;
}
}
if(pid == 0) {
srand(time(NULL) ^ (getpid()<<16));
int slp_tm = (rand() % 100) + 1;
sleep(slp_tm);
} else {
while(1) {
pid = waitpid(-1, 0, WNOHANG | WCONTINUED);
if(pid == -1) break; // erreur (pas de fils à attendre)
if(pid != 0) {
// fils est mort
printf("père : Le fils au pid = %d est mort.\n", pid);
} else { } // rien ne s'est passé
}
printf("père : je suis mort.\n");
}
return 0;
}
```
### 4. Reprendre le programme précédant en modifiant la phase d’attente de la mort des fils : le père devra afficher un point ou une étoile toutes les secondes :
— un point si aucun fils n’est mort depuis le précédent affichage,
— ou une étoile si au moins un fils est mort depuis le précédent affichage
```c
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <time.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
int n = (rand() % 100) + 1;
int i = 0;
pid_t pid;
while(i < n) {
if((pid = fork()) == 0) {
break;
} else {
i++;
}
}
if(pid == 0) {
srand(time(NULL) ^ (getpid()<<16));
int slp_tm = (rand() % 100) + 1;
sleep(slp_tm);
} else {
while(1) {
pid = waitpid(-1, 0, WNOHANG | WCONTINUED);
if(pid == -1) break; // erreur (pas de fils à attendre)
if(pid != 0) {
// fils est mort
printf(".\n");
} else {
// rien ne s'est passé
printf("*\n");
}
sleep(1);
}
printf("père : je suis mort.\n");
}
return 0;
}
```

## Exercice 2.3
```c
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <time.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
pid_t pid_fils;
int fd_tube[2];
pipe(fd_tube);
pid_fils = fork();
if(pid_fils == 0) {
close(fd_tube[0]);
printf("Fils: Je dors 5 secondes avant d'envoyer un message à papa...\n");
sleep(5);
char msg[64] = "Salut papa ça va ?";
write(fd_tube[1], msg, 64);
printf("Fils: C'est fait papa.\n");
} else {
close(fd_tube[1]);
printf("Le père va lire un message dans le tube...\n");
char *msg;
read(fd_tube[0], msg, 64);
printf("Le message est %s\n", msg);
}
return 0;
}
```