Attention ! - Université Virtuelle de Tunis

Ministère de l’Enseignement Supérieur et de la Recherche Scientifique
Université Virtuelle de Tunis
Programmation Système et Réseau
Leçon2 : La gestion des signaux
Ezzedine Zagrouba
Attention !
Ce produit pédagogique numérisé est la propriété exclusive de l'UVT. Il est strictement interdit de
la reproduire à des fins commerciales. Seul le téléchargement ou impression pour un usage
personnel (1 copie par utilisateur) est permis.
)
!
*
!
Généralités
!
)
*
!/
!
*
!
,
-
,
.
.
"
"
,
/
0
1
.
#
2
#
Identification des signaux
,
NSIG .
kill -l
$ !
!
!
,
!,
/
%
%
2
#
&
3
*2 4(
#
&
3
*254(
#
#
%
#
#
!
#
Comportement d’un processus vis à vis des signaux :
/
!
!
Les primitives de gestion des signaux
"
##
$%
#
&
#include <signal.h>
int kill(int pid, int sigint)
+
)
!
*
%
.
pid
%
sigint
!
#
7
. #
"
sigint = 0
"
pid
' (
$%
#
%
#
&
!
!
-
/
#include <signal.h>
void (*signal(int sigint, void (* fonction)(int)))
sigint
fonction
) ) $%
#
!
signit
% "
&
#include <unistd.h>
int pause()
8
!
#*
) $)# #
%
#
!
!
9
#
+
signal (sigint, SIG_IGN)
sigint#
"
signal (sigint, SIG_DFL)
9
"
##
$%
#
&
& ##
,
(#
)- & )
#include <unistd.h>
unsigned int alarm(unsigned int nb_sec)
SIGALARM
.
Exemples
"+) (&) .
6
) $)#
)
(
# &/) 0
nb_sec
#
)
!
*
#include<stdio.h>
#include<signal.h>
void hand()
{
printf("Envoyer le signal SIGKILL pour me tuer\n");
}
main()
{
signal(SIGINT,hand);
signal(SIGQUIT,hand);
while(1)
pause();
}
"+) (&) .
#include
#include
#include
#include
#include
) )
$)# #
+
& (&)#
0
<stdlib.h>
<signal.h>
<errno.h>
<unistd.h>
<stdio.h>
void traitement(int signum)
{
printf("Signal %d => ", signum);
switch (signum) {
case SIGTSTP:
printf("Je m'endors....\n");
kill(getpid(), SIGSTOP);
printf("Je me réveille !\n");
signal(SIGTSTP, traitement);
break;
case SIGINT:
case SIGTERM:
printf("Fin du programme.\n");
:
/* auto-endormissement */
/* repositionnement */
!
)
!
*
exit(0);
break;
};
}
int main(void)
{
signal(SIGTSTP, traitement);
signal(SIGINT, traitement);
signal(SIGTERM, traitement);
while (1)
{
sleep(1);
printf(".");
fflush(stdout);
}
printf("fin\n");
exit(0);
}
"+) (&) .- & )0
#include<stdio.h>
#include<signal.h>
int hh,mn,sc;
void tick()
{
sc++;
if (sc == 60)
{
sc=0;
mn++;
if (mn ==60)
{
mn=0;
hh++;
if (hh == 24)
hh=0;
}
}
alarm(1);
;
/* si on reçoit CTRL-Z */
/* si CTRL-C */
/* si kill processus */
!
)
!
*
!
printf("%d:%d:%d\n",hh,mn,sc);
}
main()
{
hh=0; mn=0; sc=0;
printf("%d:%d:%d\n",hh,mn,sc);
signal(SIGALRM,tick);
alarm(1);
for(;;);
}
Les signaux : aspect système
=
.
> 9
"
() $
&
#$ "
!
"?
!
@
9
"
%'
#
%
(
9
%
.
#
.
.
9
%
#
#
#
!
$
/
9
!
"
!
.
"
1
"!
#
%
#
Manipulation des ensembles de signaux
*
)? $A
9
!#
* .
B
<
sigset_t
/
%
9
)
!
*
#include <signal.h>
1
) )
int sigemptyset(sigset_t *p_ens)
*p_ens={}
int sigfillset(sigset_t *p_ens)
*p_ens={1,…,NSIG}
int sigaddset(sigset_t *p_ens,int sig)
*p_ens=*p_ens ∪ {sig}
int sigdelset(sigset_t *p_ens,int sig)
*p_ens=*p_ens \ {sig}
int sigismember(sigset_t *p_ens,int sig)
sig est dans *p_ens
D'
E
sigismember
2&
) $)# #
E
'
#
sig
% *p_ens#
+
*
9
!
%
/
#include <signal.h>
int sigpromask( int op, const sigset_t *p_ens, sigset_t *p_ens_ancien)
9 *p_ens
%
*p_ens_ancien.
op
3 &)
9 /
$) op
/)
#* )
SIG_SETMASK
*p_ens
SIG_BLOCK
*p_ens ∪ *p_ens_ancien
SIG_UNBLOCK
*p_ens_ancien \ *p_ens
E
# ) $)# #
+ () $
# 4& *
#
#include <signal.h>
int sigpending(sigset_t *p_ens);
C
2'
#
!
)
!
*
8
−
( &
$)# -
#
)#
% p_ens
!
9
!
#
$&) #
struct sigaction {
void (*sa_handler)() ;
sigset_t sa_mask ; /* signaux à bloquer*/
int sa_flags ; /*options*/
}
sa_mask
*
sa_handler %
!
%
8% 9
!
1
8
!
#
sa_flags
•
SA_NOCLDSTOP
SIGCHLD
" 1
SIGSTOP SIGTSTP SIGTTIN
SIGTTOU(#
SA_RESETHAND
"
signal()
(#
"
sa_sigaction() %
&
-
−
•
SA_ONESHOT
•
SA_SIGINFO
sa_handler()#
(
&"
%
/) #
#include <signal.h>
int sigaction( int sig, const struct sigaction *p_action, struct sigaction
*p_action_ancien)
sigaction()
*
"
p_action
NULL
>sa_handler
*
! p_action-> ∪{sig}
F
!
sig#
"
p_actionsig#
!
#
)
!
*
Exemples
/* sig-posix.c */
#include <stdlib.h>
#include <signal.h>
#include <errno.h>
#include <unistd.h>
#include <stdio.h>
#define DELAI 1
#define NBTOURS 60
void traitement(int signum)
{
struct sigaction rien, ancien;
printf("Signal %d => ", signum);
switch (signum) {
case SIGTSTP:
printf("J'ai reçu un SIGTSTP.\n");
/* on désarme le signal SIGTSTP */
rien.sa_handler = SIG_DFL;
rien.sa_flags = 0;
sigemptyset(&rien.sa_mask); /* rien à masquer */
sigaction(SIGTSTP, &rien, &ancien);
printf("Alors je m'endors....\n");
kill(getpid(), SIGSTOP);
/* auto-endormissement */
printf("On me réveille ?\n");
/* remise en route */
sigaction(SIGTSTP, &ancien, NULL);
printf("C'est reparti !\n");
break;
case SIGINT:
case SIGTERM:
printf("On m'a demandé d'arrêter le programme.\n");
exit(0);
break;
};
}
int main(void)
{
struct sigaction a;
int i;
a.sa_handler = traitement;
sigemptyset(&a.sa_mask);
/* fonction à lancer */
/* rien à masquer */
sigaction(SIGTSTP, &a, NULL);
sigaction(SIGINT, &a, NULL);
sigaction(SIGTERM, &a, NULL);
for (i = 1; i < NBTOURS; i++) {
sleep(DELAI);
printf("%d", i % 10);
fflush(stdout);
}
printf("Fin\n");
exit(0);
}
G
/* pause contrôle-Z */
/* fin contrôle-C */
/* arrêt */
!
)
!
*
!
Exercices
"5" ' '" 6
!
"
-
#
"5" ' '" 6
H
H
'E
9
#*
#
"5" ' '" 6
- &
(#
> 9
;
6
! -
&
';
(
8
1
#
"5" ' '" 6
!
'E
)? $A#
!#