]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
bpo-39395: putenv() and unsetenv() always available (GH-18135)
authorVictor Stinner <vstinner@python.org>
Fri, 24 Jan 2020 13:05:48 +0000 (14:05 +0100)
committerGitHub <noreply@github.com>
Fri, 24 Jan 2020 13:05:48 +0000 (14:05 +0100)
The os.putenv() and os.unsetenv() functions are now always available.

On non-Windows platforms, Python now requires setenv() and unsetenv()
functions to build.

Remove putenv_dict from posixmodule.c: it's not longer needed.

12 files changed:
Doc/library/os.rst
Doc/whatsnew/3.9.rst
Lib/os.py
Lib/test/test_os.py
Lib/test/test_posix.py
Misc/NEWS.d/next/Build/2020-01-23-03-05-13.bpo-39395.RoArIZ.rst [new file with mode: 0644]
Misc/NEWS.d/next/Library/2020-01-23-03-05-41.bpo-39395.4dda42.rst [new file with mode: 0644]
Modules/clinic/posixmodule.c.h
Modules/posixmodule.c
configure
configure.ac
pyconfig.h.in

index de3e5603e109fea50b5448d3b907b02dcbddd7aa..f59423c6f2d4eea2a5a8b713517e6704c624c0e5 100644 (file)
@@ -111,9 +111,9 @@ process and user.
    to the environment made after this time are not reflected in ``os.environ``,
    except for changes made by modifying ``os.environ`` directly.
 
-   If the platform supports the :func:`putenv` function, this mapping may be used
-   to modify the environment as well as query the environment.  :func:`putenv` will
-   be called automatically when the mapping is modified.
+   This mapping may be used to modify the environment as well as query the
+   environment.  :func:`putenv` will be called automatically when the mapping
+   is modified.
 
    On Unix, keys and values use :func:`sys.getfilesystemencoding` and
    ``'surrogateescape'`` error handler. Use :data:`environb` if you would like
@@ -130,14 +130,10 @@ process and user.
       cause memory leaks.  Refer to the system documentation for
       :c:func:`putenv`.
 
-   If :func:`putenv` is not provided, a modified copy of this mapping  may be
-   passed to the appropriate process-creation functions to cause  child processes
-   to use a modified environment.
-
-   If the platform supports the :func:`unsetenv` function, you can delete items in
-   this mapping to unset environment variables. :func:`unsetenv` will be called
-   automatically when an item is deleted from ``os.environ``, and when
-   one of the :meth:`pop` or :meth:`clear` methods is called.
+   You can delete items in this mapping to unset environment variables.
+   :func:`unsetenv` will be called automatically when an item is deleted from
+   ``os.environ``, and when one of the :meth:`pop` or :meth:`clear` methods is
+   called.
 
 
 .. data:: environb
@@ -439,17 +435,18 @@ process and user.
    changes to the environment affect subprocesses started with :func:`os.system`,
    :func:`popen` or :func:`fork` and :func:`execv`.
 
-   .. availability:: most flavors of Unix, Windows.
+   Assignments to items in ``os.environ`` are automatically translated into
+   corresponding calls to :func:`putenv`; however, calls to :func:`putenv`
+   don't update ``os.environ``, so it is actually preferable to assign to items
+   of ``os.environ``.
 
    .. note::
 
       On some platforms, including FreeBSD and Mac OS X, setting ``environ`` may
-      cause memory leaks. Refer to the system documentation for putenv.
+      cause memory leaks. Refer to the system documentation for :c:func:`putenv`.
 
-   When :func:`putenv` is supported, assignments to items in ``os.environ`` are
-   automatically translated into corresponding calls to :func:`putenv`; however,
-   calls to :func:`putenv` don't update ``os.environ``, so it is actually
-   preferable to assign to items of ``os.environ``.
+   .. versionchanged:: 3.9
+      The function is now always available.
 
 
 .. function:: setegid(egid)
@@ -638,15 +635,13 @@ process and user.
    environment affect subprocesses started with :func:`os.system`, :func:`popen` or
    :func:`fork` and :func:`execv`.
 
-   When :func:`unsetenv` is supported, deletion of items in ``os.environ`` is
-   automatically translated into a corresponding call to :func:`unsetenv`; however,
-   calls to :func:`unsetenv` don't update ``os.environ``, so it is actually
-   preferable to delete items of ``os.environ``.
-
-   .. availability:: most flavors of Unix, Windows.
+   Deletion of items in ``os.environ`` is automatically translated into a
+   corresponding call to :func:`unsetenv`; however, calls to :func:`unsetenv`
+   don't update ``os.environ``, so it is actually preferable to delete items of
+   ``os.environ``.
 
    .. versionchanged:: 3.9
-      The function is now also available on Windows.
+      The function is now always available and is also available on Windows.
 
 
 .. _os-newstreams:
index 751562e875e6deb89c5b252fd7bafd33708eb4d3..a4c4266bfc35dcf45ff3972e200856af1715b4ea 100644 (file)
@@ -227,6 +227,10 @@ descriptors.
 The :func:`os.unsetenv` function is now also available on Windows.
 (Contributed by Victor Stinner in :issue:`39413`.)
 
+The :func:`os.putenv` and :func:`os.unsetenv` functions are now always
+available.
+(Contributed by Victor Stinner in :issue:`39395`.)
+
 poplib
 ------
 
@@ -331,6 +335,10 @@ Build and C API Changes
   Python 3.0, it has been ignored and unused.
   (Contributed by Jeroen Demeyer in :issue:`36974`.)
 
+* On non-Windows platforms, the :c:func:`setenv` and :c:func:`unsetenv`
+  functions are now required to build Python.
+  (Contributed by Victor Stinner in :issue:`39395`.)
+
 
 Deprecated
 ==========
index ca418edbc57366937fddd60d230512a3f3295536..7ae102617e8b1f344e0f19a263301c98f7b53849 100644 (file)
--- a/Lib/os.py
+++ b/Lib/os.py
@@ -654,17 +654,15 @@ def get_exec_path(env=None):
     return path_list.split(pathsep)
 
 
-# Change environ to automatically call putenv(), unsetenv if they exist.
+# Change environ to automatically call putenv() and unsetenv()
 from _collections_abc import MutableMapping
 
 class _Environ(MutableMapping):
-    def __init__(self, data, encodekey, decodekey, encodevalue, decodevalue, putenv, unsetenv):
+    def __init__(self, data, encodekey, decodekey, encodevalue, decodevalue):
         self.encodekey = encodekey
         self.decodekey = decodekey
         self.encodevalue = encodevalue
         self.decodevalue = decodevalue
-        self.putenv = putenv
-        self.unsetenv = unsetenv
         self._data = data
 
     def __getitem__(self, key):
@@ -678,12 +676,12 @@ class _Environ(MutableMapping):
     def __setitem__(self, key, value):
         key = self.encodekey(key)
         value = self.encodevalue(value)
-        self.putenv(key, value)
+        putenv(key, value)
         self._data[key] = value
 
     def __delitem__(self, key):
         encodedkey = self.encodekey(key)
-        self.unsetenv(encodedkey)
+        unsetenv(encodedkey)
         try:
             del self._data[encodedkey]
         except KeyError:
@@ -712,22 +710,6 @@ class _Environ(MutableMapping):
             self[key] = value
         return self[key]
 
-try:
-    _putenv = putenv
-except NameError:
-    _putenv = lambda key, value: None
-else:
-    if "putenv" not in __all__:
-        __all__.append("putenv")
-
-try:
-    _unsetenv = unsetenv
-except NameError:
-    _unsetenv = lambda key: _putenv(key, "")
-else:
-    if "unsetenv" not in __all__:
-        __all__.append("unsetenv")
-
 def _createenviron():
     if name == 'nt':
         # Where Env Var Names Must Be UPPERCASE
@@ -755,8 +737,7 @@ def _createenviron():
         data = environ
     return _Environ(data,
         encodekey, decode,
-        encode, decode,
-        _putenv, _unsetenv)
+        encode, decode)
 
 # unicode environ
 environ = _createenviron()
@@ -781,8 +762,7 @@ if supports_bytes_environ:
     # bytes environ
     environb = _Environ(environ._data,
         _check_bytes, bytes,
-        _check_bytes, bytes,
-        _putenv, _unsetenv)
+        _check_bytes, bytes)
     del _check_bytes
 
     def getenvb(key, default=None):
index dbdc00c2fea2295534326aa9f165969b3f24f185..9e3a1695dfb34ec162c810ca1c8cbbea0f9f76ae 100644 (file)
@@ -953,8 +953,6 @@ class EnvironTests(mapping_tests.BasicTestMappingProtocol):
         value_str = value.decode(sys.getfilesystemencoding(), 'surrogateescape')
         self.assertEqual(os.environ['bytes'], value_str)
 
-    @unittest.skipUnless(hasattr(os, 'putenv'), "Test needs os.putenv()")
-    @unittest.skipUnless(hasattr(os, 'unsetenv'), "Test needs os.unsetenv()")
     def test_putenv_unsetenv(self):
         name = "PYTHONTESTVAR"
         value = "testvalue"
@@ -975,8 +973,6 @@ class EnvironTests(mapping_tests.BasicTestMappingProtocol):
 
     # On OS X < 10.6, unsetenv() doesn't return a value (bpo-13415).
     @support.requires_mac_ver(10, 6)
-    @unittest.skipUnless(hasattr(os, 'putenv'), "Test needs os.putenv()")
-    @unittest.skipUnless(hasattr(os, 'unsetenv'), "Test needs os.unsetenv()")
     def test_putenv_unsetenv_error(self):
         # Empty variable name is invalid.
         # "=" and null character are not allowed in a variable name.
index 4df882b621085a5e1e9b995e27b25bdc611adbc2..fad26d88be2f3f7b5e6e8a6df2bd25c49490747b 100644 (file)
@@ -969,7 +969,6 @@ class PosixTester(unittest.TestCase):
             self.assertEqual(type(k), item_type)
             self.assertEqual(type(v), item_type)
 
-    @unittest.skipUnless(hasattr(os, "putenv"), "requires os.putenv()")
     def test_putenv(self):
         with self.assertRaises(ValueError):
             os.putenv('FRUIT\0VEGETABLE', 'cabbage')
diff --git a/Misc/NEWS.d/next/Build/2020-01-23-03-05-13.bpo-39395.RoArIZ.rst b/Misc/NEWS.d/next/Build/2020-01-23-03-05-13.bpo-39395.RoArIZ.rst
new file mode 100644 (file)
index 0000000..aa2146a
--- /dev/null
@@ -0,0 +1,2 @@
+On non-Windows platforms, the :c:func:`setenv` and :c:func:`unsetenv` functions
+are now required to build Python.
diff --git a/Misc/NEWS.d/next/Library/2020-01-23-03-05-41.bpo-39395.4dda42.rst b/Misc/NEWS.d/next/Library/2020-01-23-03-05-41.bpo-39395.4dda42.rst
new file mode 100644 (file)
index 0000000..cf71370
--- /dev/null
@@ -0,0 +1,2 @@
+The :func:`os.putenv` and :func:`os.unsetenv` functions are now always
+available.
index 0f5995ec6400c0b99e7d82aed684ae2eda2220e9..48dd7a74b3bf22f6d21cd5f852c1d7a596492c0d 100644 (file)
@@ -6082,7 +6082,7 @@ exit:
 
 #endif /* defined(MS_WINDOWS) */
 
-#if ((defined(HAVE_SETENV) || defined(HAVE_PUTENV)) && !defined(MS_WINDOWS))
+#if !defined(MS_WINDOWS)
 
 PyDoc_STRVAR(os_putenv__doc__,
 "putenv($module, name, value, /)\n"
@@ -6123,7 +6123,7 @@ exit:
     return return_value;
 }
 
-#endif /* ((defined(HAVE_SETENV) || defined(HAVE_PUTENV)) && !defined(MS_WINDOWS)) */
+#endif /* !defined(MS_WINDOWS) */
 
 #if defined(MS_WINDOWS)
 
@@ -6161,7 +6161,7 @@ exit:
 
 #endif /* defined(MS_WINDOWS) */
 
-#if (defined(HAVE_UNSETENV) && !defined(MS_WINDOWS))
+#if !defined(MS_WINDOWS)
 
 PyDoc_STRVAR(os_unsetenv__doc__,
 "unsetenv($module, name, /)\n"
@@ -6193,7 +6193,7 @@ exit:
     return return_value;
 }
 
-#endif /* (defined(HAVE_UNSETENV) && !defined(MS_WINDOWS)) */
+#endif /* !defined(MS_WINDOWS) */
 
 PyDoc_STRVAR(os_strerror__doc__,
 "strerror($module, code, /)\n"
@@ -8809,4 +8809,4 @@ exit:
 #ifndef OS__REMOVE_DLL_DIRECTORY_METHODDEF
     #define OS__REMOVE_DLL_DIRECTORY_METHODDEF
 #endif /* !defined(OS__REMOVE_DLL_DIRECTORY_METHODDEF) */
-/*[clinic end generated code: output=0348cbdff48691e3 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=5d99f90cead7c0e1 input=a9049054013a1b77]*/
index 3a8e6aacb2afd7397f7fcc2575d58d32f2195518..b71eddf90b70e803e701475dd24d9885258ecd9c 100644 (file)
@@ -819,22 +819,8 @@ dir_fd_converter(PyObject *o, void *p)
     }
 }
 
-/* Windows _wputenv() and setenv() copy the arguments and so don't require
-   the caller to manage the variable memory. Only Unix putenv() requires
-   putenv_dict. */
-#if defined(HAVE_PUTENV) && !defined(MS_WINDOWS) && !defined(HAVE_SETENV)
-#  define PY_PUTENV_DICT
-#endif
-
 typedef struct {
     PyObject *billion;
-#ifdef PY_PUTENV_DICT
-    /* putenv() requires that the caller manages the environment variable
-       memory. Use a Python dictionary for that: name => env, where env is a
-       string like "name=value". On Windows, dict keys and values are Unicode
-       strings. On Unix, they are bytes strings. */
-    PyObject *putenv_dict;
-#endif
     PyObject *DirEntryType;
     PyObject *ScandirIteratorType;
 #if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
@@ -2118,9 +2104,6 @@ static int
 _posix_clear(PyObject *module)
 {
     Py_CLEAR(_posixstate(module)->billion);
-#ifdef PY_PUTENV_DICT
-    Py_CLEAR(_posixstate(module)->putenv_dict);
-#endif
     Py_CLEAR(_posixstate(module)->DirEntryType);
     Py_CLEAR(_posixstate(module)->ScandirIteratorType);
 #if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
@@ -2145,9 +2128,6 @@ static int
 _posix_traverse(PyObject *module, visitproc visit, void *arg)
 {
     Py_VISIT(_posixstate(module)->billion);
-#ifdef PY_PUTENV_DICT
-    Py_VISIT(_posixstate(module)->putenv_dict);
-#endif
     Py_VISIT(_posixstate(module)->DirEntryType);
     Py_VISIT(_posixstate(module)->ScandirIteratorType);
 #if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
@@ -10065,23 +10045,6 @@ os_posix_fadvise_impl(PyObject *module, int fd, Py_off_t offset,
 #endif /* HAVE_POSIX_FADVISE && !POSIX_FADVISE_AIX_BUG */
 
 
-#ifdef PY_PUTENV_DICT
-static void
-posix_putenv_dict_setitem(PyObject *name, PyObject *value)
-{
-    /* Install the first arg and newstr in putenv_dict;
-     * this will cause previous value to be collected.  This has to
-     * happen after the real putenv() call because the old value
-     * was still accessible until then. */
-    if (PyDict_SetItem(_posixstate_global->putenv_dict, name, value))
-        /* really not much we can do; just leak */
-        PyErr_Clear();
-    else
-        Py_DECREF(value);
-}
-#endif  /* PY_PUTENV_DICT */
-
-
 #ifdef MS_WINDOWS
 static PyObject*
 win32_putenv(PyObject *name, PyObject *value)
@@ -10157,8 +10120,7 @@ os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
 {
     return win32_putenv(name, value);
 }
-/* repeat !defined(MS_WINDOWS) to workaround an Argument Clinic issue */
-#elif (defined(HAVE_SETENV) || defined(HAVE_PUTENV)) && !defined(MS_WINDOWS)
+#else
 /*[clinic input]
 os.putenv
 
@@ -10181,27 +10143,12 @@ os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
         return NULL;
     }
 
-#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) {
-        return NULL;
-    }
-
-    char *env = PyBytes_AS_STRING(bytes);
-    if (putenv(env)) {
-        Py_DECREF(bytes);
-        return posix_error();
-    }
-
-    posix_putenv_dict_setitem(name, bytes);
-#endif
     Py_RETURN_NONE;
 }
-#endif  /* defined(HAVE_SETENV) || defined(HAVE_PUTENV) */
+#endif  /* !defined(MS_WINDOWS) */
 
 
 #ifdef MS_WINDOWS
@@ -10219,8 +10166,7 @@ os_unsetenv_impl(PyObject *module, PyObject *name)
 {
     return win32_putenv(name, NULL);
 }
-/* repeat !defined(MS_WINDOWS) to workaround an Argument Clinic issue */
-#elif defined(HAVE_UNSETENV) && !defined(MS_WINDOWS)
+#else
 /*[clinic input]
 os.unsetenv
     name: FSConverter
@@ -10242,24 +10188,9 @@ os_unsetenv_impl(PyObject *module, PyObject *name)
     }
 #endif
 
-#ifdef PY_PUTENV_DICT
-    /* Remove the key from putenv_dict;
-     * this will cause it to be collected.  This has to
-     * happen after the real unsetenv() call because the
-     * old value was still accessible until then.
-     */
-    if (PyDict_DelItem(_posixstate(module)->putenv_dict, name)) {
-        /* really not much we can do; just leak */
-        if (!PyErr_ExceptionMatches(PyExc_KeyError)) {
-            return NULL;
-        }
-        PyErr_Clear();
-    }
-#endif
-
     Py_RETURN_NONE;
 }
-#endif /* HAVE_UNSETENV */
+#endif /* !MS_WINDOWS */
 
 
 /*[clinic input]
@@ -14553,12 +14484,6 @@ INITFUNC(void)
     Py_INCREF(PyExc_OSError);
     PyModule_AddObject(m, "error", PyExc_OSError);
 
-#ifdef PY_PUTENV_DICT
-    /* Save putenv() parameters as values here, so we can collect them when they
-     * get re-set with another call for the same key. */
-    _posixstate(m)->putenv_dict = PyDict_New();
-#endif
-
 #if defined(HAVE_WAITID) && !defined(__APPLE__)
     waitid_result_desc.name = MODNAME ".waitid_result";
     PyObject *WaitidResultType = (PyObject *)PyStructSequence_NewType(&waitid_result_desc);
index e96683622b3045564e42346fddfdfea22d7ad977..85120e498d1faded1126cdc09bd0a027e62b01d9 100755 (executable)
--- a/configure
+++ b/configure
@@ -11548,9 +11548,9 @@ for ac_func in alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
  memrchr mbrtowc mkdirat mkfifo \
  madvise mkfifoat mknod mknodat mktime mremap nice openat pathconf pause pipe2 plock poll \
  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 pwrite pwritev pwritev2 \
  readlink readlinkat readv realpath renameat \
- sem_open sem_timedwait sem_getvalue sem_unlink sendfile setegid setenv seteuid \
+ sem_open sem_timedwait sem_getvalue sem_unlink sendfile setegid seteuid \
  setgid sethostname \
  setlocale setregid setreuid setresuid setresgid setsid setpgid setpgrp setpriority setuid setvbuf \
  sched_get_priority_max sched_setaffinity sched_setscheduler sched_setparam \
@@ -11558,7 +11558,7 @@ for ac_func in alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
  sigaction sigaltstack sigfillset siginterrupt sigpending sigrelse \
  sigtimedwait sigwait sigwaitinfo snprintf strftime strlcpy strsignal symlinkat sync \
  sysconf tcgetpgrp tcsetpgrp tempnam timegm times tmpfile tmpnam tmpnam_r \
- truncate uname unlinkat unsetenv utimensat utimes waitid waitpid wait3 wait4 \
+ truncate uname unlinkat utimensat utimes waitid waitpid wait3 wait4 \
  wcscoll wcsftime wcsxfrm wmemcmp writev _getpty rtpSpawn
 do :
   as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
index 36c165b2f2e42f3e91e4758537b86b0a10b0ecce..ab8e1b7d27ac28d841aa89c1c5fa23de38e3f7d7 100644 (file)
@@ -3598,9 +3598,9 @@ AC_CHECK_FUNCS(alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
  memrchr mbrtowc mkdirat mkfifo \
  madvise mkfifoat mknod mknodat mktime mremap nice openat pathconf pause pipe2 plock poll \
  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 pwrite pwritev pwritev2 \
  readlink readlinkat readv realpath renameat \
- sem_open sem_timedwait sem_getvalue sem_unlink sendfile setegid setenv seteuid \
+ sem_open sem_timedwait sem_getvalue sem_unlink sendfile setegid seteuid \
  setgid sethostname \
  setlocale setregid setreuid setresuid setresgid setsid setpgid setpgrp setpriority setuid setvbuf \
  sched_get_priority_max sched_setaffinity sched_setscheduler sched_setparam \
@@ -3608,7 +3608,7 @@ AC_CHECK_FUNCS(alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
  sigaction sigaltstack sigfillset siginterrupt sigpending sigrelse \
  sigtimedwait sigwait sigwaitinfo snprintf strftime strlcpy strsignal symlinkat sync \
  sysconf tcgetpgrp tcsetpgrp tempnam timegm times tmpfile tmpnam tmpnam_r \
- truncate uname unlinkat unsetenv utimensat utimes waitid waitpid wait3 wait4 \
+ truncate uname unlinkat utimensat utimes waitid waitpid wait3 wait4 \
  wcscoll wcsftime wcsxfrm wmemcmp writev _getpty rtpSpawn)
 
 # Force lchmod off for Linux. Linux disallows changing the mode of symbolic
index 1918fab8bdbe7484675248e97a95cda061c9ed62..b5602134d703ab9c2a878d5b4258d87fedcf937d 100644 (file)
 /* Define to 1 if you have the <pty.h> header file. */
 #undef HAVE_PTY_H
 
-/* Define to 1 if you have the `putenv' function. */
-#undef HAVE_PUTENV
-
 /* Define to 1 if you have the `pwrite' function. */
 #undef HAVE_PWRITE
 
 /* Define to 1 if you have the `setegid' function. */
 #undef HAVE_SETEGID
 
-/* Define to 1 if you have the `setenv' function. */
-#undef HAVE_SETENV
-
 /* Define to 1 if you have the `seteuid' function. */
 #undef HAVE_SETEUID
 
 /* Define to 1 if you have the `unlinkat' function. */
 #undef HAVE_UNLINKAT
 
-/* Define to 1 if you have the `unsetenv' function. */
-#undef HAVE_UNSETENV
-
 /* Define if you have a useable wchar_t type defined in wchar.h; useable means
    wchar_t must be an unsigned type with at least 16 bits. (see
    Include/unicodeobject.h). */