0% ont trouvé ce document utile (0 vote)
5 vues19 pages

Processus en C : fork(), wait() et mémoire

Transféré par

62623
Copyright
© All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd
0% ont trouvé ce document utile (0 vote)
5 vues19 pages

Processus en C : fork(), wait() et mémoire

Transféré par

62623
Copyright
© All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd

Laboratoire

Process

jcj mba mbo nvs

février 2025
Table des matières

1 fork() 2
1.1 Process - LaboProcess 01-01 - fork() & clonage . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.2 Process - LaboProcess 01-02 - fork() & mémoire . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
1.3 Process - LaboProcess 01-03 - fork() & fichiers . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6

2 wait() 8
2.1 Process - LaboProcess 02-01 - wait4() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
2.2 Process - LaboProcess 02-02 - Zombies . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
2.3 Process - LaboProcess 02-03 - Adoption . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13

3 Shell 15
3.1 Process - LaboProcess 03-01 - Shell simple . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
3.2 Process - LaboProcess 03-02 - Shell && . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17

1
Chapitre 1

fork()

1.1 Process - LaboProcess 01-01 - fork() & clonage


Titre : Process - LaboProcess 01-01 - fork() & clonage
Support : OS 15.6 Leap Installation Classique
Date : 07/2011
02/2025

1.1.1 Énoncé
Écrivez un programme qui se clone et ensuite affiche son pid et celui de son parent.
Observez l’affichage produit par ce programme. Pourquoi le premier et le deuxième message ne s’affichent pas
tous les deux 2 fois ?

1.1.2 Une solution


 
/*
NOM : ForkVie . c
CLASSE : Process - LaboProcess 01 -01
# OBJET : r é serv é au Makefile
AUTEUR : MBA 01/ 2024
*/
#include < stdio .h >
#include < stdlib .h >
#include < sys / types .h >
#include < unistd .h > // fork () , getpid () , getppid ()

// Filiation

int main ()
{
printf ( " BONJOUR ! Je suis le processus % u fils de % u \ n " , getpid () ,
getppid ());
fork ();
printf ( " Apr è s FORK , je suis le processus % u fils de % u \ n " , getpid () ,
getppid ());

exit (0); // On quitte sans erreur


}
 

1.1.3 Commentaires
L’ordre des affichages du père et du fils n’est pas garanti.

2
Process - LaboProcess 01-01 - fork() & clonage Page 3

1.1.4 En roue libre


— Adaptez cet exemple de manière à ce que le message affiché par le père soit différent de celui du fils après
le fork().
— Ajoutez un sleep(1) avant l’affichage par le père uniquement et observez la différence de comportement.
— L’appel système exit() est indispensable chez le fils. Vérifiez et expliquez le comportement de ce code
si cet appel système est retiré du code du fils.

©MBA MBO NVS 17 février 2025


Process - LaboProcess 01-02 - fork() & mémoire Page 4

1.2 Process - LaboProcess 01-02 - fork() & mémoire


Titre : Process - LaboProcess 01-02 - fork() & mémoire
Support : OS 15.6 Leap Installation Classique
Date : 01/2025

1.2.1 Énoncé
Écrivez un programme qui montre que les espaces d’adressage contenant code et données de processus père et
fils sont disjoints.

1.2.2 Une solution


 
/*
NOM : ForkMemoire . c
CLASSE : Process - LaboProcess 01 -02
# OBJET : r é serv é au Makefile
AUTEUR : J . C . Jaumain , 07/2011
MBA , MBO , NVS 01/2025
*/
#include < stdio .h >
#include < stdlib .h >

#include < sys / types .h > // pid_t


#include < unistd .h >

// Quelle est l ’ adresse d ’ une variable dans p è re et fils ?

int main ()
{
// une variable automatique : i nitial isatio n explicite par le p è re
int var_automatiqu e = 6;

printf ( " Avant fork , pour le p è re %u , l ’ adresse % p contient la valeur % d \ n " ,


getpid () , (void *) & var_automatique , v ar _ au t om at i qu e );

printf ( " \ n " );

pid_t fork_result = fork (); // retour de fork


i f ( fork_result == 0)
{
printf ( " Je suis %u , fils de % u \ n " , getpid () , getppid ());
printf ( " Pour % u fils de %u , l ’ adresse % p contient la valeur % d \ n " ,
getpid () , getppid () , (void *) & var_automatique ,
var_auto m at iq u e );

printf ( " \ n " );

// Je ( fils ) modifie la variable (19)


var_automatiqu e = 19;

printf ( " FILS : pour %u , fils de %u , l ’ adresse % p contient la "


" valeur % d \ n " ,
getpid () , getppid () , (void *) & var_automatique ,
var_auto m at iq u e );

printf ( " \ n " );

// Ne pas oublier l ’ exit !!! Que se passe -t - il en absence d ’ exit ?


exit (0); // commenter ...
}

printf ( " PERE : Apr è s le fork , pour % u le p è re , l ’ adresse % p contient la "


" valeur % d \ n " ,
getpid () , (void *) & var_automatique , v ar _ au t om at i qu e );

printf ( " \ n " );

// Je ( pere ) modifie la variable (13)


v ar _automatique = 13;

©MBA MBO NVS 17 février 2025


Process - LaboProcess 01-02 - fork() & mémoire Page 5

// Je donne une chance à mon fils de tourner : d é commenter le sleep


// sleep (3); // d é commenter ...

printf ( " PERE : Apr è s le fork , pour le p è re %u , l ’ adresse % p contient la "


" valeur % d \ n " ,
getpid () , (void *) & var_automatique , v ar _ au t om at i qu e );

printf ( " \ n " );

sleep (1); // Pour que le p è re se termine apr è s le fils

exit (0);
}
 

1.2.3 Commentaires
— Une fois le processus fils créé, les deux processes sont indépendants.
— Chaque process a son propre espace d’adressage. Il n’y a pas de partage de la variable locale.
— L’adresse de la variable est identique car c’est une adresse relative à l’espace d’adressage de chaque
processus. Les espaces sont physiquement séparés.
— L’ordre des affichages n’est pas garanti.

1.2.4 En roue libre


— Vérifiez si le comportement est le même pour les variables de classe d’allocation statique 1 et dynamique 2
(malloc()).
— L’appel système exit() est indispensable chez le fils et le père. Vérifiez et expliquez le comportement de
ce code si cet appel système est retiré du code du fils.
— Les valeurs changent-elles en décommentant l’avant-dernier sleep(), qui donne une chance au fils de
s’exécuter ?

1. [Link] (consulté le 2 février 2025).


2. [Link] (consulté
le 2 février 2025).

©MBA MBO NVS 17 février 2025


Process - LaboProcess 01-03 - fork() & fichiers Page 6

1.3 Process - LaboProcess 01-03 - fork() & fichiers


Titre : Process - LaboProcess 01-03 - fork() & fichiers
Support : OS 15.6 Leap Installation Classique
Date : 01/2025

1.3.1 Énoncé
Écrivez un programme qui montre que les entrées de TDFO préexistantes à un appel système fork() sont
partagées par le processus fils après fork().

1.3.2 Une solution


 
/*
NOM : ForkFichiers . c
CLASSE : Process - LaboProcess 01 -02
# OBJET : r é serv é au Makefile
AUTEUR : MBA , MBO , NVS 01/2025
*/

#include < stdio .h >


#include < stdlib .h >

#include < fcntl .h > // pour open ()


#include < unistd .h > // pour unlink () , fork () , write () , close () , sleep ()

int main ()
{
// suppression du fichier
// pour é viter l ’ utilisation du flag O_TRUNC
unlink ( " fichier " );

// ici pas de O_TRUNC


// qui brouillerait les pistes
// pour l ’ exercice " en roue libre "
int fd = open ( " fichier " , O_WRONLY | O_CREAT , 0644);

i f ( fd < 0)
{
perror ( " open " );
exit (1);
}

int fork_return ;
i f (( fork_return = fork ()) == 0)
{
write ( fd , " ABC " , 3);
close ( fd );
exit (0);
}

// sleep (1); // d é commenter

write ( fd , " DEF " , 3);


close ( fd );

sleep (1); // Pour que le p è re se termine apr è s le fils

exit (0);
}
 

1.3.3 Commentaires
— Après fork(), l’entrée de TDFO est partagée entre les processus père et fils.
— L’ordre d’exécution n’est pas garanti

©MBA MBO NVS 17 février 2025


Process - LaboProcess 01-03 - fork() & fichiers Page 7

1.3.4 En roue libre


Adaptez ce code afin d’observer et comparer son comportement quand l’appel système open() est fait dans
chaque processus indépendamment et donc après l’appel système fork().

©MBA MBO NVS 17 février 2025


Chapitre 2

wait()

2.1 Process - LaboProcess 02-01 - wait4()


Titre : Process - LaboProcess 02-01 - wait4()
Support : OS 15.6 Leap Installation Classique
Date : 07/2011
02/2025

2.1.1 Énoncé
Écrivez un programme Wait4 qui, de manière conditionnelle, crée zéro, un ou deux processes fils. Le contrôle
du nombre de fils produit est réalisé lors de la précompilation.
Un des deux process fils calcule un million (106 ) de sinus de nombres aléatoires. Il s’exécute surtout en ring 3.
L’autre process fils effectue l’impression d’un million (106 ) caractères ’a’. Il s’exécute surtout en ring 0.
Le père attend la fin de son / ses fils et affiche les ressources consommées par celui / ceux-ci.

2.1.2 Une solution


 
/*
NOM : Wait4 . c
CLASSE : Process - LaboProcess 02 -01
# OBJET : r é serv é au Makefile
AUTEUR : J . C . Jaumain , 07/2011
MBA , MBO , NVS 02/2025
*/

// pour wait4
#define _DEFAULT_SOURC E

#include < stdio .h >


#include < stdlib .h >

#include < fcntl .h >


#include < sys / resource .h >
#include < sys / stat .h >
#include < sys / time .h >
#include < sys / types .h >
#include < sys / wait .h >
#include < unistd .h >

// commenter d é commenter
#define RING_0
// commenter d é commenter
#define RING_3

#i f d e f RING_0
#include < math .h >

8
Process - LaboProcess 02-01 - wait4() Page 9

#endif

// surveiller la consommation de ressources CPU d ’ un processus enfant


int main ( int argc , char * argv [])
{
pid_t pid ;
int status ;
struct rusage usage ;

#i f d e f RING_3
// cr é e un processus consommateur de temps en RING3
i f (( pid = fork ()) == 0)
{
printf ( " RING_3 : pid du fils = % u \ n \ n " , getpid ());

srand ( getpid ()); // ensemencement de la s é quence al é atoire


for ( int i = 0; i < 10000000; ++ i )
{
sin ( rand ()); // des calculs
}

exit (0);
}

i f (( wait4 ( pid , & status , 0 , & usage )) > 0)


{
printf ( " Temps utilisateur : % ld s , % ld micro sec \ n " ,
usage . ru_utime . tv_sec , usage . ru_utime . tv_usec );
printf ( " Temps en mode noyau : % ld s , % ld micro sec \ n " ,
usage . ru_stime . tv_sec , usage . ru_stime . tv_usec );
}

printf ( " \ n " );


#endif

#i f d e f RING_0
i f (( pid = fork ()) == 0)
{
printf ( " RING_0 : pid du fils = % u \ n \ n " , getpid ());

int fd = open ( " / dev / null " , O_WRONLY ); // poubelle


for ( int i = 0; i < 10000000; ++ i )
{
write ( fd , " a " , 1); // des appels syst è me
}
close ( fd );

exit (0);
}

i f (( wait4 ( pid , & status , 0 , & usage )) > 0)


{
printf ( " Temps utilisateur : % ld s , % ld micro sec \ n " ,
usage . ru_utime . tv_sec , usage . ru_utime . tv_usec );
printf ( " Temps en mode noyau : % ld s , % ld micro sec \ n " ,
usage . ru_stime . tv_sec , usage . ru_stime . tv_usec );
}

printf ( " \ n " );


#endif

exit (0);
}
 

2.1.3 Commentaires
— On a choisi ici d’écrire dans un périphérique /dev/null qui reçoit les informations mais ne les utilise
pas. Ceci évite un affichage de caractères ’a’ à l’écran, qui prend beaucoup de temps.
— La documentation de la structure struct rusage peut être lue via la commande :
man getrusage
— La documentation de la structure struct timeval peut être lue via la commande :

©MBA MBO NVS 17 février 2025


Process - LaboProcess 02-01 - wait4() Page 10

man 2 gettimeofday
— Le préfixe time permet de demander au shell la consommation d’une commande. Pour davantage d’in-
formations :
man time

2.1.4 En roue libre


Modifiez ce code pour qu’il ne crée qu’un seul processus par exécution. Testez votre solution et observez le
temps d’exécution pour les différents cas.

©MBA MBO NVS 17 février 2025


Process - LaboProcess 02-02 - Zombies Page 11

2.2 Process - LaboProcess 02-02 - Zombies


Titre : Process - LaboProcess 02-02 - Zombies
Support : OS 15.6 Leap Installation Classique
Date : 02/2025

2.2.1 Énoncé
Écrivez un programme qui :
1. crée un processus zombie ;
2. affiche les processus en cours et leur état à l’aide de la fonction standard C system() et de la commande
ps ;
3. élimine le zombie ;
4. affiche une nouvelle fois les processus en cours et leur état.

2.2.2 Une solution


 
/*
NOM : CreerZombie . c
CLASSE : Process - LaboProcess 02 -02
# OBJET : r é serv é au Makefile
AUTEUR : J . C . Jaumain , 07/2011
AUTEUR : MBA 2023
*/

// pour usleep ()
# define _DEFAULT_SOURCE

# include < stdio .h >


# include < stdlib .h >

# include < sys / types .h >


# include < sys / wait .h > // pour wait ()
# include < unistd .h > // pour sleep () , usleep () et d ’ autres

int main ( int argc , char * argv [])


{
pid_t fork_return ;
if (( fork_return = fork ()) == 0)
{
// ici : fils

printf (" Le process fils de % u est vivant , il a le num é ro % u .\ n " ,


getppid () , getpid ());
printf ("\ n ");

sleep (1);

// le processus fils se termine apr è s 1 seconde


exit (0);
}

// ici : p è re car exit (0) du fils ... peut - ê tre pas encore ex é cut é !

usleep (100000); // 100 000 micro - secondes = 0 ,1 s

printf (" R é sultat affich é par ps ( table des process ) avec fils vivant :\ n ");
// ex é cute un bash d ’ une seule commande
system (" ps -o ppid , pid , state , command ");
printf ("\ n ");

sleep (3); // le p è re laisse le fils se terminer ...

printf (" Le process fils de % u est un zombie , il a le num é ro % u .\ n " ,


getpid () , fork_return );
printf ("\ n ");

printf (" R é sultat affich é par ps ( table des process ) avec fils zombie :\ n ");

©MBA MBO NVS 17 février 2025


Process - LaboProcess 02-02 - Zombies Page 12

// ex é cute un bash d ’ une seule commande


system (" ps -o ppid , pid , state , command ");
printf ("\ n ");

// sleep (1); // laissons system se terminer

printf (" Le p è re appelle wait () , une bonne fa ç on d ’ é liminer un zombie .\ n ");


printf ("\ n ");

wait ( NULL );

printf (" R é sultat affich é par ps ( table des process ) avec fils mort :\ n ");
// ex é cute un bash d ’ une seule commande
system (" ps -o ppid , pid , state , command ");

// sleep (1); // laissons system se terminer

exit (0);
}
 

2.2.3 Commentaires
— La fonction C system() crée un shell et exécute la chaîne reçue en argument comme seule commande
de ce shell.
— Le processus zombie est éliminé par l’appel système wait().
— La commande kill n’a pas d’effet sur un zombie. On ne tue pas un mort-vivant !

2.2.4 En roue libre


Adaptez le code pour vérifier la raison de la mort du processus fils : erreur ou signal.
Vous pouvez utiliser la commande :
kill <pid>
pour envoyer un signal au processus fils. Il faut juste qu’il soit encore en vie. À cette fin, servez-vous de l’appel
système pause() ou des fonctions sleep() et usleep().

©MBA MBO NVS 17 février 2025


Process - LaboProcess 02-03 - Adoption Page 13

2.3 Process - LaboProcess 02-03 - Adoption


Titre : Process - LaboProcess 02-03 - Adoption
Support : OS 15.6 Leap Installation Classique
Date : 02/2025

2.3.1 Énoncé
Écrivez un programme qui provoque une adoption. Il affiche ensuite les processus en cours et leurs liens de
parenté à l’aide de la fonction C system().

2.3.2 Une solution


 
/*
NOM : adoption . c
CLASSE : Process - LaboProcess 02 -03
MBA , MBO , NVS 2025
*/
# include < stdio .h >
# include < stdlib .h >

# include < sys / wait .h >


# include < unistd .h >

int main ( int argc , char * argv [])


{
if ( fork () == 0)
{
printf (" Je suis %d , mon p è re est % d .\ n " , getpid () , getppid ());
printf ("\ n ");

printf (" R é sultat affich é par ps ( table des process ) :\ n ");


// ex é cute un bash d ’ une seule commande
system (" ps -o ppid , pid , state , command ");
printf ("\ n ");

sleep (4); // laissons le p è re se terminer

printf (" Je suis %d , mon p è re est % d .\ n " , getpid () , getppid ());


printf ("\ n ");

printf (" R é sultat affich é par ps : table des process \ n \ n ");


// ex é cute un bash d ’ une seule commande
system (" ps -o ppid , pid , state , command ");
printf ("\ n ");

// sleep (4); // laissons system se terminer


exit (0);
}

// pourquoi pas de wait ? Y a -t - il risque de zombie ?

sleep (2);

printf (" Terminaison du p è re \ n ");


printf ("\ n ");

// un processus p è re qui se termine apr è s un peu plus de 2 secondes


exit (0);
}
 

2.3.3 Commentaires
— La fonction C system() crée un shell et exécute la chaîne reçue en argument comme seule commande
de ce shell.
— Un processus ne reste pas orphelin. Si le parent d’un processus se termine avant celui-ci, le fils orphelin
se fait adopter par le process init ou systemd.

©MBA MBO NVS 17 février 2025


Process - LaboProcess 02-03 - Adoption Page 14

— Pourquoi n’y a-t-il pas de wait() dans ce code ?


— Pourquoi le prompt s’affiche-t-il avant la fin de l’exécution de ce programme ?

2.3.4 En roue libre


Adaptez ce code pour qu’il créé un zombie et l’élimine grâce à la technique du double fork vue au cours. Cette
technique crée un père intermédiaire qui se termine immédiatement. Elle permet de forcer l’adoption immédiate.
Vérifiez qu’il n’y a pas de zombies qui restent, avant la fin du programme principal.

©MBA MBO NVS 17 février 2025


Chapitre 3

Shell

3.1 Process - LaboProcess 03-01 - Shell simple


Titre : Process - LaboProcess 03-01 - Shell simple
Support : OS 15.6 Leap Installation Classique
Date : 02/2025

3.1.1 Énoncé
Écrire un shell simple capable d’exécuter n’importe quelle commande externe avec un nombre d’arguments
quelconque, ainsi que la commande interne exit.

3.1.2 Une solution


 
/*
NOM : Shell . c
CLASSE : FS - LaboProcess 04 -01
# OBJET : r é serv é au Makefile
AUTEUR : J . C . Jaumain , 07/2011
*/
#include < stdio .h >
#include < stdlib .h >
#include < string .h >

#include < sys / wait .h >


#include < unistd .h >

int main ()
{
printf ( "$ > " );

// pour lire la commande au clavier


char ligne [257]; // danger de d é bordement
fgets ( ligne , 256 , stdin );
// rem . : le ’\ n ’ ( aka enter ) est consomm é et inclus dans ligne par fgets

// un tableau de pointeurs de caract è res


char * tokens [100]; // danger de d é bordement
int i ;
while ( strcmp ( ligne , " exit \ n " ) != 0)
{
i = 0;
// d é composition de ligne en tokens , 2 d é limiteurs : ’ ’ et ’\ n ’
tokens [ i ] = strtok ( ligne , " \ n " );
while ( tokens [ i ] != NULL )
{
// pr é - incr é mentation de i : la valeur retourn é e et utilis é e
// est celle de i apr è s l ’ incr é mentation
// NULL : pour commencer la recherche au 1 er caract è re

15
Process - LaboProcess 03-01 - Shell simple Page 16

// suivant la derni è re marque de fin de cha î ne ( ’\0 ’) é crite


// par strtok () dans ligne
// 2 d é limiteurs : ’ ’ et ’\ n ’
tokens [++ i ] = strtok ( NULL , " \ n " );
}

i f ( fork () == 0)
{
execvp ( tokens [0] , tokens );
// perror (" exec commande inconnue ");

// ou mieux , pour afficher é galement la commande


// dans le message d ’ erreur :
// char errmsg [200]; // danger de d é bordement
// sprintf ( errmsg , " exec commande <%s > inconnue " , tokens [0]);
// perror ( errmsg );

printf ( " Passer à la commande suivante \ n " );


}

// int status ;
// wait (& status );
wait ( NULL );

printf ( "$ > " );


fgets ( ligne , 256 , stdin );
}
exit (0);
}
 

3.1.3 Commentaires
— L’appel à la fonction C perror() ne demande pas de test du retour de l’appel système exec(). En effet,
si exec() se passe bien, c’est-à-dire si l’exécutable a bien été trouvé, le process courant est écrasé, on ne
peut y revenir.
— L’appel fork() clone le shell courant en un deuxième shell. Ce fils est écrasé par un exécutable si exec()
le trouve. Sinon, le fils reste un shell. Si on oublie de terminer ce fils avec exit(), celui-ci reste un shell
et deux shells s’exécutent. L’utilisateur doit alors taper deux fois la commande interne exit pour en
sortir.
— Le script Demo contient le symbole <<. Ce n’est pas une indirection mais cela définit le symbole de fin de
donnée pour le process.
— man exec pour obtenir l’aide relative aux fonctions execl(), execlp(), execle(), execv(), execvp()
et execvpe().

3.1.4 En roue libre


— Corrigez ce shell simple de sorte qu’il se comporte correctement si l’utilisateur introduit le nom d’un
exécutable qui n’existe pas.
— Ajoutez au shell simple la gestion de la commande :
echo $$
— Ajoutez au shell simple la gestion de la commande :
echo $?
— Votre shell fonctionne-t-il avec les commande :
cd
ou :
cd <rep>
— Votre shell fonctionne-t-il avec la commande :
ls > f

©MBA MBO NVS 17 février 2025


Process - LaboProcess 03-02 - Shell && Page 17

3.2 Process - LaboProcess 03-02 - Shell &&


Titre : Process - LaboProcess 03-02 - Shell &&
Support : OS 15.6 Leap Installation Classique
Date : 02/2025

3.2.1 Énoncé
Complétez le programme C lacunaire suivant pour qu’il réalise invariablement et comme le ferait un shell, la
suite de commandes :
gcc aff.c -o aff && ./aff Message
Quelques compléments d’information :
— Le source aff.c est fourni. Il affiche son premier argument facultatif, ici Message.
— L’opérateur && exécute ce qui se trouve à sa droite après avoir exécuté ce qui se trouve à sa gauche, si
ce qui se trouve à sa gauche s’est terminé sans erreur.
— Si aff.c provoque une erreur de compilation ou lors de l’édition des liens, un message d’erreur est affiché.
— Votre programme exécute toujours la même commande en boucle, quoi que vous entriez au clavier, sauf
si vous tapez exit, auquel cas, il s’arrête.

3.2.2 Une solution lacunaire


Cette fois, la solution fournie doit être complétée par vos soins.
 
/*
NOM : ShellAND . c
CLASSE : FS - LaboProcess 03 -02
# OBJET : r é serv é au Makefile
AUTEUR : MBA , MBO , NVS 2/2025
*/
#include < stdio .h >
#include < stdlib .h >
#include < string .h >

// # include < sys / types .h >


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

int main ()
{
printf ( "$ > " );

char ligne [257]; // pour lire la commande au clavier


fgets ( ligne , 256 , stdin );

while ( strcmp ( ligne , " exit \ n " ))


{
// ici on peut se servir des fonctions execl car la liste de commandes
// à ex é cuter est toujours la m ê me

// compl é ter ici si n é cessaire ...

// liste de param è tres termin é e par NULL


execlp ( " gcc " , " gcc " , " aff . c " , " -o " , " aff " , NULL );

// compl é ter ici si n é cessaire ...

// liste de param è tres termin é e par NULL


execl ( " ./ aff " , " aff " , " Message " , NULL );

// compl é ter ici si n é cessaire ...

printf ( "$ > " );


fgets ( ligne , 256 , stdin );
}

exit (0);
}
 

©MBA MBO NVS 17 février 2025


Process - LaboProcess 03-02 - Shell && Page 18

À titre d’information, le code d’aff.c :


 
/*
NOM : aff . c
CLASSE : Process - LaboProcess 03 -01
# OBJET : r é serv é au Makefile
AUTEUR : J . C . Jaumain , 07/2011
*/
#include < stdio .h >
#include < stdlib .h >

int main ( int argc , char * argv [])


{
printf ( " % s \ n " , argv [1]);

exit (0);
}
 

3.2.3 Commentaires
— l’opérateur && de bash est un AND. La commande qui suit && n’est exécutée que si et seulement si la
première se termine par exit(0), ce qui veut dire : tout s’est bien passé.
— gcc, comme toute commande, respecte la convention qui consiste à se terminer par exit(0) si il n’y a
pas d’erreur 1 .
— L’appel système wait() permet de récupérer le statut de fin d’un processus.

3.2.4 En roue libre


Complétez le shell et testez-le dans le cas où aff.c ne permet pas de produire un exécutable.

1. Remarquez que le script Demo de la section actuelle (3.2) utilise ce comportement pour l’exécutable make.

©MBA MBO NVS 17 février 2025

Vous aimerez peut-être aussi