Peering into the Environment

The operating system’s environment provides temporary storage for variables, settings, and options. These values are easily accessible from any C program. One of the first posts I made on this blog was about accessing the environment. Time to revisit.

You can view the environment from a terminal window. In Linux, type the env command to see a huge dump of environment variables. For Windows/DOS, type the set command.

The output shows a list of environment variables. It’s often long and detailed. The format for each variable is the same. For example:

HOME=/home/dang

The HOME variable in Linux indicates the user’s home directory. It’s followed by an equal sign, then the home directory path, which is /home/dang for my account on this system.

Internally, the environment exists as a pointer array. It’s a list of addresses, with each address referencing a string. This array exists as a global variable available to any C program. Include the stdlib.h header file to ensure that your system has access to this variable and the various environment function prototypes.

extern char **environ;

To view the environment, you cycle through the pointers stored at **environ until the NULL pointer is encountered:

2024_02_10-Lesson-a.c

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

int main()
{
    extern char **environ;

    while( *environ )
    {
        printf("%s\n",*environ);
        environ++;
    }
    return 0;
}

The **environ variable is declared externally. A while loop processes each address stored at **environ until the NULL is ecountered at the end of the list. A printf() statement outputs each string.

Because environ is a pointer-pointer, its value is the size of an address. Incrementing the environ variable references the next address (string) in the list: environ++

The program’s output is the same as the env or set command’s dump at the command prompt.

You might think that to fetch an item from the list, you use something like this code:

2024_02_10-Lesson-b.c

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

int main()
{
    extern char **environ;

    puts("Search path:");
    while( *environ )
    {
        if( strncmp(*environ,"PATH",4)==0 )
        {
            printf("%s\n",*environ);
            break;
        }
        environ++;
    }

    return 0;
}

This code adds the strncmp() function to the original example. The function scans the first four characters of the *environ string to match PATH. Once found, the search path is output. This output can be quite lengthy, so I’m not duplicating it here.

The environ man page, however, recommends that you not search the environment manually. Instead, use the getenv() function to fetch a specific entry:

2024_02_10-Lesson-c.c

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

int main()
{
    puts("Search path:");
    printf("%s\n",getenv("PATH"));

    return 0;
}

The getenv() function is prototyped in the stdlib.h header file. Its argument is a string matching a variable to find in the environment table. The return value is the variable’s value or NULL when no match is found.

Just as a user can set an environment variable, so can a program. I cover the required tools in next week’s Lesson.

Leave a Reply