How to Access Environment Variables Using setenv Function in C
-
Use the
setenv
Function to Export Environment Variables in C -
Use the
envp
Variable to Iterate Through Defined Environment Variables in C -
Use the
environ
Variable to Iterate Through Defined Environment Variables in C
This article will explain several methods of exporting environment variables using the setenv
function in C.
Use the setenv
Function to Export Environment Variables in C
Each running program on Unix-base systems has an environment that collects variable-value pairs used mainly by shell and other user space programs. The program can retrieve a single environment variable and its value with the getenv
function. But if a new variable should be defined or the existing one changed, the setenv
function should be called. It takes three arguments, the first and second of which are char
pointers pointing to the variable name and its value, respectively. The third argument is of type int
and it specifies whether the value of the given variable should be overwritten if it already exists in the environment. The nonzero value of this argument denotes overwriting behavior and zero value to the opposite.
Note though, iterating through all defined environment variables requires accessing the special global variable called - environ
, which is a NULL-terminated array of character strings. Alternatively, one can declare main
function with the third argument envp
to access variables. In the following example, we print both eniron
and envp
pointers before and after the setenv
function call. Notice that, envp
pointer has the same value after the call, whereas environ
has been changed.
#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);
}
Output:
environ: 0x7fffa05a7fe8
envp: 0x7fffa05a7fe8
----Added NEW_VAR----
environ: 0x5646431276b0
envp: 0x7fffa05a7fe8
Use the envp
Variable to Iterate Through Defined Environment Variables in C
The previous code example demonstrates why one should avoid retrieving environment variables using the main
function argument envp
after calling the setenv
function. When the setenv
function is called, the environment is relocated, but envp
still points to the old environment. The following example code demonstrates the erroneous behavior by defining a new variable with setenv
call and then iterating through envp
pointer array. Note that we also utilize goto
statement to jump to the end of the loop if the variable named NEW_VAR
is found.
#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);
}
Output:
No such variable found!
Use the environ
Variable to Iterate Through Defined Environment Variables in C
Since the previous solution can’t find the newly defined variable, we should use the environ
variable declared externally. In this case, we included multiple preprocessor conditional statements to make the code portable across the different systems, but only extern char **environ
is needed on most UNIX-based systems. Once declared, we can iterate through the list of variables using the same loop we implemented in the previous example.
#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);
}
Output:
NEW_VAR=new_value
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