Exercice

1.
Le premier programme constiste en un simple appel récursif à la fonction main(). Comme à chaque appel l'adresse de retour est empilée, la pile augmente à coup sûr. Donc un processus exécutant un tel code s'arrêtera soit après dépassement de la capacité autorisée pour sa pile, soit après épuisement de la mémoire disponible.
2.
Le deuxième programme consiste en une infinité d'appels à la fonction POSIX de clonage. Chaque clone exécutant le même code, les processus crées s'entêtent tous à se cloner aussi à l'infini. La table des processus devrait être très rapidement saturée.
3.
Le troisième programme se contente simplement de se recouvrir par lui-même.Il n'y a aucun nouveau processus créé. Si le recouvrement échoue (destruction de l'exécutable par exemple) le processus meurt simplement. La seule ressource consommée est le temps CPU.

Exercice

1.
Le seul programme capable d'afficher le résultat indiqué est p1 car c'est le seul capable d'afficher le message en réponse à l'action du signal SIGUSR1. Lorsque p2 recouvre le code du fils créé l'action associée au signal est perdue.
2.
Le processus fils se termine soit à la délivrance du signal SIGUSR1, soit par appel à exit(EXIT_FAILURE); en cas d'échec du recouvrement.
3.
Considérons pour cette question que le recouvrement du fils est toujours réussi.
4.
Si le recouvrement échoue le message Fils rate sera affiché dans tous les cas.

Si le signal SIGUSR1 est délivré au fils avant l'appel à exit(EXIT_FAILURE) le message J'ai bien recu le signal 16 est affiché par le fils.

Le message Le fils a pour code de retour 1 est affiché par le père.

Exercice

Voici le code des fonctions popen() et pclose() ici renommées mypopen() et mypclose() :
Voici un programme d'exemple utilisant ces deux fonctions :

Probleme

Le code fournit en réponse utilise les IPC POSIX disponibles uniquement avec l'extension temps-réél de POSIX.
1.
Pour deux écritures ou deux lectures le problème est évident : il faut que les deux requêtes soient sérialisés. Quant à la concurrence entre une lecture et une écriture tout dépend de l'implantation algorithmique des deux opérations. Par exemple, si l'écriture modifie le pointeur de fin avant d'avoir réellement écrit les données alors une lecture concurrente pourrait lire des données invalides. La solution la plus simple est encore d'éviter la concurrence entre les deux opérations.

Pour résoudre le problème, le plus simple est d'utiliser un sémaphore afin de bloquer l'accès à la ressource.

2.
Voici le fichier d'inclusion définissant le type :
3, 4 et 5.
Voici le fichier source contenant le code des diverses fonctions :
et un exemple d'utilisation du tube :
6.
La difficulté de réaliser des opérations bloquantes (au sens du blocage lors d'une tentative de lecture sur tube vide ou écriture sur tube trop plein) tiens à ce que les processus tentant une opération doivent être mis en attente. Par exemple un processus tentant une lecture sur tube vide doit être mis en attente soit de la fermeture du tube, soit de l'écriture dans le tube. Il faudrait donc qu'un tel processus soit bloqué (par un mécanisme à définir mais pouvant être un sémaphore). Mais son blocage ne doit pas conduire à un interblocage sur la section critique.
7.
Il faut rendre visible le tube (dans le cas où l'on utilise les IPC SYSV ne pas utiliser IPC_PRIVATE mais créer une référence puis ftok()). Dans notre exemple, il ne faut plus utiliser O_EXCL et reporter l'appel à shm_unlink() jusqu'à la fermeture.