Eryk Sun <eryk...@gmail.com> added the comment:

> Python can safely removes the string to _putenv() just after the call? 

Windows ucrt copies the buffer that's passed to _[w]putenv. This makes it 
non-compliant with POSIX but easier to use in this case. Here's an example 
using ctypes:

    >>> ucrt = ctypes.CDLL('ucrtbase')
    >>> buf = ctypes.create_unicode_buffer('spam=eggs')
    >>> ucrt._wputenv(buf)
    0

Directly modifying the buffer has no effect on the _wgetenv result:

    >>> buf[5] = 'a'
    >>> ucrt._wgetenv.restype = ctypes.POINTER(ctypes.c_wchar)
    >>> ucrt._wgetenv('spam')[:4]
    'eggs'

Linux putenv complies with POSIX, so changing "eggs" to "aggs" in the buffer 
does affect the getenv result in Linux. 

On the other hand, ucrt's [_w]getenv does not copy the environment string. For 
example:

    >>> p1 = ucrt._wgetenv('spam')
    >>> p1[0] = 'o'

    >>> p2 = ucrt._wgetenv('spam')
    >>> p2[:4]
    'oggs'

[_w]getenv is not thread safe. Even though all calls that access the ucrt 
environment are internally synchronized on a common lock, accessing the 
*result* from [_w]getenv still needs to be synchronized with concurrent 
_[w]putenv calls in a multithreaded process. Better still, use [_w]getenv_s or 
_[w]dupenv_s, which returns a copy.

> There is also _wputenv_s which affects _spawn, _exec and system.

The documentation is perhaps misleading. When a variable is set with 
_[w]putenv[_s], it also sets the variable in the process environment block to 
stay in sync. This indirectly affects _spawn*, _exec* and system(). 
common_spawnv (in ucrt\exec\spawnv.cpp), which implements the latter functions, 
calls CreateProcess with lpEnvironment as NULL (i.e.  inherit the current 
process environment), unless the caller passes a new environment (e.g. envp of 
spawnve).

----------

_______________________________________
Python tracker <rep...@bugs.python.org>
<https://bugs.python.org/issue39406>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to