Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

getenv

8 réponses
Avatar
matt
Bonsoir,

J'utilise un shell pour lancer mon executable, du genre :

#!/bin/sh

export REP_ENTREE=/var/test/entree/
export REP_SORTIE=/var/test/sortie/

./mon_exe


et dans mon_exe, je recupere les variables d'environnement REP_ENTREE et
REP_SORTIE.

est ce que je peux recuperer mes variables comme ceci :

char *rep_entree = getenv("REP_ENTREE");
char *rep_sortie = getenv("REP_SORTIE");

ou faut il que je fasse comme cela :

char *value = NULL;
char rep_entree[FILENAME_MAX] = {0};
char rep_sortie[FILENAME_MAX] = {0};

value = getenv("REP_ENTREE");
strcpy(rep_entree, value);

value = getenv("REP_SORTIE");
strcpy(rep_sortie, value);

avec bien sur les tests qui vont bien pour le retour de la fonction getenv.

Merci pour vos réponses,

Matt.

8 réponses

Avatar
Harpo
On Sat, 21 Apr 2007 21:49:19 +0200, matt wrote:

avec bien sur les tests qui vont bien pour le retour de la fonction getenv.



OK, recommence avec les tests et après on verra.

--
SKILL (Simple Knowledge Inference Logic Language)
http://patrick.davalan.free.fr/skill-0/


Avatar
matt
On Sat, 21 Apr 2007 21:49:19 +0200, matt wrote:

avec bien sur les tests qui vont bien pour le retour de la fonction getenv.



OK, recommence avec les tests et après on verra.



Bonjour,

dans le premier cas :

int recup()
{
char *rep_entree = getenv("REP_ENTREE");
if(rep_entree == NULL)
return 1;

char *rep_sortie = getenv("REP_SORTIE");
if(rep_sortie == NULL)
return 1;

return 0;
}

pour le deuxieme cas :

int recup()
{
char *value = NULL;
char rep_entree[FILENAME_MAX] = {0};
char rep_sortie[FILENAME_MAX] = {0};

value = getenv("REP_ENTREE");
if(value == NULL)
return 1;

strcpy(rep_entree, value);

value = getenv("REP_SORTIE");
if(value == NULL)
return 1;

strcpy(rep_sortie, value);

return 0;
}

Voici les tests que j'effectue.

dans les deux cas, ca fonctionne.
Mais quelle est la bonne methode ?

Matt...



Avatar
Harpo
On Sun, 22 Apr 2007 08:21:19 +0200, matt wrote:

Bonjour,

dans le premier cas :

int recup()
{
char *rep_entree = getenv("REP_ENTREE");
if(rep_entree == NULL)
return 1;

char *rep_sortie = getenv("REP_SORTIE");
if(rep_sortie == NULL)
return 1;

return 0;
}

pour le deuxieme cas :

int recup()
{
char *value = NULL;
char rep_entree[FILENAME_MAX] = {0};
char rep_sortie[FILENAME_MAX] = {0};

value = getenv("REP_ENTREE");
if(value == NULL)
return 1;

strcpy(rep_entree, value);

value = getenv("REP_SORTIE");
if(value == NULL)
return 1;

strcpy(rep_sortie, value);

return 0;
}

Voici les tests que j'effectue.

dans les deux cas, ca fonctionne.
Mais quelle est la bonne methode ?


La première, bien que tu mélanges les déclarations et les autres
instructions, ce qui n'est pas standard et ne marche qu'en raison de la
permissivité du compilateur, tu devrais mettre plus d'options de warning.

La seconde solution est mauvaise principalement parce que tu ne peux, au
moment où tu écris le programme, connaître la longueur de la chaîne
placée dans la variable d'environnement, FILENAME_MAX ne garantit rien,
il faudrait au minimum remplacer le strcpy par strncpy pour éviter un
'overrun' qui fait les délices des crackers.
Bien d'abord regarder dans le manuel ce que font strcpy et strncpy, je ne
me rappelle plus exactement je n'utilise qu'exceptionnellement ces
fonctions.

De plus la copie est inutile, autant mettre l'adresse quelque part si tu
en as besoin après.

--
SKILL (Simple Knowledge Inference Logic Language)
http://patrick.davalan.free.fr/skill-0/

Avatar
espie
In article <462b02e9$0$27398$,
Harpo wrote:
La première, bien que tu mélanges les déclarations et les autres
instructions, ce qui n'est pas standard et ne marche qu'en raison de la
permissivité du compilateur, tu devrais mettre plus d'options de warning.

Faudra te mettre a jour, hein. C'est parfaitement standard en C99, et on

est quand meme en 2007, maintenant.

Si tu vas par la, tu as oublie de l'allumer parce qu'il ne fait pas
de declaration de fonctions K&R ;-)

Avatar
Harpo
On Sun, 22 Apr 2007 08:14:57 +0000, Marc Espie wrote:

Faudra te mettre a jour, hein. C'est parfaitement standard en C99, et on
est quand meme en 2007, maintenant.


Désolé, je ne savais pas. Enfin qu'on est en 2007 si...
Je me demande d'ailleurs si c'est souvent utile.

Si tu vas par la, tu as oublie de l'allumer parce qu'il ne fait pas
de declaration de fonctions K&R ;-)


Bon ça va... Je me casse encore une fois !

--
SKILL (Simple Knowledge Inference Logic Language)
http://patrick.davalan.free.fr/skill-0/

Avatar
espie
In article <462b1ac6$0$25942$,
Harpo wrote:
On Sun, 22 Apr 2007 08:14:57 +0000, Marc Espie wrote:

Faudra te mettre a jour, hein. C'est parfaitement standard en C99, et on
est quand meme en 2007, maintenant.


Désolé, je ne savais pas. Enfin qu'on est en 2007 si...
Je me demande d'ailleurs si c'est souvent utile.


C'est juste du sucre syntaxique en plus. Ca permet d'introduire des
variables juste au bon moment sans avoir besoin de rajouter des blocs
en rab.

Pour ma part, le principal avantage que j'y vois, c'est que ca permet
simplement de coupler systematiquement l'initialisation a la declaration
de la variable. Ca evite d'etre le cul entre deux chaises:
- entre les variables pas initialisees au point de declaration, qu'on
risque d'oublier plus tard.
- et celles qu'on initialise a n'importe quoi, juste parce que, alors
qu'on ne sait pas encore ce qu'il faut mettre dedans.

Tu me diras que le compilateur donne des avertissements pour les variables
non initialisees, ce qui est vrai. Encore faut-il que le programmeur les
lise. Et ca necessite de regarder des choses en plus quand on fait de l'audit.

Ca depend aussi du style de commentaires. Si on programme ses boucles dans
l'optique de les prouver (invariant de boucle et condition de terminaison),
la declaration de variable se place `naturellement' en entree de boucle,
juste a cote de l'invariant...

A cote de ca, on perd le cote bien net et psycho-rigide de `j'ai un gros
bloc de declarations de variables en tete de ma fonction'. Bof. Ca ne me
gene pas trop. Mais je bosse beaucoup avec des langages assez dynamiques,
et retrouver le type d'une variable simplement n'est pas quelque chose
de crucial en ce qui me concerne... meme en C. C'est la semantique de la
variable qui m'interesse le plus souvent. Son type devrait (doit ?) aller
de soit. J'ai peut-etre passe trop de temps avec le RAII (Resource Acquisition
Is Initialization) du C++. Mais bon, pour du code critique, faut bien
avouer qu'avoir un chemin d'initialisation des ressources/recuperation
d'erreur le plus simple et le plus clair posssible peut servir.


Avatar
matt
int recup()
{
char *rep_entree = getenv("REP_ENTREE");
if(rep_entree == NULL)
return 1;

char *rep_sortie = getenv("REP_SORTIE");
if(rep_sortie == NULL)
return 1;

return 0;
}



La première, bien que tu mélanges les déclarations et les autres
instructions, ce qui n'est pas standard et ne marche qu'en raison de la
permissivité du compilateur, tu devrais mettre plus d'options de warning.



Ok, merci pour ta réponse, et je vais donc opter pour la premiere solution.

Bonne soirée,

Matt...

PS : Voici pour mes options de warning :

-O2 -Wchar-subscripts -Wcomment -Wformat=2 -Wimplicit-int
-Werror-implicit-function-declaration -Wmain -Wparentheses
-Wsequence-point -Wreturn-type -Wswitch -Wtrigraphs -Wunused
-Wuninitialized -Wunknown-pragmas -Wfloat-equal -Wundef
-Wshadow -Wpointer-arith -Wbad-function-cast -Wwrite-strings
-Wconversion -Wsign-compare -Waggregate-return -Wstrict-prototypes
-Wmissing-prototypes -Wmissing-declarations -Wmissing-noreturn
-Wformat -Wmissing-format-attribute -Wno-deprecated-declarations
-Wpacked -Wredundant-decls -Wnested-externs -Winline -Wlong-long
-Wunreachable-code


Avatar
Harpo
On Sun, 22 Apr 2007 09:26:38 +0000, Marc Espie wrote:

Je me demande d'ailleurs si c'est souvent utile.


C'est juste du sucre syntaxique en plus. Ca permet d'introduire des
variables juste au bon moment sans avoir besoin de rajouter des blocs
en rab.


C'est ce que je fais (rajouter des blocs) pour limiter la portée des
variables et éviter qu'elles soient sur la pile si j'appelle une fonction
après le bloc, bien que le compilateur soit capable de s'en tirer tout
seul, en principe.
Je pense que rajouter des blocs simplifie la lecture.

Pour ma part, le principal avantage que j'y vois, c'est que ca permet
simplement de coupler systematiquement l'initialisation a la declaration
de la variable. Ca evite d'etre le cul entre deux chaises: - entre les
variables pas initialisees au point de declaration, qu'on risque
d'oublier plus tard.
- et celles qu'on initialise a n'importe quoi, juste parce que, alors
qu'on ne sait pas encore ce qu'il faut mettre dedans.


Personnellement je n'initialise les variables que si ça me fait gagner
une ligne de code, par exemple initialiser un compteur à 0.
C'estpeut-être un tort, je devrais peut-être initialiser les pointeurs
à NULL, voire toutes les variables.

Tu me diras que le compilateur donne des avertissements pour les
variables non initialisees, ce qui est vrai. Encore faut-il que le
programmeur les lise.


Euh... Je pense que c'est la moindre des choses.

Et ca necessite de regarder des choses en plus
quand on fait de l'audit.


C'est vrai. mais dans ce cas aussi, on peut compiler les programmes et
lire les warnings. Déjà, s'il y en a c'est louche.

Ca depend aussi du style de commentaires. Si on programme ses boucles
dans l'optique de les prouver (invariant de boucle et condition de
terminaison), la declaration de variable se place `naturellement' en
entree de boucle, juste a cote de l'invariant...


Oui, mais je ne vois pas le problème, on la déclare en entrée du bloc,
et voilà.

A cote de ca, on perd le cote bien net et psycho-rigide de `j'ai un gros
bloc de declarations de variables en tete de ma fonction'. Bof. Ca ne me
gene pas trop.


Moi non plus, je me demandais si cela apportait quelque chose.

Mais je bosse beaucoup avec des langages assez
dynamiques, et retrouver le type d'une variable simplement n'est pas
quelque chose de crucial en ce qui me concerne... meme en C. C'est la
semantique de la variable qui m'interesse le plus souvent. Son type
devrait (doit ?) aller de soit.


Ok, c'est le principal. Pour cela il y a le nom de la variable, trouver
des noms et gérer les espaces de noms prend une partie du temps de
programmation surtout en C.

Il y a aussi les commentaires, personnellement, je n'en mets plus guère
qu'à la déclaration des variables, leur valeur doit refléter un certain
état qui devrait être évident à la lecture. cela va dans le sens d'une
initialisation à la déclaration, je vais y penser.

Sa portée est importante aussi, la limiter permet d'éviter de chercher
partout où elle aurait pu être modifiée.

J'ai peut-etre passe trop de temps avec
le RAII (Resource Acquisition Is Initialization) du C++. Mais bon, pour
du code critique, faut bien avouer qu'avoir un chemin d'initialisation
des ressources/recuperation d'erreur le plus simple et le plus clair
posssible peut servir.


Je ne connais pas le concept de RAII et je ne sais pas si je comprends
bien, mais on devrait connaître l'état d'un programme en connaissant
l'état des variables, c'était déjà le cas quand on cherchait des
erreurs dans des core dumps.

--
SKILL (Simple Knowledge Inference Logic Language)
http://patrick.davalan.free.fr/skill-0/