Acessar variáveis de ambiente usando a função setenv em C

Jinku Hu 12 outubro 2023
  1. Use a função setenv para exportar variáveis ​​de ambiente em C
  2. Use a variável envp para iterar por meio de variáveis ​​de ambiente definidas em C
  3. Use a variável environ para iterar por meio de variáveis ​​de ambiente definidas em C
Acessar variáveis de ambiente usando a função setenv em C

Este artigo irá explicar vários métodos de exportação de variáveis ​​de ambiente usando a função setenv em C.

Use a função setenv para exportar variáveis ​​de ambiente em C

Cada programa em execução em sistemas baseados em Unix tem um ambiente que coleta pares de valores variáveis ​​usados ​​principalmente por shell e outros programas de espaço do usuário. O programa pode recuperar uma única variável de ambiente e seu valor com a função getenv. Mas se uma nova variável deve ser definida ou a existente alterada, a função setenv deve ser chamada. Leva três argumentos, o primeiro e o segundo dos quais são ponteiros char apontando para o nome da variável e seu valor, respectivamente. O terceiro argumento é do tipo int e especifica se o valor da variável fornecida deve ser sobrescrito se já existir no ambiente. O valor diferente de zero deste argumento denota comportamento de substituição e valor zero para o oposto.

No entanto, observe que a iteração por todas as variáveis ​​de ambiente definidas requer o acesso à variável global especial chamada - environ, que é un array terminada em NULL de cadeias de caracteres. Alternativamente, pode-se declarar a função main com o terceiro argumento envp para acessar variáveis. No exemplo a seguir, imprimimos os ponteiros eniron e envp antes e depois da chamada da função setenv. Observe que, o ponteiro envp tem o mesmo valor após a chamada, enquanto ambi foi alterado.

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

Resultado:

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

Use a variável envp para iterar por meio de variáveis ​​de ambiente definidas em C

O exemplo de código anterior demonstra por que se deve evitar a recuperação de variáveis ​​de ambiente usando o argumento da função main envp depois de chamar a função setenv. Quando a função setenv é chamada, o ambiente é realocado, mas envp ainda aponta para o ambiente antigo. O código de exemplo a seguir demonstra o comportamento errôneo, definindo uma nova variável com a chamada setenv e, em seguida, iterando por meio do array de ponteiro envp. Observe que também utilizamos a instrução goto para pular para o final do loop se a variável chamada NEW_VAR for encontrada.

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

Resultado:

No such variable found!

Use a variável environ para iterar por meio de variáveis ​​de ambiente definidas em C

Uma vez que a solução anterior não consegue encontrar a variável recém-definida, devemos usar a variável Environment declarada externamente. Nesse caso, incluímos várias instruções condicionais de pré-processador para tornar o código portátil entre os diferentes sistemas, mas apenas extern char **environ é necessário na maioria dos sistemas baseados em UNIX. Depois de declarados, podemos iterar pela lista de variáveis ​​usando o mesmo loop que implementamos no exemplo anterior.

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

Resultado:

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