2011-10-05 14 views
8

Stiamo avendo un sacco di problemi a interpretare il nostro insegnante. Abbiamo chiesto chiarimenti e ottenuto il seguente da luiComprensione requisiti per execve e impostazione di vars ambiente

  1. Per execve, inviarlo un ambiente si imposta con le variabili esportate e creare un comando incorporato per deporre le uova una sottoshell di/bin/bash, in questo modo è possibile guarda le tue variabili esportate usando env.

    (Si sta parlando di creare il nostro ambiente Le variabili di qui.)

  2. Si creare il proprio. Puoi iniziare copiando environ quando inizia la shell e aggiungi solo variabili esportate

Questo è correlato al seguente post su Stack Overflow da me (leggere questo post ti aiuterà a capire cosa sto cercando di fare):

using a new path with execve to run ls command

Siamo solo molto confuso su questo. Ancora una volta spiegherò cosa stiamo cercando di fare ora. Come per la tua shell Linux, dobbiamo scrivere il nostro programma che può impostare variabili d'ambiente come PATH e USER e qualsiasi altra variabile che l'utente vuole definire.

Un esempio di come si potrebbe chiamare questo sarebbe (all'interno del vostro programma alla sua pronta):

mysetenv dog spike 

che creerebbe una variabile d'ambiente che sembra "cane = spike"

Ancora più importante, dobbiamo essere in grado di impostare la nostra variabile PATH e inviarla a un comando exec. Questa è la parte confusa perché, sulla base di tutte le nostre domande, non capiamo cosa dovremmo fare.

risposta

26

In realtà è molto semplice. Sai già che i tuoi argomenti sono un elenco di char *, terminato da un puntatore NULL. Allo stesso modo, l'ambiente è semplicemente un elenco di char *, terminato da un puntatore NULL. Convenzionalmente, i valori nella lista assumono la forma VARNAME=var-value, sebbene tu possa passare altri formati, se lo desideri.

Così, per prendere un caso semplice:

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

In questo esempio, il programma verrà eseguito /bin/sh con argomenti -c e env, il che significa che la shell eseguirà il programma env trovato il suo percorso attuale. Qui l'ambiente è impostato per contenere 5 valori nel formato ortodosso. Se si modifica env a date (o env; date), si vedrà l'effetto dell'impostazione TZ, ad esempio. Quando eseguo che sulla mia macchina MacOS X, l'output è:

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

Il guscio ha aggiunto variabili d'ambiente SHLVL, _ e PWD a quelle ho impostato in modo esplicito nella chiamata execve().

È inoltre possibile eseguire attività più elaborate, come la copia in alcune delle altre variabili di ambiente dal proprio ambiente originale in cui non sono in conflitto con quelle che si desidera impostare in modo esplicito.Puoi anche giocare a giochi come avere due valori per una singola variabile nell'ambiente - quale effetto ha? E puoi giocare con nomi di variabili che contengono spazi (la shell non gli piace di più), o voci che non corrispondono affatto alla notazione "varname = value" (nessun segno di uguale).

+0

Hai davvero chiarito tutto per me. Ho già trasformato tutto, ma grazie! lo capisco adesso – james

1

Il codice da Jonathan Leffler funziona perfettamente, tranne se si desidera modificare la variabile PWD (directory di lavoro).

Quello che ho fatto, al fine di cambiare la directory di lavoro, è stato quello di mettere un chdir(..) prima execve(..) e chiamare:

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

Sono un po 'in ritardo alla festa qui, ma se si desidera conservare le vecchie variabili d'ambiente e creare il proprio, utilizzare setenv e quindi passare environ a execve().

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

environ è una variabile dichiarata in unistd.h, e registra le variabili di ambiente nel corso di questo processo in esecuzione.

setenv() e putenv() modificare environ, in modo che quando si passa sopra execve(), le variabili di ambiente saranno proprio come ci si aspetterebbe.

Problemi correlati