1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
|
/*
============================================================================
Name : test.c
Author :
Version : septembre 28
Copyright : Your copyright notice
Description : Shell, Ansi-style
============================================================================
*/
/* en-tetes standard */
#include <sys/types.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h> /* pour avoir wait & co. */
#include <ctype.h> /* pour avoir isspace & co. */
#include <string.h>
#include <errno.h> /* pour avoir errno */
char ligne[4096]; /* contient la ligne d'entrée */
void affiche_invite()
{
printf("> ");
fflush(stdout);
}
void lit_ligne()
{
if (!fgets(ligne,sizeof(ligne)-1,stdin)) {
/* ^D ou fin de fichier => on quittte */
printf("\n");
exit(0);
}
}
/* attent la fin du processus pid */
void attent(pid_t pid)
{
/* il faut boucler car waitpid peut retourner avec une erreur non fatale */
while (1) {
int status;
int r = waitpid(pid,&status,0); /* attente bloquante */
if (r<0) {
if (errno==EINTR) continue; /* interrompu => on recommence Ã* attendre */
printf("erreur de waitpid (%s)\n",strerror(errno));
break;
}
if (WIFEXITED(status))
printf("terminaison normale, status %i\n",WEXITSTATUS(status));
if (WIFSIGNALED(status))
printf("terminaison par signal %i\n",WTERMSIG(status));
break;
}
}
/* execute la ligne */
void execute()
{
pid_t pid;
/* supprime le \n final */
if (strchr(ligne,'\n')) *strchr(ligne,'\n') = 0;
/* saute les lignes vides */
if (!strcmp(ligne,"")) return;
pid = fork();
if (pid < 0) {
printf("fork a échoué (%s)\n",strerror(errno));
return;
}
if (pid==0) {
/* fils */
execlp(ligne, /* programme Ã* exécuter */
ligne, /* argv[0], par convention le nom de programme exécuté */
NULL /* pas d'autre argument */
);
/* on n'arrive ici que si le exec a échoué */
printf("impossible d'éxecuter \"%s\" (%s)\n",ligne,strerror(errno));
exit(1);
}
else {
/* père */
attent(pid);
}
}
int main()
{
/* boucle d'interaction */
while (1) {
affiche_invite();
lit_ligne();
execute();
}
return 0;
} |
Partager