1

Here is my code test.c:

int main(int argc, char* argv[])
{
    char* newhome = getenv("HOME");
    strcat(newhome, "/myDir");
    setenv("HOME", newhome, 1);
    printf("ENV: %s\n", getenv("HOME"));
    printf("ARG: %s\n", argv[1]); 
    return 0;
}

The "HOME" env has been set as "/home/user/myDir" in this program. But when I compile and run my code with the "~/" arg, I get such output that the given "~/" arg is still resolved as the default "HOME" env value "/home/user", but not the new set value "/home/user/myDir":

$ cc test.c -o test
$ ./test ~/
ENV: /home/user/myDir
ARG: /home/user
$

So how should I modify my code to fetch the new set value of "HOME" if I give the arg "~/", such as this output:

$ ./test ~/
ENV: /home/user/myDir
ARG: /home/user/myDir
$ ./test ~/../
ENV: /home/user
ARG: /home/user
Haruka
  • 237
  • 1
  • 2
  • 7
  • 1
    I suspect `~/` is expanded by bash and the C program never sees it. – R Sahu Dec 03 '15 at 07:17
  • 1
    a) `~/` is resolved by the shell before your program runs b) `newhome` is allocated for its value, not the longer string you put in it c) modified environment is visible from your prog and forked processes, not the caller – Déjà vu Dec 03 '15 at 07:17
  • A similar question has already been asked: [Changing a environmental variable through a C program](http://stackoverflow.com/questions/11710029/changing-a-environmental-variable-through-a-c-program) – Thomas Padron-McCarthy Dec 03 '15 at 07:20
  • You have undefined behavior in that code. From [the getenv(3) manual page](http://man7.org/linux/man-pages/man3/getenv.3.html): "As typically implemented, `getenv()` returns a pointer to a string within the environment list. The caller must take care ***not to modify*** this string" (emphasis mine). – Some programmer dude Dec 03 '15 at 07:23
  • Related: http://stackoverflow.com/q/18277177/694576 Same issue with `chdir`. – alk Dec 03 '15 at 07:54

3 Answers3

4

When you run your program, it will run as a separate process. Since each process has its own environment, the setenv call will change the HOME variable in that environment.

When the program exits, you return to the shell process, and its environment. In that environment, there have been no changes to HOME.

Thomas Padron-McCarthy
  • 27,232
  • 8
  • 51
  • 75
2

First of all the arguments to your program are set when the program starts.

Second of all the tilde ~ is expanded by the shell, before it starts your program.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • you're right, the shell resolves the path automatically before the start of my program. But is it possible that if I give an argument ~/, and printf this arg, the output result is just ~/ but not the value of $HOME env, I mean just output the original content what I gave in argument, but not the resolved path. – Haruka Dec 03 '15 at 07:57
  • @Jason If you pass the argument withing quotes, like `"~/"` then the shell will not expand it. – Some programmer dude Dec 03 '15 at 07:59
0

Tilde expansion is performed by the shell before your app runs, so updating the environment variable will not effect the command-line arguments.

keithmo
  • 4,893
  • 1
  • 21
  • 17