Obtener la variable de entorno en C++

Jinku Hu 12 octubre 2023
  1. Utilice la función std::getenv para acceder a la variable de entorno en C++
  2. Utilizar rutinas de comprobación personalizadas para verificar los valores válidos de las variables de entorno
Obtener la variable de entorno en C++

Este artículo explicará varios métodos de cómo obtener la variable de entorno en C++.

Utilice la función std::getenv para acceder a la variable de entorno en C++

getenv es una función compatible con POSIX implementada en la biblioteca estándar de C, que puede ser importada en el archivo fuente de C++ utilizando la cabecera <cstdlib>. La función toma la cadena de caracteres como único argumento y busca el nombre de la variable de entorno que sea igual.

Las variables de entorno se representan convencionalmente con todas las letras mayúsculas, pero getenv sigue requiriendo que la cadena del argumento no tenga letras minúsculas, ya que no coincidiría con el nombre de la variable aunque esté definida en el entorno del programa. La función devuelve el tipo char* donde se almacena el valor de la variable correspondiente.

Fíjate en que asignamos el valor de retorno de getenv a la variable const char* porque necesitamos asegurarnos de que el programa no modifica esa ubicación; de lo contrario, se producirá un comportamiento indefinido.

#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);
}

Producción :

HOME : /home/username

También es importante no pasar el valor devuelto por la función getenv directamente al constructor std::string, ya que podría lanzar un fallo de segmentación cuando la función getenv no consiga calcular ninguna variable de entorno.

Este problema está causado aquí dentro de la implementación del código del constructor std::string que llama a la función std::char_traits::length() bajo el capó. Esta última función causará un comportamiento indefinido si se le pasa nullptr como argumento. Así, se da el escenario en el que getenv puede devolver nullptr cuando no se encuentra la variable de entorno, y si se la pasamos al constructor string, se forma el código erróneo.

#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);
}

Utilizar rutinas de comprobación personalizadas para verificar los valores válidos de las variables de entorno

Uno de los escollos más peligrosos cuando se accede a las variables de entorno es verificar el valor recuperado. Tenga en cuenta que estas variables pueden ser manipuladas por el atacante fuera del ámbito de nuestro programa. Por lo tanto, es necesario que haya una sanitización adicional de estos valores para asegurar la ejecución correcta y segura del programa.

Estas rutinas de comprobación dependen en su mayoría del programa y deben ser manejadas de forma diferente para cada caso. En el siguiente ejemplo, demostramos el escenario en el que asumimos que el valor de la cadena no debe tener ningún espacio y, si lo tiene, extraemos la subcadena antes del primer carácter de espacio. De este modo, evitamos cualquier valor de entrada irregular del entorno del sistema. Observa que el algoritmo std::find se utiliza para buscar un carácter en la cadena, y devuelve string::npos si no se encuentra la char especificada.

#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);
}
Autor: 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