Laboratoire 10 - Signaux et tubes
Remarque: n’oubliez pas, lors de l’utilisation d’appels système, de traiter les cas d’erreur.
Modification du gestionnaire d’un signal
- On veut gérer le signal d’interruption de processus (signal
SIGINT). Attention, il faut que l’arrêt du processus reste possible, par un autre moyen. Pour ce faire, créez un programmep0permettant d’essayer les diverses possibilités de gestion d’un signal et constatez qu’il est possible de:
- gérer directement le signal, en affichant le texte
Réception du signal SIGINTdans le gestionnaire montrant que le signal a bien été capturé et que l’on maîtrise la situation, - ignorer l’occurrence du signal,
- traiter une fois le signal, puis de revenir au traitement du signal par défaut par défaut,
- traiter deux fois le signal, puis de revenir au traitement du signal par défaut par défaut.
-
Comment peut-on vérifier qu’un signal n’est pas réceptionné autant de fois qu’il est envoyé ?
-
Reprenez le programme
p0et modifiez-le afin de capturer le signalSIGUSR1. Lorsque ce signal est capturé, effectuez une boucle de 5 itérations; à chaque itération affichez le messageItération <numéro d'itération> pour la gestion du signal <numéro du signal>. -
Que se passe-t-il si le programme
p0reçoit le signalSIGINTdurant le traitement d’un signalSIGUSR1? Pourquoi ? -
Modifiez le programme
p0de sorte que l’exécution de la gérante du signalSIGUSR1ne puisse être interrompue lors de la réception du signalSIGINT. -
Noter, les fonctions et appels systèmes suivant vous seront utiles:
sigaction,sigemptyset,sigaddset
Tubes shell
- Créez un programme
shellpipequi prend comme argument deux commandes séparées par le symbole seul+et qui exécute ces deux commandes en dirigeant la sortie de la première vers l’entrée de la seconde.
$ ./shellpipe ls / + wc -l
shellpipedoit attendre que les deux commandes terminent. Le programme retourne le code de retour de la dernière commande.
Extra: Redirection de processus
Cet exercice implémente la substitution de processus (<()) du shell bash.
Implémentez shellfifo.c, qui prend deux commandes séparées par "<|" et où l’argument "{}" de la première commande est substitué par le chemin d’un fichier tube nommé fifo dont le bout en écriture est connecté à la sortie standard de la seconde commande.
$ echo "Hello" > hello
$ echo "Goodbye" > bye
$ ./shellfifo wc hello "{}" bye "<|" echo Bonjour le monde
1 1 6 hello
1 3 17 fifo
1 1 8 bye
3 5 31 total
C’est +/- équivalent en shell bash à <() sauf que "{}" et "<|" sont beaucoup plus faciles à traiter que la syntaxe bash.
$ wc hello <(echo "Bonjour le monde") bye
1 1 6 hello
1 3 17 /dev/fd/63
1 1 8 bye
3 5 31 total
Attention:
- L’entrée standard des deux commandes reste inchangée (on laisse 0 tranquille!)
shellfifodoit attendre que les deux commandes terminent et retournent le code de retour de la premièreshellfifone laisse pas trainer des fichiers fifo non plus- Normalement, il faudrait créer le fichier fifo dans
/tmp/avec un nom unique, voir par exemplemkdtemp(3). Pour l’exercice, appelez juste votre fichierfifodans le répertoire courant. - Les fonctions et appels systèmes
mkfifoetdup2vous seront utiles.
Bonus: Redirection Version 2
Ajouter une option -p qui, au lieu d’un tube nommé, utilise à la place un tube anonyme et un chemin de pseudo tube /proc/self/fd/XX. C’est en fait l’implémentation du shell bash sous Linux quand /proc est disponible.
Par exemple:
$ ./shellfifo -p wc hello "{}" bye "<|" echo Bonjour le monde
1 1 6 hello
1 3 17 /proc/self/fd/3
1 1 8 bye
3 5 31 total