#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>
#include <signal.h>
struct sigaction action;
void hand_sigusr1(int sig){
printf("(de %d) Signal
SIGUSR1 recu\n", getpid());
exit(0);
}
int main() {
pid_t pid;
int i = 0;
int status;
action.sa_handler=hand_sigusr1;
sigaction(SIGUSR1,&action,NULL);
if((pid=fork())==0){
printf("Je suis le fils de PID %d\n",
getpid());
/* processus fils bouclant */
while(1) { i = 0; };
}
printf("Je suis le pere de PID %d\n", getpid());
if(kill(pid,0)==-1){
printf("(de %d) Fils %d inexistant\n",
getpid(), pid);
}
else{
printf("(de %d) Envoi du signal SIGUSR1
au processus %d\n", getpid (), pid);
kill(pid,SIGUSR1);
}
pid=waitpid(pid,&status,0);
printf("(de %d) Status du fils %d :
%d\n",getpid(),pid,status);
}
n en argument sur la ligne de
commande et compte à rebours à partir de n
: le programme doit afficher les valeurs n,
n-1, n-2,
... à raison d'une valeur toutes les secondes et il termine si le
compteur atteint 0. Si
l'utilisateur tape Ctrl+C
(signal SIGINT
) avant que le compteur arrive à 0,
alors le compte rebours reprend à partir de n.$ ./compte-a-rebours 5
5 4 3 2
(l'utilisateur tape Ctrl+C)
5 4 3 2 1 0
Alerte : vous dormez !
$
alarm()
pour
déclencher le
chronomètre.
$ ./jeu-de-des
(appui sur Ctrl+C)
2 3
(appui sur Ctrl+C)
5 1
appui sur Ctrl+C)
6 6
(appui 2 fois rapidement sur
Ctrl+C)
$
void syracuse(void)
qui
étant donnée une valeur initiale calcule les termes de la suite de
Syracuse jusqu’à ce qu’elle vaille 1. Comme la valeur d'un terme de la
suite peut être très grande, utiliser le type long long
plutôt que le type int
. SIGTSTP
(Ctrl+Z), le programme affiche la valeur initiale courante,
l’indice du dernier terme calculé et la valeur prise par la suite, sans
stopper le programme.SIGINT
)
termine le programme en affichant : la plus grande valeur initiale
testée ; l’altitude maximale atteinte et la valeur initiale pour
laquelle cette altitude maximale est atteinte ; le temps de vol maximal
et la valeur initiale pour laquelle ce temps de vol a été atteint.SIGUSR1
, il écrit un nombre
tiré au hasard dans le tube et renvoie le signal SIGUSR2
au fils qui a émis le signal SIGUSR1
(Pour savoir quel est
le fils qui a émis le signal, utiliser le drapeau SA_SIGINFO
de la primitive sigaction()
)
. Chaque fils
émet le signal SIGUSR1
au père toutes les 2 secondes et
lorsqu'il reçoit le signal SIGUSR2
, il lit le nombre dans
le tube et exécute un calcul long sur ce nombre (on pourra simplement
endormir le processus pendant 5 secondes). Exercice
6.
Analysez le comportement du programme C suivant :
#include <stdio.h>
#include <signal.h>
sigset_t ens1, ens2, ens3;
int sig ;
main ()
{
sigemptyset(&ens1);
sigaddset(&ens1, SIGINT);
sigaddset(&ens1, SIGUSR1);
sigprocmask(SIG_SETMASK, &ens1, NULL);
sleep(15);
sigpending(&ens2);
printf("Signaux pendants :");
for (sig=1; sig<NSIG; sig++)
if (sigismember(&ens2, sig))
printf("%d ", sig);
putchar('\n');
sleep(15);
sigemptyset(&ens1);
printf("Deblocage des signaux \n");
sigprocmask(SIG_SETMASK, &ens1, NULL);
printf("Fin du processus \n");
}
Exercice
7.
Idem avec le programme C suivant :
#include <stdio.h>
#include <signal.h>
sigset_t ens;
struct sigaction action ;
void hand(int sig) {
char c ; int i ;
printf(“signal recu : %d\n”, sig);
sigprocmask(SIG_BLOCK, NULL, &ens);
printf(“Signaux bloques :”);
for (i=1; i<NSIG; i++)
if (sigismember(&ens, i))
printf("%d ", i);
putchar('\n');
if (sig = = SIGINT)
{
action.sa.handler = SIG_DFL;
sigaction(SIGINT, &action,
NULL);
}
printf(« Sortie du handler \n ») ;
}
main()
{
action.sa_handler = hand ;
sigemptyset(&action.sa_mask) ;
sigaction(SIGQUIT, &action, NULL);
sigaddset(&action.sa_mask, SIGQUIT) ;
sigaction(SIGINT, &action, NULL);
while(1) sleep(1) ;
}