Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

206
Vistas
¿Cómo hereda un programa las variables de entorno?

Cuando uso la función getenv() de la biblioteca estándar de C, mi programa hereda las variables de entorno de su padre.

Ejemplo:

 $ export FOO=42 $ <<< 'int main() {printf("%s\n", getenv("FOO"));}' gcc -w -xc - && ./a.exe 42

En libc, la variable de environ.c environ Espero que esté vacío en la ejecución, pero obtengo 42 .

Yendo un poco más lejos, getenv se puede simplificar de la siguiente manera:

 char * getenv (const char *name) { size_t len = strlen (name); char **ep; uint16_t name_start; name_start = *(const uint16_t *) name; len -= 2; name += 2; for (ep = __environ; *ep != NULL; ++ep) { uint16_t ep_start = *(uint16_t *) *ep; if (name_start == ep_start && !strncmp (*ep + 2, name, len) && (*ep)[len + 2] == '=') return &(*ep)[len + 3]; } return NULL; } libc_hidden_def (getenv)

Aquí solo obtendré el contenido de la variable __environ . Sin embargo, nunca lo inicialicé.

Entonces me confundo porque se supone que environ es NULL a menos que mi función principal no sea el punto de entrada real de mi programa. Quizás gcc me está molestando al agregar una función _init que es parte de la biblioteca estándar de C.

¿Dónde se inicializa environ ?

over 4 years ago · Santiago Trujillo
3 Respuestas
Responde la pregunta

0

Las variables de entorno se transmiten desde el proceso principal como un tercer argumento a main . La forma más fácil de descubrir esto es leer la documentación de la llamada al sistema execve , particularmente este bit:

 int execve(const char *filename, char *const argv[], char *const envp[]);

Descripción

execve() ejecuta el programa al que apunta filename . [...] argv es una matriz de cadenas de argumentos que se pasan al nuevo programa. Por convención, la primera de estas cadenas debe contener el nombre de archivo asociado con el archivo que se está ejecutando. envp es una matriz de cadenas, convencionalmente de la forma key=value , que se pasan como entorno al nuevo programa. Tanto argv como envp deben terminar con un puntero NULL. Se puede acceder al argumento vector y entorno por la función principal del programa llamado, cuando se define como:

 int main(int argc, char *argv[], char *envp[])

La biblioteca C copia el argumento envp en la variable global environ en algún lugar de su código de inicio, antes de llamar a main : por ejemplo, GNU libc hace esto en _init y musl libc lo hace en __init_libc . (Puede encontrar el código de musl libc más fácil de rastrear que el de GNU libc). Por el contrario, si inicia un programa usando una de las funciones de contenedor exec que no toman un vector de entorno explícito, la biblioteca C proporciona environ como el tercer argumento para execve La herencia de las variables de entorno es, por lo tanto, estrictamente una convención de espacio de usuario. En lo que respecta al núcleo, cada programa recibe dos vectores de argumentos y no le importa lo que haya en ellos.

(Tenga en cuenta que el main de tres argumentos es una extensión del lenguaje C. El estándar C solo especifica int main(void) e int main(int argc, char **argv) pero permite implementaciones para definir formas adicionales ( C11 Anexo J. 5.1 Argumentos del entorno ). El main de tres argumentos ha sido cómo funcionan las variables de entorno desde Unix V7, si no más, y también está documentado por Microsoft; consulte ¿Qué debería devolver main() en C y C++? ).

over 4 years ago · Santiago Trujillo Denunciar

0

No hay ningún misterio aquí.

Primero, la concha se bifurca. El proceso bifurcado obviamente tiene el mismo entorno. Luego se ejecuta un nuevo programa en el niño. La llamada al sistema en cuestión es execve , que, entre otras cosas, acepta un puntero a un entorno.

Entonces, qué entorno se establece después de ejecutar un binario depende completamente del código que estaba ejecutando el exec.

Todo esto se puede ver fácilmente ejecutando strace.

EDITAR: dado que la pregunta fue editada para preguntar sobre el environ :

Cuando ejecuta un binario vinculado dinámicamente, el primer código de espacio de usuario que hace algo proviene del cargador. El cargador, entre otras cosas, configura variables como argc , argv o environ y solo luego llama a main() desde el binario.

Una vez más, las fuentes para todo esto están disponibles gratuitamente. Mientras que las fuentes de glibc son bastante difíciles de leer debido al formato atroz, las de BSD son lo suficientemente fáciles y conceptualmente equivalentes.

http://code.metager.de/source/xref/freebsd/libexec/rtld-elf/rtld.c#389

over 4 years ago · Santiago Trujillo Denunciar

0

En Linux, cuando se inicia un programa, tiene sus argumentos y variables ambientales almacenadas en la pila. Para los programas en C, el código que se ejecuta antes de main mira esto, crea las matrices de punteros argv y envp , y luego llama a main con estos valores (y argc ).

Cuando un programa llama a execvpe para convertirse en un nuevo programa (a menudo después de llamar a fork ), se pasa un envp , junto con un argv . El kernel copiará los datos en estos en la pila del nuevo programa.

Cuando se llama a cualquiera de las otras funciones exec , la glibc pasará al execvpe del programa actual como el envp del nuevo programa a environ (o directamente a sys_exec).

over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda