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.

1

3 Answers 3

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.

9
  • So, I understood that execve is part of the libc. Inside this function I will found a real system call which should be fork(), is it right?
    – nowox
    Jun 25, 2015 at 6:01
  • 1
    No, no, no.  fork() and exec() (by which I mean the exec family of functions) are related somewhat like a left glove and a right glove; they often go together, and they are conceptually related, but they are not the same thing.  execl() is in libc, but execve() is a system call.  execl() calls execve(), not unlike the way the libc function fprintf() calls the write() system call, and the libc function sleep() calls the alarm() system call.  You can check by typing man foo  —  if the man page comes up as foo(2), it's a syscall; foo(3) is a library function. Jun 25, 2015 at 6:47
  • 1
    @fixer1234 — Thanks, but −1: unclear what you're asking; −1: too broad.  Seriously; I said, “Every process contains its environment list in memory, the same way it contains … ordinary variables.”  Can you clarify what more than that you want?  Would it help if I said, “Every process contains its environment list in user space memory …” ?  Would it help if I said, “Processes ‘own’ their local memory, and can access it directly, without kernel intervention.  An appropriately privileged process may be able to access another process’s local memory via system calls.” ? Jul 11, 2015 at 19:15
  • I reread your answer. What I was asking is sort of in there, implied by the process you describe. No fair making me think. :-)
    – fixer1234
    Jul 12, 2015 at 0:36
  • @fixer1234: I’m glad if you found what you were looking for.  I presume you’ve read What are PATH and other environment variables, and how can I set or use them?; and, if you believe that there’s nothing there that answers the question “What are environment variables?”, I don’t entirely disagree.  user945389’s answer perhaps comes closest: “Environment Variables … store various values to allow programs to get necessary OS information, or ‘Environment’ information.  For example, USERPROFILE and MAIL ….”  … (Cont’d) Jul 13, 2015 at 3:34
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.

7
  • I am cloning glibc to browse the codebase. I want to know what's behind getenv. man won't help me here.
    – nowox
    Jun 24, 2015 at 18:24
  • I've already linked to the source in my answer, as well as giving you a link explaining environment variables. If you don't yet understand what they are then reading the c source code probably won't help you.
    – DavidPostill
    Jun 24, 2015 at 18:31
  • Ok I see that I got confused again and felt into X-Y issue. getenv.c is referring to __environ which is declared in posix/environ.c and then local to the current process. I don't understand how a process can inherit environment variables from its parent.
    – nowox
    Jun 24, 2015 at 18:42
  • @nowox The man page helps very well here. You can detect a link to man 5 environ and there extern char **environ; in it, a table that a process inherits from it's parent, and which you can modify too.
    – ott--
    Jun 24, 2015 at 18:49
  • @David, Environment variables are nothing to do with shells, other than in that they provide a means to manipulate theirs. Environment variables are a part of every process, copied on fork(), and passed to successor with exec(). See Scott's answer. Jul 1, 2015 at 12:28
2

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

3
  • I will need to see the sources of this function to understand what is behind. How this function can get the information from the shell.
    – nowox
    Jun 24, 2015 at 18:08
  • man getenv will bring up the manual page for it in Linux. Jun 24, 2015 at 18:10
  • 1
    @nowox See my answer for a link to a version of the source code (I've no idea whether it is the latest Linux code)
    – DavidPostill
    Jun 24, 2015 at 18:22

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .