8

From several websites I read that getenv is a system call. However I cannot find any reference to sys_getenv.

I am trying to understand what "environment variables" are, exactly. Are they part of the kernel or a mechanism of the shell? Digging a little bit deeper I found that getenv is part of standard C library. Unfortunately this doesn't help me to answer my original question.

MariusMatutiae
  • 48,517
  • 12
  • 86
  • 136
nowox
  • 3,017

3 Answers3

13

Do you understand the argument list?  For example, if you type ls -l foo bar, the shell executes /bin/ls with an argument list consisting of four strings:

    ls -l foo bar

whereas, if you type ls -l "foo bar" (or ls -l 'foo bar' or ls -l foo\ bar), the shell executes /bin/ls with an argument list consisting of three strings:

    ls -l foo bar

and ls -l * might get you something like:

    ls -l ant bat cat dog etc

i.e., whatever files are in the current directory.

Well,

the environment is basically just a second argument list.

Perhaps it would be better to say “the environment is a second list of strings, structured exactly like the argument list, but treated differently.”  If you look at execve(2), you’ll see that the execve system call takes three arguments:

  • char *filename,                                (the program to execute; e.g., /bin/ls)
  • char *argv[],
  • char *envp[]

Whenever any program executes any other program, it is basically using execve (possibly via some higher-level function, such as execl), so it is passing an argument list and an environment list.  The environment list looks a lot like the output from env; e.g.,

    HOME=/home/fred USERNAME=fred PATH=/bin:/usr/bin:… TERM=xterm SHELL=/bin/bash PWD=/home/fred/Super_User_files
    etc…

The executed program can do whatever it wants with the environment list — look at it (e.g., with getenv), modify it, or ignore it — the same things it can do with the argument list.  When a program executes another program with one of the higher-level execute functions, like execl, it automatically calls execve with the same environment list that was passed in to the program.  And that’s what happens in 90% of the programs that execute other programs.  But shells let you modify the environment, and then they use execve directly to pass the most up-to-date user-specified environment to every program that it runs.

TL;DR

Every process contains its environment list in memory, the same way it contains its argument list and ordinary variables.  The environment is passed from program to program through the exec mechanism.  Library functions make it easy for a program to pass its own environment to any other program that it runs.  (Naturally, environment is preserved (copied) across a fork, just as all other local memory is.)  The kernel doesn’t really know anything about the environment except for the fact that it provides a means for the environment to be passed through execve.

4

To whom do environment variables belong?

Each process owns its own environment variables.

Notes:

  • Every process has an environment block that contains a set of environment variables and their values.

  • The environment variables are inherited from the parent process and is a copy of the parent block.

  • By default, a child process inherits the environment variables of its parent process.

  • A process may choose to pass a different environment to a child process by creating a new environment block and passing this to the child process when it is created.

  • It's not possible for any process to alter any other process's environment variables.


What is getenv

getenv is function in the Standard C Library.

Name

getenv, secure_getenv - get an environment variable Synopsis

#include <stdlib.h>

char *getenv(const char *name);

char *secure_getenv(const char *name);

Feature Test Macro Requirements for glibc (see feature_test_macros(7)):

secure_getenv(): _GNU_SOURCE

Description

The getenv() function searches the environment list to find the environment variable name, and returns a pointer to the corresponding value string.

The GNU-specific secure_getenv() function is just like getenv() except that it returns NULL in cases where "secure execution" is required.

...

Source getenv(3) - Linux man page


Further reading

getenv() source code


"I am trying to understand what "environment variables" are, exactly."

See the answer https://superuser.com/a/932191/337631 by Scott for a detailed explanation from a coding perspective.

DavidPostill
  • 162,382
2

getenv is part of the Standard C Library. So, in C you would need to include stdlib.h.

Excellll
  • 12,847