• Aucun résultat trouvé

X)’”“I•‹–0*"*UŒ"5!13&amp amp;0——+™˜œw

N/A
N/A
Protected

Academic year: 2022

Partager " X)’”“I•‹–0*"*UŒ"5!13&amp amp;0——+™˜œw"

Copied!
11
0
0

Texte intégral

(1)

798;:=<?>@(ACB(DFE!GHIH?>JLKM@ON;B(GPQ>G!B(HRNTSUH

VXWRY?Z\[]^`_

acbdb _e

acbdbcf

gihXjk?lnmlojMp q;gihXr!lnsFtImuwv9louwvxlosxkIk?j!vytIj{zxj!|~}xk?ulnj!|I|(s|€}‚k?jƒjot~„†…|

‡ˆ) * U‰ 2&0Š 201‹13U46() 2,Œ"5

'ŽU‰ ‘)’”“I•‹–5"*‰ U13&0†—+™˜š›™w**!13&0†——+™˜œ*

'Ž,Œ"5ž‘X)’”“I•‹–0*"*UŒ"5!13&0—+™˜Ÿ›™*13&0——+™˜œw*

 ¡™&02 "$#‰‰"(¢‹"*‹‰ 213*03£=¤¥¥-¦\‰& !0& !"*§¨›)2&‰c&2*©"*U“

ª

'Ž,Œ"5,2 21‹* ž6!"‰c 20«

¬

'ŽU‰ U 13* 06"*,Œ"5

­ #include <stdio.h>

® #include <unistd.h>

¯°

void main()

± {

² pid_t p;

³ p=fork();

´ switch(p)

µ {

­·¶ case (0):

­-­ //sleep(15);

­$® printf("Le fils pid est =%d et mon ppid est=%d\n", getpid(), getppid());

­$¯ break;

­¸° case (-1):

­$± //sleep(15);

­-² printf("Erreur fork\n");

­-³ break;

­$´ default:

­·µ printf("Le pere pid est =%d et mon ppid est=%d\n", getpid(), getppid());

®¶ }

®­ printf("Fin du processus %d\n",getpid());

®-® }

gihXjk?lnmlojº¹ q;»ƒrk?mtI¼w½¾jƒzj!|~¼UtŽt¿m=ÀsFtI|~jotÁlou}†mj!|~zj!|ÃÂļwk¿m¼wÀ…j!|

 !‰ 2x"*L‰ 2&0Š 201‹13)Å·›‹F)&013‰"*2 iž‘X)’063"Æ#*Ž«"LŠ*Ç«X"L)&066iÇ#Lž 25©"*F§

*È2*0"5¢

ƒ

ž6!",./& ÊËn13&Œw"&F§Ì,Íy‰ !"*UŒ"5"*&0x§ÎÏy‰ !"*U‰ 

(2)

­ #include<unistd.h>

® #include<stdio.h>

¯ void main()

° {

± pid_t p;

² int x = 2;

³ p=fork();

´ switch(p)

µ {

­·¶ case (0):

­-­ x = x + 3;

­$® printf("Le fils pid=%d ppid=%d uid=%d gid=%d x=%d\n", getpid(), getppid(), getuid(), getgid(), x);

­$¯ break;

­¸° case (-1):

­$± printf("Erreur fork\n");

­-² break;

­-³ default:

­$´ x = x * 5;

­·µ printf("Le fils pid=%d ppid=%d uid=%d gid=%d x=%d\n", getpid(), getppid(), getuid(), getgid(), x);

®¶ }

®­ printf("Fin programme\n");

®-® }

®-¯

gihXjk?lnmlojÑÐ qÓҜ¼w|€}¼wk(tImlns…mjkÔzj!|~zxj!|Ilˆk?m=}xtIj!sxk¿|Rzxjƒ„l?Õmjk?|

‡ˆ) * !X‰ 2&0Š0 1313!46&¨ !XŒ)’* —&131‹3•Ä&0&y«0X"*)=2 2ˆ›) 2È2 20«&06ˆ"*)&2¨ˆ"5wÈ2

ª›¬ ÍÖ¨Ï×6ØÙ0ڍ0'ŽU‰ 2&0Š 201‹13./&0 2Ê—Û"*UŒ"5) 2!0©o"*Čc)’ !U*"(#&0 o!"Ž"* ¬ ) 0)=2 2(Û"*

‰c 2U#& ›«" ¬ )0 2)=2 2n) %Ü,

­ #include<stdio.h>

® #include<fcntl.h>

¯ #include<unistd.h>

° #include<sys/stat.h>

± #include<sys/types.h>

² void main()

³ {

´ pid_t p;

µ char chaine[3];

­·¶ int desc;

­-­ desc=open("toto",O_RDWR,0);

­$® p=fork();

­$¯ switch(p)

­¸° {

­$± case (0):

­-² printf("Le fils PID=%d PPID=%d\n", getpid(), getppid());

­-³ write(desc,"ab",2);

­$´ sleep(10);

­·µ read(desc,chaine,2);

®¶ chaine[2]=’\0’;

®­ printf("chaine lue par le fils %s\n", chaine);

(3)

®-® close(desc);

®-¯ break;

®·° case (-1):

®-± printf("Erreur fork\n");

®² break;

®³ default:

®-´ printf("Le père Valeur de retour du fork=%d\n", p);

®µ printf("Le père PID=%d PPID=%d\n", getpid(), getppid());

¯¶ sleep(3);

¯­ read(desc,chaine,2);

¯-® chaine[2]=’\0’;

¯-¯ printf("chaine lue par le père %s\n", chaine);

¯·° write(desc,"AB",2);

¯-± close(desc);

¯² }

¯³ printf("Fin du Programme\n");

¯-´ }

¯µ

°¶

gihXjk?lnmlojœÝÞqߋàvl¿Õxk?uwvxm|(¼UtImuwv{zxj!|á}xk?uloj!|(|(s|â}Tk¿jšjotㄅ|á}†¼ki…¼Álou¾äåäæ¼wvzxj

ç

¼wm=t

‡ˆ) * ‹Ó‰ 2&0Š 201‹13‹4—) 2‹TŒ"*Uwž‘X)’0«Ç‰c&0 w)’0)‚›U‰ 2&¨)2Ä"*3—+™˜Ãw——+™˜~0U"Æ#& 2 2“

è¿"53‰5‰c 2L!"Æ#&i‰02é•T¨)’ &ӝ”)&01313†‰ 132 «?§)*&0i3‰ &)›303"$#&0 2)5L‰0

"Æ#& 2&0) !*&0(

­ #include<unistd.h>

® #include<stdio.h>

¯ #include<errno.h>

° #include<string.h>

±²

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

³ {

´ pid_t pid;

µ int statut;

­·¶

­-­ if((argc==2) && (strcmp(argv[1],"synchro")!=0))

­$® {

­$¯ printf("Lancer le programme avec un argument:\n");

­¸° printf("\t Synchro pour afficher le fils puis le pere\n");

­$± printf("Aucun argument sinon. \n");

­-² }

­-³ else

­$´ {

­·µ system("clear");

®¶ printf("\n\t\t\tGENERATION AUTOMATIQUE DE PROCESSUS\n\n");

®­

®-® pid = fork();

®-¯ switch(pid)

®·° {

(4)

®-± case -1:

®² perror("erreur fork:\t");

®³ break;

®-´ case 0:

®µ sleep(1);

¯¶ printf("fils PID: %d \t PPID: %d\n", getpid(),getppid());

¯­ break;

¯-® default:

¯-¯ if((argc==2) && (strcmp(argv[1],"synchro")==0))

¯·° {

¯-± wait(&statut);

¯² printf("pere PID: %d \t PPID: %d\n", getpid(),getppid());

¯³ }

¯-´ else

¯µ {

°¶ printf("pere PID: %d \t PPID: %d\n", getpid(),getppid());

°2­ wait(&statut);} /* Eviter un processus zombie */

°™®

°™¯ }

°-° printf("\n\tFin du programme. PID: %d\n", getpid());

°™± }

°2² }

°2³

°™´

°µ

gihXjk?lnmlojMê q\ëìj!lnu¾sFÂ3k?jäæj!v¾tÔzÓí™svî}k?ulnj!|I|(s|nï™mv¾t¿jkI}k¿rot¿j!sFkÔ}k¿jäæmk¿jÑÂwjkŽð

|(muwv

‡ˆ) * U*2 2‰ 2 13‰"*w)&1‹10§¨ 2›

É

§1‹‰"›‰«"*«Š))«Ç*ñË=

­ #include <stdio.h>

® #include <errno.h>

¯ #include <unistd.h>

° #include <string.h>

±²

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

³ {

´ pid_t pid;

µ int i, statut, a;

­·¶ char commande[10];

­-­ strcpy(commande, "");

­$® while(strcmp(commande, "exit")!=0)

­$¯ {

­¸° printf("$");

­$± fflush(stdin);

­-² scanf("%s", commande);

­-³ pid = fork();

­$´ switch (pid)

­·µ {

®¶ case -1:

(5)

®­ perror("erreur de fork\n");

®-® exit(-1);

®-¯ case 0:

®·° printf("%s PPID = %d, PID = %d \n", commande, getppid(),getpid());

®-± if (strcmp(commande,"exit")!=0)

®² execlp(commande, commande, NULL);

®³ perror("execlp");

®-´

®µ //il ne faut pas que le fils continue

¯¶ exit(-1);

¯­ default:

¯-® pid = wait (&statut);

¯-¯ if (pid==-1)

¯·° perror("le wait");

¯-± else

¯² printf("processus zombi %d\n", pid);

¯³ }

¯-´ }

¯µ

°¶ printf ("\n \t tout est termine\n");

°2­

°™® }

gihXjk?lnmlojÑò qLócvytIjk¿}xk?rotIj!sxkìzj!sFhmäæjƒÂwjk?|(muwv

‡ˆ) * U*2 2‰ 2 ’"*"Ž46ŽŠ 2,46"*!0‰‰"*«"*! 2* 2)=2&o"*wô3

­ /*

® Petit interpreteur shell qui ne gere que les appels, les redirections et le &

¯ */

°±

#include <stdio.h>

² #include <stdlib.h>

³ #include <string.h>

´ #include <unistd.h>

µ #include <sys/wait.h>

­·¶

­-­ #define MAXSTR 1000

­$® #define MAXARGS 40

­$¯ #define PROMPT "> "

­¸°

­$± int

­-² main()

­-³ {

­$´ char s[MAXSTR], *ss, *ptr, *argv[MAXARGS];

­·µ int argc, i, j, shouldIwait=1;

®¶

®­ while (1) {

®-® printf("%s", PROMPT);

®-¯ if (fgets(s, MAXSTR, stdin) == NULL) {

®·° printf("bye...\n");

(6)

®-± exit(0);

®² }

®³ /* Recuperation de la ligne de commande et decomposition en mots */

®-´ ss = s;

®µ ptr = strtok(ss, " \t\n");

¯¶ for (argc=0 ; ptr!=NULL ; argc++) {

¯­ argv[argc] = ptr;

¯-® ptr = strtok(NULL, " \t\n");

¯-¯ }

¯·°

¯-± /* Recherche du & afin de savoir si lancement en arriere plan ou pas */

¯² for (i=1 ; i<argc ; i++)

¯³ if (!strcmp(argv[i], "&")) {

¯-´ shouldIwait = 0;

¯µ /* On considere que s’il y a des mots apres le & il s’agit d’ue erreur et on n’en tient pas compte.

°¶ Le comportement du shell dans ce cas est de considerer que le & est un separateur de commande ! */

°2­ argc = i;

°™® break;

°™¯ }

°-°

°™± if (argc == 0) /* ligne vide */

°2² continue;

°2³

°™´ switch (fork()) {

°µ

±¶ case -1:

±­ fprintf(stderr, "impossible de forker !\n");

±-® continue;

±-¯

±·° case 0:

±-± /* Analyse des arguments et gestion des redirections */

±² for (i=1 ; i<argc ;)

±³ if (!strcmp(argv[i], "<")) {

±-´ if (i == argc-1) {

±µ fprintf(stderr, "erreur de syntaxe\n");

²·¶ exit(1);

²-­ }

²$® if (freopen(argv[i+1], "r", stdin) == NULL) {

²$¯ fprintf(stderr, "impossible d’ouvrir le fichier \"%s\"\n", argv[i+1]);

²¸° exit(1);

²$± }

²-² for (j=i ; j+2<argc ; j++)

²-³ strcpy(argv[j], argv[j+2]);

²$´ argc -= 2;

²·µ } else if (!strcmp(argv[i], ">")) {

³·¶ if (i == argc-1) {

³-­ fprintf(stderr, "erreur de syntaxe\n");

³$® exit(1);

³$¯ }

³¸° if (freopen(argv[i+1], "w", stdout) == NULL) {

³$± fprintf(stderr, "impossible d’ecrire dans le fichier \"%s\"\n", argv[i+1]);

³-² exit(1);

³-³ }

³$´ for (j=i ; j+2<argc ; j++)

(7)

³·µ strcpy(argv[j], argv[j+2]);

´¶ argc -= 2;

´­ } else if (!strcmp(argv[i], ">>")) {

´-® if (i == argc-1) {

´-¯ fprintf(stderr, "erreur de syntaxe\n");

´·° exit(1);

´-± }

´² if (freopen(argv[i+1], "a", stdout) == NULL) {

´³ fprintf(stderr, "impossible d’ecrire dans le fichier \"%s\"\n", argv[i+1]);

´-´ exit(1);

´µ }

µ-¶ for (j=i ; j+2<argc ; j++)

µ™­ strcpy(argv[j], argv[j+2]);

µÆ® argc -= 2;

µÆ¯ } else i++;

µ$° argv[argc] = NULL;

µÆ± /* Recouvrement pour execution de la commande */

µ™² if (execvp(argv[0], argv) == -1) {

µ™³ fprintf(stderr, "impossible d’executer la commande \"%s\"", s);

µÆ´ exit(1);

µ-µ }

­·¶-¶

­·¶™­

default:

­·¶Æ®

/* Eventuellement bloquer en attente de la terminaison de la commande */

­·¶Æ¯

if (shouldIwait == 1)

­·¶$°

wait(NULL);

­·¶Æ±

/* Par defaut on bloque */

­·¶™²

shouldIwait = 1;

­·¶™³

}

­·¶Æ´

}

­·¶-µ

return 0;

­-­·¶

}

gihXjk?lnmlojæõ qLócvytIjk¿}xk?rotIj!sxkïLt(k?uwm|(mäæjƒÂwjk?|(muwv

‡ˆ) * U*2 2‰ 2 ’"*"Ž46ŽŠ 2Ä"*0‰‰c"5«"* 2* 2)=2&!"*!‰‰c

­ /*

® Petit interpreteur shell qui gere les appels, les redirections et les pipes

¯ Solution par rapport a la premiere version : on travaille avec un tableau de commandes

° coms et un tableau d’entiers argcoms qui donne le nombre de mots pour chaque commande

± (equivalents de argc et argv dans la premiere version mais avec une dimension de plus).

² */

³

´ #include <stdio.h>

µ #include <stdlib.h>

­·¶ #include <string.h>

­-­ #include <unistd.h>

­$® #include <sys/wait.h>

­$¯

­¸° #define MAXSTR 1000

(8)

­$± #define MAXCOM 10 /* nombre maximum de commandes par ligne */

­-² #define MAXARGS 40 /* nombre maximum de mots par commande */

­-³ #define PROMPT "> " /* invite de l’interpreteur */

­$´

­·µ int

®¶ main()

®­ {

®-® solution : fork recursivement de facon a ce que le pere soit la derniere commande

®-¯ char s[MAXSTR], *ss, *ptr, *argv[MAXCOM*MAXARGS], *coms[MAXCOM][MAXARGS];

®·° int argc, argcoms[MAXCOM], ncom, fd[MAXCOM][2], start, i, j, k, shouldIwait=1;

®-±

®² while (1) {

®³ printf("%s", PROMPT);

®-´ if (fgets(s, MAXSTR, stdin) == NULL) {

®µ printf("bye...\n");

¯¶ exit(0);

¯­ }

¯-® /* faire en sorte que chaque caractere special accepte (<,>,>>,|,&)

¯-¯ soit precede et suivi d’au moins un espace */

¯·° for (ptr=s ; *ptr!=’\0’ ; ptr++)

¯-± if (*ptr==’<’ || *ptr==’>’ || *ptr==’|’ || *ptr==’&’) {

¯² if (ptr[1] == ’>’) {

¯³ memmove(&ptr[3], &ptr[2], strlen(ptr));

¯-´ ptr[2] = ’ ’;

¯µ k = 2;

°¶ } else {

°2­ memmove(&ptr[2], &ptr[1], strlen(ptr));

°™® ptr[1] = ’ ’;

°™¯ k = 1;

°-° }

°™± memmove(&ptr[1], ptr, strlen(ptr)+1);

°2² *ptr = ’ ’;

°2³ ptr += k;

°™´ }

°µ printf("nouvelle commande : %s\n", s);

±¶

±­ /* Recuperation de la ligne de commande et decomposition en mots */

±-® ss = s;

±-¯ ptr = strtok(ss, " \t\n");

±·° for (argc=0 ; ptr!=NULL ; argc++) {

±-± argv[argc] = ptr;

±² ptr = strtok(NULL, " \t\n");

±³ }

±-´

±µ /* Recherche du & afin de savoir si lancement en arriere plan ou pas */

²·¶ for (i=1 ; i<argc ; i++)

²-­ if (!strcmp(argv[i], "&")) {

²$® shouldIwait = 0;

²$¯ /* On considere que s’il y a des mots apres le & il s’agit d’ue erreur et on n’en tient pas compte.

²¸° Le comportement du shell dans ce cas est de considerer que le & est un separateur de commande ! */

²$± argc = i;

²-² break;

²-³ }

²$´

(9)

²·µ if (argc == 0) /* ligne vide */

³·¶ continue;

³-­

³$® /* Gestion des pipe : detection des |, decomposition en plusieurs commandes et creation des pipes */

³$¯ ncom = 0; /* le nombre de commandes rencontrees */

³¸° start = i = 0;

³$±

³-² while (1) {

³-³ /* Recherche du prochain | et enregistrement de la commande courante dans coms */

³$´ for (; i<argc ; i++)

³·µ if (strcmp(argv[i], "|"))

´¶ coms[ncom][i-start] = argv[i];

´­ else break;

´-® argcoms[ncom] = i-start;

´-¯ ncom++;

´·° /* Si on est arrive a la fin de la ligne, la decomposition en commandes est terminee */

´-± if (i == argc)

´² break;

´³ i++;

´-´ start = i;

´µ }

µ-¶

µ™­ printf("%d commandes :\n", ncom);

µÆ® for (i=0 ; i<ncom ; i++) {

µÆ¯ for (j=0 ; j<argcoms[i] ; j++)

µ$° printf("%s ", coms[i][j]);

µÆ± printf("\n");

µ™² }

µ™³

µÆ´ /* Creation des pipes afin de faire communiquer les differentes commandes */

µ-µ for (i=1 ; i<ncom ; i++)

­·¶-¶

if (pipe(fd[i-1]) == -1) {

­·¶™­

fprintf(stderr, "erreur lors de la creation d’un pipe\n");

­·¶Æ®

exit(1);

­·¶Æ¯

}

­·¶$°

­·¶Æ±

/* Creation des processus fils et redirection des entrees/sorties standard

­·¶™²

afin de mettre en communication les commandes via les pipes */

­·¶™³

­·¶Æ´

for (i=0 ; i<ncom ; i++)

­·¶-µ

switch (fork()) {

­-­·¶

­-­-­

case -1:

­-­$®

fprintf(stderr, "impossible de forker !\n");

­-­$¯

continue;

­-­¸°

­-­$±

case 0:

­-­-²

printf("%d: le fils i=%d argcoms[i]=%d\n", getpid(), i, argcoms[i]);

­-­-³

for (j=0 ; j<argcoms[i] ; j++)

­-­$´

printf("%d: _%s_\n", getpid(), coms[i][j]);

­-­·µ

/* Redirection de l’entree standard pour les commandes autres que la premiere */

­$®¶ if (i > 0)

­$®­ {printf("%d: je duplique le descripteur %d\n", getpid(), fd[i-1][0]);

­$®-®

if (dup2(fd[i-1][0], STDIN_FILENO) == -1) {

(10)

­$®-¯

fprintf(stderr, "commande %d : impossible de rediriger l’entree standard dans le pipe no %d\n", i, i-1);

­$®·°

exit(1);

­$®-±

}

­$®² }

­$®³ /* Redirection de la sortie standard pour les commandes autres que la derniere */

­$®-´

if (i < ncom-1)

­$®µ {printf("%d: je duplique le descripteur %d\n", getpid(), fd[i][1]);

­$¯¶ if (dup2(fd[i][1], STDOUT_FILENO) == -1) {

­$¯­ fprintf(stderr, "commande %d : impossible de rediriger l’entree standard dans le pipe no %d\n", i, i);

­$¯-®

exit(1);

­$¯-¯

}

­$¯·°

}

­$¯-±

/* Analyse des arguments, gestion des redirections et du lancement en arriere plan */

­$¯² /* Remarque : on ne fait pas de controle d’erreur si la commande implique une redirection */

­$¯³ for (j=1 ; j<argcoms[i] ;)

­$¯-´

if (!strcmp(coms[i][j], "<")) {

­$¯µ if (j == argcoms[i]-1) {

­¸°¶ fprintf(stderr, "erreur de syntaxe\n");

­¸°2­

exit(1);

­¸°™®

}

­¸°™¯

if (freopen(coms[i][j+1], "r", stdin) == NULL) {

­¸°-°

fprintf(stderr, "impossible d’ouvrir le fichier \"%s\"\n", coms[i][j+1]);

­¸°™±

exit(1);

­¸°2²

}

­¸°2³

for (k=j ; k+2<argcoms[i] ; k++)

­¸°™´

strcpy(argv[k], argv[k+2]);

­¸°µ argcoms[i] -= 2;

­$±¶ } else if (!strcmp(coms[i][j], ">")) {

­$±­ if (j == argcoms[i]-1) {

­$±-®

fprintf(stderr, "erreur de syntaxe\n");

­$±-¯

exit(1);

­$±·°

}

­$±-±

if (freopen(coms[i][j+1], "w", stdout) == NULL) {

­$±² fprintf(stderr, "impossible d’ecrire dans le fichier \"%s\"\n", coms[i][j+1]);

­$±³ exit(1);

­$±-´

}

­$±µ for (k=j ; k+2<argcoms[i] ; k++)

­-²·¶

strcpy(argv[k], argv[k+2]);

­-²-­

argcoms[i] -= 2;

­-²$®

} else if (!strcmp(coms[i][j], ">>")) {

­-²$¯

if (j == argcoms[i]-1) {

­-²¸°

fprintf(stderr, "erreur de syntaxe\n");

­-²$±

exit(1);

­-²-²

}

­-²-³

if (freopen(coms[i][j+1], "a", stdout) == NULL) {

­-²$´

fprintf(stderr, "impossible d’ecrire dans le fichier \"%s\"\n", coms[i][j+1]);

­-²·µ

exit(1);

­-³·¶

}

­-³-­

for (k=j ; k+2<argcoms[i] ; k++)

­-³$®

strcpy(argv[k], argv[k+2]);

­-³$¯

argcoms[i] -= 2;

­-³¸°

} else j++;

­-³$±

coms[i][argcoms[i]] = NULL;

­-³-²

/* Recouvrement pour execution de la commande */

(11)

­-³-³

if (execvp(coms[i][0], coms[i]) == -1) {

­-³$´

fprintf(stderr, "impossible d’executer la commande \"%s\"", coms[i][0]);

­-³·µ

exit(1);

­$´¶ }

­$´­

­$´-®

default:

­$´-¯

/* Si pas de & detecte, lorsque tous les fils ont ete crees, bloquer en attente de leur terminaison */

­$´·°

if (i == ncom) {

­$´-±

if (shouldIwait == 1)

­$´² wait(NULL);

­$´³ /* Par defaut on bloque */

­$´-´

shouldIwait = 1;

­$´µ }

­·µ-¶

}

­·µ™­

}

­·µÆ®

return 0;

­·µÆ¯

}

Références