Zugriff auf Umgebungsvariablen mit der Funktion setenv in C

Jinku Hu 12 Oktober 2023
  1. Exportieren von Umgebungsvariablen mit der Funktion setenv in C
  2. Verwendung der Variable envp zur Iteration durch definierte Umgebungsvariablen in C
  3. Verwendung der Variable environ zur Iteration durch definierte Umgebungsvariablen in C
Zugriff auf Umgebungsvariablen mit der Funktion setenv in C

In diesem Artikel werden verschiedene Methoden zum Exportieren von Umgebungsvariablen mit der Funktion setenv in C erläutert.

Exportieren von Umgebungsvariablen mit der Funktion setenv in C

Jedes laufende Programm auf Unix-basierten Systemen hat eine Umgebung, die Variablen-Wert-Paare sammelt, die hauptsächlich von Shell- und anderen User-Space-Programmen verwendet werden. Das Programm kann eine einzelne Umgebungsvariable und ihren Wert mit der Funktion getenv abrufen. Soll aber eine neue Variable definiert oder die vorhandene geändert werden, muss die Funktion setenv aufgerufen werden. Sie nimmt drei Argumente entgegen, von denen das erste und das zweite char-Zeiger sind, die auf den Variablennamen bzw. seinen Wert zeigen. Das dritte Argument ist vom Typ int und gibt an, ob der Wert der angegebenen Variable überschrieben werden soll, wenn er bereits in der Umgebung existiert. Ein Wert ungleich Null dieses Arguments bedeutet Überschreibverhalten und ein Wert von Null das Gegenteil.

Beachten Sie jedoch, dass die Iteration durch alle definierten Umgebungsvariablen den Zugriff auf die spezielle globale Variable namens - environ erfordert, die ein NULL-terminiertes Array von Zeichenketten ist. Alternativ kann man die Funktion main mit dem dritten Argument envp deklarieren, um auf die Variablen zuzugreifen. Im folgenden Beispiel geben wir die Zeiger auf eniron und envp vor und nach dem Aufruf der Funktion setenv aus. Beachten Sie, dass der Zeiger envp nach dem Aufruf den gleichen Wert hat, während environ geändert wurde.

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

Ausgabe:

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

Verwendung der Variable envp zur Iteration durch definierte Umgebungsvariablen in C

Das vorherige Codebeispiel zeigt, warum man es vermeiden sollte, nach dem Aufruf der Funktion setenv Umgebungsvariablen mit dem Argument envp der Funktion main abzurufen. Wenn die Funktion setenv aufgerufen wird, wird die Umgebung verlagert, aber envp zeigt immer noch auf die alte Umgebung. Der folgende Beispielcode demonstriert das fehlerhafte Verhalten, indem er eine neue Variable mit dem Aufruf von setenv definiert und dann durch das Zeigerarray von envp iteriert. Beachten Sie, dass wir auch die Anweisung goto verwenden, um zum Ende der Schleife zu springen, wenn die Variable namens NEW_VAR gefunden wird.

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

Ausgabe:

No such variable found!

Verwendung der Variable environ zur Iteration durch definierte Umgebungsvariablen in C

Da die bisherige Lösung die neu definierte Variable nicht finden kann, sollten wir die extern deklarierte Variable environ verwenden. In diesem Fall haben wir mehrere Präprozessor-Bedingungsanweisungen eingefügt, um den Code über die verschiedenen Systeme hinweg portabel zu machen, aber nur extern char **environ wird auf den meisten UNIX-basierten Systemen benötigt. Nach der Deklaration können wir mit der gleichen Schleife, die wir im vorherigen Beispiel implementiert haben, durch die Liste der Variablen iterieren.

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

Ausgabe:

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