diff mbox series

[v2,13/13] manual: Updates for thread-safe getenv

Message ID 7b639a0c6ed7b5b4bc0f4f5e027eb93d8781e250.1722193092.git.fweimer@redhat.com
State New
Headers show
Series getenv/environ thread safety | expand

Commit Message

Florian Weimer July 28, 2024, 7:03 p.m. UTC
---
 NEWS                |   5 ++
 manual/argp.texi    |  20 +++---
 manual/conf.texi    |   2 +-
 manual/filesys.texi |   4 +-
 manual/getopt.texi  |   6 +-
 manual/intro.texi   |  17 +----
 manual/locale.texi  |   9 +--
 manual/macros.texi  |   4 --
 manual/memory.texi  |  18 +++---
 manual/message.texi |  37 +++++------
 manual/pattern.texi |  64 +++++++++----------
 manual/process.texi |   4 +-
 manual/socket.texi  | 145 +++++++++++++++++++++---------------------
 manual/startup.texi | 122 ++++++++++++++++++++++++++++-------
 manual/sysinfo.texi |   2 +-
 manual/syslog.texi  |  18 +++---
 manual/time.texi    | 150 +++++++++++++++++++++-----------------------
 17 files changed, 333 insertions(+), 294 deletions(-)
diff mbox series

Patch

diff --git a/NEWS b/NEWS
index d488874aba..026be0c167 100644
--- a/NEWS
+++ b/NEWS
@@ -89,6 +89,11 @@  Major new features:
   of large writes. This behaviour is controlled by a new tunable
   x86_memset_non_temporal_threshold.
 
+* The getenv function is now thread-safe and async-signal-safe, provided
+  that the environ array is only manipulated using the function setenv,
+  unsetenv, and clearenv.  If putenv is used, the safety properties of
+  getenv depend on how the string into the environment is updated.
+
 Deprecated and removed features, and other changes affecting compatibility:
 
 * Architectures which use a 32-bit seconds-since-epoch field in struct
diff --git a/manual/argp.texi b/manual/argp.texi
index 0023441812..b09e0b9880 100644
--- a/manual/argp.texi
+++ b/manual/argp.texi
@@ -35,7 +35,7 @@  needed in @code{main}.
 
 @deftypefun {error_t} argp_parse (const struct argp *@var{argp}, int @var{argc}, char **@var{argv}, unsigned @var{flags}, int *@var{arg_index}, void *@var{input})
 @standards{GNU, argp.h}
-@safety{@prelim{}@mtunsafe{@mtasurace{:argpbuf} @mtslocale{} @mtsenv{}}@asunsafe{@ascuheap{} @ascuintl{} @asulock{} @asucorrupt{}}@acunsafe{@acsmem{} @aculock{} @acucorrupt{}}}
+@safety{@prelim{}@mtunsafe{@mtasurace{:argpbuf} @mtslocale{}}@asunsafe{@ascuheap{} @ascuintl{} @asulock{} @asucorrupt{}}@acunsafe{@acsmem{} @aculock{} @acucorrupt{}}}
 @c Optionally alloca()tes standard help options, initializes the parser,
 @c then parses individual args in a loop, and then finalizes.
 @c  parser_init
@@ -56,12 +56,12 @@  needed in @code{main}.
 @c    group_parse dup
 @c   parser_parse_opt
 @c    group_parse dup
-@c    argp_error dup @mtasurace:argpbuf @mtsenv @mtslocale @ascuheap @ascuintl @asucorrupt @acsmem @acucorrupt @aculock
-@c    dgettext (bad key error) dup @mtsenv @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsfd @acsmem
+@c    argp_error dup @mtasurace:argpbuf @mtslocale @ascuheap @ascuintl @asucorrupt @acsmem @acucorrupt @aculock
+@c    dgettext (bad key error) dup @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsfd @acsmem
 @c  parser_finalize
 @c   group_parse
 @c   fprintf dup @mtslocale @asucorrupt @aculock @acucorrupt [no @ascuheap @acsmem]
-@c   dgettext dup @mtsenv @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsfd @acsmem
+@c   dgettext dup @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsfd @acsmem
 @c   arg_state_help
 @c   free dup @ascuhelp @acsmem
 The @code{argp_parse} function parses the arguments in @var{argv}, of
@@ -666,7 +666,7 @@  parser function.  @xref{Argp Parsing State}.
 @cindex usage messages, in argp
 @deftypefun void argp_usage (const struct argp_state *@var{state})
 @standards{GNU, argp.h}
-@safety{@prelim{}@mtunsafe{@mtasurace{:argpbuf} @mtsenv{} @mtslocale{}}@asunsafe{@ascuheap{} @ascuintl{} @asucorrupt{}}@acunsafe{@acsmem{} @acucorrupt{} @aculock{}}}
+@safety{@prelim{}@mtunsafe{@mtasurace{:argpbuf} @mtslocale{}}@asunsafe{@ascuheap{} @ascuintl{} @asucorrupt{}}@acunsafe{@acsmem{} @acucorrupt{} @aculock{}}}
 @c Just calls argp_state_help with stderr and ARGP_HELP_STD_USAGE.
 Outputs the standard usage message for the argp parser referred to by
 @var{state} to @code{@var{state}->err_stream} and terminates the program
@@ -676,7 +676,7 @@  with @code{exit (argp_err_exit_status)}.  @xref{Argp Global Variables}.
 @cindex syntax error messages, in argp
 @deftypefun void argp_error (const struct argp_state *@var{state}, const char *@var{fmt}, @dots{})
 @standards{GNU, argp.h}
-@safety{@prelim{}@mtunsafe{@mtasurace{:argpbuf} @mtsenv{} @mtslocale{}}@asunsafe{@ascuheap{} @ascuintl{} @asucorrupt{}}@acunsafe{@acsmem{} @acucorrupt{} @aculock{}}}
+@safety{@prelim{}@mtunsafe{@mtasurace{:argpbuf} @mtslocale{}}@asunsafe{@ascuheap{} @ascuintl{} @asucorrupt{}}@acunsafe{@acsmem{} @acucorrupt{} @aculock{}}}
 @c Lock stream, vasprintf the formatted message into a buffer, print the
 @c buffer prefixed by the short program name (in libc,
 @c argp_short_program_name is a macro that expands to
@@ -713,7 +713,7 @@  for options, bad phase of the moon, etc.
 
 @deftypefun void argp_state_help (const struct argp_state *@var{state}, FILE *@var{stream}, unsigned @var{flags})
 @standards{GNU, argp.h}
-@safety{@prelim{}@mtunsafe{@mtasurace{:argpbuf} @mtsenv{} @mtslocale{}}@asunsafe{@ascuheap{} @ascuintl{} @asucorrupt{}}@acunsafe{@acsmem{} @acucorrupt{} @aculock{}}}
+@safety{@prelim{}@mtunsafe{@mtasurace{:argpbuf} @mtslocale{}}@asunsafe{@ascuheap{} @ascuintl{} @asucorrupt{}}@acunsafe{@acsmem{} @acucorrupt{} @aculock{}}}
 @c Just calls _help with the short program name and optionally exit.
 @c The main problems in _help, besides the usual issues with stream I/O
 @c and translation, are the use of a static buffer (uparams, thus
@@ -721,11 +721,11 @@  for options, bad phase of the moon, etc.
 @c from the environment for ARGP_HELP_FMT, accessing the locale object
 @c multiple times.
 
-@c _help @mtsenv @mtasurace:argpbuf @mtslocale @ascuheap @ascuintl @asucorrupt @acsmem @acucorrupt @aculock
+@c _help @mtasurace:argpbuf @mtslocale @ascuheap @ascuintl @asucorrupt @acsmem @acucorrupt @aculock
 @c  dgettext @ascuintl
 @c  flockfile @aculock
 @c  funlockfile @aculock
-@c  fill_in_uparams @mtsenv @mtasurace:argpbuf @mtslocale @asucorrupt @ascuheap @aculock @acucorrupt @acsmem
+@c  fill_in_uparams @mtasurace:argpbuf @mtslocale @asucorrupt @ascuheap @aculock @acucorrupt @acsmem
 @c   argp_failure dup (status = errnum = 0)
 @c   atoi dup @mtslocale
 @c  argp_hol @ascuheap @acsmem
@@ -1066,7 +1066,7 @@  program options, argp offers the @code{argp_help} interface.
 
 @deftypefun void argp_help (const struct argp *@var{argp}, FILE *@var{stream}, unsigned @var{flags}, char *@var{name})
 @standards{GNU, argp.h}
-@safety{@prelim{}@mtunsafe{@mtasurace{:argpbuf} @mtsenv{} @mtslocale{}}@asunsafe{@ascuheap{} @ascuintl{} @asucorrupt{}}@acunsafe{@acsmem{} @acucorrupt{} @aculock{}}}
+@safety{@prelim{}@mtunsafe{@mtasurace{:argpbuf} @mtslocale{}}@asunsafe{@ascuheap{} @ascuintl{} @asucorrupt{}}@acunsafe{@acsmem{} @acucorrupt{} @aculock{}}}
 @c Just calls _help.
 This outputs a help message for the argp parser @var{argp} to
 @var{stream}.  The type of messages printed will be determined by
diff --git a/manual/conf.texi b/manual/conf.texi
index be680e0692..c522d56955 100644
--- a/manual/conf.texi
+++ b/manual/conf.texi
@@ -272,7 +272,7 @@  constants are declared in the header file @file{unistd.h}.
 
 @deftypefun {long int} sysconf (int @var{parameter})
 @standards{POSIX.1, unistd.h}
-@safety{@prelim{}@mtsafe{@mtsenv{}}@asunsafe{@asulock{} @ascuheap{}}@acunsafe{@aculock{} @acsmem{} @acsfd{}}}
+@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{} @ascuheap{}}@acunsafe{@aculock{} @acsmem{} @acsfd{}}}
 @c Some parts of the implementation open /proc and /sys files and dirs
 @c to collect system details, using fd and stream I/O depending on the
 @c case.  The returned max value may change over time for NPROCS,
diff --git a/manual/filesys.texi b/manual/filesys.texi
index 47d929744e..40c2e53e06 100644
--- a/manual/filesys.texi
+++ b/manual/filesys.texi
@@ -150,7 +150,7 @@  this function is deprecated.
 @vindex PWD
 @deftypefun {char *} get_current_dir_name (void)
 @standards{GNU, unistd.h}
-@safety{@prelim{}@mtsafe{@mtsenv{}}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{} @acsfd{}}}
+@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{} @acsfd{}}}
 @c Besides getcwd, which this function calls as a fallback, it calls
 @c getenv, with the potential thread-safety issues that brings about.
 The @code{get_current_dir_name} function is basically equivalent to
@@ -3443,7 +3443,7 @@  never less than @code{25}.
 
 @deftypefun {char *} tempnam (const char *@var{dir}, const char *@var{prefix})
 @standards{SVID, stdio.h}
-@safety{@prelim{}@mtsafe{@mtsenv{}}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{}}}
+@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{}}}
 @c There's no way (short of being setuid) to avoid getenv("TMPDIR"),
 @c even with a non-NULL dir.
 @c
diff --git a/manual/getopt.texi b/manual/getopt.texi
index b4c0b15ac2..5c87100a46 100644
--- a/manual/getopt.texi
+++ b/manual/getopt.texi
@@ -55,7 +55,7 @@  option argument, for those options that accept arguments.
 
 @deftypefun int getopt (int @var{argc}, char *const *@var{argv}, const char *@var{options})
 @standards{POSIX.2, unistd.h}
-@safety{@prelim{}@mtunsafe{@mtasurace{:getopt} @mtsenv{}}@asunsafe{@ascuheap{} @ascuintl{} @asulock{} @asucorrupt{}}@acunsafe{@acsmem{} @aculock{} @acucorrupt{}}}
+@safety{@prelim{}@mtunsafe{@mtasurace{:getopt}}@asunsafe{@ascuheap{} @ascuintl{} @asulock{} @asucorrupt{}}@acunsafe{@acsmem{} @aculock{} @acucorrupt{}}}
 @c Swapping elements of passed-in argv may be partial in case of
 @c cancellation.  Gettext brings about a whole lot of AS and AC safety
 @c issues.  The getopt API involves returning values in the
@@ -237,7 +237,7 @@  was seen.
 
 @deftypefun int getopt_long (int @var{argc}, char *const *@var{argv}, const char *@var{shortopts}, const struct option *@var{longopts}, int *@var{indexptr})
 @standards{GNU, getopt.h}
-@safety{@prelim{}@mtunsafe{@mtasurace{:getopt} @mtsenv{}}@asunsafe{@ascuheap{} @ascuintl{} @asulock{} @asucorrupt{}}@acunsafe{@acsmem{} @aculock{} @acucorrupt{}}}
+@safety{@prelim{}@mtunsafe{@mtasurace{:getopt}}@asunsafe{@ascuheap{} @ascuintl{} @asulock{} @asucorrupt{}}@acunsafe{@acsmem{} @aculock{} @acucorrupt{}}}
 @c Same issues as getopt.
 Decode options from the vector @var{argv} (whose length is @var{argc}).
 The argument @var{shortopts} describes the short options to accept, just as
@@ -292,7 +292,7 @@  getopt functionality there is one more function available.
 
 @deftypefun int getopt_long_only (int @var{argc}, char *const *@var{argv}, const char *@var{shortopts}, const struct option *@var{longopts}, int *@var{indexptr})
 @standards{GNU, getopt.h}
-@safety{@prelim{}@mtunsafe{@mtasurace{:getopt} @mtsenv{}}@asunsafe{@ascuheap{} @ascuintl{} @asulock{} @asucorrupt{}}@acunsafe{@acsmem{} @aculock{} @acucorrupt{}}}
+@safety{@prelim{}@mtunsafe{@mtasurace{:getopt}}@asunsafe{@ascuheap{} @ascuintl{} @asulock{} @asucorrupt{}}@acunsafe{@acsmem{} @aculock{} @acucorrupt{}}}
 @c Same issues as getopt.
 
 The @code{getopt_long_only} function is equivalent to the
diff --git a/manual/intro.texi b/manual/intro.texi
index 879c1b38d9..2a0f882184 100644
--- a/manual/intro.texi
+++ b/manual/intro.texi
@@ -433,7 +433,7 @@  Functions marked with @code{i18n} may call internationalization
 functions of the @code{gettext} family and will be only as safe as those
 functions.  This note is thus equivalent to:
 
-@sampsafety{@mtsafe{@mtsenv{}}@asunsafe{@asucorrupt{} @ascuheap{} @ascudlopen{}}@acunsafe{@acucorrupt{}}}
+@sampsafety{@mtsafe{}@asunsafe{@asucorrupt{} @ascuheap{} @ascudlopen{}}@acunsafe{@acucorrupt{}}}
 
 
 @item @code{timer}
@@ -732,21 +732,6 @@  constant in these contexts, which makes the former safe.
 @c because of the unexpected locale changes.
 
 
-@item @code{env}
-@cindex env
-
-Functions marked with @code{env} as an MT-Safety issue access the
-environment with @code{getenv} or similar, without any guards to ensure
-safety in the presence of concurrent modifications.
-
-We do not mark these functions as MT- or AS-Unsafe, however, because
-functions that modify the environment are all marked with
-@code{const:env} and regarded as unsafe.  Being unsafe, the latter are
-not to be called when multiple threads are running or asynchronous
-signals are enabled, and so the environment can be considered
-effectively constant in these contexts, which makes the former safe.
-
-
 @item @code{hostid}
 @cindex hostid
 
diff --git a/manual/locale.texi b/manual/locale.texi
index 1b3f97839b..9e20295fc3 100644
--- a/manual/locale.texi
+++ b/manual/locale.texi
@@ -222,23 +222,21 @@  The symbols in this section are defined in the header file @file{locale.h}.
 
 @deftypefun {char *} setlocale (int @var{category}, const char *@var{locale})
 @standards{ISO, locale.h}
-@safety{@prelim{}@mtunsafe{@mtasuconst{:@mtslocale{}} @mtsenv{}}@asunsafe{@asuinit{} @asulock{} @ascuheap{} @asucorrupt{}}@acunsafe{@acuinit{} @acucorrupt{} @aculock{} @acsmem{} @acsfd{}}}
+@safety{@prelim{}@mtunsafe{@mtasuconst{:@mtslocale{}}}@asunsafe{@asuinit{} @asulock{} @ascuheap{} @asucorrupt{}}@acunsafe{@acuinit{} @acucorrupt{} @aculock{} @acsmem{} @acsfd{}}}
 @c Uses of the global locale object are unguarded in functions that
 @c ought to be MT-Safe, so we're ruling out the use of this function
 @c once threads are started.  It takes a write lock itself, but it may
 @c return a pointer loaded from the global locale object after releasing
 @c the lock, or before taking it.
-@c setlocale @mtasuconst:@mtslocale @mtsenv @asuinit @ascuheap @asulock @asucorrupt @acucorrupt @acsmem @acsfd @aculock
+@c setlocale @mtasuconst:@mtslocale @asuinit @ascuheap @asulock @asucorrupt @acucorrupt @acsmem @acsfd @aculock
 @c  libc_rwlock_wrlock @asulock @aculock
 @c  libc_rwlock_unlock @aculock
-@c  getenv LOCPATH @mtsenv
 @c  malloc @ascuheap @acsmem
 @c  free @ascuheap @acsmem
 @c  new_composite_name ok
 @c  setdata ok
 @c  setname ok
-@c  _nl_find_locale @mtsenv @asuinit @ascuheap @asulock @asucorrupt @acucorrupt @acsmem @acsfd @aculock
-@c   getenv LC_ALL and LANG @mtsenv
+@c  _nl_find_locale @asuinit @ascuheap @asulock @asucorrupt @acucorrupt @acsmem @acsfd @aculock
 @c   _nl_load_locale_from_archive @ascuheap @acucorrupt @acsmem @acsfd
 @c    sysconf _SC_PAGE_SIZE ok
 @c    _nl_normalize_codeset @ascuheap @acsmem
@@ -301,7 +299,6 @@  The symbols in this section are defined in the header file @file{locale.h}.
 @c     (libc_once-initializes gconv_cache and gconv_path_envvar; they're
 @c      never modified afterwards)
 @c     __gconv_load_cache @ascuheap @acsmem @acsfd
-@c      getenv GCONV_PATH @mtsenv
 @c      open_not_cancel @acsfd
 @c      __fxstat64 ok
 @c      close_not_cancel_no_status ok
diff --git a/manual/macros.texi b/manual/macros.texi
index 579da3fb81..584f26602f 100644
--- a/manual/macros.texi
+++ b/manual/macros.texi
@@ -125,10 +125,6 @@  const\comments\
 @macro mtslocale {comments}
 locale\comments\
 @end macro
-@c Function accesses the assumed-constant environment.
-@macro mtsenv {comments}
-env\comments\
-@end macro
 @c Function accesses the assumed-constant hostid.
 @macro mtshostid {comments}
 hostid\comments\
diff --git a/manual/memory.texi b/manual/memory.texi
index 3710d7ec66..c444f0f0e5 100644
--- a/manual/memory.texi
+++ b/manual/memory.texi
@@ -415,14 +415,12 @@  this function is in @file{stdlib.h}.
 @c   fastbin_index ok
 @c   fastbin ok
 @c   catomic_compare_and_exhange_val_acq ok
-@c   malloc_printerr dup @mtsenv
+@c   malloc_printerr dup
 @c     if we get to it, we're toast already, undefined behavior must have
 @c     been invoked before
-@c    libc_message @mtsenv [no leaks with cancellation disabled]
+@c    libc_message [no leaks with cancellation disabled]
 @c     FATAL_PREPARE ok
 @c      pthread_setcancelstate disable ok
-@c     libc_secure_getenv @mtsenv
-@c      getenv @mtsenv
 @c     open_not_cancel_2 dup @acsfd
 @c     strchrnul ok
 @c     WRITEV_FOR_FATAL ok
@@ -1096,7 +1094,7 @@  systems that do not support @w{ISO C11}.
 @standards{BSD, stdlib.h}
 @safety{@prelim{}@mtunsafe{@mtuinit{}}@asunsafe{@asuinit{} @asulock{}}@acunsafe{@acuinit{} @aculock{} @acsfd{} @acsmem{}}}
 @c __libc_valloc @mtuinit @asuinit @asulock @aculock @acsfd @acsmem
-@c  ptmalloc_init (once) @mtsenv @asulock @aculock @acsfd @acsmem
+@c  ptmalloc_init (once) @asulock @aculock @acsfd @acsmem
 @c   _dl_addr @asucorrupt? @aculock
 @c    __rtld_lock_lock_recursive (dl_load_lock) @asucorrupt? @aculock
 @c    _dl_find_dso_for_object ok, iterates over dl_ns and its _ns_loaded objs
@@ -1105,7 +1103,6 @@  systems that do not support @w{ISO C11}.
 @c     _dl_addr_inside_object ok
 @c    determine_info ok
 @c    __rtld_lock_unlock_recursive (dl_load_lock) @aculock
-@c   *_environ @mtsenv
 @c   next_env_entry ok
 @c   strcspn dup ok
 @c   __libc_mallopt dup @mtasuconst:mallopt [setting mp_]
@@ -1147,7 +1144,7 @@  interface, defined in @file{malloc.h}.
 @deftypefun int mallopt (int @var{param}, int @var{value})
 @safety{@prelim{}@mtunsafe{@mtuinit{} @mtasuconst{:mallopt}}@asunsafe{@asuinit{} @asulock{}}@acunsafe{@acuinit{} @aculock{}}}
 @c __libc_mallopt @mtuinit @mtasuconst:mallopt @asuinit @asulock @aculock
-@c  ptmalloc_init (once) dup @mtsenv @asulock @aculock @acsfd @acsmem
+@c  ptmalloc_init (once) dup @asulock @aculock @acsfd @acsmem
 @c  mutex_lock (main_arena->mutex) @asulock @aculock
 @c  malloc_consolidate dup ok
 @c  set_max_fast ok
@@ -1456,7 +1453,7 @@  space's data segment).
 @c that collect the possibly inconsistent data.
 
 @c __libc_mallinfo2 @mtuinit @mtasuconst:mallopt @asuinit @asulock @aculock
-@c  ptmalloc_init (once) dup @mtsenv @asulock @aculock @acsfd @acsmem
+@c  ptmalloc_init (once) dup @asulock @aculock @acsfd @acsmem
 @c  mutex_lock dup @asulock @aculock
 @c  int_mallinfo @mtasuconst:mallopt [mp_ access on main_arena]
 @c   malloc_consolidate dup ok
@@ -1556,13 +1553,12 @@  penalties for the program if the debugging mode is not enabled.
 
 @deftypefun void mtrace (void)
 @standards{GNU, mcheck.h}
-@safety{@prelim{}@mtunsafe{@mtsenv{} @mtasurace{:mtrace} @mtuinit{}}@asunsafe{@asuinit{} @ascuheap{} @asucorrupt{} @asulock{}}@acunsafe{@acuinit{} @acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
+@safety{@prelim{}@mtunsafe{@mtasurace{:mtrace} @mtuinit{}}@asunsafe{@asuinit{} @ascuheap{} @asucorrupt{} @asulock{}}@acunsafe{@acuinit{} @acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
 @c Like the mcheck hooks, these are not designed with thread safety in
 @c mind, because the hook pointers are temporarily modified without
 @c regard to other threads, signals or cancellation.
 
-@c mtrace @mtuinit @mtasurace:mtrace @mtsenv @asuinit @ascuheap @asucorrupt @acuinit @acucorrupt @aculock @acsfd @acsmem
-@c  __libc_secure_getenv dup @mtsenv
+@c mtrace @mtuinit @mtasurace:mtrace @asuinit @ascuheap @asucorrupt @acuinit @acucorrupt @aculock @acsfd @acsmem
 @c  malloc dup @ascuheap @acsmem
 @c  fopen dup @ascuheap @asulock @aculock @acsmem @acsfd
 @c  fcntl dup ok
diff --git a/manual/message.texi b/manual/message.texi
index ef68693fd1..2cff798346 100644
--- a/manual/message.texi
+++ b/manual/message.texi
@@ -85,11 +85,10 @@  are defined/declared in the @file{nl_types.h} header file.
 
 @deftypefun nl_catd catopen (const char *@var{cat_name}, int @var{flag})
 @standards{X/Open, nl_types.h}
-@safety{@prelim{}@mtsafe{@mtsenv{}}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{}}}
-@c catopen @mtsenv @ascuheap @acsmem
+@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{}}}
+@c catopen @ascuheap @acsmem
 @c  strchr ok
 @c  setlocale(,NULL) ok
-@c  getenv @mtsenv
 @c  strlen ok
 @c  alloca ok
 @c  stpcpy ok
@@ -831,7 +830,7 @@  not part of the C library they can be found in a separate library named
 
 @deftypefun {char *} gettext (const char *@var{msgid})
 @standards{GNU, libintl.h}
-@safety{@prelim{}@mtsafe{@mtsenv{}}@asunsafe{@asucorrupt{} @ascuheap{} @asulock{} @ascudlopen{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
+@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{} @ascuheap{} @asulock{} @ascudlopen{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
 @c Wrapper for dcgettext.
 The @code{gettext} function searches the currently selected message
 catalogs for a string which is equal to @var{msgid}.  If there is such a
@@ -879,7 +878,7 @@  information.
 
 @deftypefun {char *} dgettext (const char *@var{domainname}, const char *@var{msgid})
 @standards{GNU, libintl.h}
-@safety{@prelim{}@mtsafe{@mtsenv{}}@asunsafe{@asucorrupt{} @ascuheap{} @asulock{} @ascudlopen{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
+@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{} @ascuheap{} @asulock{} @ascudlopen{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
 @c Wrapper for dcgettext.
 The @code{dgettext} function acts just like the @code{gettext}
 function.  It only takes an additional first argument @var{domainname}
@@ -894,9 +893,9 @@  anachronism.  The returned string must never be modified.
 
 @deftypefun {char *} dcgettext (const char *@var{domainname}, const char *@var{msgid}, int @var{category})
 @standards{GNU, libintl.h}
-@safety{@prelim{}@mtsafe{@mtsenv{}}@asunsafe{@asucorrupt{} @ascuheap{} @asulock{} @ascudlopen{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
-@c dcgettext @mtsenv @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsfd @acsmem
-@c  dcigettext @mtsenv @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsfd @acsmem
+@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{} @ascuheap{} @asulock{} @ascudlopen{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
+@c dcgettext @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsfd @acsmem
+@c  dcigettext @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsfd @acsmem
 @c   libc_rwlock_rdlock @asulock @aculock
 @c   current_locale_name ok [protected from @mtslocale]
 @c   tfind ok
@@ -911,16 +910,15 @@  anachronism.  The returned string must never be modified.
 @c   strchr ok
 @c   stpcpy ok
 @c   category_to_name ok
-@c   guess_category_value @mtsenv
-@c    getenv @mtsenv
+@c   guess_category_value
 @c    current_locale_name dup ok [protected from @mtslocale by dcigettext]
 @c    strcmp ok
 @c   ENABLE_SECURE ok
-@c   _nl_find_domain @mtsenv @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsfd @acsmem
+@c   _nl_find_domain @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsfd @acsmem
 @c    libc_rwlock_rdlock dup @asulock @aculock
 @c    _nl_make_l10nflist dup @ascuheap @acsmem
 @c    libc_rwlock_unlock dup ok
-@c    _nl_load_domain @mtsenv @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsfd @acsmem
+@c    _nl_load_domain @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsfd @acsmem
 @c     libc_lock_lock_recursive @aculock
 @c     libc_lock_unlock_recursive @aculock
 @c     open->open_not_cancel_2 @acsfd
@@ -937,7 +935,7 @@  anachronism.  The returned string must never be modified.
 @c     hash_string dup ok
 @c     free dup @ascuheap @acsmem
 @c     libc_rwlock_init ok
-@c     _nl_find_msg dup @mtsenv @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsfd @acsmem
+@c     _nl_find_msg dup @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsfd @acsmem
 @c     libc_rwlock_fini ok
 @c     EXTRACT_PLURAL_EXPRESSION @ascuheap @acsmem
 @c      strstr dup ok
@@ -952,16 +950,15 @@  anachronism.  The returned string must never be modified.
 @c    _nl_explode_name dup @ascuheap @acsmem
 @c    libc_rwlock_wrlock dup @asulock @aculock
 @c    free dup @asulock @aculock @acsfd @acsmem
-@c   _nl_find_msg @mtsenv @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsfd @acsmem
-@c    _nl_load_domain dup @mtsenv @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsfd @acsmem
+@c   _nl_find_msg @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsfd @acsmem
+@c    _nl_load_domain dup @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsfd @acsmem
 @c    strlen ok
 @c    hash_string ok
 @c    W ok
 @c     SWAP ok
 @c      bswap_32 ok
 @c    strcmp ok
-@c    get_output_charset @mtsenv @ascuheap @acsmem
-@c     getenv dup @mtsenv
+@c    get_output_charset @ascuheap @acsmem
 @c     strlen dup ok
 @c     malloc dup @ascuheap @acsmem
 @c     memcpy dup ok
@@ -1272,7 +1269,7 @@  purpose.
 
 @deftypefun {char *} ngettext (const char *@var{msgid1}, const char *@var{msgid2}, unsigned long int @var{n})
 @standards{GNU, libintl.h}
-@safety{@prelim{}@mtsafe{@mtsenv{}}@asunsafe{@asucorrupt{} @ascuheap{} @asulock{} @ascudlopen{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
+@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{} @ascuheap{} @asulock{} @ascudlopen{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
 @c Wrapper for dcngettext.
 The @code{ngettext} function is similar to the @code{gettext} function
 as it finds the message catalogs in the same way.  But it takes two
@@ -1296,7 +1293,7 @@  Please note that the numeric value @var{n} has to be passed to the
 
 @deftypefun {char *} dngettext (const char *@var{domain}, const char *@var{msgid1}, const char *@var{msgid2}, unsigned long int @var{n})
 @standards{GNU, libintl.h}
-@safety{@prelim{}@mtsafe{@mtsenv{}}@asunsafe{@asucorrupt{} @ascuheap{} @asulock{} @ascudlopen{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
+@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{} @ascuheap{} @asulock{} @ascudlopen{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
 @c Wrapper for dcngettext.
 The @code{dngettext} is similar to the @code{dgettext} function in the
 way the message catalog is selected.  The difference is that it takes
@@ -1306,7 +1303,7 @@  parameters are handled in the same way @code{ngettext} handles them.
 
 @deftypefun {char *} dcngettext (const char *@var{domain}, const char *@var{msgid1}, const char *@var{msgid2}, unsigned long int @var{n}, int @var{category})
 @standards{GNU, libintl.h}
-@safety{@prelim{}@mtsafe{@mtsenv{}}@asunsafe{@asucorrupt{} @ascuheap{} @asulock{} @ascudlopen{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
+@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{} @ascuheap{} @asulock{} @ascudlopen{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
 @c Wrapper for dcigettext.
 The @code{dcngettext} is similar to the @code{dcgettext} function in the
 way the message catalog is selected.  The difference is that it takes
diff --git a/manual/pattern.texi b/manual/pattern.texi
index 250fa1e265..9de0842c14 100644
--- a/manual/pattern.texi
+++ b/manual/pattern.texi
@@ -27,29 +27,25 @@  declared in @file{fnmatch.h}.
 
 @deftypefun int fnmatch (const char *@var{pattern}, const char *@var{string}, int @var{flags})
 @standards{POSIX.2, fnmatch.h}
-@safety{@prelim{}@mtsafe{@mtsenv{} @mtslocale{}}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{}}}
-@c fnmatch @mtsenv @mtslocale @ascuheap @acsmem
+@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{}}}
+@c fnmatch @mtslocale @ascuheap @acsmem
 @c  strnlen dup ok
 @c  mbsrtowcs
 @c  memset dup ok
 @c  malloc dup @ascuheap @acsmem
 @c  mbsinit dup ok
 @c  free dup @ascuheap @acsmem
-@c  FCT = internal_fnwmatch @mtsenv @mtslocale @ascuheap @acsmem
+@c  FCT = internal_fnwmatch @mtslocale @ascuheap @acsmem
 @c   FOLD @mtslocale
 @c    towlower @mtslocale
-@c   EXT @mtsenv @mtslocale @ascuheap @acsmem
+@c   EXT @mtslocale @ascuheap @acsmem
 @c    STRLEN = wcslen dup ok
-@c    getenv @mtsenv
 @c    malloc dup @ascuheap @acsmem
 @c    MEMPCPY = wmempcpy dup ok
-@c    FCT dup @mtsenv @mtslocale @ascuheap @acsmem
+@c    FCT dup @mtslocale @ascuheap @acsmem
 @c    STRCAT = wcscat dup ok
 @c    free dup @ascuheap @acsmem
-@c   END @mtsenv
-@c    getenv @mtsenv
 @c   MEMCHR = wmemchr dup ok
-@c   getenv @mtsenv
 @c   IS_CHAR_CLASS = is_char_class @mtslocale
 @c    wctype @mtslocale
 @c   BTOWC ok
@@ -385,8 +381,8 @@  This is a GNU extension.
 
 @deftypefun int glob (const char *@var{pattern}, int @var{flags}, int (*@var{errfunc}) (const char *@var{filename}, int @var{error-code}), glob_t *@var{vector-ptr})
 @standards{POSIX.2, glob.h}
-@safety{@prelim{}@mtunsafe{@mtasurace{:utent} @mtsenv{} @mtascusig{:ALRM} @mtascutimer{} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @asucorrupt{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
-@c glob @mtasurace:utent @mtsenv @mtascusig:ALRM @mtascutimer @mtslocale @ascudlopen @ascuplugin @asucorrupt @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@safety{@prelim{}@mtunsafe{@mtasurace{:utent} @mtascusig{:ALRM} @mtascutimer{} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @asucorrupt{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
+@c glob @mtasurace:utent @mtascusig:ALRM @mtascutimer @mtslocale @ascudlopen @ascuplugin @asucorrupt @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
 @c  strlen dup ok
 @c  strchr dup ok
 @c  malloc dup @ascuheap @acsmem
@@ -396,7 +392,6 @@  This is a GNU extension.
 @c  globfree dup @asucorrupt @ascuheap @acucorrupt @acsmem
 @c  glob_pattern_p ok
 @c   glob_pattern_type dup ok
-@c  getenv dup @mtsenv
 @c  GET_LOGIN_NAME_MAX ok
 @c  getlogin_r dup @mtasurace:utent @mtascusig:ALRM @mtascutimer @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
 @c  GETPW_R_SIZE_MAX ok
@@ -409,7 +404,7 @@  This is a GNU extension.
 @c  S_ISDIR dup ok
 @c  strdup dup @ascuheap @acsmem
 @c  glob_pattern_type ok
-@c  glob_in_dir @mtsenv @mtslocale @asucorrupt @ascuheap @acucorrupt @acsfd @acsmem
+@c  glob_in_dir @mtslocale @asucorrupt @ascuheap @acucorrupt @acsfd @acsmem
 @c   strlen dup ok
 @c   glob_pattern_type dup ok
 @c   malloc dup @ascuheap @acsmem
@@ -425,7 +420,7 @@  This is a GNU extension.
 @c   readdir64 ok [protected by exclusive use of the stream]
 @c   REAL_DIR_ENTRY ok
 @c   DIRENT_MIGHT_BE_DIR ok
-@c   fnmatch dup @mtsenv @mtslocale @ascuheap @acsmem
+@c   fnmatch dup @mtslocale @ascuheap @acsmem
 @c   DIRENT_MIGHT_BE_SYMLINK ok
 @c   link_exists_p ok
 @c    link_exists2_p ok
@@ -509,7 +504,7 @@  is encountered @code{glob} @emph{can} fail.
 
 @deftypefun int glob64 (const char *@var{pattern}, int @var{flags}, int (*@var{errfunc}) (const char *@var{filename}, int @var{error-code}), glob64_t *@var{vector-ptr})
 @standards{GNU, glob.h}
-@safety{@prelim{}@mtunsafe{@mtasurace{:utent} @mtsenv{} @mtascusig{:ALRM} @mtascutimer{} @mtslocale{}}@asunsafe{@ascudlopen{} @asucorrupt{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
+@safety{@prelim{}@mtunsafe{@mtasurace{:utent} @mtascusig{:ALRM} @mtascutimer{} @mtslocale{}}@asunsafe{@ascudlopen{} @asucorrupt{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
 @c Same code as glob, but with glob64_t #defined as glob_t.
 The @code{glob64} function was added as part of the Large File Summit
 extensions but is not part of the original LFS proposal.  The reason for
@@ -1622,7 +1617,7 @@  the function @code{regerror} to turn it into an error message string.
 
 @deftypefun size_t regerror (int @var{errcode}, const regex_t *restrict @var{compiled}, char *restrict @var{buffer}, size_t @var{length})
 @standards{POSIX.2, regex.h}
-@safety{@prelim{}@mtsafe{@mtsenv{}}@asunsafe{@asucorrupt{} @ascuheap{} @asulock{} @ascudlopen{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
+@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{} @ascuheap{} @asulock{} @ascudlopen{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
 @c regerror calls gettext, strcmp and mempcpy or memcpy.
 This function produces an error message string for the error code
 @var{errcode}, and stores the string in @var{length} bytes of memory
@@ -1787,20 +1782,19 @@  the beginning of the vector.
 
 @deftypefun int wordexp (const char *@var{words}, wordexp_t *@var{word-vector-ptr}, int @var{flags})
 @standards{POSIX.2, wordexp.h}
-@safety{@prelim{}@mtunsafe{@mtasurace{:utent} @mtasuconst{:@mtsenv{}} @mtsenv{} @mtascusig{:ALRM} @mtascutimer{} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuintl{} @ascuheap{} @asucorrupt{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
-@c wordexp @mtasurace:utent @mtasuconst:@mtsenv @mtsenv @mtascusig:ALRM @mtascutimer @mtslocale @ascudlopen @ascuplugin @ascuintl @ascuheap @asucorrupt @asulock @acucorrupt @aculock @acsfd @acsmem
+@safety{@prelim{}@mtunsafe{@mtasurace{:utent} @mtascusig{:ALRM} @mtascutimer{} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuintl{} @ascuheap{} @asucorrupt{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
+@c wordexp @mtasurace:utent @mtascusig:ALRM @mtascutimer @mtslocale @ascudlopen @ascuplugin @ascuintl @ascuheap @asucorrupt @asulock @acucorrupt @aculock @acsfd @acsmem
 @c  w_newword ok
 @c  wordfree dup @asucorrupt @ascuheap @acucorrupt @acsmem
 @c  calloc dup @ascuheap @acsmem
-@c  getenv dup @mtsenv
 @c  strcpy dup ok
 @c  parse_backslash @ascuheap @acsmem
 @c   w_addchar dup @ascuheap @acsmem
-@c  parse_dollars @mtasuconst:@mtsenv @mtslocale @mtsenv @ascudlopen @ascuplugin @ascuintl @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c  parse_dollars @mtslocale @ascudlopen @ascuplugin @ascuintl @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
 @c   w_addchar dup @ascuheap @acsmem
-@c   parse_arith @mtasuconst:@mtsenv @mtslocale @mtsenv @ascudlopen @ascuplugin @ascuintl @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c   parse_arith @mtslocale @ascudlopen @ascuplugin @ascuintl @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
 @c    w_newword dup ok
-@c    parse_dollars dup @mtasuconst:@mtsenv @mtslocale @mtsenv @ascudlopen @ascuplugin @ascuintl @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c    parse_dollars dup @mtslocale @ascudlopen @ascuplugin @ascuintl @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
 @c    parse_backtick dup @ascuplugin @ascuheap @aculock @acsfd @acsmem
 @c    parse_qtd_backslash dup @ascuheap @acsmem
 @c    eval_expr @mtslocale
@@ -1842,7 +1836,7 @@  the beginning of the vector.
 @c     free dup @ascuheap @acsmem
 @c     kill dup ok
 @c    free dup @ascuheap @acsmem
-@c   parse_param @mtasuconst:@mtsenv @mtslocale @mtsenv @ascudlopen @ascuplugin @ascuintl @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c   parse_param @mtslocale @ascudlopen @ascuplugin @ascuintl @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
 @c     reads from __libc_argc and __libc_argv without guards
 @c    w_newword dup ok
 @c    isalpha dup @mtslocale^^
@@ -1860,14 +1854,13 @@  the beginning of the vector.
 @c    stpcpy dup ok
 @c    w_addword dup @ascuheap @acsmem
 @c    strdup dup @ascuheap @acsmem
-@c    getenv dup @mtsenv
-@c    parse_dollars dup @mtasuconst:@mtsenv @mtslocale @mtsenv @ascudlopen @ascuplugin @ascuintl @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
-@c    parse_tilde dup @mtslocale @mtsenv @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
-@c    fnmatch dup @mtsenv @mtslocale @ascuheap @acsmem
+@c    parse_dollars dup @mtslocale @ascudlopen @ascuplugin @ascuintl @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c    parse_tilde dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c    fnmatch dup @mtslocale @ascuheap @acsmem
 @c    mempcpy dup ok
 @c    _ dup @ascuintl
 @c    fxprintf dup @aculock
-@c    setenv dup @mtasuconst:@mtsenv @ascuheap @asulock @acucorrupt @aculock @acsmem
+@c    setenv dup @ascuheap @asulock @acucorrupt @aculock @acsmem
 @c    strspn dup ok
 @c    strcspn dup ok
 @c  parse_backtick @ascuplugin @ascuheap @aculock @acsfd @acsmem
@@ -1877,8 +1870,8 @@  the beginning of the vector.
 @c   parse_qtd_backslash dup @ascuheap @acsmem
 @c   parse_backslash dup @ascuheap @acsmem
 @c   w_addchar dup @ascuheap @acsmem
-@c  parse_dquote @mtasuconst:@mtsenv @mtslocale @mtsenv @ascudlopen @ascuplugin @ascuintl @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
-@c   parse_dollars dup @mtasuconst:@mtsenv @mtslocale @mtsenv @ascudlopen @ascuplugin @ascuintl @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c  parse_dquote @mtslocale @ascudlopen @ascuplugin @ascuintl @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c   parse_dollars dup @mtslocale @ascudlopen @ascuplugin @ascuintl @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
 @c   parse_backtick dup @ascuplugin @ascuheap @aculock @acsfd @acsmem
 @c   parse_qtd_backslash dup @ascuheap @acsmem
 @c   w_addchar dup @ascuheap @acsmem
@@ -1888,10 +1881,9 @@  the beginning of the vector.
 @c   free dup @ascuheap @acsmem
 @c  parse_squote dup @ascuheap @acsmem
 @c   w_addchar dup @ascuheap @acsmem
-@c  parse_tilde @mtslocale @mtsenv @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c  parse_tilde @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
 @c   strchr dup ok
 @c   w_addchar dup @ascuheap @acsmem
-@c   getenv dup @mtsenv
 @c   w_addstr dup @ascuheap @acsmem
 @c    strlen dup ok
 @c    w_addmem dup @ascuheap @acsmem
@@ -1901,17 +1893,17 @@  the beginning of the vector.
 @c   getuid dup ok
 @c   getpwuid_r dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
 @c   getpwnam_r dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
-@c  parse_glob @mtasurace:utent @mtasuconst:@mtsenv @mtsenv @mtascusig:ALRM @mtascutimer @mtslocale @ascudlopen @ascuplugin @ascuintl @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c  parse_glob @mtasurace:utent @mtascusig:ALRM @mtascutimer @mtslocale @ascudlopen @ascuplugin @ascuintl @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
 @c   strchr dup ok
-@c   parse_dollars dup @mtasuconst:@mtsenv @mtslocale @mtsenv @ascudlopen @ascuplugin @ascuintl @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c   parse_dollars dup @mtslocale @ascudlopen @ascuplugin @ascuintl @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
 @c   parse_qtd_backslash @ascuheap @acsmem
 @c    w_addchar dup @ascuheap @acsmem
 @c   parse_backslash dup @ascuheap @acsmem
 @c   w_addchar dup @ascuheap @acsmem
 @c   w_addword dup @ascuheap @acsmem
 @c   w_newword dup ok
-@c   do_parse_glob @mtasurace:utent @mtsenv @mtascusig:ALRM @mtascutimer @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @aculock @acsfd @acsmem
-@c    glob dup @mtasurace:utent @mtsenv @mtascusig:ALRM @mtascutimer @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @aculock @acsfd @acsmem [auto glob_t avoids @asucorrupt @acucorrupt]
+@c   do_parse_glob @mtasurace:utent @mtascusig:ALRM @mtascutimer @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @aculock @acsfd @acsmem
+@c    glob dup @mtasurace:utent @mtascusig:ALRM @mtascutimer @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @aculock @acsfd @acsmem [auto glob_t avoids @asucorrupt @acucorrupt]
 @c    w_addstr dup @ascuheap @acsmem
 @c    w_addchar dup @ascuheap @acsmem
 @c    globfree dup @ascuheap @acsmem [auto glob_t avoids @asucorrupt @acucorrupt]
diff --git a/manual/process.texi b/manual/process.texi
index 8254e5ee86..78e355899d 100644
--- a/manual/process.texi
+++ b/manual/process.texi
@@ -477,7 +477,7 @@  the @code{environ} variable.
 
 @deftypefun int execvp (const char *@var{filename}, char *const @var{argv}@t{[]})
 @standards{POSIX.1, unistd.h}
-@safety{@prelim{}@mtsafe{@mtsenv{}}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{}}}
+@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{}}}
 The @code{execvp} function is similar to @code{execv}, except that it
 searches the directories listed in the @code{PATH} environment variable
 (@pxref{Standard Environment}) to find the full file name of a
@@ -490,7 +490,7 @@  to run the commands that users type.
 
 @deftypefun int execlp (const char *@var{filename}, const char *@var{arg0}, @dots{})
 @standards{POSIX.1, unistd.h}
-@safety{@prelim{}@mtsafe{@mtsenv{}}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{}}}
+@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{}}}
 This function is like @code{execl}, except that it performs the same
 file name searching as the @code{execvp} function.
 @end deftypefun
diff --git a/manual/socket.texi b/manual/socket.texi
index 8708cbb07c..b46ea147e1 100644
--- a/manual/socket.texi
+++ b/manual/socket.texi
@@ -1287,19 +1287,18 @@  need to save it across calls.  You can also use @code{getaddrinfo} and
 
 @deftypefun {struct hostent *} gethostbyname (const char *@var{name})
 @standards{BSD, netdb.h}
-@safety{@prelim{}@mtunsafe{@mtasurace{:hostbyname} @mtsenv{} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @asucorrupt{} @ascuheap{} @asulock{}}@acunsafe{@aculock{} @acucorrupt{} @acsmem{} @acsfd{}}}
-@c gethostbyname @mtasurace:hostbyname @mtsenv @mtslocale @ascudlopen @ascuplugin @asucorrupt @ascuheap @asulock @aculock @acucorrupt @acsmem @acsfd
+@safety{@prelim{}@mtunsafe{@mtasurace{:hostbyname} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @asucorrupt{} @ascuheap{} @asulock{}}@acunsafe{@aculock{} @acucorrupt{} @acsmem{} @acsfd{}}}
+@c gethostbyname @mtasurace:hostbyname @mtslocale @ascudlopen @ascuplugin @asucorrupt @ascuheap @asulock @aculock @acucorrupt @acsmem @acsfd
 @c  libc_lock_lock dup @asulock @aculock
 @c  malloc dup @ascuheap @acsmem
-@c  nss_hostname_digits_dots @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
-@c   res_maybe_init(!preinit) @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@c  nss_hostname_digits_dots @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@c   res_maybe_init(!preinit) @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
 @c    res_iclose @acsuheap @acsmem @acsfd
 @c     close_not_cancel_no_status dup @acsfd
 @c     free dup @acsuheap @acsmem
-@c    res_vinit @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@c    res_vinit @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
 @c     res_randomid ok
 @c      getpid dup ok
-@c     getenv dup @mtsenv
 @c     strncpy dup ok
 @c     fopen dup @ascuheap @asulock @acsmem @acsfd @aculock
 @c     fsetlocking dup ok [no concurrent uses]
@@ -1334,8 +1333,8 @@  need to save it across calls.  You can also use @code{getaddrinfo} and
 @c     gethostname dup ok
 @c     strcpy dup ok
 @c     rawmemchr dup ok
-@c    res_ninit @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
-@c     res_vinit dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@c    res_ninit @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@c     res_vinit dup @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
 @c   isdigit dup @mtslocale
 @c   isxdigit dup @mtslocale
 @c   strlen dup ok
@@ -1347,7 +1346,7 @@  need to save it across calls.  You can also use @code{getaddrinfo} and
 @c   strcpy dup ok
 @c   memcpy dup ok
 @c   strchr dup ok
-@c  gethostbyname_r dup @mtsenv @mtslocale @ascudlopen @ascuplugin @asucorrupt @ascuheap @asulock @aculock @acucorrupt @acsmem @acsfd
+@c  gethostbyname_r dup @mtslocale @ascudlopen @ascuplugin @asucorrupt @ascuheap @asulock @aculock @acucorrupt @acsmem @acsfd
 @c  realloc dup @ascuheap @acsmem
 @c  free dup @ascuheap @acsmem
 @c  libc_lock_unlock dup @aculock
@@ -1358,12 +1357,12 @@  named @var{name}.  If the lookup fails, it returns a null pointer.
 
 @deftypefun {struct hostent *} gethostbyname2 (const char *@var{name}, int @var{af})
 @standards{IPv6 Basic API, netdb.h}
-@safety{@prelim{}@mtunsafe{@mtasurace{:hostbyname2} @mtsenv{} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @asucorrupt{} @ascuheap{} @asulock{}}@acunsafe{@aculock{} @acucorrupt{} @acsmem{} @acsfd{}}}
-@c gethostbyname2 @mtasurace:hostbyname2 @mtsenv @mtslocale @ascudlopen @ascuplugin @asucorrupt @ascuheap @asulock @aculock @acucorrupt @acsmem @acsfd
+@safety{@prelim{}@mtunsafe{@mtasurace{:hostbyname2} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @asucorrupt{} @ascuheap{} @asulock{}}@acunsafe{@aculock{} @acucorrupt{} @acsmem{} @acsfd{}}}
+@c gethostbyname2 @mtasurace:hostbyname2 @mtslocale @ascudlopen @ascuplugin @asucorrupt @ascuheap @asulock @aculock @acucorrupt @acsmem @acsfd
 @c  libc_lock_lock dup @asulock @aculock
 @c  malloc dup @ascuheap @acsmem
-@c  nss_hostname_digits_dots dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
-@c  gethostbyname2_r dup @mtsenv @mtslocale @ascudlopen @ascuplugin @asucorrupt @ascuheap @asulock @aculock @acucorrupt @acsmem @acsfd
+@c  nss_hostname_digits_dots dup @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@c  gethostbyname2_r dup @mtslocale @ascudlopen @ascuplugin @asucorrupt @ascuheap @asulock @aculock @acucorrupt @acsmem @acsfd
 @c  realloc dup @ascuheap @acsmem
 @c  free dup @ascuheap @acsmem
 @c  libc_lock_unlock dup @aculock
@@ -1375,11 +1374,11 @@  allows the caller to specify the desired address family (e.g.@:
 
 @deftypefun {struct hostent *} gethostbyaddr (const void *@var{addr}, socklen_t @var{length}, int @var{format})
 @standards{BSD, netdb.h}
-@safety{@prelim{}@mtunsafe{@mtasurace{:hostbyaddr} @mtsenv{} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @asucorrupt{} @ascuheap{} @asulock{}}@acunsafe{@aculock{} @acucorrupt{} @acsmem{} @acsfd{}}}
-@c gethostbyaddr @mtasurace:hostbyaddr @mtsenv @mtslocale @ascudlopen @ascuplugin @asucorrupt @ascuheap @asulock @aculock @acucorrupt @acsmem @acsfd
+@safety{@prelim{}@mtunsafe{@mtasurace{:hostbyaddr} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @asucorrupt{} @ascuheap{} @asulock{}}@acunsafe{@aculock{} @acucorrupt{} @acsmem{} @acsfd{}}}
+@c gethostbyaddr @mtasurace:hostbyaddr @mtslocale @ascudlopen @ascuplugin @asucorrupt @ascuheap @asulock @aculock @acucorrupt @acsmem @acsfd
 @c  libc_lock_lock dup @asulock @aculock
 @c  malloc dup @ascuheap @acsmem
-@c  gethostbyaddr_r dup @mtsenv @mtslocale @ascudlopen @ascuplugin @asucorrupt @ascuheap @asulock @aculock @acucorrupt @acsmem @acsfd
+@c  gethostbyaddr_r dup @mtslocale @ascudlopen @ascuplugin @asucorrupt @ascuheap @asulock @aculock @acucorrupt @acsmem @acsfd
 @c  realloc dup @ascuheap @acsmem
 @c  free dup @ascuheap @acsmem
 @c  libc_lock_unlock dup @aculock
@@ -1431,12 +1430,11 @@  used in this context.
 
 @deftypefun int gethostbyname_r (const char *restrict @var{name}, struct hostent *restrict @var{result_buf}, char *restrict @var{buf}, size_t @var{buflen}, struct hostent **restrict @var{result}, int *restrict @var{h_errnop})
 @standards{GNU, netdb.h}
-@safety{@prelim{}@mtsafe{@mtsenv{} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @asucorrupt{} @ascuheap{} @asulock{}}@acunsafe{@aculock{} @acucorrupt{} @acsmem{} @acsfd{}}}
-@c gethostbyname_r @mtsenv @mtslocale @ascudlopen @ascuplugin @asucorrupt @ascuheap @asulock @aculock @acucorrupt @acsmem @acsfd
-@c  nss_hostname_digits_dots dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
-@c  nscd_gethostbyname_r @mtsenv @ascuheap @acsfd @acsmem
-@c   nscd_gethst_r @mtsenv @ascuheap @acsfd @acsmem
-@c    getenv dup @mtsenv
+@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @asucorrupt{} @ascuheap{} @asulock{}}@acunsafe{@aculock{} @acucorrupt{} @acsmem{} @acsfd{}}}
+@c gethostbyname_r @mtslocale @ascudlopen @ascuplugin @asucorrupt @ascuheap @asulock @aculock @acucorrupt @acsmem @acsfd
+@c  nss_hostname_digits_dots dup @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@c  nscd_gethostbyname_r @ascuheap @acsfd @acsmem
+@c   nscd_gethst_r @ascuheap @acsfd @acsmem
 @c    nscd_get_map_ref dup @ascuheap @acsfd @acsmem
 @c    nscd_cache_search dup ok
 @c    memcpy dup ok
@@ -1446,11 +1444,10 @@  used in this context.
 @c    close_not_cancel_no_status dup @acsfd
 @c    nscd_drop_map_ref dup @ascuheap @acsmem
 @c    nscd_unmap dup @ascuheap @acsmem
-@c  res_maybe_init(!preinit) dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
-@c  res_hconf_init @mtsenv @mtslocale @asucorrupt @ascuheap @aculock @acucorrupt @acsmem [no @asuinit:reshconf @acuinit:reshconf, conditionally called]
-@c   res_hconf.c:do_init @mtsenv @mtslocale @asucorrupt @ascuheap @aculock @acucorrupt @acsmem
+@c  res_maybe_init(!preinit) dup @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@c  res_hconf_init @mtslocale @asucorrupt @ascuheap @aculock @acucorrupt @acsmem [no @asuinit:reshconf @acuinit:reshconf, conditionally called]
+@c   res_hconf.c:do_init @mtslocale @asucorrupt @ascuheap @aculock @acucorrupt @acsmem
 @c    memset dup ok
-@c    getenv dup @mtsenv
 @c    fopen dup @ascuheap @asulock @acsmem @acsfd @aculock
 @c    fsetlocking dup ok [no concurrent uses]
 @c    fgets_unlocked dup ok [no concurrent uses]
@@ -1555,13 +1552,13 @@  gethostname (char *host)
 
 @deftypefun int gethostbyname2_r (const char *@var{name}, int @var{af}, struct hostent *restrict @var{result_buf}, char *restrict @var{buf}, size_t @var{buflen}, struct hostent **restrict @var{result}, int *restrict @var{h_errnop})
 @standards{GNU, netdb.h}
-@safety{@prelim{}@mtsafe{@mtsenv{} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @asucorrupt{} @ascuheap{} @asulock{}}@acunsafe{@aculock{} @acucorrupt{} @acsmem{} @acsfd{}}}
-@c gethostbyname2_r @mtsenv @mtslocale @ascudlopen @ascuplugin @asucorrupt @ascuheap @asulock @aculock @acucorrupt @acsmem @acsfd
-@c  nss_hostname_digits_dots dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
-@c  nscd_gethostbyname2_r @mtsenv @ascuheap @asulock @aculock @acsfd @acsmem
-@c   nscd_gethst_r dup @mtsenv @ascuheap @asulock @aculock @acsfd @acsmem
-@c  res_maybe_init(!preinit) dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
-@c  res_hconf_init dup @mtsenv @mtslocale @asucorrupt @ascuheap @aculock @acucorrupt @acsmem [no @asuinit:reshconf @acuinit:reshconf, conditionally called]
+@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @asucorrupt{} @ascuheap{} @asulock{}}@acunsafe{@aculock{} @acucorrupt{} @acsmem{} @acsfd{}}}
+@c gethostbyname2_r @mtslocale @ascudlopen @ascuplugin @asucorrupt @ascuheap @asulock @aculock @acucorrupt @acsmem @acsfd
+@c  nss_hostname_digits_dots dup @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@c  nscd_gethostbyname2_r @ascuheap @asulock @aculock @acsfd @acsmem
+@c   nscd_gethst_r dup @ascuheap @asulock @aculock @acsfd @acsmem
+@c  res_maybe_init(!preinit) dup @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@c  res_hconf_init dup @mtslocale @asucorrupt @ascuheap @aculock @acucorrupt @acsmem [no @asuinit:reshconf @acuinit:reshconf, conditionally called]
 @c  nss_hosts_lookup2 dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
 @c  *fct.l -> _nss_*_gethostbyname2_r @ascuplugin
 @c  nss_next2 dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
@@ -1573,13 +1570,13 @@  allows the caller to specify the desired address family (e.g.@:
 
 @deftypefun int gethostbyaddr_r (const void *@var{addr}, socklen_t @var{length}, int @var{format}, struct hostent *restrict @var{result_buf}, char *restrict @var{buf}, size_t @var{buflen}, struct hostent **restrict @var{result}, int *restrict @var{h_errnop})
 @standards{GNU, netdb.h}
-@safety{@prelim{}@mtsafe{@mtsenv{} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @asucorrupt{} @ascuheap{} @asulock{}}@acunsafe{@aculock{} @acucorrupt{} @acsmem{} @acsfd{}}}
-@c gethostbyaddr_r @mtsenv @mtslocale @ascudlopen @ascuplugin @asucorrupt @ascuheap @asulock @aculock @acucorrupt @acsmem @acsfd
+@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @asucorrupt{} @ascuheap{} @asulock{}}@acunsafe{@aculock{} @acucorrupt{} @acsmem{} @acsfd{}}}
+@c gethostbyaddr_r @mtslocale @ascudlopen @ascuplugin @asucorrupt @ascuheap @asulock @aculock @acucorrupt @acsmem @acsfd
 @c  memcmp dup ok
-@c  nscd_gethostbyaddr_r @mtsenv @ascuheap @asulock @aculock @acsfd @acsmem
-@c   nscd_gethst_r dup @mtsenv @ascuheap @asulock @aculock @acsfd @acsmem
-@c  res_maybe_init(!preinit) dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
-@c  res_hconf_init dup @mtsenv @mtslocale @asucorrupt @ascuheap @aculock @acucorrupt @acsmem [no @asuinit:reshconf @acuinit:reshconf, conditionally called]
+@c  nscd_gethostbyaddr_r @ascuheap @asulock @aculock @acsfd @acsmem
+@c   nscd_gethst_r dup @ascuheap @asulock @aculock @acsfd @acsmem
+@c  res_maybe_init(!preinit) dup @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@c  res_hconf_init dup @mtslocale @asucorrupt @ascuheap @aculock @acucorrupt @acsmem [no @asuinit:reshconf @acuinit:reshconf, conditionally called]
 @c  nss_hosts_lookup2 dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
 @c  *fct.l -> _nss_*_gethostbyaddr_r @ascuplugin
 @c  nss_next2 dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
@@ -1609,11 +1606,11 @@  when using these functions because they are not reentrant.
 
 @deftypefun void sethostent (int @var{stayopen})
 @standards{BSD, netdb.h}
-@safety{@prelim{}@mtunsafe{@mtasurace{:hostent} @mtsenv{} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
-@c sethostent @mtasurace:hostent @mtsenv @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@safety{@prelim{}@mtunsafe{@mtasurace{:hostent} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
+@c sethostent @mtasurace:hostent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
 @c  libc_lock_lock dup @asulock @aculock
-@c  nss_setent(nss_hosts_lookup2) @mtasurace:hostent @mtsenv @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
-@c   res_maybe_init(!preinit) dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@c  nss_setent(nss_hosts_lookup2) @mtasurace:hostent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c   res_maybe_init(!preinit) dup @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
 @c   set_h_errno dup ok
 @c   setup(nss_hosts_lookup2) @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
 @c    *lookup_fct = nss_hosts_lookup2 dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
@@ -1635,20 +1632,20 @@  reopening the database for each call.
 
 @deftypefun {struct hostent *} gethostent (void)
 @standards{BSD, netdb.h}
-@safety{@prelim{}@mtunsafe{@mtasurace{:hostent} @mtasurace{:hostentbuf} @mtsenv{} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
-@c gethostent @mtasurace:hostent @mtasurace:hostentbuf @mtsenv @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@safety{@prelim{}@mtunsafe{@mtasurace{:hostent} @mtasurace{:hostentbuf} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
+@c gethostent @mtasurace:hostent @mtasurace:hostentbuf @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
 @c  libc_lock_lock dup @asulock @aculock
-@c  nss_getent(gethostent_r) @mtasurace:hostent @mtsenv @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c  nss_getent(gethostent_r) @mtasurace:hostent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
 @c   malloc dup @ascuheap @acsmem
-@c   *func = gethostent_r dup @mtasurace:hostent @mtsenv @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c   *func = gethostent_r dup @mtasurace:hostent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
 @c   realloc dup @ascuheap @acsmem
 @c   free dup @ascuheap @acsmem
 @c  libc_lock_unlock dup @aculock
 @c
-@c gethostent_r @mtasurace:hostent @mtsenv @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c gethostent_r @mtasurace:hostent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
 @c  libc_lock_lock dup @asulock @aculock
-@c  nss_getent_r(nss_hosts_lookup2) @mtasurace:hostent @mtsenv @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
-@c   res_maybe_init(!preinit) dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@c  nss_getent_r(nss_hosts_lookup2) @mtasurace:hostent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c   res_maybe_init(!preinit) dup @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
 @c   setup(nss_hosts_lookup2) dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
 @c   *fct.f @mtasurace:hostent @ascuplugin
 @c   nss_next2 dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
@@ -1662,11 +1659,11 @@  returns a null pointer if there are no more entries.
 
 @deftypefun void endhostent (void)
 @standards{BSD, netdb.h}
-@safety{@prelim{}@mtunsafe{@mtasurace{:hostent} @mtsenv{} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
-@c endhostent @mtasurace:hostent @mtsenv @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@safety{@prelim{}@mtunsafe{@mtasurace{:hostent} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
+@c endhostent @mtasurace:hostent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
 @c  libc_lock_lock @asulock @aculock
-@c  nss_endent(nss_hosts_lookup2) @mtasurace:hostent @mtsenv @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
-@c   res_maybe_init(!preinit) dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@c  nss_endent(nss_hosts_lookup2) @mtasurace:hostent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c   res_maybe_init(!preinit) dup @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
 @c   setup(nss_passwd_lookup2) dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
 @c   *fct.f @mtasurace:hostent @ascuplugin
 @c   nss_next2 dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
@@ -3526,18 +3523,18 @@  copy the information if you need to save it.
 
 @deftypefun {struct netent *} getnetbyname (const char *@var{name})
 @standards{BSD, netdb.h}
-@safety{@prelim{}@mtunsafe{@mtasurace{:netbyname} @mtsenv{} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
-@c getnetbyname =~ getpwuid @mtasurace:netbyname @mtsenv @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@safety{@prelim{}@mtunsafe{@mtasurace{:netbyname} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
+@c getnetbyname =~ getpwuid @mtasurace:netbyname @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
 @c  libc_lock_lock dup @asulock @aculock
 @c  malloc dup @ascuheap @acsmem
-@c  getnetbyname_r dup @mtsenv @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c  getnetbyname_r dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
 @c  realloc dup @ascuheap @acsmem
 @c  free dup @ascuheap @acsmem
 @c  libc_lock_unlock dup @aculock
 @c
-@c getnetbyname_r =~ getpwuid_r @mtsenv @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c getnetbyname_r =~ getpwuid_r @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
 @c   no nscd support
-@c  res_maybe_init(!preinit) dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@c  res_maybe_init(!preinit) dup @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
 @c  nss_networks_lookup2 =~ nss_passwd_lookup2 @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
 @c  *fct.l -> _nss_*_getnetbyname_r @ascuplugin
 @c  nss_next2 dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
@@ -3576,11 +3573,11 @@  functions because they are not reentrant.
 
 @deftypefun void setnetent (int @var{stayopen})
 @standards{BSD, netdb.h}
-@safety{@prelim{}@mtunsafe{@mtasurace{:netent} @mtsenv{} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
-@c setnetent @mtasurace:netent @mtsenv @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@safety{@prelim{}@mtunsafe{@mtasurace{:netent} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
+@c setnetent @mtasurace:netent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
 @c  libc_lock_lock dup @asulock @aculock
-@c  nss_setent(nss_networks_lookup2) @mtasurace:netent @mtsenv @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
-@c   res_maybe_init(!preinit) dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@c  nss_setent(nss_networks_lookup2) @mtasurace:netent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c   res_maybe_init(!preinit) dup @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
 @c   setup(nss_networks_lookup2) @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
 @c    *lookup_fct = nss_networks_lookup2 dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
 @c    nss_lookup dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
@@ -3598,20 +3595,20 @@  reopening the database for each call.
 
 @deftypefun {struct netent *} getnetent (void)
 @standards{BSD, netdb.h}
-@safety{@prelim{}@mtunsafe{@mtasurace{:netent} @mtasurace{:netentbuf} @mtsenv{} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
-@c getnetent @mtasurace:netent @mtasurace:netentbuf @mtsenv @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@safety{@prelim{}@mtunsafe{@mtasurace{:netent} @mtasurace{:netentbuf} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
+@c getnetent @mtasurace:netent @mtasurace:netentbuf @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
 @c  libc_lock_lock dup @asulock @aculock
-@c  nss_getent(getnetent_r) @mtasurace:netent @mtsenv @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c  nss_getent(getnetent_r) @mtasurace:netent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
 @c   malloc dup @ascuheap @acsmem
-@c   *func = getnetent_r dup @mtasurace:netent @mtsenv @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c   *func = getnetent_r dup @mtasurace:netent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
 @c   realloc dup @ascuheap @acsmem
 @c   free dup @ascuheap @acsmem
 @c  libc_lock_unlock dup @aculock
 @c
-@c getnetent_r @mtasurace:netent @mtsenv @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c getnetent_r @mtasurace:netent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
 @c  libc_lock_lock dup @asulock @aculock
-@c  nss_getent_r(nss_networks_lookup2) @mtasurace:netent @mtsenv @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
-@c   res_maybe_init(!preinit) dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@c  nss_getent_r(nss_networks_lookup2) @mtasurace:netent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c   res_maybe_init(!preinit) dup @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
 @c   setup(nss_networks_lookup2) dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
 @c   *fct.f @mtasurace:servent @ascuplugin
 @c   nss_next2 dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
@@ -3624,11 +3621,11 @@  returns a null pointer if there are no more entries.
 
 @deftypefun void endnetent (void)
 @standards{BSD, netdb.h}
-@safety{@prelim{}@mtunsafe{@mtasurace{:netent} @mtsenv{} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
-@c endnetent @mtasurace:netent @mtsenv @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@safety{@prelim{}@mtunsafe{@mtasurace{:netent} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
+@c endnetent @mtasurace:netent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
 @c  libc_lock_lock @asulock @aculock
-@c  nss_endent(nss_networks_lookup2) @mtasurace:netent @mtsenv @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
-@c   res_maybe_init(!preinit) dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@c  nss_endent(nss_networks_lookup2) @mtasurace:netent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c   res_maybe_init(!preinit) dup @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
 @c   setup(nss_networks_lookup2) dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
 @c   *fct.f @mtasurace:netent @ascuplugin
 @c   nss_next2 dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
diff --git a/manual/startup.texi b/manual/startup.texi
index 747beed4d9..8fd8754208 100644
--- a/manual/startup.texi
+++ b/manual/startup.texi
@@ -92,9 +92,14 @@  int main (int @var{argc}, char *@var{argv}[], char *@var{envp}[])
 
 The first two arguments are just the same.  The third argument
 @var{envp} gives the program's environment; it is the same as the value
-of @code{environ}.  @xref{Environment Variables}.  POSIX.1 does not
-allow this three-argument form, so to be portable it is best to write
-@code{main} to take two arguments, and use the value of @code{environ}.
+of @code{environ}.  The @var{envp} array is subject to the same
+restrictions as the @code{environ} variable.  @xref{Environment
+Variables}.
+
+POSIX.1 does not allow this three-argument form, so to be portable it is
+best to write @code{main} to take two arguments, and use the value of
+@code{environ}.
+
 
 @menu
 * Argument Syntax::             By convention, options start with a hyphen.
@@ -326,20 +331,31 @@  functions can be safely used in multi-threaded programs.
 
 @deftypefun {char *} getenv (const char *@var{name})
 @standards{ISO, stdlib.h}
-@safety{@prelim{}@mtsafe{@mtsenv{}}@assafe{}@acsafe{}}
-@c Unguarded access to __environ.
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
 This function returns a string that is the value of the environment
 variable @var{name}.  You must not modify this string.  In some non-Unix
 systems not using @theglibc{}, it might be overwritten by subsequent
 calls to @code{getenv} (but not by any other library function).  If the
 environment variable @var{name} is not defined, the value is a null
 pointer.
+
+In @theglibc{} implementation, if the variable was last set using the
+@code{setenv} function, the string returned by @code{getenv} will not
+change or be deallocated even if the environment is subsequently
+modified using @code{setenv}, @code{putenv}, or @code{unsetenv}.  If the
+variable was set using @code{putenv} or with a direct @code{environ}
+array update, @code{getenv} returns a pointer into the
+application-supplied string, and the behavior depends on what the
+application does with that string.
+
+While the @code{getenv} function is thread-safe, threads may not observe
+environment variable updates in the same order as they happened on other
+threads.
 @end deftypefun
 
 @deftypefun {char *} secure_getenv (const char *@var{name})
 @standards{GNU, stdlib.h}
-@safety{@prelim{}@mtsafe{@mtsenv{}}@assafe{}@acsafe{}}
-@c Calls getenv unless secure mode is enabled.
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
 This function is similar to @code{getenv}, but it returns a null
 pointer if the environment is untrusted.  This happens when the
 program file has SUID or SGID bits set.  General-purpose libraries
@@ -352,13 +368,13 @@  This function is a GNU extension.
 
 @deftypefun int putenv (char *@var{string})
 @standards{SVID, stdlib.h}
-@safety{@prelim{}@mtunsafe{@mtasuconst{:@mtsenv{}}}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{}}}
-@c putenv @mtasuconst:@mtsenv @ascuheap @asulock @acucorrupt @aculock @acsmem
+@safety{@mtsafe{}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{}}}
+@c putenv @ascuheap @asulock @acucorrupt @aculock @acsmem
 @c  strchr dup ok
 @c  strndup dup @ascuheap @acsmem
-@c  add_to_environ dup @mtasuconst:@mtsenv @ascuheap @asulock @acucorrupt @aculock @acsmem
+@c  add_to_environ dup @ascuheap @asulock @acucorrupt @aculock @acsmem
 @c  free dup @ascuheap @acsmem
-@c  unsetenv dup @mtasuconst:@mtsenv @asulock @aculock
+@c  unsetenv dup @asulock @aculock
 The @code{putenv} function adds or removes definitions from the environment.
 If the @var{string} is of the form @samp{@var{name}=@var{value}}, the
 definition is added to the environment.  Otherwise, the @var{string} is
@@ -376,6 +392,12 @@  reflect automatically in the environment.  This also requires that
 variable is removed from the environment.  The same applies of course to
 dynamically allocated variables which are freed later.
 
+Modification of a string installed into the environment using
+@code{putenv} can impact the thread-safety and async-signal-safety of
+@code{getenv}.  Simple modifications of an environment variable, for
+example single-byte changes to the value part (such as changing a
+@samp{0} to a @samp{1}), do not impact safety.
+
 This function is part of the extended Unix interface.  You should define
 @var{_XOPEN_SOURCE} before including any header.
 @end deftypefun
@@ -383,9 +405,9 @@  This function is part of the extended Unix interface.  You should define
 
 @deftypefun int setenv (const char *@var{name}, const char *@var{value}, int @var{replace})
 @standards{BSD, stdlib.h}
-@safety{@prelim{}@mtunsafe{@mtasuconst{:@mtsenv{}}}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{}}}
-@c setenv @mtasuconst:@mtsenv @ascuheap @asulock @acucorrupt @aculock @acsmem
-@c  add_to_environ @mtasuconst:@mtsenv @ascuheap @asulock @acucorrupt @aculock @acsmem
+@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{}}}
+@c setenv @ascuheap @asulock @acucorrupt @aculock @acsmem
+@c  add_to_environ @ascuheap @asulock @acucorrupt @aculock @acsmem
 @c   strlen dup ok
 @c   libc_lock_lock @asulock @aculock
 @c   strncmp dup ok
@@ -423,8 +445,8 @@  the Unix standard.
 
 @deftypefun int unsetenv (const char *@var{name})
 @standards{BSD, stdlib.h}
-@safety{@prelim{}@mtunsafe{@mtasuconst{:@mtsenv{}}}@asunsafe{@asulock{}}@acunsafe{@aculock{}}}
-@c unsetenv @mtasuconst:@mtsenv @asulock @aculock
+@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{}}}
+@c unsetenv @asulock @aculock
 @c  strchr dup ok
 @c  strlen dup ok
 @c  libc_lock_lock @asulock @aculock
@@ -440,6 +462,15 @@  The function returns @code{-1} if @var{name} is a null pointer, points to
 an empty string, or points to a string containing a @code{=} character.
 It returns @code{0} if the call succeeded.
 
+In @theglibc{} implementation, this function does not actually
+deallocate the storage for the environment variable.  This ensures that
+@code{getenv} is thread-safe and the returned strings can be used
+without restriction (unless @code{putenv} was used to set these
+variables).  If storage for changed environment variables needs to be
+reclaimed, applications must use @code{putenv} to set environment
+variables and manage storage reclamation themselves.  Storage for
+variables set using @code{setenv} cannot be reclaimed.
+
 This function was originally part of the BSD library but is now part of
 the Unix standard.  The BSD version had no return value, though.
 @end deftypefun
@@ -452,11 +483,7 @@  to enable writing standard compliant Fortran environments.
 
 @deftypefun int clearenv (void)
 @standards{GNU, stdlib.h}
-@safety{@prelim{}@mtunsafe{@mtasuconst{:@mtsenv{}}}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsmem{}}}
-@c clearenv @mtasuconst:@mtsenv @ascuheap @asulock @aculock @acsmem
-@c  libc_lock_lock @asulock @aculock
-@c  free dup @ascuheap @acsmem
-@c  libc_lock_unlock @aculock
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
 The @code{clearenv} function removes all entries from the environment.
 Using @code{putenv} and @code{setenv} new entries can be added again
 later.
@@ -479,10 +506,61 @@  strings appear in the environment is not significant, but the same
 @var{name} must not appear more than once.  The last element of the
 array is a null pointer.
 
-This variable is declared in the header file @file{unistd.h}.
+The @code{environ} variable is defined by POSIX, but the declaration in
+@file{unistd.h} is a GNU extension.
 
 If you just want to get the value of an environment variable, use
 @code{getenv}.
+
+Direct writes to @code{environ} can impact the thread safety and
+async-signal-safety of functionality that uses the process environment.
+It is recommended to update @code{environ} using the functions
+@code{setenv}, @code{putenv}, @code{unsetenv}, @code{clearenv} only, as
+described above.
+
+The @code{environ} array can be passed to functions in the @code{execve}
+and @code{posix_spawn} families.  @xref{Executing a File}.
+
+As a GNU extension, if @code{environ} is used with these execution
+functions, @theglibc{} ensures that a copy of the environment variables
+is passed to the subprocess, without data races, even if the environment
+is concurrently modified using the environment-updating functions
+describe above.
+
+@strong{Note:} If the @code{environ} pointer is passed to
+@code{execve}-style functions in multi-threaded programs, these
+functions may need additional stack space to store a shallow copy of the
+@code{environ} array.  This does not apply to single-threaded programs
+or the functions in @code{posix_spawn} family.
+
+In this context, @emph{concurrently modified} means that the invocations
+of the environment-modifying functions are not in a happens-before
+relationship with the @code{execve} or @code{posix_spawn} calls.  The
+copy of the @code{environ} array passed to the new process has the
+following properties:
+
+@itemize @bullet
+@item
+If an environment variable is not modified or unset by the concurrent
+calls, it retains its value.
+
+@item
+If a variable is unset by concurrent calls, it is unspecified whether it
+is present in the copy.
+
+@item
+If a variable is set by concurrent calls, it is unspecified whether it
+retains its original value (if any), or one of the set values.
+
+@item
+Variables are not duplicated if the original array did not contain any
+duplicates.
+
+@item
+Even if the variable modifications obey a happens-before relationship
+among themselves, the copy may not correspond to any intermediate state
+consistent with that happens-before relationship.
+@end itemize
 @end deftypevar
 
 Unix systems, and @gnusystems{}, pass the initial value of
diff --git a/manual/sysinfo.texi b/manual/sysinfo.texi
index 1ca77adc7e..2b1be40cbe 100644
--- a/manual/sysinfo.texi
+++ b/manual/sysinfo.texi
@@ -177,7 +177,7 @@  The specifics of this function are analogous to @code{sethostname}, above.
 
 @deftypefun {long int} gethostid (void)
 @standards{BSD, unistd.h}
-@safety{@prelim{}@mtsafe{@mtshostid{} @mtsenv{} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @asucorrupt{} @ascuheap{} @asulock{}}@acunsafe{@aculock{} @acucorrupt{} @acsmem{} @acsfd{}}}
+@safety{@prelim{}@mtsafe{@mtshostid{} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @asucorrupt{} @ascuheap{} @asulock{}}@acunsafe{@aculock{} @acucorrupt{} @acsmem{} @acsfd{}}}
 @c On HURD, calls _hurd_get_host_config and strtol.  On Linux, open
 @c HOSTIDFILE, reads an int32_t and closes; if that fails, it calls
 @c gethostname and gethostbyname_r to use the h_addr.
diff --git a/manual/syslog.texi b/manual/syslog.texi
index 02f84d6e6f..0e71fc0677 100644
--- a/manual/syslog.texi
+++ b/manual/syslog.texi
@@ -285,11 +285,11 @@  The symbols referred to in this section are declared in the file
 @c syslog() is implemented as a call to vsyslog().
 @deftypefun void syslog (int @var{facility_priority}, const char *@var{format}, @dots{})
 @standards{BSD, syslog.h}
-@safety{@prelim{}@mtsafe{@mtsenv{} @mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{} @asulock{} @ascudlopen{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{} @acsfd{}}}
-@c syslog @mtsenv @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
+@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{} @asulock{} @ascudlopen{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{} @acsfd{}}}
+@c syslog @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
 @c  va_start dup ok
-@c  vsyslog_chk @mtsenv @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
-@c   syslog(INTERNALLOG) dup @mtsenv @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
+@c  vsyslog_chk @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
+@c   syslog(INTERNALLOG) dup @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
 @c   open_memstream @ascuheap @acsmem
 @c   stpcpy dup ok
 @c   getpid dup ok
@@ -297,8 +297,8 @@  The symbols referred to in this section are declared in the file
 @c   fsetlocking [no @mtasurace:stream @asulock for exclusive stream]
 @c   fprintf @mtslocale @ascuheap @acsmem [no @asucorrupt @aculock @acucorrupt on temp memstream]
 @c   time dup ok
-@c   localtime_r dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
-@c   strftime_l(C) dup @mtsenv @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
+@c   localtime_r dup @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@c   strftime_l(C) dup @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
 @c   ftell dup ok [no @asucorrupt @aculock @acucorrupt on temp memstream]
 @c   fputs_unlocked dup ok [no @mtasurace:stream @asucorrupt @acucorrupt on temp memstream]
 @c   putc_unlocked dup ok [no @mtasurace:stream @asucorrupt @acucorrupt on temp memstream]
@@ -444,9 +444,9 @@  syslog (LOG_MAKEPRI(LOG_LOCAL1, LOG_ERROR),
 
 @deftypefun void vsyslog (int @var{facility_priority}, const char *@var{format}, va_list @var{arglist})
 @standards{BSD, syslog.h}
-@safety{@prelim{}@mtsafe{@mtsenv{} @mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{} @asulock{} @ascudlopen{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{} @acsfd{}}}
-@c vsyslog @mtsenv @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
-@c  vsyslog_chk dup @mtsenv @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
+@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{} @asulock{} @ascudlopen{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{} @acsfd{}}}
+@c vsyslog @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
+@c  vsyslog_chk dup @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
 
 This is functionally identical to @code{syslog}, with the BSD style variable
 length argument.
diff --git a/manual/time.texi b/manual/time.texi
index 6b1080db06..03b400646d 100644
--- a/manual/time.texi
+++ b/manual/time.texi
@@ -1100,10 +1100,10 @@  has a geographical format.  @xref{Time Zone State}.
 
 @deftypefun {struct tm *} localtime (const time_t *@var{time})
 @standards{ISO, time.h}
-@safety{@prelim{}@mtunsafe{@mtasurace{:tmbuf} @mtsenv{} @mtslocale{}}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsmem{} @acsfd{}}}
+@safety{@prelim{}@mtunsafe{@mtasurace{:tmbuf} @mtslocale{}}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsmem{} @acsfd{}}}
 @c Calls tz_convert with a static buffer.
-@c localtime @mtasurace:tmbuf @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
-@c  tz_convert dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@c localtime @mtasurace:tmbuf @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@c  tz_convert dup @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
 The @code{localtime} function converts the simple time pointed to by
 @var{time} to broken-down time representation, expressed relative to the
 user's specified time zone.
@@ -1130,24 +1130,22 @@  all threads.  A variant function avoids this problem.
 
 @deftypefun {struct tm *} localtime_r (const time_t *@var{time}, struct tm *@var{resultp})
 @standards{POSIX.1c, time.h}
-@safety{@prelim{}@mtsafe{@mtsenv{} @mtslocale{}}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsmem{} @acsfd{}}}
-@c localtime_r @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
-@c  tz_convert(use_localtime) @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsmem{} @acsfd{}}}
+@c localtime_r @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@c  tz_convert(use_localtime) @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
 @c   libc_lock_lock dup @asulock @aculock
-@c   tzset_internal @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@c   tzset_internal @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
 @c     always called with tzset_lock held
 @c     sets static is_initialized before initialization;
 @c     reads and sets old_tz; sets tz_rules.
 @c     some of the issues only apply on the first call.
 @c     subsequent calls only trigger these when called by localtime;
 @c     otherwise, they're ok.
-@c    getenv dup @mtsenv
 @c    strcmp dup ok
 @c    strdup @ascuheap
-@c    tzfile_read @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@c    tzfile_read @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
 @c     memcmp dup ok
 @c     strstr dup ok
-@c     getenv dup @mtsenv
 @c     asprintf dup @mtslocale @ascuheap @acsmem
 @c     stat64 dup ok
 @c     fopen dup @ascuheap @asulock @acsmem @acsfd @aculock
@@ -1176,9 +1174,8 @@  all threads.  A variant function avoids this problem.
 @c      double-underscore-prefixed name, this interface violation could
 @c      be regarded as undefined behavior.
 @c     strlen ok
-@c    tzset_parse_tz @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@c    tzset_parse_tz @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
 @c     sscanf dup @mtslocale @ascuheap @acsmem
-@c     isalnum dup @mtsenv
 @c     tzstring @ascuheap @acsmem
 @c       reads and changes tzstring_list without synchronization, but
 @c       only called with tzset_lock held (save for interface violations)
@@ -1187,20 +1184,20 @@  all threads.  A variant function avoids this problem.
 @c      strcpy dup ok
 @c     isdigit dup @mtslocale
 @c     compute_offset ok
-@c     tzfile_default @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@c     tzfile_default @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
 @c       sets tzname, timezone, types, zone_names, rule_*off, etc; no guards
 @c      strlen dup ok
-@c      tzfile_read dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@c      tzfile_read dup @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
 @c      mempcpy dup ok
 @c      compute_tzname_max ok [if guarded by tzset_lock]
 @c        iterates over zone_names; no guards
 @c     free dup @ascuheap @acsmem
 @c     strtoul dup @mtslocale
 @c     update_vars dup ok
-@c   tzfile_compute(use_localtime) @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@c   tzfile_compute(use_localtime) @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
 @c     sets tzname; no guards.  with !use_localtime, as in gmtime, it's ok
 @c    tzstring dup @acsuheap @acsmem
-@c    tzset_parse_tz dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@c    tzset_parse_tz dup @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
 @c    offtime dup ok
 @c    tz_compute dup ok
 @c    strcmp dup ok
@@ -1227,9 +1224,9 @@  object the result was written into, i.e., it returns @var{resultp}.
 
 @deftypefun {struct tm *} gmtime (const time_t *@var{time})
 @standards{ISO, time.h}
-@safety{@prelim{}@mtunsafe{@mtasurace{:tmbuf} @mtsenv{} @mtslocale{}}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsmem{} @acsfd{}}}
-@c gmtime @mtasurace:tmbuf @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
-@c  tz_convert dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@safety{@prelim{}@mtunsafe{@mtasurace{:tmbuf} @mtslocale{}}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsmem{} @acsfd{}}}
+@c gmtime @mtasurace:tmbuf @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@c  tz_convert dup @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
 This function is similar to @code{localtime}, except that the broken-down
 time is expressed as UTC rather than relative to a local time zone.
 The broken-down time's @code{tm_gmtoff} is 0, and its
@@ -1243,15 +1240,15 @@  is placed in a static variable.  A thread-safe replacement is also provided for
 
 @deftypefun {struct tm *} gmtime_r (const time_t *@var{time}, struct tm *@var{resultp})
 @standards{POSIX.1c, time.h}
-@safety{@prelim{}@mtsafe{@mtsenv{} @mtslocale{}}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsmem{} @acsfd{}}}
+@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsmem{} @acsfd{}}}
 @c You'd think tz_convert could avoid some safety issues with
 @c !use_localtime, but no such luck: tzset_internal will always bring
 @c about all possible AS and AC problems when it's first called.
 @c Calling any of localtime,gmtime_r once would run the initialization
 @c and avoid the heap, mem and fd issues in gmtime* in subsequent calls,
 @c but the unsafe locking would remain.
-@c gmtime_r @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
-@c  tz_convert(gmtime_r) dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@c gmtime_r @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@c  tz_convert(gmtime_r) dup @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
 This function is similar to @code{localtime_r}, except that it converts
 just like @code{gmtime} the given time as UTC.
 
@@ -1262,8 +1259,8 @@  object the result was written into, i.e., it returns @var{resultp}.
 
 @deftypefun time_t mktime (struct tm *@var{brokentime})
 @standards{ISO, time.h}
-@safety{@prelim{}@mtsafe{@mtsenv{} @mtslocale{}}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsmem{} @acsfd{}}}
-@c mktime @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsmem{} @acsfd{}}}
+@c mktime @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
 @c   passes a static localtime_offset to mktime_internal; it is read
 @c   once, used as an initial guess, and updated at the end, but not
 @c   used except as a guess for subsequent calls, so it should be safe.
@@ -1273,11 +1270,11 @@  object the result was written into, i.e., it returns @var{resultp}.
 @c   call to an external function, and a conditional change of the
 @c   variable before the external call, so refraining from allocating a
 @c   local variable at the first load would be a very bad optimization.
-@c  tzset dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
-@c  mktime_internal(localtime_r) @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@c  tzset dup @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@c  mktime_internal(localtime_r) @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
 @c   ydhms_diff ok
-@c   ranged_convert(localtime_r) @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
-@c    *convert = localtime_r dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@c   ranged_convert(localtime_r) @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@c    *convert = localtime_r dup @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
 @c    time_t_avg dup ok
 @c   guess_time_tm dup ok
 @c    ydhms_diff dup ok
@@ -1311,7 +1308,7 @@  members.  @xref{Time Zone State}.
 
 @deftypefun time_t timelocal (struct tm *@var{brokentime})
 @standards{???, time.h}
-@safety{@prelim{}@mtsafe{@mtsenv{} @mtslocale{}}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsmem{} @acsfd{}}}
+@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsmem{} @acsfd{}}}
 @c Alias to mktime.
 
 @code{timelocal} is functionally identical to @code{mktime}, but more
@@ -1325,13 +1322,13 @@  available.  @code{timelocal} is rather rare.
 
 @deftypefun time_t timegm (struct tm *@var{brokentime})
 @standards{ISO, time.h}
-@safety{@prelim{}@mtsafe{@mtsenv{} @mtslocale{}}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsmem{} @acsfd{}}}
-@c timegm @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsmem{} @acsfd{}}}
+@c timegm @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
 @c   gmtime_offset triggers the same caveats as localtime_offset in mktime.
 @c   although gmtime_r, as called by mktime, might save some issues,
 @c   tzset calls tzset_internal with always, which forces
 @c   reinitialization, so all issues may arise.
-@c  tzset dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@c  tzset dup @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
 @c  mktime_internal(gmtime_r) @asulock @aculock
 @c ..gmtime_r @asulock @aculock
 @c    ... dup ok
@@ -1364,10 +1361,10 @@  strings.  These functions are declared in the header file @file{time.h}.
 
 @deftypefun size_t strftime (char *@var{s}, size_t @var{size}, const char *@var{template}, const struct tm *@var{brokentime})
 @standards{ISO, time.h}
-@safety{@prelim{}@mtsafe{@mtsenv{} @mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{} @asulock{} @ascudlopen{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{} @acsfd{}}}
-@c strftime @mtsenv @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
-@c  strftime_l @mtsenv @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
-@c   strftime_internal @mtsenv @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
+@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{} @asulock{} @ascudlopen{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{} @acsfd{}}}
+@c strftime @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
+@c  strftime_l @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
+@c   strftime_internal @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
 @c    add ok
 @c     memset_zero dup ok
 @c     memset_space dup ok
@@ -1387,7 +1384,7 @@  strings.  These functions are declared in the header file @file{time.h}.
 @c    ISDIGIT ok
 @c    STRLEN ok
 @c     strlen dup ok
-@c    strftime_internal dup @mtsenv @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
+@c    strftime_internal dup @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
 @c    TOUPPER dup ok
 @c    nl_get_era_entry @ascuheap @asulock @acsmem @aculock
 @c     nl_init_era_entries @ascuheap @asulock @acsmem @aculock
@@ -1414,12 +1411,12 @@  strings.  These functions are declared in the header file @file{time.h}.
 @c     memset dup ok
 @c    memset_zero ok
 @c     memset dup ok
-@c    mktime dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@c    mktime dup @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
 @c    iso_week_days ok
 @c    isleap ok
-@c    tzset dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
-@c    localtime_r dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
-@c    gmtime_r dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@c    tzset dup @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@c    localtime_r dup @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@c    gmtime_r dup @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
 @c    tm_diff ok
 This function is similar to the @code{sprintf} function (@pxref{Formatted
 Input}), but the conversion specifications that can appear in the format
@@ -1750,7 +1747,7 @@  For an example of @code{strftime}, see @ref{Time Functions Example}.
 
 @deftypefun size_t strftime_l (char *restrict @var{s}, size_t @var{size}, const char *restrict @var{template}, const struct tm *@var{brokentime}, locale_t @var{locale})
 @standards{POSIX.1, time.h}
-@safety{@prelim{}@mtsafe{@mtsenv{} @mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{} @asulock{} @ascudlopen{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{} @acsfd{}}}
+@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{} @asulock{} @ascudlopen{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{} @acsfd{}}}
 The @code{strftime_l} function is equivalent to the @code{strftime}
 function except that it operates in @var{locale} rather than in
 the current locale.
@@ -1758,10 +1755,10 @@  the current locale.
 
 @deftypefun size_t wcsftime (wchar_t *@var{s}, size_t @var{size}, const wchar_t *@var{template}, const struct tm *@var{brokentime})
 @standards{ISO, time.h}
-@safety{@prelim{}@mtsafe{@mtsenv{} @mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{} @asulock{} @ascudlopen{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{} @acsfd{}}}
-@c wcsftime @mtsenv @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
-@c  wcsftime_l @mtsenv @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
-@c   wcsftime_internal @mtsenv @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
+@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{} @asulock{} @ascudlopen{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{} @acsfd{}}}
+@c wcsftime @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
+@c  wcsftime_l @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
+@c   wcsftime_internal @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
 @c    add ok
 @c     memset_zero dup ok
 @c     memset_space dup ok
@@ -1782,7 +1779,7 @@  the current locale.
 @c    ISDIGIT ok
 @c    STRLEN ok
 @c     wcslen dup ok
-@c    wcsftime_internal dup @mtsenv @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
+@c    wcsftime_internal dup @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
 @c    TOUPPER dup ok
 @c    nl_get_era_entry dup @ascuheap @asulock @acsmem @aculock
 @c    DO_NUMBER ok
@@ -1798,12 +1795,12 @@  the current locale.
 @c     wmemset dup ok
 @c    memset_zero ok
 @c     wmemset dup ok
-@c    mktime dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@c    mktime dup @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
 @c    iso_week_days ok
 @c    isleap ok
-@c    tzset dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
-@c    localtime_r dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
-@c    gmtime_r dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@c    tzset dup @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@c    localtime_r dup @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@c    gmtime_r dup @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
 @c    tm_diff ok
 The @code{wcsftime} function is equivalent to the @code{strftime}
 function with the difference that it operates on wide character
@@ -1886,9 +1883,9 @@  Programs should instead use @code{strftime} or even @code{sprintf}.
 
 @deftypefun {Deprecated function} {char *} ctime (const time_t *@var{time})
 @standards{ISO, time.h}
-@safety{@prelim{}@mtunsafe{@mtasurace{:tmbuf} @mtasurace{:asctime} @mtsenv{} @mtslocale{}}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsmem{} @acsfd{}}}
-@c ctime @mtasurace:tmbuf @mtasurace:asctime @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
-@c  localtime dup @mtasurace:tmbuf @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@safety{@prelim{}@mtunsafe{@mtasurace{:tmbuf} @mtasurace{:asctime} @mtslocale{}}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsmem{} @acsfd{}}}
+@c ctime @mtasurace:tmbuf @mtasurace:asctime @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@c  localtime dup @mtasurace:tmbuf @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
 @c  asctime dup @mtasurace:asctime @mtslocale
 The @code{ctime} function is similar to @code{asctime}, except that you
 specify the calendar time argument as a @code{time_t} simple time value
@@ -1911,9 +1908,9 @@  Programs should instead use @code{strftime} or even @code{sprintf}.
 
 @deftypefun {Deprecated function} {char *} ctime_r (const time_t *@var{time}, char *@var{buffer})
 @standards{???, time.h}
-@safety{@prelim{}@mtsafe{@mtsenv{} @mtslocale{}}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsmem{} @acsfd{}}}
-@c ctime_r @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
-@c  localtime_r dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsmem{} @acsfd{}}}
+@c ctime_r @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@c  localtime_r dup @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
 @c  asctime_r dup @mtslocale
 This function is similar to @code{ctime}, but places the result in the
 string pointed to by @var{buffer}, and the time zone state is not
@@ -1962,9 +1959,9 @@  which is defined and implemented in terms of calls to @code{strptime}.
 
 @deftypefun {char *} strptime (const char *@var{s}, const char *@var{fmt}, struct tm *@var{tp})
 @standards{XPG4, time.h}
-@safety{@prelim{}@mtsafe{@mtsenv{} @mtslocale{}}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsmem{} @acsfd{}}}
-@c strptime @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
-@c  strptime_internal @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsmem{} @acsfd{}}}
+@c strptime @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@c  strptime_internal @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
 @c   memset dup ok
 @c   ISSPACE ok
 @c    isspace_l dup ok
@@ -1973,11 +1970,11 @@  which is defined and implemented in terms of calls to @code{strptime}.
 @c    strlen dup ok
 @c    strncasecmp_l dup ok
 @c   strcmp dup ok
-@c   recursive @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
-@c    strptime_internal dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@c   recursive @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@c    strptime_internal dup @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
 @c   get_number ok
 @c    ISSPACE dup ok
-@c   localtime_r dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@c   localtime_r dup @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
 @c   nl_select_era_entry @ascuheap @asulock @acsmem @aculock
 @c    nl_init_era_entries dup @ascuheap @asulock @acsmem @aculock
 @c   get_alt_number dup @ascuheap @asulock @acsmem @aculock
@@ -2406,9 +2403,9 @@  in a @code{time_t} variable.
 
 @deftypefun {struct tm *} getdate (const char *@var{string})
 @standards{Unix98, time.h}
-@safety{@prelim{}@mtunsafe{@mtasurace{:getdate} @mtsenv{} @mtslocale{}}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsmem{} @acsfd{}}}
-@c getdate @mtasurace:getdate @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
-@c  getdate_r dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@safety{@prelim{}@mtunsafe{@mtasurace{:getdate} @mtslocale{}}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsmem{} @acsfd{}}}
+@c getdate @mtasurace:getdate @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@c  getdate_r dup @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
 The interface to @code{getdate} is the simplest possible for a function
 to parse a string and return the value.  @var{string} is the input
 string and the result is returned in a statically-allocated variable.
@@ -2519,9 +2516,8 @@  any arbitrary file and chances are high that with some bogus input
 
 @deftypefun int getdate_r (const char *@var{string}, struct tm *@var{tp})
 @standards{GNU, time.h}
-@safety{@prelim{}@mtsafe{@mtsenv{} @mtslocale{}}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsmem{} @acsfd{}}}
-@c getdate_r @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
-@c  getenv dup @mtsenv
+@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsmem{} @acsfd{}}}
+@c getdate_r @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
 @c  stat64 dup ok
 @c  access dup ok
 @c  fopen dup @ascuheap @asulock @acsmem @acsfd @aculock
@@ -2532,17 +2528,17 @@  any arbitrary file and chances are high that with some bogus input
 @c  fclose dup @ascuheap @asulock @aculock @acsmem @acsfd
 @c  memcpy dup ok
 @c  getline dup @ascuheap @acsmem [no @asucorrupt @aculock @acucorrupt, exclusive]
-@c  strptime dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@c  strptime dup @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
 @c  feof_unlocked dup ok
 @c  free dup @ascuheap @acsmem
 @c  ferror_unlocked dup dup ok
 @c  time dup ok
-@c  localtime_r dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
-@c  first_wday @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@c  localtime_r dup @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@c  first_wday @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
 @c   memset dup ok
-@c   mktime dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@c   mktime dup @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
 @c  check_mday ok
-@c  mktime dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@c  mktime dup @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
 The @code{getdate_r} function is the reentrant counterpart of
 @code{getdate}.  It does not use the global variable @code{getdate_err}
 to signal an error, but instead returns an error code.  The same error
@@ -2815,10 +2811,10 @@  Programs should instead use the @code{tm_gmtoff} and
 
 @deftypefun void tzset (void)
 @standards{POSIX.1, time.h}
-@safety{@prelim{}@mtsafe{@mtsenv{} @mtslocale{}}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsmem{} @acsfd{}}}
-@c tzset @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsmem{} @acsfd{}}}
+@c tzset @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
 @c  libc_lock_lock dup @asulock @aculock
-@c  tzset_internal dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@c  tzset_internal dup @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
 @c  libc_lock_unlock dup @aculock
 The @code{tzset} function initializes the state variables from
 the value of the @env{TZ} environment variable.