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;
}
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 wasexec
ed 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 variableenviron
:
extern char **environ;
Access to specific environment variables is normally through the
getenv
andputenv
functions, described in Section 7.9,
instead of through the environ variable. But to go through the
entire environment, theenviron
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
add a comment |
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 wasexec
ed 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 variableenviron
:
extern char **environ;
Access to specific environment variables is normally through the
getenv
andputenv
functions, described in Section 7.9,
instead of through the environ variable. But to go through the
entire environment, theenviron
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
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
add a comment |
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 wasexec
ed 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 variableenviron
:
extern char **environ;
Access to specific environment variables is normally through the
getenv
andputenv
functions, described in Section 7.9,
instead of through the environ variable. But to go through the
entire environment, theenviron
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
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 wasexec
ed 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 variableenviron
:
extern char **environ;
Access to specific environment variables is normally through the
getenv
andputenv
functions, described in Section 7.9,
instead of through the environ variable. But to go through the
entire environment, theenviron
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
linux environment-variables exec api
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
add a comment |
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
add a comment |
1 Answer
1
active
oldest
votes
/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()
andputenv()
for examining and modifying the environment - the
exec*
family of functions (not inlcudingexecve
) which either implicitly (viaenviron
) 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.
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 theprctl()
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 likeint main(){ strcpy(getenv("PATH"), "/no/where"); poll(0, 0, -1); }
followed bygrep -z ^PATH /proc/PID/environ
.
– mosvy
Aug 15 at 5:11
@mosvy The relocation you mention happens very fast. Try changing an environment variable withsetenv()
, 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 withsetenv()
and see how the variableenviron
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 (viaprctl(PR_SET_MM_ENV_START)
), or to implement it fully in userland (viaprocess_vm_readv()
or/proc/PID/mem
). And the waysetenv()
works in glibc is just an implementation detail.
– mosvy
Aug 16 at 2:47
|
show 1 more comment
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
/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()
andputenv()
for examining and modifying the environment - the
exec*
family of functions (not inlcudingexecve
) which either implicitly (viaenviron
) 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.
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 theprctl()
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 likeint main(){ strcpy(getenv("PATH"), "/no/where"); poll(0, 0, -1); }
followed bygrep -z ^PATH /proc/PID/environ
.
– mosvy
Aug 15 at 5:11
@mosvy The relocation you mention happens very fast. Try changing an environment variable withsetenv()
, 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 withsetenv()
and see how the variableenviron
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 (viaprctl(PR_SET_MM_ENV_START)
), or to implement it fully in userland (viaprocess_vm_readv()
or/proc/PID/mem
). And the waysetenv()
works in glibc is just an implementation detail.
– mosvy
Aug 16 at 2:47
|
show 1 more comment
/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()
andputenv()
for examining and modifying the environment - the
exec*
family of functions (not inlcudingexecve
) which either implicitly (viaenviron
) 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.
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 theprctl()
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 likeint main(){ strcpy(getenv("PATH"), "/no/where"); poll(0, 0, -1); }
followed bygrep -z ^PATH /proc/PID/environ
.
– mosvy
Aug 15 at 5:11
@mosvy The relocation you mention happens very fast. Try changing an environment variable withsetenv()
, 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 withsetenv()
and see how the variableenviron
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 (viaprctl(PR_SET_MM_ENV_START)
), or to implement it fully in userland (viaprocess_vm_readv()
or/proc/PID/mem
). And the waysetenv()
works in glibc is just an implementation detail.
– mosvy
Aug 16 at 2:47
|
show 1 more comment
/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()
andputenv()
for examining and modifying the environment - the
exec*
family of functions (not inlcudingexecve
) which either implicitly (viaenviron
) 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.
/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()
andputenv()
for examining and modifying the environment - the
exec*
family of functions (not inlcudingexecve
) which either implicitly (viaenviron
) 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.
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 theprctl()
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 likeint main(){ strcpy(getenv("PATH"), "/no/where"); poll(0, 0, -1); }
followed bygrep -z ^PATH /proc/PID/environ
.
– mosvy
Aug 15 at 5:11
@mosvy The relocation you mention happens very fast. Try changing an environment variable withsetenv()
, 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 withsetenv()
and see how the variableenviron
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 (viaprctl(PR_SET_MM_ENV_START)
), or to implement it fully in userland (viaprocess_vm_readv()
or/proc/PID/mem
). And the waysetenv()
works in glibc is just an implementation detail.
– mosvy
Aug 16 at 2:47
|
show 1 more comment
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 theprctl()
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 likeint main(){ strcpy(getenv("PATH"), "/no/where"); poll(0, 0, -1); }
followed bygrep -z ^PATH /proc/PID/environ
.
– mosvy
Aug 15 at 5:11
@mosvy The relocation you mention happens very fast. Try changing an environment variable withsetenv()
, 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 withsetenv()
and see how the variableenviron
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 (viaprctl(PR_SET_MM_ENV_START)
), or to implement it fully in userland (viaprocess_vm_readv()
or/proc/PID/mem
). And the waysetenv()
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
|
show 1 more comment
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
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