bibic

bibliothèques pour l'interpréteur de commande
git clone git://git.asteride.xyz/~ldp/bibic.git
Journaux | Fichiers | Références | LICENCE

commit f1600032749242f26853a3fb72a1b0253bb784f6
parent 3293c154dabbe69f008fdcae348742eb71780fd2
Auteur: Selve <selve@asteride.xyz>
Date:   Mon, 11 Dec 2023 17:54:24 -0500

transfert des options au script

L'option « -- » a été ajoutée aux arguments de l'interpréteur pour ne pas qu'il
interprète à tord les options destinées au script. Aussi, des commentaires ont
été ajoutés.

Diffstat:
Menvic.c | 65+++++++++++++++++++++++++++++++++++++++++++----------------------
1 file changed, 43 insertions(+), 22 deletions(-)

diff --git a/envic.c b/envic.c @@ -23,41 +23,60 @@ static void utilisation(void); int main(int argc, char **argv) { - char *sh; - char *var; + char *sh; /* interpéreteur de commande */ + char *var; /* pointeur vers variable d'environnement */ + char **args; /* arguments à passer à l'interpréteur */ if (argc < 2) { utilisation(); return 1; } - /* argv[0] contient le nom du programme que sh exécutera, et argv[1] - * contient temporairement le chemin absolu vers ce programme. Une fois - * que ce chemini aura été assigné à la variable d'environnement ENV, il - * servira à contenir l'argument -s. */ - argv[0] = argv[1]; + /* création des arguments à fournir à l'interpréteur + * 0: nom du script + * 1: option pour forcer l'interprétation en entrée standard, + * sert avant tout à indiquer à l'interpréteur de transférer les + * arguments au script + * 2: option pour indiquer à l'interpréteur de traiter les arguments qui + * suivent comme des arguments et non comme des options. Nécessaire + * pour qu'il soit possible de fournir des options aux scripts. + * …: arguments à fournir au script */ + if ((args = malloc(argc + 2)) == NULL) + goto erreur; + args[0] = argv[1]; + args[1] = "-si"; + args[2] = "--"; + args[argc + 1] = NULL; + + /* copier les arguments */ + while (argc > 2) { + args[argc] = argv[argc-1]; + argc--; + } - /* POSIX stipule que le chemin contenu dans la variable ENV doit être - * absolu. Ce chemin est formé par la concaténation du dossier courant - * et du fichier donné en premier argument, séparés par une barre - * oblique (/). */ - if (*argv[1] != '/') { - static char abs[PATH_MAX]; - size_t lngr; + /* POSIX stipule que le chemin contenu dans la variable ENV doit être + * absolu. Il faut assembler ce chemin. Ce chemin est formé par la + * concaténation du dossier courant, d'une barre oblique (/) et du + * fichier dans lequel se trouve le script. + * Bien sûr, nul besoin de tout cela si le chemin fourni est déjà un + * besoin absolu. */ + if (**argv != '/') { + static char abs[PATH_MAX]; /* chemin absolu */ + size_t lngr; /* longueur du chemin */ if (getcwd(abs, PATH_MAX) == NULL) goto erreur; lngr = strlen(abs); - /* il faut encore ajouter au moins deux caractères au chemin */ + /* il faut encore ajouter au moins deux caractères au chemin. */ if (lngr + 2 >= PATH_MAX) { errno = ENAMETOOLONG; goto erreur; } abs[lngr++] = '/'; strncpy(abs + lngr, argv[1], PATH_MAX - lngr); - /* strncpy rempli le reste du tampon avec des caractères NUL - * si le dernier caractère n'est pas NUL, c'est que le chemin - * est trop long */ + /* strncpy remplit le reste du tampon avec des caractères NUL. + * si donc le dernier caractère n'est pas NUL, c'est que le + * chemin est trop long. */ if (abs[PATH_MAX - 1] != '\0') { errno = ENAMETOOLONG; goto erreur; @@ -66,22 +85,24 @@ main(int argc, char **argv) argv[1] = abs; } - + /* ENVIC_SHELL a priorité sur SHELL. Si ni l'une ni l'autre n'existe, + * l'interpréteur spécifié par le macro IC_DEF est assigné à sh */ if ((var = getenv("ENVIC_SHELL")) != NULL || (var = getenv("SHELL")) != NULL) sh = var; else sh = IC_DEF; + /* Si la variable ENV existe déjà, on déplace son contenu vers + * ENVIC_ENV, sinon, il faut supprimer ENVIC_ENV pour ne pas que les + * programmes sourcent un fichier sans raison. */ if ((var = getenv("ENV")) != NULL) setenv("ENVIC_ENV", var, 1); else unsetenv("ENVIC_ENV"); setenv("ENV", argv[1], 1); - argv[1] = "-s"; - - execve(sh, argv, environ); + execve(sh, args, environ); erreur: perror("envic");