Accedere alle variabili d'ambiente usando la funzione setenv in C

Jinku Hu 12 ottobre 2023
  1. Usa la funzione setenv per esportare le variabili d’ambiente in C
  2. Usa la variabile envp per scorrere le variabili d’ambiente definite in C
  3. Usa la variabile environ per scorrere le variabili d’ambiente definite in C
Accedere alle variabili d'ambiente usando la funzione setenv in C

Questo articolo spiegherà diversi metodi per esportare variabili d’ambiente usando la funzione setenv in C.

Usa la funzione setenv per esportare le variabili d’ambiente in C

Ogni programma in esecuzione su sistemi base Unix ha un ambiente che raccoglie coppie di valori variabili utilizzate principalmente dalla shell e da altri programmi nello spazio utente. Il programma può recuperare una singola variabile d’ambiente e il suo valore con la funzione getenv. Ma se una nuova variabile deve essere definita o quella esistente modificata, deve essere chiamata la funzione setenv. Richiede tre argomenti, il primo e il secondo dei quali sono puntatori char che puntano rispettivamente al nome della variabile e al suo valore. Il terzo argomento è di tipo int e specifica se il valore della variabile data deve essere sovrascritto se esiste già nell’ambiente. Il valore diverso da zero di questo argomento denota il comportamento di sovrascrittura e il valore zero al contrario.

Nota comunque, l’iterazione di tutte le variabili d’ambiente definite richiede l’accesso alla speciale variabile globale chiamata - environment, che è un array di stringhe di caratteri terminato da NULL. In alternativa, si può dichiarare la funzione main con il terzo argomento envp per accedere alle variabili. Nell’esempio seguente, stampiamo entrambi i puntatori eniron e envp prima e dopo la chiamata alla funzione setenv. Si noti che il puntatore envp ha lo stesso valore dopo la chiamata, mentre envp è stato modificato.

#include <stdio.h>
#include <stdlib.h>

extern char **environ;

int main(int argc, const char *argv[], const char *envp[]) {
  printf("environ:  %p\n", environ);
  printf("envp:     %p\n", envp);

  setenv("NEW_VAR", "new_value", 1);

  puts("----Added NEW_VAR----");
  printf("environ:  %p\n", environ);
  printf("envp:     %p\n", envp);

  exit(EXIT_SUCCESS);
}

Produzione:

environ:  0x7fffa05a7fe8
envp:     0x7fffa05a7fe8
----Added NEW_VAR----
environ:  0x5646431276b0
envp:     0x7fffa05a7fe8

Usa la variabile envp per scorrere le variabili d’ambiente definite in C

L’esempio di codice precedente dimostra perché si dovrebbe evitare di recuperare le variabili d’ambiente usando l’argomento della funzione main envp dopo aver chiamato la funzione setenv. Quando viene chiamata la funzione setenv, l’ambiente viene riposizionato, ma envp punta ancora al vecchio ambiente. Il seguente codice di esempio dimostra il comportamento errato definendo una nuova variabile con la chiamata setenv e quindi iterando attraverso l’array di puntatori envp. Nota che utilizziamo anche l’istruzione goto per saltare alla fine del bucle se viene trovata la variabile denominata NEW_VAR.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, const char *argv[], const char *envp[]) {
  if (setenv("NEW_VAR", "new_value", 1) != 0) {
    perror("setenv");
    exit(EXIT_FAILURE);
  }

  if (envp != NULL) {
    for (size_t i = 0; envp[i] != NULL; ++i) {
      if (strcmp(envp[i], "NEW_VAR=new_value") == 0) {
        puts(envp[i]);
        goto END;
      }
    }
    printf("No such variable found!\n");
  }
END:

  exit(EXIT_SUCCESS);
}

Produzione:

No such variable found!

Usa la variabile environ per scorrere le variabili d’ambiente definite in C

Poiché la soluzione precedente non riesce a trovare la variabile appena definita, dovremmo usare la variabile environment dichiarata esternamente. In questo caso, abbiamo incluso più istruzioni condizionali del preprocessore per rendere il codice portabile tra i diversi sistemi, ma sulla maggior parte dei sistemi basati su UNIX è necessario solo extern char **environ. Una volta dichiarato, possiamo scorrere l’lista delle variabili utilizzando lo stesso bucle che abbiamo implementato nell’esempio precedente.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#if defined(_POSIX_) || defined(__USE_POSIX)
extern char **environ;
#elif defined(_WIN32)
_CRTIMP extern char **_environ;
#endif

int main(void) {
  if (setenv("NEW_VAR", "new_value", 1) != 0) {
    perror("setenv");
    exit(EXIT_FAILURE);
  }

  if (environ != NULL) {
    for (size_t i = 0; environ[i] != NULL; ++i) {
      if (strcmp(environ[i], "NEW_VAR=new_value") == 0) {
        puts(environ[i]);
        goto END;
      }
    }
    printf("No such variable found!\n");
  }
END:

  exit(EXIT_SUCCESS);
}

Produzione:

NEW_VAR=new_value
Autore: 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