186 lines
5.2 KiB
Markdown
186 lines
5.2 KiB
Markdown
## todo list :
|
|
|
|
- **builtins**
|
|
- echo
|
|
- [builtins] echo -n
|
|
- [builtins] cd <relative path>
|
|
- [builtins] cd <absolute path>
|
|
- [builtins] pwd
|
|
- [builtins] export
|
|
- [builtins] unset
|
|
- [builtins] env
|
|
- [builtins] exit
|
|
- ' _ignore any special characters_ [ressource](https://linuxhandbook.com/quotes-in-bash/){:target="_blank"}
|
|
- " _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.
|
|
|