TD

Gestion des Signaux Linux en Langage C


Instructions

  • Chercher les numéros de signaux

1) avec kill -l,

2) dans /usr/include (man signal)

  • Compiler avec la commande make

  • Expliquer le fonctionnement de ces programmes

  • Manuel de wait sous UBUNTU


Programme ps_sig1.c

/*  
 * ######
 * ## ps_sig1.c
 * ## ~~~~~~~~~
 * ## 04.02.1995: Creation TL
 * ## 07.05.2018:
 * ##
 * ## Gestion des interuptions
 * ## Detournement des IT : SIGINT, SIGUSR1, SIGUSR2
 * ##
 * ## Voir le man de la commande kill
 * ##
 * ######
 */


#include <stdio.h>
#include <sys/signal.h>

#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>

  
typedef void (*sighandler_t) (int);

  
void fonc1() { printf("\n PS_SIG1> Reception signal SIGUSR1\n"); }
  
void fonc2() { printf("\n PS_SIG1> Reception signal SIGUSR2\n"); }

int main()
{
  
signalSIGUSR1, (sighandler_tfonc1 );
  
signalSIGUSR2, (sighandler_tfonc2 );
  
signalSIGINT SIG_IGN );

  for (;;) {
    
putchar('\n');  putchar('*');  sleep(1);
  }
}
/*--  fin  ps_sig1.c  --*/

Programme ps_sig2.c

/*
 * ######
 * ## ps_sig2.c
 * ## ~~~~~~~~~
 * ## 04.02.1995: Creation TL
 * ## 07.05.2018:
 * ######
 */

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>

#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>

int mainargcargv )

  
int    argc;  char **argv;

{
  
int  pidf1code_retour;

  
printf" PS_SIG2> argc      = %d\n",  argc );

  if ( 
argc == ) {
    exit( 
);
  }

  
/*
   * Conversion de l'argument (ascii) en integer
   * Dans certains systeme, la conversion genere une erreur
   * provoquant l'arret premature du programe
   *
   * Essayer : ./ps_sig2 abcd
   */

  
pidf1 atoiargvargc-] );
  if ( 
pidf1 == ) {
    
printf" PS_SIG2> %s : argument incorrect\n",  argvargc-] );
    exit( 
);
  }

  
printf" PS_SIG2> argv[ arc-1 ] = %s\n",  argv] );
  
printf" PS_SIG2> PID  de l'autre FILS = %d\n"pidf1 );

  
sleep);
  
code_retour killpidf1SIGUSR1 );
  if ( 
code_retour == -) {
    
perror"FILS2(usr1): " );
  }

  
sleep);
  
code_retour killpidf1SIGINT );
  if ( 
code_retour == -) {
    
perror"FILS2(int): " );
  }

  
sleep);
  
code_retour killpidf1SIGUSR2 );
  if ( 
code_retour == -) {
    
perror"FILS2(usr2): " );
  }

  for (;;) {
    
putchar'\n' );   putchar'~' );   sleep);
  }
}
/*--  fin  ps_sig2  --*/

Programme ps_sig3.c

/*  
 * ######
 * ## ps_sig3.c
 * ## ~~~~~~~
 * ## 04.02.1995: Creation TL
 * ## 07.05.2018:
 * ######
 */

#include <stdio.h>
#include <stdlib.h>

#include <signal.h>

#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <wait.h>


int main()
{
  
int   pidpid1pid2;   char arg1256 ];   char arg2256 ];
  
int status;

  
/* Creation Fils 1 */
  
  
pid1 fork();
  if ( 
pid1 == -) {
    
printf(" \n PS_SIG3> Creation FILS( 1 ) impossible\n ");
    exit( 
);
  }

  
/* Instructions pour le fils 1 */
  
  
if ( pid1 == ) {
    
sprintfarg1"%d\n"getpid() ); // UNUSED
    
execl"ps_sig1"arg1NULL );
    
/* 
     * Que se passe-t-uil en cas de succes ou d'erreur
     * de l'appel de execl ?
     * Faut-il mettre le PathName de la commande ?
     */
    
exit(3);
  }

  
/* Creation Fils 2 */
  
  
pid2 fork();
  if ( 
pid2 == -) {
    
printf("\n PS_SIG3> Creation FILS( 2 ) impossible\n" );
    exit( 
);
  }

  
/* Instructions pour le fils 2 */

  
if ( pid2 == ) {
    
sprintfarg2"%d\n"pid1 ); // PID du FRERE
    
execl"ps_sig2"arg2NULL );
    
/* 
     * Que se passe-t-uil en cas de succes ou d'erreur
     * de l'appel de execl ?
     * Faut-il mettre le PathName de la commande ?
     */
    
exit( );
  }
  
sleep10 );

  
/* Instructions du Pere */
  
  
pid wait( &status );

  if ( 
pid == pid1 ) {
    
printf"\nPS_SIG3> FILS( 1 ) arrete par signal %d\n"status );

    
/* On demande l'arret de l'autre Fils */
    
if ( ( killpid2SIGTERM ) ) == -1) {
      
perror"\n PS_SIG3> Pb. kill (1)" );
    }
  } else if ( 
pid == pid2 ) {
    
printf("\n PS_SIG3> FILS( 2 ) arrete par signal %d\n"status );

    
/* On demande l'arret de l'autre Fils */
    
if ( ( killpid1SIGTERM ) ) == -1) {
      
perror"\n PS_SIG3> Pb. kill (2)" );
    }
  }

  
/* On attend l'arret de l'autre Fils */

  
pid wait( &status );

  if ( 
pid == pid1 ) {
    
printf("\n PS_SIG3> FILS( 1 ) arrete par signal %d\n"status );
  } else if ( 
pid == pid2 ) {
    
printf("\n PS_SIG3> FILS( 2 ) arrete par signal %d\n"status );
  }
  exit( 
);
}
/* ---  fin  ps_sig3  --- */

Makefile pouvant être utilisé pour la génération des exécutables


Ce Makefile prend en compte les fichiers feenable.c et sigaction.c