/* devoir n°2 exercice 1 : pp.c */
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <signal.h>
pid_t le_pid_A, le_pid_B;
int compteur = 1;
void traite_le_SIGUSR1_A(){
}
void traite_le_SIGUSR1_B(){
printf("Message recu !\n");
}
void traite_le_A(){
int i;
signal( SIGUSR1, traite_le_SIGUSR1_A );
for( i = 0; i < 5; i++ ) printf("A\n");
kill( le_pid_B, SIGUSR1 );
pause();
traite_le_A();
}
void traite_le_B(){
signal( SIGUSR1, traite_le_SIGUSR1_B );
pause();
compteur++;
if( compteur > 5 ){
kill( le_pid_A, SIGKILL );
kill( le_pid_B, SIGKILL );
}
else kill( le_pid_A, SIGUSR1 );
traite_le_B();
}
main( ){
le_pid_A = getpid();
if( (le_pid_B = fork()) == -1 ){
printf("fork() non possible\n");
exit();
}
sleep(1);
if( le_pid_B == 0 ) traite_le_B();
else traite_le_A();
}
/* langage algorithmique
procedure traite_le_SIGUSR1_A()
debut
fin
procedure traite_le_SIGUSR1_B()
debut
affiche "Message recu !"
fin
procedure traite_le_A()
variable i : entier
debut
si reception du signal SIGUSR1 alors saute à traite_le_SIGUSR1_A()
pour i = 0 jusqu'a i strictement inferieur a 5 affiche "A"
emet au processus B le signal SIGUSR1
attend un message
traite_le_A()
fin
procedure traite_le_B()
debut
si reception du signal SIGUSR1 alors saute à traite_le_SIGUSR1_B()
attend un message
incremente la variable compteur
si la variable compteur est superieure a 5 alors
emet au processus A le signal SIGKILL
emet au processus B le signal SIGKILL
sinon emet au processus A le signal SIGUSR1
fin de si
traite_le_B()
fin
procedure principale main()
debut
le_pid_A = getpid()
si ( le_pid_B = fork() ) == -1
affiche "fork() non possible"
fin de si
attend la mise en place de la fourche
si le_pid_B == 0
traite_le_B()
sinon traite_le_A()
fin de si
fin
*/
/* exemple d'execution
[root@localhost /root]# egcs -o/bin/pp /usr/src/cours/devoir2/dev2ex1/pp.c
[root@localhost /root]# pp
A
A
A
A
A
Message recu !
A
A
A
A
A
Message recu !
A
A
A
A
A
Message recu !
A
A
A
A
A
Message recu !
A
A
A
A
A
Message recu !
Killed
[root@localhost /root]#
*/
/* devoir n°2 exercice 2 petit 1: envoie.c */
#include <stdio.h>
#include <signal.h>
#include <sys/types.h>
#include <fcntl.h>
char *nbr_tty[16] = {"0","1","2","3","4","5","6","7","8","9","10","11","12","13","14","15"};
void sortie(){
printf("10 secondes écoulees, sortie.\n");
exit();
}
main( ){
int i, fd_tty;
char dev_tty[11];
signal( SIGALRM, sortie );
alarm( 10 );
for( i=0; i <= 15; i++ ){
strcpy( dev_tty, "\0" );
strcat( dev_tty, "/dev/tty" );
strcat( dev_tty, nbr_tty[i] );
if( fd_tty = open( dev_tty, O_WRONLY ) ){
write( fd_tty, "coucou, le monde\n", 17 );
close( fd_tty );
}
}
}
/* langage algorithmique
procedure sortie()
debut
affiche "10 secondes ecoulees, sortie."
sortie
fin
procedure principale main()
variable i : type entier
variable fdd_tty : type entier
variable dev_tty[11] : type tableau 11 caracteres
debut
si reception du signal SIGALRM alors saute à sortie()
alarm()
pour i = 0 jusqu'a i strictement inferieur ou egal a 16
copie "\0" dans dev_tty
concatene "/dev/tty" dans dev_tty
concatene nbr_tty[i] dans dev_tty
si ouvre le fichier fd_tty du nom inscrit dans le tableau dev_tty en mode lecture seule
ecrit "coucou, le monde\n" dans le fichier fd_tty
ferme le fichier fd_tty
fin de si
fin de pour
fin
*/
/* exemple d'execution
[root@localhost /root]# egcs -o/bin/envoie /usr/src/cours/devoir2/dev2ex2/1/envoie.c
[root@localhost /root]# envoie
coucou, le monde
[root@localhost /root]#
(idem sur les 15 autres terminaux)
*/
/* devoir n°2 exercice 2 petit 2: pilote.c */
#include <stdio.h>
#include <signal.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#define SECONDES 63
void fourche(){
pid_t le_pid = fork();
if( le_pid == 0 ){
execlp( "envoie", NULL );
printf("erreur dans exec.\n");
kill( getppid(), SIGKILL );
kill( getpid(), SIGKILL );
}
else
if ( le_pid == -1 ){
printf("fork() non possible.\n");
exit();
}
}
main(){
signal( SIGALRM, fourche );
fourche();
for(;;){
alarm( SECONDES );
pause();
}
}
/* langage algorithmique
definition SECONDE 63
procedure fourche()
variable le_pid : pid_t
debut
le_pid = fork()
si le_pid == 0
execlp( "envoie", NULL )
affiche "erreur dans exec."
emet au processus getppid() le signal SIGKILL
emet au processus getpid() le signal SIGKILL
sinon si le_pid == -1
affiche "fork() non possible."
sortie
fin de si
fin
procedure main()
debut
si reception du signal SIGALRM alors saute à fourche
fourche()
pour jusqu'a l'infini
alarm( SECONDES )
attend un message
fin de pour
fin
*/
/* exemple d'execution
[root@localhost /root]# egcs -o/bin/pilote /usr/src/cours/devoir2/dev2ex2/2/pilote.c
[root@localhost /root]# pilote
coucou, le monde
coucou, le monde <-- 63 secondes
coucou, le monde <-- 63 secondes
'^c'
[root@localhost /root]#
(idem sur les 15 autres terminaux)
*/
/* devoir n°2 exercice 2 petit 3: pilote.c */
#include <stdio.h>
#include <signal.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#define SECONDES 63
char *cmd_line;
void fourche(){
pid_t le_pid = fork();
if( le_pid == 0 ){
execlp( cmd_line, cmd_line, NULL );
printf("erreur dans exec.\n");
kill( getppid(), SIGKILL );
kill( getpid(), SIGKILL );
}
else
if ( le_pid == -1 ){
printf( "fork() non possible\n" );
exit();
}
}
main( int argc, char *argv[] ){
if( argc < 2 ){ printf("Pas assez de parametres.\n"); exit(); }
if( argc > 2 ){ printf("Trop de parametres.\n"); exit(); }
cmd_line = (char *) malloc( strlen( argv[1] ));
strcpy( cmd_line, argv[1] );
signal( SIGALRM, fourche );
fourche();
for(;;){
alarm( SECONDES );
pause();
}
}
/* langage algorithmique
definition SECONDES 63
variable cmd_line : pointeur de caracteres
procedure fourche()
variable le_pid : pid_t
debut
le_pid = fork()
si le_pid == 0
execlp( cmd_line, cmd_line, NULL )
affiche "erreur dans exec."
emet au processus getppid() le signal SIGKILL
emet au processus getpid() le signal SIGKILL
sinon si le_pid == -1
affiche "fork() non possible."
sortie
fin de si
fin
procedure main( variable argc : entier, variable argv : pointeur tableau de cararcteres )
debut
si argc strictement inferieur a 2
affiche "Pas assez de parametres."
sortie
fin de si
si argc strictement superieur a 2
affiche "Trop de parametres."
sortie
fin de si
cmd_line = (char *) malloc( strlen( argv[1] ))
strcpy( cmd_line, argv[1] )
si reception du signal SIGALRM alors saute à fourche
fourche()
pour jusqu'a l'infini
alarm( SECONDES )
attend un message
fin de pour
fin
*/
/* exemple d'execution
[root@localhost /root]# egcs -o/bin/pilote /usr/src/cours/devoir2/dev2ex2/3/pilote.c
[root@localhost /root]# pilote ls
Desktop Sans titre autosave config.log nsmail
Makefile Xrootenv.0 config.cache config.status
Desktop Sans titre autosave config.log nsmail
Makefile Xrootenv.0 config.cache config.status <-- 63 secondes
Desktop Sans titre autosave config.log nsmail
Makefile Xrootenv.0 config.cache config.status <-- 63 secondes
'^c'
[root@localhost /root]#
*/
/* devoir n°2 exercice 2 projet: pp.c */
#include <stdio.h>
#include <sys/types.h>
#include <signal.h>
#include <unistd.h>
#include <string.h>
#define ENTREE 1
#define SORTIE 0
#define NL 10
int toggle = 0;
int le_tube[2];
FILE *la_sortie, *l_entree;
pid_t le_pid_A, le_pid_B, le_pid_C;
void traite_le_SUGUSR1_A(){
printf("Le pere A : signal recu : SIGUSR1 (fin de la tache precedente)\n");
toggle = !toggle;
}
void traite_le_SUGUSR2_A(){
if ( toggle == 0 ){
printf("Le pere A : signal recu de B : SIGUSR2\n");
toggle = !toggle;
printf("Le pere A : envoie au fils C : SIGUSR2\n");
kill( le_pid_C, SIGUSR2 );
}
if ( toggle == 1 ){
printf("Le pere A : signal recu de C : SIGUSR2\n");
printf("Le pere A : Fin du fils B.\n");
kill( le_pid_B, SIGKILL );
printf("Le pere A : Fin du fils C.\n");
kill( le_pid_C, SIGKILL );
printf("Le pere A : Fin de moi !\n");
kill( le_pid_A, SIGKILL );
}
pause();
}
void traite_le_SUGUSR1_B(){
/* ne marche pas sur mon systeme ?
le_buf = realloc( le_buf, ++i );
*/
int i = 0, le_car;
char le_buf[100];
printf("\tLe fils B : message a envoyer :");
while( (le_car = fgetc( stdin )) != NL && i <= 99 ){
if( le_car == EOF ){
close( le_tube[ENTREE] );
printf("\n\tLe fils B : envoie au pere A : SIGUSR2\n");
kill( le_pid_A, SIGUSR2 );
pause();
}
fputc( le_car, l_entree );
i++;
}
printf("\tLe fils B : ecriture et envoie du message\n");
fputc( NL, l_entree );
fflush( l_entree );
}
void traite_le_SUGUSR1_C(){
int le_car = 0, premier = 0;
printf("\t\tLe fils C : signal recu : SIGUSR1\n");
printf("\t\tLe fils C : message recu : ");
while( (le_car = fgetc( la_sortie )) != NL ){
if( le_car >= 97 && le_car <= 122 ) le_car = le_car - 32;
printf("%c", le_car);
premier ++;
}
if( premier == 0 ) printf("PAS DE MESSAGE");
printf("\n");
}
void traite_le_SUGUSR2_C(){
printf("\t\tLe fils C : signal recu : SIGUSR2\n");
close( le_tube[SORTIE] );
printf("\t\tLe fils C : envoie au pere A : SIGUSR2\n");
kill( le_pid_A, SIGUSR2 );
pause();
}
void traite_le_A(){
signal( SIGUSR1, traite_le_SUGUSR1_A );
signal( SIGUSR2, traite_le_SUGUSR2_A );
if ( toggle == 0 ){
printf("Le pere A : signal envoye : SIGUSR1 (autorisation tache B)\n");
kill( le_pid_B, SIGUSR1 );
}
else if ( toggle == 1 ){
printf("Le pere A : signal envoye : SIGUSR1 (autorisation tache C)\n");
kill( le_pid_C, SIGUSR1 );
}
pause();
traite_le_A();
}
void traite_le_B(){
signal( SIGUSR1, traite_le_SUGUSR1_B );
pause();
printf("\tLe fils B : envoie au pere A de SIGUSR1\n");
kill( le_pid_A, SIGUSR1 );
traite_le_B();
}
void traite_le_C(){
signal( SIGUSR1, traite_le_SUGUSR1_C );
signal( SIGUSR2, traite_le_SUGUSR2_C );
pause();
printf("\t\tLe fils C : envoie au pere A de SIGUSR1\n");
kill( le_pid_A, SIGUSR1 );
traite_le_C();
}
main(){
if( pipe( le_tube ) == -1 ){
printf( "Erreur dans pipe();\n" );
exit();
}
le_pid_A = getpid();
if( ( le_pid_B = fork() ) == -1 ){
printf( "Erreur dans fork();\n" );
exit();
}
else if( le_pid_B == 0 ){
printf("\tDebut du fils B\n");
close( le_tube[SORTIE] );
if(!( l_entree = fdopen( le_tube[ENTREE], "w" ))){
printf("Erreur dans fdopen();\n");
kill( le_pid_A, SIGKILL );
kill( le_pid_B, SIGKILL );
}
printf("\tFils B : debut de l'attente\n");
traite_le_B();
}
sleep(1);
if( ( le_pid_C = fork() ) == -1 ){
printf("Erreur dans fork();\n");
kill( le_pid_B, SIGKILL );
exit();
}
else if( le_pid_C == 0 ){
printf("\t\tDebut du fils C\n");
close( le_tube[ENTREE] );
if(!( la_sortie = fdopen( le_tube[SORTIE], "r" ))){
printf( "Erreur dans fdopen();\n" );
kill( le_pid_A, SIGKILL );
kill( le_pid_B, SIGKILL );
kill( le_pid_C, SIGKILL );
}
printf("\t\tFils C : debut de l'attente\n");
traite_le_C();
}
sleep(1);
printf("Le pere A : debut des echanges ...\n");
traite_le_A();
}
/* langage algorithmique
definition ENTREE 1
definition SORTIE 0
definition NL 10
variable globale toggle : entier
variable globale le_tube : tableau de 2 entier
variable globale la_sortie : pointeur de fichier
variable globale l_entree: pointeur de fichier
variable globale le_pid_A : pid_t
variable globale le_pid_B : pid_t
variable globale le_pid_C : pid_t
procedure traite_le_SUGUSR1_A()
debut
affiche "Le pere A : signal recu : SIGUSR1 (fin de la tache precedente)"
toggle = negation de toggle
fin
procedure traite_le_SUGUSR2_A()
debut
si toggle == 0
affiche "Le pere A : signal recu de B : SIGUSR2"
toggle = negation de toggle
affiche "Le pere A : envoie au fils C : SIGUSR2"
emet au processus C le signal SIGUSR2
fin de si
si toggle == 1
affiche "Le pere A : signal recu de C : SIGUSR2"
affiche "Le pere A : Fin du fils B."
emet au processus B le signal SIGKILL
affiche "Le pere A : Fin du fils C."
emet au processus C le signal SIGKILL
affiche "Le pere A : Fin de moi !"
emet au processus A le signal SIGKILL
fin de si
attend un message
fin
procedure traite_le_SUGUSR1_B()
variable i : entier
variable le_car : entier
variable le_buf : tableau de 100 caracteres
debut
affiche "Le fils B : message a envoyer :"
tant que le_car = fgetc( stdin ) est different de NL et i est strictement inferieur ou egal a 99
si le_car == EOF
ferme le_tube[ENTREE]
affiche "Le fils B : envoie au pere A : SIGUSR2"
emet au processus A le signal SIGUSR2
attend un message
fin de si
fputc( le_car, l_entree )
incremente i
fin de tant que
affiche "Le fils B : ecriture et envoie du message"
fputc( NL, l_entree )
fflush( l_entree )
fin
procedure traite_le_SUGUSR1_C()
variable le_car : entier
variable premier : entier
debut
affiche "Le fils C : signal recu : SIGUSR1"
affiche "Le fils C : message recu : "
tant que le_car = fgetc( la_sortie ) est different de NL
si le_car est strictement supperieur ou egal a 97 et le_car est strictement inferieur ou egal a 122
le_car = le_car - 32
fin de si
affiche le_car
incremente premier
fin de tant que
si premier == 0
affiche "PAS DE MESSAGE"
fin de si
affiche saut de ligne
fin
procedure traite_le_SUGUSR2_C()
debut
affiche "Le fils C : signal recu : SIGUSR2"
ferme le_tube[SORTIE]
affiche "Le fils C : envoie au pere A : SIGUSR2"
emet au processus A le signal SIGUSR2
attend un message
fin
procedure traite_le_A()
debut
si reception du signal SIGUSR1 alors saute à traite_le_SIGUSR1_A()
si reception du signal SIGUSR2 alors saute à traite_le_SIGUSR2_A()
si toggle == 0
affiche "Le pere A : signal envoye : SIGUSR1 (autorisation tache B)"
emet au processus B le signal SIGUSR1
sinon si toggle == 1
affiche "Le pere A : signal envoye : SIGUSR1 (autorisation tache C)"
emet au processus C le signal SIGUSR1
fin de si
attend un message
traite_le_A()
fin
procedure traite_le_B()
debut
si reception du signal SIGUSR1 alors saute à traite_le_SIGUSR1_B()
attend un message
affiche "Le fils B : envoie au pere A de SIGUSR1"
emet au processus A le signal SIGUSR1
traite_le_B()
fin
procedure traite_le_C()
debut
si reception du signal SIGUSR1 alors saute à traite_le_SIGUSR1_C()
si reception du signal SIGUSR2 alors saute à traite_le_SIGUSR2_C()
attend un message
affiche "Le fils C : envoie au pere A de SIGUSR1"
emet au processus A le signal SIGUSR1
traite_le_C()
fin
procedure main()
debut
si pipe( le_tube ) == -1
affiche "Erreur dans pipe()"
sortie
fin de si
le_pid_A = getpid()
si le_pid_B = fork() == -1
affiche "Erreur dans fork()"
sortie
sinon si le_pid_B == 0
affiche "Debut du fils B"
ferme le_tube[SORTIE] )
si echoue l_entree = ouvre le_tube[ENTREE] en mode ecriture
affiche "Erreur dans fdopen()"
emet au processus A le signal SIGKILL
emet au processus B le signal SIGKILL
fin de si echoue
affiche "Fils B : debut de l'attente"
traite_le_B()
fin de si
attendre la mise en place de la fourche
si le_pid_C = fork() == -1
affiche "Erreur dans fork()"
emet au processus B le signal SIGKILL
sortie
sinon si le_pid_C == 0
affiche "Debut du fils C"
ferme le_tube[ENTREE]
si echoue la_sortie = ouvre le_tube[SORTIE] en mode lecture
affiche "Erreur dans fdopen()"
emet au processus A le signal SIGKILL
emet au processus B le signal SIGKILL
emet au processus C le signal SIGKILL
fin de si echoue
affiche "Fils C : debut de l'attente"
traite_le_C()
fin de si
attendre la mise en place de la fourche
affiche "Le pere A : debut des echanges ..."
traite_le_A()
fin
*/
/* exemple d'execution
[root@localhost /root]# egcs -o/bin/pp /usr/src/cours/devoir2/dev2ex2/projet/pp.c
[root@localhost /root]# pp
Debut du fils B
Fils B : debut de l'attente
Debut du fils C
Fils C : debut de l'attente
Le pere A : debut des echanges ...
Le pere A : signal envoye : SIGUSR1 (autorisation tache B)
Le fils B : message a envoyer :exercice AA1254ww
Le fils B : ecriture et envoie du message
Le fils B : envoie au pere A de SIGUSR1
Le pere A : signal recu : SIGUSR1 (fin de la tache precedente)
Le pere A : signal envoye : SIGUSR1 (autorisation tache C)
Le fils C : signal recu : SIGUSR1
Le fils C : message recu : EXERCICE AA1254WW
Le fils C : envoie au pere A de SIGUSR1
Le pere A : signal recu : SIGUSR1 (fin de la tache precedente)
Le pere A : signal envoye : SIGUSR1 (autorisation tache B)
Le fils B : message a envoyer :
Le fils B : ecriture et envoie du message
Le fils B : envoie au pere A de SIGUSR1
Le pere A : signal recu : SIGUSR1 (fin de la tache precedente)
Le pere A : signal envoye : SIGUSR1 (autorisation tache C)
Le fils C : signal recu : SIGUSR1
Le fils C : message recu : PAS DE MESSAGE
Le fils C : envoie au pere A de SIGUSR1
Le pere A : signal recu : SIGUSR1 (fin de la tache precedente)
Le pere A : signal envoye : SIGUSR1 (autorisation tache B)
Le fils B : message a envoyer : '\n'
Le fils B : ecriture et envoie du message
Le fils B : envoie au pere A de SIGUSR1
Le pere A : signal recu : SIGUSR1 (fin de la tache precedente)
Le pere A : signal envoye : SIGUSR1 (autorisation tache C)
Le fils C : signal recu : SIGUSR1
Le fils C : message recu : PAS DE MESSAGE
Le fils C : envoie au pere A de SIGUSR1
Le pere A : signal recu : SIGUSR1 (fin de la tache precedente)
Le pere A : signal envoye : SIGUSR1 (autorisation tache B)
Le fils B : message a envoyer :sdgfsdg
Le fils B : ecriture et envoie du message
Le fils B : envoie au pere A de SIGUSR1
Le pere A : signal recu : SIGUSR1 (fin de la tache precedente)
Le pere A : signal envoye : SIGUSR1 (autorisation tache C)
Le fils C : signal recu : SIGUSR1
Le fils C : message recu : SDGFSDG
Le fils C : envoie au pere A de SIGUSR1
Le pere A : signal recu : SIGUSR1 (fin de la tache precedente)
Le pere A : signal envoye : SIGUSR1 (autorisation tache B)
Le fils B : message a envoyer : '^D'
Le fils B : envoie au pere A : SIGUSR2
Le pere A : signal recu de B : SIGUSR2
Le pere A : envoie au fils C : SIGUSR2
Le fils C : signal recu : SIGUSR2
Le fils C : envoie au pere A : SIGUSR2
Le pere A : signal recu de C : SIGUSR2
Le pere A : Fin du fils B.
Le pere A : Fin du fils C.
Le pere A : Fin de moi !
Killed
[root@localhost /root]#
*/