Do the strings accessible via global variable `environ` not reflect any change to the environment?change...

How do slats reduce stall speed?

Do living authors still get paid royalties for their old work?

Chord with lyrics - What does it mean if there is an empty space instead of a Chord?

Unsolved Problems (Not Independent of ZFC) due to Lack of Computational Power

Unbiased estimator of exponential of measure of a set?

Best Practice: dependency on data model names

Can others monetize my project with GPLv3?

Why should someone be willing to write a strong recommendation even if that means losing a undergraduate from their lab?

Multicolumn in table not centered

Does Denmark lose almost $700 million a year "carrying" Greenland?

Why don't sharp and flat root note chords seem to be present in much guitar music?

!I!n!s!e!r!t! !n!b!e!t!w!e!e!n!

Would it be illegal for Facebook to actively promote a political agenda?

How can I pack my food so it doesn't smell?

Label on a bended arrow

Should my "average" PC be able to discern the potential of encountering a gelatinous cube from subtle clues?

I think my coworker went through my notebook and took my project ideas

How can I describe being temporarily stupid?

Repurpose telephone line to ethernet

How do you call it when two celestial bodies come as close to each other as they will in their current orbits?

How to avoid using System.String with Rfc2898DeriveBytes in C#

How to dismiss intrusive questions from a colleague with whom I don't work?

Why doesn't mathematics collapse down, even though humans quite often make mistakes in their proofs?

Church Booleans



Do the strings accessible via global variable `environ` not reflect any change to the environment?


change /proc/PID/environ after process startWhy doesn't unsetenv() modify /proc/pid/environ?Is there a bash builtin command which can show the environment variables of the current shell?How to change locale environment variable?Where is the environment string actual stored?Any other way to define an environment variable?Environment variable for command called via niceThe environment given to a program vs the execution environment in which the program is invokedCannot change the environment variableSetting the global value of an environment variable after loginWhat happens to memory when we use putenv() on an environment variable which already exists?






.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ margin-bottom:0;
}







2















From https://unix.stackexchange.com/a/436631/674




the file /proc/$$/environ ... does not reflect any changes to the environment, but just reports what the program received when it was execed by the process.




From APUE:




Each program is also passed an environment list. Like the
argument list, the environment list is an array of character
pointers, with each pointer containing the address of a
null-terminated C string. The address of the array of pointers is
contained in the global variable environ:



extern char **environ;


Access to specific environment variables is normally through the
getenv and putenv functions, described in Section 7.9,
instead of through the environ variable. But to go through the
entire environment, the environ pointer must be used.




Are /proc/$$/environ and the global variable environ independent from each other or consistent with each other?



Do the strings accessed via environ also not reflect any changes to the environment, but just reports the environment received by execve()?



Or do the strings accessed via environ always reflect any change to them, just like that getenv always get the up-to-date environment strings?



Do the strings accessed via getenv always reflect any change and are always up-to-date?



Thanks.










share|improve this question






















  • 1





    This ground has already been covered at unix.stackexchange.com/questions/302970 and unix.stackexchange.com/questions/302948 .

    – JdeBP
    Apr 16 '18 at 5:02


















2















From https://unix.stackexchange.com/a/436631/674




the file /proc/$$/environ ... does not reflect any changes to the environment, but just reports what the program received when it was execed by the process.




From APUE:




Each program is also passed an environment list. Like the
argument list, the environment list is an array of character
pointers, with each pointer containing the address of a
null-terminated C string. The address of the array of pointers is
contained in the global variable environ:



extern char **environ;


Access to specific environment variables is normally through the
getenv and putenv functions, described in Section 7.9,
instead of through the environ variable. But to go through the
entire environment, the environ pointer must be used.




Are /proc/$$/environ and the global variable environ independent from each other or consistent with each other?



Do the strings accessed via environ also not reflect any changes to the environment, but just reports the environment received by execve()?



Or do the strings accessed via environ always reflect any change to them, just like that getenv always get the up-to-date environment strings?



Do the strings accessed via getenv always reflect any change and are always up-to-date?



Thanks.










share|improve this question






















  • 1





    This ground has already been covered at unix.stackexchange.com/questions/302970 and unix.stackexchange.com/questions/302948 .

    – JdeBP
    Apr 16 '18 at 5:02














2












2








2


1






From https://unix.stackexchange.com/a/436631/674




the file /proc/$$/environ ... does not reflect any changes to the environment, but just reports what the program received when it was execed by the process.




From APUE:




Each program is also passed an environment list. Like the
argument list, the environment list is an array of character
pointers, with each pointer containing the address of a
null-terminated C string. The address of the array of pointers is
contained in the global variable environ:



extern char **environ;


Access to specific environment variables is normally through the
getenv and putenv functions, described in Section 7.9,
instead of through the environ variable. But to go through the
entire environment, the environ pointer must be used.




Are /proc/$$/environ and the global variable environ independent from each other or consistent with each other?



Do the strings accessed via environ also not reflect any changes to the environment, but just reports the environment received by execve()?



Or do the strings accessed via environ always reflect any change to them, just like that getenv always get the up-to-date environment strings?



Do the strings accessed via getenv always reflect any change and are always up-to-date?



Thanks.










share|improve this question
















From https://unix.stackexchange.com/a/436631/674




the file /proc/$$/environ ... does not reflect any changes to the environment, but just reports what the program received when it was execed by the process.




From APUE:




Each program is also passed an environment list. Like the
argument list, the environment list is an array of character
pointers, with each pointer containing the address of a
null-terminated C string. The address of the array of pointers is
contained in the global variable environ:



extern char **environ;


Access to specific environment variables is normally through the
getenv and putenv functions, described in Section 7.9,
instead of through the environ variable. But to go through the
entire environment, the environ pointer must be used.




Are /proc/$$/environ and the global variable environ independent from each other or consistent with each other?



Do the strings accessed via environ also not reflect any changes to the environment, but just reports the environment received by execve()?



Or do the strings accessed via environ always reflect any change to them, just like that getenv always get the up-to-date environment strings?



Do the strings accessed via getenv always reflect any change and are always up-to-date?



Thanks.







linux environment-variables exec api






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited 2 days ago









mosvy

15.9k2 gold badges19 silver badges51 bronze badges




15.9k2 gold badges19 silver badges51 bronze badges










asked Apr 16 '18 at 3:17









TimTim

30.4k89 gold badges293 silver badges538 bronze badges




30.4k89 gold badges293 silver badges538 bronze badges











  • 1





    This ground has already been covered at unix.stackexchange.com/questions/302970 and unix.stackexchange.com/questions/302948 .

    – JdeBP
    Apr 16 '18 at 5:02














  • 1





    This ground has already been covered at unix.stackexchange.com/questions/302970 and unix.stackexchange.com/questions/302948 .

    – JdeBP
    Apr 16 '18 at 5:02








1




1





This ground has already been covered at unix.stackexchange.com/questions/302970 and unix.stackexchange.com/questions/302948 .

– JdeBP
Apr 16 '18 at 5:02





This ground has already been covered at unix.stackexchange.com/questions/302970 and unix.stackexchange.com/questions/302948 .

– JdeBP
Apr 16 '18 at 5:02










1 Answer
1






active

oldest

votes


















2














/proc/$$/environ and the variable environ are independent. environ does reflect changes to the environment, and in fact the value of the pointer in environ also changes when environment variables are added to the environment via putenv() (but this is an implementation detail.)



We'll have to distinguish between the system call level, and the library level. At the system call level, the only mechanism related to the environment is the envp argument to the execve call. This parameter is expected to contain name=value pairs that make up the environment of the new program. This environment is copied to the stack of the new process, where the user space startup code can pick it up.



At the library level, we have




  • the global variable environ, which points to a copy of the environment

  • the functions getenv() and putenv() for examining and modifying the environment

  • the exec* family of functions (not inlcuding execve) which either implicitly (via environ) or explicitly (passed via a parameter) access the environment


The exec* library functions ultimately call the execve system call. The environ variable does not point to the environment on the stack; instead the environment is copied to the process heap before the environ variable is set up (this is again an implementation detail.)



Why doesn't /proc/$$/environ reflect changes to the environment? /proc/$$/environ is a virtual file provided by the kernel, and the kernel has no way of knowing what is going on at this low level in the address space in a user process. The kernel has no knowledge of the environ variable, and is unaware of the data structures used by the process to store the environment.






share|improve this answer




























  • Psst! This is no longer the only mechanism at the system call level. See unix.stackexchange.com/a/438007/5132 .

    – JdeBP
    Apr 16 '18 at 6:26











  • The link describes the prctl() system call with which you can, among other things, tell the kernel where in the process' memory the environment variables are stored, so /proc/$$/environ can reflect the updated environment. The process itself has to make the call. prctl() also assumes the variables are stored in the conventional way, and on the stack. But a process is free to do what it wants with the environment, including copying it to the heap, using a different data structure, etc. A shell might want to mix the environment with its internal (not yet exported) variables.

    – Johan Myréen
    Apr 16 '18 at 13:43











  • The last paragraph is kind of misleading -- the /proc/PID/environ really works by copying live stuff from the address space of the process. /proc/PID/environ will only stop reflecting the process' environment when the either the environment strings or the whole list (char **environ) has been relocated elsewhere. Just try it with a simple program like int main(){ strcpy(getenv("PATH"), "/no/where"); poll(0, 0, -1); } followed by grep -z ^PATH /proc/PID/environ.

    – mosvy
    Aug 15 at 5:11











  • @mosvy The relocation you mention happens very fast. Try changing an environment variable with setenv(), and you'll find the new string is allocated on the heap, and the change is not reflected by /proc/PID/environ. Or add a variable with setenv() and see how the variable environ now points to the heap. Yes, stuff is copied from the address space of the process, and you can poke new values to this array, but there is no guarantee that it is at all part of the data structures that libc uses to pass as the environment to a new process.

    – Johan Myréen
    Aug 15 at 17:07











  • That doesn't matter. The kernel has all the ways of knowing what is going in the address space of a process -- it's just a matter of convenience how deep it goes. It's not like /proc/PID/environ is the original environment of a process (it may reflect useland changes to it). There are also ways to make it point elsewhere (via prctl(PR_SET_MM_ENV_START)), or to implement it fully in userland (via process_vm_readv() or /proc/PID/mem). And the way setenv() works in glibc is just an implementation detail.

    – mosvy
    Aug 16 at 2:47
















Your Answer








StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "106"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f437997%2fdo-the-strings-accessible-via-global-variable-environ-not-reflect-any-change-t%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes









2














/proc/$$/environ and the variable environ are independent. environ does reflect changes to the environment, and in fact the value of the pointer in environ also changes when environment variables are added to the environment via putenv() (but this is an implementation detail.)



We'll have to distinguish between the system call level, and the library level. At the system call level, the only mechanism related to the environment is the envp argument to the execve call. This parameter is expected to contain name=value pairs that make up the environment of the new program. This environment is copied to the stack of the new process, where the user space startup code can pick it up.



At the library level, we have




  • the global variable environ, which points to a copy of the environment

  • the functions getenv() and putenv() for examining and modifying the environment

  • the exec* family of functions (not inlcuding execve) which either implicitly (via environ) or explicitly (passed via a parameter) access the environment


The exec* library functions ultimately call the execve system call. The environ variable does not point to the environment on the stack; instead the environment is copied to the process heap before the environ variable is set up (this is again an implementation detail.)



Why doesn't /proc/$$/environ reflect changes to the environment? /proc/$$/environ is a virtual file provided by the kernel, and the kernel has no way of knowing what is going on at this low level in the address space in a user process. The kernel has no knowledge of the environ variable, and is unaware of the data structures used by the process to store the environment.






share|improve this answer




























  • Psst! This is no longer the only mechanism at the system call level. See unix.stackexchange.com/a/438007/5132 .

    – JdeBP
    Apr 16 '18 at 6:26











  • The link describes the prctl() system call with which you can, among other things, tell the kernel where in the process' memory the environment variables are stored, so /proc/$$/environ can reflect the updated environment. The process itself has to make the call. prctl() also assumes the variables are stored in the conventional way, and on the stack. But a process is free to do what it wants with the environment, including copying it to the heap, using a different data structure, etc. A shell might want to mix the environment with its internal (not yet exported) variables.

    – Johan Myréen
    Apr 16 '18 at 13:43











  • The last paragraph is kind of misleading -- the /proc/PID/environ really works by copying live stuff from the address space of the process. /proc/PID/environ will only stop reflecting the process' environment when the either the environment strings or the whole list (char **environ) has been relocated elsewhere. Just try it with a simple program like int main(){ strcpy(getenv("PATH"), "/no/where"); poll(0, 0, -1); } followed by grep -z ^PATH /proc/PID/environ.

    – mosvy
    Aug 15 at 5:11











  • @mosvy The relocation you mention happens very fast. Try changing an environment variable with setenv(), and you'll find the new string is allocated on the heap, and the change is not reflected by /proc/PID/environ. Or add a variable with setenv() and see how the variable environ now points to the heap. Yes, stuff is copied from the address space of the process, and you can poke new values to this array, but there is no guarantee that it is at all part of the data structures that libc uses to pass as the environment to a new process.

    – Johan Myréen
    Aug 15 at 17:07











  • That doesn't matter. The kernel has all the ways of knowing what is going in the address space of a process -- it's just a matter of convenience how deep it goes. It's not like /proc/PID/environ is the original environment of a process (it may reflect useland changes to it). There are also ways to make it point elsewhere (via prctl(PR_SET_MM_ENV_START)), or to implement it fully in userland (via process_vm_readv() or /proc/PID/mem). And the way setenv() works in glibc is just an implementation detail.

    – mosvy
    Aug 16 at 2:47


















2














/proc/$$/environ and the variable environ are independent. environ does reflect changes to the environment, and in fact the value of the pointer in environ also changes when environment variables are added to the environment via putenv() (but this is an implementation detail.)



We'll have to distinguish between the system call level, and the library level. At the system call level, the only mechanism related to the environment is the envp argument to the execve call. This parameter is expected to contain name=value pairs that make up the environment of the new program. This environment is copied to the stack of the new process, where the user space startup code can pick it up.



At the library level, we have




  • the global variable environ, which points to a copy of the environment

  • the functions getenv() and putenv() for examining and modifying the environment

  • the exec* family of functions (not inlcuding execve) which either implicitly (via environ) or explicitly (passed via a parameter) access the environment


The exec* library functions ultimately call the execve system call. The environ variable does not point to the environment on the stack; instead the environment is copied to the process heap before the environ variable is set up (this is again an implementation detail.)



Why doesn't /proc/$$/environ reflect changes to the environment? /proc/$$/environ is a virtual file provided by the kernel, and the kernel has no way of knowing what is going on at this low level in the address space in a user process. The kernel has no knowledge of the environ variable, and is unaware of the data structures used by the process to store the environment.






share|improve this answer




























  • Psst! This is no longer the only mechanism at the system call level. See unix.stackexchange.com/a/438007/5132 .

    – JdeBP
    Apr 16 '18 at 6:26











  • The link describes the prctl() system call with which you can, among other things, tell the kernel where in the process' memory the environment variables are stored, so /proc/$$/environ can reflect the updated environment. The process itself has to make the call. prctl() also assumes the variables are stored in the conventional way, and on the stack. But a process is free to do what it wants with the environment, including copying it to the heap, using a different data structure, etc. A shell might want to mix the environment with its internal (not yet exported) variables.

    – Johan Myréen
    Apr 16 '18 at 13:43











  • The last paragraph is kind of misleading -- the /proc/PID/environ really works by copying live stuff from the address space of the process. /proc/PID/environ will only stop reflecting the process' environment when the either the environment strings or the whole list (char **environ) has been relocated elsewhere. Just try it with a simple program like int main(){ strcpy(getenv("PATH"), "/no/where"); poll(0, 0, -1); } followed by grep -z ^PATH /proc/PID/environ.

    – mosvy
    Aug 15 at 5:11











  • @mosvy The relocation you mention happens very fast. Try changing an environment variable with setenv(), and you'll find the new string is allocated on the heap, and the change is not reflected by /proc/PID/environ. Or add a variable with setenv() and see how the variable environ now points to the heap. Yes, stuff is copied from the address space of the process, and you can poke new values to this array, but there is no guarantee that it is at all part of the data structures that libc uses to pass as the environment to a new process.

    – Johan Myréen
    Aug 15 at 17:07











  • That doesn't matter. The kernel has all the ways of knowing what is going in the address space of a process -- it's just a matter of convenience how deep it goes. It's not like /proc/PID/environ is the original environment of a process (it may reflect useland changes to it). There are also ways to make it point elsewhere (via prctl(PR_SET_MM_ENV_START)), or to implement it fully in userland (via process_vm_readv() or /proc/PID/mem). And the way setenv() works in glibc is just an implementation detail.

    – mosvy
    Aug 16 at 2:47
















2












2








2







/proc/$$/environ and the variable environ are independent. environ does reflect changes to the environment, and in fact the value of the pointer in environ also changes when environment variables are added to the environment via putenv() (but this is an implementation detail.)



We'll have to distinguish between the system call level, and the library level. At the system call level, the only mechanism related to the environment is the envp argument to the execve call. This parameter is expected to contain name=value pairs that make up the environment of the new program. This environment is copied to the stack of the new process, where the user space startup code can pick it up.



At the library level, we have




  • the global variable environ, which points to a copy of the environment

  • the functions getenv() and putenv() for examining and modifying the environment

  • the exec* family of functions (not inlcuding execve) which either implicitly (via environ) or explicitly (passed via a parameter) access the environment


The exec* library functions ultimately call the execve system call. The environ variable does not point to the environment on the stack; instead the environment is copied to the process heap before the environ variable is set up (this is again an implementation detail.)



Why doesn't /proc/$$/environ reflect changes to the environment? /proc/$$/environ is a virtual file provided by the kernel, and the kernel has no way of knowing what is going on at this low level in the address space in a user process. The kernel has no knowledge of the environ variable, and is unaware of the data structures used by the process to store the environment.






share|improve this answer















/proc/$$/environ and the variable environ are independent. environ does reflect changes to the environment, and in fact the value of the pointer in environ also changes when environment variables are added to the environment via putenv() (but this is an implementation detail.)



We'll have to distinguish between the system call level, and the library level. At the system call level, the only mechanism related to the environment is the envp argument to the execve call. This parameter is expected to contain name=value pairs that make up the environment of the new program. This environment is copied to the stack of the new process, where the user space startup code can pick it up.



At the library level, we have




  • the global variable environ, which points to a copy of the environment

  • the functions getenv() and putenv() for examining and modifying the environment

  • the exec* family of functions (not inlcuding execve) which either implicitly (via environ) or explicitly (passed via a parameter) access the environment


The exec* library functions ultimately call the execve system call. The environ variable does not point to the environment on the stack; instead the environment is copied to the process heap before the environ variable is set up (this is again an implementation detail.)



Why doesn't /proc/$$/environ reflect changes to the environment? /proc/$$/environ is a virtual file provided by the kernel, and the kernel has no way of knowing what is going on at this low level in the address space in a user process. The kernel has no knowledge of the environ variable, and is unaware of the data structures used by the process to store the environment.







share|improve this answer














share|improve this answer



share|improve this answer








edited Apr 16 '18 at 7:07

























answered Apr 16 '18 at 6:17









Johan MyréenJohan Myréen

8,7791 gold badge19 silver badges29 bronze badges




8,7791 gold badge19 silver badges29 bronze badges
















  • Psst! This is no longer the only mechanism at the system call level. See unix.stackexchange.com/a/438007/5132 .

    – JdeBP
    Apr 16 '18 at 6:26











  • The link describes the prctl() system call with which you can, among other things, tell the kernel where in the process' memory the environment variables are stored, so /proc/$$/environ can reflect the updated environment. The process itself has to make the call. prctl() also assumes the variables are stored in the conventional way, and on the stack. But a process is free to do what it wants with the environment, including copying it to the heap, using a different data structure, etc. A shell might want to mix the environment with its internal (not yet exported) variables.

    – Johan Myréen
    Apr 16 '18 at 13:43











  • The last paragraph is kind of misleading -- the /proc/PID/environ really works by copying live stuff from the address space of the process. /proc/PID/environ will only stop reflecting the process' environment when the either the environment strings or the whole list (char **environ) has been relocated elsewhere. Just try it with a simple program like int main(){ strcpy(getenv("PATH"), "/no/where"); poll(0, 0, -1); } followed by grep -z ^PATH /proc/PID/environ.

    – mosvy
    Aug 15 at 5:11











  • @mosvy The relocation you mention happens very fast. Try changing an environment variable with setenv(), and you'll find the new string is allocated on the heap, and the change is not reflected by /proc/PID/environ. Or add a variable with setenv() and see how the variable environ now points to the heap. Yes, stuff is copied from the address space of the process, and you can poke new values to this array, but there is no guarantee that it is at all part of the data structures that libc uses to pass as the environment to a new process.

    – Johan Myréen
    Aug 15 at 17:07











  • That doesn't matter. The kernel has all the ways of knowing what is going in the address space of a process -- it's just a matter of convenience how deep it goes. It's not like /proc/PID/environ is the original environment of a process (it may reflect useland changes to it). There are also ways to make it point elsewhere (via prctl(PR_SET_MM_ENV_START)), or to implement it fully in userland (via process_vm_readv() or /proc/PID/mem). And the way setenv() works in glibc is just an implementation detail.

    – mosvy
    Aug 16 at 2:47





















  • Psst! This is no longer the only mechanism at the system call level. See unix.stackexchange.com/a/438007/5132 .

    – JdeBP
    Apr 16 '18 at 6:26











  • The link describes the prctl() system call with which you can, among other things, tell the kernel where in the process' memory the environment variables are stored, so /proc/$$/environ can reflect the updated environment. The process itself has to make the call. prctl() also assumes the variables are stored in the conventional way, and on the stack. But a process is free to do what it wants with the environment, including copying it to the heap, using a different data structure, etc. A shell might want to mix the environment with its internal (not yet exported) variables.

    – Johan Myréen
    Apr 16 '18 at 13:43











  • The last paragraph is kind of misleading -- the /proc/PID/environ really works by copying live stuff from the address space of the process. /proc/PID/environ will only stop reflecting the process' environment when the either the environment strings or the whole list (char **environ) has been relocated elsewhere. Just try it with a simple program like int main(){ strcpy(getenv("PATH"), "/no/where"); poll(0, 0, -1); } followed by grep -z ^PATH /proc/PID/environ.

    – mosvy
    Aug 15 at 5:11











  • @mosvy The relocation you mention happens very fast. Try changing an environment variable with setenv(), and you'll find the new string is allocated on the heap, and the change is not reflected by /proc/PID/environ. Or add a variable with setenv() and see how the variable environ now points to the heap. Yes, stuff is copied from the address space of the process, and you can poke new values to this array, but there is no guarantee that it is at all part of the data structures that libc uses to pass as the environment to a new process.

    – Johan Myréen
    Aug 15 at 17:07











  • That doesn't matter. The kernel has all the ways of knowing what is going in the address space of a process -- it's just a matter of convenience how deep it goes. It's not like /proc/PID/environ is the original environment of a process (it may reflect useland changes to it). There are also ways to make it point elsewhere (via prctl(PR_SET_MM_ENV_START)), or to implement it fully in userland (via process_vm_readv() or /proc/PID/mem). And the way setenv() works in glibc is just an implementation detail.

    – mosvy
    Aug 16 at 2:47



















Psst! This is no longer the only mechanism at the system call level. See unix.stackexchange.com/a/438007/5132 .

– JdeBP
Apr 16 '18 at 6:26





Psst! This is no longer the only mechanism at the system call level. See unix.stackexchange.com/a/438007/5132 .

– JdeBP
Apr 16 '18 at 6:26













The link describes the prctl() system call with which you can, among other things, tell the kernel where in the process' memory the environment variables are stored, so /proc/$$/environ can reflect the updated environment. The process itself has to make the call. prctl() also assumes the variables are stored in the conventional way, and on the stack. But a process is free to do what it wants with the environment, including copying it to the heap, using a different data structure, etc. A shell might want to mix the environment with its internal (not yet exported) variables.

– Johan Myréen
Apr 16 '18 at 13:43





The link describes the prctl() system call with which you can, among other things, tell the kernel where in the process' memory the environment variables are stored, so /proc/$$/environ can reflect the updated environment. The process itself has to make the call. prctl() also assumes the variables are stored in the conventional way, and on the stack. But a process is free to do what it wants with the environment, including copying it to the heap, using a different data structure, etc. A shell might want to mix the environment with its internal (not yet exported) variables.

– Johan Myréen
Apr 16 '18 at 13:43













The last paragraph is kind of misleading -- the /proc/PID/environ really works by copying live stuff from the address space of the process. /proc/PID/environ will only stop reflecting the process' environment when the either the environment strings or the whole list (char **environ) has been relocated elsewhere. Just try it with a simple program like int main(){ strcpy(getenv("PATH"), "/no/where"); poll(0, 0, -1); } followed by grep -z ^PATH /proc/PID/environ.

– mosvy
Aug 15 at 5:11





The last paragraph is kind of misleading -- the /proc/PID/environ really works by copying live stuff from the address space of the process. /proc/PID/environ will only stop reflecting the process' environment when the either the environment strings or the whole list (char **environ) has been relocated elsewhere. Just try it with a simple program like int main(){ strcpy(getenv("PATH"), "/no/where"); poll(0, 0, -1); } followed by grep -z ^PATH /proc/PID/environ.

– mosvy
Aug 15 at 5:11













@mosvy The relocation you mention happens very fast. Try changing an environment variable with setenv(), and you'll find the new string is allocated on the heap, and the change is not reflected by /proc/PID/environ. Or add a variable with setenv() and see how the variable environ now points to the heap. Yes, stuff is copied from the address space of the process, and you can poke new values to this array, but there is no guarantee that it is at all part of the data structures that libc uses to pass as the environment to a new process.

– Johan Myréen
Aug 15 at 17:07





@mosvy The relocation you mention happens very fast. Try changing an environment variable with setenv(), and you'll find the new string is allocated on the heap, and the change is not reflected by /proc/PID/environ. Or add a variable with setenv() and see how the variable environ now points to the heap. Yes, stuff is copied from the address space of the process, and you can poke new values to this array, but there is no guarantee that it is at all part of the data structures that libc uses to pass as the environment to a new process.

– Johan Myréen
Aug 15 at 17:07













That doesn't matter. The kernel has all the ways of knowing what is going in the address space of a process -- it's just a matter of convenience how deep it goes. It's not like /proc/PID/environ is the original environment of a process (it may reflect useland changes to it). There are also ways to make it point elsewhere (via prctl(PR_SET_MM_ENV_START)), or to implement it fully in userland (via process_vm_readv() or /proc/PID/mem). And the way setenv() works in glibc is just an implementation detail.

– mosvy
Aug 16 at 2:47







That doesn't matter. The kernel has all the ways of knowing what is going in the address space of a process -- it's just a matter of convenience how deep it goes. It's not like /proc/PID/environ is the original environment of a process (it may reflect useland changes to it). There are also ways to make it point elsewhere (via prctl(PR_SET_MM_ENV_START)), or to implement it fully in userland (via process_vm_readv() or /proc/PID/mem). And the way setenv() works in glibc is just an implementation detail.

– mosvy
Aug 16 at 2:47




















draft saved

draft discarded




















































Thanks for contributing an answer to Unix & Linux Stack Exchange!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f437997%2fdo-the-strings-accessible-via-global-variable-environ-not-reflect-any-change-t%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Taj Mahal Inhaltsverzeichnis Aufbau | Geschichte | 350-Jahr-Feier | Heutige Bedeutung | Siehe auch |...

Baia Sprie Cuprins Etimologie | Istorie | Demografie | Politică și administrație | Arii naturale...

Nicolae Petrescu-Găină Cuprins Biografie | Opera | In memoriam | Varia | Controverse, incertitudini...