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?jjot~ |
) * U 2&0 20113U46() 2,"5
✓ 'U )I5"* U13&0+w**!13&0+*
✓ ',"5X)I0*"*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½¾jzj!|~¼Utt¿m=ÀsFtI|~jotÁlou}mj!|~zj!|ÃÂļwk¿m¼wÀ j!|
! 2x"*L 2&0 20113)Å·F)&013"*2 iX)063"Æ#*«"L*Ç«X"L)&066iÇ#L 25©"*F§
*È2*0"5¢
ƒ
6!",./& ÊËn13&w"&F§Ì,Íy !"*U"5"*&0x§ÎÏy !"*U
#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!|Ilk?m=}xtIj!sxk¿|Rzxjl?Õmjk?|
) * !X 2&00 1313!46&¨ !X)* &1313Ä&0&y«0X"*)=2 2) 2È2 20«&06"*)&2¨"5wÈ2
ª¬ ÍÖ¨Ï×6ØÙ0Ú0'U 2&0 20113./&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);
®-® 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|â}Tk¿jjotã |á}¼ki ¼Álou¾äåäæ¼wvzxj
ç
¼wm=t
) * Ó 2&0 201134) 2T"*UwX)0«Çc&0 w)0)U 2&¨)2Ä"*3+Ãw+~0U"Æ#& 2 2
è¿"535c 2L!"Æ#&i02éT¨) &Ó)&01313 132 «?§)*&0i3 &)303"$#&0 2)5L0
"Æ#& 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)
®·° {
®-± 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äæmk¿jÑÂwjkð
|(muwv
) * U*2 2 2 13"*w)&110§¨ 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:
® 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");
®-± 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++)
³·µ 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Ä"*0c"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
$± #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;
²-³ }
²$´
²·µ 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) {
$®-¯
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 */
-³-³
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;
·µÆ¯
}