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

adresse d'une variable d'environnement

23 réponses
Avatar
Kevin Denis
Bonjour,

je suis sur un système linux x86 32bits.
J'ai des variables d'environnements, et depuis un programme C, je
souhaite connaitre leurs adresses.
Typiquement:
MAVAR="blablable(...)blablbabla"
export MAVAR

Si je regarde le man, je vois que la fonction getenv à l'air de
faire l'affaire. getenv renvoie un pointeur, et il est de type:
#include <stdlib.h>
char *getenv (const char *name);

J'écris donc:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(void){
char *p = NULL; //je vais utiliser un pointeur
p = getenv('MAVAR'); //getenv me renvoie un pointeur
printf('Adresse de MAVAR: %p', p); //j'affiche le pointeur
return 0; //comme ça gcc râle moins
}

sauf que ça ne fonctionne pas
J'ai lors de la compilation des warning:
warning: multi-character character constant
et
warning: passing arg 1 of `getenv' makes pointer from integer without a cast

et au lancement le programme ne fait rien d'autre qu'un segfault.

Un conseil pour me montrer ce que je fais mal?
Merci
--
Kevin

10 réponses

1 2 3
Avatar
-ed-
Il a été expliqué clairement que cette adresse n'était pas utilisab le (notamment, impossible de modifier la variable originale "de l'exterieur "). Pour ça il faut être dans le même environnement que celui qui a c réé la variable et utiliser une commande shell.

Il faut comprendre que les valeurs des variables d'environnement sont recop iées dans chaque contexte d'un processus nouvellement crée, avec donc u n nouvel espace mémoire et une nouvelle adresse. Même si un processus p ouvait modifier une variable d'environnement (certaines extensions au C le permettent : setenv() ), la variable originale ne sera pas modifiée.

C'est exactement la même chsoe avec les paramètres d'une fonction C. La valeur est recopiée, et l'adresse du paramètre n'est pas l'adresse de la variable originale.
Avatar
Kevin Denis
Le 23-08-2011, -ed- a écrit :
Il a été expliqué clairement que cette adresse n'était pas utilisable
(notamment, impossible de modifier la variable originale "de
l'exterieur"). Pour ça il faut être dans le même environnement que
celui qui a créé la variable et utiliser une commande shell.



Mais je ne veux pas modifier la valeur de la variable
d'environnement (!?) Je cherche juste à connaitre son adresse lors
de l'exécution de mon programme, rien de plus.

Je suppose que puisque ces variables d'environnement sont consultables
depuis un programme C, c'est qu'elles sont rangées quelque part, et
ce quelque part c'est forcément une adresse.
Je cherche donc à connaitre quelle est l'adresse du premier caractère
de ma variable d'environnement lorsque je lance un programme C.

Mon problème, c'est que lorsque je fais mon getenv("MAVAR")
j'ai des warnings à la compilation:
-est-ce une erreur de type? (pourtant j'ai mis char * ?)
-est ce que je n'ai pas compris la syntaxe de getenv?

Et lorsque je souhait connaitre l'adresse de ce pointeur, ça
segfaulte:
-pourquoi ça segfaulte?

ou est-ce que quelqu'un aurait un exemple d'utilisation de getenv?

Il faut comprendre que les valeurs des variables d'environnement sont
recopiées dans chaque contexte d'un processus nouvellement crée,
avec donc un nouvel espace mémoire et une nouvelle adresse.



Je suis d'accord.

Même si un processus pouvait modifier une variable d'environnement



Mais je ne veux pas la modifier, je veux seulement connaitre son
adresse, dans le contexte de ce programme.
--
Kevin
Avatar
Bruno Ducrot
Le 23-08-2011, Kevin Denis a écrit :
Et lorsque je souhait connaitre l'adresse de ce pointeur, ça
segfaulte:
-pourquoi ça segfaulte?



Parce que tu as écris :
getenv('MAVAR');

avec des simples quotes, et non avec des doubles quotes. 'MAVAR'
retournera un int, et non un pointeur.

ou est-ce que quelqu'un aurait un exemple d'utilisation de getenv?



Ton programme, mais en remplaçant les simples quotes par des doubles.

Tu as commis cette erreur sur deux lignes (un pour getenv, et l'autre
pour un printf).

A plus,

--
Bruno Ducrot

A quoi ca sert que Ducrot hisse des carcasses ?
Avatar
Pascal J. Bourguignon
Kevin Denis writes:

Le 23-08-2011, -ed- a écrit :
Il a été expliqué clairement que cette adresse n'était pas utilisable
(notamment, impossible de modifier la variable originale "de
l'exterieur"). Pour ça il faut être dans le même environnement que
celui qui a créé la variable et utiliser une commande shell.



Mais je ne veux pas modifier la valeur de la variable
d'environnement (!?) Je cherche juste à connaitre son adresse lors
de l'exécution de mon programme, rien de plus.

Je suppose que puisque ces variables d'environnement sont consultables
depuis un programme C, c'est qu'elles sont rangées quelque part, et
ce quelque part c'est forcément une adresse.
Je cherche donc à connaitre quelle est l'adresse du premier caractère
de ma variable d'environnement lorsque je lance un programme C.

Mon problème, c'est que lorsque je fais mon getenv("MAVAR")
j'ai des warnings à la compilation:
-est-ce une erreur de type? (pourtant j'ai mis char * ?)
-est ce que je n'ai pas compris la syntaxe de getenv?

Et lorsque je souhait connaitre l'adresse de ce pointeur, ça
segfaulte:
-pourquoi ça segfaulte?

ou est-ce que quelqu'un aurait un exemple d'utilisation de getenv?



#include <stdlib.h>

char* name="Hello";
char* env=getenv(name)
char* value=strcpy(env?env:"");



Il faut comprendre que les valeurs des variables d'environnement sont
recopiées dans chaque contexte d'un processus nouvellement crée,
avec donc un nouvel espace mémoire et une nouvelle adresse.



Je suis d'accord.

Même si un processus pouvait modifier une variable d'environnement



Mais je ne veux pas la modifier, je veux seulement connaitre son
adresse, dans le contexte de ce programme.



Son addresse n'a aucun sens. Comme on te la répété une demi douzaine de
fois, getenv peut retourner toujours la même adresse, ou chaque fois une
autre adresse.

Il est tout à fait possible d'avoir:

getenv("HOME") == getenv("PWD")

ou
getenv("HOME") != getenv("HOME")

donc l'adresse retournée par getenv n'a aucun sens. Tout ce que tu peux
faire avec, c'est de copier la chaine référencée par ce pointeur quand
il n'est pas nul.

--
__Pascal Bourguignon__ http://www.informatimago.com/
A bad day in () is better than a good day in {}.
Avatar
Éric Lévénez
Le 23/08/11 12:26, Pascal J. Bourguignon a écrit :

#include<stdlib.h>

char* name="Hello";
char* env=getenv(name)
char* value=strcpy(env?env:"");



Je pense que tu voulais mettre strdup au lieu de strcpy.

--
Éric Lévénez
FAQ de fclc : <http://www.levenez.com/lang/c/faq/>
Avatar
Pascal J. Bourguignon
Éric Lévénez writes:

Le 23/08/11 12:26, Pascal J. Bourguignon a écrit :

#include<stdlib.h>

char* name="Hello";
char* env=getenv(name)
char* value=strcpy(env?env:"");



Je pense que tu voulais mettre strdup au lieu de strcpy.



Oui, c'est ce à quoi je pensais fortement...

--
__Pascal Bourguignon__ http://www.informatimago.com/
A bad day in () is better than a good day in {}.
Avatar
Pascal J. Bourguignon
Tonton Th writes:

On 08/23/2011 12:26 PM, Pascal J. Bourguignon wrote:

char* value=strcpy(env?env:"");



Ouaouuu !



Comme indiqué dans les autres réponses, c'est strdup, pas strcpy.

char* value=strdup(env?env:"");

Sinon, je ne vois pas ce que signifie ce "Ouaouuu !".

--
__Pascal Bourguignon__ http://www.informatimago.com/
A bad day in () is better than a good day in {}.
Avatar
Marc
Antoine Leca wrote:

char* value=strdup(env || "");



|| renvoie 1 ou 0, pas de très bons arguments pour strdup.
Avatar
Xavier Roche
Le 07/09/2011 16:38, Marc a écrit :
Antoine Leca wrote:
char* value=strdup(env || "");





A la limite, un strdup(env != NULL ? env : "") aurait été visuellement
plus clair, mais je chipotte.

Et pour être sûr au premier coup d’œil que le free(env) plus bas fait
bien ce qu'on veut, j'aurais même osé un:

char*const value = strdup(env != NULL ? env : "");

Mais là c'est du cinquième ordre de chipotage.
Avatar
Antoine Leca
Marc écrivit :
Antoine Leca wrote:

char* value=strdup(env || "");



|| renvoie 1 ou 0, pas de très bons arguments pour strdup.



Oui, on dirait que je lis trop de scripts shell ces jours-ci...


Antoine
1 2 3