Obtenir la variable d'environnement en C++

Jinku Hu 12 octobre 2023
  1. Utilisez la fonction std::getenv pour accéder à la variable d’environnement en C++
  2. Utiliser les routines de vérification personnalisées pour vérifier les valeurs valides des variables d’environnement
Obtenir la variable d'environnement en C++

Cet article explique plusieurs méthodes pour obtenir la variable d’environnement en C++.

Utilisez la fonction std::getenv pour accéder à la variable d’environnement en C++

getenv est une fonction compatible POSIX implémentée dans la bibliothèque standard C, qui peut être importée dans le fichier source C++ en utilisant l’en-tête <cstdlib>. La fonction prend la chaîne de caractères comme seul argument et recherche le nom de la variable d’environnement qui est égale.

Les variables d’environnement sont traditionnellement représentées par des majuscules, mais getenv exige toujours que la chaîne d’argument n’ait pas de minuscules car elle ne correspondrait pas au nom de la variable même si elle est définie dans l’environnement du programme. La fonction renvoie le type char* où la valeur de la variable correspondante est stockée.

Notez que nous assignons la valeur de retour du getenv à la variable const char* parce que nous devons nous assurer que le programme ne modifie pas cet emplacement ; sinon, il en résultera un comportement indéfini.

#include <cstdlib>
#include <iostream>
#include <string>

using std::cerr;
using std::cout;
using std::endl;
using std::getenv;
using std::string;

const char *ENV_VAR = "HOME";

int main() {
  const char *tmp = getenv("HOME");
  string env_var(tmp ? tmp : "");
  if (env_var.empty()) {
    cerr << "[ERROR] No such variable found!" << endl;
    exit(EXIT_FAILURE);
  }

  cout << "HOME : " << env_var << endl;

  exit(EXIT_SUCCESS);
}

Production :

HOME : /home/username

Il est également important de ne pas passer la valeur retournée par la fonction getenv directement au constructeur std::string, car cela pourrait entraîner une erreur de segmentation lorsque la fonction getenv ne parvient pas à calculer une variable d’environnement.

Ce problème est causé ici dans l’implémentation du code du constructeur std::string qui appelle la fonction std::char_traits::length() sous le capot. Cette dernière fonction va provoquer un comportement indéfini si nullptr lui est passé en argument. Ainsi, il y a le scénario où getenv peut retourner nullptr lorsque la variable d’environnement n’est pas trouvée, et si nous la passons au constructeur de la string, le code erroné est formé.

#include <cstdlib>
#include <iostream>
#include <string>

using std::cerr;
using std::cout;
using std::endl;
using std::getenv;
using std::string;

const char *ENV_VAR = "HOME";

int main() {
  // Erroneous
  string env_var(getenv("HOME"));
  if (env_var.empty()) {
    cerr << "[ERROR] No such variable found!" << endl;
    exit(EXIT_FAILURE);
  }

  cout << "HOME : " << env_var << endl;

  exit(EXIT_SUCCESS);
}

Utiliser les routines de vérification personnalisées pour vérifier les valeurs valides des variables d’environnement

L’un des pièges les plus dangereux lors de l’accès aux variables d’environnement est la vérification de la valeur récupérée. Notez que ces variables peuvent être manipulées par l’attaquant en dehors du champ d’application de notre programme. Il faut donc procéder à un nettoyage supplémentaire de ces valeurs pour garantir une exécution correcte et sûre du programme.

Ces routines de vérification dépendent principalement du programme et doivent être traitées différemment pour chaque cas. Dans l’exemple suivant, nous démontrons le scénario dans lequel nous supposons que la valeur de la chaîne ne doit pas contenir d’espace et, si c’est le cas, nous extrayons la sous-chaîne avant le premier caractère d’espace. De cette façon, nous évitons toute valeur d’entrée irrégulière de l’environnement système. Notez que l’algorithme std::find est utilisé pour rechercher un caractère dans la string, et qu’il renvoie string::npos si le char spécifié n’est pas trouvé.

#include <algorithm>
#include <cstdlib>
#include <iostream>
#include <string>

using std::cerr;
using std::cout;
using std::endl;
using std::find;
using std::getenv;
using std::string;

const char *ENV_VAR = "HOME";

int main() {
  const char *tmp = getenv(ENV_VAR);
  string env_var(tmp ? tmp : "");
  if (env_var.empty()) {
    cerr << "[ERROR] No such variable found!" << endl;
    exit(EXIT_FAILURE);
  }

  // Env Variable Value Sanitization
  int pos = env_var.find(' ');
  if (pos != string::npos) env_var = env_var.substr(0, pos);

  cout << "HOME : " << env_var << endl;

  exit(EXIT_SUCCESS);
}
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