How to change environment variable in shell executing a C program from that C program?
c, shell, unix
Solution
This is impossible. There is no way for a subprocess to change its parent's environment variables.
To understand why it is impossible, look at the signature of `execve`
int execve(const char *program, char *const *argv, char *const *envp);
which is paired with the true signature of `main` on Unix systems
int main(int argc, char **argv, char **envp);
and perhaps you begin to understand that as far as the kernel is concerned, the environment variables are a second set of command line arguments. That they appear to be independently accessible via `getenv` and `setenv` etc, and appear to inherit from parent to child, is an illusion maintained by the C library.
For more detail on how this works, study the x86-64 ELF ABI specification, section 3.4.1 "Initial Stack and Register State" paying particular attention to figure 3.9 which shows the layout of the data copied by `execve` onto the newly created stack. (The document linked is specific to one CPU architecture, but the way this works is generally consistent across modern Unixes; fine details will of course vary from CPU to CPU and OS to OS.)
Problem
I want to change the value of `PATH` variable inside the C program and then see the changed value in the shell using which I run this program. Doing something like this, ``` #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> int main () { char *path = getenv ("PATH"); printf ("%s\n\n", path); setenv ("PATH", strcat (path, ":~/myNewPath/"), 1); printf ("%s\n\n", path); int pid = fork (); if (pid == -1) abort (); if (pid == 0) { } else { // use execlp? how? source? any hints? } return 0; } ``` If I use `source` command in the `exec*` system call. What will be the syntax to update this `PATH` variable in the shell backwards?