diff --git a/README.md b/README.md index 83139e8..bd28a1a 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,184 @@ -## title +## todo list : -
- Advanced Topics -
+- [] [builtins] echo +- [] [builtins] echo -n +- [] [builtins] cd +- [] [builtins] cd +- [] [builtins] pwd +- [] [builtins] export +- [] [builtins] unset +- [] [builtins] env +- [] [builtins] exit +- [] ' _ignore any special characters_ [ressource](https://linuxhandbook.com/quotes-in-bash/) +- [] " _ignore any special characters except '$'_ +- [] +- [] +- [] +- [] +- [] +- [] +- [] +- [] +- [] +- [] + +--- + +Ordre Interpreteur : +1) Couper les mots (comment faire ? je ne vois pas comment gerer ce genre de bordel ci dessous) +``` +shell@prompt> ./arg_test 'mot1 '$NAME" mot2" + argc = 2 + argv[0] = |./arg_test| + argv[1] = |mot1 Tour-Lemdows10 mot2| +shell@prompt> +``` +2) $ - Env Vars Expand. if $VAR not set, expand to nothing(""). + Dont save it as "" argument for fonctions, just delete. + +-------------- + +Commandes dans variables d'env fonctionne : +``` +shell@prompt> export VAR_TEST="echo" +shell@prompt> $VAR_TEST "string :)" +string :) +shell@prompt> +``` +-------------- + +l'expension des variables dans des variables est fait au moment de export(), +donc pas de recursivité infini et de prise de tête au moment de l'interpretation. +Il suffit de faire "une passe" pour dévelloper les variables, +aucun besoin de refaire des passes succesives pour d'éventuels nouvelles variables aprés dévellopement : + +``` +export : + export VAR_TEST="test $NAME" +dans l'env : + NAME="Tour-Lemdows10" + VAR_TEST="test Tour-Lemdows10" + +export : + export NAME="Un nouveau nom" +dans l'env : + NAME="Un nouveau nom" + VAR_TEST="test Tour-Lemdows10" +``` +``` +export : + export VAR_TEST="test $VAR_TEST" +dans l'env : + VAR_TEST="test test Tour-Lemdows10" + +export : + export VAR_TEST="test $VAR_TEST" +dans l'env : + VAR_TEST="test test test Tour-Lemdows10" +``` + +------------------- + +Tests pour Hugo, pour illustrer les pipes simultanés : +``` +sleep 3 ; sleep 3 ; sleep 3 ; sleep 3 +sleep 3 | sleep 3 | sleep 3 | sleep 3 + +sleep 5 ; ls | wc -l +sleep 5 | ls | wc -l +``` + +------------------- + +argv passé à execv(), telle quelle ou aprés avoir trouvé le PATH ? +exemple, si j'apelle "cat file.txt", dans un shell genre bash/zsh, +la commande cat recoit t'elle : +``` +argv[0] == "cat" +argv[1] == "file.txt" +``` +OU +``` +argv[0] == "/bin/cat" +argv[1] == "file.txt" +``` + +------------------- + +A test sur bash et minishell : + + echo "phrase quelquonque" > file1 > file2 > file3 + +------------------- + +Pour les builtins dans une commande simple : +1) detecter la commande builtin +2) Ne pas fork() et execv(). + A la place, chercher la fonction aproprié dans un tableau contenant les pointeurs vers les fonctions builtins. + Puis appeler la fonction dans le genre : builtin(ft_arrlen(cmd->argv), cmd->argv, &c). + + +Pour les builtins dans une commande complexe (pipes, redirections, here doc, ...) : +1) detecter la commande builtin +2) fork() +3) Ne pas execv(). + A la place, chercher la fonction aproprié dans un tableau contenant les pointeurs vers les fonctions builtins. + Puis appeler la fonction dans le genre : builtin(ft_arrlen(cmd->argv), cmd->argv, &c). +4) aprés la fin de la commande, free toute la mémoire du sous_processus, puis quitter le sous_processus en renvoyant le return de la commande builtin. +par exemple comme ça : + free_exit(&c, builtin(ft_arrlen(cmd->argv), cmd->argv, &c)) + + +Peut-être faire un champ "void *builtin_command" dans une struct "cmd" pour contenir l'adresse de la fonction builtin. +``` +typedef struct s_cmd +{ + char **argv; + pid_t pid; + void *builtin_command; +} t_cmd; +``` +Si la commande n'est pas builtin + + cmd->builtin_command == NULL. + +------------------- + +tester comment ce comporte minishell aprés le crash d'une commande (message sigfault comme dans bash ? Autres ?) + +------------------- + +Implementer les exit status dans les builtins + +------------------- + +EDIT : Aprés reflexion et verification, ça semble en effet le mieux a faire. +En l'etat le return de la derniere fonction marche correctement, j'ai verifier pas de problemes. +Si le child est deja fini avant l'apelle de wait, ça return quand même. +Cependant, pour optimiser la liberation des resources dés que possible, +il semble plus logique de liberer les sous_processus dés qu'ils ont terminés, +et donc, pas nécessairement dans l'ordre de la pipeline. +Donc, un waitpid() sur la derniere commande pour sauvegarder le retour, +puis wait() pour les autres, l'ordre n'ayant plus d'importance. + +Revoir le wait() de mon pipex. Il n'est peut être pas correct. +En effet, j'attend que le premier process se ferme avec waitpid(), puis le deuxiéme, le troisiéme, ... +Mais en faite, il vaudrait peut être mieux attendre qu'un sous process QUELQUONQUE se ferme, puis le suivant, et le suivant, ... + +Vu le fonctionnement des pipes, je crois que ce n'est pas toujours la premiere commande qui ce termine en premier, +et donc, qu'il ne faudrait pas attendre la fin de la premiere commande en particulier, +mais d'une commande QUELQUONQUE avec wait() plutot que waitpid(). + +IDÉE : +Attendre avec waitpid() la derniere commande pour obtenir son status, puis wait() en boucle les autres commandes, +et enfin renvoyer le status. + +------------------- + +Faire des test avec + + "env -i ./minishell" +pour voir si ça ne crash pas. + +Normal si le comportement attendu n'est pas correct (en l'absence de PATH et tout ça) mais ça ne devrait pas crasher pour autant. -**done** diff --git a/ressources/parsing.md b/ressources/parsing.md new file mode 100644 index 0000000..0ef6fa7 --- /dev/null +++ b/ressources/parsing.md @@ -0,0 +1 @@ +https://raw.githubusercontent.com/kukinpower/minishell/master/images/3.png diff --git a/ressources/parsing.png b/ressources/parsing.png new file mode 100644 index 0000000..d6ef34e Binary files /dev/null and b/ressources/parsing.png differ