bpo-39406: Implement os.putenv() with setenv() if available (GH-18128)
If setenv() C function is available, os.putenv() is now implemented with setenv() instead of putenv(), so Python doesn't have to handle the environment variable memory.
This commit is contained in:
parent
0852c7dd52
commit
b477d19a6b
|
@ -0,0 +1,3 @@
|
||||||
|
If ``setenv()`` C function is available, :func:`os.putenv` is now
|
||||||
|
implemented with ``setenv()`` instead of ``putenv()``, so Python doesn't
|
||||||
|
have to handle the environment variable memory.
|
|
@ -6034,7 +6034,7 @@ exit:
|
||||||
|
|
||||||
#endif /* (defined(HAVE_POSIX_FADVISE) && !defined(POSIX_FADVISE_AIX_BUG)) */
|
#endif /* (defined(HAVE_POSIX_FADVISE) && !defined(POSIX_FADVISE_AIX_BUG)) */
|
||||||
|
|
||||||
#if defined(HAVE_PUTENV) && defined(MS_WINDOWS)
|
#if defined(MS_WINDOWS)
|
||||||
|
|
||||||
PyDoc_STRVAR(os_putenv__doc__,
|
PyDoc_STRVAR(os_putenv__doc__,
|
||||||
"putenv($module, name, value, /)\n"
|
"putenv($module, name, value, /)\n"
|
||||||
|
@ -6080,9 +6080,9 @@ exit:
|
||||||
return return_value;
|
return return_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* defined(HAVE_PUTENV) && defined(MS_WINDOWS) */
|
#endif /* defined(MS_WINDOWS) */
|
||||||
|
|
||||||
#if defined(HAVE_PUTENV) && !defined(MS_WINDOWS)
|
#if ((defined(HAVE_SETENV) || defined(HAVE_PUTENV)) && !defined(MS_WINDOWS))
|
||||||
|
|
||||||
PyDoc_STRVAR(os_putenv__doc__,
|
PyDoc_STRVAR(os_putenv__doc__,
|
||||||
"putenv($module, name, value, /)\n"
|
"putenv($module, name, value, /)\n"
|
||||||
|
@ -6123,7 +6123,7 @@ exit:
|
||||||
return return_value;
|
return return_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* defined(HAVE_PUTENV) && !defined(MS_WINDOWS) */
|
#endif /* ((defined(HAVE_SETENV) || defined(HAVE_PUTENV)) && !defined(MS_WINDOWS)) */
|
||||||
|
|
||||||
#if defined(HAVE_UNSETENV)
|
#if defined(HAVE_UNSETENV)
|
||||||
|
|
||||||
|
@ -8773,4 +8773,4 @@ exit:
|
||||||
#ifndef OS__REMOVE_DLL_DIRECTORY_METHODDEF
|
#ifndef OS__REMOVE_DLL_DIRECTORY_METHODDEF
|
||||||
#define OS__REMOVE_DLL_DIRECTORY_METHODDEF
|
#define OS__REMOVE_DLL_DIRECTORY_METHODDEF
|
||||||
#endif /* !defined(OS__REMOVE_DLL_DIRECTORY_METHODDEF) */
|
#endif /* !defined(OS__REMOVE_DLL_DIRECTORY_METHODDEF) */
|
||||||
/*[clinic end generated code: output=51ba5b9536420cea input=a9049054013a1b77]*/
|
/*[clinic end generated code: output=6f42d8be634f5942 input=a9049054013a1b77]*/
|
||||||
|
|
|
@ -819,19 +819,20 @@ dir_fd_converter(PyObject *o, void *p)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Windows: _wputenv(env) copies the *env* string and doesn't require the
|
/* Windows _wputenv() and setenv() copy the arguments and so don't require
|
||||||
caller to manage the variable memory. */
|
the caller to manage the variable memory. Only Unix putenv() requires
|
||||||
#if defined(HAVE_PUTENV) && !defined(MS_WINDOWS)
|
putenv_dict. */
|
||||||
|
#if defined(HAVE_PUTENV) && !defined(MS_WINDOWS) && !defined(HAVE_SETENV)
|
||||||
# define PY_PUTENV_DICT
|
# define PY_PUTENV_DICT
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
PyObject *billion;
|
PyObject *billion;
|
||||||
#ifdef PY_PUTENV_DICT
|
#ifdef PY_PUTENV_DICT
|
||||||
/* putenv() and _wputenv() requires that the caller manages the environment
|
/* putenv() requires that the caller manages the environment variable
|
||||||
variable memory. Use a Python dictionary for that: name => env, where
|
memory. Use a Python dictionary for that: name => env, where env is a
|
||||||
env is a string like "name=value". On Windows, dict keys and values are
|
string like "name=value". On Windows, dict keys and values are Unicode
|
||||||
Unicode strings. On Unix, they are bytes strings. */
|
strings. On Unix, they are bytes strings. */
|
||||||
PyObject *putenv_dict;
|
PyObject *putenv_dict;
|
||||||
#endif
|
#endif
|
||||||
PyObject *DirEntryType;
|
PyObject *DirEntryType;
|
||||||
|
@ -10081,8 +10082,6 @@ posix_putenv_dict_setitem(PyObject *name, PyObject *value)
|
||||||
#endif /* PY_PUTENV_DICT */
|
#endif /* PY_PUTENV_DICT */
|
||||||
|
|
||||||
|
|
||||||
#ifdef HAVE_PUTENV
|
|
||||||
|
|
||||||
#ifdef MS_WINDOWS
|
#ifdef MS_WINDOWS
|
||||||
/*[clinic input]
|
/*[clinic input]
|
||||||
os.putenv
|
os.putenv
|
||||||
|
@ -10132,8 +10131,6 @@ os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
|
||||||
posix_error();
|
posix_error();
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
/* _wputenv(env) copies the *env* string and doesn't require the caller
|
|
||||||
to manage the variable memory. */
|
|
||||||
Py_DECREF(unicode);
|
Py_DECREF(unicode);
|
||||||
|
|
||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
|
@ -10142,7 +10139,8 @@ error:
|
||||||
Py_DECREF(unicode);
|
Py_DECREF(unicode);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
#else /* MS_WINDOWS */
|
/* repeat !defined(MS_WINDOWS) to workaround an Argument Clinic issue */
|
||||||
|
#elif (defined(HAVE_SETENV) || defined(HAVE_PUTENV)) && !defined(MS_WINDOWS)
|
||||||
/*[clinic input]
|
/*[clinic input]
|
||||||
os.putenv
|
os.putenv
|
||||||
|
|
||||||
|
@ -10157,8 +10155,6 @@ static PyObject *
|
||||||
os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
|
os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
|
||||||
/*[clinic end generated code: output=d29a567d6b2327d2 input=a97bc6152f688d31]*/
|
/*[clinic end generated code: output=d29a567d6b2327d2 input=a97bc6152f688d31]*/
|
||||||
{
|
{
|
||||||
PyObject *bytes = NULL;
|
|
||||||
char *env;
|
|
||||||
const char *name_string = PyBytes_AS_STRING(name);
|
const char *name_string = PyBytes_AS_STRING(name);
|
||||||
const char *value_string = PyBytes_AS_STRING(value);
|
const char *value_string = PyBytes_AS_STRING(value);
|
||||||
|
|
||||||
|
@ -10166,22 +10162,28 @@ os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
|
||||||
PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
|
PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
bytes = PyBytes_FromFormat("%s=%s", name_string, value_string);
|
|
||||||
|
#ifdef HAVE_SETENV
|
||||||
|
if (setenv(name_string, value_string, 1)) {
|
||||||
|
return posix_error();
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
PyObject *bytes = PyBytes_FromFormat("%s=%s", name_string, value_string);
|
||||||
if (bytes == NULL) {
|
if (bytes == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
env = PyBytes_AS_STRING(bytes);
|
char *env = PyBytes_AS_STRING(bytes);
|
||||||
if (putenv(env)) {
|
if (putenv(env)) {
|
||||||
Py_DECREF(bytes);
|
Py_DECREF(bytes);
|
||||||
return posix_error();
|
return posix_error();
|
||||||
}
|
}
|
||||||
|
|
||||||
posix_putenv_dict_setitem(name, bytes);
|
posix_putenv_dict_setitem(name, bytes);
|
||||||
|
#endif
|
||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
}
|
}
|
||||||
#endif /* MS_WINDOWS */
|
#endif /* defined(HAVE_SETENV) || defined(HAVE_PUTENV) */
|
||||||
#endif /* HAVE_PUTENV */
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef HAVE_UNSETENV
|
#ifdef HAVE_UNSETENV
|
||||||
|
|
|
@ -782,7 +782,6 @@ infodir
|
||||||
docdir
|
docdir
|
||||||
oldincludedir
|
oldincludedir
|
||||||
includedir
|
includedir
|
||||||
runstatedir
|
|
||||||
localstatedir
|
localstatedir
|
||||||
sharedstatedir
|
sharedstatedir
|
||||||
sysconfdir
|
sysconfdir
|
||||||
|
@ -896,7 +895,6 @@ datadir='${datarootdir}'
|
||||||
sysconfdir='${prefix}/etc'
|
sysconfdir='${prefix}/etc'
|
||||||
sharedstatedir='${prefix}/com'
|
sharedstatedir='${prefix}/com'
|
||||||
localstatedir='${prefix}/var'
|
localstatedir='${prefix}/var'
|
||||||
runstatedir='${localstatedir}/run'
|
|
||||||
includedir='${prefix}/include'
|
includedir='${prefix}/include'
|
||||||
oldincludedir='/usr/include'
|
oldincludedir='/usr/include'
|
||||||
docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
|
docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
|
||||||
|
@ -1149,15 +1147,6 @@ do
|
||||||
| -silent | --silent | --silen | --sile | --sil)
|
| -silent | --silent | --silen | --sile | --sil)
|
||||||
silent=yes ;;
|
silent=yes ;;
|
||||||
|
|
||||||
-runstatedir | --runstatedir | --runstatedi | --runstated \
|
|
||||||
| --runstate | --runstat | --runsta | --runst | --runs \
|
|
||||||
| --run | --ru | --r)
|
|
||||||
ac_prev=runstatedir ;;
|
|
||||||
-runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \
|
|
||||||
| --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \
|
|
||||||
| --run=* | --ru=* | --r=*)
|
|
||||||
runstatedir=$ac_optarg ;;
|
|
||||||
|
|
||||||
-sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
|
-sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
|
||||||
ac_prev=sbindir ;;
|
ac_prev=sbindir ;;
|
||||||
-sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
|
-sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
|
||||||
|
@ -1295,7 +1284,7 @@ fi
|
||||||
for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \
|
for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \
|
||||||
datadir sysconfdir sharedstatedir localstatedir includedir \
|
datadir sysconfdir sharedstatedir localstatedir includedir \
|
||||||
oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
|
oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
|
||||||
libdir localedir mandir runstatedir
|
libdir localedir mandir
|
||||||
do
|
do
|
||||||
eval ac_val=\$$ac_var
|
eval ac_val=\$$ac_var
|
||||||
# Remove trailing slashes.
|
# Remove trailing slashes.
|
||||||
|
@ -1448,7 +1437,6 @@ Fine tuning of the installation directories:
|
||||||
--sysconfdir=DIR read-only single-machine data [PREFIX/etc]
|
--sysconfdir=DIR read-only single-machine data [PREFIX/etc]
|
||||||
--sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
|
--sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
|
||||||
--localstatedir=DIR modifiable single-machine data [PREFIX/var]
|
--localstatedir=DIR modifiable single-machine data [PREFIX/var]
|
||||||
--runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run]
|
|
||||||
--libdir=DIR object code libraries [EPREFIX/lib]
|
--libdir=DIR object code libraries [EPREFIX/lib]
|
||||||
--includedir=DIR C header files [PREFIX/include]
|
--includedir=DIR C header files [PREFIX/include]
|
||||||
--oldincludedir=DIR C header files for non-gcc [/usr/include]
|
--oldincludedir=DIR C header files for non-gcc [/usr/include]
|
||||||
|
@ -10303,6 +10291,7 @@ fi
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then
|
if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then
|
||||||
if test -n "$ac_tool_prefix"; then
|
if test -n "$ac_tool_prefix"; then
|
||||||
# Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args.
|
# Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args.
|
||||||
|
@ -11561,7 +11550,7 @@ for ac_func in alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
|
||||||
posix_fallocate posix_fadvise posix_spawn posix_spawnp pread preadv preadv2 \
|
posix_fallocate posix_fadvise posix_spawn posix_spawnp pread preadv preadv2 \
|
||||||
pthread_condattr_setclock pthread_init pthread_kill putenv pwrite pwritev pwritev2 \
|
pthread_condattr_setclock pthread_init pthread_kill putenv pwrite pwritev pwritev2 \
|
||||||
readlink readlinkat readv realpath renameat \
|
readlink readlinkat readv realpath renameat \
|
||||||
sem_open sem_timedwait sem_getvalue sem_unlink sendfile setegid seteuid \
|
sem_open sem_timedwait sem_getvalue sem_unlink sendfile setegid setenv seteuid \
|
||||||
setgid sethostname \
|
setgid sethostname \
|
||||||
setlocale setregid setreuid setresuid setresgid setsid setpgid setpgrp setpriority setuid setvbuf \
|
setlocale setregid setreuid setresuid setresgid setsid setpgid setpgrp setpriority setuid setvbuf \
|
||||||
sched_get_priority_max sched_setaffinity sched_setscheduler sched_setparam \
|
sched_get_priority_max sched_setaffinity sched_setscheduler sched_setparam \
|
||||||
|
|
|
@ -3600,7 +3600,7 @@ AC_CHECK_FUNCS(alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
|
||||||
posix_fallocate posix_fadvise posix_spawn posix_spawnp pread preadv preadv2 \
|
posix_fallocate posix_fadvise posix_spawn posix_spawnp pread preadv preadv2 \
|
||||||
pthread_condattr_setclock pthread_init pthread_kill putenv pwrite pwritev pwritev2 \
|
pthread_condattr_setclock pthread_init pthread_kill putenv pwrite pwritev pwritev2 \
|
||||||
readlink readlinkat readv realpath renameat \
|
readlink readlinkat readv realpath renameat \
|
||||||
sem_open sem_timedwait sem_getvalue sem_unlink sendfile setegid seteuid \
|
sem_open sem_timedwait sem_getvalue sem_unlink sendfile setegid setenv seteuid \
|
||||||
setgid sethostname \
|
setgid sethostname \
|
||||||
setlocale setregid setreuid setresuid setresgid setsid setpgid setpgrp setpriority setuid setvbuf \
|
setlocale setregid setreuid setresuid setresgid setsid setpgid setpgrp setpriority setuid setvbuf \
|
||||||
sched_get_priority_max sched_setaffinity sched_setscheduler sched_setparam \
|
sched_get_priority_max sched_setaffinity sched_setscheduler sched_setparam \
|
||||||
|
|
|
@ -895,6 +895,9 @@
|
||||||
/* Define to 1 if you have the `setegid' function. */
|
/* Define to 1 if you have the `setegid' function. */
|
||||||
#undef HAVE_SETEGID
|
#undef HAVE_SETEGID
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `setenv' function. */
|
||||||
|
#undef HAVE_SETENV
|
||||||
|
|
||||||
/* Define to 1 if you have the `seteuid' function. */
|
/* Define to 1 if you have the `seteuid' function. */
|
||||||
#undef HAVE_SETEUID
|
#undef HAVE_SETEUID
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue