France Hardware : Forums de discussion
Retrouvez les prix près de chez vous :  
Index du forum | Liste des membres | Liste des groupes | Inscription | F-A-Q | Recherche
Pseudo :    Password :     
22 343 membres enregistrés - 1 872 934 posts - 95 152 topics
Index des forums FH  | Index des forums DegroupNews
      Programmation
           Sujets divers
                [C] faire un minishell (Urgent, rendu dans 12h)
41 connectés(record : 207 le 05 juin 2007 - 05 h 23)

Vous devez vous connecter pour répondre au topic.
1,2,3,4 | Suivant
[C] faire un minishell (Urgent, rendu dans 12h)

Woofy
Pour les bons tuyaux me demander

Messages : 26 018
Inscrit le 11/01/02
Ville : Paris / Grenoble
Non connecté
  Posté le 18 novembre 2004 - 20 h 55 m 09 s
Bon, pas besoin d'un long discours :



Description : vous devez programmer un mini interpreteur de commande. Cet
interpreteur de commande doit afficher un prompt et attendre
que vous tapiez une ligne de commande. Une ligne de commande
est validee par un retour a la ligne.
Le prompt n'est de nouveau affiche qu'apres la fin de
l'execution de la commande.

Contraintes: - vous n'avez le droit d'utiliser que execve, parmi
la famille des exec* (DONC interdiction des exec*p)
- vous devez gerer l'environnement et faire les builtins
"pwd", "cd", "rehash", "where", "which", "printenv",
"setenv", "unsetenv", "exec", "logout", "exit".


On doit egalement gerer les binaires du systeme.

Bon, par ou commencer?
Par la justement : ou est mon erreur dans le code suivant? Il semble faire une boucle infinie (et avec le fork, c'est pas genial)




int exec_com(int ac, char **av, list_t **head)
{
int i;
int builtin;
int cell;
elem_t *current;
char *command;

builtin = 0;
for (i = 0; tab[i].com; i++)
{
if (my_strcmp(av[0], tab[i].com) == 0)
{
tab[i].f(ac, av);
builtin = 1;
}
}
if (!builtin)
{
if (fork())
{
cell = my_hash(av[0]) % TAB_HASH_SIZE;
current = head[cell]->begin;
while (current && (current->data)->com != av[0])
current = current->next;
if (!current)
{
my_putstr(av[0]);
my_putstr(" : Command not found\n");
return (0);
}
else
{
command = my_strcat(my_strcat(current->data->rep, "/"), av[0]);
my_putstr(command);
if (execve(command, av, environ) == -1)
{
my_putstr(av[0]);
my_putstr(" : Error in execution of command!");
return (0);
}
return (1);
}
}
else
wait();
my_putstr("Command not found\n");
}
return (0);
}


La fonction my_hash :




int my_hash(char *str)
{
int i;
int res;

i = 0;
res = 0;
while (str[i])
res += str[i++];
return (res);
}


La fonction my_strcmp fait la meme chose que strcmp.

La fonction my_putstr affiche la string correspondante.

Dans le code commente, ca ne marche pas.
Il faut prendre en compte le fait que le tableau de liste passe est surement mauvais, mais dans ce cas la il ne devrais pas faire ca.

PS : les balises CODE ne marchent pas???


Message édité 2 fois, la dernière par Woofy le 18 novembre 2004 - 20 h 58.

:smileymouth: Totalement inutile, donc completement indispensable :smileymouth:

:sms:


bernie38
Waldorf (le pote à Statler)

Messages : 11 393
Inscrit le 28/08/03
Ville : Claix
Non connecté
  Posté le 18 novembre 2004 - 20 h 57 m 24 s
ben y'a rien dans ton message ?



La Montagne n'est pas dangereuse : on ne peut qu'y perdre la vie, tandis qu'en ville on devient bête et méchant
Voltaire


Woofy
Pour les bons tuyaux me demander

Messages : 26 018
Inscrit le 11/01/02
Ville : Paris / Grenoble
Non connecté
  Posté le 18 novembre 2004 - 20 h 59 m 18 s
Les balises code me font tout planter. bizarre!

Bon, je te laisse potasser! :D



:smileymouth: Totalement inutile, donc completement indispensable :smileymouth:

:sms:


bernie38
Waldorf (le pote à Statler)

Messages : 11 393
Inscrit le 28/08/03
Ville : Claix
Non connecté
  Posté le 18 novembre 2004 - 21 h 04 m 51 s
encore du C :hot: moi qui croyais que c'était du shell, du vrai... là, c'est programmer un interpréteur. Elle est où la fameuse boucle infinie ? tu l 'as localisée ?



La Montagne n'est pas dangereuse : on ne peut qu'y perdre la vie, tandis qu'en ville on devient bête et méchant
Voltaire


Woofy
Pour les bons tuyaux me demander

Messages : 26 018
Inscrit le 11/01/02
Ville : Paris / Grenoble
Non connecté
  Posté le 18 novembre 2004 - 21 h 07 m 45 s
J'te l'avais dit!

Le shell, on l'a fait en 2 jours.

Le probleme viendrais d'ici :

if (fork())
{
cell = my_hash(av[0]) % TAB_HASH_SIZE;
current = head[cell]->begin;
while (current && (current->data)->com != av[0])
current = current->next;
if (!current)
{
my_putstr(av[0]);
my_putstr(" : Command not found\n");
return (0);
}
else
{
command = my_strcat(my_strcat(current->data->rep, "/"), av[0]);
my_putstr(command);
if (execve(command, av, environ) == -1)
{
my_putstr(av[0]);
my_putstr(" : Error in execution of command!");
return (0);
}
return (1);
}
}
else
wait();



:smileymouth: Totalement inutile, donc completement indispensable :smileymouth:

:sms:


bernie38
Waldorf (le pote à Statler)

Messages : 11 393
Inscrit le 28/08/03
Ville : Claix
Non connecté
  Posté le 18 novembre 2004 - 21 h 12 m 36 s
ah, merde, j'ai pas d'unix sous la main sinon j'aurais bien tenté. Et puis le fork, c'est un peu délicat à manier, tu as regardé un peu sur le net ? ou le man ?
est-ce que le fork te rend un PID (le PID du fils, celui qui est forké) ?
et le débug tu peux le lancer ?

En fait, j'ai l'impression que tu n'as pas posté la totalité du code, et je comprends pas tout ce qui est fait :(



La Montagne n'est pas dangereuse : on ne peut qu'y perdre la vie, tandis qu'en ville on devient bête et méchant
Voltaire


Woofy
Pour les bons tuyaux me demander

Messages : 26 018
Inscrit le 11/01/02
Ville : Paris / Grenoble
Non connecté
  Posté le 18 novembre 2004 - 21 h 13 m 27 s
Disons qu'en fait, le probleme que j'ai c'est que ce bout de code me sature la machine : la fork doit tourner en boucle, au bout d'un moment il m'affiche mon "prompt $>" en boucle, impossible de faire Ctrl C, si je fait ps sur un autre term il me dit No more process, et si je ne fait pas un kill -9 -1 la machine plante en m'affichant en boucle un magnifique Out of swap (et la, y a plus que reset qui marche)


Bon, la je sais pas ce que j'ai fait, mais ce qui marchait avant ne marche plus.
Mais alors plus du tout!



:smileymouth: Totalement inutile, donc completement indispensable :smileymouth:

:sms:


Woofy
Pour les bons tuyaux me demander

Messages : 26 018
Inscrit le 11/01/02
Ville : Paris / Grenoble
Non connecté
  Posté le 18 novembre 2004 - 21 h 15 m 17 s


Le 18 novembre 2004 - 21 h 12, bernie38 a écrit :
ah, merde, j'ai pas d'unix sous la main sinon j'aurais bien tenté. Et puis le fork, c'est un peu délicat à manier, tu as regardé un peu sur le net ? ou le man ?
est-ce que le fork te rend un PID (le PID du fils, celui qui est forké) ?
et le débug tu peux le lancer ?

En fait, j'ai l'impression que tu n'as pas posté la totalité du code, et je comprends pas tout ce qui est fait :(


Non j'ai pas tout mis, je doit avoir pas loin d'une dizaine de fichiers, et sous emacs c'est chiant a recuperer. De plus, ca surchargerais beaucoup la page.

Non mais je sais pas si je vais pas laisser tomber! Proche du but, et encore si loin!

Oui, le fork est delicat a manier. Mais ce que je ne comprend pas, c'est qu'il devrait sortir du fork.



:smileymouth: Totalement inutile, donc completement indispensable :smileymouth:

:sms:


Woofy
Pour les bons tuyaux me demander

Messages : 26 018
Inscrit le 11/01/02
Ville : Paris / Grenoble
Non connecté
  Posté le 18 novembre 2004 - 21 h 16 m 56 s
Mon main :



int main()
{
char *s;
char **tab_params;
int tablen;
list_t **path;

path = make_list_path();
while (1)
{
my_putstr("prompt $>");
s = my_read();
if (s)
{
tab_params = my_str_to_wordtab(s);
tablen = my_tablen(tab_params);
if (s && my_strcmp(tab_params[0], "exit") == 0)
break;
else
exec_com(tablen, tab_params, path);
free(tab_params);
}
}
free(path);
return (0);
}




:smileymouth: Totalement inutile, donc completement indispensable :smileymouth:

:sms:


Woofy
Pour les bons tuyaux me demander

Messages : 26 018
Inscrit le 11/01/02
Ville : Paris / Grenoble
Non connecté
  Posté le 18 novembre 2004 - 21 h 19 m 46 s
Le make_list_path :



list_t **make_list_path()
{
list_t **head;
int i;
int j;
int count;
char result[500];
char *path;
char *tmp;

path = get_env("PATH");
// printf("%s\n", path);
head = malloc(sizeof(*head) * (TAB_HASH_SIZE + 1));
for (i = 0; i < TAB_HASH_SIZE; i++)
head[i] = ll_create();
head[i] = 0;
j = 0;
count = 0;
for (i = 0; path[i]; i++)
{
if (path[i] == ':')
{
result[j] = '\0';
// tmp = strdup(result);
my_putstr(tmp);
make_list_com(head, tmp);
j = 0;
i++;
}
result[j++] = path[i];
}
result[j] = '\0';
tmp = my_strdup(result);
make_list_com(head, tmp);
head[TAB_HASH_SIZE] = 0;
// aff_list_path(head);
return (head);
}



et le make_list_com :



int my_hash(char *str)
{
int i;
int res;

i = 0;
res = 0;
while (str[i])
res += str[i++];
return (res);
}

void make_list_com(list_t **head, char *path)
{
elem_t *current;
DIR *d;
struct dirent *com;
int cell;
path_t *data;

d = 0;
d = opendir(path);
//printf("Path = %s\n", path);
while (d && (com = readdir(d)))
{
// printf("com = %s\n", com->d_name);
if (!(opendir(com->d_name)))
{
cell = my_hash(com->d_name) % TAB_HASH_SIZE;
data = malloc(sizeof(*data));
data->rep = path;
data->com = com->d_name;
// printf("comwrite = %s\n", com->d_name);
ll_add(head[cell], data);
}
}
if (d)
closedir(d);
}


le get_env :



void print_no_var(char *var)
{
my_putstr("Environment variable ");
my_putstr(var);
my_putstr(" unknown\n");
return;
}

char *get_env(char *var)
{
int varlen;
int i;
int j;
char path[500];
char res[500];

varlen = my_strlen(var);
for (i = 0; environ[i] && my_strncmp(environ[i], var, varlen) != 0; i++)
;
if (!environ[i])
print_no_var(var);
my_strcpy(path, environ[i]);
j = 0;
for (i = varlen + 1; path[i]; i++)
res[j++] = path[i];
res[j] = '\0';
// printf("%s\n", res);
return (res);
}



Message édité 1 fois, la dernière par Woofy le 18 novembre 2004 - 21 h 21.

:smileymouth: Totalement inutile, donc completement indispensable :smileymouth:

:sms:


bernie38
Waldorf (le pote à Statler)

Messages : 11 393
Inscrit le 28/08/03
Ville : Claix
Non connecté
  Posté le 18 novembre 2004 - 21 h 19 m 57 s


Le 18 novembre 2004 - 21 h 15, Woofy a écrit :

Non j'ai pas tout mis, je doit avoir pas loin d'une dizaine de fichiers, et sous emacs c'est chiant a recuperer. De plus, ca surchargerais beaucoup la page.

Non mais je sais pas si je vais pas laisser tomber! Proche du but, et encore si loin!

Oui, le fork est delicat a manier. Mais ce que je ne comprend pas, c'est qu'il devrait sortir du fork.

sortir du fork ? mais quand tu fais fork(), ça te crée un process fils identique au père, qui vit sa vie ! donc, pour le terminer, il doit y avoir un exit quelque part, ça se finit pas à la dernière instruction comprise dans le fork(){} !

EDIT : un lien sur une man page http://www.scit.wlv.ac.uk/cgi-bin/mansec?2+fork
ça peut servir !


Message édité 1 fois, la dernière par bernie38 le 18 novembre 2004 - 21 h 21.

La Montagne n'est pas dangereuse : on ne peut qu'y perdre la vie, tandis qu'en ville on devient bête et méchant
Voltaire


Woofy
Pour les bons tuyaux me demander

Messages : 26 018
Inscrit le 11/01/02
Ville : Paris / Grenoble
Non connecté
  Posté le 18 novembre 2004 - 21 h 21 m 31 s
un exit ou un return?



:smileymouth: Totalement inutile, donc completement indispensable :smileymouth:

:sms:


bernie38
Waldorf (le pote à Statler)

Messages : 11 393
Inscrit le 28/08/03
Ville : Claix
Non connecté
  Posté le 18 novembre 2004 - 21 h 23 m 28 s


Le 18 novembre 2004 - 21 h 21, Woofy a écrit :
un exit ou un return?

disons un exit, mais un return doit avoir le même effet... enfin, je crois, faudrait que je jette un oeil sur un ou 2 prog que j'ai écrit y'a longtemps, mais ce sera demain matin, donc trop tard :(



La Montagne n'est pas dangereuse : on ne peut qu'y perdre la vie, tandis qu'en ville on devient bête et méchant
Voltaire


Woofy
Pour les bons tuyaux me demander

Messages : 26 018
Inscrit le 11/01/02
Ville : Paris / Grenoble
Non connecté
  Posté le 18 novembre 2004 - 21 h 25 m 26 s
ben disons que j'avais fait un return sur un ptit programme simple, ca sortais. (genre :
if (!fork())
my_putstr("fils");
return;
else
wait()
my_putstr("pere");
}



:smileymouth: Totalement inutile, donc completement indispensable :smileymouth:

:sms:


Woofy
Pour les bons tuyaux me demander

Messages : 26 018
Inscrit le 11/01/02
Ville : Paris / Grenoble
Non connecté
  Posté le 18 novembre 2004 - 21 h 27 m 35 s
Bon ben en fait c'etait exit, enfin c'est ce qu'on me dit dans l'oreillette.

Maintenant, c'est mon tableau de liste et ma fonction de hashage qui deconnem mais je sais pas ce que ca fait.
Bon, je vais te laisser la, moi vais essayer de finir tout seul, mais je perd espoir! :(



:smileymouth: Totalement inutile, donc completement indispensable :smileymouth:

:sms:


bernie38
Waldorf (le pote à Statler)

Messages : 11 393
Inscrit le 28/08/03
Ville : Claix
Non connecté
  Posté le 18 novembre 2004 - 21 h 30 m 34 s


Le 18 novembre 2004 - 21 h 25, Woofy a écrit :
ben disons que j'avais fait un return sur un ptit programme simple, ca sortais. (genre :
if (!fork())
my_putstr("fils");
return;
else
wait()
my_putstr("pere");
}

if (!fork()) --> sémantiquement, c'est pas très juste parce que fork() retourne un pid et pas un booleen (qui n'existe pas en C, sauf en C99 je crois)

et if (!fork()) veut dire que fork() échoue, non ? Si c'est ça, ton test serait inversé. Tiens, regarde ça (surtout ce qui est en gras) :


Upon successful completion, fork() and fork1() return 0 to
the child process
and return the process ID of the child
process to the parent process.
Otherwise, (pid_t)-1 is
returned to the parent process, no child process is created,
and errno is set to indicate the error.



La Montagne n'est pas dangereuse : on ne peut qu'y perdre la vie, tandis qu'en ville on devient bête et méchant
Voltaire


Woofy
Pour les bons tuyaux me demander

Messages : 26 018
Inscrit le 11/01/02
Ville : Paris / Grenoble
Non connecté
  Posté le 18 novembre 2004 - 21 h 33 m 32 s
Return 0 : donc dans ce cas il est considere comme nul et la condition !fork() est verifiee.
Sisi ca passe, on l'utilise partout.

Sinon je pourrais faire :

if ((pid = fork) == 0) ca reviens au meme



:smileymouth: Totalement inutile, donc completement indispensable :smileymouth:

:sms:


bernie38
Waldorf (le pote à Statler)

Messages : 11 393
Inscrit le 28/08/03
Ville : Claix
Non connecté
  Posté le 18 novembre 2004 - 21 h 34 m 34 s


Le 18 novembre 2004 - 21 h 27, Woofy a écrit :
Bon ben en fait c'etait exit, enfin c'est ce qu'on me dit dans l'oreillette.

Maintenant, c'est mon tableau de liste et ma fonction de hashage qui deconnem mais je sais pas ce que ca fait.
Bon, je vais te laisser la, moi vais essayer de finir tout seul, mais je perd espoir! :(

la fonction de hash :


int my_hash(char *str)
{
int i;
int res;

i = 0;
res = 0;
while (str[i])
res += str[i++];
return (res);
}

je comprends pas ce que tu veux faire. Elle renvoie dans un int le dernier caractère de la chaine str, c'est ça ? Elle sert à quoi ?



La Montagne n'est pas dangereuse : on ne peut qu'y perdre la vie, tandis qu'en ville on devient bête et méchant
Voltaire


bernie38
Waldorf (le pote à Statler)

Messages : 11 393
Inscrit le 28/08/03
Ville : Claix
Non connecté
  Posté le 18 novembre 2004 - 21 h 36 m 16 s


Le 18 novembre 2004 - 21 h 33, Woofy a écrit :
Return 0 : donc dans ce cas il est considere comme nul et la condition !fork() est verifiee.
Sisi ca passe, on l'utilise partout.

Sinon je pourrais faire :

if ((pid = fork) == 0) ca reviens au meme

mais c'est le process fils qui reçoit 0 si ça marche, le process père reçoit le pid du fils. C'est bien comme ça que tu le comprends ? Et que tu l'utilises ?

bon, là c'est beaucoup plus que du "simple" C, c'est carrément du système ! c'est super intéressant, mais ça embarque vraiment loin !



La Montagne n'est pas dangereuse : on ne peut qu'y perdre la vie, tandis qu'en ville on devient bête et méchant
Voltaire


Erel69
206
(¯`·.__[T3aM.L1b3rTe©]__.·´¯)

Messages : 19 449
Inscrit le 07/11/01
Ville : Lyon
Non connecté
  Posté le 18 novembre 2004 - 21 h 37 m 00 s
déjà ajouter du char avec du int c'est normal ?



Obscurité au-delà du crépuscule, pourpre au-delà du sang qui coule, enfoui dans le flot du temps, en ton haut nom, je jure fidélité à l'obscurité. Que les fous qui se dressent devant nous soient détruits, par le pouvoir que toi et moi possédons...

1,2,3,4 | Suivant
Page genérée en 3.3955 secondes par RahForum 2.0 | Gzip off |  Stats |  Metaforums |  RSS
© 2004 Cerbere Systems.
Prix Matériel Informatique | Informatique Lyon | Informatique Grenoble | Informatique Annecy | Informatique Marseille | Informatique Bordeaux | Forum Informatique
ADSL |Actualité ADSL | e-commerce | Commande Au Volant
Creative Commons
Message Boards and Forums Directory