Accéder aux variables d'environnement à l'aide de la fonction setenv en C

Jinku Hu 12 octobre 2023
  1. Utilisez la fonction setenv pour exporter des variables d’environnement en C
  2. Utilisez la variable envp pour parcourir les variables d’environnement définies en C
  3. Utilisez la variable environ pour parcourir les variables d’environnement définies en C
Accéder aux variables d'environnement à l'aide de la fonction setenv en C

Cet article explique plusieurs méthodes d’exportation de variables d’environnement à l’aide de la fonction setenv en C.

Utilisez la fonction setenv pour exporter des variables d’environnement en C

Chaque programme en cours d’exécution sur les systèmes de base Unix a un environnement qui collecte des paires de valeurs variables utilisées principalement par le shell et d’autres programmes de l’espace utilisateur. Le programme peut récupérer une seule variable d’environnement et sa valeur avec la fonction getenv. Mais si une nouvelle variable doit être définie ou la variable existante modifiée, la fonction setenv doit être appelée. Il prend trois arguments, dont le premier et le second sont des pointeurs char pointant respectivement vers le nom de la variable et sa valeur. Le troisième argument est de type int et spécifie si la valeur de la variable donnée doit être écrasée si elle existe déjà dans l’environnement. La valeur différente de zéro de cet argument dénote un comportement d’écrasement et une valeur nulle à l’opposé.

Notez cependant que l’itération de toutes les variables d’environnement définies nécessite d’accéder à la variable globale spéciale appelée - environ, qui est un tableau de chaînes de caractères terminé par NULL. Alternativement, on peut déclarer la fonction main avec le troisième argument envp pour accéder aux variables. Dans l’exemple suivant, nous imprimons les pointeurs eniron et envp avant et après l’appel de la fonction setenv. Notez que le pointeur envp a la même valeur après l’appel, alors que environ a été modifié.

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

extern char **environ;

int main(int argc, const char *argv[], const char *envp[]) {
  printf("environ:  %p\n", environ);
  printf("envp:     %p\n", envp);

  setenv("NEW_VAR", "new_value", 1);

  puts("----Added NEW_VAR----");
  printf("environ:  %p\n", environ);
  printf("envp:     %p\n", envp);

  exit(EXIT_SUCCESS);
}

Production:

environ:  0x7fffa05a7fe8
envp:     0x7fffa05a7fe8
----Added NEW_VAR----
environ:  0x5646431276b0
envp:     0x7fffa05a7fe8

Utilisez la variable envp pour parcourir les variables d’environnement définies en C

L’exemple de code précédent montre pourquoi il faut éviter de récupérer les variables d’environnement en utilisant l’argument de fonction main envp après avoir appelé la fonction setenv. Lorsque la fonction setenv est appelée, l’environnement est déplacé, mais envp pointe toujours vers l’ancien environnement. L’exemple de code suivant illustre le comportement erroné en définissant une nouvelle variable avec l’appel setenv, puis en itérant dans le tableau de pointeurs envp. Notez que nous utilisons également l’instruction goto pour sauter à la fin de la boucle si la variable nommée NEW_VAR est trouvée.

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

int main(int argc, const char *argv[], const char *envp[]) {
  if (setenv("NEW_VAR", "new_value", 1) != 0) {
    perror("setenv");
    exit(EXIT_FAILURE);
  }

  if (envp != NULL) {
    for (size_t i = 0; envp[i] != NULL; ++i) {
      if (strcmp(envp[i], "NEW_VAR=new_value") == 0) {
        puts(envp[i]);
        goto END;
      }
    }
    printf("No such variable found!\n");
  }
END:

  exit(EXIT_SUCCESS);
}

Production:

No such variable found!

Utilisez la variable environ pour parcourir les variables d’environnement définies en C

Puisque la solution précédente ne trouve pas la variable nouvellement définie, nous devrions utiliser la variable environ déclarée en externe. Dans ce cas, nous avons inclus plusieurs instructions conditionnelles de préprocesseur pour rendre le code portable sur les différents systèmes, mais seul extern char **environ est nécessaire sur la plupart des systèmes UNIX. Une fois déclarés, nous pouvons parcourir la liste des variables en utilisant la même boucle que nous avons implémentée dans l’exemple précédent.

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

#if defined(_POSIX_) || defined(__USE_POSIX)
extern char **environ;
#elif defined(_WIN32)
_CRTIMP extern char **_environ;
#endif

int main(void) {
  if (setenv("NEW_VAR", "new_value", 1) != 0) {
    perror("setenv");
    exit(EXIT_FAILURE);
  }

  if (environ != NULL) {
    for (size_t i = 0; environ[i] != NULL; ++i) {
      if (strcmp(environ[i], "NEW_VAR=new_value") == 0) {
        puts(environ[i]);
        goto END;
      }
    }
    printf("No such variable found!\n");
  }
END:

  exit(EXIT_SUCCESS);
}

Production:

NEW_VAR=new_value
Auteur: Jinku Hu
Jinku Hu avatar Jinku Hu avatar

Founder of DelftStack.com. Jinku has worked in the robotics and automotive industries for over 8 years. He sharpened his coding skills when he needed to do the automatic testing, data collection from remote servers and report creation from the endurance test. He is from an electrical/electronics engineering background but has expanded his interest to embedded electronics, embedded programming and front-/back-end programming.

LinkedIn Facebook