2011-10-05 18 views
8

Estamos teniendo muchos problemas para interpretar a nuestro profesor. Pedimos una aclaración y conseguimos la siguiente vuelta de élentendiendo los requisitos para execve y entorno de entorno vars

  1. Para execve, enviar un entorno en el que la configuración con las variables exportadas y crear una orden interna para generar un subnivel de/bin/bash, de esa manera se puede vea sus variables exportadas usando env.

    (Él está hablando de la creación de nuestro propio entorno vars aquí.)

  2. Sí crear el suyo propio. Puede empezar por copiar Environ cuando su concha se inicia y se agregan variables sólo se exportan

Esto se relaciona con el siguiente mensaje el desbordamiento de la pila por mí (leer este otro post le ayudará a entender lo que estoy tratando de hacer):

using a new path with execve to run ls command

Somos simplemente muy confundido acerca de esto. Una vez más, explicaré lo que estamos tratando de hacer ahora. De forma similar a como lo hace su shell de Linux, necesitamos escribir nuestro propio programa que pueda establecer variables de entorno como PATH y USER y cualquier otro vars que el usuario quiera definir.

Un ejemplo de cómo se llama esto sería (dentro de su programa en su sistema):

mysetenv dog spike 

lo que crearía una variable de entorno que parece "perro = pico"

que es más importante, necesitamos poder establecer nuestra propia variable PATH y enviarla a un comando exec. Esta es la parte confusa porque, en base a todas nuestras preguntas, no entendemos lo que se supone que debemos hacer.

Respuesta

26

En realidad es muy simple. Ya sabe que sus argumentos son una lista de char *, terminada por un puntero NULL. Del mismo modo, el entorno es simplemente una lista de char *, terminada por un puntero NULL. Convencionalmente, los valores en la lista toman el formato VARNAME=var-value, aunque puede pasar otros formatos si lo desea.

Así, para tomar un caso simple:

#include <unistd.h> 
#include <stdio.h> 

int main(void) 
{ 
    char *argv[] = { "/bin/sh", "-c", "env", 0 }; 
    char *envp[] = 
    { 
     "HOME=/", 
     "PATH=/bin:/usr/bin", 
     "TZ=UTC0", 
     "USER=beelzebub", 
     "LOGNAME=tarzan", 
     0 
    }; 
    execve(argv[0], &argv[0], envp); 
    fprintf(stderr, "Oops!\n"); 
    return -1; 
} 

En este ejemplo, el programa se ejecutará /bin/sh con argumentos -c y env, lo que significa que la cáscara se ejecutará el programa env encontrado en su curso actual. El entorno aquí está configurado para contener 5 valores en el formato ortodoxo. Si cambia env a date (o env; date), verá el efecto de la configuración TZ, por ejemplo. Cuando corro que en mi máquina MacOS X, la salida es:

USER=beelzebub 
PATH=/bin:/usr/bin 
PWD=/Users/jleffler/tmp/soq 
TZ=UTC0 
SHLVL=1 
HOME=/ 
LOGNAME=tarzan 
_=/usr/bin/env 

La cáscara ha añadido variables de entorno SHLVL, _ y PWD a los que he establecido explícitamente en la llamada execve().

También puede hacer cosas más elegantes, como copiar en algunas de las otras variables de entorno de su entorno original donde no entren en conflicto con las que desea establecer explícitamente.También puede jugar juegos como tener dos valores para una sola variable en el entorno: ¿cuál tiene efecto? Y puede jugar juegos con nombres de variable que contienen espacios (al shell no le gusta mucho), o entradas que no coinciden en absoluto con la notación 'varname = value' (no hay signo igual).

+0

Realmente lo has aclarado todo para mí. Ya entregué todo, ¡pero gracias! Ahora lo entiendo. – james

1

El código de Jonathan Leffler funciona muy bien, excepto si desea cambiar la variable PWD (directorio de trabajo).

Lo que hice, con el fin de cambiar el directorio de trabajo, fue poner un chdir(..) antes execve(..) y llame:

chdir("/foo/bar"); 
execve(argv[0], &argv[0], envp); 
0

Estoy un poco tarde a la fiesta aquí, pero si desea conservar las viejas variables de entorno, además de crear las suyas propias, use setenv, y luego pase environ a execve().

setenv("dog", "spike", 1); 
    extern char** environ; 
    execve(argv[0], argv, environ); 

environ es una variable declarada en unistd.h, y se realiza un seguimiento de las variables de entorno durante este proceso en ejecución.

setenv() y modificar putenv()environ, por lo que cuando se pasa por encima de execve(), las variables de entorno será igual de lo que espera.