This is the mail archive of the glibc-cvs@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

GNU C Library master sources branch lxoliva/thread-safety-docs created. glibc-2.18-403-g876ffdd


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU C Library master sources".

The branch, lxoliva/thread-safety-docs has been created
        at  876ffddf9eb9d099ca9120513c30ab4167dd5807 (commit)

- Log -----------------------------------------------------------------
http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=876ffddf9eb9d099ca9120513c30ab4167dd5807

commit 876ffddf9eb9d099ca9120513c30ab4167dd5807
Author: Alexandre Oliva <aoliva@redhat.com>
Date:   Fri Nov 8 06:08:22 2013 -0200

    MT-, AS- and AC-safety docs: manual/signal.texi
    
    for ChangeLog
    
    	* manual/signal.texi: Document MTASC-safety properties.

diff --git a/manual/signal.texi b/manual/signal.texi
index adcda37..2477b51 100644
--- a/manual/signal.texi
+++ b/manual/signal.texi
@@ -889,6 +889,19 @@ may come from a signal handler in the same process.
 @comment string.h
 @comment GNU
 @deftypefun {char *} strsignal (int @var{signum})
+@c strsignal
+@c   uses a static buffer if tsd key creation fails
+@c  [once] init
+@c   libc_key_create
+@c    pthread_key_create
+@c  getbuffer
+@c   libc_getspecific
+@c    pthread_getspecific
+@c   malloc asmalloc, memleak
+@c   libc_setspecific
+@c    pthread_setspecific
+@c  snprintf dup glocale, asmalloc, memleak
+@c  _ asi18n
 This function returns a pointer to a statically-allocated string
 containing a message describing the signal @var{signum}.  You
 should not modify the contents of this string; and, since it can be
@@ -1172,6 +1185,7 @@ the signal.  These are described in more detail in @ref{Flags for Sigaction}.
 @comment signal.h
 @comment POSIX.1
 @deftypefun int sigaction (int @var{signum}, const struct sigaction *restrict @var{action}, struct sigaction *restrict @var{old-action})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 The @var{action} argument is used to set up a new action for the signal
 @var{signum}, while the @var{old-action} argument is used to return
 information about the action previously associated with this symbol.
@@ -2497,6 +2511,8 @@ about.)
 @comment signal.h
 @comment POSIX.1
 @deftypefun int sigemptyset (sigset_t *@var{set})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
+@c Just memsets all of set to zero.
 This function initializes the signal set @var{set} to exclude all of the
 defined signals.  It always returns @code{0}.
 @end deftypefun
@@ -2504,6 +2520,7 @@ defined signals.  It always returns @code{0}.
 @comment signal.h
 @comment POSIX.1
 @deftypefun int sigfillset (sigset_t *@var{set})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 This function initializes the signal set @var{set} to include
 all of the defined signals.  Again, the return value is @code{0}.
 @end deftypefun
@@ -2511,6 +2528,7 @@ all of the defined signals.  Again, the return value is @code{0}.
 @comment signal.h
 @comment POSIX.1
 @deftypefun int sigaddset (sigset_t *@var{set}, int @var{signum})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 This function adds the signal @var{signum} to the signal set @var{set}.
 All @code{sigaddset} does is modify @var{set}; it does not block or
 unblock any signals.
@@ -2527,6 +2545,7 @@ The @var{signum} argument doesn't specify a valid signal.
 @comment signal.h
 @comment POSIX.1
 @deftypefun int sigdelset (sigset_t *@var{set}, int @var{signum})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 This function removes the signal @var{signum} from the signal set
 @var{set}.  All @code{sigdelset} does is modify @var{set}; it does not
 block or unblock any signals.  The return value and error conditions are
@@ -2538,6 +2557,7 @@ Finally, there is a function to test what signals are in a signal set:
 @comment signal.h
 @comment POSIX.1
 @deftypefun int sigismember (const sigset_t *@var{set}, int @var{signum})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 The @code{sigismember} function tests whether the signal @var{signum} is
 a member of the signal set @var{set}.  It returns @code{1} if the signal
 is in the set, @code{0} if not, and @code{-1} if there is an error.
@@ -2576,6 +2596,7 @@ Instead, use @code{pthread_sigmask}.
 @comment signal.h
 @comment POSIX.1
 @deftypefun int sigprocmask (int @var{how}, const sigset_t *restrict @var{set}, sigset_t *restrict @var{oldset})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 The @code{sigprocmask} function is used to examine or change the calling
 process's signal mask.  The @var{how} argument determines how the signal
 mask is changed, and must be one of the following values:

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=a25dde168228cad4f07d8b800dbb6b143e538261

commit a25dde168228cad4f07d8b800dbb6b143e538261
Author: Alexandre Oliva <aoliva@redhat.com>
Date:   Fri Nov 8 06:08:24 2013 -0200

    MT-, AS- and AC-safety docs: manual/time.texi
    
    for ChangeLog
    
    	* manual/time.texi: Document MTASC-safety properties.

diff --git a/manual/time.texi b/manual/time.texi
index ff31e28..7345d73 100644
--- a/manual/time.texi
+++ b/manual/time.texi
@@ -409,6 +409,7 @@ subtracting.  @xref{Elapsed Time}.
 @comment time.h
 @comment ISO
 @deftypefun time_t time (time_t *@var{result})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 The @code{time} function returns the current calendar time as a value of
 type @code{time_t}.  If the argument @var{result} is not a null pointer,
 the calendar time value is also stored in @code{*@var{result}}.  If the
@@ -475,6 +476,12 @@ Instead, use the facilities described in @ref{Time Zone Functions}.
 @comment sys/time.h
 @comment BSD
 @deftypefun int gettimeofday (struct timeval *@var{tp}, struct timezone *@var{tzp})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
+@c On most GNU/Linux systems this is a direct syscall, but the posix/
+@c implementation (not used on GNU/Linux or GNU/Hurd) relies on time and
+@c localtime_r, saving and restoring tzname in an unsafe manner.
+@c On some GNU/Linux variants, ifunc resolvers are used in shared libc
+@c for vdso resolution.  ifunc-vdso-revisit.
 The @code{gettimeofday} function returns the current calendar time as
 the elapsed time since the epoch in the @code{struct timeval} structure
 indicated by @var{tp}.  (@pxref{Elapsed Time} for a description of
@@ -2315,6 +2322,15 @@ The @code{struct timeval} data type is described in @ref{Elapsed Time}.
 @comment sys/time.h
 @comment BSD
 @deftypefun int setitimer (int @var{which}, const struct itimerval *@var{new}, struct itimerval *@var{old})
+@safety{@mtsafe{stimer}@assafe{}@acsafe{}}
+@c This function is marked with stimer because the same set of timers is
+@c shared by all threads of a process, so calling it in one thread may
+@c interfere with timers set by another thread.  This interference is
+@c not regarded as destructive, because the interface specification
+@c makes this overriding while returning the previous value the expected
+@c behavior, and the kernel will serialize concurrent calls so that the
+@c last one prevails, with each call getting the timer information from
+@c the timer installed by the previous call in that serialization.
 The @code{setitimer} function sets the timer specified by @var{which}
 according to @var{new}.  The @var{which} argument can have a value of
 @code{ITIMER_REAL}, @code{ITIMER_VIRTUAL}, or @code{ITIMER_PROF}.
@@ -2335,6 +2351,7 @@ The timer period is too large.
 @comment sys/time.h
 @comment BSD
 @deftypefun int getitimer (int @var{which}, struct itimerval *@var{old})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 The @code{getitimer} function stores information about the timer specified
 by @var{which} in the structure pointed at by @var{old}.
 
@@ -2367,6 +2384,8 @@ timer.
 @comment unistd.h
 @comment POSIX.1
 @deftypefun {unsigned int} alarm (unsigned int @var{seconds})
+@safety{@mtsafe{stimer}@assafe{}@acsafe{}}
+@c Wrapper for setitimer.
 The @code{alarm} function sets the real-time timer to expire in
 @var{seconds} seconds.  If you want to cancel any existing alarm, you
 can do this by calling @code{alarm} with a @var{seconds} argument of

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=45981425e6b7e25f45cdbc72ed18cd4c77ed6ff2

commit 45981425e6b7e25f45cdbc72ed18cd4c77ed6ff2
Author: Alexandre Oliva <aoliva@redhat.com>
Date:   Fri Nov 8 06:08:24 2013 -0200

    MT-, AS- and AC-safety docs: manual/threads.texi
    
    for ChangeLog
    
    	* manual/threads.texi: Document MTASC-safety properties.

diff --git a/manual/threads.texi b/manual/threads.texi
index 9a5ef6a..e52277e 100644
--- a/manual/threads.texi
+++ b/manual/threads.texi
@@ -31,6 +31,7 @@ before thread-specific data, so they should not be used in thread-specific
 data destructors or even as members of the thread-specific data, since the
 latter is passed as an argument to the destructor function.
 
+@c FIXME: use @deftypefun for these.
 @item int pthread_key_delete (pthread_key_t @var{key})
 Destroy the thread-specific data @var{key} in the calling thread.  The
 destructor for the thread-specific data is not called during destruction, nor
@@ -82,3 +83,124 @@ attributes or the stack address is set in the attribute.
 The system does not have sufficient memory.
 @end table
 @end deftypefun
+
+@c FIXME these are undocumented:
+@c pthread_atfork
+@c pthread_attr_destroy
+@c pthread_attr_getaffinity_np
+@c pthread_attr_getdetachstate
+@c pthread_attr_getguardsize
+@c pthread_attr_getinheritsched
+@c pthread_attr_getschedparam
+@c pthread_attr_getschedpolicy
+@c pthread_attr_getscope
+@c pthread_attr_getstack
+@c pthread_attr_getstackaddr
+@c pthread_attr_getstacksize
+@c pthread_attr_init
+@c pthread_attr_setaffinity_np
+@c pthread_attr_setdetachstate
+@c pthread_attr_setguardsize
+@c pthread_attr_setinheritsched
+@c pthread_attr_setschedparam
+@c pthread_attr_setschedpolicy
+@c pthread_attr_setscope
+@c pthread_attr_setstack
+@c pthread_attr_setstackaddr
+@c pthread_attr_setstacksize
+@c pthread_barrierattr_destroy
+@c pthread_barrierattr_getpshared
+@c pthread_barrierattr_init
+@c pthread_barrierattr_setpshared
+@c pthread_barrier_destroy
+@c pthread_barrier_init
+@c pthread_barrier_wait
+@c pthread_cancel
+@c pthread_cleanup_push
+@c pthread_cleanup_pop
+@c pthread_condattr_destroy
+@c pthread_condattr_getclock
+@c pthread_condattr_getpshared
+@c pthread_condattr_init
+@c pthread_condattr_setclock
+@c pthread_condattr_setpshared
+@c pthread_cond_broadcast
+@c pthread_cond_destroy
+@c pthread_cond_init
+@c pthread_cond_signal
+@c pthread_cond_timedwait
+@c pthread_cond_wait
+@c pthread_create
+@c pthread_detach
+@c pthread_equal
+@c pthread_exit
+@c pthread_getaffinity_np
+@c pthread_getattr_np
+@c pthread_getconcurrency
+@c pthread_getcpuclockid
+@c pthread_getname_np
+@c pthread_getschedparam
+@c pthread_join
+@c pthread_kill
+@c pthread_kill_other_threads_np
+@c pthread_mutexattr_destroy
+@c pthread_mutexattr_getkind_np
+@c pthread_mutexattr_getprioceiling
+@c pthread_mutexattr_getprotocol
+@c pthread_mutexattr_getpshared
+@c pthread_mutexattr_getrobust
+@c pthread_mutexattr_getrobust_np
+@c pthread_mutexattr_gettype
+@c pthread_mutexattr_init
+@c pthread_mutexattr_setkind_np
+@c pthread_mutexattr_setprioceiling
+@c pthread_mutexattr_setprotocol
+@c pthread_mutexattr_setpshared
+@c pthread_mutexattr_setrobust
+@c pthread_mutexattr_setrobust_np
+@c pthread_mutexattr_settype
+@c pthread_mutex_consistent
+@c pthread_mutex_consistent_np
+@c pthread_mutex_destroy
+@c pthread_mutex_getprioceiling
+@c pthread_mutex_init
+@c pthread_mutex_lock
+@c pthread_mutex_setprioceiling
+@c pthread_mutex_timedlock
+@c pthread_mutex_trylock
+@c pthread_mutex_unlock
+@c pthread_once
+@c pthread_rwlockattr_destroy
+@c pthread_rwlockattr_getkind_np
+@c pthread_rwlockattr_getpshared
+@c pthread_rwlockattr_init
+@c pthread_rwlockattr_setkind_np
+@c pthread_rwlockattr_setpshared
+@c pthread_rwlock_destroy
+@c pthread_rwlock_init
+@c pthread_rwlock_rdlock
+@c pthread_rwlock_timedrdlock
+@c pthread_rwlock_timedwrlock
+@c pthread_rwlock_tryrdlock
+@c pthread_rwlock_trywrlock
+@c pthread_rwlock_unlock
+@c pthread_rwlock_wrlock
+@c pthread_self
+@c pthread_setaffinity_np
+@c pthread_setcancelstate
+@c pthread_setcanceltype
+@c pthread_setconcurrency
+@c pthread_setname_np
+@c pthread_setschedparam
+@c pthread_setschedprio
+@c pthread_sigmask
+@c pthread_sigqueue
+@c pthread_spin_destroy
+@c pthread_spin_init
+@c pthread_spin_lock
+@c pthread_spin_trylock
+@c pthread_spin_unlock
+@c pthread_testcancel
+@c pthread_timedjoin_np
+@c pthread_tryjoin_np
+@c pthread_yield

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=a0dfa154399acd383471c53ba88959b874fedbf5

commit a0dfa154399acd383471c53ba88959b874fedbf5
Author: Alexandre Oliva <aoliva@redhat.com>
Date:   Fri Nov 8 06:08:23 2013 -0200

    MT-, AS- and AC-safety docs: manual/terminal.texi
    
    for ChangeLog
    
    	* manual/terminal.texi: Document MTASC-safety properties.

diff --git a/manual/terminal.texi b/manual/terminal.texi
index 9e9c057..914c454 100644
--- a/manual/terminal.texi
+++ b/manual/terminal.texi
@@ -44,6 +44,9 @@ file @file{unistd.h}.
 @comment unistd.h
 @comment POSIX.1
 @deftypefun int isatty (int @var{filedes})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
+@c isatty ok
+@c  tcgetattr dup ok
 This function returns @code{1} if @var{filedes} is a file descriptor
 associated with an open terminal device, and @math{0} otherwise.
 @end deftypefun
@@ -55,6 +58,20 @@ associated file name using the @code{ttyname} function.  See also the
 @comment unistd.h
 @comment POSIX.1
 @deftypefun {char *} ttyname (int @var{filedes})
+@safety{@mtunsafe{staticbuf}@asunsafe{asmalloc, selfdeadlock}@acunsafe{lockleak, fdleak, memleak}}
+@c ttyname staticbuf, asmalloc, selfdeadlock, lockleak, memleak, fdleak
+@c  isatty dup ok
+@c  fstat dup ok
+@c  memcpy dup ok
+@c  getttyname staticbuf, asmalloc, selfdeadlock, lockleak, memleak, fdleak
+@c   opendir asmalloc, memleak, fdleak
+@c   readdir ok [protected by exclusive access]
+@c   strcmp dup ok
+@c   free dup selfdeadlock, lockleak, fdleak, memleak
+@c   malloc dup selfdeadlock, lockleak, fdleak, memleak
+@c   closedir asmalloc, memleak, fdleak
+@c   mempcpy dup ok
+@c   stat dup ok
 If the file descriptor @var{filedes} is associated with a terminal
 device, the @code{ttyname} function returns a pointer to a
 statically-allocated, null-terminated string containing the file name of
@@ -65,6 +82,18 @@ isn't associated with a terminal, or the file name cannot be determined.
 @comment unistd.h
 @comment POSIX.1
 @deftypefun int ttyname_r (int @var{filedes}, char *@var{buf}, size_t @var{len})
+@safety{@mtsafe{}@asunsafe{asmalloc}@acsafe{memleak, fdleak}}
+@c ttyname_r asmalloc, memleak, fdleak
+@c  isatty dup ok
+@c  fstat dup ok
+@c  memcpy dup ok
+@c  getttyname_r asmalloc, memleak, fdleak
+@c   opendir asmalloc, memleak, fdleak
+@c   readdir ok [protected by exclusive access]
+@c   strcmp dup ok
+@c   closedir asmalloc, memleak, fdleak
+@c   stpncpy dup ok
+@c   stat dup ok
 The @code{ttyname_r} function is similar to the @code{ttyname} function
 except that it places its result into the user-specified buffer starting
 at @var{buf} with length @var{len}.
@@ -264,6 +293,9 @@ array.
 @comment termios.h
 @comment POSIX.1
 @deftypefun int tcgetattr (int @var{filedes}, struct termios *@var{termios-p})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
+@c Converting the kernel-returned termios data structure to the userland
+@c format does not ensure atomic or consistent writing.
 This function is used to examine the attributes of the terminal
 device with file descriptor @var{filedes}.  The attributes are returned
 in the structure that @var{termios-p} points to.
@@ -284,6 +316,9 @@ The @var{filedes} is not associated with a terminal.
 @comment termios.h
 @comment POSIX.1
 @deftypefun int tcsetattr (int @var{filedes}, int @var{when}, const struct termios *@var{termios-p})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
+@c Converting the incoming termios data structure to the kernel format
+@c does not ensure atomic or consistent reading.
 This function sets the attributes of the terminal device with file
 descriptor @var{filedes}.  The new attributes are taken from the
 structure that @var{termios-p} points to.

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=a2c7c207f28df1ec55af9be2cc1cf5960d24febb

commit a2c7c207f28df1ec55af9be2cc1cf5960d24febb
Author: Alexandre Oliva <aoliva@redhat.com>
Date:   Fri Nov 8 06:08:23 2013 -0200

    MT-, AS- and AC-safety docs: manual/sysinfo.texi
    
    for ChangeLog
    
    	* manual/sysinfo.texi: Document MTASC-safety properties.

diff --git a/manual/sysinfo.texi b/manual/sysinfo.texi
index 5df2a0f..f71123e 100644
--- a/manual/sysinfo.texi
+++ b/manual/sysinfo.texi
@@ -145,6 +145,8 @@ This process cannot set the host name because it is not privileged.
 @comment unistd.h
 @comment ???
 @deftypefun int getdomainnname (char *@var{name}, size_t @var{length})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
+@c Syscalls uname, then strlen and memcpy.
 @cindex NIS domain name
 @cindex YP domain name
 

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=193c6eeb2028567849d9279f04b96ef450195b1a

commit 193c6eeb2028567849d9279f04b96ef450195b1a
Author: Alexandre Oliva <aoliva@redhat.com>
Date:   Fri Nov 8 06:08:22 2013 -0200

    MT-, AS- and AC-safety docs: manual/startup.texi
    
    for ChangeLog
    
    	* manual/startup.texi: Document MTASC-safety properties.

diff --git a/manual/startup.texi b/manual/startup.texi
index a277714..93be2af 100644
--- a/manual/startup.texi
+++ b/manual/startup.texi
@@ -322,6 +322,8 @@ functions can be safely used in multi-threaded programs.
 @comment stdlib.h
 @comment ISO
 @deftypefun {char *} getenv (const char *@var{name})
+@safety{@mtunsafe{envromt}@assafe{}@acsafe{}}
+@c Unguarded access to __environ.
 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
@@ -333,6 +335,8 @@ pointer.
 @comment stdlib.h
 @comment GNU
 @deftypefun {char *} secure_getenv (const char *@var{name})
+@safety{@mtunsafe{envromt}@assafe{}@acsafe{}}
+@c Calls getenv unless secure mode is enabled.
 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
@@ -358,8 +362,8 @@ value is nonzero and @code{errno} is set to indicate the error.
 The difference to the @code{setenv} function is that the exact string
 given as the parameter @var{string} is put into the environment.  If the
 user should change the string after the @code{putenv} call this will
-reflect in automatically in the environment.  This also requires that
-@var{string} is no automatic variable which scope is left before the
+reflect automatically in the environment.  This also requires that
+@var{string} not be an automatic variable whose scope is left before the
 variable is removed from the environment.  The same applies of course to
 dynamically allocated variables which are freed later.
 
@@ -372,6 +376,24 @@ available in old SVID libraries you should define either
 @comment stdlib.h
 @comment BSD
 @deftypefun int setenv (const char *@var{name}, const char *@var{value}, int @var{replace})
+@safety{@mtsafe{}@asunsafe{asmalloc, selfdeadlock}@acunsafe{incansist, lockleak, memleak}}
+@c setenv asmalloc, selfdeadlock, incansist, lockleak, memleak
+@c  add_to_environ asmalloc, selfdeadlock, incansist, lockleak, memleak
+@c   strlen dup ok
+@c   libc_lock_lock selfdeadlock, lockleak
+@c   strncmp dup ok
+@c   realloc dup asmalloc, memleak
+@c   libc_lock_unlock lockleak
+@c   malloc dup asmalloc, memleak
+@c   free dup asmalloc, memleak
+@c   mempcpy dup ok
+@c   memcpy dup ok
+@c   KNOWN_VALUE ok
+@c    tfind(strcmp) [no xguargs, guarded access]
+@c     strcmp dup ok
+@c   STORE_VALUE asmalloc, incansist, memleak
+@c    tsearch(strcmp) asmalloc, incansist, memleak [no xguargs or asynconsist, guarded access makes for mtsafe and selfdeadlock]
+@c     strcmp dup ok
 The @code{setenv} function can be used to add a new definition to the
 environment.  The entry with the name @var{name} is replaced by the
 value @samp{@var{name}=@var{value}}.  Please note that this is also true

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=25ae8c8ef974de2e8058fbd5491421815509e8a6

commit 25ae8c8ef974de2e8058fbd5491421815509e8a6
Author: Alexandre Oliva <aoliva@redhat.com>
Date:   Fri Nov 8 06:08:23 2013 -0200

    MT-, AS- and AC-safety docs: manual/socket.texi
    
    for ChangeLog
    
    	* manual/socket.texi: Document MTASC-safety properties.

diff --git a/manual/socket.texi b/manual/socket.texi
index 4c7e623..e428615 100644
--- a/manual/socket.texi
+++ b/manual/socket.texi
@@ -1771,6 +1771,7 @@ declared in @file{sys/socket.h}.
 @comment sys/socket.h
 @comment BSD
 @deftypefun int socket (int @var{namespace}, int @var{style}, int @var{protocol})
+@safety{@mtsafe{}@assafe{}@acsafe{fdleak}}
 This function creates a socket and specifies communication style
 @var{style}, which should be one of the socket styles listed in
 @ref{Communication Styles}.  The @var{namespace} argument specifies
@@ -1977,6 +1978,7 @@ program must do with the @code{connect} function, which is declared in
 @comment sys/socket.h
 @comment BSD
 @deftypefun int connect (int @var{socket}, struct sockaddr *@var{addr}, socklen_t @var{length})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 The @code{connect} function initiates a connection from the socket
 with file descriptor @var{socket} to the socket whose address is
 specified by the @var{addr} and @var{length} arguments.  (This socket
@@ -2254,6 +2256,7 @@ you get a @code{SIGPIPE} signal for any use of @code{send} or
 @comment sys/socket.h
 @comment BSD
 @deftypefun ssize_t send (int @var{socket}, const void *@var{buffer}, size_t @var{size}, int @var{flags})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 The @code{send} function is like @code{write}, but with the additional
 flags @var{flags}.  The possible values of @var{flags} are described
 in @ref{Socket Data Options}.
@@ -2731,6 +2734,7 @@ you don't want to specify @var{flags} (@pxref{I/O Primitives}).
 @comment sys/socket.h
 @comment BSD
 @deftypefun ssize_t sendmsg (int @var{socket}, const struct msghdr *@var{message}, int @var{flags})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 
 This function is defined as a cancellation point in multi-threaded
 programs, so one has to be prepared for this and make sure that
@@ -2742,6 +2746,7 @@ whatever) are freed even if the thread is cancel.
 @comment sys/socket.h
 @comment BSD
 @deftypefun ssize_t recvmsg (int @var{socket}, struct msghdr *@var{message}, int @var{flags})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 
 This function is defined as a cancellation point in multi-threaded
 programs, so one has to be prepared for this and make sure that

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=c1cdac9138436a153fe2f4f9769c7e7a71a00cfb

commit c1cdac9138436a153fe2f4f9769c7e7a71a00cfb
Author: Alexandre Oliva <aoliva@redhat.com>
Date:   Fri Nov 8 06:08:22 2013 -0200

    MT-, AS- and AC-safety docs: manual/search.texi
    
    for ChangeLog
    
    	* manual/search.texi: Document MTASC-safety properties.

diff --git a/manual/search.texi b/manual/search.texi
index efd3604..46f5f1c 100644
--- a/manual/search.texi
+++ b/manual/search.texi
@@ -113,6 +113,7 @@ the header file @file{stdlib.h}.
 @comment stdlib.h
 @comment ISO
 @deftypefun {void *} bsearch (const void *@var{key}, const void *@var{array}, size_t @var{count}, size_t @var{size}, comparison_fn_t @var{compare})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 The @code{bsearch} function searches the sorted array @var{array} for an object
 that is equivalent to @var{key}.  The array contains @var{count} elements,
 each of which is of size @var{size} bytes.
@@ -146,6 +147,7 @@ To sort an array using an arbitrary comparison function, use the
 @comment stdlib.h
 @comment ISO
 @deftypefun void qsort (void *@var{array}, size_t @var{count}, size_t @var{size}, comparison_fn_t @var{compare})
+@safety{@mtsafe{xguargs}@assafe{asmalloc}@acsafe{memleak}}
 The @var{qsort} function sorts the array @var{array}.  The array contains
 @var{count} elements, each of which is of size @var{size}.
 
@@ -436,6 +438,11 @@ in the header file @file{search.h}.
 @comment search.h
 @comment SVID
 @deftypefun {void *} tsearch (const void *@var{key}, void **@var{rootp}, comparison_fn_t @var{compar})
+@safety{@mtunsafe{xguargs}@asunsafe{asynconsist, asmalloc}@acunsafe{incansist, memleak}}
+@c The tree is not modified in a thread-safe manner, and rotations may
+@c leave the tree in an inconsistent state that could be observed in an
+@c asynchronous signal handler or after asynchronous cancellation of the
+@c thread performing the rotation or the insertion.
 The @code{tsearch} function searches in the tree pointed to by
 @code{*@var{rootp}} for an element matching @var{key}.  The function
 pointed to by @var{compar} is used to determine whether two elements
@@ -465,6 +472,7 @@ of space @code{NULL} is returned.
 @comment search.h
 @comment SVID
 @deftypefun {void *} tfind (const void *@var{key}, void *const *@var{rootp}, comparison_fn_t @var{compar})
+@safety{@mtsafe{xguargs}@assafe{}@acsafe{}}
 The @code{tfind} function is similar to the @code{tsearch} function.  It
 locates an element matching the one pointed to by @var{key} and returns
 a pointer to this element.  But if no matching element is available no
@@ -479,6 +487,7 @@ elements.
 @comment search.h
 @comment SVID
 @deftypefun {void *} tdelete (const void *@var{key}, void **@var{rootp}, comparison_fn_t @var{compar})
+@safety{@mtunsafe{xguargs}@asunsafe{asynconsist, asmalloc}@acunsafe{incansist, memleak}}
 To remove a specific element matching @var{key} from the tree
 @code{tdelete} can be used.  It locates the matching element using the
 same method as @code{tfind}.  The corresponding element is then removed
@@ -492,6 +501,7 @@ is deleted @code{tdelete} returns some unspecified value not equal to
 @comment search.h
 @comment GNU
 @deftypefun void tdestroy (void *@var{vroot}, __free_fn_t @var{freefct})
+@safety{@mtsafe{}@assafe{asmalloc}@acsafe{memleak}}
 If the complete search tree has to be removed one can use
 @code{tdestroy}.  It frees all resources allocated by the @code{tsearch}
 function to generate the tree pointed to by @var{vroot}.
@@ -546,6 +556,7 @@ The current node is a leaf.
 @comment search.h
 @comment SVID
 @deftypefun void twalk (const void *@var{root}, __action_fn_t @var{action})
+@safety{@mtsafe{xguards}@assafe{}@acsafe{}}
 For each node in the tree with a node pointed to by @var{root}, the
 @code{twalk} function calls the function provided by the parameter
 @var{action}.  For leaf nodes the function is called exactly once with

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=27ab67783a7576aef16832f8936ebc824d68b477

commit 27ab67783a7576aef16832f8936ebc824d68b477
Author: Alexandre Oliva <aoliva@redhat.com>
Date:   Fri Nov 8 06:08:21 2013 -0200

    MT-, AS- and AC-safety docs: manual/resource.texi
    
    for ChangeLog
    
    	* manual/resource.texi: Document MTASC-safety properties.

diff --git a/manual/resource.texi b/manual/resource.texi
index 1ec7af2..71b08f7 100644
--- a/manual/resource.texi
+++ b/manual/resource.texi
@@ -223,6 +223,8 @@ The symbols for use with @code{getrlimit}, @code{setrlimit},
 @comment sys/resource.h
 @comment BSD
 @deftypefun int getrlimit (int @var{resource}, struct rlimit *@var{rlp})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
+@c Direct syscall on most systems.
 Read the current and maximum limits for the resource @var{resource}
 and store them in @code{*@var{rlp}}.
 
@@ -237,6 +239,8 @@ LFS interface transparently replaces the old interface.
 @comment sys/resource.h
 @comment Unix98
 @deftypefun int getrlimit64 (int @var{resource}, struct rlimit64 *@var{rlp})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
+@c Direct syscall on most systems, wrapper to the getrlimit otherwise.
 This function is similar to @code{getrlimit} but its second parameter is
 a pointer to a variable of type @code{struct rlimit64}, which allows it
 to read values which wouldn't fit in the member of a @code{struct
@@ -1516,6 +1520,9 @@ There is a much older interface available, too.
 @comment unistd.h
 @comment BSD
 @deftypefun int getpagesize (void)
+@safety{@mtsafe{}@assafe{}@acsafe{}}
+@c Obtained from the aux vec at program startup time.  GNU/Linux/m68k is
+@c the exception, with the possibility of a syscall.
 The @code{getpagesize} function returns the page size of the process.
 This value is fixed for the runtime of the process but can vary in
 different runs of the application.
@@ -1559,6 +1566,8 @@ get this information two functions.  They are declared in the file
 @comment sys/sysinfo.h
 @comment GNU
 @deftypefun {long int} get_phys_pages (void)
+@safety{@mtsafe{}@asunsafe{asmalloc, selfdeadlock}@acunsafe{lockleak, fdleak, memleak}}
+@c This fopens a /proc file and scans it for the requested information.
 The @code{get_phys_pages} function returns the total number of pages of
 physical the system has.  To get the amount of memory this number has to
 be multiplied by the page size.
@@ -1569,6 +1578,7 @@ This function is a GNU extension.
 @comment sys/sysinfo.h
 @comment GNU
 @deftypefun {long int} get_avphys_pages (void)
+@safety{@mtsafe{}@asunsafe{asmalloc, selfdeadlock}@acunsafe{lockleak, fdleak, memleak}}
 The @code{get_phys_pages} function returns the number of available pages of
 physical the system has.  To get the amount of memory this number has to
 be multiplied by the page size.
@@ -1614,6 +1624,10 @@ in @file{sys/sysinfo.h}.
 @comment sys/sysinfo.h
 @comment GNU
 @deftypefun int get_nprocs_conf (void)
+@safety{@mtsafe{}@asunsafe{asmalloc, selfdeadlock}@acunsafe{lockleak, fdleak, memleak}}
+@c This function reads from from /sys using dir streams (single user, so
+@c no staticbuf MT-Safety issue), and on some arches, from /proc using
+@c streams.
 The @code{get_nprocs_conf} function returns the number of processors the
 operating system configured.
 
@@ -1623,6 +1637,8 @@ This function is a GNU extension.
 @comment sys/sysinfo.h
 @comment GNU
 @deftypefun int get_nprocs (void)
+@safety{@mtsafe{}@assafe{}@acsafe{fdleak}}
+@c This function reads from /proc using file descriptor I/O.
 The @code{get_nprocs} function returns the number of available processors.
 
 This function is a GNU extension.

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=bcb984ba0fb28d5bec68befab7480dd878cddf36

commit bcb984ba0fb28d5bec68befab7480dd878cddf36
Author: Alexandre Oliva <aoliva@redhat.com>
Date:   Fri Nov 8 06:08:25 2013 -0200

    MT-, AS- and AC-safety docs: manual/users.texi
    
    for ChangeLog
    
    	* manual/users.texi: Document MTASC-safety properties.

diff --git a/manual/users.texi b/manual/users.texi
index 957e346..f68d58c 100644
--- a/manual/users.texi
+++ b/manual/users.texi
@@ -221,30 +221,37 @@ This is an integer data type used to represent group IDs.  In
 @comment unistd.h
 @comment POSIX.1
 @deftypefun uid_t getuid (void)
+@safety{@mtsafe{}@assafe{}@acsafe{}}
+@c Atomic syscall, except on hurd, where it takes a lock within a hurd
+@c critical section.
 The @code{getuid} function returns the real user ID of the process.
 @end deftypefun
 
 @comment unistd.h
 @comment POSIX.1
 @deftypefun gid_t getgid (void)
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 The @code{getgid} function returns the real group ID of the process.
 @end deftypefun
 
 @comment unistd.h
 @comment POSIX.1
 @deftypefun uid_t geteuid (void)
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 The @code{geteuid} function returns the effective user ID of the process.
 @end deftypefun
 
 @comment unistd.h
 @comment POSIX.1
 @deftypefun gid_t getegid (void)
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 The @code{getegid} function returns the effective group ID of the process.
 @end deftypefun
 
 @comment unistd.h
 @comment POSIX.1
 @deftypefun int getgroups (int @var{count}, gid_t *@var{groups})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 The @code{getgroups} function is used to inquire about the supplementary
 group IDs of the process.  Up to @var{count} of these group IDs are
 stored in the array @var{groups}; the return value from the function is
@@ -291,6 +298,7 @@ include the header files @file{sys/types.h} and @file{unistd.h}.
 @comment unistd.h
 @comment POSIX.1
 @deftypefun int seteuid (uid_t @var{neweuid})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 This function sets the effective user ID of a process to @var{neweuid},
 provided that the process is allowed to change its effective user ID.  A
 privileged process (effective user ID zero) can change its effective
@@ -318,6 +326,7 @@ have this function.
 @comment unistd.h
 @comment POSIX.1
 @deftypefun int setuid (uid_t @var{newuid})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 If the calling process is privileged, this function sets both the real
 and effective user ID of the process to @var{newuid}.  It also deletes
 the file user ID of the process, if any.  @var{newuid} may be any
@@ -334,6 +343,7 @@ The return values and error conditions are the same as for @code{seteuid}.
 @comment unistd.h
 @comment BSD
 @deftypefun int setreuid (uid_t @var{ruid}, uid_t @var{euid})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 This function sets the real user ID of the process to @var{ruid} and the
 effective user ID to @var{euid}.  If @var{ruid} is @code{-1}, it means
 not to change the real user ID; likewise if @var{euid} is @code{-1}, it
@@ -369,6 +379,7 @@ the header files @file{sys/types.h} and @file{unistd.h}.
 @comment unistd.h
 @comment POSIX.1
 @deftypefun int setegid (gid_t @var{newgid})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 This function sets the effective group ID of the process to
 @var{newgid}, provided that the process is allowed to change its group
 ID.  Just as with @code{seteuid}, if the process is privileged it may
@@ -388,6 +399,7 @@ This function is only present if @code{_POSIX_SAVED_IDS} is defined.
 @comment unistd.h
 @comment POSIX.1
 @deftypefun int setgid (gid_t @var{newgid})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 This function sets both the real and effective group ID of the process
 to @var{newgid}, provided that the process is privileged.  It also
 deletes the file group ID, if any.
@@ -402,6 +414,7 @@ as those for @code{seteuid}.
 @comment unistd.h
 @comment BSD
 @deftypefun int setregid (gid_t @var{rgid}, gid_t @var{egid})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 This function sets the real group ID of the process to @var{rgid} and
 the effective group ID to @var{egid}.  If @var{rgid} is @code{-1}, it
 means not to change the real group ID; likewise if @var{egid} is
@@ -438,6 +451,7 @@ should include the header file @file{grp.h}.
 @comment grp.h
 @comment BSD
 @deftypefun int setgroups (size_t @var{count}, const gid_t *@var{groups})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 This function sets the process's supplementary group IDs.  It can only
 be called from privileged processes.  The @var{count} argument specifies
 the number of group IDs in the array @var{groups}.
@@ -455,6 +469,36 @@ The calling process is not privileged.
 @comment grp.h
 @comment BSD
 @deftypefun int initgroups (const char *@var{user}, gid_t @var{group})
+@safety{@mtsafe{glocale}@asunsafe{shlimb, uplugin, asmalloc, selfdeadlock}@acunsafe{incansist, memleak, fdleak, lockleak}}
+@c initgroups glocale, shlimb, uplugin, asmalloc, selfdeadlock, incansist, lockleak, fdleak, memleak
+@c  sysconf(_SC_NGROUPS_MAX) dup fdleak
+@c  MIN dup ok
+@c  malloc asmalloc, memleak
+@c  internal_getgrouplist glocale, shlimb, uplugin, asmalloc, selfdeadlock, incansist, lockleak, fdleak, memleak
+@c   nscd_getgrouplist asmalloc, selfdeadlock, lockleak, fdleak, memleak
+@c    nscd_get_map_ref dup asmalloc, selfdeadlock, lockleak, fdleak, memleak
+@c    nscd_cache_search dup ok
+@c    nscd_open_socket dup fdleak
+@c    realloc dup asmalloc, memleak
+@c    readall dup ok
+@c    memcpy dup ok
+@c    close_not_cancel_no_status dup fdleak
+@c    nscd_drop_map_ref dup selfdeadlock, lockleak, fdleak, memleak
+@c    nscd_unmap dup selfdeadlock, lockleak, fdleak, memleak
+@c   nss_database_lookup dup glocale, asmalloc, selfdeadlock, incansist, memleak, fdleak, lockleak
+@c   nss_lookup_function dup shlimb, uplugin, asmalloc, selfdeadlock, incansist, lockleak, fdleak, memleak
+@c   compat_call shlimb, uplugin, asmalloc, selfdeadlock, incansist, lockleak, fdleak, memleak
+@c    sysconf(_SC_GETGR_R_SIZE_MAX) ok
+@c    nss_lookup_function dup shlimb, uplugin, asmalloc, selfdeadlock, incansist, lockleak, fdleak, memleak
+@c    *getgrent_fct uplugin
+@c    *setgrent_fct uplugin
+@c    *endgrent_fct uplugin
+@c    realloc dup asmalloc, memleak
+@c    free dup asmalloc, memleak
+@c   *initgroups_dyn_fct uplugin
+@c   nss_next_action dup ok
+@c  setgroups dup ok
+@c  free dup asmalloc, memleak
 The @code{initgroups} function sets the process's supplementary group
 IDs to be the normal default for the user name @var{user}.  The group
 @var{group} is automatically included.
@@ -476,6 +520,13 @@ include the header file @file{grp.h}.
 @comment grp.h
 @comment BSD
 @deftypefun int getgrouplist (const char *@var{user}, gid_t @var{group}, gid_t *@var{groups}, int *@var{ngroups})
+@safety{@mtsafe{glocale}@asunsafe{shlimb, uplugin, asmalloc, selfdeadlock}@acunsafe{incansist, memleak, fdleak, lockleak}}
+@c getgrouplist glocale, shlimb, uplugin, asmalloc, selfdeadlock, incansist, lockleak, fdleak, memleak
+@c  MAX dup ok
+@c  malloc dup asmalloc, memleak
+@c  internal_getgrouplist dup glocale, shlimb, uplugin, asmalloc, selfdeadlock, incansist, lockleak, fdleak, memleak
+@c  memcpy dup ok
+@c  free dup asmalloc, memleak
 The @code{getgrouplist} function scans the group database for all the
 groups @var{user} belongs to.  Up to *@var{ngroups} group IDs
 corresponding to these groups are stored in the array @var{groups}; the
@@ -792,6 +843,41 @@ The @code{getlogin} function is declared in @file{unistd.h}, while
 @comment unistd.h
 @comment POSIX.1
 @deftypefun {char *} getlogin (void)
+@safety{@mtunsafe{staticbuf, tempsig, stimer, glocale}@asunsafe{shlimb, uplugin, asmalloc, selfdeadlock}@acunsafe{incansist, lockleak, fdleak, memleak}}
+@c getlogin (linux) staticbuf, tempsig, stimer, glocale, shlimb, uplugin, asmalloc, selfdeadlock, incansist, lockleak, fdleak, memleak
+@c  getlogin_r_loginuid dup glocale, shlimb, uplugin, asmalloc, selfdeadlock, incansist, lockleak, fdleak, memleak
+@c  getlogin_fd0 (unix) staticbuf, tempsig, stimer, asmalloc, selfdeadlock, lockleak, fdleak, memleak
+@c    uses static buffer name => staticbuf
+@c   ttyname_r dup asmalloc, memleak, fdleak
+@c   strncpy dup ok
+@c   setutent dup staticbuf, selfdeadlock, lockleak, fdleak
+@c   getutline_r dup staticbuf, tempsig, stimer, selfdeadlock, lockleak, fdleak
+@c   endutent dup staticbuf, selfdeadlock, lockleak
+@c   libc_lock_unlock dup ok
+@c   strlen dup ok
+@c   memcpy dup ok
+@c
+@c getlogin_r (linux) staticbuf, tempsig, stimer, glocale, shlimb, uplugin, asmalloc, selfdeadlock, incansist, lockleak, fdleak, memleak
+@c  getlogin_r_loginuid glocale, shlimb, uplugin, asmalloc, selfdeadlock, incansist, lockleak, fdleak, memleak
+@c   open_not_cancel_2 dup fdleak
+@c   read_not_cancel dup ok
+@c   close_not_cancel_no_status dup fdleak
+@c   strtoul glocale, glocale
+@c   getpwuid_r dup glocale, shlimb, uplugin, asmalloc, selfdeadlock, incansist, lockleak, fdleak, memleak
+@c   realloc dup selfdeadlock, lockleak, fdleak, memleak
+@c   strlen dup ok
+@c   memcpy dup ok
+@c   free dup selfdeadlock, lockleak, fdleak, memleak
+@c  getlogin_r_fd0 (unix) staticbuf, tempsig, stimer, asmalloc, selfdeadlock, lockleak, memleak, fdleak
+@c   ttyname_r dup asmalloc, memleak, fdleak
+@c   strncpy dup ok
+@c   libc_lock_lock dup selfdeadlock, lockleak
+@c   *libc_utmp_jump_table->setutent dup staticbuf, fdleak
+@c   *libc_utmp_jump_table->getutline_r dup staticbuf, tempsig, stimer
+@c   *libc_utmp_jump_table->endutent dup staticbuf, selfdeadlock, lockleak
+@c   libc_lock_unlock dup ok
+@c   strlen dup ok
+@c   memcpy dup ok
 The @code{getlogin} function returns a pointer to a string containing the
 name of the user logged in on the controlling terminal of the process,
 or a null pointer if this information cannot be determined.  The string
@@ -802,6 +888,11 @@ this function or to @code{cuserid}.
 @comment stdio.h
 @comment POSIX.1
 @deftypefun {char *} cuserid (char *@var{string})
+@safety{@mtsafe{glocale}@asunsafe{shlimb, uplugin, asmalloc, selfdeadlock}@acunsafe{incansist, lockleak, fdleak, memleak}}
+@c cuserid glocale, shlimb, uplugin, asmalloc, selfdeadlock, incansist, lockleak, fdleak, memleak
+@c  geteuid dup ok
+@c  getpwuid_r dup glocale, shlimb, uplugin, asmalloc, selfdeadlock, incansist, lockleak, fdleak, memleak
+@c  strncpy dup ok
 The @code{cuserid} function returns a pointer to a string containing a
 user name associated with the effective ID of the process.  If
 @var{string} is not a null pointer, it should be an array that can hold
@@ -1013,6 +1104,22 @@ compatibility only, @file{utmp.h} defines @code{ut_time} as an alias for
 @comment utmp.h
 @comment SVID
 @deftypefun void setutent (void)
+@safety{@mtunsafe{staticbuf}@asunsafe{selfdeadlock}@acunsafe{lockleak, fdleak}}
+@c Besides the static variables in utmp_file.c, there's the jump_table.
+@c They're both modified while holding a lock, but other threads may
+@c cause the variables to be modified between calling this function and
+@c others that rely on the internal state it sets up.
+
+@c setutent staticbuf, selfdeadlock, lockleak, fdleak
+@c  libc_lock_lock dup selfdeadlock, lockleak
+@c  *libc_utmp_jump_table->setutent staticbuf, fdleak
+@c   setutent_unknown staticbuf, fdleak
+@c    *libc_utmp_file_functions.setutent = setutent_file staticbuf, fdleak
+@c      open_not_cancel_2 dup fdleak
+@c      fcntl_not_cancel dup ok
+@c      close_not_cancel_no_status dup fdleak
+@c      lseek64 dup ok
+@c  libc_lock_unlock dup ok
 This function opens the user accounting database to begin scanning it.
 You can then call @code{getutent}, @code{getutid} or @code{getutline} to
 read entries and @code{pututline} to write entries.
@@ -1024,6 +1131,15 @@ the database.
 @comment utmp.h
 @comment SVID
 @deftypefun {struct utmp *} getutent (void)
+@safety{@mtunsafe{1stcall, staticbuf, tempsig, stimer}@asunsafe{asmaloc, selfdeadlock, tempsig, stimer}@acunsafe{tempsig, stimer, lockleak, fdleak, memleak}}
+@c The static buffer that holds results is allocated with malloc at
+@c the first call; the test is not thread-safe, so multiple concurrent
+@c calls could malloc multiple buffers.
+
+@c getutent 1stcall, staticbuf, tempsig, stimer, asmalloc, selfdeadlock, lockleak, fdleak, memleak
+@c  malloc selfdeadlock, lockleak, fdleak, memleak
+@c  getutent_r dup staticbuf, tempsig, stimer, selfdeadlock, lockleak, fdleak
+
 The @code{getutent} function reads the next entry from the user
 accounting database.  It returns a pointer to the entry, which is
 statically allocated and may be overwritten by subsequent calls to
@@ -1037,12 +1153,27 @@ A null pointer is returned in case no further entry is available.
 @comment utmp.h
 @comment SVID
 @deftypefun void endutent (void)
+@safety{@mtunsafe{staticbuf}@asunsafe{selfdeadlock}@acunsafe{lockleak, fdleak}}
+@c endutent staticbuf, selfdeadlock, lockleak, fdleak
+@c  libc_lock_lock dup selfdeadlock, lockleak
+@c  *libc_utmp_jump_table->endutent staticbuf, fdleak
+@c   endutent_unknown ok
+@c   endutent_file staticbuf, fdleak
+@c    close_not_cancel_no_status dup fdleak
+@c  libc_lock_unlock dup ok
 This function closes the user accounting database.
 @end deftypefun
 
 @comment utmp.h
 @comment SVID
 @deftypefun {struct utmp *} getutid (const struct utmp *@var{id})
+@safety{@mtunsafe{1stcall, staticbuf, tempsig, stimer}@asunsafe{selfdeadlock, asmalloc, tempsig, stimer}@acunsafe{tempsig, stimer, lockleak, memleak, fdleak}}
+@c Same caveats as getutline.
+@c
+@c getutid 1stcall, staticbuf, tempsig, stimer, asmalloc, selfdeadlock, lockleak, memleak, fdleak
+@c   uses a static buffer malloced on the first call
+@c  malloc dup asmalloc, memleak
+@c  getutid_r dup staticbuf, tempsig, stimer, selfdeadlock, lockleak, fdleak
 This function searches forward from the current point in the database
 for an entry that matches @var{id}.  If the @code{ut_type} member of the
 @var{id} structure is one of @code{RUN_LVL}, @code{BOOT_TIME},
@@ -1073,6 +1204,14 @@ over again.
 @comment utmp.h
 @comment SVID
 @deftypefun {struct utmp *} getutline (const struct utmp *@var{line})
+@safety{@mtunsafe{1stcall, staticbuf, tempsig, stimer}@asunsafe{asmaloc, selfdeadlock, tempsig, stimer}@acunsafe{tempsig, stimer, lockleak, fdleak, memleak}}
+@c The static buffer that holds results is allocated with malloc at
+@c the first call; the test is not thread-safe, so multiple concurrent
+@c calls could malloc multiple buffers.
+
+@c getutline 1stcall, staticbuf, tempsig, stimer, asmalloc, selfdeadlock, lockleak, fdleak, memleak
+@c  malloc selfdeadlock, lockleak, fdleak, memleak
+@c  getutline_r dup staticbuf, tempsig, stimer, selfdeadlock, lockleak, fdleak
 This function searches forward from the current point in the database
 until it finds an entry whose @code{ut_type} value is
 @code{LOGIN_PROCESS} or @code{USER_PROCESS}, and whose @code{ut_line}
@@ -1095,6 +1234,29 @@ over again.
 @comment utmp.h
 @comment SVID
 @deftypefun {struct utmp *} pututline (const struct utmp *@var{utmp})
+@safety{@mtunsafe{staticbuf, tempsig, stimer}@asunsafe{selfdeadlock, tempsig, stimer}@acunsafe{tempsig, stimer, lockleak, fdleak}}
+@c pututline staticbuf, tempsig, stimer, selfdeadlock, lockleak, fdleak
+@c  libc_lock_lock dup selfdeadlock, lockleak
+@c  *libc_utmp_jump_table->pututline staticbuf, tempsig, stimer, fdleak
+@c   pututline_unknown staticbuf, fdleak
+@c    setutent_unknown dup staticbuf, fdleak
+@c   pututline_file tempsig, stimer, fdleak
+@c    TRANSFORM_UTMP_FILE_NAME ok
+@c     strcmp dup ok
+@c     acesss dup ok
+@c    open_not_cancel_2 dup fdleak
+@c    fcntl_not_cancel dup ok
+@c    close_not_cancel_no_status dup fdleak
+@c    llseek dup ok
+@c    dup2 dup ok
+@c    utmp_equal dup ok
+@c    internal_getut_r dup tempsig, stimer
+@c    LOCK_FILE dup tempsig, stimer
+@c    LOCKING_FAILED dup ok
+@c    ftruncate64 dup ok
+@c    write_not_cancel dup ok
+@c    UNLOCK_FILE dup stimer
+@c  libc_lock_unlock dup lockleak
 The @code{pututline} function inserts the entry @code{*@var{utmp}} at
 the appropriate place in the user accounting database.  If it finds that
 it is not already at the correct place in the database, it uses
@@ -1125,6 +1287,27 @@ user-provided buffer.
 @comment utmp.h
 @comment GNU
 @deftypefun int getutent_r (struct utmp *@var{buffer}, struct utmp **@var{result})
+@safety{@mtunsafe{staticbuf, tempsig, stimer}@asunsafe{selfdeadlock, tempsig, stimer}@acunsafe{tempsig, stimer, lockleak, fdleak}}
+@c getutent_r staticbuf, tempsig, stimer, selfdeadlock, lockleak, fdleak
+@c  libc_lock_lock dup selfdeadlock, lockleak
+@c  *libc_utmp_jump_table->getutent_r staticbuf, tempsig, stimer, fdleak
+@c   getutent_r_unknown staticbuf, fdleak
+@c    setutent_unknown dup staticbuf, fdleak
+@c   getutent_r_file staticbuf, tempsig, stimer
+@c    LOCK_FILE tempsig, stimer
+@c     alarm dup stimer
+@c     sigemptyset dup ok
+@c     sigaction dup ok
+@c     memset dup ok
+@c     fcntl_not_cancel dup ok
+@c    LOCKING_FAILED ok
+@c    read_not_cancel dup ok
+@c    UNLOCK_FILE stimer
+@c     fcntl_not_cancel dup ok
+@c     alarm dup stimer
+@c     sigaction dup ok
+@c    memcpy dup ok
+@c  libc_lock_unlock dup ok
 The @code{getutent_r} is equivalent to the @code{getutent} function.  It
 returns the next entry from the database.  But instead of storing the
 information in a static buffer it stores it in the buffer pointed to by
@@ -1142,6 +1325,22 @@ This function is a GNU extension.
 @comment utmp.h
 @comment GNU
 @deftypefun int getutid_r (const struct utmp *@var{id}, struct utmp *@var{buffer}, struct utmp **@var{result})
+@safety{@mtunsafe{staticbuf, tempsig, stimer}@asunsafe{selfdeadlock, tempsig, stimer}@acunsafe{tempsig, stimer, lockleak, fdleak}}
+@c getutid_r staticbuf, tempsig, stimer, selfdeadlock, lockleak, fdleak
+@c  libc_lock_lock dup selfdeadlock, lockleak
+@c  *libc_utmp_jump_table->getutid_r staticbuf, tempsig, stimer, fdleak
+@c   getutid_r_unknown staticbuf, fdleak
+@c    setutent_unknown dup staticbuf, fdleak
+@c   getutid_r_file tempsig, stimer
+@c    internal_getut_r tempsig, stimer
+@c     LOCK_FILE dup tempsig, stimer
+@c     LOCKING_FAILED dup ok
+@c     read_not_cancel dup ok
+@c     utmp_equal ok
+@c      strncmp dup ok
+@c     UNLOCK_FILE dup stimer
+@c    memcpy dup ok
+@c  libc_lock_unlock dup lockleak
 This function retrieves just like @code{getutid} the next entry matching
 the information stored in @var{id}.  But the result is stored in the
 buffer pointed to by the parameter @var{buffer}.
@@ -1157,6 +1356,28 @@ This function is a GNU extension.
 @comment utmp.h
 @comment GNU
 @deftypefun int getutline_r (const struct utmp *@var{line}, struct utmp *@var{buffer}, struct utmp **@var{result})
+@safety{@mtunsafe{staticbuf, tempsig, stimer}@asunsafe{selfdeadlock, tempsig, stimer}@acunsafe{tempsig, stimer, lockleak, fdleak}}
+@c getutline_r staticbuf, tempsig, stimer, selfdeadlock, lockleak, fdleak
+@c  libc_lock_lock dup selfdeadlock, lockleak
+@c  *libc_utmp_jump_table->getutline_r staticbuf, tempsig, stimer, fdleak
+@c   getutline_r_unknown staticbuf, fdleak
+@c    setutent_unknown dup staticbuf, fdleak
+@c   getutline_r_file staticbuf, tempsig, stimer
+@c    LOCK_FILE tempsig, stimer
+@c     alarm dup stimer
+@c     sigemptyset dup ok
+@c     sigaction dup ok
+@c     memset dup ok
+@c     fcntl_not_cancel dup ok
+@c    LOCKING_FAILED ok
+@c    read_not_cancel dup ok
+@c    strncmp dup ok
+@c    UNLOCK_FILE stimer
+@c     fcntl_not_cancel dup ok
+@c     alarm dup stimer
+@c     sigaction dup ok
+@c    memcpy dup ok
+@c  libc_lock_unlock dup ok
 This function retrieves just like @code{getutline} the next entry
 matching the information stored in @var{line}.  But the result is stored
 in the buffer pointed to by the parameter @var{buffer}.
@@ -1180,6 +1401,14 @@ be used.
 @comment utmp.h
 @comment SVID
 @deftypefun int utmpname (const char *@var{file})
+@safety{@mtunsafe{staticbuf}@asunsafe{selfdeadlock, asmalloc}@acunsafe{lockleak, memleak}}
+@c utmpname staticbuf, selfdeadlock, asmalloc, lockleak, memleak
+@c  libc_lock_lock dup selfdeadlock, lockleak
+@c  *libc_utmp_jump_table->endutent dup staticbuf
+@c  strcmp dup ok
+@c  free dup asmalloc, memleak
+@c  strdup dup asmalloc, memleak
+@c  libc_lock_unlock dup lockleak
 The @code{utmpname} function changes the name of the database to be
 examined to @var{file}, and closes any previously opened database.  By
 default @code{getutent}, @code{getutid}, @code{getutline} and
@@ -1208,6 +1437,18 @@ the following function:
 @comment utmp.h
 @comment SVID
 @deftypefun void updwtmp (const char *@var{wtmp_file}, const struct utmp *@var{utmp})
+@safety{@mtunsafe{tempsig, stimer}@asunsafe{tempsig, stimer}@acunsafe{tempsig, stimer, fdleak}}
+@c updwtmp tempsig, stimer, fdleak
+@c  TRANSFORM_UTMP_FILE_NAME dup ok
+@c  *libc_utmp_file_functions->updwtmp = updwtmp_file tempsig, stimer, fdleak
+@c   open_not_cancel_2 dup fdleak
+@c   LOCK_FILE dup tempsig, stimer
+@c   LOCKING_FAILED dup ok
+@c   lseek64 dup ok
+@c   ftruncate64 dup ok
+@c   write_not_cancel dup ok
+@c   UNLOCK_FILE dup stimer
+@c   close_not_cancel_no_status dup fdleak
 The @code{updwtmp} function appends the entry *@var{utmp} to the
 database specified by @var{wtmp_file}.  For possible values for the
 @var{wtmp_file} argument see the @code{utmpname} function.
@@ -1330,6 +1571,7 @@ can be found using the @code{sizeof} operator.
 @comment utmpx.h
 @comment XPG4.2
 @deftypefun void setutxent (void)
+@safety{@mtunsafe{staticbuf}@asunsafe{selfdeadlock}@acunsafe{lockleak, fdleak}}
 This function is similar to @code{setutent}.  In @theglibc{} it is
 simply an alias for @code{setutent}.
 @end deftypefun
@@ -1337,6 +1579,7 @@ simply an alias for @code{setutent}.
 @comment utmpx.h
 @comment XPG4.2
 @deftypefun {struct utmpx *} getutxent (void)
+@safety{@mtunsafe{1stcall, staticbuf, tempsig, stimer}@asunsafe{asmaloc, selfdeadlock, tempsig, stimer}@acunsafe{tempsig, stimer, lockleak, fdleak, memleak}}
 The @code{getutxent} function is similar to @code{getutent}, but returns
 a pointer to a @code{struct utmpx} instead of @code{struct utmp}.  In
 @theglibc{} it simply is an alias for @code{getutent}.
@@ -1345,6 +1588,7 @@ a pointer to a @code{struct utmpx} instead of @code{struct utmp}.  In
 @comment utmpx.h
 @comment XPG4.2
 @deftypefun void endutxent (void)
+@safety{@mtunsafe{staticbuf}@asunsafe{selfdeadlock}@acunsafe{lockleak}}
 This function is similar to @code{endutent}.  In @theglibc{} it is
 simply an alias for @code{endutent}.
 @end deftypefun
@@ -1352,6 +1596,7 @@ simply an alias for @code{endutent}.
 @comment utmpx.h
 @comment XPG4.2
 @deftypefun {struct utmpx *} getutxid (const struct utmpx *@var{id})
+@safety{@mtunsafe{1stcall, staticbuf, tempsig, stimer}@asunsafe{selfdeadlock, asmalloc, tempsig, stimer}@acunsafe{tempsig, stimer, lockleak, memleak, fdleak}}
 This function is similar to @code{getutid}, but uses @code{struct utmpx}
 instead of @code{struct utmp}.  In @theglibc{} it is simply an alias
 for @code{getutid}.
@@ -1360,6 +1605,7 @@ for @code{getutid}.
 @comment utmpx.h
 @comment XPG4.2
 @deftypefun {struct utmpx *} getutxline (const struct utmpx *@var{line})
+@safety{@mtunsafe{1stcall, staticbuf, tempsig, stimer}@asunsafe{asmaloc, selfdeadlock, tempsig, stimer}@acunsafe{tempsig, stimer, lockleak, fdleak, memleak}}
 This function is similar to @code{getutid}, but uses @code{struct utmpx}
 instead of @code{struct utmp}.  In @theglibc{} it is simply an alias
 for @code{getutline}.
@@ -1368,6 +1614,7 @@ for @code{getutline}.
 @comment utmpx.h
 @comment XPG4.2
 @deftypefun {struct utmpx *} pututxline (const struct utmpx *@var{utmp})
+@safety{@mtunsafe{staticbuf, tempsig, stimer}@asunsafe{selfdeadlock, tempsig, stimer}@acunsafe{tempsig, stimer, lockleak, fdleak}}
 The @code{pututxline} function is functionally identical to
 @code{pututline}, but uses @code{struct utmpx} instead of @code{struct
 utmp}.  In @theglibc{}, @code{pututxline} is simply an alias for
@@ -1377,6 +1624,7 @@ utmp}.  In @theglibc{}, @code{pututxline} is simply an alias for
 @comment utmpx.h
 @comment XPG4.2
 @deftypefun int utmpxname (const char *@var{file})
+@safety{@mtunsafe{staticbuf}@asunsafe{selfdeadlock, asmalloc}@acunsafe{lockleak, memleak}}
 The @code{utmpxname} function is functionally identical to
 @code{utmpname}.  In @theglibc{}, @code{utmpxname} is simply an
 alias for @code{utmpname}.
@@ -1391,6 +1639,7 @@ identical.
 @comment utmp.h
 @comment GNU
 @deftypefun int getutmp (const struct utmpx *@var{utmpx}, struct utmp *@var{utmp})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 @code{getutmp} copies the information, insofar as the structures are
 compatible, from @var{utmpx} to @var{utmp}.
 @end deftypefun
@@ -1399,6 +1648,7 @@ compatible, from @var{utmpx} to @var{utmp}.
 @comment utmp.h
 @comment GNU
 @deftypefun int getutmpx (const struct utmp *@var{utmp}, struct utmpx *@var{utmpx})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 @code{getutmpx} copies the information, insofar as the structures are
 compatible, from @var{utmp} to @var{utmpx}.
 @end deftypefun
@@ -1418,6 +1668,17 @@ for @code{ut_user} in @file{utmp.h}.
 @comment utmp.h
 @comment BSD
 @deftypefun int login_tty (int @var{filedes})
+@safety{@mtunsafe{staticbuf}@asunsafe{asmalloc, selfdeadlock}@acunsafe{lockleak, fdleak, memleak}}
+@c If this function is canceled, it may have succeeded in redirecting
+@c only some of the standard streams to the newly opened terminal.
+@c Should there be a safety annotation for this?
+@c login_tty staticbuf, asmalloc, selfdeadlock, lockleak, memleak, fdleak
+@c  setsid dup ok
+@c  ioctl dup ok
+@c  ttyname dup staticbuf, asmalloc, selfdeadlock, lockleak, memleak, fdleak
+@c  close dup fdleak
+@c  open dup fdleak
+@c  dup2 dup ok
 This function makes @var{filedes} the controlling terminal of the
 current process, redirects standard input, standard output and
 standard error output to this terminal, and closes @var{filedes}.
@@ -1429,6 +1690,24 @@ on error.
 @comment utmp.h
 @comment BSD
 @deftypefun void login (const struct utmp *@var{entry})
+@safety{@mtunsafe{staticbuf, tempsig, stimer}@asunsafe{selfdeadlock, asmalloc, tempsig, stimer}@acunsafe{tempsig, stimer, lockleak, incansist, fdleak, memleak}}
+@c login staticbuf, tempsig, stimer, selfdeadlock, asmalloc, lockleak, incansist, fdleak, memleak
+@c  getpid dup ok
+@c  tty_name asmalloc, incansist, memleak, fdleak
+@c   ttyname_r dup asmalloc, memleak, fdleak
+@c   memchr dup ok
+@c   realloc dup asmalloc, memleak
+@c   malloc dup asmalloc, memleak
+@c   free dup asmalloc, memleak
+@c  strncmp dup ok
+@c  basename dup ok
+@c  strncpy dup ok
+@c  utmpname dup staticbuf, selfdeadlock, asmalloc, lockleak, memleak
+@c  setutent dup staticbuf, selfdeadlock, lockleak, fdleak
+@c  pututline dup staticbuf, tempsig, stimer, selfdeadlock, lockleak, fdleak
+@c  endutent dup staticbuf, selfdeadlock, lockleak
+@c  free dup asmalloc, memleak
+@c  updwtmp dup tempsig, stimer, fdleak
 The @code{login} functions inserts an entry into the user accounting
 database.  The @code{ut_line} member is set to the name of the terminal
 on standard input.  If standard input is not a terminal @code{login}
@@ -1444,6 +1723,17 @@ A copy of the entry is written to the user accounting log file.
 @comment utmp.h
 @comment BSD
 @deftypefun int logout (const char *@var{ut_line})
+@safety{@mtunsafe{staticbuf, tempsig, stimer}@asunsafe{selfdeadlock, asmalloc, tempsig, stimer}@acunsafe{tempsig, stimer, lockleak, fdleak, memleak}}
+@c logout staticbuf, tempsig, stimer, selfdeadlock, asmalloc, lockleak, fdleak, memleak
+@c  utmpname dup staticbuf, selfdeadlock, asmalloc, lockleak, memleak
+@c  setutent dup staticbuf, selfdeadlock, lockleak, fdleak
+@c  strncpy dup ok
+@c  getutline_r dup staticbuf, tempsig, stimer, selfdeadlock, lockleak, fdleak
+@c  bzero dup ok
+@c  gettimeofday dup ok
+@c  time dup ok
+@c  pututline dup staticbuf, tempsig, stimer, selfdeadlock, lockleak, fdleak
+@c  endutent dup staticbuf, selfdeadlock, lockleak
 This function modifies the user accounting database to indicate that the
 user on @var{ut_line} has logged out.
 
@@ -1454,6 +1744,14 @@ written to the database, or @code{0} on error.
 @comment utmp.h
 @comment BSD
 @deftypefun void logwtmp (const char *@var{ut_line}, const char *@var{ut_name}, const char *@var{ut_host})
+@safety{@mtunsafe{tempsig, stimer}@asunsafe{tempsig, stimer}@acunsafe{tempsig, stimer, fdleak}}
+@c logwtmp tempsig, stimer, fdleak
+@c  memset dup ok
+@c  getpid dup ok
+@c  strncpy dup ok
+@c  gettimeofday dup ok
+@c  time dup ok
+@c  updwtmp dup tempsig, stimer, fdleak
 The @code{logwtmp} function appends an entry to the user accounting log
 file, for the current time and the information provided in the
 @var{ut_line}, @var{ut_name} and @var{ut_host} arguments.
@@ -1535,6 +1833,14 @@ functions are declared in @file{pwd.h}.
 @comment pwd.h
 @comment POSIX.1
 @deftypefun {struct passwd *} getpwuid (uid_t @var{uid})
+@safety{@mtunsafe{staticbuf, glocale}@asunsafe{shlimb, uplugin, asmalloc, selfdeadlock}@acunsafe{incansist, lockleak, fdleak, memleak}}
+@c getpwuid staticbuf, glocale, shlimb, uplugin, asmalloc, selfdeadlock, incansist, lockleak, fdleak, memleak
+@c  libc_lock_lock dup selfdeadlock, lockleak
+@c  malloc dup asmalloc, memleak
+@c  getpwuid_r dup glocale, shlimb, uplugin, asmalloc, selfdeadlock, incansist, lockleak, fdleak, memleak
+@c  realloc dup asmalloc, memleak
+@c  free dup asmalloc, memleak
+@c  libc_lock_unlock dup lockleak
 This function returns a pointer to a statically-allocated structure
 containing information about the user whose user ID is @var{uid}.  This
 structure may be overwritten on subsequent calls to @code{getpwuid}.
@@ -1546,6 +1852,208 @@ user ID @var{uid}.
 @comment pwd.h
 @comment POSIX.1c
 @deftypefun int getpwuid_r (uid_t @var{uid}, struct passwd *@var{result_buf}, char *@var{buffer}, size_t @var{buflen}, struct passwd **@var{result})
+@safety{@mtsafe{glocale}@asunsafe{shlimb, uplugin, asmalloc, selfdeadlock}@acunsafe{incansist, lockleak, fdleak, memleak}}
+@c getpwuid_r glocale, shlimb, uplugin, asmalloc, selfdeadlock, incansist, lockleak, fdleak, memleak
+@c  nscd_getpwuid_r asmalloc, selfdeadlock, lockleak, fdleak, memleak
+@c   itoa_word dup ok
+@c   nscd_getpw_r asmalloc, selfdeadlock, lockleak, fdleak, memleak
+@c    nscd_get_map_ref asmalloc, selfdeadlock, lockleak, fdleak, memleak
+@c     nscd_acquire_maplock ok
+@c     nscd_get_mapping asmalloc, selfdeadlock, lockleak, fdleak, memleak
+@c      open_socket dup ok
+@c      memset dup ok
+@c      wait_on_socket dup ok
+@c      recvmsg dup ok
+@c      strcmp dup ok
+@c      fstat64 dup ok
+@c      mmap dup memleak
+@c      munmap dup ok
+@c      malloc dup selfdeadlock, lockleak, fdleak, memleak
+@c      close dup ok
+@c      nscd_unmap dup selfdeadlock, lockleak, fdleak, memleak
+@c    nscd_cache_search ok
+@c     nis_hash ok
+@c     memcmp dup ok
+@c    nscd_open_socket fdleak
+@c     open_socket fdleak
+@c      socket dup fdleak
+@c      fcntl dup ok
+@c      strcpy dup ok
+@c      connect dup ok
+@c      send dup ok
+@c      gettimeofday dup ok
+@c      poll dup ok
+@c      close_not_cancel_no_status dup fdleak
+@c     wait_on_socket dup ok
+@c     read dup ok
+@c     close_not_cancel_no_status dup fdleak
+@c    readall ok
+@c     read dup ok
+@c     wait_on_socket ok
+@c      poll dup ok
+@c      gettimeofday dup ok
+@c    memcpy dup ok
+@c    close_not_cancel_no_status dup fdleak
+@c    nscd_drop_map_ref selfdeadlock, lockleak, fdleak, memleak
+@c     nscd_unmap dup selfdeadlock, lockleak, fdleak, memleak
+@c    nscd_unmap selfdeadlock, lockleak, fdleak, memleak
+@c     munmap dup ok
+@c     free dup selfdeadlock, lockleak, fdleak, memleak
+@c  nss_passwd_lookup2 glocale, shlimb, uplugin, asmalloc, selfdeadlock, incansist, lockleak, fdleak, memleak
+@c   nss_database_lookup glocale, asmalloc, selfdeadlock, incansist, memleak, fdleak, lockleak
+@c    libc_lock_lock selfdeadlock, lockleak
+@c    libc_lock_unlock lockleak
+@c    nss_parse_file glocale, asmalloc, selfdeadlock, incansist, memleak, fdleak, lockleak
+@c     fopen dup asmalloc, selfdeadlock, memleak, fdleak, lockleak
+@c     fsetlocking dup ok [no concurrent uses]
+@c     malloc dup selfdeadlock, lockleak, fdleak, memleak
+@c     fclose dup asmalloc, selfdeadlock, memleak, fdleak, lockleak
+@c     getline dup asmalloc, lockleak, incansist, memleak
+@c     strchrnul dup ok
+@c     nss_getline glocale, asmalloc, memleak
+@c      isspace glocale^^
+@c      strlen dup ok
+@c      malloc dup selfdeadlock, lockleak, fdleak, memleak
+@c      memcpy dup ok
+@c      nss_parse_service_list dup glocale^, asmalloc, memleak
+@c     feof_unlocked dup ok
+@c     free dup selfdeadlock, lockleak, fdleak, memleak
+@c    strcmp dup ok
+@c    nss_parse_service_list glocale^, asmalloc, memleak
+@c     isspace glocale^^
+@c     malloc dup selfdeadlock, lockleak, fdleak, memleak
+@c     mempcpy dup ok
+@c     strncasecmp dup ok
+@c     free dup selfdeadlock, lockleak, fdleak, memleak
+@c    malloc dup selfdeadlock, lockleak, fdleak, memleak
+@c   nss_lookup shlimb, uplugin, asmalloc, selfdeadlock, incansist, lockleak, fdleak, memleak
+@c    nss_lookup_function shlimb, uplugin, asmalloc, selfdeadlock, incansist, lockleak, fdleak, memleak
+@c     libc_lock_lock selfdeadlock, lockleak
+@c     tsearch asmalloc, incansist, memleak [no xguargs or asynconsist due to locking]
+@c      known_compare ok
+@c       strcmp dup ok
+@c     malloc dup selfdeadlock, lockleak, fdleak, memleak
+@c     tdelete asmalloc, incansist, memleak [no xguargs or asynconsist due to locking]
+@c     free dup selfdeadlock, lockleak, fdleak, memleak
+@c     nss_load_library shlimb, uplugin, asmalloc, sefldeadlock, lockleak, fdleak, memleak
+@c      nss_new_service asmalloc, memleak
+@c       strcmp dup ok
+@c       malloc dup selfdeadlock, lockleak, fdleak, memleak
+@c      strlen dup ok
+@c      stpcpy dup ok
+@c      libc_dlopen shlimb, asmalloc, selfdeadlock, lockleak, fdleak, memleak
+@c      libc_dlsym dup selfdeadlock, lockleak, fdleak, memleak
+@c      *ifct(*nscd_init_cb) uplugin
+@c     stpcpy dup ok
+@c     libc_dlsym dup selfdeadlock, lockleak, fdleak, memleak
+@c     libc_lock_unlock dup ok
+@c    nss_next_action ok
+@c  *fct.l -> _nss_*_getpwuid_r uplugin
+@c  nss_next2 shlimb, uplugin, asmalloc, selfdeadlock, incansist, lockleak, fdleak, memleak
+@c   nss_next_action dup ok
+@c   nss_lookup_function dup shlimb, uplugin, asmalloc, selfdeadlock, incansist, lockleak, fdleak, memleak
+
+@c _nss_files_getpwuid_r glocale, asmalloc, selfdeadlock, lockleak, memleak, fdleak
+@c  libc_lock_lock dup selfdeadlock, lockleak
+@c  internal_setent asmalloc, selfdeadlock, lockleak, memleak, fdleak
+@c   fopen dup asmalloc, selfdeadlock, memleak, fdleak, lockleak
+@c   fileno dup ok
+@c   fcntl dup ok
+@c   fclose dup asmalloc, selfdeadlock, lockleak, memleak, fdleak
+@c   rewind dup lockleak [stream guarded by non-recursive pwent lock]
+@c  internal_getent glocale^
+@c   fgets_unlocked dup ok [stream guarded by non-recursive pwent lock]
+@c   isspace dup glocale^^
+@c   _nss_files_parse_pwent = parse_line ok
+@c    strpbrk dup ok
+@c  internal_endent asmalloc, selfdeadlock, lockleak, memleak, fdleak
+@c   fclose dup asmalloc, selfdeadlock, lockleak, memleak, fdleak
+@c  libc_lock_unlock dup lockleak
+
+@c _nss_nis_getpwuid_r ... not fully reviewed (assumed) oncesafe, selfdeadlock, incansist, lockleak
+@c  yp_get_default_domain selfdeadlock, lockleak
+@c   libc_lock_lock dup selfdeadlock, lockleak
+@c   getdomainname dup ok
+@c   strcmp dup ok
+@c   libc_lock_unlock dup lockleak
+@c  snprintf dup asmalloc, memleak
+@c  yp_match
+@c   do_ypcall_tr(xdr_ypreq_key,xdr_ypresp_val)
+@c    do_ypcall(xdr_ypreq_key,xdr_ypresp_val)
+@c     libc_lock_lock selfdeadlock, lockleak
+@c     strcmp
+@c     yp_bind
+@c     ypclnt_call
+@c      clnt_call
+@c      clnt_perror
+@c     libc_lock_unlock lockleak
+@c     yp_unbind_locked
+@c     yp_unbind
+@c      strcmp dup ok
+@c      calloc dup selfdeadlock, lockleak, fdleak, memleak
+@c      yp_bind_file
+@c       strlen dup ok
+@c       snprintf dup asmalloc, memleak
+@c       open dup fdleak, cancelpt
+@c       pread dup cancelpt
+@c       yp_bind_client_create
+@c       close dup fdleak, cancelpt
+@c      yp_bind_ypbindprog
+@c       clnttcp_create
+@c       clnt_destroy
+@c       clnt_call(xdr_domainname,xdr_ypbind_resp)
+@c       memset dup ok
+@c       yp_bind_client_create
+@c      free dup selfdeadlock, lockleak, fdleak, memleak
+@c     calloc dup selfdeadlock, lockleak, fdleak, memleak
+@c     free dup selfdeadlock, lockleak, fdleak, memleak
+@c    ypprot_err
+@c   memcpy dup ok
+@c   xdr_free(xdr_ypresp_val)
+@c    xdr_ypresp_val
+@c     xdr_ypstat
+@c      xdr_enum
+@c       XDR_PUTLONG
+@c        *x_putlong
+@c       XDR_GETLONG
+@c        *x_getlong
+@c       xdr_long
+@c        XDR_PUTLONG dup
+@c        XDR_GETLONG dup
+@c       xdr_short
+@c        XDR_PUTLONG dup
+@c        XDR_GETLONG dup
+@c     xdr_valdat
+@c      xdr_bytes
+@c       xdr_u_int
+@c        XDR_PUTLONG dup
+@c        XDR_GETLONG dup
+@c       mem_alloc asmalloc, memleak
+@c        malloc dup selfdeadlock, lockleak, fdleak, memleak
+@c       xdr_opaque
+@c        XDR_GETBYTES
+@c         *x_getbytes
+@c        XDR_PUTBYTES
+@c         *x_putbytes
+@c       mem_free asmalloc, memleak
+@c        free dup selfdeadlock, lockleak, fdleak, memleak
+@c  yperr2nss ok
+@c  strchr dup ok
+@c  _nls_default_nss oncesafe, asmalloc, selfdeadlock, incansist, memleak, fdleak, lockleak
+@c   init oncesafe^, asmalloc, selfdeadlock, incansist, memleak, fdleak, lockleak
+@c    fopen dup asmalloc, selfdeadlock, memleak, fdleak, lockleak
+@c    fsetlocking ok [no concurrent uses]
+@c    feof_unlocked dup ok
+@c    getline dup asmalloc, lockleak, incansist, memleak
+@c    isspace dup glocale^^
+@c    strncmp dup ok
+@c    free dup selfdeadlock, memleak, fdleak, lockleak
+@c    fclose dup asmalloc, selfdeadlock, lockleak, memleak, fdleak
+@c  free dup selfdeadlock, memleak, fdleak, lockleak
+@c  mempcpy dup ok
+@c  strncpy dup ok
+@c  isspace dup glocale^^
+@c  _nss_files_parse_pwent ok
 This function is similar to @code{getpwuid} in that it returns
 information about the user whose user ID is @var{uid}.  However, it
 fills the user supplied structure pointed to by @var{result_buf} with
@@ -1568,6 +2076,14 @@ error code @code{ERANGE} is returned and @var{errno} is set to
 @comment pwd.h
 @comment POSIX.1
 @deftypefun {struct passwd *} getpwnam (const char *@var{name})
+@safety{@mtunsafe{staticbuf, glocale}@asunsafe{shlimb, uplugin, asmalloc, selfdeadlock}@acunsafe{incansist, lockleak, fdleak, memleak}}
+@c getpwnam staticbuf, glocale, shlimb, uplugin, asmalloc, selfdeadlock, incansist, lockleak, fdleak, memleak
+@c  libc_lock_lock dup selfdeadlock, lockleak
+@c  malloc dup asmalloc, memleak
+@c  getpwnam_r dup glocale, shlimb, uplugin, asmalloc, selfdeadlock, incansist, lockleak, fdleak, memleak
+@c  realloc dup asmalloc, memleak
+@c  free dup asmalloc, memleak
+@c  libc_lock_unlock dup lockleak
 This function returns a pointer to a statically-allocated structure
 containing information about the user whose user name is @var{name}.
 This structure may be overwritten on subsequent calls to
@@ -1579,6 +2095,25 @@ A null pointer return indicates there is no user named @var{name}.
 @comment pwd.h
 @comment POSIX.1c
 @deftypefun int getpwnam_r (const char *@var{name}, struct passwd *@var{result_buf}, char *@var{buffer}, size_t @var{buflen}, struct passwd **@var{result})
+@safety{@mtsafe{glocale}@asunsafe{shlimb, uplugin, asmalloc, selfdeadlock}@acunsafe{incansist, lockleak, fdleak, memleak}}
+@c getpwnam_r glocale, shlimb, uplugin, asmalloc, selfdeadlock, incansist, lockleak, fdleak, memleak
+@c  nscd_getpwnam_r asmalloc, selfdeadlock, lockleak, fdleak, memleak
+@c   strlen dup ok
+@c   nscd_getpw_r dup asmalloc, selfdeadlock, lockleak, fdleak, memleak
+@c  nss_passwd_lookup2 dup glocale, shlimb, uplugin, asmalloc, selfdeadlock, incansist, lockleak, fdleak, memleak
+@c  *fct.l uplugin
+@c  nss_next2 dup shlimb, uplugin, asmalloc, selfdeadlock, incansist, lockleak, fdleak, memleak
+@c
+@c _nss_files_getpwnam_r glocale, asmalloc, selfdeadlock, lockleak, memleak, fdleak
+@c  libc_lock_lock dup selfdeadlock, lockleak
+@c  internal_setent dup asmalloc, selfdeadlock, lockleak, memleak, fdleak
+@c  internal_getent dup glocale^
+@c  strcmp dup ok
+@c  internal_endent dup asmalloc, selfdeadlock, lockleak, memleak, fdleak
+@c  libc_lock_unlock dup lockleak
+@c
+@c _nss_*_getpwnam_r (assumed) oncesafe, selfdeadlock, incansist, lockleak
+
 This function is similar to @code{getpwnam} in that is returns
 information about the user whose user name is @var{name}.  However, like
 @code{getpwuid_r}, it fills the user supplied buffers in
@@ -1603,6 +2138,16 @@ particular file.
 @comment pwd.h
 @comment SVID
 @deftypefun {struct passwd *} fgetpwent (FILE *@var{stream})
+@safety{@mtunsafe{staticbuf}@asunsafe{asynconsist, selfdeadlock}@acunsafe{incansist, lockleak}}
+@c fgetpwent staticbuf, asynconsist, selfdeadlock, incansist, lockleak
+@c  fgetpos dup asynconsist, lockleak, incansist
+@c  libc_lock_lock dup selfdeadlock, lockleak
+@c  malloc dup asmalloc, memleak
+@c  fgetpwent_r dup asynconsist, incansist, lockleak
+@c  realloc dup asmalloc, memleak
+@c  free dup asmalloc, memleak
+@c  fsetpos dup asynconsist, lockleak, incansist
+@c  libc_lock_unlock dup lockleak
 This function reads the next user entry from @var{stream} and returns a
 pointer to the entry.  The structure is statically allocated and is
 rewritten on subsequent calls to @code{fgetpwent}.  You must copy the
@@ -1615,6 +2160,14 @@ password database file.
 @comment pwd.h
 @comment GNU
 @deftypefun int fgetpwent_r (FILE *@var{stream}, struct passwd *@var{result_buf}, char *@var{buffer}, size_t @var{buflen}, struct passwd **@var{result})
+@safety{@mtsafe{}@asunsafe{asynconsist}@acunsafe{incansist, lockleak}}
+@c fgetpwent_r asynconsist, incansist, lockleak
+@c  flockfile dup lockleak
+@c  fgets_unlocked asynconsist, incansist [no xguargs due to explicit locking]
+@c  feof_unlocked dup ok
+@c  funlockfile dup lockleak
+@c  isspace dup glocale^^
+@c  parse_line dup ok
 This function is similar to @code{fgetpwent} in that it reads the next
 user entry from @var{stream}.  But the result is returned in the
 structure pointed to by @var{result_buf}.  The
@@ -1637,6 +2190,17 @@ The way to scan all the entries in the user database is with
 @comment pwd.h
 @comment SVID, BSD
 @deftypefun void setpwent (void)
+@safety{@mtunsafe{staticbuf, glocale}@asunsafe{shlimb, uplugin, asmalloc, selfdeadlock}@acunsafe{incansist, lockleak, fdleak, memleak}}
+@c setpwent staticbuf, glocale, shlimb, uplugin, asmalloc, selfdeadlock, incansist, lockleak, fdleak, memleak
+@c  libc_lock_lock selfdeadlock, lockleak
+@c  nss_setent(nss_passwd_lookup2) staticbuf, glocale, shlimb, uplugin, asmalloc, selfdeadlock, incansist, lockleak, fdleak, memleak
+@c    ** resolv's res_maybe_init not called here
+@c   setup(nss_passwd_lookup2) glocale, shlimb, uplugin, asmalloc, selfdeadlock, incansist, lockleak, fdleak, memleak
+@c    *lookup_fct = nss_passwd_lookup2 dup glocale, shlimb, uplugin, asmalloc, selfdeadlock, incansist, lockleak, fdleak, memleak
+@c    nss_lookup dup shlimb, uplugin, asmalloc, selfdeadlock, incansist, lockleak, fdleak, memleak
+@c   *fct.f staticbuf, uplugin
+@c   nss_next2 dup shlimb, uplugin, asmalloc, selfdeadlock, incansist, lockleak, fdleak, memleak
+@c  libc_lock_unlock lockleak
 This function initializes a stream which @code{getpwent} and
 @code{getpwent_r} use to read the user database.
 @end deftypefun
@@ -1644,6 +2208,15 @@ This function initializes a stream which @code{getpwent} and
 @comment pwd.h
 @comment POSIX.1
 @deftypefun {struct passwd *} getpwent (void)
+@safety{@mtunsafe{staticbuf, glocale}@asunsafe{shlimb, uplugin, asmalloc, selfdeadlock}@acunsafe{incansist, lockleak, fdleak, memleak}}
+@c getpwent staticbuf, glocale, shlimb, uplugin, asmalloc, selfdeadlock, incansist, lockleak, fdleak, memleak
+@c  libc_lock_lock dup selfdeadlock, lockleak
+@c  nss_getent(getpwent_r) staticbuf, glocale, shlimb, uplugin, asmalloc, selfdeadlock, incansist, lockleak, fdleak, memleak
+@c   malloc dup asmalloc, memleak
+@c   *func = getpwent_r dup staticbuf, glocale, shlimb, uplugin, asmalloc, selfdeadlock, incansist, lockleak, fdleak, memleak
+@c   realloc dup asmalloc, memleak
+@c   free dup asmalloc, memleak
+@c  libc_lock_unlock dup lockleak
 The @code{getpwent} function reads the next entry from the stream
 initialized by @code{setpwent}.  It returns a pointer to the entry.  The
 structure is statically allocated and is rewritten on subsequent calls
@@ -1656,6 +2229,20 @@ A null pointer is returned when no more entries are available.
 @comment pwd.h
 @comment GNU
 @deftypefun int getpwent_r (struct passwd *@var{result_buf}, char *@var{buffer}, size_t @var{buflen}, struct passwd **@var{result})
+@safety{@mtunsafe{staticbuf, glocale}@asunsafe{shlimb, uplugin, asmalloc, selfdeadlock}@acunsafe{incansist, lockleak, fdleak, memleak}}
+@c The static buffer here is not the result_buf, but rather the
+@c variables that keep track of what nss backend we've last used, and
+@c whatever internal state the nss backend uses to keep track of the
+@c last read entry.
+@c getpwent_r staticbuf, glocale, shlimb, uplugin, asmalloc, selfdeadlock, incansist, lockleak, fdleak, memleak
+@c  libc_lock_lock dup selfdeadlock, lockleak
+@c  nss_getent_r(nss_passwd_lookup2) staticbuf, glocale, shlimb, uplugin, asmalloc, selfdeadlock, incansist, lockleak, fdleak, memleak
+@c   setup(nss_passwd_lookup2) dup glocale, shlimb, uplugin, asmalloc, selfdeadlock, incansist, lockleak, fdleak, memleak
+@c   *fct.f staticbuf, uplugin
+@c   nss_next2 dup shlimb, uplugin, asmalloc, selfdeadlock, incansist, lockleak, fdleak, memleak
+@c   nss_lookup dup shlimb, uplugin, asmalloc, selfdeadlock, incansist, lockleak, fdleak, memleak
+@c   *sfct.f staticbuf, uplugin
+@c  libc_lock_unlock dup lockleak
 This function is similar to @code{getpwent} in that it returns the next
 entry from the stream initialized by @code{setpwent}.  Like
 @code{fgetpwent_r}, it uses the user-supplied buffers in
@@ -1668,6 +2255,15 @@ The return values are the same as for @code{fgetpwent_r}.
 @comment pwd.h
 @comment SVID, BSD
 @deftypefun void endpwent (void)
+@safety{@mtunsafe{staticbuf, glocale}@asunsafe{shlimb, uplugin, asmalloc, selfdeadlock}@acunsafe{incansist, lockleak, fdleak, memleak}}
+@c endpwent staticbuf, glocale, shlimb, uplugin, asmalloc, selfdeadlock, incansist, lockleak, fdleak, memleak
+@c  libc_lock_lock selfdeadlock, lockleak
+@c  nss_endent(nss_passwd_lookup2) staticbuf, glocale, shlimb, uplugin, asmalloc, selfdeadlock, incansist, lockleak, fdleak, memleak
+@c    ** resolv's res_maybe_init not called here
+@c   setup(nss_passwd_lookup2) dup glocale, shlimb, uplugin, asmalloc, selfdeadlock, incansist, lockleak, fdleak, memleak
+@c   *fct.f staticbuf, uplugin
+@c   nss_next2 dup shlimb, uplugin, asmalloc, selfdeadlock, incansist, lockleak, fdleak, memleak
+@c  libc_lock_unlock lockleak
 This function closes the internal stream used by @code{getpwent} or
 @code{getpwent_r}.
 @end deftypefun
@@ -1678,6 +2274,9 @@ This function closes the internal stream used by @code{getpwent} or
 @comment pwd.h
 @comment SVID
 @deftypefun int putpwent (const struct passwd *@var{p}, FILE *@var{stream})
+@safety{@mtsafe{glocale}@asunsafe{asynconsist}@acunsafe{lockleak, incansist}}
+@c putpwent glocale, asynconsist, lockleak, incansist
+@c  fprintf dup glocale, asynconsist, lockleak, incansist [no asmalloc, memleak]
 This function writes the user entry @code{*@var{p}} to the stream
 @var{stream}, in the format used for the standard user database
 file.  The return value is zero on success and nonzero on failure.
@@ -1751,6 +2350,9 @@ declared in @file{grp.h}.
 @comment grp.h
 @comment POSIX.1
 @deftypefun {struct group *} getgrgid (gid_t @var{gid})
+@safety{@mtunsafe{staticbuf, glocale}@asunsafe{shlimb, uplugin, asmalloc, selfdeadlock}@acunsafe{incansist, lockleak, fdleak, memleak}}
+@c getgrgid =~ getpwuid dup staticbuf, glocale, shlimb, uplugin, asmalloc, selfdeadlock, incansist, lockleak, fdleak, memleak
+@c  getgrgid_r dup glocale, shlimb, uplugin, asmalloc, selfdeadlock, incansist, lockleak, fdleak, memleak
 This function returns a pointer to a statically-allocated structure
 containing information about the group whose group ID is @var{gid}.
 This structure may be overwritten by subsequent calls to
@@ -1762,6 +2364,26 @@ A null pointer indicates there is no group with ID @var{gid}.
 @comment grp.h
 @comment POSIX.1c
 @deftypefun int getgrgid_r (gid_t @var{gid}, struct group *@var{result_buf}, char *@var{buffer}, size_t @var{buflen}, struct group **@var{result})
+@safety{@mtsafe{glocale}@asunsafe{shlimb, uplugin, asmalloc, selfdeadlock}@acunsafe{incansist, lockleak, fdleak, memleak}}
+@c getgrgid_r =~ getpwuid_r dup glocale, shlimb, uplugin, asmalloc, selfdeadlock, incansist, lockleak, fdleak, memleak
+@c  nscd_getgrgid_r asmalloc, selfdeadlock, lockleak, fdleak, memleak
+@c   itoa_word dup ok
+@c   nscd_getgr_r asmalloc, selfdeadlock, lockleak, fdleak, memleak
+@c    nscd_get_map_ref dup asmalloc, selfdeadlock, lockleak, fdleak, memleak
+@c    nscd_cache_search dup ok
+@c    nscd_open_socket dup fdleak
+@c    readvall ok
+@c     readv dup ok
+@c     memcpy dup ok
+@c      wait_on_socket dup ok
+@c    memcpy dup ok
+@c    readall dup ok
+@c    close_not_cancel_no_status dup fdleak
+@c    nscd_drop_map_ref dup selfdeadlock, lockleak, fdleak, memleak
+@c    nscd_unmap dup selfdeadlock, lockleak, fdleak, memleak
+@c  nss_group_lookup2 =~ nss_passwd_lookup2 dup glocale, shlimb, uplugin, asmalloc, selfdeadlock, incansist, lockleak, fdleak, memleak
+@c  *fct.l -> _nss_*_getgrgid_r uplugin
+@c  nss_next2 dup shlimb, uplugin, asmalloc, selfdeadlock, incansist, lockleak, fdleak, memleak
 This function is similar to @code{getgrgid} in that it returns
 information about the group whose group ID is @var{gid}.  However, it
 fills the user supplied structure pointed to by @var{result_buf} with
@@ -1783,6 +2405,9 @@ error code @code{ERANGE} is returned and @var{errno} is set to
 @comment grp.h
 @comment SVID, BSD
 @deftypefun {struct group *} getgrnam (const char *@var{name})
+@safety{@mtunsafe{staticbuf, glocale}@asunsafe{shlimb, uplugin, asmalloc, selfdeadlock}@acunsafe{incansist, lockleak, fdleak, memleak}}
+@c getgrnam =~ getpwnam dup staticbuf, glocale, shlimb, uplugin, asmalloc, selfdeadlock, incansist, lockleak, fdleak, memleak
+@c  getgrnam_r dup glocale, shlimb, uplugin, asmalloc, selfdeadlock, incansist, lockleak, fdleak, memleak
 This function returns a pointer to a statically-allocated structure
 containing information about the group whose group name is @var{name}.
 This structure may be overwritten by subsequent calls to
@@ -1794,6 +2419,14 @@ A null pointer indicates there is no group named @var{name}.
 @comment grp.h
 @comment POSIX.1c
 @deftypefun int getgrnam_r (const char *@var{name}, struct group *@var{result_buf}, char *@var{buffer}, size_t @var{buflen}, struct group **@var{result})
+@safety{@mtsafe{glocale}@asunsafe{shlimb, uplugin, asmalloc, selfdeadlock}@acunsafe{incansist, lockleak, fdleak, memleak}}
+@c getgrnam_r =~ getpwnam_r dup glocale, shlimb, uplugin, asmalloc, selfdeadlock, incansist, lockleak, fdleak, memleak
+@c  nscd_getgrnam_r asmalloc, selfdeadlock, lockleak, fdleak, memleak
+@c   strlen dup ok
+@c   nscd_getgr_r dup asmalloc, selfdeadlock, lockleak, fdleak, memleak
+@c  nss_group_lookup2 dup glocale, shlimb, uplugin, asmalloc, selfdeadlock, incansist, lockleak, fdleak, memleak
+@c  *fct.l uplugin
+@c  nss_next2 dup shlimb, uplugin, asmalloc, selfdeadlock, incansist, lockleak, fdleak, memleak
 This function is similar to @code{getgrnam} in that is returns
 information about the group whose group name is @var{name}.  Like
 @code{getgrgid_r}, it uses the user supplied buffers in
@@ -1817,6 +2450,16 @@ particular file.
 @comment grp.h
 @comment SVID
 @deftypefun {struct group *} fgetgrent (FILE *@var{stream})
+@safety{@mtunsafe{staticbuf}@asunsafe{asynconsist, selfdeadlock}@acunsafe{incansist, lockleak}}
+@c fgetgrent staticbuf, asynconsist, selfdeadlock, incansist, lockleak
+@c  fgetpos dup asynconsist, lockleak, incansist
+@c  libc_lock_lock dup selfdeadlock, lockleak
+@c  malloc dup asmalloc, memleak
+@c  fgetgrent_r dup asynconsist, incansist, lockleak
+@c  realloc dup asmalloc, memleak
+@c  free dup asmalloc, memleak
+@c  fsetpos dup asynconsist, lockleak, incansist
+@c  libc_lock_unlock dup lockleak
 The @code{fgetgrent} function reads the next entry from @var{stream}.
 It returns a pointer to the entry.  The structure is statically
 allocated and is overwritten on subsequent calls to @code{fgetgrent}.  You
@@ -1830,6 +2473,14 @@ group database file.
 @comment grp.h
 @comment GNU
 @deftypefun int fgetgrent_r (FILE *@var{stream}, struct group *@var{result_buf}, char *@var{buffer}, size_t @var{buflen}, struct group **@var{result})
+@safety{@mtsafe{}@asunsafe{asynconsist}@acunsafe{incansist, lockleak}}
+@c fgetgrent_r asynconsist, incansist, lockleak
+@c  flockfile dup lockleak
+@c  fgets_unlocked asynconsist, incansist [no xguargs due to explicit locking]
+@c  feof_unlocked dup ok
+@c  funlockfile dup lockleak
+@c  isspace dup glocale^^
+@c  parse_line dup ok
 This function is similar to @code{fgetgrent} in that it reads the next
 user entry from @var{stream}.  But the result is returned in the
 structure pointed to by @var{result_buf}.  The first @var{buflen} bytes
@@ -1852,6 +2503,9 @@ The way to scan all the entries in the group database is with
 @comment grp.h
 @comment SVID, BSD
 @deftypefun void setgrent (void)
+@safety{@mtunsafe{staticbuf, glocale}@asunsafe{shlimb, uplugin, asmalloc, selfdeadlock}@acunsafe{incansist, lockleak, fdleak, memleak}}
+@c setgrent =~ setpwent dup staticbuf, glocale, shlimb, uplugin, asmalloc, selfdeadlock, incansist, lockleak, fdleak, memleak
+@c ...*lookup_fct = nss_group_lookup2 dup glocale, shlimb, uplugin, asmalloc, selfdeadlock, incansist, lockleak, fdleak, memleak
 This function initializes a stream for reading from the group data base.
 You use this stream by calling @code{getgrent} or @code{getgrent_r}.
 @end deftypefun
@@ -1859,6 +2513,9 @@ You use this stream by calling @code{getgrent} or @code{getgrent_r}.
 @comment grp.h
 @comment SVID, BSD
 @deftypefun {struct group *} getgrent (void)
+@safety{@mtunsafe{staticbuf, glocale}@asunsafe{shlimb, uplugin, asmalloc, selfdeadlock}@acunsafe{incansist, lockleak, fdleak, memleak}}
+@c getgrent =~ getpwent dup staticbuf, glocale, shlimb, uplugin, asmalloc, selfdeadlock, incansist, lockleak, fdleak, memleak
+@c   *func = getgrent_r dup staticbuf, glocale, shlimb, uplugin, asmalloc, selfdeadlock, incansist, lockleak, fdleak, memleak
 The @code{getgrent} function reads the next entry from the stream
 initialized by @code{setgrent}.  It returns a pointer to the entry.  The
 structure is statically allocated and is overwritten on subsequent calls
@@ -1869,6 +2526,8 @@ wish to save the information.
 @comment grp.h
 @comment GNU
 @deftypefun int getgrent_r (struct group *@var{result_buf}, char *@var{buffer}, size_t @var{buflen}, struct group **@var{result})
+@safety{@mtunsafe{staticbuf, glocale}@asunsafe{shlimb, uplugin, asmalloc, selfdeadlock}@acunsafe{incansist, lockleak, fdleak, memleak}}
+@c getgrent_r =~ getpwent_r dup staticbuf, glocale, shlimb, uplugin, asmalloc, selfdeadlock, incansist, lockleak, fdleak, memleak
 This function is similar to @code{getgrent} in that it returns the next
 entry from the stream initialized by @code{setgrent}.  Like
 @code{fgetgrent_r}, it places the result in user-supplied buffers
@@ -1882,6 +2541,8 @@ value is non-zero and @var{result} contains a null pointer.
 @comment grp.h
 @comment SVID, BSD
 @deftypefun void endgrent (void)
+@safety{@mtunsafe{staticbuf, glocale}@asunsafe{shlimb, uplugin, asmalloc, selfdeadlock}@acunsafe{incansist, lockleak, fdleak, memleak}}
+@c endgrent =~ endpwent dup staticbuf, glocale, shlimb, uplugin, asmalloc, selfdeadlock, incansist, lockleak, fdleak, memleak
 This function closes the internal stream used by @code{getgrent} or
 @code{getgrent_r}.
 @end deftypefun
@@ -1966,6 +2627,40 @@ These functions are declared in @file{netdb.h}.
 @comment netdb.h
 @comment BSD
 @deftypefun int setnetgrent (const char *@var{netgroup})
+@safety{@mtunsafe{staticbuf, glocale}@asunsafe{shlimb, uplugin, asmalloc, selfdeadlock}@acunsafe{incansist, lockleak, fdleak, memleak}}
+@c setnetgrent staticbuf, glocale, shlimb, uplugin, asmalloc, selfdeadlock, incansist, lockleak, fdleak, memleak
+@c  libc_lock_lock dup selfdeadlock, lockleak
+@c  nscd_setnetgrent asmalloc, selfdeadlock, lockleak, fdleak, memleak
+@c   __nscd_setnetgrent asmalloc, selfdeadlock, lockleak, fdleak, memleak
+@c    strlen dup ok
+@c    nscd_get_map_ref dup ok
+@c    nscd_cache_search dup ok
+@c    nscd_open_socket dup fdleak
+@c    malloc dup asmalloc, memleak
+@c    readall dup ok
+@c    free dup asmalloc, memleak
+@c    close_not_cancel_no_status dup fdleak
+@c    nscd_drop_map_ref dup selfdeadlock, lockleak, fdleak, memleak
+@c    nscd_unmap dup selfdeadlock, lockleak, fdleak, memleak
+@c  internal_setnetgrent glocale, shlimb, uplugin, asmalloc, selfdeadlock, incansist, lockleak, fdleak, memleak
+@c   free_memory dup asmalloc, memleak
+@c    free dup asmalloc, memleak
+@c   internal_setnetgrent_reuse glocale, shlimb, uplugin, asmalloc, selfdeadlock, incansist, lockleak, fdleak, memleak
+@c    endnetgrent_hook dup shlimb, uplugin, asmalloc, selfdeadlock, incansist, lockleak, fdleak, memleak
+@c     nss_lookup_function dup shlimb, uplugin, asmalloc, selfdeadlock, incansist, lockleak, fdleak, memleak
+@c     *endfct uplugin
+@c    (netgroup::)setup glocale, shlimb, uplugin, asmalloc, selfdeadlock, incansist, lockleak, fdleak, memleak
+@c     nss_netgroup_lookup dup glocale, shlimb, uplugin, asmalloc, selfdeadlock, incansist, lockleak, fdleak, memleak
+@c      nss_netgroup_lookup2 =~ nss_passwd_lookup2 dup glocale, shlimb, uplugin, asmalloc, selfdeadlock, incansist, lockleak, fdleak, memleak
+@c     nss_lookup dup shlimb, uplugin, asmalloc, selfdeadlock, incansist, lockleak, fdleak, memleak
+@c    *fct.f uplugin
+@c    nss_next2 dup shlimb, uplugin, asmalloc, selfdeadlock, incansist, lockleak, fdleak, memleak
+@c    nss_lookup_function dup shlimb, uplugin, asmalloc, selfdeadlock, incansist, lockleak, fdleak, memleak
+@c    *endfct uplugin
+@c    strlen dup ok
+@c    malloc dup asmalloc, memleak
+@c    memcpy dup ok
+@c  libc_lock_unlock dup lockleak
 A call to this function initializes the internal state of the library to
 allow following calls of the @code{getnetgrent} to iterate over all entries
 in the netgroup with name @var{netgroup}.
@@ -1991,6 +2686,12 @@ the @code{innetgr} function and parts of the implementation of the
 @comment netdb.h
 @comment BSD
 @deftypefun int getnetgrent (char **@var{hostp}, char **@var{userp}, char **@var{domainp})
+@safety{@mtunsafe{staticbuf, glocale}@asunsafe{shlimb, uplugin, asmalloc, selfdeadlock}@acunsafe{incansist, lockleak, fdleak, memleak}}
+@c getnetgrent staticbuf, glocale, shlimb, uplugin, asmalloc, selfdeadlock, incansist, lockleak, fdleak, memleak
+@c   uses unsafely a static buffer allocated within a libc_once call
+@c  allocate (libc_once) asmalloc, memleak
+@c   malloc dup asmalloc, memleak
+@c  getnetgrent_r dup staticbuf, glocale, shlimb, uplugin, asmalloc, selfdeadlock, incansist, lockleak, fdleak, memleak
 This function returns the next unprocessed entry of the currently
 selected netgroup.  The string pointers, in which addresses are passed in
 the arguments @var{hostp}, @var{userp}, and @var{domainp}, will contain
@@ -2006,6 +2707,19 @@ value of @code{0} means no further entries exist or internal errors occurred.
 @comment netdb.h
 @comment GNU
 @deftypefun int getnetgrent_r (char **@var{hostp}, char **@var{userp}, char **@var{domainp}, char *@var{buffer}, size_t @var{buflen})
+@safety{@mtunsafe{staticbuf, glocale}@asunsafe{shlimb, uplugin, asmalloc, selfdeadlock}@acunsafe{incansist, lockleak, fdleak, memleak}}
+@c getnetgrent_r staticbuf, glocale, shlimb, uplugin, asmalloc, selfdeadlock, incansist, lockleak, fdleak, memleak
+@c  libc_lock_lock dup selfdeadlock, lockleak
+@c  internal_getnetgrent_r glocale, shlimb, uplugin, asmalloc, selfdeadlock, incansist, lockleak, fdleak, memleak
+@c   nss_lookup_function dup shlimb, uplugin, asmalloc, selfdeadlock, incansist, lockleak, fdleak, memleak
+@c   *fct uplugin
+@c   nscd_getnetgrent ok
+@c    rawmemchr dup ok
+@c   internal_setnetgrent_reuse dup glocale, shlimb, uplugin, asmalloc, selfdeadlock, incansist, lockleak, fdleak, memleak
+@c   strcmp dup ok
+@c   malloc dup asmalloc, memleak
+@c   memcpy dup ok
+@c  libc_lock_unlock dup lockleak
 This function is similar to @code{getnetgrent} with only one exception:
 the strings the three string pointers @var{hostp}, @var{userp}, and
 @var{domainp} point to, are placed in the buffer of @var{buflen} bytes
@@ -2024,6 +2738,13 @@ SunOS libc does not provide this function.
 @comment netdb.h
 @comment BSD
 @deftypefun void endnetgrent (void)
+@safety{@mtunsafe{staticbuf}@asunsafe{shlimb, uplugin, asmalloc, selfdeadlock}@acunsafe{incansist, lockleak, fdleak, memleak}}
+@c endnetgrent staticbuf, shlimb, uplugin, asmalloc, selfdeadlock, incansist, lockleak, fdleak, memleak
+@c  libc_lock_lock dup selfdeadlock, lockleak
+@c  internal_endnetgrent shlimb, uplugin, asmalloc, selfdeadlock, incansist, lockleak, fdleak, memleak
+@c   endnetgrent_hook dup shlimb, uplugin, asmalloc, selfdeadlock, incansist, lockleak, fdleak, memleak
+@c   free_memory dup asmalloc, memleak
+@c  libc_lock_unlock dup lockleak
 This function frees all buffers which were allocated to process the last
 selected netgroup.  As a result all string pointers returned by calls
 to @code{getnetgrent} are invalid afterwards.
@@ -2039,6 +2760,37 @@ selected netgroup.
 @comment netdb.h
 @comment BSD
 @deftypefun int innetgr (const char *@var{netgroup}, const char *@var{host}, const char *@var{user}, const char *@var{domain})
+@safety{@mtunsafe{staticbuf, glocale}@asunsafe{shlimb, uplugin, asmalloc, selfdeadlock}@acunsafe{incansist, lockleak, fdleak, memleak}}
+@c This function does not use the static data structure that the
+@c *netgrent* ones do, but since each nss must maintains internal state
+@c to support iteration and concurrent iteration will interfere
+@c destructively, we regard this internal state as a static buffer.
+@c getnetgrent_r iteration in each nss backend.
+@c innetgr staticbuf, glocale, shlimb, uplugin, asmalloc, selfdeadlock, incansist, lockleak, fdleak, memleak
+@c  nscd_innetgr selfdeadlock, lockleak, fdleak, memleak
+@c   strlen dup ok
+@c   malloc dup asmalloc, memleak
+@c   stpcpy dup ok
+@c   nscd_get_map_ref dup ok
+@c   nscd_cache_search dup ok
+@c   nscd_open_socket dup fdleak
+@c   close_not_cancel_no_status dup fdleak
+@c   nscd_drop_map_ref dup selfdeadlock, lockleak, fdleak, memleak
+@c   nscd_unmap dup selfdeadlock, lockleak, fdleak, memleak
+@c   free dup asmalloc, memleak
+@c  memset dup ok
+@c  (netgroup::)setup dup glocale, shlimb, uplugin, asmalloc, selfdeadlock, incansist, lockleak, fdleak, memleak
+@c  *setfct.f uplugin
+@c  nss_lookup_function dup shlimb, uplugin, asmalloc, selfdeadlock, incansist, lockleak, fdleak, memleak
+@c  *getfct uplugin
+@c  strcmp dup ok
+@c  strlen dup ok
+@c  malloc dup asmalloc, memleak
+@c  memcpy dup ok
+@c  strcasecmp dup
+@c  *endfct uplugin
+@c  nss_next2 dup shlimb, uplugin, asmalloc, selfdeadlock, incansist, lockleak, fdleak, memleak
+@c  free_memory dup asmalloc, memleak
 This function tests whether the triple specified by the parameters
 @var{hostp}, @var{userp}, and @var{domainp} is part of the netgroup
 @var{netgroup}.  Using this function has the advantage that

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=05f42eb8439fcb88808791526d7d134519d9a968

commit 05f42eb8439fcb88808791526d7d134519d9a968
Author: Alexandre Oliva <aoliva@redhat.com>
Date:   Fri Nov 8 06:08:20 2013 -0200

    MT-, AS- and AC-safety docs: manual/string.texi
    
    for ChangeLog
    
    	* manual/string.texi: Document MTASC-safety properties.

diff --git a/manual/string.texi b/manual/string.texi
index 1e45d9d..24bc67b 100644
--- a/manual/string.texi
+++ b/manual/string.texi
@@ -219,6 +219,7 @@ This function is declared in the header file @file{string.h}.
 @comment string.h
 @comment ISO
 @deftypefun size_t strlen (const char *@var{s})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 The @code{strlen} function returns the length of the null-terminated
 string @var{s} in bytes.  (In other words, it returns the offset of the
 terminating null character within the array.)
@@ -285,6 +286,7 @@ The wide character equivalent is declared in @file{wchar.h}.
 @comment wchar.h
 @comment ISO
 @deftypefun size_t wcslen (const wchar_t *@var{ws})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 The @code{wcslen} function is the wide character equivalent to
 @code{strlen}.  The return value is the number of wide characters in the
 wide character string pointed to by @var{ws} (this is also the offset of
@@ -300,6 +302,7 @@ This function was introduced in @w{Amendment 1} to @w{ISO C90}.
 @comment string.h
 @comment GNU
 @deftypefun size_t strnlen (const char *@var{s}, size_t @var{maxlen})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 The @code{strnlen} function returns the length of the string @var{s} in
 bytes if this length is smaller than @var{maxlen} bytes.  Otherwise it
 returns @var{maxlen}.  Therefore this function is equivalent to
@@ -322,6 +325,7 @@ This function is a GNU extension and is declared in @file{string.h}.
 @comment wchar.h
 @comment GNU
 @deftypefun size_t wcsnlen (const wchar_t *@var{ws}, size_t @var{maxlen})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 @code{wcsnlen} is the wide character equivalent to @code{strnlen}.  The
 @var{maxlen} parameter specifies the maximum number of wide characters.
 
@@ -367,6 +371,7 @@ Functions}).
 @comment string.h
 @comment ISO
 @deftypefun {void *} memcpy (void *restrict @var{to}, const void *restrict @var{from}, size_t @var{size})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 The @code{memcpy} function copies @var{size} bytes from the object
 beginning at @var{from} into the object beginning at @var{to}.  The
 behavior of this function is undefined if the two arrays @var{to} and
@@ -388,6 +393,7 @@ memcpy (new, old, arraysize * sizeof (struct foo));
 @comment wchar.h
 @comment ISO
 @deftypefun {wchar_t *} wmemcpy (wchar_t *restrict @var{wto}, const wchar_t *restrict @var{wfrom}, size_t @var{size})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 The @code{wmemcpy} function copies @var{size} wide characters from the object
 beginning at @var{wfrom} into the object beginning at @var{wto}.  The
 behavior of this function is undefined if the two arrays @var{wto} and
@@ -413,6 +419,7 @@ This function was introduced in @w{Amendment 1} to @w{ISO C90}.
 @comment string.h
 @comment GNU
 @deftypefun {void *} mempcpy (void *restrict @var{to}, const void *restrict @var{from}, size_t @var{size})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 The @code{mempcpy} function is nearly identical to the @code{memcpy}
 function.  It copies @var{size} bytes from the object beginning at
 @code{from} into the object pointed to by @var{to}.  But instead of
@@ -440,6 +447,7 @@ This function is a GNU extension.
 @comment wchar.h
 @comment GNU
 @deftypefun {wchar_t *} wmempcpy (wchar_t *restrict @var{wto}, const wchar_t *restrict @var{wfrom}, size_t @var{size})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 The @code{wmempcpy} function is nearly identical to the @code{wmemcpy}
 function.  It copies @var{size} wide characters from the object
 beginning at @code{wfrom} into the object pointed to by @var{wto}.  But
@@ -468,6 +476,7 @@ This function is a GNU extension.
 @comment string.h
 @comment ISO
 @deftypefun {void *} memmove (void *@var{to}, const void *@var{from}, size_t @var{size})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 @code{memmove} copies the @var{size} bytes at @var{from} into the
 @var{size} bytes at @var{to}, even if those two blocks of space
 overlap.  In the case of overlap, @code{memmove} is careful to copy the
@@ -480,6 +489,7 @@ The value returned by @code{memmove} is the value of @var{to}.
 @comment wchar.h
 @comment ISO
 @deftypefun {wchar_t *} wmemmove (wchar_t *@var{wto}, const wchar_t *@var{wfrom}, size_t @var{size})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 @code{wmemmove} copies the @var{size} wide characters at @var{wfrom}
 into the @var{size} wide characters at @var{wto}, even if those two
 blocks of space overlap.  In the case of overlap, @code{memmove} is
@@ -507,6 +517,7 @@ This function is a GNU extension.
 @comment string.h
 @comment SVID
 @deftypefun {void *} memccpy (void *restrict @var{to}, const void *restrict @var{from}, int @var{c}, size_t @var{size})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 This function copies no more than @var{size} bytes from @var{from} to
 @var{to}, stopping if a byte matching @var{c} is found.  The return
 value is a pointer into @var{to} one byte past where @var{c} was copied,
@@ -517,6 +528,7 @@ or a null pointer if no byte matching @var{c} appeared in the first
 @comment string.h
 @comment ISO
 @deftypefun {void *} memset (void *@var{block}, int @var{c}, size_t @var{size})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 This function copies the value of @var{c} (converted to an
 @code{unsigned char}) into each of the first @var{size} bytes of the
 object beginning at @var{block}.  It returns the value of @var{block}.
@@ -525,6 +537,7 @@ object beginning at @var{block}.  It returns the value of @var{block}.
 @comment wchar.h
 @comment ISO
 @deftypefun {wchar_t *} wmemset (wchar_t *@var{block}, wchar_t @var{wc}, size_t @var{size})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 This function copies the value of @var{wc} into each of the first
 @var{size} wide characters of the object beginning at @var{block}.  It
 returns the value of @var{block}.
@@ -533,6 +546,7 @@ returns the value of @var{block}.
 @comment string.h
 @comment ISO
 @deftypefun {char *} strcpy (char *restrict @var{to}, const char *restrict @var{from})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 This copies characters from the string @var{from} (up to and including
 the terminating null character) into the string @var{to}.  Like
 @code{memcpy}, this function has undefined results if the strings
@@ -542,6 +556,7 @@ overlap.  The return value is the value of @var{to}.
 @comment wchar.h
 @comment ISO
 @deftypefun {wchar_t *} wcscpy (wchar_t *restrict @var{wto}, const wchar_t *restrict @var{wfrom})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 This copies wide characters from the string @var{wfrom} (up to and
 including the terminating null wide character) into the string
 @var{wto}.  Like @code{wmemcpy}, this function has undefined results if
@@ -551,6 +566,7 @@ the strings overlap.  The return value is the value of @var{wto}.
 @comment string.h
 @comment ISO
 @deftypefun {char *} strncpy (char *restrict @var{to}, const char *restrict @var{from}, size_t @var{size})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 This function is similar to @code{strcpy} but always copies exactly
 @var{size} characters into @var{to}.
 
@@ -576,6 +592,7 @@ waste a considerable amount of time copying null characters.
 @comment wchar.h
 @comment ISO
 @deftypefun {wchar_t *} wcsncpy (wchar_t *restrict @var{wto}, const wchar_t *restrict @var{wfrom}, size_t @var{size})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 This function is similar to @code{wcscpy} but always copies exactly
 @var{size} wide characters into @var{wto}.
 
@@ -602,6 +619,7 @@ waste a considerable amount of time copying null wide characters.
 @comment string.h
 @comment SVID
 @deftypefun {char *} strdup (const char *@var{s})
+@safety{@mtsafe{}@asunsafe{asmalloc}@acsafe{memleak}}
 This function copies the null-terminated string @var{s} into a newly
 allocated string.  The string is allocated using @code{malloc}; see
 @ref{Unconstrained Allocation}.  If @code{malloc} cannot allocate space
@@ -612,6 +630,7 @@ returns a pointer to the new string.
 @comment wchar.h
 @comment GNU
 @deftypefun {wchar_t *} wcsdup (const wchar_t *@var{ws})
+@safety{@mtsafe{}@asunsafe{asmalloc}@acsafe{memleak}}
 This function copies the null-terminated wide character string @var{ws}
 into a newly allocated string.  The string is allocated using
 @code{malloc}; see @ref{Unconstrained Allocation}.  If @code{malloc}
@@ -625,6 +644,7 @@ This function is a GNU extension.
 @comment string.h
 @comment GNU
 @deftypefun {char *} strndup (const char *@var{s}, size_t @var{size})
+@safety{@mtsafe{}@asunsafe{asmalloc}@acsafe{memleak}}
 This function is similar to @code{strdup} but always copies at most
 @var{size} characters into the newly allocated string.
 
@@ -642,6 +662,7 @@ terminates the destination string.
 @comment string.h
 @comment Unknown origin
 @deftypefun {char *} stpcpy (char *restrict @var{to}, const char *restrict @var{from})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 This function is like @code{strcpy}, except that it returns a pointer to
 the end of the string @var{to} (that is, the address of the terminating
 null character @code{to + strlen (from)}) rather than the beginning.
@@ -664,6 +685,7 @@ declared in @file{string.h}.
 @comment wchar.h
 @comment GNU
 @deftypefun {wchar_t *} wcpcpy (wchar_t *restrict @var{wto}, const wchar_t *restrict @var{wfrom})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 This function is like @code{wcscpy}, except that it returns a pointer to
 the end of the string @var{wto} (that is, the address of the terminating
 null character @code{wto + strlen (wfrom)}) rather than the beginning.
@@ -679,6 +701,7 @@ The behavior of @code{wcpcpy} is undefined if the strings overlap.
 @comment string.h
 @comment GNU
 @deftypefun {char *} stpncpy (char *restrict @var{to}, const char *restrict @var{from}, size_t @var{size})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 This function is similar to @code{stpcpy} but copies always exactly
 @var{size} characters into @var{to}.
 
@@ -704,6 +727,7 @@ declared in @file{string.h}.
 @comment wchar.h
 @comment GNU
 @deftypefun {wchar_t *} wcpncpy (wchar_t *restrict @var{wto}, const wchar_t *restrict @var{wfrom}, size_t @var{size})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 This function is similar to @code{wcpcpy} but copies always exactly
 @var{wsize} characters into @var{wto}.
 
@@ -731,6 +755,7 @@ Its behavior is undefined if the strings overlap.
 @comment string.h
 @comment GNU
 @deftypefn {Macro} {char *} strdupa (const char *@var{s})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 This macro is similar to @code{strdup} but allocates the new string
 using @code{alloca} instead of @code{malloc} (@pxref{Variable Size
 Automatic}).  This means of course the returned string has the same
@@ -757,6 +782,7 @@ This function is only available if GNU CC is used.
 @comment string.h
 @comment GNU
 @deftypefn {Macro} {char *} strndupa (const char *@var{s}, size_t @var{size})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 This function is similar to @code{strndup} but like @code{strdupa} it
 allocates the new string using @code{alloca}
 @pxref{Variable Size Automatic}.  The same advantages and limitations
@@ -772,6 +798,7 @@ parameter list in a function call.
 @comment string.h
 @comment ISO
 @deftypefun {char *} strcat (char *restrict @var{to}, const char *restrict @var{from})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 The @code{strcat} function is similar to @code{strcpy}, except that the
 characters from @var{from} are concatenated or appended to the end of
 @var{to}, instead of overwriting it.  That is, the first character from
@@ -794,6 +821,7 @@ This function has undefined results if the strings overlap.
 @comment wchar.h
 @comment ISO
 @deftypefun {wchar_t *} wcscat (wchar_t *restrict @var{wto}, const wchar_t *restrict @var{wfrom})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 The @code{wcscat} function is similar to @code{wcscpy}, except that the
 characters from @var{wfrom} are concatenated or appended to the end of
 @var{wto}, instead of overwriting it.  That is, the first character from
@@ -942,6 +970,7 @@ is almost always unnecessary to use @code{strcat}.
 @comment string.h
 @comment ISO
 @deftypefun {char *} strncat (char *restrict @var{to}, const char *restrict @var{from}, size_t @var{size})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 This function is like @code{strcat} except that not more than @var{size}
 characters from @var{from} are appended to the end of @var{to}.  A
 single null character is also always appended to @var{to}, so the total
@@ -968,6 +997,7 @@ The behavior of @code{strncat} is undefined if the strings overlap.
 @comment wchar.h
 @comment ISO
 @deftypefun {wchar_t *} wcsncat (wchar_t *restrict @var{wto}, const wchar_t *restrict @var{wfrom}, size_t @var{size})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 This function is like @code{wcscat} except that not more than @var{size}
 characters from @var{from} are appended to the end of @var{to}.  A
 single null character is also always appended to @var{to}, so the total
@@ -1012,6 +1042,7 @@ hello, wo
 @comment string.h
 @comment BSD
 @deftypefun void bcopy (const void *@var{from}, void *@var{to}, size_t @var{size})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 This is a partially obsolete alternative for @code{memmove}, derived from
 BSD.  Note that it is not quite equivalent to @code{memmove}, because the
 arguments are not in the same order and there is no return value.
@@ -1020,6 +1051,7 @@ arguments are not in the same order and there is no return value.
 @comment string.h
 @comment BSD
 @deftypefun void bzero (void *@var{block}, size_t @var{size})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 This is a partially obsolete alternative for @code{memset}, derived from
 BSD.  Note that it is not as general as @code{memset}, because the only
 value it can store is zero.
@@ -1055,6 +1087,7 @@ All of these functions are declared in the header file @file{string.h}.
 @comment string.h
 @comment ISO
 @deftypefun int memcmp (const void *@var{a1}, const void *@var{a2}, size_t @var{size})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 The function @code{memcmp} compares the @var{size} bytes of memory
 beginning at @var{a1} against the @var{size} bytes of memory beginning
 at @var{a2}.  The value returned has the same sign as the difference
@@ -1068,6 +1101,7 @@ If the contents of the two blocks are equal, @code{memcmp} returns
 @comment wchar.h
 @comment ISO
 @deftypefun int wmemcmp (const wchar_t *@var{a1}, const wchar_t *@var{a2}, size_t @var{size})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 The function @code{wmemcmp} compares the @var{size} wide characters
 beginning at @var{a1} against the @var{size} wide characters beginning
 at @var{a2}.  The value returned is smaller than or larger than zero
@@ -1120,6 +1154,7 @@ you are better off writing a specialized comparison function to compare
 @comment string.h
 @comment ISO
 @deftypefun int strcmp (const char *@var{s1}, const char *@var{s2})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 The @code{strcmp} function compares the string @var{s1} against
 @var{s2}, returning a value that has the same sign as the difference
 between the first differing pair of characters (interpreted as
@@ -1139,6 +1174,7 @@ strings are written in into account.  To get that one has to use
 @comment wchar.h
 @comment ISO
 @deftypefun int wcscmp (const wchar_t *@var{ws1}, const wchar_t *@var{ws2})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 
 The @code{wcscmp} function compares the wide character string @var{ws1}
 against @var{ws2}.  The value returned is smaller than or larger than zero
@@ -1159,6 +1195,11 @@ strings are written in into account.  To get that one has to use
 @comment string.h
 @comment BSD
 @deftypefun int strcasecmp (const char *@var{s1}, const char *@var{s2})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
+@c Although this calls tolower multiple times, it's a macro, and
+@c strcasecmp is optimized so that the locale pointer is read only once.
+@c There are some asm implementations too, for which the single-read
+@c from locale TLS pointers also applies.
 This function is like @code{strcmp}, except that differences in case are
 ignored.  How uppercase and lowercase characters are related is
 determined by the currently selected locale.  In the standard @code{"C"}
@@ -1172,6 +1213,9 @@ regards these characters as parts of the alphabet they do match.
 @comment wchar.h
 @comment GNU
 @deftypefun int wcscasecmp (const wchar_t *@var{ws1}, const wchar_t *@var{ws2})
+@safety{@mtsafe{glocale}@assafe{}@acsafe{}}
+@c Since towlower is not a macro, the locale object may be read multiple
+@c times.
 This function is like @code{wcscmp}, except that differences in case are
 ignored.  How uppercase and lowercase characters are related is
 determined by the currently selected locale.  In the standard @code{"C"}
@@ -1185,6 +1229,7 @@ regards these characters as parts of the alphabet they do match.
 @comment string.h
 @comment ISO
 @deftypefun int strncmp (const char *@var{s1}, const char *@var{s2}, size_t @var{size})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 This function is the similar to @code{strcmp}, except that no more than
 @var{size} characters are compared.  In other words, if the two
 strings are the same in their first @var{size} characters, the
@@ -1194,6 +1239,7 @@ return value is zero.
 @comment wchar.h
 @comment ISO
 @deftypefun int wcsncmp (const wchar_t *@var{ws1}, const wchar_t *@var{ws2}, size_t @var{size})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 This function is the similar to @code{wcscmp}, except that no more than
 @var{size} wide characters are compared.  In other words, if the two
 strings are the same in their first @var{size} wide characters, the
@@ -1203,6 +1249,7 @@ return value is zero.
 @comment string.h
 @comment BSD
 @deftypefun int strncasecmp (const char *@var{s1}, const char *@var{s2}, size_t @var{n})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 This function is like @code{strncmp}, except that differences in case
 are ignored.  Like @code{strcasecmp}, it is locale dependent how
 uppercase and lowercase characters are related.
@@ -1214,6 +1261,7 @@ uppercase and lowercase characters are related.
 @comment wchar.h
 @comment GNU
 @deftypefun int wcsncasecmp (const wchar_t *@var{ws1}, const wchar_t *@var{s2}, size_t @var{n})
+@safety{@mtsafe{glocale}@assafe{}@acsafe{}}
 This function is like @code{wcsncmp}, except that differences in case
 are ignored.  Like @code{wcscasecmp}, it is locale dependent how
 uppercase and lowercase characters are related.
@@ -1247,6 +1295,8 @@ strncmp ("hello, world", "hello, stupid world!!!", 5)
 @comment string.h
 @comment GNU
 @deftypefun int strverscmp (const char *@var{s1}, const char *@var{s2})
+@safety{@mtsafe{glocale}@assafe{}@acsafe{}}
+@c Calls isdigit multiple times, locale may change in between.
 The @code{strverscmp} function compares the string @var{s1} against
 @var{s2}, considering them as holding indices/version numbers.  The
 return value follows the same conventions as found in the
@@ -1297,6 +1347,7 @@ because filenames frequently hold indices/version numbers.
 @comment string.h
 @comment BSD
 @deftypefun int bcmp (const void *@var{a1}, const void *@var{a2}, size_t @var{size})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 This is an obsolete alias for @code{memcmp}, derived from BSD.
 @end deftypefun
 
@@ -1343,6 +1394,9 @@ transformed strings with @code{strcmp} or @code{wcscmp}.
 @comment string.h
 @comment ISO
 @deftypefun int strcoll (const char *@var{s1}, const char *@var{s2})
+@safety{@mtsafe{}@asunsafe{asmalloc}@acunsafe{memleak}}
+@c Calls strcoll_l with the current locale, which dereferences only the
+@c LC_COLLATE data pointer.
 The @code{strcoll} function is similar to @code{strcmp} but uses the
 collating sequence of the current locale for collation (the
 @code{LC_COLLATE} locale).
@@ -1351,6 +1405,8 @@ collating sequence of the current locale for collation (the
 @comment wchar.h
 @comment ISO
 @deftypefun int wcscoll (const wchar_t *@var{ws1}, const wchar_t *@var{ws2})
+@safety{@mtsafe{}@asunsafe{asmalloc}@acunsafe{memleak}}
+@c Same as strcoll, but calling wcscoll_l.
 The @code{wcscoll} function is similar to @code{wcscmp} but uses the
 collating sequence of the current locale for collation (the
 @code{LC_COLLATE} locale).
@@ -1391,6 +1447,7 @@ sort_strings (char **array, int nstrings)
 @comment string.h
 @comment ISO
 @deftypefun size_t strxfrm (char *restrict @var{to}, const char *restrict @var{from}, size_t @var{size})
+@safety{@mtsafe{}@asunsafe{asmalloc}@acsafe{memleak}}
 The function @code{strxfrm} transforms the string @var{from} using the
 collation transformation determined by the locale currently selected for
 collation, and stores the transformed string in the array @var{to}.  Up
@@ -1420,6 +1477,7 @@ what size the allocated array should be.  It does not matter what
 @comment wchar.h
 @comment ISO
 @deftypefun size_t wcsxfrm (wchar_t *restrict @var{wto}, const wchar_t *@var{wfrom}, size_t @var{size})
+@safety{@mtsafe{}@asunsafe{asmalloc}@acsafe{memleak}}
 The function @code{wcsxfrm} transforms wide character string @var{wfrom}
 using the collation transformation determined by the locale currently
 selected for collation, and stores the transformed string in the array
@@ -1579,6 +1637,7 @@ declared in the header file @file{string.h}.
 @comment string.h
 @comment ISO
 @deftypefun {void *} memchr (const void *@var{block}, int @var{c}, size_t @var{size})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 This function finds the first occurrence of the byte @var{c} (converted
 to an @code{unsigned char}) in the initial @var{size} bytes of the
 object beginning at @var{block}.  The return value is a pointer to the
@@ -1588,6 +1647,7 @@ located byte, or a null pointer if no match was found.
 @comment wchar.h
 @comment ISO
 @deftypefun {wchar_t *} wmemchr (const wchar_t *@var{block}, wchar_t @var{wc}, size_t @var{size})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 This function finds the first occurrence of the wide character @var{wc}
 in the initial @var{size} wide characters of the object beginning at
 @var{block}.  The return value is a pointer to the located wide
@@ -1597,6 +1657,7 @@ character, or a null pointer if no match was found.
 @comment string.h
 @comment GNU
 @deftypefun {void *} rawmemchr (const void *@var{block}, int @var{c})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 Often the @code{memchr} function is used with the knowledge that the
 byte @var{c} is available in the memory block specified by the
 parameters.  But this means that the @var{size} parameter is not really
@@ -1627,6 +1688,7 @@ This function is a GNU extension.
 @comment string.h
 @comment GNU
 @deftypefun {void *} memrchr (const void *@var{block}, int @var{c}, size_t @var{size})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 The function @code{memrchr} is like @code{memchr}, except that it searches
 backwards from the end of the block defined by @var{block} and @var{size}
 (instead of forwards from the front).
@@ -1637,6 +1699,7 @@ This function is a GNU extension.
 @comment string.h
 @comment ISO
 @deftypefun {char *} strchr (const char *@var{string}, int @var{c})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 The @code{strchr} function finds the first occurrence of the character
 @var{c} (converted to a @code{char}) in the null-terminated string
 beginning at @var{string}.  The return value is a pointer to the located
@@ -1663,6 +1726,7 @@ need that information, it is better (but less portable) to use
 @comment wchar.h
 @comment ISO
 @deftypefun {wchar_t *} wcschr (const wchar_t *@var{wstring}, int @var{wc})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 The @code{wcschr} function finds the first occurrence of the wide
 character @var{wc} in the null-terminated wide character string
 beginning at @var{wstring}.  The return value is a pointer to the
@@ -1678,6 +1742,7 @@ to use @code{wcschrnul} in this case, though.
 @comment string.h
 @comment GNU
 @deftypefun {char *} strchrnul (const char *@var{string}, int @var{c})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 @code{strchrnul} is the same as @code{strchr} except that if it does
 not find the character, it returns a pointer to string's terminating
 null character rather than a null pointer.
@@ -1688,6 +1753,7 @@ This function is a GNU extension.
 @comment wchar.h
 @comment GNU
 @deftypefun {wchar_t *} wcschrnul (const wchar_t *@var{wstring}, wchar_t @var{wc})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 @code{wcschrnul} is the same as @code{wcschr} except that if it does not
 find the wide character, it returns a pointer to wide character string's
 terminating null wide character rather than a null pointer.
@@ -1723,6 +1789,7 @@ actually is faster.
 @comment string.h
 @comment ISO
 @deftypefun {char *} strrchr (const char *@var{string}, int @var{c})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 The function @code{strrchr} is like @code{strchr}, except that it searches
 backwards from the end of the string @var{string} (instead of forwards
 from the front).
@@ -1737,6 +1804,7 @@ strrchr ("hello, world", 'l')
 @comment wchar.h
 @comment ISO
 @deftypefun {wchar_t *} wcsrchr (const wchar_t *@var{wstring}, wchar_t @var{c})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 The function @code{wcsrchr} is like @code{wcschr}, except that it searches
 backwards from the end of the string @var{wstring} (instead of forwards
 from the front).
@@ -1745,6 +1813,7 @@ from the front).
 @comment string.h
 @comment ISO
 @deftypefun {char *} strstr (const char *@var{haystack}, const char *@var{needle})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 This is like @code{strchr}, except that it searches @var{haystack} for a
 substring @var{needle} rather than just a single character.  It
 returns a pointer into the string @var{haystack} that is the first
@@ -1763,6 +1832,7 @@ strstr ("hello, world", "wo")
 @comment wchar.h
 @comment ISO
 @deftypefun {wchar_t *} wcsstr (const wchar_t *@var{haystack}, const wchar_t *@var{needle})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 This is like @code{wcschr}, except that it searches @var{haystack} for a
 substring @var{needle} rather than just a single wide character.  It
 returns a pointer into the string @var{haystack} that is the first wide
@@ -1773,6 +1843,7 @@ character of the substring, or a null pointer if no match was found.  If
 @comment wchar.h
 @comment XPG
 @deftypefun {wchar_t *} wcswcs (const wchar_t *@var{haystack}, const wchar_t *@var{needle})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 @code{wcswcs} is an deprecated alias for @code{wcsstr}.  This is the
 name originally used in the X/Open Portability Guide before the
 @w{Amendment 1} to @w{ISO C90} was published.
@@ -1782,6 +1853,9 @@ name originally used in the X/Open Portability Guide before the
 @comment string.h
 @comment GNU
 @deftypefun {char *} strcasestr (const char *@var{haystack}, const char *@var{needle})
+@safety{@mtsafe{glocale}@assafe{}@acsafe{}}
+@c There may be multiple calls of strncasecmp, each accessing the locale
+@c object independently.
 This is like @code{strstr}, except that it ignores case in searching for
 the substring.   Like @code{strcasecmp}, it is locale dependent how
 uppercase and lowercase characters are related.
@@ -1800,6 +1874,7 @@ strcasestr ("hello, World", "wo")
 @comment string.h
 @comment GNU
 @deftypefun {void *} memmem (const void *@var{haystack}, size_t @var{haystack-len},@*const void *@var{needle}, size_t @var{needle-len})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 This is like @code{strstr}, but @var{needle} and @var{haystack} are byte
 arrays rather than null-terminated strings.  @var{needle-len} is the
 length of @var{needle} and @var{haystack-len} is the length of
@@ -1811,6 +1886,7 @@ This function is a GNU extension.
 @comment string.h
 @comment ISO
 @deftypefun size_t strspn (const char *@var{string}, const char *@var{skipset})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 The @code{strspn} (``string span'') function returns the length of the
 initial substring of @var{string} that consists entirely of characters that
 are members of the set specified by the string @var{skipset}.  The order
@@ -1831,6 +1907,7 @@ separately.  The function is not locale-dependent.
 @comment wchar.h
 @comment ISO
 @deftypefun size_t wcsspn (const wchar_t *@var{wstring}, const wchar_t *@var{skipset})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 The @code{wcsspn} (``wide character string span'') function returns the
 length of the initial substring of @var{wstring} that consists entirely
 of wide characters that are members of the set specified by the string
@@ -1841,6 +1918,7 @@ important.
 @comment string.h
 @comment ISO
 @deftypefun size_t strcspn (const char *@var{string}, const char *@var{stopset})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 The @code{strcspn} (``string complement span'') function returns the length
 of the initial substring of @var{string} that consists entirely of characters
 that are @emph{not} members of the set specified by the string @var{stopset}.
@@ -1862,6 +1940,7 @@ separately.  The function is not locale-dependent.
 @comment wchar.h
 @comment ISO
 @deftypefun size_t wcscspn (const wchar_t *@var{wstring}, const wchar_t *@var{stopset})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 The @code{wcscspn} (``wide character string complement span'') function
 returns the length of the initial substring of @var{wstring} that
 consists entirely of wide characters that are @emph{not} members of the
@@ -1873,6 +1952,7 @@ the set @var{stopset}.)
 @comment string.h
 @comment ISO
 @deftypefun {char *} strpbrk (const char *@var{string}, const char *@var{stopset})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 The @code{strpbrk} (``string pointer break'') function is related to
 @code{strcspn}, except that it returns a pointer to the first character
 in @var{string} that is a member of the set @var{stopset} instead of the
@@ -1897,6 +1977,7 @@ separately.  The function is not locale-dependent.
 @comment wchar.h
 @comment ISO
 @deftypefun {wchar_t *} wcspbrk (const wchar_t *@var{wstring}, const wchar_t *@var{stopset})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 The @code{wcspbrk} (``wide character string pointer break'') function is
 related to @code{wcscspn}, except that it returns a pointer to the first
 wide character in @var{wstring} that is a member of the set
@@ -1910,6 +1991,7 @@ returns a null pointer if no such character from @var{stopset} is found.
 @comment string.h
 @comment BSD
 @deftypefun {char *} index (const char *@var{string}, int @var{c})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 @code{index} is another name for @code{strchr}; they are exactly the same.
 New code should always use @code{strchr} since this name is defined in
 @w{ISO C} while @code{index} is a BSD invention which never was available
@@ -1919,6 +2001,7 @@ on @w{System V} derived systems.
 @comment string.h
 @comment BSD
 @deftypefun {char *} rindex (const char *@var{string}, int @var{c})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 @code{rindex} is another name for @code{strrchr}; they are exactly the same.
 New code should always use @code{strrchr} since this name is defined in
 @w{ISO C} while @code{rindex} is a BSD invention which never was available
@@ -1940,6 +2023,7 @@ in the header file @file{string.h}.
 @comment string.h
 @comment ISO
 @deftypefun {char *} strtok (char *restrict @var{newstring}, const char *restrict @var{delimiters})
+@safety{@mtunsafe{staticbuf}@asunsafe{staticbuf}@acsafe{}}
 A string can be split into tokens by making a series of calls to the
 function @code{strtok}.
 
@@ -1978,7 +2062,8 @@ separately.  The function is not locale-dependent.
 
 @comment wchar.h
 @comment ISO
-@deftypefun {wchar_t *} wcstok (wchar_t *@var{newstring}, const wchar_t *@var{delimiters})
+@deftypefun {wchar_t *} wcstok (wchar_t *@var{newstring}, const wchar_t *@var{delimiters}, wchat_t **@var{save_ptr})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 A string can be split into tokens by making a series of calls to the
 function @code{wcstok}.
 
@@ -1986,11 +2071,8 @@ The string to be split up is passed as the @var{newstring} argument on
 the first call only.  The @code{wcstok} function uses this to set up
 some internal state information.  Subsequent calls to get additional
 tokens from the same wide character string are indicated by passing a
-null pointer as the @var{newstring} argument.  Calling @code{wcstok}
-with another non-null @var{newstring} argument reinitializes the state
-information.  It is guaranteed that no other library function ever calls
-@code{wcstok} behind your back (which would mess up this internal state
-information).
+null pointer as the @var{newstring} argument, which causes the pointer
+previously stored in @var{save_ptr} to be used instead.
 
 The @var{delimiters} argument is a wide character string that specifies
 a set of delimiters that may surround the token being extracted.  All
@@ -1999,8 +2081,10 @@ The first wide character that is @emph{not} a member of this set of
 delimiters marks the beginning of the next token.  The end of the token
 is found by looking for the next wide character that is a member of the
 delimiter set.  This wide character in the original wide character
-string @var{newstring} is overwritten by a null wide character, and the
-pointer to the beginning of the token in @var{newstring} is returned.
+string @var{newstring} is overwritten by a null wide character, the
+pointer past the overwritten wide character is saved in @var{save_ptr},
+and the pointer to the beginning of the token in @var{newstring} is
+returned.
 
 On the next call to @code{wcstok}, the searching begins at the next
 wide character beyond the one that marked the end of the previous token.
@@ -2010,11 +2094,6 @@ same on every call in a series of calls to @code{wcstok}.
 If the end of the wide character string @var{newstring} is reached, or
 if the remainder of string consists only of delimiter wide characters,
 @code{wcstok} returns a null pointer.
-
-Note that ``character'' is here used in the sense of byte.  In a string
-using a multibyte character encoding (abstract) character consisting of
-more than one byte are not treated as an entity.  Each byte is treated
-separately.  The function is not locale-dependent.
 @end deftypefun
 
 @strong{Warning:} Since @code{strtok} and @code{wcstok} alter the string
@@ -2039,7 +2118,7 @@ does not have as its purpose the modification of a certain data
 structure, then it is error-prone to modify the data structure
 temporarily.
 
-The functions @code{strtok} and @code{wcstok} are not reentrant.
+The function @code{strtok} is not reentrant, whereas @code{wcstok} is.
 @xref{Nonreentrancy}, for a discussion of where and why reentrancy is
 important.
 
@@ -2075,13 +2154,15 @@ available for multibyte character strings.
 @comment string.h
 @comment POSIX
 @deftypefun {char *} strtok_r (char *@var{newstring}, const char *@var{delimiters}, char **@var{save_ptr})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 Just like @code{strtok}, this function splits the string into several
 tokens which can be accessed by successive calls to @code{strtok_r}.
-The difference is that the information about the next token is stored in
-the space pointed to by the third argument, @var{save_ptr}, which is a
-pointer to a string pointer.  Calling @code{strtok_r} with a null
-pointer for @var{newstring} and leaving @var{save_ptr} between the calls
-unchanged does the job without hindering reentrancy.
+The difference is that, as in @code{wcstok}, the information about the
+next token is stored in the space pointed to by the third argument,
+@var{save_ptr}, which is a pointer to a string pointer.  Calling
+@code{strtok_r} with a null pointer for @var{newstring} and leaving
+@var{save_ptr} between the calls unchanged does the job without
+hindering reentrancy.
 
 This function is defined in POSIX.1 and can be found on many systems
 which support multi-threading.
@@ -2090,6 +2171,7 @@ which support multi-threading.
 @comment string.h
 @comment BSD
 @deftypefun {char *} strsep (char **@var{string_ptr}, const char *@var{delimiter})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 This function has a similar functionality as @code{strtok_r} with the
 @var{newstring} argument replaced by the @var{save_ptr} argument.  The
 initialization of the moving pointer has to be done by the user.
@@ -2141,6 +2223,7 @@ token = strsep (&running, delimiters);    /* token => NULL */
 @comment string.h
 @comment GNU
 @deftypefun {char *} basename (const char *@var{filename})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 The GNU version of the @code{basename} function returns the last
 component of the path in @var{filename}.  This function is the preferred
 usage, since it does not modify the argument, @var{filename}, and
@@ -2176,6 +2259,7 @@ on different systems.
 @comment libgen.h
 @comment XPG
 @deftypefun {char *} basename (const char *@var{path})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 This is the standard XPG defined @code{basename}. It is similar in
 spirit to the GNU version, but may modify the @var{path} by removing
 trailing '/' characters.  If the @var{path} is made up entirely of '/'
@@ -2211,6 +2295,7 @@ main (int argc, char *argv[])
 @comment libgen.h
 @comment XPG
 @deftypefun {char *} dirname (char *@var{path})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 The @code{dirname} function is the compliment to the XPG version of
 @code{basename}.  It returns the parent directory of the file specified
 by @var{path}.  If @var{path} is @code{NULL}, an empty string, or
@@ -2233,6 +2318,8 @@ The prototype for this function is in @file{string.h}.
 @comment string.h
 @comment GNU
 @deftypefun {char *} strfry (char *@var{string})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
+@c Calls initstate_r, time, getpid, strlen, and random_r.
 
 @code{strfry} creates a pseudorandom anagram of a string, replacing the
 input with the anagram in place.  For each position in the string,
@@ -2268,6 +2355,7 @@ This function is declared in @file{string.h}.
 @comment string.h
 @comment GNU
 @deftypefun {void *} memfrob (void *@var{mem}, size_t @var{length})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 
 @code{memfrob} transforms (frobnicates) each byte of the data structure
 at @var{mem}, which is @var{length} bytes long, by bitwise exclusive
@@ -2298,6 +2386,7 @@ this task.
 @comment stdlib.h
 @comment XPG
 @deftypefun {char *} l64a (long int @var{n})
+@safety{@mtunsafe{staticbuf}@asunsafe{staticbuf}@acsafe{}}
 This function encodes a 32-bit input value using characters from the
 basic character set.  It returns a pointer to a 7 character buffer which
 contains an encoded version of @var{n}.  To encode a series of bytes the
@@ -2373,6 +2462,7 @@ used.
 @comment stdlib.h
 @comment XPG
 @deftypefun {long int} a64l (const char *@var{string})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 The parameter @var{string} should contain a string which was produced by
 a call to @code{l64a}.  The function processes at least 6 characters of
 this string, and decodes the characters it finds according to the table
@@ -2459,6 +2549,7 @@ These functions are declared in the standard include file @file{argz.h}.
 @comment argz.h
 @comment GNU
 @deftypefun {error_t} argz_create (char *const @var{argv}[], char **@var{argz}, size_t *@var{argz_len})
+@safety{@mtsafe{}@asunsafe{asmalloc}@acsafe{memleak}}
 The @code{argz_create} function converts the Unix-style argument vector
 @var{argv} (a vector of pointers to normal C strings, terminated by
 @code{(char *)0}; @pxref{Program Arguments}) into an argz vector with
@@ -2468,6 +2559,7 @@ the same elements, which is returned in @var{argz} and @var{argz_len}.
 @comment argz.h
 @comment GNU
 @deftypefun {error_t} argz_create_sep (const char *@var{string}, int @var{sep}, char **@var{argz}, size_t *@var{argz_len})
+@safety{@mtsafe{}@asunsafe{asmalloc}@acsafe{memleak}}
 The @code{argz_create_sep} function converts the null-terminated string
 @var{string} into an argz vector (returned in @var{argz} and
 @var{argz_len}) by splitting it into elements at every occurrence of the
@@ -2477,6 +2569,7 @@ character @var{sep}.
 @comment argz.h
 @comment GNU
 @deftypefun {size_t} argz_count (const char *@var{argz}, size_t @var{arg_len})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 Returns the number of elements in the argz vector @var{argz} and
 @var{argz_len}.
 @end deftypefun
@@ -2484,6 +2577,7 @@ Returns the number of elements in the argz vector @var{argz} and
 @comment argz.h
 @comment GNU
 @deftypefun {void} argz_extract (const char *@var{argz}, size_t @var{argz_len}, char **@var{argv})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 The @code{argz_extract} function converts the argz vector @var{argz} and
 @var{argz_len} into a Unix-style argument vector stored in @var{argv},
 by putting pointers to every element in @var{argz} into successive
@@ -2501,6 +2595,7 @@ still active.  This function is useful for passing the elements in
 @comment argz.h
 @comment GNU
 @deftypefun {void} argz_stringify (char *@var{argz}, size_t @var{len}, int @var{sep})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 The @code{argz_stringify} converts @var{argz} into a normal string with
 the elements separated by the character @var{sep}, by replacing each
 @code{'\0'} inside @var{argz} (except the last one, which terminates the
@@ -2511,6 +2606,8 @@ readable manner.
 @comment argz.h
 @comment GNU
 @deftypefun {error_t} argz_add (char **@var{argz}, size_t *@var{argz_len}, const char *@var{str})
+@safety{@mtsafe{}@asunsafe{asmalloc}@acsafe{memleak}}
+@c Calls strlen and argz_append.
 The @code{argz_add} function adds the string @var{str} to the end of the
 argz vector @code{*@var{argz}}, and updates @code{*@var{argz}} and
 @code{*@var{argz_len}} accordingly.
@@ -2519,6 +2616,7 @@ argz vector @code{*@var{argz}}, and updates @code{*@var{argz}} and
 @comment argz.h
 @comment GNU
 @deftypefun {error_t} argz_add_sep (char **@var{argz}, size_t *@var{argz_len}, const char *@var{str}, int @var{delim})
+@safety{@mtsafe{}@asunsafe{asmalloc}@acsafe{memleak}}
 The @code{argz_add_sep} function is similar to @code{argz_add}, but
 @var{str} is split into separate elements in the result at occurrences of
 the character @var{delim}.  This is useful, for instance, for
@@ -2529,6 +2627,7 @@ a value of @code{':'} for @var{delim}.
 @comment argz.h
 @comment GNU
 @deftypefun {error_t} argz_append (char **@var{argz}, size_t *@var{argz_len}, const char *@var{buf}, size_t @var{buf_len})
+@safety{@mtsafe{}@asunsafe{asmalloc}@acsafe{memleak}}
 The @code{argz_append} function appends @var{buf_len} bytes starting at
 @var{buf} to the argz vector @code{*@var{argz}}, reallocating
 @code{*@var{argz}} to accommodate it, and adding @var{buf_len} to
@@ -2538,6 +2637,8 @@ The @code{argz_append} function appends @var{buf_len} bytes starting at
 @comment argz.h
 @comment GNU
 @deftypefun {void} argz_delete (char **@var{argz}, size_t *@var{argz_len}, char *@var{entry})
+@safety{@mtsafe{}@asunsafe{asmalloc}@acsafe{memleak}}
+@c Calls free if no argument is left.
 If @var{entry} points to the beginning of one of the elements in the
 argz vector @code{*@var{argz}}, the @code{argz_delete} function will
 remove this entry and reallocate @code{*@var{argz}}, modifying
@@ -2549,6 +2650,8 @@ pointers into argz vectors such as @var{entry} will then become invalid.
 @comment argz.h
 @comment GNU
 @deftypefun {error_t} argz_insert (char **@var{argz}, size_t *@var{argz_len}, char *@var{before}, const char *@var{entry})
+@safety{@mtsafe{}@asunsafe{asmalloc}@acsafe{memleak}}
+@c Calls argz_add or realloc and memmove.
 The @code{argz_insert} function inserts the string @var{entry} into the
 argz vector @code{*@var{argz}} at a point just before the existing
 element pointed to by @var{before}, reallocating @code{*@var{argz}} and
@@ -2562,6 +2665,7 @@ is @code{0}, @var{entry} is added to the end instead (as if by
 @comment argz.h
 @comment GNU
 @deftypefun {char *} argz_next (const char *@var{argz}, size_t @var{argz_len}, const char *@var{entry})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 The @code{argz_next} function provides a convenient way of iterating
 over the elements in the argz vector @var{argz}.  It returns a pointer
 to the next element in @var{argz} after the element @var{entry}, or
@@ -2595,6 +2699,7 @@ invariant is maintained for argz vectors created by the functions here.
 @comment argz.h
 @comment GNU
 @deftypefun error_t argz_replace (@w{char **@var{argz}, size_t *@var{argz_len}}, @w{const char *@var{str}, const char *@var{with}}, @w{unsigned *@var{replace_count}})
+@safety{@mtsafe{}@asunsafe{asmalloc}@acsafe{memleak}}
 Replace any occurrences of the string @var{str} in @var{argz} with
 @var{with}, reallocating @var{argz} as necessary.  If
 @var{replace_count} is non-zero, @code{*@var{replace_count}} will be
@@ -2630,6 +2735,7 @@ These functions are declared in the standard include file @file{envz.h}.
 @comment envz.h
 @comment GNU
 @deftypefun {char *} envz_entry (const char *@var{envz}, size_t @var{envz_len}, const char *@var{name})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 The @code{envz_entry} function finds the entry in @var{envz} with the name
 @var{name}, and returns a pointer to the whole entry---that is, the argz
 element which begins with @var{name} followed by a @code{'='} character.  If
@@ -2639,6 +2745,7 @@ there is no entry with that name, @code{0} is returned.
 @comment envz.h
 @comment GNU
 @deftypefun {char *} envz_get (const char *@var{envz}, size_t @var{envz_len}, const char *@var{name})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 The @code{envz_get} function finds the entry in @var{envz} with the name
 @var{name} (like @code{envz_entry}), and returns a pointer to the value
 portion of that entry (following the @code{'='}).  If there is no entry with
@@ -2648,6 +2755,9 @@ that name (or only a null entry), @code{0} is returned.
 @comment envz.h
 @comment GNU
 @deftypefun {error_t} envz_add (char **@var{envz}, size_t *@var{envz_len}, const char *@var{name}, const char *@var{value})
+@safety{@mtsafe{}@asunsafe{asmalloc}@acsafe{memleak}}
+@c Calls envz_remove, which calls enz_entry and argz_delete, and then
+@c argz_add or equivalent code that reallocs and appends name=value.
 The @code{envz_add} function adds an entry to @code{*@var{envz}}
 (updating @code{*@var{envz}} and @code{*@var{envz_len}}) with the name
 @var{name}, and value @var{value}.  If an entry with the same name
@@ -2659,6 +2769,7 @@ already exists in @var{envz}, it is removed first.  If @var{value} is
 @comment envz.h
 @comment GNU
 @deftypefun {error_t} envz_merge (char **@var{envz}, size_t *@var{envz_len}, const char *@var{envz2}, size_t @var{envz2_len}, int @var{override})
+@safety{@mtsafe{}@asunsafe{asmalloc}@acsafe{memleak}}
 The @code{envz_merge} function adds each entry in @var{envz2} to @var{envz},
 as if with @code{envz_add}, updating @code{*@var{envz}} and
 @code{*@var{envz_len}}.  If @var{override} is true, then values in @var{envz2}
@@ -2672,6 +2783,10 @@ being added to @var{envz}, if @var{override} is false.
 @comment envz.h
 @comment GNU
 @deftypefun {void} envz_strip (char **@var{envz}, size_t *@var{envz_len})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 The @code{envz_strip} function removes any null entries from @var{envz},
 updating @code{*@var{envz}} and @code{*@var{envz_len}}.
 @end deftypefun
+
+@c FIXME this are undocumented:
+@c strcasecmp_l @safety{@mtsafe{}@assafe{}@acsafe{}} see strcasecmp

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=7d7b2b98782f7a0ed92ffe62213eb9a9cd1cf630

commit 7d7b2b98782f7a0ed92ffe62213eb9a9cd1cf630
Author: Alexandre Oliva <aoliva@redhat.com>
Date:   Fri Nov 8 06:08:20 2013 -0200

    MT-, AS- and AC-safety docs: manual/stdio.texi
    
    for  ChangeLog
    
    	* manual/stdio.texi: Document MTASC-safety properties.

diff --git a/manual/stdio.texi b/manual/stdio.texi
index 30630ca..20305b6 100644
--- a/manual/stdio.texi
+++ b/manual/stdio.texi
@@ -148,6 +148,8 @@ Everything described in this section is declared in the header file
 @comment stdio.h
 @comment ISO
 @deftypefun {FILE *} fopen (const char *@var{filename}, const char *@var{opentype})
+@safety{@mtsafe{}@asunsafe{asmalloc, selfdeadlock}@acunsafe{memleak, fdleak, lockleak}}
+@c fopen may leak the list lock if cancelled within _IO_link_in.
 The @code{fopen} function opens a stream for I/O to the file
 @var{filename}, and returns a pointer to the stream.
 
@@ -265,6 +267,7 @@ Locks}.
 @comment stdio.h
 @comment Unix98
 @deftypefun {FILE *} fopen64 (const char *@var{filename}, const char *@var{opentype})
+@safety{@mtsafe{}@asunsafe{asmalloc, selfdeadlock}@acsafe{memleak, fdleak, lockleak}}
 This function is similar to @code{fopen} but the stream it returns a
 pointer for is opened using @code{open64}.  Therefore this stream can be
 used even on files larger than @math{2^31} bytes on 32 bit machines.
@@ -294,6 +297,16 @@ resource limit; @pxref{Limits on Resources}.
 @comment stdio.h
 @comment ISO
 @deftypefun {FILE *} freopen (const char *@var{filename}, const char *@var{opentype}, FILE *@var{stream})
+@safety{@mtsafe{}@asunsafe{asynconsist}@acunsafe{incansist, fdleak}}
+@c Like most I/O operations, this one is guarded by a recursive lock,
+@c released even upon cancellation, but cancellation may leak file
+@c descriptors and leave the stream in an inconsistent state (e.g.,
+@c still bound to the closed descriptor).  Also, if the stream is
+@c part-way through a significant update (say running freopen) when a
+@c signal handler calls freopen again on the same stream, the result is
+@c likely to be an inconsistent stream, and the possibility of closing
+@c twice file descriptor number that the stream used to use, the second
+@c time when it might have already been reused by another thread.
 This function is like a combination of @code{fclose} and @code{fopen}.
 It first closes the stream referred to by @var{stream}, ignoring any
 errors that are detected in the process.  (Because errors are ignored,
@@ -320,6 +333,7 @@ interface replaces transparently the old interface.
 @comment stdio.h
 @comment Unix98
 @deftypefun {FILE *} freopen64 (const char *@var{filename}, const char *@var{opentype}, FILE *@var{stream})
+@safety{@mtsafe{}@asunsafe{asynconsist}@acunsafe{incansist, fdleak}}
 This function is similar to @code{freopen}.  The only difference is that
 on 32 bit machine the stream returned is able to read beyond the
 @math{2^31} bytes limits imposed by the normal interface.  It should be
@@ -341,6 +355,7 @@ descriptor and these functions are also available in @theglibc{}.
 @comment stdio_ext.h
 @comment GNU
 @deftypefun int __freadable (FILE *@var{stream})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 The @code{__freadable} function determines whether the stream
 @var{stream} was opened to allow reading.  In this case the return value
 is nonzero.  For write-only streams the function returns zero.
@@ -351,6 +366,7 @@ This function is declared in @file{stdio_ext.h}.
 @comment stdio_ext.h
 @comment GNU
 @deftypefun int __fwritable (FILE *@var{stream})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 The @code{__fwritable} function determines whether the stream
 @var{stream} was opened to allow writing.  In this case the return value
 is nonzero.  For read-only streams the function returns zero.
@@ -364,6 +380,7 @@ They provide even finer-grained information.
 @comment stdio_ext.h
 @comment GNU
 @deftypefun int __freading (FILE *@var{stream})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 The @code{__freading} function determines whether the stream
 @var{stream} was last read from or whether it is opened read-only.  In
 this case the return value is nonzero, otherwise it is zero.
@@ -377,6 +394,7 @@ This function is declared in @file{stdio_ext.h}.
 @comment stdio_ext.h
 @comment GNU
 @deftypefun int __fwriting (FILE *@var{stream})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 The @code{__fwriting} function determines whether the stream
 @var{stream} was last written to or whether it is opened write-only.  In
 this case the return value is nonzero, otherwise it is zero.
@@ -396,6 +414,21 @@ cannot perform any additional operations on it.
 @comment stdio.h
 @comment ISO
 @deftypefun int fclose (FILE *@var{stream})
+@safety{@mtsafe{}@asunsafe{asmalloc, selfdeadlock}@acunsafe{lockleak, memleak, fdleak}}
+@c After fclose, it is undefined behavior to use the stream it points
+@c to.  Therefore, one must only call fclose when the stream is
+@c otherwise unused.  Concurrent uses started before will complete
+@c successfully because of the lock, which makes it MT-Safe.  Calling it
+@c from a signal handler is perfectly safe if the stream is known to be
+@c no longer used, which is a precondition for fclose to be safe in the
+@c first place; since this is no further requirement, fclose is safe for
+@c use in async signals too.  After calling fclose, you can no longer
+@c use the stream, not even to fclose it again, so its memory and file
+@c descriptor may leak if fclose is canceled before @c releasing them.
+@c That the stream must be unused and it becomes unused after the call
+@c is what would enable fclose to be AS- and AC-Safe while freopen
+@c isn't.  However, because of the possibility of leaving __gconv_lock
+@c taken upon cancellation, AC-Safety is lost.
 This function causes @var{stream} to be closed and the connection to
 the corresponding file to be broken.  Any buffered output is written
 and any buffered input is discarded.  The @code{fclose} function returns
@@ -418,6 +451,12 @@ another function.
 @comment stdio.h
 @comment GNU
 @deftypefun int fcloseall (void)
+@safety{@mtunsafe{staticbuf}@asunsafe{staticbuf}@acsafe{}}
+@c Like fclose, using any previously-opened streams after fcloseall is
+@c undefined.  However, the implementation of fcloseall isn't equivalent
+@c to calling fclose for all streams: it just flushes and unbuffers all
+@c streams, without any locking.  It's the flushing without locking that
+@c makes it unsafe.
 This function causes all open streams of the process to be closed and
 the connection to corresponding files to be broken.  All buffered data
 is written and any buffered input is discarded.  The @code{fcloseall}
@@ -474,6 +513,9 @@ perform the stream locking in the application code.
 @comment stdio.h
 @comment POSIX
 @deftypefun void flockfile (FILE *@var{stream})
+@safety{@mtsafe{}@assafe{}@acunsafe{lockleak}}
+@c There's no way to tell whether the lock was acquired before or after
+@c cancellation so as to unlock only when appropriate.
 The @code{flockfile} function acquires the internal locking object
 associated with the stream @var{stream}.  This ensures that no other
 thread can explicitly through @code{flockfile}/@code{ftrylockfile} or
@@ -485,6 +527,7 @@ thread will block until the lock is acquired.  An explicit call to
 @comment stdio.h
 @comment POSIX
 @deftypefun int ftrylockfile (FILE *@var{stream})
+@safety{@mtsafe{}@assafe{}@acunsafe{lockleak}}
 The @code{ftrylockfile} function tries to acquire the internal locking
 object associated with the stream @var{stream} just like
 @code{flockfile}.  But unlike @code{flockfile} this function does not
@@ -496,6 +539,7 @@ another thread.
 @comment stdio.h
 @comment POSIX
 @deftypefun void funlockfile (FILE *@var{stream})
+@safety{@mtsafe{}@assafe{}@acunsafe{lockleak}}
 The @code{funlockfile} function releases the internal locking object of
 the stream @var{stream}. The stream must have been locked before by a
 call to @code{flockfile} or a successful call of @code{ftrylockfile}.
@@ -621,6 +665,15 @@ was introduced in Solaris and is available in @theglibc{} as well.
 @comment stdio_ext.h
 @comment GNU
 @deftypefun int __fsetlocking (FILE *@var{stream}, int @var{type})
+@safety{@mtunsafe{xguargs, uunguard, lockleak}@asunsafe{lockleak}@acsafe{}}
+@c Changing the implicit-locking status of a stream while it's in use by
+@c another thread may cause a lock to be implicitly acquired and not
+@c released, or vice-versa.  This function should probably hold the lock
+@c while changing this setting, to make sure we don't change it while
+@c there are any concurrent uses.  Meanwhile, callers should acquire the
+@c lock themselves to be safe, and even concurrent uses with external
+@c locking will be fine, as long as functions that require external
+@c locking are not called without holding locks.
 
 The @code{__fsetlocking} function can be used to select whether the
 stream operations will implicitly acquire the locking object of the
@@ -635,6 +688,9 @@ locking.  Every stream operation with exception of the @code{_unlocked}
 variants will implicitly lock the stream.
 
 @item FSETLOCKING_BYCALLER
+@c ??? Does the possibility of disabling implicit locking on any stream
+@c make any of the non-_unlocked functions as MT-unsafe as the _unlocked
+@c ones?
 After the @code{__fsetlocking} function returns the user is responsible
 for locking the stream.  None of the stream operations will implicitly
 do this anymore until the state is set back to
@@ -725,6 +781,10 @@ will simply be strange or the application will simply crash.  The
 @comment wchar.h
 @comment ISO
 @deftypefun int fwide (FILE *@var{stream}, int @var{mode})
+@safety{@mtsafe{}@asunsafe{asynconsist}@acunsafe{lockleak}}
+@c Querying is always safe, but changing the stream when it's in use
+@c upthread may be problematic.  Like most lock-acquiring functions,
+@c this one may leak the lock if canceled.
 
 The @code{fwide} function can be used to set and query the state of the
 orientation of the stream @var{stream}.  If the @var{mode} parameter has
@@ -811,6 +871,16 @@ These narrow streams functions are declared in the header file
 @comment stdio.h
 @comment ISO
 @deftypefun int fputc (int @var{c}, FILE *@var{stream})
+@safety{@mtsafe{}@asunsafe{asynconsist}@acunsafe{incansist, lockleak}}
+@c If the stream is in use when interrupted by a signal, the recursive
+@c lock won't help ensure the stream is consistent; indeed, if fputc
+@c gets a signal precisely before the post-incremented _IO_write_ptr
+@c value is stored, we may overwrite the interrupted write.  Conversely,
+@c depending on compiler optimizations, the incremented _IO_write_ptr
+@c may be stored before the character is stored in the buffer,
+@c corrupting the stream if async cancel hits between the two stores.
+@c There may be other reasons for AS- and AC-unsafety in the overflow
+@c cases.
 The @code{fputc} function converts the character @var{c} to type
 @code{unsigned char}, and writes it to the stream @var{stream}.
 @code{EOF} is returned if a write error occurs; otherwise the
@@ -820,6 +890,7 @@ character @var{c} is returned.
 @comment wchar.h
 @comment ISO
 @deftypefun wint_t fputwc (wchar_t @var{wc}, FILE *@var{stream})
+@safety{@mtsafe{}@asunsafe{asynconsist}@acunsafe{incansist, lockleak}}
 The @code{fputwc} function writes the wide character @var{wc} to the
 stream @var{stream}.  @code{WEOF} is returned if a write error occurs;
 otherwise the character @var{wc} is returned.
@@ -828,6 +899,10 @@ otherwise the character @var{wc} is returned.
 @comment stdio.h
 @comment POSIX
 @deftypefun int fputc_unlocked (int @var{c}, FILE *@var{stream})
+@safety{@mtunsafe{xguargs}@asunsafe{asynconsist}@acunsafe{incansist}}
+@c The unlocked functions can't possibly satisfy the MT-Safety
+@c requirements on their own, because they require external locking for
+@c safety.
 The @code{fputc_unlocked} function is equivalent to the @code{fputc}
 function except that it does not implicitly lock the stream.
 @end deftypefun
@@ -835,6 +910,7 @@ function except that it does not implicitly lock the stream.
 @comment wchar.h
 @comment POSIX
 @deftypefun wint_t fputwc_unlocked (wchar_t @var{wc}, FILE *@var{stream})
+@safety{@mtunsafe{xguargs}@asunsafe{asynconsist}@acunsafe{incansist}}
 The @code{fputwc_unlocked} function is equivalent to the @code{fputwc}
 function except that it does not implicitly lock the stream.
 
@@ -844,6 +920,7 @@ This function is a GNU extension.
 @comment stdio.h
 @comment ISO
 @deftypefun int putc (int @var{c}, FILE *@var{stream})
+@safety{@mtsafe{}@asunsafe{asynconsist}@acunsafe{incansist, lockleak}}
 This is just like @code{fputc}, except that most systems implement it as
 a macro, making it faster.  One consequence is that it may evaluate the
 @var{stream} argument more than once, which is an exception to the
@@ -854,6 +931,7 @@ use for writing a single character.
 @comment wchar.h
 @comment ISO
 @deftypefun wint_t putwc (wchar_t @var{wc}, FILE *@var{stream})
+@safety{@mtsafe{}@asunsafe{asynconsist}@acunsafe{incansist, lockleak}}
 This is just like @code{fputwc}, except that it can be implement as
 a macro, making it faster.  One consequence is that it may evaluate the
 @var{stream} argument more than once, which is an exception to the
@@ -864,6 +942,7 @@ use for writing a single wide character.
 @comment stdio.h
 @comment POSIX
 @deftypefun int putc_unlocked (int @var{c}, FILE *@var{stream})
+@safety{@mtunsafe{xguargs}@asunsafe{asynconsist}@acunsafe{incansist}}
 The @code{putc_unlocked} function is equivalent to the @code{putc}
 function except that it does not implicitly lock the stream.
 @end deftypefun
@@ -871,6 +950,7 @@ function except that it does not implicitly lock the stream.
 @comment wchar.h
 @comment GNU
 @deftypefun wint_t putwc_unlocked (wchar_t @var{wc}, FILE *@var{stream})
+@safety{@mtunsafe{xguargs}@asunsafe{asynconsist}@acunsafe{incansist}}
 The @code{putwc_unlocked} function is equivalent to the @code{putwc}
 function except that it does not implicitly lock the stream.
 
@@ -880,6 +960,7 @@ This function is a GNU extension.
 @comment stdio.h
 @comment ISO
 @deftypefun int putchar (int @var{c})
+@safety{@mtsafe{}@asunsafe{asynconsist}@acunsafe{incansist, lockleak}}
 The @code{putchar} function is equivalent to @code{putc} with
 @code{stdout} as the value of the @var{stream} argument.
 @end deftypefun
@@ -887,6 +968,7 @@ The @code{putchar} function is equivalent to @code{putc} with
 @comment wchar.h
 @comment ISO
 @deftypefun wint_t putwchar (wchar_t @var{wc})
+@safety{@mtsafe{}@asunsafe{asynconsist}@acunsafe{incansist, lockleak}}
 The @code{putwchar} function is equivalent to @code{putwc} with
 @code{stdout} as the value of the @var{stream} argument.
 @end deftypefun
@@ -894,6 +976,7 @@ The @code{putwchar} function is equivalent to @code{putwc} with
 @comment stdio.h
 @comment POSIX
 @deftypefun int putchar_unlocked (int @var{c})
+@safety{@mtunsafe{xguargs}@asunsafe{asynconsist}@acunsafe{incansist}}
 The @code{putchar_unlocked} function is equivalent to the @code{putchar}
 function except that it does not implicitly lock the stream.
 @end deftypefun
@@ -901,6 +984,7 @@ function except that it does not implicitly lock the stream.
 @comment wchar.h
 @comment GNU
 @deftypefun wint_t putwchar_unlocked (wchar_t @var{wc})
+@safety{@mtunsafe{xguargs}@asunsafe{asynconsist}@acunsafe{incansist}}
 The @code{putwchar_unlocked} function is equivalent to the @code{putwchar}
 function except that it does not implicitly lock the stream.
 
@@ -910,6 +994,7 @@ This function is a GNU extension.
 @comment stdio.h
 @comment ISO
 @deftypefun int fputs (const char *@var{s}, FILE *@var{stream})
+@safety{@mtsafe{}@asunsafe{asynconsist}@acunsafe{incansist, lockleak}}
 The function @code{fputs} writes the string @var{s} to the stream
 @var{stream}.  The terminating null character is not written.
 This function does @emph{not} add a newline character, either.
@@ -933,6 +1018,7 @@ outputs the text @samp{Are you hungry?} followed by a newline.
 @comment wchar.h
 @comment ISO
 @deftypefun int fputws (const wchar_t *@var{ws}, FILE *@var{stream})
+@safety{@mtsafe{}@asunsafe{asynconsist}@acunsafe{incansist, lockleak}}
 The function @code{fputws} writes the wide character string @var{ws} to
 the stream @var{stream}.  The terminating null character is not written.
 This function does @emph{not} add a newline character, either.  It
@@ -945,6 +1031,7 @@ a non-negative value.
 @comment stdio.h
 @comment GNU
 @deftypefun int fputs_unlocked (const char *@var{s}, FILE *@var{stream})
+@safety{@mtunsafe{xguargs}@asunsafe{asynconsist}@acunsafe{incansist}}
 The @code{fputs_unlocked} function is equivalent to the @code{fputs}
 function except that it does not implicitly lock the stream.
 
@@ -954,6 +1041,7 @@ This function is a GNU extension.
 @comment wchar.h
 @comment GNU
 @deftypefun int fputws_unlocked (const wchar_t *@var{ws}, FILE *@var{stream})
+@safety{@mtunsafe{xguargs}@asunsafe{asynconsist}@acunsafe{incansist}}
 The @code{fputws_unlocked} function is equivalent to the @code{fputws}
 function except that it does not implicitly lock the stream.
 
@@ -963,6 +1051,7 @@ This function is a GNU extension.
 @comment stdio.h
 @comment ISO
 @deftypefun int puts (const char *@var{s})
+@safety{@mtsafe{}@asunsafe{asynconsist}@acunsafe{lockleak, incansist}}
 The @code{puts} function writes the string @var{s} to the stream
 @code{stdout} followed by a newline.  The terminating null character of
 the string is not written.  (Note that @code{fputs} does @emph{not}
@@ -982,6 +1071,7 @@ outputs the text @samp{This is a message.} followed by a newline.
 @comment stdio.h
 @comment SVID
 @deftypefun int putw (int @var{w}, FILE *@var{stream})
+@safety{@mtsafe{}@asunsafe{asynconsist}@acunsafe{lockleak, incansist}}
 This function writes the word @var{w} (that is, an @code{int}) to
 @var{stream}.  It is provided for compatibility with SVID, but we
 recommend you use @code{fwrite} instead (@pxref{Block Input/Output}).
@@ -1014,6 +1104,11 @@ it will fit in a @samp{char} variable without loss of information.
 @comment stdio.h
 @comment ISO
 @deftypefun int fgetc (FILE *@var{stream})
+@safety{@mtsafe{}@asunsafe{asynconsist}@acunsafe{lockleak, incansist}}
+@c Same caveats as fputc, but instead of losing a write in case of async
+@c signals, we may read the same character more than once, and the
+@c stream may be left in odd states due to cancellation in the underflow
+@c cases.
 This function reads the next character as an @code{unsigned char} from
 the stream @var{stream} and returns its value, converted to an
 @code{int}.  If an end-of-file condition or read error occurs,
@@ -1023,6 +1118,7 @@ the stream @var{stream} and returns its value, converted to an
 @comment wchar.h
 @comment ISO
 @deftypefun wint_t fgetwc (FILE *@var{stream})
+@safety{@mtsafe{}@asunsafe{asynconsist}@acunsafe{lockleak, incansist}}
 This function reads the next wide character from the stream @var{stream}
 and returns its value.  If an end-of-file condition or read error
 occurs, @code{WEOF} is returned instead.
@@ -1031,6 +1127,7 @@ occurs, @code{WEOF} is returned instead.
 @comment stdio.h
 @comment POSIX
 @deftypefun int fgetc_unlocked (FILE *@var{stream})
+@safety{@mtunsafe{xguargs}@asunsafe{asynconsist}@acunsafe{incansist}}
 The @code{fgetc_unlocked} function is equivalent to the @code{fgetc}
 function except that it does not implicitly lock the stream.
 @end deftypefun
@@ -1038,6 +1135,7 @@ function except that it does not implicitly lock the stream.
 @comment wchar.h
 @comment GNU
 @deftypefun wint_t fgetwc_unlocked (FILE *@var{stream})
+@safety{@mtunsafe{xguargs}@asunsafe{asynconsist}@acunsafe{incansist}}
 The @code{fgetwc_unlocked} function is equivalent to the @code{fgetwc}
 function except that it does not implicitly lock the stream.
 
@@ -1047,6 +1145,7 @@ This function is a GNU extension.
 @comment stdio.h
 @comment ISO
 @deftypefun int getc (FILE *@var{stream})
+@safety{@mtsafe{}@asunsafe{asynconsist}@acunsafe{lockleak, incansist}}
 This is just like @code{fgetc}, except that it is permissible (and
 typical) for it to be implemented as a macro that evaluates the
 @var{stream} argument more than once.  @code{getc} is often highly
@@ -1057,6 +1156,7 @@ character.
 @comment wchar.h
 @comment ISO
 @deftypefun wint_t getwc (FILE *@var{stream})
+@safety{@mtsafe{}@asunsafe{asynconsist}@acunsafe{lockleak, incansist}}
 This is just like @code{fgetwc}, except that it is permissible for it to
 be implemented as a macro that evaluates the @var{stream} argument more
 than once.  @code{getwc} can be highly optimized, so it is usually the
@@ -1066,6 +1166,7 @@ best function to use to read a single wide character.
 @comment stdio.h
 @comment POSIX
 @deftypefun int getc_unlocked (FILE *@var{stream})
+@safety{@mtunsafe{xguargs}@asunsafe{asynconsist}@acunsafe{incansist}}
 The @code{getc_unlocked} function is equivalent to the @code{getc}
 function except that it does not implicitly lock the stream.
 @end deftypefun
@@ -1073,6 +1174,7 @@ function except that it does not implicitly lock the stream.
 @comment wchar.h
 @comment GNU
 @deftypefun wint_t getwc_unlocked (FILE *@var{stream})
+@safety{@mtunsafe{xguargs}@asunsafe{asynconsist}@acunsafe{incansist}}
 The @code{getwc_unlocked} function is equivalent to the @code{getwc}
 function except that it does not implicitly lock the stream.
 
@@ -1082,6 +1184,7 @@ This function is a GNU extension.
 @comment stdio.h
 @comment ISO
 @deftypefun int getchar (void)
+@safety{@mtsafe{}@asunsafe{asynconsist}@acunsafe{lockleak, incansist}}
 The @code{getchar} function is equivalent to @code{getc} with @code{stdin}
 as the value of the @var{stream} argument.
 @end deftypefun
@@ -1089,6 +1192,7 @@ as the value of the @var{stream} argument.
 @comment wchar.h
 @comment ISO
 @deftypefun wint_t getwchar (void)
+@safety{@mtsafe{}@asunsafe{asynconsist}@acunsafe{lockleak, incansist}}
 The @code{getwchar} function is equivalent to @code{getwc} with @code{stdin}
 as the value of the @var{stream} argument.
 @end deftypefun
@@ -1096,6 +1200,7 @@ as the value of the @var{stream} argument.
 @comment stdio.h
 @comment POSIX
 @deftypefun int getchar_unlocked (void)
+@safety{@mtunsafe{xguargs}@asunsafe{asynconsist}@acunsafe{incansist}}
 The @code{getchar_unlocked} function is equivalent to the @code{getchar}
 function except that it does not implicitly lock the stream.
 @end deftypefun
@@ -1103,6 +1208,7 @@ function except that it does not implicitly lock the stream.
 @comment wchar.h
 @comment GNU
 @deftypefun wint_t getwchar_unlocked (void)
+@safety{@mtunsafe{xguargs}@asunsafe{asynconsist}@acunsafe{incansist}}
 The @code{getwchar_unlocked} function is equivalent to the @code{getwchar}
 function except that it does not implicitly lock the stream.
 
@@ -1145,6 +1251,7 @@ y_or_n_p (const char *question)
 @comment stdio.h
 @comment SVID
 @deftypefun int getw (FILE *@var{stream})
+@safety{@mtsafe{}@asunsafe{asynconsist}@acunsafe{lockleak, incansist}}
 This function reads a word (that is, an @code{int}) from @var{stream}.
 It's provided for compatibility with SVID.  We recommend you use
 @code{fread} instead (@pxref{Block Input/Output}).  Unlike @code{getc},
@@ -1173,6 +1280,12 @@ All these functions are declared in @file{stdio.h}.
 @comment stdio.h
 @comment GNU
 @deftypefun ssize_t getline (char **@var{lineptr}, size_t *@var{n}, FILE *@var{stream})
+@safety{@mtsafe{}@asunsafe{asynconsist, asmalloc}@acunsafe{lockleak, incansist, memleak}}
+@c Besides the usual possibility of getting an inconsistent stream in a
+@c signal handler or leaving it inconsistent in case of cancellation,
+@c the possibility of leaving a dangling pointer upon cancellation
+@c between reallocing the buffer at *lineptr and updating the pointer
+@c brings about another case of incansist.
 This function reads an entire line from @var{stream}, storing the text
 (including the newline and a terminating null character) in a buffer
 and storing the buffer address in @code{*@var{lineptr}}.
@@ -1208,6 +1321,8 @@ If an error occurs or end of file is reached without any bytes read,
 @comment stdio.h
 @comment GNU
 @deftypefun ssize_t getdelim (char **@var{lineptr}, size_t *@var{n}, int @var{delimiter}, FILE *@var{stream})
+@safety{@mtsafe{}@asunsafe{asynconsist, asmalloc}@acunsafe{lockleak, incansist, memleak}}
+@c See the getline incansist note.
 This function is like @code{getline} except that the character which
 tells it to stop reading is not necessarily newline.  The argument
 @var{delimiter} specifies the delimiter character; @code{getdelim} keeps
@@ -1232,6 +1347,7 @@ getline (char **lineptr, size_t *n, FILE *stream)
 @comment stdio.h
 @comment ISO
 @deftypefun {char *} fgets (char *@var{s}, int @var{count}, FILE *@var{stream})
+@safety{@mtsafe{}@asunsafe{asynconsist}@acunsafe{lockleak, incansist}}
 The @code{fgets} function reads characters from the stream @var{stream}
 up to and including a newline character and stores them in the string
 @var{s}, adding a null character to mark the end of the string.  You
@@ -1255,6 +1371,7 @@ error message.  We recommend using @code{getline} instead of @code{fgets}.
 @comment wchar.h
 @comment ISO
 @deftypefun {wchar_t *} fgetws (wchar_t *@var{ws}, int @var{count}, FILE *@var{stream})
+@safety{@mtsafe{}@asunsafe{asynconsist}@acunsafe{lockleak, incansist}}
 The @code{fgetws} function reads wide characters from the stream
 @var{stream} up to and including a newline character and stores them in
 the string @var{ws}, adding a null wide character to mark the end of the
@@ -1280,6 +1397,7 @@ message.
 @comment stdio.h
 @comment GNU
 @deftypefun {char *} fgets_unlocked (char *@var{s}, int @var{count}, FILE *@var{stream})
+@safety{@mtunsafe{xguargs}@asunsafe{asynconsist}@acunsafe{incansist}}
 The @code{fgets_unlocked} function is equivalent to the @code{fgets}
 function except that it does not implicitly lock the stream.
 
@@ -1289,6 +1407,7 @@ This function is a GNU extension.
 @comment wchar.h
 @comment GNU
 @deftypefun {wchar_t *} fgetws_unlocked (wchar_t *@var{ws}, int @var{count}, FILE *@var{stream})
+@safety{@mtunsafe{xguargs}@asunsafe{asynconsist}@acunsafe{incansist}}
 The @code{fgetws_unlocked} function is equivalent to the @code{fgetws}
 function except that it does not implicitly lock the stream.
 
@@ -1298,6 +1417,7 @@ This function is a GNU extension.
 @comment stdio.h
 @comment ISO
 @deftypefn {Deprecated function} {char *} gets (char *@var{s})
+@safety{@mtsafe{}@asunsafe{asynconsist}@acunsafe{lockleak, incansist}}
 The function @code{gets} reads characters from the stream @code{stdin}
 up to the next newline character, and stores them in the string @var{s}.
 The newline character is discarded (note that this differs from the
@@ -1388,6 +1508,7 @@ reverses the action of @code{getc}.
 @comment stdio.h
 @comment ISO
 @deftypefun int ungetc (int @var{c}, FILE *@var{stream})
+@safety{@mtsafe{}@asunsafe{asynconsist}@acunsafe{lockleak, incansist}}
 The @code{ungetc} function pushes back the character @var{c} onto the
 input stream @var{stream}.  So the next input from @var{stream} will
 read @var{c} before anything else.
@@ -1425,6 +1546,7 @@ will encounter end of file.
 @comment wchar.h
 @comment ISO
 @deftypefun wint_t ungetwc (wint_t @var{wc}, FILE *@var{stream})
+@safety{@mtsafe{}@asunsafe{asynconsist}@acunsafe{lockleak, incansist}}
 The @code{ungetwc} function behaves just like @code{ungetc} just that it
 pushes back a wide character.
 @end deftypefun
@@ -1483,6 +1605,7 @@ These functions are declared in @file{stdio.h}.
 @comment stdio.h
 @comment ISO
 @deftypefun size_t fread (void *@var{data}, size_t @var{size}, size_t @var{count}, FILE *@var{stream})
+@safety{@mtsafe{}@asunsafe{asynconsist}@acunsafe{lockleak, incansist}}
 This function reads up to @var{count} objects of size @var{size} into
 the array @var{data}, from the stream @var{stream}.  It returns the
 number of objects actually read, which might be less than @var{count} if
@@ -1498,6 +1621,7 @@ object.  Therefore, the stream remains at the actual end of the file.
 @comment stdio.h
 @comment GNU
 @deftypefun size_t fread_unlocked (void *@var{data}, size_t @var{size}, size_t @var{count}, FILE *@var{stream})
+@safety{@mtunsafe{xguargs}@asunsafe{asynconsist}@acunsafe{incansist}}
 The @code{fread_unlocked} function is equivalent to the @code{fread}
 function except that it does not implicitly lock the stream.
 
@@ -1507,6 +1631,7 @@ This function is a GNU extension.
 @comment stdio.h
 @comment ISO
 @deftypefun size_t fwrite (const void *@var{data}, size_t @var{size}, size_t @var{count}, FILE *@var{stream})
+@safety{@mtsafe{}@asunsafe{asynconsist}@acunsafe{lockleak, incansist}}
 This function writes up to @var{count} objects of size @var{size} from
 the array @var{data}, to the stream @var{stream}.  The return value is
 normally @var{count}, if the call succeeds.  Any other value indicates
@@ -1516,6 +1641,7 @@ some sort of error, such as running out of space.
 @comment stdio.h
 @comment GNU
 @deftypefun size_t fwrite_unlocked (const void *@var{data}, size_t @var{size}, size_t @var{count}, FILE *@var{stream})
+@safety{@mtunsafe{xguargs}@asunsafe{asynconsist}@acunsafe{incansist}}
 The @code{fwrite_unlocked} function is equivalent to the @code{fwrite}
 function except that it does not implicitly lock the stream.
 
@@ -2257,6 +2383,7 @@ just include @file{stdio.h}.
 @comment stdio.h
 @comment ISO
 @deftypefun int printf (const char *@var{template}, @dots{})
+@safety{@mtsafe{glocale}@asunsafe{asynconsist, asmalloc}@acunsafe{memleak, lockleak, incansist}}
 The @code{printf} function prints the optional arguments under the
 control of the template string @var{template} to the stream
 @code{stdout}.  It returns the number of characters printed, or a
@@ -2266,6 +2393,7 @@ negative value if there was an output error.
 @comment wchar.h
 @comment ISO
 @deftypefun int wprintf (const wchar_t *@var{template}, @dots{})
+@safety{@mtsafe{glocale}@asunsafe{asynconsist, asmalloc}@acunsafe{memleak, lockleak, incansist}}
 The @code{wprintf} function prints the optional arguments under the
 control of the wide template string @var{template} to the stream
 @code{stdout}.  It returns the number of wide characters printed, or a
@@ -2275,6 +2403,7 @@ negative value if there was an output error.
 @comment stdio.h
 @comment ISO
 @deftypefun int fprintf (FILE *@var{stream}, const char *@var{template}, @dots{})
+@safety{@mtsafe{glocale}@asunsafe{asynconsist, asmalloc}@acunsafe{memleak, lockleak, incansist}}
 This function is just like @code{printf}, except that the output is
 written to the stream @var{stream} instead of @code{stdout}.
 @end deftypefun
@@ -2282,6 +2411,7 @@ written to the stream @var{stream} instead of @code{stdout}.
 @comment wchar.h
 @comment ISO
 @deftypefun int fwprintf (FILE *@var{stream}, const wchar_t *@var{template}, @dots{})
+@safety{@mtsafe{glocale}@asunsafe{asynconsist, asmalloc}@acunsafe{memleak, lockleak, incansist}}
 This function is just like @code{wprintf}, except that the output is
 written to the stream @var{stream} instead of @code{stdout}.
 @end deftypefun
@@ -2289,6 +2419,7 @@ written to the stream @var{stream} instead of @code{stdout}.
 @comment stdio.h
 @comment ISO
 @deftypefun int sprintf (char *@var{s}, const char *@var{template}, @dots{})
+@safety{@mtsafe{glocale}@asunsafe{asmalloc, glocale}@acsafe{memleak}}
 This is like @code{printf}, except that the output is stored in the character
 array @var{s} instead of written to a stream.  A null character is written
 to mark the end of the string.
@@ -2313,6 +2444,7 @@ described below.
 @comment wchar.h
 @comment GNU
 @deftypefun int swprintf (wchar_t *@var{s}, size_t @var{size}, const wchar_t *@var{template}, @dots{})
+@safety{@mtsafe{glocale}@asunsafe{asmalloc}@acsafe{memleak}}
 This is like @code{wprintf}, except that the output is stored in the
 wide character array @var{ws} instead of written to a stream.  A null
 wide character is written to mark the end of the string.  The @var{size}
@@ -2337,6 +2469,7 @@ again and decided to not define an function exactly corresponding to
 @comment stdio.h
 @comment GNU
 @deftypefun int snprintf (char *@var{s}, size_t @var{size}, const char *@var{template}, @dots{})
+@safety{@mtsafe{glocale}@asunsafe{asmalloc}@acsafe{memleak}}
 The @code{snprintf} function is similar to @code{sprintf}, except that
 the @var{size} argument specifies the maximum number of characters to
 produce.  The trailing null character is counted towards this limit, so
@@ -2407,6 +2540,7 @@ in dynamically allocated memory.
 @comment stdio.h
 @comment GNU
 @deftypefun int asprintf (char **@var{ptr}, const char *@var{template}, @dots{})
+@safety{@mtsafe{glocale}@asunsafe{asmalloc}@acsafe{memleak}}
 This function is similar to @code{sprintf}, except that it dynamically
 allocates a string (as with @code{malloc}; @pxref{Unconstrained
 Allocation}) to hold the output, instead of putting the output in a
@@ -2439,6 +2573,7 @@ make_message (char *name, char *value)
 @comment stdio.h
 @comment GNU
 @deftypefun int obstack_printf (struct obstack *@var{obstack}, const char *@var{template}, @dots{})
+@safety{@mtunsafe{xguargs, glocale}@asunsafe{asynconsist, asmalloc}@acsafe{incansist, memleak}}
 This function is similar to @code{asprintf}, except that it uses the
 obstack @var{obstack} to allocate the space.  @xref{Obstacks}.
 
@@ -2509,6 +2644,7 @@ Prototypes for these functions are declared in @file{stdio.h}.
 @comment stdio.h
 @comment ISO
 @deftypefun int vprintf (const char *@var{template}, va_list @var{ap})
+@safety{@mtsafe{glocale}@asunsafe{asynconsist, asmalloc}@acunsafe{memleak, lockleak, incansist}}
 This function is similar to @code{printf} except that, instead of taking
 a variable number of arguments directly, it takes an argument list
 pointer @var{ap}.
@@ -2517,6 +2653,7 @@ pointer @var{ap}.
 @comment wchar.h
 @comment ISO
 @deftypefun int vwprintf (const wchar_t *@var{template}, va_list @var{ap})
+@safety{@mtsafe{glocale}@asunsafe{asynconsist, asmalloc}@acunsafe{memleak, lockleak, incansist}}
 This function is similar to @code{wprintf} except that, instead of taking
 a variable number of arguments directly, it takes an argument list
 pointer @var{ap}.
@@ -2525,6 +2662,48 @@ pointer @var{ap}.
 @comment stdio.h
 @comment ISO
 @deftypefun int vfprintf (FILE *@var{stream}, const char *@var{template}, va_list @var{ap})
+@safety{@mtsafe{glocale}@asunsafe{asynconsist, asmalloc}@acunsafe{memleak, lockleak, incansist}}
+@c Although vfprintf sets up a cleanup region to release the lock on the
+@c output stream, it doesn't use it to release args_value or string in
+@c case of cancellation.  This doesn't make it unsafe, but cancelling it
+@c may leak memory.  The unguarded use of __printf_function_table is
+@c also of concern for all callers.
+@c _itoa ok
+@c   _udiv_qrnnd_preinv ok
+@c group_number ok
+@c _i18n_number_rewrite
+@c   __wctrans ok
+@c   __towctrans glocale
+@c   __wcrtomb ok? dup below
+@c   outdigit_value ok
+@c   outdigitwc_value ok
+@c outchar ok
+@c outstring ok
+@c PAD ok
+@c __printf_fp glocale, asmalloc, memleak
+@c __printf_fphex glocale
+@c __readonly_area
+@c   [GNU/Linux] fopen, strtoul, free
+@c __strerror_r ok if no translation, check otherwise
+@c __btowc ? gconv-modules
+@c __wcrtomb ok (not using internal state) gconv-modules
+@c ARGCHECK
+@c UNBUFFERED_P (tested before taking the stream lock)
+@c buffered_vfprintf ok
+@c __find_spec(wc|mb)
+@c read_int
+@c __libc_use_alloca
+@c process_arg
+@c process_string_arg
+@c extend_alloca
+@c __parse_one_spec(wc|mb)
+@c *__printf_arginfo_table unguarded
+@c __printf_va_arg_table-> unguarded
+@c *__printf_function_table unguarded
+@c done_add
+@c printf_unknown
+@c   outchar
+@c   _itoa_word
 This is the equivalent of @code{fprintf} with the variable argument list
 specified directly as for @code{vprintf}.
 @end deftypefun
@@ -2532,6 +2711,7 @@ specified directly as for @code{vprintf}.
 @comment wchar.h
 @comment ISO
 @deftypefun int vfwprintf (FILE *@var{stream}, const wchar_t *@var{template}, va_list @var{ap})
+@safety{@mtsafe{glocale}@asunsafe{asynconsist, asmalloc}@acunsafe{memleak, lockleak, incansist}}
 This is the equivalent of @code{fwprintf} with the variable argument list
 specified directly as for @code{vwprintf}.
 @end deftypefun
@@ -2539,6 +2719,7 @@ specified directly as for @code{vwprintf}.
 @comment stdio.h
 @comment ISO
 @deftypefun int vsprintf (char *@var{s}, const char *@var{template}, va_list @var{ap})
+@safety{@mtsafe{glocale}@asunsafe{asmalloc}@acsafe{memleak}}
 This is the equivalent of @code{sprintf} with the variable argument list
 specified directly as for @code{vprintf}.
 @end deftypefun
@@ -2546,6 +2727,7 @@ specified directly as for @code{vprintf}.
 @comment wchar.h
 @comment GNU
 @deftypefun int vswprintf (wchar_t *@var{s}, size_t @var{size}, const wchar_t *@var{template}, va_list @var{ap})
+@safety{@mtsafe{glocale}@asunsafe{asmalloc}@acsafe{memleak}}
 This is the equivalent of @code{swprintf} with the variable argument list
 specified directly as for @code{vwprintf}.
 @end deftypefun
@@ -2553,6 +2735,7 @@ specified directly as for @code{vwprintf}.
 @comment stdio.h
 @comment GNU
 @deftypefun int vsnprintf (char *@var{s}, size_t @var{size}, const char *@var{template}, va_list @var{ap})
+@safety{@mtsafe{glocale}@asunsafe{asmalloc}@acsafe{memleak}}
 This is the equivalent of @code{snprintf} with the variable argument list
 specified directly as for @code{vprintf}.
 @end deftypefun
@@ -2560,6 +2743,7 @@ specified directly as for @code{vprintf}.
 @comment stdio.h
 @comment GNU
 @deftypefun int vasprintf (char **@var{ptr}, const char *@var{template}, va_list @var{ap})
+@safety{@mtsafe{glocale}@asunsafe{asmalloc}@acsafe{memleak}}
 The @code{vasprintf} function is the equivalent of @code{asprintf} with the
 variable argument list specified directly as for @code{vprintf}.
 @end deftypefun
@@ -2567,6 +2751,10 @@ variable argument list specified directly as for @code{vprintf}.
 @comment stdio.h
 @comment GNU
 @deftypefun int obstack_vprintf (struct obstack *@var{obstack}, const char *@var{template}, va_list @var{ap})
+@safety{@mtunsafe{xguargs, glocale}@asunsafe{asynconsist, asmalloc}@acsafe{incansist, memleak}}
+@c The obstack is not guarded by mutexes, it might be at an inconsistent
+@c state within a signal handler, and it could be left at an
+@c inconsistent state in case of cancellation.
 The @code{obstack_vprintf} function is the equivalent of
 @code{obstack_printf} with the variable argument list specified directly
 as for @code{vprintf}.@refill
@@ -2639,6 +2827,7 @@ file @file{printf.h}.
 @comment printf.h
 @comment GNU
 @deftypefun size_t parse_printf_format (const char *@var{template}, size_t @var{n}, int *@var{argtypes})
+@safety{@mtsafe{glocale}@assafe{}@acsafe{}}
 This function returns information about the number and types of
 arguments expected by the @code{printf} template string @var{template}.
 The information is stored in the array @var{argtypes}; each element of
@@ -2879,6 +3068,12 @@ The function to register a new output conversion is
 @comment printf.h
 @comment GNU
 @deftypefun int register_printf_function (int @var{spec}, printf_function @var{handler-function}, printf_arginfo_function @var{arginfo-function})
+@safety{@mtunsafe{uunguard}@asunsafe{asmalloc, selfdeadlock}@acunsafe{memleak, lockleak}}
+@c This function is guarded by the global non-recursive libc lock, but
+@c users of the variables it sets aren't, and those should be MT-Safe,
+@c so we're ruling out the use of this extension with threads.  Calling
+@c it from a signal handler may self-deadlock, and cancellation may
+@c leave the lock held, besides leaking allocated memory.
 This function defines the conversion specifier character @var{spec}.
 Thus, if @var{spec} is @code{'Y'}, it defines the conversion @samp{%Y}.
 You can redefine the built-in conversions like @samp{%s}, but flag
@@ -3125,6 +3320,12 @@ which implement a special way to print floating-point numbers.
 @comment printf.h
 @comment GNU
 @deftypefun int printf_size (FILE *@var{fp}, const struct printf_info *@var{info}, const void *const *@var{args})
+@safety{@mtunsafe{xguargs, glocale}@asunsafe{asynconsist, asmalloc}@acunsafe{memleak, incansist}}
+@c This is meant to be called by vfprintf, that should hold the lock on
+@c the stream, but if this function is called directly, output will be
+@c racy, besides the uses of the global locale object while other
+@c threads may be changing it and the possbility of leaving the stream
+@c object in an inconsistent state in case of cancellation.
 Print a given floating point number as for the format @code{%f} except
 that there is a postfix character indicating the divisor for the
 number to make this less than 1000.  There are two possible divisors:
@@ -3183,6 +3384,7 @@ provide the function which returns information about the arguments.
 @comment printf.h
 @comment GNU
 @deftypefun int printf_size_info (const struct printf_info *@var{info}, size_t @var{n}, int *@var{argtypes})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 This function will return in @var{argtypes} the information about the
 used parameters in the way the @code{vfprintf} implementation expects
 it.  The format always takes one argument.
@@ -3799,6 +4001,7 @@ Prototypes for these functions are in the header file @file{stdio.h}.
 @comment stdio.h
 @comment ISO
 @deftypefun int scanf (const char *@var{template}, @dots{})
+@safety{@mtsafe{glocale}@asunsafe{asynconsist, asmalloc}@acunsafe{memleak, lockleak, incansist}}
 The @code{scanf} function reads formatted input from the stream
 @code{stdin} under the control of the template string @var{template}.
 The optional arguments are pointers to the places which receive the
@@ -3813,6 +4016,7 @@ template, then @code{EOF} is returned.
 @comment wchar.h
 @comment ISO
 @deftypefun int wscanf (const wchar_t *@var{template}, @dots{})
+@safety{@mtsafe{glocale}@asunsafe{asynconsist, asmalloc}@acunsafe{memleak, lockleak, incansist}}
 The @code{wscanf} function reads formatted input from the stream
 @code{stdin} under the control of the template string @var{template}.
 The optional arguments are pointers to the places which receive the
@@ -3827,6 +4031,7 @@ template, then @code{WEOF} is returned.
 @comment stdio.h
 @comment ISO
 @deftypefun int fscanf (FILE *@var{stream}, const char *@var{template}, @dots{})
+@safety{@mtsafe{glocale}@asunsafe{asynconsist, asmalloc}@acunsafe{memleak, lockleak, incansist}}
 This function is just like @code{scanf}, except that the input is read
 from the stream @var{stream} instead of @code{stdin}.
 @end deftypefun
@@ -3834,6 +4039,7 @@ from the stream @var{stream} instead of @code{stdin}.
 @comment wchar.h
 @comment ISO
 @deftypefun int fwscanf (FILE *@var{stream}, const wchar_t *@var{template}, @dots{})
+@safety{@mtsafe{glocale}@asunsafe{asynconsist, asmalloc}@acunsafe{memleak, lockleak, incansist}}
 This function is just like @code{wscanf}, except that the input is read
 from the stream @var{stream} instead of @code{stdin}.
 @end deftypefun
@@ -3841,6 +4047,7 @@ from the stream @var{stream} instead of @code{stdin}.
 @comment stdio.h
 @comment ISO
 @deftypefun int sscanf (const char *@var{s}, const char *@var{template}, @dots{})
+@safety{@mtsafe{glocale}@asunsafe{asmalloc}@acsafe{memleak}}
 This is like @code{scanf}, except that the characters are taken from the
 null-terminated string @var{s} instead of from a stream.  Reaching the
 end of the string is treated as an end-of-file condition.
@@ -3854,6 +4061,7 @@ as an argument to receive a string read under control of the @samp{%s},
 @comment wchar.h
 @comment ISO
 @deftypefun int swscanf (const wchar_t *@var{ws}, const wchar_t *@var{template}, @dots{})
+@safety{@mtsafe{glocale}@asunsafe{asmalloc}@acsafe{memleak}}
 This is like @code{wscanf}, except that the characters are taken from the
 null-terminated string @var{ws} instead of from a stream.  Reaching the
 end of the string is treated as an end-of-file condition.
@@ -3880,6 +4088,7 @@ introduced in @w{ISO C99} and were before available as GNU extensions.
 @comment stdio.h
 @comment ISO
 @deftypefun int vscanf (const char *@var{template}, va_list @var{ap})
+@safety{@mtsafe{glocale}@asunsafe{asynconsist, asmalloc}@acunsafe{memleak, lockleak, incansist}}
 This function is similar to @code{scanf}, but instead of taking
 a variable number of arguments directly, it takes an argument list
 pointer @var{ap} of type @code{va_list} (@pxref{Variadic Functions}).
@@ -3888,6 +4097,7 @@ pointer @var{ap} of type @code{va_list} (@pxref{Variadic Functions}).
 @comment wchar.h
 @comment ISO
 @deftypefun int vwscanf (const wchar_t *@var{template}, va_list @var{ap})
+@safety{@mtsafe{glocale}@asunsafe{asynconsist, asmalloc}@acunsafe{memleak, lockleak, incansist}}
 This function is similar to @code{wscanf}, but instead of taking
 a variable number of arguments directly, it takes an argument list
 pointer @var{ap} of type @code{va_list} (@pxref{Variadic Functions}).
@@ -3896,6 +4106,7 @@ pointer @var{ap} of type @code{va_list} (@pxref{Variadic Functions}).
 @comment stdio.h
 @comment ISO
 @deftypefun int vfscanf (FILE *@var{stream}, const char *@var{template}, va_list @var{ap})
+@safety{@mtsafe{glocale}@asunsafe{asynconsist, asmalloc}@acunsafe{memleak, lockleak, incansist}}
 This is the equivalent of @code{fscanf} with the variable argument list
 specified directly as for @code{vscanf}.
 @end deftypefun
@@ -3903,6 +4114,7 @@ specified directly as for @code{vscanf}.
 @comment wchar.h
 @comment ISO
 @deftypefun int vfwscanf (FILE *@var{stream}, const wchar_t *@var{template}, va_list @var{ap})
+@safety{@mtsafe{glocale}@asunsafe{asynconsist, asmalloc}@acunsafe{memleak, lockleak, incansist}}
 This is the equivalent of @code{fwscanf} with the variable argument list
 specified directly as for @code{vwscanf}.
 @end deftypefun
@@ -3910,6 +4122,7 @@ specified directly as for @code{vwscanf}.
 @comment stdio.h
 @comment ISO
 @deftypefun int vsscanf (const char *@var{s}, const char *@var{template}, va_list @var{ap})
+@safety{@mtsafe{glocale}@asunsafe{asmalloc}@acsafe{memleak}}
 This is the equivalent of @code{sscanf} with the variable argument list
 specified directly as for @code{vscanf}.
 @end deftypefun
@@ -3917,6 +4130,7 @@ specified directly as for @code{vscanf}.
 @comment wchar.h
 @comment ISO
 @deftypefun int vswscanf (const wchar_t *@var{s}, const wchar_t *@var{template}, va_list @var{ap})
+@safety{@mtsafe{glocale}@asunsafe{asmalloc}@acsafe{memleak}}
 This is the equivalent of @code{swscanf} with the variable argument list
 specified directly as for @code{vwscanf}.
 @end deftypefun
@@ -3966,6 +4180,7 @@ This symbol is declared in @file{wchar.h}.
 @comment stdio.h
 @comment ISO
 @deftypefun int feof (FILE *@var{stream})
+@safety{@mtsafe{}@assafe{}@acunsafe{lockleak}}
 The @code{feof} function returns nonzero if and only if the end-of-file
 indicator for the stream @var{stream} is set.
 
@@ -3975,6 +4190,9 @@ This symbol is declared in @file{stdio.h}.
 @comment stdio.h
 @comment GNU
 @deftypefun int feof_unlocked (FILE *@var{stream})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
+@c There isn't much of a thread unsafety risk in reading a flag word and
+@c testing a bit in it.
 The @code{feof_unlocked} function is equivalent to the @code{feof}
 function except that it does not implicitly lock the stream.
 
@@ -3986,6 +4204,7 @@ This symbol is declared in @file{stdio.h}.
 @comment stdio.h
 @comment ISO
 @deftypefun int ferror (FILE *@var{stream})
+@safety{@mtsafe{}@assafe{}@acunsafe{lockleak}}
 The @code{ferror} function returns nonzero if and only if the error
 indicator for the stream @var{stream} is set, indicating that an error
 has occurred on a previous operation on the stream.
@@ -3996,6 +4215,7 @@ This symbol is declared in @file{stdio.h}.
 @comment stdio.h
 @comment GNU
 @deftypefun int ferror_unlocked (FILE *@var{stream})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 The @code{ferror_unlocked} function is equivalent to the @code{ferror}
 function except that it does not implicitly lock the stream.
 
@@ -4023,6 +4243,7 @@ function.
 @comment stdio.h
 @comment ISO
 @deftypefun void clearerr (FILE *@var{stream})
+@safety{@mtsafe{}@assafe{}@acunsafe{lockleak}}
 This function clears the end-of-file and error indicators for the
 stream @var{stream}.
 
@@ -4033,6 +4254,7 @@ end-of-file indicator for the stream.
 @comment stdio.h
 @comment GNU
 @deftypefun void clearerr_unlocked (FILE *@var{stream})
+@safety{@mtunsafe{xguargs}@assafe{}@acunsafe{lockleak}}
 The @code{clearerr_unlocked} function is equivalent to the @code{clearerr}
 function except that it does not implicitly lock the stream.
 
@@ -4146,6 +4368,7 @@ are declared in the header file @file{stdio.h}.
 @comment stdio.h
 @comment ISO
 @deftypefun {long int} ftell (FILE *@var{stream})
+@safety{@mtsafe{}@asunsafe{asynconsist}@acunsafe{lockleak, incansist}}
 This function returns the current file position of the stream
 @var{stream}.
 
@@ -4158,6 +4381,7 @@ possibly for other reasons as well.  If a failure occurs, a value of
 @comment stdio.h
 @comment Unix98
 @deftypefun off_t ftello (FILE *@var{stream})
+@safety{@mtsafe{}@asunsafe{asynconsist}@acunsafe{lockleak, incansist}}
 The @code{ftello} function is similar to @code{ftell}, except that it
 returns a value of type @code{off_t}.  Systems which support this type
 use it to describe all file positions, unlike the POSIX specification
@@ -4181,6 +4405,7 @@ LFS interface transparently replaces the old interface.
 @comment stdio.h
 @comment Unix98
 @deftypefun off64_t ftello64 (FILE *@var{stream})
+@safety{@mtsafe{}@asunsafe{asynconsist}@acunsafe{lockleak, incansist}}
 This function is similar to @code{ftello} with the only difference that
 the return value is of type @code{off64_t}.  This also requires that the
 stream @var{stream} was opened using either @code{fopen64},
@@ -4196,6 +4421,7 @@ and so transparently replaces the old interface.
 @comment stdio.h
 @comment ISO
 @deftypefun int fseek (FILE *@var{stream}, long int @var{offset}, int @var{whence})
+@safety{@mtsafe{}@asunsafe{asynconsist}@acunsafe{lockleak, incansist}}
 The @code{fseek} function is used to change the file position of the
 stream @var{stream}.  The value of @var{whence} must be one of the
 constants @code{SEEK_SET}, @code{SEEK_CUR}, or @code{SEEK_END}, to
@@ -4215,6 +4441,7 @@ place in the file.
 @comment stdio.h
 @comment Unix98
 @deftypefun int fseeko (FILE *@var{stream}, off_t @var{offset}, int @var{whence})
+@safety{@mtsafe{}@asunsafe{asynconsist}@acunsafe{lockleak, incansist}}
 This function is similar to @code{fseek} but it corrects a problem with
 @code{fseek} in a system with POSIX types.  Using a value of type
 @code{long int} for the offset is not compatible with POSIX.
@@ -4238,6 +4465,7 @@ LFS interface transparently replaces the old interface.
 @comment stdio.h
 @comment Unix98
 @deftypefun int fseeko64 (FILE *@var{stream}, off64_t @var{offset}, int @var{whence})
+@safety{@mtsafe{}@asunsafe{asynconsist}@acunsafe{lockleak, incansist}}
 This function is similar to @code{fseeko} with the only difference that
 the @var{offset} parameter is of type @code{off64_t}.  This also
 requires that the stream @var{stream} was opened using either
@@ -4286,6 +4514,7 @@ the offset provided is relative to the end of the file.
 @comment stdio.h
 @comment ISO
 @deftypefun void rewind (FILE *@var{stream})
+@safety{@mtsafe{}@asunsafe{asynconsist}@acunsafe{lockleak, incansist}}
 The @code{rewind} function positions the stream @var{stream} at the
 beginning of the file.  It is equivalent to calling @code{fseek} or
 @code{fseeko} on the @var{stream} with an @var{offset} argument of
@@ -4407,6 +4636,7 @@ representation.
 @comment stdio.h
 @comment ISO
 @deftypefun int fgetpos (FILE *@var{stream}, fpos_t *@var{position})
+@safety{@mtsafe{}@asunsafe{asynconsist}@acunsafe{lockleak, incansist}}
 This function stores the value of the file position indicator for the
 stream @var{stream} in the @code{fpos_t} object pointed to by
 @var{position}.  If successful, @code{fgetpos} returns zero; otherwise
@@ -4421,6 +4651,7 @@ interface transparently replaces the old interface.
 @comment stdio.h
 @comment Unix98
 @deftypefun int fgetpos64 (FILE *@var{stream}, fpos64_t *@var{position})
+@safety{@mtsafe{}@asunsafe{asynconsist}@acunsafe{lockleak, incansist}}
 This function is similar to @code{fgetpos} but the file position is
 returned in a variable of type @code{fpos64_t} to which @var{position}
 points.
@@ -4433,6 +4664,7 @@ and so transparently replaces the old interface.
 @comment stdio.h
 @comment ISO
 @deftypefun int fsetpos (FILE *@var{stream}, const fpos_t *@var{position})
+@safety{@mtsafe{}@asunsafe{asynconsist}@acunsafe{lockleak, incansist}}
 This function sets the file position indicator for the stream @var{stream}
 to the position @var{position}, which must have been set by a previous
 call to @code{fgetpos} on the same stream.  If successful, @code{fsetpos}
@@ -4449,6 +4681,7 @@ interface transparently replaces the old interface.
 @comment stdio.h
 @comment Unix98
 @deftypefun int fsetpos64 (FILE *@var{stream}, const fpos64_t *@var{position})
+@safety{@mtsafe{}@asunsafe{asynconsist}@acunsafe{lockleak, incansist}}
 This function is similar to @code{fsetpos} but the file position used
 for positioning is provided in a variable of type @code{fpos64_t} to
 which @var{position} points.
@@ -4560,6 +4793,7 @@ If you want to flush the buffered output at another time, call
 @comment stdio.h
 @comment ISO
 @deftypefun int fflush (FILE *@var{stream})
+@safety{@mtsafe{}@asunsafe{asynconsist}@acunsafe{lockleak, incansist}}
 This function causes any buffered output on @var{stream} to be delivered
 to the file.  If @var{stream} is a null pointer, then
 @code{fflush} causes buffered output on @emph{all} open output streams
@@ -4572,6 +4806,7 @@ otherwise.
 @comment stdio.h
 @comment POSIX
 @deftypefun int fflush_unlocked (FILE *@var{stream})
+@safety{@mtunsafe{xguargs}@asunsafe{asynconsist}@acunsafe{incansist}}
 The @code{fflush_unlocked} function is equivalent to the @code{fflush}
 function except that it does not implicitly lock the stream.
 @end deftypefun
@@ -4588,6 +4823,7 @@ exported.
 @comment stdio_ext.h
 @comment GNU
 @deftypefun void _flushlbf (void)
+@safety{@mtsafe{}@asunsafe{asynconsist}@acunsafe{lockleak, incansist}}
 The @code{_flushlbf} function flushes all line buffered streams
 currently opened.
 
@@ -4609,6 +4845,7 @@ situation a non-standard function introduced in Solaris and available in
 @comment stdio_ext.h
 @comment GNU
 @deftypefun void __fpurge (FILE *@var{stream})
+@safety{@mtunsafe{xguargs}@asunsafe{asynconsist}@acunsafe{incansist}}
 The @code{__fpurge} function causes the buffer of the stream
 @var{stream} to be emptied.  If the stream is currently in read mode all
 input in the buffer is lost.  If the stream is in output mode the
@@ -4633,6 +4870,7 @@ file @file{stdio.h}.
 @comment stdio.h
 @comment ISO
 @deftypefun int setvbuf (FILE *@var{stream}, char *@var{buf}, int @var{mode}, size_t @var{size})
+@safety{@mtsafe{}@asunsafe{asynconsist}@acunsafe{lockleak, incansist}}
 This function is used to specify that the stream @var{stream} should
 have the buffering mode @var{mode}, which can be either @code{_IOFBF}
 (for full buffering), @code{_IOLBF} (for line buffering), or
@@ -4710,6 +4948,7 @@ efficient size.
 @comment stdio.h
 @comment ISO
 @deftypefun void setbuf (FILE *@var{stream}, char *@var{buf})
+@safety{@mtsafe{}@asunsafe{asynconsist}@acunsafe{lockleak, incansist}}
 If @var{buf} is a null pointer, the effect of this function is
 equivalent to calling @code{setvbuf} with a @var{mode} argument of
 @code{_IONBF}.  Otherwise, it is equivalent to calling @code{setvbuf}
@@ -4723,6 +4962,7 @@ use @code{setvbuf} in all new programs.
 @comment stdio.h
 @comment BSD
 @deftypefun void setbuffer (FILE *@var{stream}, char *@var{buf}, size_t @var{size})
+@safety{@mtsafe{}@asunsafe{asynconsist}@acunsafe{lockleak, incansist}}
 If @var{buf} is a null pointer, this function makes @var{stream} unbuffered.
 Otherwise, it makes @var{stream} fully buffered using @var{buf} as the
 buffer.  The @var{size} argument specifies the length of @var{buf}.
@@ -4734,6 +4974,7 @@ This function is provided for compatibility with old BSD code.  Use
 @comment stdio.h
 @comment BSD
 @deftypefun void setlinebuf (FILE *@var{stream})
+@safety{@mtsafe{}@asunsafe{asynconsist}@acunsafe{lockleak, incansist}}
 This function makes @var{stream} be line buffered, and allocates the
 buffer for you.
 
@@ -4748,6 +4989,7 @@ using a non-standard function introduced in Solaris and available in
 @comment stdio_ext.h
 @comment GNU
 @deftypefun int __flbf (FILE *@var{stream})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 The @code{__flbf} function will return a nonzero value in case the
 stream @var{stream} is line buffered.  Otherwise the return value is
 zero.
@@ -4761,6 +5003,7 @@ much of it is used.  These functions were also introduced in Solaris.
 @comment stdio_ext.h
 @comment GNU
 @deftypefun size_t __fbufsize (FILE *@var{stream})
+@safety{@mtunsafe{xguargs}@asunsafe{asynconsist}@acsafe{}}
 The @code{__fbufsize} function return the size of the buffer in the
 stream @var{stream}.  This value can be used to optimize the use of the
 stream.
@@ -4771,6 +5014,7 @@ This function is declared in the @file{stdio_ext.h} header.
 @comment stdio_ext.h
 @comment GNU
 @deftypefun size_t __fpending (FILE *@var{stream})
+@safety{@mtunsafe{xguargs}@asunsafe{asynconsist}@acsafe{}}
 The @code{__fpending}
 function returns the number of bytes currently in the output buffer.
 For wide-oriented stream the measuring unit is wide characters.  This
@@ -4818,6 +5062,10 @@ I/O to a string or memory buffer.  These facilities are declared in
 @comment stdio.h
 @comment GNU
 @deftypefun {FILE *} fmemopen (void *@var{buf}, size_t @var{size}, const char *@var{opentype})
+@safety{@mtsafe{}@asunsafe{asmalloc, selfdeadlock}@acsafe{memleak, lockleak}}
+@c Unlike open_memstream, fmemopen does (indirectly) call _IO_link_in,
+@c bringing with it additional potential for async trouble with
+@c list_all_lock.
 This function opens a stream that allows the access specified by the
 @var{opentype} argument, that reads from or writes to the buffer specified
 by the argument @var{buf}.  This array must be at least @var{size} bytes long.
@@ -4870,6 +5118,7 @@ Got r
 @comment stdio.h
 @comment GNU
 @deftypefun {FILE *} open_memstream (char **@var{ptr}, size_t *@var{sizeloc})
+@safety{@mtsafe{}@asunsafe{asmalloc}@acsafe{memleak}}
 This function opens a stream for writing to a buffer.  The buffer is
 allocated dynamically and grown as necessary, using @code{malloc}.
 After you've closed the stream, this buffer is your responsibility to
@@ -4985,6 +5234,7 @@ closed.
 @comment stdio.h
 @comment GNU
 @deftypefun {FILE *} fopencookie (void *@var{cookie}, const char *@var{opentype}, cookie_io_functions_t @var{io-functions})
+@safety{@mtsafe{}@asunsafe{asmalloc, selfdeadlock}@acunsafe{memleak, lockleak}}
 This function actually creates the stream for communicating with the
 @var{cookie} using the functions in the @var{io-functions} argument.
 The @var{opentype} argument is interpreted as for @code{fopen};
@@ -5166,6 +5416,7 @@ It is a non-recoverable error.
 @comment fmtmsg.h
 @comment XPG
 @deftypefun int fmtmsg (long int @var{classification}, const char *@var{label}, int @var{severity}, const char *@var{text}, const char *@var{action}, const char *@var{tag})
+@safety{@mtsafe{}@asunsafe{selfdeadlock}@acsafe{}}
 Display a message described by its parameters on the device(s) specified
 in the @var{classification} parameter.  The @var{label} parameter
 identifies the source of the message.  The string should consist of two
@@ -5306,6 +5557,7 @@ introducing new classes in a running program.  One could use the
 but this is toilsome.
 
 @deftypefun int addseverity (int @var{severity}, const char *@var{string})
+@safety{@mtsafe{}@asunsafe{asmalloc, selfdeadlock}@acunsafe{lockleak, memleak}}
 This function allows the introduction of new severity classes which can be
 addressed by the @var{severity} parameter of the @code{fmtmsg} function.
 The @var{severity} parameter of @code{addseverity} must match the value

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=d50fab12d26162af2fd30c5bf5ec9373f473ae9c

commit d50fab12d26162af2fd30c5bf5ec9373f473ae9c
Author: Alexandre Oliva <aoliva@redhat.com>
Date:   Fri Nov 8 06:08:21 2013 -0200

    MT-, AS- and AC-safety docs: manual/process.texi
    
    for ChangeLog
    
    	* manual/process.texi: Document MTASC-safety properties.

diff --git a/manual/process.texi b/manual/process.texi
index e962941..6e10cd3 100644
--- a/manual/process.texi
+++ b/manual/process.texi
@@ -55,6 +55,43 @@ until the subprogram terminates before you can do anything else.
 @comment ISO
 @deftypefun int system (const char *@var{command})
 @pindex sh
+@safety{@mtsafe{}@asunsafe{uplugin, asmalloc, selfdeadlock}@acunsafe{lockleak, memleak}}
+@c system uplugin, asmalloc, selfdeadlock, lockleak, memleak
+@c  do_system uplugin, asmalloc, selfdeadlock, lockleak, memleak
+@c   sigemptyset dup ok
+@c   libc_lock_lock selfdeadlock, lockleak
+@c   ADD_REF ok
+@c   sigaction dup ok
+@c   SUB_REF ok
+@c   libc_lock_unlock lockleak
+@c   sigaddset dup ok
+@c   sigprocmask dup ok
+@c   CLEANUP_HANDLER uplugin, asmalloc, memleak
+@c    libc_cleanup_region_start uplugin, asmalloc, memleak
+@c     pthread_cleanup_push_defer uplugin, asmalloc, memleak
+@c      CANCELLATION_P uplugin, asmalloc, memleak
+@c       CANCEL_ENABLED_AND_CANCELED ok
+@c       do_cancel uplugin, asmalloc, memleak
+@c    cancel_handler ok
+@c     kill syscall ok
+@c     waitpid dup ok
+@c     libc_lock_lock ok
+@c     sigaction dup ok
+@c     libc_lock_unlock ok
+@c   FORK ok
+@c    clone syscall ok
+@c   waitpid dup ok
+@c   CLEANUP_RESET ok
+@c    libc_cleanup_region_end ok
+@c     pthread_cleanup_pop_restore ok
+@c  SINGLE_THREAD_P ok
+@c  LIBC_CANCEL_ASYNC uplugin, asmalloc, memleak
+@c   libc_enable_asynccancel uplugin, asmalloc, memleak
+@c    CANCEL_ENABLED_AND_CANCELED_AND_ASYNCHRONOUS dup ok
+@c    do_cancel dup uplugin, asmalloc, memleak
+@c  LIBC_CANCEL_RESET ok
+@c   libc_disable_asynccancel ok
+@c    lll_futex_wait dup ok
 This function executes @var{command} as a shell command.  In @theglibc{},
 it always uses the default shell @code{sh} to run the command.
 In particular, it searches the directories in @code{PATH} to find
@@ -157,12 +194,14 @@ of representing a process ID.  In @theglibc{}, this is an @code{int}.
 @comment unistd.h
 @comment POSIX.1
 @deftypefun pid_t getpid (void)
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 The @code{getpid} function returns the process ID of the current process.
 @end deftypefun
 
 @comment unistd.h
 @comment POSIX.1
 @deftypefun pid_t getppid (void)
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 The @code{getppid} function returns the process ID of the parent of the
 current process.
 @end deftypefun
@@ -177,6 +216,19 @@ It is declared in the header file @file{unistd.h}.
 @comment unistd.h
 @comment POSIX.1
 @deftypefun pid_t fork (void)
+@safety{@mtsafe{uplugin}@assafe{uplugin}@acunsafe{lockleak}}
+@c The nptl/.../linux implementation safely collects fork_handlers into
+@c an alloca()ed linked list and increments ref counters; it uses atomic
+@c ops and retries, avoiding locking altogether.  It then takes the
+@c IO_list lock, resets the thread-local pid, and runs fork.  The parent
+@c restores the thread-local pid, releases the lock, and runs parent
+@c handlers, decrementing the ref count and signaling futex wait if
+@c requested by unregister_atfork.  The child bumps the fork generation,
+@c sets the thread-local pid, resets cpu clocks, initializes the robust
+@c mutex list, the stream locks, the IO_list lock, the dynamic loader
+@c lock, runs the child handlers, reseting ref counters to 1, and
+@c initializes the fork lock.  These are all safe, unless atfork
+@c handlers themselves are unsafe.
 The @code{fork} function creates a new process.
 
 If the operation is successful, there are then both parent and child
@@ -242,6 +294,9 @@ signals and signal actions from the parent process.)
 @comment unistd.h
 @comment BSD
 @deftypefun pid_t vfork (void)
+@safety{@mtsafe{uplugin}@assafe{uplugin}@acunsafe{lockleak}}
+@c The vfork implementation proper is a safe syscall, but it may fall
+@c back to fork if the vfork syscall is not available.
 The @code{vfork} function is similar to @code{fork} but on some systems
 it is more efficient; however, there are restrictions you must follow to
 use it safely.
@@ -287,6 +342,7 @@ header file @file{unistd.h}.
 @comment unistd.h
 @comment POSIX.1
 @deftypefun int execv (const char *@var{filename}, char *const @var{argv}@t{[]})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 The @code{execv} function executes the file named by @var{filename} as a
 new process image.
 
@@ -305,6 +361,7 @@ The environment for the new process image is taken from the
 @comment unistd.h
 @comment POSIX.1
 @deftypefun int execl (const char *@var{filename}, const char *@var{arg0}, @dots{})
+@safety{@mtsafe{}@asunsafe{asmalloc}@acsafe{memleak}}
 This is similar to @code{execv}, but the @var{argv} strings are
 specified individually instead of as an array.  A null pointer must be
 passed as the last such argument.
@@ -313,6 +370,7 @@ passed as the last such argument.
 @comment unistd.h
 @comment POSIX.1
 @deftypefun int execve (const char *@var{filename}, char *const @var{argv}@t{[]}, char *const @var{env}@t{[]})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 This is similar to @code{execv}, but permits you to specify the environment
 for the new program explicitly as the @var{env} argument.  This should
 be an array of strings in the same format as for the @code{environ}
@@ -322,6 +380,7 @@ variable; see @ref{Environment Access}.
 @comment unistd.h
 @comment POSIX.1
 @deftypefun int execle (const char *@var{filename}, const char *@var{arg0}, @dots{}, char *const @var{env}@t{[]})
+@safety{@mtsafe{}@asunsafe{asmalloc}@acsafe{memleak}}
 This is similar to @code{execl}, but permits you to specify the
 environment for the new program explicitly.  The environment argument is
 passed following the null pointer that marks the last @var{argv}
@@ -332,6 +391,7 @@ the @code{environ} variable.
 @comment unistd.h
 @comment POSIX.1
 @deftypefun int execvp (const char *@var{filename}, char *const @var{argv}@t{[]})
+@safety{@mtunsafe{envromt}@asunsafe{asmalloc}@acsafe{memleak}}
 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
@@ -345,6 +405,7 @@ to run the commands that users type.
 @comment unistd.h
 @comment POSIX.1
 @deftypefun int execlp (const char *@var{filename}, const char *@var{arg0}, @dots{})
+@safety{@mtunsafe{envromt}@asunsafe{asmalloc}@acsafe{memleak}}
 This function is like @code{execl}, except that it performs the same
 file name searching as the @code{execvp} function.
 @end deftypefun
@@ -462,6 +523,7 @@ are declared in the header file @file{sys/wait.h}.
 @comment sys/wait.h
 @comment POSIX.1
 @deftypefun pid_t waitpid (pid_t @var{pid}, int *@var{status-ptr}, int @var{options})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 The @code{waitpid} function is used to request status information from a
 child process whose process ID is @var{pid}.  Normally, the calling
 process is suspended until the child process makes status information
@@ -565,6 +627,7 @@ terminated.
 @comment sys/wait.h
 @comment POSIX.1
 @deftypefun pid_t wait (int *@var{status-ptr})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 This is a simplified version of @code{waitpid}, and is used to wait
 until any one child process terminates.  The call:
 
@@ -591,6 +654,7 @@ protected using cancellation handlers.
 @comment sys/wait.h
 @comment BSD
 @deftypefun pid_t wait4 (pid_t @var{pid}, int *@var{status-ptr}, int @var{options}, struct rusage *@var{usage})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 If @var{usage} is a null pointer, @code{wait4} is equivalent to
 @code{waitpid (@var{pid}, @var{status-ptr}, @var{options})}.
 
@@ -643,6 +707,7 @@ These macros are defined in the header file @file{sys/wait.h}.
 @comment sys/wait.h
 @comment POSIX.1
 @deftypefn Macro int WIFEXITED (int @var{status})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 This macro returns a nonzero value if the child process terminated
 normally with @code{exit} or @code{_exit}.
 @end deftypefn
@@ -650,6 +715,7 @@ normally with @code{exit} or @code{_exit}.
 @comment sys/wait.h
 @comment POSIX.1
 @deftypefn Macro int WEXITSTATUS (int @var{status})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 If @code{WIFEXITED} is true of @var{status}, this macro returns the
 low-order 8 bits of the exit status value from the child process.
 @xref{Exit Status}.
@@ -658,6 +724,7 @@ low-order 8 bits of the exit status value from the child process.
 @comment sys/wait.h
 @comment POSIX.1
 @deftypefn Macro int WIFSIGNALED (int @var{status})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 This macro returns a nonzero value if the child process terminated
 because it received a signal that was not handled.
 @xref{Signal Handling}.
@@ -666,6 +733,7 @@ because it received a signal that was not handled.
 @comment sys/wait.h
 @comment POSIX.1
 @deftypefn Macro int WTERMSIG (int @var{status})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 If @code{WIFSIGNALED} is true of @var{status}, this macro returns the
 signal number of the signal that terminated the child process.
 @end deftypefn
@@ -673,6 +741,7 @@ signal number of the signal that terminated the child process.
 @comment sys/wait.h
 @comment BSD
 @deftypefn Macro int WCOREDUMP (int @var{status})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 This macro returns a nonzero value if the child process terminated
 and produced a core dump.
 @end deftypefn
@@ -680,12 +749,14 @@ and produced a core dump.
 @comment sys/wait.h
 @comment POSIX.1
 @deftypefn Macro int WIFSTOPPED (int @var{status})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 This macro returns a nonzero value if the child process is stopped.
 @end deftypefn
 
 @comment sys/wait.h
 @comment POSIX.1
 @deftypefn Macro int WSTOPSIG (int @var{status})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 If @code{WIFSTOPPED} is true of @var{status}, this macro returns the
 signal number of the signal that caused the child process to stop.
 @end deftypefn
@@ -739,6 +810,7 @@ more flexible.  @code{wait3} is now obsolete.
 @comment sys/wait.h
 @comment BSD
 @deftypefun pid_t wait3 (union wait *@var{status-ptr}, int @var{options}, struct rusage *@var{usage})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 If @var{usage} is a null pointer, @code{wait3} is equivalent to
 @code{waitpid (-1, @var{status-ptr}, @var{options})}.
 

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=4bf88bea40b909c32ab176869861b01f4627a0f0

commit 4bf88bea40b909c32ab176869861b01f4627a0f0
Author: Alexandre Oliva <aoliva@redhat.com>
Date:   Fri Nov 8 06:08:25 2013 -0200

    MT-, AS- and AC-safety docs: manual/pattern.texi
    
    for ChangeLog
    
    	* manual/pattern.texi: Document MTASC-safety properties.

diff --git a/manual/pattern.texi b/manual/pattern.texi
index afd6480..eb1bb79 100644
--- a/manual/pattern.texi
+++ b/manual/pattern.texi
@@ -28,6 +28,38 @@ declared in @file{fnmatch.h}.
 @comment fnmatch.h
 @comment POSIX.2
 @deftypefun int fnmatch (const char *@var{pattern}, const char *@var{string}, int @var{flags})
+@safety{@mtunsafe{envromt, glocale}@asunsafe{asmalloc}@acunsafe{memleak}}
+@c fnmatch envromt, glocale, asmalloc, memleak
+@c  strnlen dup ok
+@c  mbsrtowcs
+@c  memset dup ok
+@c  malloc dup asmalloc, memleak
+@c  mbsinit dup ok
+@c  free dup asmalloc, memleak
+@c  FCT = internal_fnwmatch envromt, glocale, asmalloc, memleak
+@c   FOLD glocale
+@c    towlower glocale
+@c   EXT envromt, glocale, asmalloc, memleak
+@c    STRLEN = wcslen dup ok
+@c    getenv envromt
+@c    malloc dup asmalloc, memleak
+@c    MEMPCPY = wmempcpy dup ok
+@c    FCT dup envromt, glocale, asmalloc, memleak
+@c    STRCAT = wcscat dup ok
+@c    free dup asmalloc, memleak
+@c   END envromt
+@c    getenv envromt
+@c   MEMCHR = wmemchr dup ok
+@c   getenv envromt
+@c   IS_CHAR_CLASS = is_char_class glocale
+@c    wctype glocale
+@c   BTOWC ok
+@c   ISWCTYPE ok
+@c   auto findidx dup ok
+@c   elem_hash dup ok
+@c   memcmp dup ok
+@c   collseq_table_lookup dup ok
+@c   NO_LEADING_PERIOD ok
 This function tests whether the string @var{string} matches the pattern
 @var{pattern}.  It returns @code{0} if they do match; otherwise, it
 returns the nonzero value @code{FNM_NOMATCH}.  The arguments
@@ -327,6 +359,63 @@ This is a GNU extension.
 @comment glob.h
 @comment POSIX.2
 @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})
+@safety{@mtunsafe{staticbuf, envromt, tempsig, stimer, glocale}@asunsafe{shlimb, uplugin, asynconsist, asmalloc, selfdeadlock}@acunsafe{incansist, lockleak, fdleak, memleak}}
+@c glob staticbuf, envromt, tempsig, stimer, glocale, shlimb, uplugin, asynconsist, asmalloc, selfdeadlock, incansist, lockleak, fdleak, memleak
+@c  strlen dup ok
+@c  strchr dup ok
+@c  malloc dup asmalloc, memleak
+@c  mempcpy dup ok
+@c  next_brace_sub ok
+@c  free dup asmalloc, memleak
+@c  globfree dup asynconsist, asmalloc, incansist, memleak
+@c  glob_pattern_p ok
+@c   glob_pattern_type dup ok
+@c  getenv dup envromt
+@c  GET_LOGIN_NAME_MAX ok
+@c  getlogin_r dup staticbuf, tempsig, stimer, glocale, shlimb, uplugin, asmalloc, selfdeadlock, incansist, lockleak, fdleak, memleak
+@c  GETPW_R_SIZE_MAX ok
+@c  getpwnam_r dup glocale, shlimb, uplugin, asmalloc, selfdeadlock, incansist, lockleak, fdleak, memleak
+@c  realloc dup asmalloc, memleak
+@c  memcpy dup ok
+@c  memchr dup ok
+@c  *pglob->gl_stat user-supplied
+@c  stat64 dup ok
+@c  S_ISDIR dup ok
+@c  strdup dup asmalloc, memleak
+@c  glob_pattern_type ok
+@c  glob_in_dir envromt, glocale, asynconsist, asmalloc, incansist, fdleak, memleak
+@c   strlen dup ok
+@c   glob_pattern_type dup ok
+@c   malloc dup asmalloc, memleak
+@c   mempcpy dup ok
+@c   *pglob->gl_stat user-supplied
+@c   stat64 dup ok
+@c   free dup asmalloc, memleak
+@c   *pglob->gl_opendir user-supplied
+@c   opendir dup asmalloc, memleak, fdleak
+@c   dirfd dup ok
+@c   *pglob->gl_readdir user-supplied
+@c   CONVERT_DIRENT_DIRENT64 ok
+@c   readdir64 ok [protected by exclusive use of the stream]
+@c   REAL_DIR_ENTRY ok
+@c   DIRENT_MIGHT_BE_DIR ok
+@c   fnmatch dup envromt, glocale, asmalloc, memleak
+@c   DIRENT_MIGHT_BE_SYMLINK ok
+@c   link_exists_p ok
+@c    link_exists2_p ok
+@c     strlen dup ok
+@c     mempcpy dup ok
+@c     *pglob->gl_stat user-supplied
+@c    fxstatat64 dup ok
+@c   realloc dup asmalloc, memleak
+@c   pglob->gl_closedir user-supplied
+@c   closedir asmalloc, memleak, fdleak
+@c  prefix_array dup asynconsist, asmalloc, incansist, memleak
+@c   strlen dup ok
+@c   malloc dup asmalloc, memleak
+@c   free dup asmalloc, memleak
+@c   mempcpy dup ok
+@c  strcpy dup ok
 The function @code{glob} does globbing using the pattern @var{pattern}
 in the current directory.  It puts the result in a newly allocated
 vector, and stores the size and address of this vector into
@@ -398,6 +487,8 @@ is encountered @code{glob} @emph{can} fail.
 @comment glob.h
 @comment GNU
 @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})
+@safety{@mtunsafe{staticbuf, envromt, tempsig, stimer, glocale}@asunsafe{shlimb, synconsist, asmalloc, selfdeadlock}@acunsafe{incansist, lockleak, fdleak, memleak}}
+@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
 this is simple: it is not necessary.  The necessity for a @code{glob64}
@@ -662,6 +753,9 @@ the time when all @code{glob} calls are done.
 @comment glob.h
 @comment POSIX.2
 @deftypefun void globfree (glob_t *@var{pglob})
+@safety{@mtsafe{}@asunsafe{asynconsist, asmalloc}@acunsafe{incansist, memleak}}
+@c globfree dup asynconsist, asmalloc, incansist, memleak
+@c  free dup asmalloc, memleak
 The @code{globfree} function frees all resources allocated by previous
 calls to @code{glob} associated with the object pointed to by
 @var{pglob}.  This function should be called whenever the currently used
@@ -671,6 +765,7 @@ calls to @code{glob} associated with the object pointed to by
 @comment glob.h
 @comment GNU
 @deftypefun void globfree64 (glob64_t *@var{pglob})
+@safety{@mtsafe{}@asunsafe{asynconsist, selfdeadlock}@acunsafe{incansist, lockleak, fdleak, memleak}}
 This function is equivalent to @code{globfree} but it frees records of
 type @code{glob64_t} which were allocated by @code{glob64}.
 @end deftypefun
@@ -733,6 +828,251 @@ expression into it by calling @code{regcomp}.
 @comment regex.h
 @comment POSIX.2
 @deftypefun int regcomp (regex_t *restrict @var{compiled}, const char *restrict @var{pattern}, int @var{cflags})
+@safety{@mtsafe{glocale}@asunsafe{asynconsist, asmalloc, selfdeadlock, shlimb}@acunsafe{incansist, lockleak, memleak, fdleak, shlimb}}
+@c All of the issues have to do with memory allocation and multi-byte 
+@c character handling present in the input string, or implied by ranges
+@c or inverted character classes.
+@c (re_)malloc asmalloc, memleak
+@c re_compile_internal glocale, asynconsist, asmalloc, selfdeadlock, shlimb, incansist, lockleak, memleak, fdleak
+@c  (re_)realloc asmalloc, memleak (asynconsist, incansist, for other
+@c    callers that don't zero the buffer)
+@c  init_dfa glocale, asynconsist, asmalloc, sefldeadlock, shlimb, incansist, lockleak, memleak, fdleak
+@c   (re_)malloc asmalloc, memleak
+@c   calloc asmalloc, memleak
+@c   _NL_CURRENT ok
+@c   _NL_CURRENT_WORD ok
+@c   btowc asynconsist, asmalloc, sefldeadlock, shlimb, incansist, lockleak, memleak, fdleak
+@c  libc_lock_init ok
+@c  re_string_construct glocale, asynconsist, asmalloc, selfdeadlock, shlimb, incansist, lockleak, memleak, fdleak
+@c   re_string_construct_common ok
+@c   re_string_realloc_buffers asmalloc, memleak
+@c    (re_)realloc dup asmalloc, memleak
+@c   build_wcs_upper_buffer glocale, asynconsist, asmalloc, selfdeadlock, shlimb, incansist, lockleak, memleak, fdleak
+@c    isascii ok
+@c    mbsinit ok
+@c    toupper ok
+@c    mbrtowc dup asynconsist, asmalloc, selfdeadlock, shlimb, incansist, lockleak, memleak, fdleak
+@c    iswlower glocale
+@c    towupper glocale
+@c    wcrtomb dup asynconsist, asmalloc, selfdeadlock, shlimb, incansist, lockleak, memleak, fdleak
+@c    (re_)malloc dup asmalloc, memleak
+@c   build_upper_buffer ok (glocale, but optimized)
+@c    islower ok
+@c    toupper ok
+@c   build_wcs_buffer asynconsist, asmalloc, selfdeadlock, shlimb, incansist, lockleak, memleak, fdleak
+@c    mbrtowc dup asynconsist, asmalloc, selfdeadlock, shlimb, incansist, lockleak, memleak, fdleak
+@c   re_string_translate_buffer ok
+@c  parse (maybe glocale), asynconsist, asmalloc, sefldeadlock, shlimb, incansist, lockleak, memleak, fdleak
+@c   fetch_token (maybe glocale), asynconsist, asmalloc, sefldeadlock, shlimb, incansist, lockleak, memleak, fdleak
+@c    peek_token ok (maybe glocale)
+@c     re_string_eoi ok
+@c     re_string_peek_byte ok
+@c     re_string_cur_idx ok
+@c     re_string_length ok
+@c     re_string_peek_byte_case ok (maybe glocale)
+@c      re_string_peek_byte dup ok
+@c      re_string_is_single_byte_char ok
+@c      isascii ok
+@c      re_string_peek_byte dup ok
+@c     re_string_wchar_at ok
+@c     re_string_skip_bytes ok
+@c    re_string_skip_bytes dup ok
+@c   parse_reg_exp (maybe glocale), asynconsist, asmalloc, sefldeadlock, shlimb, incansist, lockleak, memleak, fdleak
+@c    parse_branch (maybe glocale), asynconsist, asmalloc, sefldeadlock, shlimb, incansist, lockleak, memleak, fdleak
+@c     parse_expression (maybe glocale), asynconsist, asmalloc, sefldeadlock, shlimb, incansist, lockleak, memleak, fdleak
+@c      create_token_tree dup asmalloc, memleak
+@c      re_string_eoi dup ok
+@c      re_string_first_byte ok
+@c      fetch_token dup (maybe glocale), asynconsist, asmalloc, sefldeadlock, shlimb, incansist, lockleak, memleak, fdleak
+@c      create_tree dup asmalloc, memleak
+@c      parse_sub_exp (maybe glocale), asynconsist, asmalloc, sefldeadlock, shlimb, incansist, lockleak, memleak, fdleak
+@c       fetch_token dup (maybe glocale), asynconsist, asmalloc, sefldeadlock, shlimb, incansist, lockleak, memleak, fdleak
+@c       parse_reg_exp dup (maybe glocale), asynconsist, asmalloc, sefldeadlock, shlimb, incansist, lockleak, memleak, fdleak
+@c       postorder() asmalloc, memleak
+@c        free_tree asmalloc, memleak
+@c         free_token dup asmalloc, memleak
+@c       create_tree dup asmalloc, memleak
+@c      parse_bracket_exp (maybe glocale), asynconsist, asmalloc, sefldeadlock, shlimb, incansist, lockleak, memleak, fdleak
+@c       _NL_CURRENT dup ok
+@c       _NL_CURRENT_WORD dup ok
+@c       calloc dup asmalloc, memleak
+@c       (re_)free dup asmalloc, memleak
+@c       peek_token_bracket ok
+@c        re_string_eoi dup ok
+@c        re_string_peek_byte dup ok
+@c        re_string_first_byte dup ok
+@c        re_string_cur_idx dup ok
+@c        re_string_length dup ok
+@c        re_string_skip_bytes dup ok
+@c       bitset_set ok
+@c       re_string_skip_bytes ok
+@c       parse_bracket_element ok (maybe glocale)
+@c        re_string_char_size_at ok
+@c        re_string_wchar_at dup ok
+@c        re_string_skip_bytes dup ok
+@c        parse_bracket_symbol ok (maybe glocale)
+@c         re_string_eoi dup ok
+@c         re_string_fetch_byte_case ok (maybe glocale)
+@c          re_string_fetch_byte ok
+@c          re_string_first_byte dup ok
+@c          isascii ok
+@c          re_string_char_size_at dup ok
+@c          re_string_skip_bytes dup ok
+@c         re_string_fetch_byte dup ok
+@c         re_string_peek_byte dup ok
+@c         re_string_skip_bytes dup ok
+@c        peek_token_bracket dup ok
+@c       auto build_range_exp asynconsist, asmalloc, sefldeadlock, shlimb, incansist, lockleak, memleak, fdleak
+@c        auto lookup_collation_sequence_value asynconsist, asmalloc, sefldeadlock, shlimb, incansist, lockleak, memleak, fdleak
+@c         btowc dup asynconsist, asmalloc, sefldeadlock, shlimb, incansist, lockleak, memleak, fdleak
+@c         collseq_table_lookup ok
+@c         auto seek_collating_symbol_entry dup ok
+@c        (re_)realloc dup asmalloc, memleak
+@c        collseq_table_lookup dup ok
+@c       bitset_set dup ok
+@c       (re_)realloc dup asmalloc, memleak
+@c       build_equiv_class (maybe glocale), asmalloc, memleak
+@c        _NL_CURRENT ok
+@c        auto findidx ok
+@c        bitset_set dup ok
+@c        (re_)realloc dup asmalloc, memleak
+@c       auto build_collating_symbol asmalloc, memleak
+@c        auto seek_collating_symbol_entry ok
+@c        bitset_set dup ok
+@c        (re_)realloc dup asmalloc, memleak
+@c       build_charclass (maybe glocale), asmalloc, memleak
+@c        (re_)realloc dup asmalloc, memleak
+@c        bitset_set dup ok
+@c        isalnum ok
+@c        iscntrl ok
+@c        isspace ok
+@c        isalpha ok
+@c        isdigit ok
+@c        isprint ok
+@c        isupper ok
+@c        isblank ok
+@c        isgraph ok
+@c        ispunct ok
+@c        isxdigit ok
+@c       bitset_not ok
+@c       bitset_mask ok
+@c       create_token_tree dup asmalloc, memleak
+@c       create_tree dup asmalloc, memleak
+@c       free_charset dup asmalloc, memleak
+@c      init_word_char (maybe glocale)
+@c       isalnum ok
+@c      build_charclass_op (maybe glocale), asmalloc, memleak
+@c       calloc dup asmalloc, memleak
+@c       build_charclass dup (maybe glocale), asmalloc, memleak
+@c       (re_)free dup asmalloc, memleak
+@c       free_charset dup asmalloc, memleak
+@c       bitset_set dup ok
+@c       bitset_not dup ok
+@c       bitset_mask dup ok
+@c       create_token_tree dup asmalloc, memleak
+@c       create_tree dup asmalloc, memleak
+@c      parse_dup_op (maybe glocale), asynconsist, asmalloc, sefldeadlock, shlimb, incansist, lockleak, memleak, fdleak
+@c       re_string_cur_idx dup ok
+@c       fetch_number ok (maybe glocale), asynconsist, asmalloc, sefldeadlock, shlimb, incansist, lockleak, memleak, fdleak
+@c        fetch_token dup (maybe glocale), asynconsist, asmalloc, sefldeadlock, shlimb, incansist, lockleak, memleak, fdleak
+@c       re_string_set_index ok
+@c       postorder() asmalloc, memleak
+@c        free_tree dup asmalloc, memleak
+@c        mark_opt_subexp ok
+@c       duplicate_tree asmalloc, memleak
+@c        create_token_tree dup asmalloc, memleak
+@c       create_tree dup asmalloc, memleak
+@c     postorder() asmalloc, memleak
+@c      free_tree dup asmalloc, memleak
+@c    fetch_token dup (maybe glocale), asynconsist, asmalloc, sefldeadlock, shlimb, incansist, lockleak, memleak, fdleak
+@c    parse_branch dup (maybe glocale), asynconsist, asmalloc, sefldeadlock, shlimb, incansist, lockleak, memleak, fdleak
+@c    create_tree dup asmalloc, memleak
+@c   create_tree asmalloc, memleak
+@c    create_token_tree asmalloc, memleak
+@c     (re_)malloc dup asmalloc, memleak
+@c  analyze asmalloc, memleak
+@c   (re_)malloc dup asmalloc, memleak
+@c   preorder() asmalloc, memleak
+@c    optimize_subexps ok
+@c    calc_next ok
+@c    link_nfa_nodes asmalloc, memleak
+@c     re_node_set_init_1 asmalloc, memleak
+@c      (re_)malloc dup asmalloc, memleak
+@c     re_node_set_init_2 asmalloc, memleak
+@c      (re_)malloc dup asmalloc, memleak
+@c   postorder() asmalloc, memleak
+@c    lower_subexps asmalloc, memleak
+@c     lower_subexp asmalloc, memleak
+@c      create_tree dup asmalloc, memleak
+@c    calc_first asmalloc, memleak
+@c     re_dfa_add_node asmalloc, memleak
+@c      (re_)realloc dup asmalloc, memleak
+@c      re_node_set_init_empty ok
+@c   calc_eclosure asmalloc, memleak
+@c    calc_eclosure_iter asmalloc, memleak
+@c     re_node_set_alloc asmalloc, memleak
+@c      (re_)malloc dup asmalloc, memleak
+@c     duplicate_node_closure asmalloc, memleak
+@c      re_node_set_empty ok
+@c      duplicate_node asmalloc, memleak
+@c       re_dfa_add_node dup asmalloc, memleak
+@c      re_node_set_insert asmalloc, memleak
+@c       (re_)realloc dup asmalloc, memleak
+@c      search_duplicated_node ok
+@c     re_node_set_merge asmalloc, memleak
+@c      (re_)realloc dup asmalloc, memleak
+@c     re_node_set_free asmalloc, memleak
+@c      (re_)free dup asmalloc, memleak
+@c     re_node_set_insert dup asmalloc, memleak
+@c    re_node_set_free dup asmalloc, memleak
+@c   calc_inveclosure asmalloc, memleak
+@c    re_node_set_init_empty dup ok
+@c    re_node_set_insert_last asmalloc, memleak
+@c     (re_)realloc dup asmalloc, memleak
+@c  optimize_utf8 ok
+@c  create_initial_state asmalloc, memleak
+@c   re_node_set_init_copy asmalloc, memleak
+@c    (re_)malloc dup asmalloc, memleak
+@c    re_node_set_init_empty dup ok
+@c   re_node_set_contains ok
+@c   re_node_set_merge dup asmalloc, memleak
+@c   re_acquire_state_context asmalloc, memleak
+@c    calc_state_hash ok
+@c    re_node_set_compare ok
+@c    create_cd_newstate asmalloc, memleak
+@c     calloc dup asmalloc, memleak
+@c     re_node_set_init_copy dup asmalloc, memleak
+@c     (re_)free dup asmalloc, memleak
+@c     free_state asmalloc, memleak
+@c      re_node_set_free dup asmalloc, memleak
+@c      (re_)free dup asmalloc, memleak
+@c     NOT_SATISFY_PREV_CONSTRAINT ok
+@c     re_node_set_remove_at ok
+@c     register_state asmalloc, memleak
+@c      re_node_set_alloc dup asmalloc, memleak
+@c      re_node_set_insert_last dup asmalloc, memleak
+@c      (re_)realloc dup asmalloc, memleak
+@c   re_node_set_free dup asmalloc, memleak
+@c  free_workarea_compile asmalloc, memleak
+@c   (re_)free dup asmalloc, memleak
+@c  re_string_destruct asmalloc, memleak
+@c   (re_)free dup asmalloc, memleak
+@c  free_dfa_content asmalloc, memleak
+@c   free_token asmalloc, memleak
+@c    free_charset asmalloc, memleak
+@c     (re_)free dup asmalloc, memleak
+@c    (re_)free dup asmalloc, memleak
+@c   (re_)free dup asmalloc, memleak
+@c   re_node_set_free dup asmalloc, memleak
+@c re_compile_fastmap glocale, asynconsist, asmalloc, selfdeadlock, shlimb, incansist, lockleak, memleak, fdleak
+@c  re_compile_fastmap_iter glocale, asynconsist, asmalloc, selfdeadlock, shlimb, incansist, lockleak, memleak, fdleak
+@c   re_set_fastmap ok
+@c    tolower ok
+@c   mbrtowc dup asynconsist, asmalloc, selfdeadlock, shlimb, incansist, lockleak, memleak, fdleak
+@c   wcrtomb dup asynconsist, asmalloc, selfdeadlock, shlimb, incansist, lockleak, memleak, fdleak
+@c   towlower glocale
+@c   _NL_CURRENT ok
+@c (re_)free asmalloc, memleak
 The function @code{regcomp} ``compiles'' a regular expression into a
 data structure that you can use with @code{regexec} to match against a
 string.  The compiled regular expression format is designed for
@@ -882,6 +1222,247 @@ unless the regular expression contains anchor characters (@samp{^} or
 @comment regex.h
 @comment POSIX.2
 @deftypefun int regexec (const regex_t *restrict @var{compiled}, const char *restrict @var{string}, size_t @var{nmatch}, regmatch_t @var{matchptr}[restrict], int @var{eflags})
+@safety{@mtsafe{glocale}@asunsafe{asynconsist, asmalloc, selfdeadlock, shlimb}@acunsafe{incansist, lockleak, memleak, fdleak, shlimb}}
+@c libc_lock_lock selfdeadlock, lockleak
+@c re_search_internal glocale, asynconsist, asmalloc, selfdeadlock, shlimb, incansist, lockleak, memleak, fdleak
+@c  re_string_allocate asmalloc, memleak
+@c   re_string_construct_common dup ok
+@c   re_string_realloc_buffers dup asmalloc, memleak
+@c  match_ctx_init asmalloc, memleak
+@c   (re_)malloc dup asmalloc, memleak
+@c  re_string_byte_at ok
+@c  re_string_first_byte dup ok
+@c  check_matching glocale, asynconsist, asmalloc, selfdeadlock, shlimb, incansist, lockleak, memleak, fdleak
+@c   re_string_cur_idx dup ok
+@c   acquire_init_state_context dup asmalloc, memleak
+@c    re_string_context_at ok
+@c     re_string_byte_at dup ok
+@c     bitset_contain ok
+@c    re_acquire_state_context dup asmalloc, memleak
+@c   check_subexp_matching_top asmalloc, memleak
+@c    match_ctx_add_subtop asmalloc, memleak
+@c     (re_)realloc dup asmalloc, memleak
+@c     calloc dup asmalloc, memleak
+@c   transit_state_bkref glocale, asynconsist, asmalloc, selfdeadlock, shlimb, incansist, lockleak, memleak, fdleak
+@c    re_string_cur_idx dup ok
+@c    re_string_context_at dup ok
+@c    NOT_SATISFY_NEXT_CONSTRAINT ok
+@c    get_subexp glocale, asynconsist, asmalloc, selfdeadlock, shlimb, incansist, lockleak, memleak, fdleak
+@c     re_string_get_buffer ok
+@c     search_cur_bkref_entry ok
+@c     clean_state_log_if_needed glocale, asynconsist, asmalloc, selfdeadlock, shlimb, incansist, lockleak, memleak, fdleak
+@c      extend_buffers glocale, asynconsist, asmalloc, selfdeadlock, shlimb, incansist, lockleak, memleak, fdleak
+@c       re_string_realloc_buffers dup asmalloc, memleak
+@c       (re_)realloc dup asmalloc, memleak
+@c       build_wcs_upper_buffer dup glocale, asynconsist, asmalloc, selfdeadlock, shlimb, incansist, lockleak, memleak, fdleak
+@c       build_upper_buffer dup ok (glocale, but optimized)
+@c       build_wcs_buffer dup asynconsist, asmalloc, selfdeadlock, shlimb, incansist, lockleak, memleak, fdleak
+@c       re_string_translate_buffer dup ok
+@c     get_subexp_sub glocale, asynconsist, asmalloc, selfdeadlock, shlimb, incansist, lockleak, memleak, fdleak
+@c      check_arrival glocale, asynconsist, asmalloc, selfdeadlock, shlimb, incansist, lockleak, memleak, fdleak
+@c       (re_)realloc dup asmalloc, memleak
+@c       re_string_context_at dup ok
+@c       re_node_set_init_1 dup asmalloc, memleak
+@c       check_arrival_expand_ecl asmalloc, memleak
+@c        re_node_set_alloc dup asmalloc, memleak
+@c        find_subexp_node ok
+@c        re_node_set_merge dup asmalloc, memleak
+@c        re_node_set_free dup asmalloc, memleak
+@c        check_arrival_expand_ecl_sub asmalloc, memleak
+@c         re_node_set_contains dup ok
+@c         re_node_set_insert dup asmalloc, memleak
+@c       re_node_set_free dup asmalloc, memleak
+@c       re_node_set_init_copy dup asmalloc, memleak
+@c       re_node_set_init_empty dup ok
+@c       expand_bkref_cache asmalloc, memleak
+@c        search_cur_bkref_entry dup ok
+@c        re_node_set_contains dup ok
+@c        re_node_set_init_1 dup asmalloc, memleak
+@c        check_arrival_expand_ecl dup asmalloc, memleak
+@c        re_node_set_merge dup asmalloc, memleak
+@c        re_node_set_init_copy dup asmalloc, memleak
+@c        re_node_set_insert dup asmalloc, memleak
+@c        re_node_set_free dup asmalloc, memleak
+@c        re_acquire_state asmalloc, memleak
+@c         calc_state_hash dup ok
+@c         re_node_set_compare dup ok
+@c         create_ci_newstate asmalloc, memleak
+@c          calloc dup asmalloc, memleak
+@c          re_node_set_init_copy dup asmalloc, memleak
+@c          (re_)free dup asmalloc, memleak
+@c          register_state dup asmalloc, memleak
+@c          free_state dup asmalloc, memleak
+@c       re_acquire_state_context dup asmalloc, memleak
+@c       re_node_set_merge dup asmalloc, memleak
+@c       check_arrival_add_next_nodes glocale, asmalloc, memleak
+@c        re_node_set_init_empty dup ok
+@c        check_node_accept_bytes glocale, asmalloc, memleak
+@c         re_string_byte_at dup ok
+@c         re_string_char_size_at dup ok
+@c         re_string_elem_size_at (maybe glocale)
+@c          _NL_CURRENT_WORD dup ok
+@c          _NL_CURRENT dup ok
+@c          auto findidx dup ok
+@c         _NL_CURRENT_WORD dup ok
+@c         _NL_CURRENT dup ok
+@c         collseq_table_lookup dup ok
+@c         find_collation_sequence_value (maybe glocale)
+@c          _NL_CURRENT_WORD dup ok
+@c          _NL_CURRENT dup ok
+@c         auto findidx dup ok
+@c         wcscoll glocale, asmalloc, memleak
+@c        re_node_set_empty dup ok
+@c        re_node_set_merge dup asmalloc, memleak
+@c        re_node_set_free dup asmalloc, memleak
+@c        re_node_set_insert dup asmalloc, memleak
+@c        re_acquire_state dup asmalloc, memleak
+@c        check_node_accept ok
+@c         re_string_byte_at dup ok
+@c         bitset_contain dup ok
+@c         re_string_context_at dup ok
+@c         NOT_SATISFY_NEXT_CONSTRAINT dup ok
+@c      match_ctx_add_entry asmalloc, memleak
+@c       (re_)realloc dup asmalloc, memleak
+@c       (re_)free dup asmalloc, memleak
+@c      clean_state_log_if_needed dup glocale, asynconsist, asmalloc, selfdeadlock, shlimb, incansist, lockleak, memleak, fdleak
+@c     extend_buffers dup glocale, asynconsist, asmalloc, selfdeadlock, shlimb, incansist, lockleak, memleak, fdleak
+@c     find_subexp_node dup ok
+@c     calloc dup asmalloc, memleak
+@c     check_arrival dup ***
+@c     match_ctx_add_sublast asmalloc, memleak
+@c      (re_)realloc dup asmalloc, memleak
+@c    re_acquire_state_context dup asmalloc, memleak
+@c    re_node_set_init_union asmalloc, memleak
+@c     (re_)malloc dup asmalloc, memleak
+@c     re_node_set_init_copy dup asmalloc, memleak
+@c     re_node_set_init_empty dup ok
+@c    re_node_set_free dup asmalloc, memleak
+@c    check_subexp_matching_top dup asmalloc, memleak
+@c   check_halt_state_context ok
+@c    re_string_context_at dup ok
+@c    check_halt_node_context ok
+@c     NOT_SATISFY_NEXT_CONSTRAINT dup ok
+@c   re_string_eoi dup ok
+@c   extend_buffers dup glocale, asynconsist, asmalloc, selfdeadlock, shlimb, incansist, lockleak, memleak, fdleak
+@c   transit_state glocale, asynconsist, asmalloc, selfdeadlock, shlimb, incansist, lockleak, memleak, fdleak
+@c    transit_state_mb glocale, asynconsist, asmalloc, selfdeadlock, shlimb, incansist, lockleak, memleak, fdleak
+@c     re_string_context_at dup ok
+@c     NOT_SATISFY_NEXT_CONSTRAINT dup ok
+@c     check_node_accept_bytes dup glocale, asmalloc, memleak
+@c     re_string_cur_idx dup ok
+@c     clean_state_log_if_needed glocale, asynconsist, asmalloc, selfdeadlock, shlimb, incansist, lockleak, memleak, fdleak
+@c     re_node_set_init_union dup asmalloc, memleak
+@c     re_acquire_state_context dup asmalloc, memleak
+@c    re_string_fetch_byte dup ok
+@c    re_string_context_at dup ok
+@c    build_trtable asmalloc, memleak
+@c     (re_)malloc dup asmalloc, memleak
+@c     group_nodes_into_DFAstates asmalloc, memleak
+@c      bitset_empty dup ok
+@c      bitset_set dup ok
+@c      bitset_merge dup ok
+@c      bitset_set_all ok
+@c      bitset_clear ok
+@c      bitset_contain dup ok
+@c      bitset_copy ok
+@c      re_node_set_init_copy dup asmalloc, memleak
+@c      re_node_set_insert dup asmalloc, memleak
+@c      re_node_set_init_1 dup asmalloc, memleak
+@c      re_node_set_free dup asmalloc, memleak
+@c     re_node_set_alloc dup asmalloc, memleak
+@c     malloc dup asmalloc, memleak
+@c     free dup asmalloc, memleak
+@c     re_node_set_free dup asmalloc, memleak
+@c     bitset_empty ok
+@c     re_node_set_empty dup ok
+@c     re_node_set_merge dup asmalloc, memleak
+@c     re_acquire_state_context dup asmalloc, memleak
+@c     bitset_merge ok
+@c     calloc dup asmalloc, memleak
+@c     bitset_contain dup ok
+@c   merge_state_with_log glocale, asynconsist, asmalloc, selfdeadlock, shlimb, incansist, lockleak, memleak, fdleak
+@c    re_string_cur_idx dup ok
+@c    re_node_set_init_union dup asmalloc, memleak
+@c    re_string_context_at dup ok
+@c    re_node_set_free dup asmalloc, memleak
+@c    check_subexp_matching_top asmalloc, memleak
+@c     match_ctx_add_subtop dup asmalloc, memleak
+@c    transit_state_bkref dup glocale, asynconsist, asmalloc, selfdeadlock, shlimb, incansist, lockleak, memleak, fdleak
+@c   find_recover_state
+@c    re_string_cur_idx dup ok
+@c    re_string_skip_bytes dup ok
+@c    merge_state_with_log dup glocale, asynconsist, asmalloc, selfdeadlock, shlimb, incansist, lockleak, memleak, fdleak
+@c  check_halt_state_context dup ok
+@c  prune_impossible_nodes glocale, asmalloc, memleak
+@c   (re_)malloc dup asmalloc, memleak
+@c   sift_ctx_init ok
+@c    re_node_set_init_empty dup ok
+@c   sift_states_backward glocale, asmalloc, memleak
+@c    re_node_set_init_1 dup asmalloc, memleak
+@c    update_cur_sifted_state glocale, asmalloc, memleak
+@c     add_epsilon_src_nodes asmalloc, memleak
+@c      re_acquire_state dup asmalloc, memleak
+@c      re_node_set_alloc dup asmalloc, memleak
+@c      re_node_set_merge dup asmalloc, memleak
+@c      re_node_set_add_intersect asmalloc, memleak
+@c       (re_)realloc dup asmalloc, memleak
+@c     check_subexp_limits asmalloc, memleak
+@c      sub_epsilon_src_nodes asmalloc, memleak
+@c       re_node_set_init_empty dup ok
+@c       re_node_set_contains dup ok
+@c       re_node_set_add_intersect dup asmalloc, memleak
+@c       re_node_set_free dup asmalloc, memleak
+@c       re_node_set_remove_at dup ok
+@c      re_node_set_contains dup ok
+@c     re_acquire_state dup asmalloc, memleak
+@c     sift_states_bkref glocale, asmalloc, memleak
+@c      search_cur_bkref_entry dup ok
+@c      check_dst_limits ok
+@c       search_cur_bkref_entry dup ok
+@c       check_dst_limits_calc_pos ok
+@c        check_dst_limits_calc_pos_1 ok
+@c      re_node_set_init_copy dup asmalloc, memleak
+@c      re_node_set_insert dup asmalloc, memleak
+@c      sift_states_backward dup glocale, asmalloc, memleak
+@c      merge_state_array dup asmalloc, memleak
+@c      re_node_set_remove ok
+@c       re_node_set_contains dup ok
+@c       re_node_set_remove_at dup ok
+@c      re_node_set_free dup asmalloc, memleak
+@c    re_node_set_free dup asmalloc, memleak
+@c    re_node_set_empty dup ok
+@c    build_sifted_states glocale, asmalloc, memleak
+@c     sift_states_iter_mb glocale, asmalloc, memleak
+@c      check_node_accept_bytes dup glocale, asmalloc, memleak
+@c     check_node_accept dup ok
+@c     check_dst_limits dup ok
+@c     re_node_set_insert dup asmalloc, memleak
+@c   re_node_set_free dup asmalloc, memleak
+@c   check_halt_state_context dup ok
+@c   merge_state_array asmalloc, memleak
+@c    re_node_set_init_union dup asmalloc, memleak
+@c    re_acquire_state dup asmalloc, memleak
+@c    re_node_set_free dup asmalloc, memleak
+@c   (re_)free dup asmalloc, memleak
+@c  set_regs asmalloc, memleak
+@c   (re_)malloc dup asmalloc, memleak
+@c   re_node_set_init_empty dup ok
+@c   free_fail_stack_return asmalloc, memleak
+@c    re_node_set_free dup asmalloc, memleak
+@c    (re_)free dup asmalloc, memleak
+@c   update_regs ok
+@c   re_node_set_free dup asmalloc, memleak
+@c   pop_fail_stack asmalloc, memleak
+@c    re_node_set_free dup asmalloc, memleak
+@c    (re_)free dup asmalloc, memleak
+@c   (re_)free dup asmalloc, memleak
+@c  (re_)free dup asmalloc, memleak
+@c  match_ctx_free asmalloc, memleak
+@c   match_ctx_clean asmalloc, memleak
+@c    (re_)free dup asmalloc, memleak
+@c   (re_)free dup asmalloc, memleak
+@c  re_string_destruct dup asmalloc, memleak
+@c libc_lock_unlock lockleak
 This function tries to match the compiled regular expression
 @code{*@var{compiled}} against @var{string}.
 
@@ -1044,6 +1625,9 @@ free the storage it uses by calling @code{regfree}.
 @comment regex.h
 @comment POSIX.2
 @deftypefun void regfree (regex_t *@var{compiled})
+@safety{@mtsafe{}@asunsafe{asmalloc}@acunsafe{memleak}}
+@c (re_)free dup asmalloc, memleak
+@c free_dfa_content dup asmalloc, memleak
 Calling @code{regfree} frees all the storage that @code{*@var{compiled}}
 points to.  This includes various internal fields of the @code{regex_t}
 structure that aren't documented in this manual.
@@ -1061,6 +1645,8 @@ the function @code{regerror} to turn it into an error message string.
 @comment regex.h
 @comment POSIX.2
 @deftypefun size_t regerror (int @var{errcode}, const regex_t *restrict @var{compiled}, char *restrict @var{buffer}, size_t @var{length})
+@safety{@mtunsafe{envromt}@asunsafe{asynconsist, asmalloc, selfdeadlock, shlimb}@acunsafe{incansist, lockleak, fdleak, memleak, shlimb}}
+@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
 starting at @var{buffer}.  For the @var{compiled} argument, supply the
@@ -1226,6 +1812,145 @@ the beginning of the vector.
 @comment wordexp.h
 @comment POSIX.2
 @deftypefun int wordexp (const char *@var{words}, wordexp_t *@var{word-vector-ptr}, int @var{flags})
+@safety{@mtunsafe{staticbuf, envromt, tempsig, stimer, glocale}@asunsafe{shlimb, uplugin, asi18n, asmalloc, asynconsist, selfdeadlock}@acunsafe{incansist, lockleak, fdleak, memleak}}
+@c wordexp staticbuf, envromt, tempsig, stimer, glocale, shlimb, uplugin, asi18n, asmalloc, asynconsist, selfdeadlock, incansist, lockleak, fdleak, memleak
+@c  w_newword ok
+@c  wordfree dup asynconsist, asmalloc, incansist, memleak
+@c  calloc dup asmalloc, memleak
+@c  getenv dup envromt
+@c  strcpy dup ok
+@c  parse_backslash asmalloc, memleak
+@c   w_addchar dup asmalloc, memleak
+@c  parse_dollars glocale, envromt, shlimb, uplugin, asi18n, asmalloc, selfdeadlock, incansist, lockleak, fdleak, memleak
+@c   w_addchar dup asmalloc, memleak
+@c   parse_arith glocale, envromt, shlimb, uplugin, asi18n, asmalloc, selfdeadlock, incansist, lockleak, fdleak, memleak
+@c    w_newword dup ok
+@c    parse_dollars dup glocale, envromt, shlimb, uplugin, asi18n, asmalloc, selfdeadlock, incansist, lockleak, fdleak, memleak
+@c    parse_backtick dup uplugin, asmalloc, lockleak, fdleak, memleak
+@c    parse_qtd_backslash dup asmalloc, memleak
+@c    eval_expr glocale
+@c     eval_expr_multidiv glocale
+@c      eval_expr_val glocale^
+@c       isspace dup glocale^^
+@c       eval_expr dup glocale
+@c      isspace dup glocale^^
+@c     isspace dup glocale^^
+@c    free dup asmalloc, memleak
+@c    w_addchar dup asmalloc, memleak
+@c    w_addstr dup asmalloc, memleak
+@c    itoa_word dup ok
+@c   parse_comm uplugin, asmalloc, lockleak, fdleak, memleak
+@c    w_newword dup ok
+@c    pthread_setcancelstate uplugin, asmalloc, memleak
+@c      (disable cancellation around exec_comm; it may do_cancel the
+@c       second time, if async cancel is enabled)
+@c     THREAD_ATOMIC_CMPXCHG_VAL dup ok
+@c     CANCEL_ENABLED_AND_CANCELED_AND_ASYNCHRONOUS dup ok
+@c     do_cancel uplugin, asmalloc, memleak
+@c      THREAD_ATOMIC_BIT_SET dup ok
+@c      pthread_unwind uplugin, asmalloc, memleak
+@c       Unwind_ForcedUnwind if available uplugin, asmalloc, memleak
+@c       libc_unwind_longjmp otherwise
+@c       cleanups
+@c    exec_comm uplugin, asmalloc, lockleak, fdleak, memleak
+@c     pipe2 dup ok
+@c     pipe dup ok
+@c     fork dup uplugin, lockleak
+@c     close dup fdleak
+@c     on child: exec_comm_child -> exec or abort
+@c     waitpid dup ok
+@c     read dup ok
+@c     w_addmem dup asmalloc, memleak
+@c     strchr dup ok
+@c     w_addword dup asmalloc, memleak
+@c     w_newword dup ok
+@c     w_addchar dup asmalloc, memleak
+@c     free dup asmalloc, memleak
+@c     kill dup ok
+@c    free dup asmalloc, memleak
+@c   parse_param glocale, envromt, shlimb, uplugin, asi18n, asmalloc, selfdeadlock, incansist, lockleak, fdleak, memleak
+@c     reads from __libc_argc and __libc_argv without guards
+@c    w_newword dup ok
+@c    isalpha dup glocale^^
+@c    w_addchar dup asmalloc, memleak
+@c    isalnum dup glocale^^
+@c    isdigit dup glocale^^
+@c    strchr dup ok
+@c    itoa_word dup ok
+@c    atoi dup glocale
+@c    getpid dup ok
+@c    w_addstr dup asmalloc, memleak
+@c    free dup asmalloc, memleak
+@c    strlen dup ok
+@c    malloc dup asmalloc, memleak
+@c    stpcpy dup ok
+@c    w_addword dup asmalloc, memleak
+@c    strdup dup asmalloc, memleak
+@c    getenv dup envromt
+@c    parse_dollars dup glocale, envromt, shlimb, uplugin, asi18n, asmalloc, selfdeadlock, incansist, lockleak, fdleak, memleak
+@c    parse_tilde dup glocale, envromt, shlimb, uplugin, asmalloc, selfdeadlock, incansist, lockleak, fdleak, memleak
+@c    fnmatch dup envromt, glocale, asmalloc, memleak
+@c    mempcpy dup ok
+@c    _ dup asi18n
+@c    fxprintf dup lockleak
+@c    setenv dup asmalloc, selfdeadlock, incansist, lockleak, memleak
+@c    strspn dup ok
+@c    strcspn dup ok
+@c  parse_backtick uplugin, asmalloc, lockleak, fdleak, memleak
+@c   w_newword dup ok
+@c   exec_comm dup uplugin, asmalloc, lockleak, fdleak, memleak
+@c   free dup asmalloc, memleak
+@c   parse_qtd_backslash dup asmalloc, memleak
+@c   parse_backslash dup asmalloc, memleak
+@c   w_addchar dup asmalloc, memleak
+@c  parse_dquote glocale, envromt, shlimb, uplugin, asi18n, asmalloc, selfdeadlock, incansist, lockleak, fdleak, memleak
+@c   parse_dollars dup glocale, envromt, shlimb, uplugin, asi18n, asmalloc, selfdeadlock, incansist, lockleak, fdleak, memleak
+@c   parse_backtick dup uplugin, asmalloc, lockleak, fdleak, memleak
+@c   parse_qtd_backslash dup asmalloc, memleak
+@c   w_addchar dup asmalloc, memleak
+@c  w_addword dup asmalloc, memleak
+@c   strdup dup asmalloc, memleak
+@c   realloc dup asmalloc, memleak
+@c   free dup asmalloc, memleak
+@c  parse_squote dup asmalloc, memleak
+@c   w_addchar dup asmalloc, memleak
+@c  parse_tilde glocale, envromt, shlimb, uplugin, asmalloc, selfdeadlock, incansist, lockleak, fdleak, memleak
+@c   strchr dup ok
+@c   w_addchar dup asmalloc, memleak
+@c   getenv dup envromt
+@c   w_addstr dup asmalloc, memleak
+@c    strlen dup ok
+@c    w_addmem dup asmalloc, memleak
+@c     realloc dup asmalloc, memleak
+@c     free dup asmalloc, memleak
+@c     mempcpy dup ok
+@c   getuid dup ok
+@c   getpwuid_r dup glocale, shlimb, uplugin, asmalloc, selfdeadlock, incansist, lockleak, fdleak, memleak
+@c   getpwnam_r dup glocale, shlimb, uplugin, asmalloc, selfdeadlock, incansist, lockleak, fdleak, memleak
+@c  parse_glob staticbuf, envromt, tempsig, stimer, glocale, shlimb, uplugin, asi18n, asmalloc, selfdeadlock, incansist, lockleak, fdleak, memleak
+@c   strchr dup ok
+@c   parse_dollars dup glocale, envromt, shlimb, uplugin, asi18n, asmalloc, selfdeadlock, incansist, lockleak, fdleak, memleak
+@c   parse_qtd_backslash asmalloc, memleak
+@c    w_addchar dup asmalloc, memleak
+@c   parse_backslash dup asmalloc, memleak
+@c   w_addchar dup asmalloc, memleak
+@c   w_addword dup asmalloc, memleak
+@c   w_newword dup ok
+@c   do_parse_glob staticbuf, envromt, tempsig, stimer, glocale, shlimb, uplugin, asmalloc, selfdeadlock, lockleak, fdleak, memleak
+@c    glob dup staticbuf, envromt, tempsig, stimer, glocale, shlimb, uplugin, asmalloc, selfdeadlock, lockleak, fdleak, memleak [auto glob_t avoids asynconsist, incansist]
+@c    w_addstr dup asmalloc, memleak
+@c    w_addchar dup asmalloc, memleak
+@c    globfree dup asmalloc, memleak [auto glob_t avoids asynconsist, incansist]
+@c    free dup asmalloc, memleak
+@c    w_newword dup ok
+@c    strdup dup asmalloc, memleak
+@c    w_addword dup asmalloc, memleak
+@c   wordfree dup asynconsist, asmalloc, incansist, memleak
+@c  strchr dup ok
+@c  w_addchar dup asmalloc, memleak
+@c   realloc dup asmalloc, memleak
+@c   free dup asmalloc, memleak
+@c  free dup asmalloc, memleak
 Perform word expansion on the string @var{words}, putting the result in
 a newly allocated vector, and store the size and address of this vector
 into @code{*@var{word-vector-ptr}}.  The argument @var{flags} is a
@@ -1289,6 +2014,9 @@ quoting character is a syntax error.
 @comment wordexp.h
 @comment POSIX.2
 @deftypefun void wordfree (wordexp_t *@var{word-vector-ptr})
+@safety{@mtsafe{}@asunsafe{asynconsist, asmalloc}@acunsafe{incansist, memleak}}
+@c wordfree dup asynconsist, asmalloc, incansist, memleak
+@c  free dup asmalloc, memleak
 Free the storage used for the word-strings and vector that
 @code{*@var{word-vector-ptr}} points to.  This does not free the
 structure @code{*@var{word-vector-ptr}} itself---only the other

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=fae3b2eebe8d9467cc023cef7ea032631b82775a

commit fae3b2eebe8d9467cc023cef7ea032631b82775a
Author: Alexandre Oliva <aoliva@redhat.com>
Date:   Fri Nov 8 06:08:20 2013 -0200

    MT-, AS- and AC-safety docs: manual/locale.texi
    
    for  ChangeLog
    
    	* manual/locale.texi: Document MTASC-safety properties.

diff --git a/manual/locale.texi b/manual/locale.texi
index 2f10fcd..4afa104 100644
--- a/manual/locale.texi
+++ b/manual/locale.texi
@@ -224,6 +224,137 @@ The symbols in this section are defined in the header file @file{locale.h}.
 @comment locale.h
 @comment ISO
 @deftypefun {char *} setlocale (int @var{category}, const char *@var{locale})
+@safety{@mtunsafe{uunguard, envromt}@asunsafe{oncesafe, selfdeadlock, asmalloc, asynconsist, incansist}@acunsafe{oncesafe, incansist, lockleak, memleak, fdleak}}
+@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 This function returns a pointer read...
+@c setlocale envromt, oncesafe, asmalloc, selfdeadlock, asynconsist, incansist, memleak, fdleak, lockleak
+@c  libc_rwlock_wrlock selfdeadlock, lockleak
+@c  libc_rwlock_unlock lockleak
+@c  getenv LOCPATH envromt
+@c  malloc asmalloc, memleak
+@c  free asmalloc, memleak
+@c  new_composite_name ok
+@c  setdata ok
+@c  setname ok
+@c  _nl_find_locale envromt, oncesafe, asmalloc, selfdeadlock, asynconsist, incansist, memleak, fdleak, lockleak
+@c   getenv LC_ALL and LANG envromt
+@c   _nl_load_locale_from_archive asmalloc, memleak, fdleak
+@c    sysconf _SC_PAGE_SIZE ok
+@c    _nl_normalize_codeset asmalloc, memleak
+@c     isalnum_l ok (C locale)
+@c     isdigit_l ok (C locale)
+@c     malloc asmalloc, memleak
+@c     tolower_l ok (C locale)
+@c    open_not_cancel_2 fdleak
+@c    fxstat64 ok
+@c    close_not_cancel_no_status ok
+@c    __mmap64 memleak
+@c    calculate_head_size ok
+@c    __munmap ok
+@c    compute_hashval ok
+@c    qsort dup asmalloc, memleak
+@c     rangecmp ok
+@c    malloc asmalloc, memleak
+@c    strdup asmalloc, memleak
+@c    _nl_intern_locale_data asmalloc, memleak
+@c     malloc asmalloc, memleak
+@c     free asmalloc, memleak
+@c   _nl_expand_alias asmalloc, selfdeadlock, memleak, fdleak, lockleak
+@c    libc_lock_lock selfdeadlock, lockleak
+@c    bsearch ok
+@c     alias_compare ok
+@c      strcasecmp ok
+@c    read_alias_file asmalloc, selfdeadlock, memleak, fdleak, lockleak
+@c     fopen asmalloc, selfdeadlock, memleak, fdleak, lockleak
+@c     fsetlocking ok
+@c     feof_unlocked ok
+@c     fgets_unlocked ok
+@c     isspace ok (locale mutex is locked)
+@c     extend_alias_table memleak, asmalloc
+@c      realloc memleak, asmalloc
+@c     realloc memleak, asmalloc
+@c     fclose asmalloc, selfdeadlock, memleak, fdleak, lockleak
+@c     qsort asmalloc, memleak
+@c      alias_compare dup
+@c    libc_lock_unlock lockleak
+@c   _nl_explode_name asmalloc, memleak
+@c    _nl_find_language ok
+@c    _nl_normalize_codeset dup asmalloc, memleak
+@c   _nl_make_l10nflist asmalloc, memleak
+@c    malloc asmalloc, memleak
+@c    free asmalloc, memleak
+@c    __argz_stringify ok
+@c    __argz_count ok
+@c    __argz_next ok
+@c   _nl_load_locale asmalloc, memleak, fdleak
+@c    open_not_cancel_2 fdleak
+@c    __fxstat64 ok
+@c    close_not_cancel_no_status ok
+@c    mmap memleak
+@c    malloc asmalloc, memleak
+@c    read_not_cancel ok
+@c    free asmalloc, memleak
+@c    _nl_intern_locale_data dup asmalloc, memleak
+@c    munmap ok
+@c   __gconv_compare_alias oncesafe, asmalloc, asynconsist, selfdeadlock, memleak,incansist, fdleak, lockleak
+@c    __gconv_read_conf oncesafe, asmalloc, asynconsist, selfdeadlock, memleak,incansist, fdleak, lockleak
+@c     (libc_once-initializes gconv_cache and gconv_path_envvar; they're
+@c      never modified afterwards)
+@c     __gconv_load_cache asmalloc, memleak, fdleak
+@c      getenv GCONV_PATH envromt
+@c      open_not_cancel fdleak
+@c      __fxstat64 ok
+@c      close_not_cancel_no_status ok
+@c      mmap memleak
+@c      malloc asmalloc, memleak
+@c      __read ok
+@c      free asmalloc, memleak
+@c      munmap ok
+@c     __gconv_get_path selfdeadlock, asmalloc, lockleak, memleak, fdleak
+@c      getcwd asmalloc, memleak, fdleak
+@c      libc_lock_lock selfdeadlock, lockleak
+@c      malloc asmalloc, memleak
+@c      strtok_r ok
+@c      libc_lock_unlock lockleak
+@c     read_conf_file asmalloc, asynconsist, selfdeadlock, memleak, incansist, fdleak, lockleak
+@c      fopen asmalloc, selfdeadlock, memleak, fdleak, lockleak
+@c      fsetlocking ok
+@c      feof_unlocked ok
+@c      getdelim asmalloc, asynconsist, memleak, incansist
+@c      isspace_l ok (C locale)
+@c      add_alias
+@c       isspace_l ok (C locale)
+@c       toupper_l ok (C locale)
+@c       add_alias2 dup asynconsist, asmalloc, incansist, memleak
+@c      add_module asmalloc, memleak
+@c       isspace_l ok (C locale)
+@c       toupper_l ok (C locale)
+@c       strtol ok (glocale, but we hold the locale lock)
+@c       tfind __gconv_alias_db ok
+@c        __gconv_alias_compare dup ok
+@c       calloc asmalloc, memleak
+@c       insert_module dup asmalloc
+@c     __tfind ok (because the tree is read only by then)
+@c      __gconv_alias_compare dup ok
+@c     insert_module asmalloc
+@c      free asmalloc
+@c     add_alias2 asynconsist, asmalloc, incansist, memleak
+@c      detect_conflict ok, reads __gconv_modules_db
+@c      malloc asmalloc, memleak
+@c      tsearch __gconv_alias_db asynconsist, asmalloc, incansist, memleak
+@c       __gconv_alias_compare ok
+@c      free asmalloc
+@c    __gconv_compare_alias_cache ok
+@c     find_module_idx ok
+@c    do_lookup_alias ok
+@c     __tfind ok (because the tree is read only by then)
+@c      __gconv_alias_compare ok
+@c   strndup asmalloc, memleak
+@c   strcasecmp_l ok (C locale)
 The function @code{setlocale} sets the current locale for category
 @var{category} to @var{locale}.  A list of all the locales the system
 provides can be created by running
@@ -414,6 +545,10 @@ according to the selected locale using this information.
 @comment locale.h
 @comment ISO
 @deftypefun {struct lconv *} localeconv (void)
+@safety{@mtunsafe{staticbuf, glocale}@assafe{}@acsafe{}}
+@c This function reads from multiple components of the locale object,
+@c without synchronization, while writing to the static buffer it uses
+@c as the return value.
 The @code{localeconv} function returns a pointer to a structure whose
 components contain information about how numeric and monetary values
 should be formatted in the current locale.
@@ -680,6 +815,10 @@ was introduced.
 @comment langinfo.h
 @comment XOPEN
 @deftypefun {char *} nl_langinfo (nl_item @var{item})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
+@c It calls _nl_langinfo_l with the current locale, which returns a
+@c pointer into constant strings defined in locale data structures.  It
+@c doesn't run afoul of glocale itself, but callers may.
 The @code{nl_langinfo} function can be used to access individual
 elements of the locale categories.  Unlike the @code{localeconv}
 function, which returns all the information, @code{nl_langinfo}
@@ -974,6 +1113,11 @@ locale information, making it easier for the user to format
 numbers according to these rules.
 
 @deftypefun ssize_t strfmon (char *@var{s}, size_t @var{maxsize}, const char *@var{format}, @dots{})
+@safety{@mtsafe{glocale}@asunsafe{asmalloc}@acsafe{memleak}}
+@c It (and strfmon_l) both call vstrfmon_l, which, besides accessing the
+@c locale object passed to it, accesses the active locale through
+@c isdigit (but to_digit assumes ASCII digits only).  It may call
+@c __printf_fp (glocale, asmalloc, memleak) and guess_grouping (safe).
 The @code{strfmon} function is similar to the @code{strftime} function
 in that it takes a buffer, its size, a format string,
 and values to write into the buffer as text in a form specified
@@ -1185,6 +1329,10 @@ access to the corresponding locale definitions.
 @comment GNU
 @comment stdlib.h
 @deftypefun int rpmatch (const char *@var{response})
+@safety{@mtsafe{glocale}@asunsafe{asynconsist, asmalloc, selfdeadlock, shlimb}@acunsafe{incansist, lockleak, memleak, fdleak, shlimb}}
+@c Calls nl_langinfo with YESEXPR and NOEXPR, triggering glocale, but
+@c it's regcomp and regexec that bring in all of the safety issues.
+@c regfree is also called, but it doesn't introduce any further issues.
 The function @code{rpmatch} checks the string in @var{response} whether
 or not it is a correct yes-or-no answer and if yes, which one.  The
 check uses the @code{YESEXPR} and @code{NOEXPR} data in the

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=2d1e6d2272a7f1bac43155b990b7fed984397297

commit 2d1e6d2272a7f1bac43155b990b7fed984397297
Author: Alexandre Oliva <aoliva@redhat.com>
Date:   Fri Nov 8 06:08:20 2013 -0200

    MT-, AS- and AC-safety docs: manual/llio.texi
    
    for ChangeLog
    
    	* manual/llio.texi: Document MTASC-safety properties.

diff --git a/manual/llio.texi b/manual/llio.texi
index dd0eaa3..299e8f6 100644
--- a/manual/llio.texi
+++ b/manual/llio.texi
@@ -78,6 +78,7 @@ declared in @file{unistd.h}.
 @comment fcntl.h
 @comment POSIX.1
 @deftypefun int open (const char *@var{filename}, int @var{flags}[, mode_t @var{mode}])
+@safety{@mtsafe{}@assafe{}@acsafe{fdleak}}
 The @code{open} function creates and returns a new file descriptor for
 the file named by @var{filename}.  Initially, the file position
 indicator for the file is at the beginning of the file.  The argument
@@ -164,6 +165,7 @@ and @code{freopen} functions, that create streams.
 @comment fcntl.h
 @comment Unix98
 @deftypefun int open64 (const char *@var{filename}, int @var{flags}[, mode_t @var{mode}])
+@safety{@mtsafe{}@assafe{}@acsafe{fdleak}}
 This function is similar to @code{open}.  It returns a file descriptor
 which can be used to access the file named by @var{filename}.  The only
 difference is that on 32 bit systems the file is opened in the
@@ -178,6 +180,7 @@ replaces the old API.
 @comment fcntl.h
 @comment POSIX.1
 @deftypefn {Obsolete function} int creat (const char *@var{filename}, mode_t @var{mode})
+@safety{@mtsafe{}@assafe{}@acsafe{fdleak}}
 This function is obsolete.  The call:
 
 @smallexample
@@ -202,6 +205,7 @@ since all of the lowlevel file handling functions are equally replaced.
 @comment fcntl.h
 @comment Unix98
 @deftypefn {Obsolete function} int creat64 (const char *@var{filename}, mode_t @var{mode})
+@safety{@mtsafe{}@assafe{}@acsafe{fdleak}}
 This function is similar to @code{creat}.  It returns a file descriptor
 which can be used to access the file named by @var{filename}.  The only
 the difference is that on 32 bit systems the file is opened in the
@@ -219,6 +223,7 @@ replaces the old API.
 @comment unistd.h
 @comment POSIX.1
 @deftypefun int close (int @var{filedes})
+@safety{@mtsafe{}@assafe{}@acsafe{fdleak}}
 The function @code{close} closes the file descriptor @var{filedes}.
 Closing a file has the following consequences:
 
@@ -300,6 +305,7 @@ but must be a signed type.
 @comment unistd.h
 @comment POSIX.1
 @deftypefun ssize_t read (int @var{filedes}, void *@var{buffer}, size_t @var{size})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 The @code{read} function reads up to @var{size} bytes from the file
 with descriptor @var{filedes}, storing the results in the @var{buffer}.
 (This is not necessarily a character string, and no terminating null
@@ -395,6 +401,10 @@ functions that read from streams, such as @code{fgetc}.
 @comment unistd.h
 @comment Unix98
 @deftypefun ssize_t pread (int @var{filedes}, void *@var{buffer}, size_t @var{size}, off_t @var{offset})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
+@c This is usually a safe syscall.  The sysdeps/posix fallback emulation
+@c is not MT-Safe because it uses lseek, read and lseek back, but is it
+@c used anywhere?
 The @code{pread} function is similar to the @code{read} function.  The
 first three arguments are identical, and the return values and error
 codes also correspond.
@@ -430,6 +440,10 @@ version 2.
 @comment unistd.h
 @comment Unix98
 @deftypefun ssize_t pread64 (int @var{filedes}, void *@var{buffer}, size_t @var{size}, off64_t @var{offset})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
+@c This is usually a safe syscall.  The sysdeps/posix fallback emulation
+@c is not MT-Safe because it uses lseek64, read and lseek64 back, but is
+@c it used anywhere?
 This function is similar to the @code{pread} function.  The difference
 is that the @var{offset} parameter is of type @code{off64_t} instead of
 @code{off_t} which makes it possible on 32 bit machines to address
@@ -447,6 +461,7 @@ When the source file is compiled with @code{_FILE_OFFSET_BITS == 64} on a
 @comment unistd.h
 @comment POSIX.1
 @deftypefun ssize_t write (int @var{filedes}, const void *@var{buffer}, size_t @var{size})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 The @code{write} function writes up to @var{size} bytes from
 @var{buffer} to the file with descriptor @var{filedes}.  The data in
 @var{buffer} is not necessarily a character string and a null character is
@@ -557,6 +572,10 @@ functions that write to streams, such as @code{fputc}.
 @comment unistd.h
 @comment Unix98
 @deftypefun ssize_t pwrite (int @var{filedes}, const void *@var{buffer}, size_t @var{size}, off_t @var{offset})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
+@c This is usually a safe syscall.  The sysdeps/posix fallback emulation
+@c is not MT-Safe because it uses lseek, write and lseek back, but is it
+@c used anywhere?
 The @code{pwrite} function is similar to the @code{write} function.  The
 first three arguments are identical, and the return values and error codes
 also correspond.
@@ -592,6 +611,10 @@ version 2.
 @comment unistd.h
 @comment Unix98
 @deftypefun ssize_t pwrite64 (int @var{filedes}, const void *@var{buffer}, size_t @var{size}, off64_t @var{offset})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
+@c This is usually a safe syscall.  The sysdeps/posix fallback emulation
+@c is not MT-Safe because it uses lseek64, write and lseek64 back, but
+@c is it used anywhere?
 This function is similar to the @code{pwrite} function.  The difference
 is that the @var{offset} parameter is of type @code{off64_t} instead of
 @code{off_t} which makes it possible on 32 bit machines to address
@@ -624,6 +647,7 @@ To read the current file position value from a descriptor, use
 @comment unistd.h
 @comment POSIX.1
 @deftypefun off_t lseek (int @var{filedes}, off_t @var{offset}, int @var{whence})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 The @code{lseek} function is used to change the file position of the
 file with descriptor @var{filedes}.
 
@@ -713,6 +737,7 @@ descriptors.
 @comment unistd.h
 @comment Unix98
 @deftypefun off64_t lseek64 (int @var{filedes}, off64_t @var{offset}, int @var{whence})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 This function is similar to the @code{lseek} function.  The difference
 is that the @var{offset} parameter is of type @code{off64_t} instead of
 @code{off_t} which makes it possible on 32 bit machines to address
@@ -825,6 +850,7 @@ declared in the header file @file{stdio.h}.
 @comment stdio.h
 @comment POSIX.1
 @deftypefun {FILE *} fdopen (int @var{filedes}, const char *@var{opentype})
+@safety{@mtsafe{}@asunsafe{asmalloc, selfdeadlock}@acunsafe{memleak, lockleak}}
 The @code{fdopen} function returns a new stream for the file descriptor
 @var{filedes}.
 
@@ -853,6 +879,7 @@ see @ref{Creating a Pipe}.
 @comment stdio.h
 @comment POSIX.1
 @deftypefun int fileno (FILE *@var{stream})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 This function returns the file descriptor associated with the stream
 @var{stream}.  If an error is detected (for example, if the @var{stream}
 is not valid) or if @var{stream} does not do I/O to a file,
@@ -862,6 +889,7 @@ is not valid) or if @var{stream} does not do I/O to a file,
 @comment stdio.h
 @comment GNU
 @deftypefun int fileno_unlocked (FILE *@var{stream})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 The @code{fileno_unlocked} function is equivalent to the @code{fileno}
 function except that it does not implicitly lock the stream if the state
 is @code{FSETLOCKING_INTERNAL}.
@@ -1071,6 +1099,11 @@ Contains the length of the buffer.
 @comment sys/uio.h
 @comment BSD
 @deftypefun ssize_t readv (int @var{filedes}, const struct iovec *@var{vector}, int @var{count})
+@safety{@mtsafe{}@assafe{asmalloc}@acsafe{memleak}}
+@c The fallback sysdeps/posix implementation, used even on GNU/Linux
+@c with old kernels that lack a full readv/writev implementation, may
+@c malloc the buffer into which data is read, if the total read size is
+@c too large for alloca.
 
 The @code{readv} function reads data from @var{filedes} and scatters it
 into the buffers described in @var{vector}, which is taken to be
@@ -1089,6 +1122,11 @@ errors are the same as in @code{read}.
 @comment sys/uio.h
 @comment BSD
 @deftypefun ssize_t writev (int @var{filedes}, const struct iovec *@var{vector}, int @var{count})
+@safety{@mtsafe{}@assafe{asmalloc}@acsafe{memleak}}
+@c The fallback sysdeps/posix implementation, used even on GNU/Linux
+@c with old kernels that lack a full readv/writev implementation, may
+@c malloc the buffer from which data is written, if the total write size
+@c is too large for alloca.
 
 The @code{writev} function gathers data from the buffers described in
 @var{vector}, which is taken to be @var{count} structures long, and writes
@@ -1149,6 +1187,7 @@ These functions are declared in @file{sys/mman.h}.
 @comment sys/mman.h
 @comment POSIX
 @deftypefun {void *} mmap (void *@var{address}, size_t @var{length}, int @var{protect}, int @var{flags}, int @var{filedes}, off_t @var{offset})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 
 The @code{mmap} function creates a new mapping, connected to bytes
 (@var{offset}) to (@var{offset} + @var{length} - 1) in the file open on
@@ -1268,6 +1307,9 @@ The file is on a filesystem that doesn't support mapping.
 @comment sys/mman.h
 @comment LFS
 @deftypefun {void *} mmap64 (void *@var{address}, size_t @var{length}, int @var{protect}, int @var{flags}, int @var{filedes}, off64_t @var{offset})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
+@c The page_shift auto detection when MMAP2_PAGE_SHIFT is -1 (it never
+@c is) would be thread-unsafe.
 The @code{mmap64} function is equivalent to the @code{mmap} function but
 the @var{offset} parameter is of type @code{off64_t}.  On 32-bit systems
 this allows the file associated with the @var{filedes} descriptor to be
@@ -1284,6 +1326,7 @@ replaces the old API.
 @comment sys/mman.h
 @comment POSIX
 @deftypefun int munmap (void *@var{addr}, size_t @var{length})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 
 @code{munmap} removes any memory maps from (@var{addr}) to (@var{addr} +
 @var{length}).  @var{length} should be the length of the mapping.
@@ -1310,6 +1353,7 @@ aligned.
 @comment sys/mman.h
 @comment POSIX
 @deftypefun int msync (void *@var{address}, size_t @var{length}, int @var{flags})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 
 When using shared mappings, the kernel can write the file at any time
 before the mapping is removed.  To be certain data has actually been
@@ -1357,6 +1401,7 @@ There is no existing mapping in at least part of the given region.
 @comment sys/mman.h
 @comment GNU
 @deftypefun {void *} mremap (void *@var{address}, size_t @var{length}, size_t @var{new_length}, int @var{flag})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 
 This function can be used to change the size of an existing memory
 area. @var{address} and @var{length} must cover a region entirely mapped
@@ -1405,6 +1450,7 @@ Coding Standards}.
 @comment sys/mman.h
 @comment POSIX
 @deftypefun int madvise (void *@var{addr}, size_t @var{length}, int @var{advice})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 
 This function can be used to provide the system with @var{advice} about
 the intended usage patterns of the memory region starting at @var{addr}
@@ -1531,6 +1577,7 @@ that descriptor into an @code{fd_set}.
 @comment sys/types.h
 @comment BSD
 @deftypefn Macro void FD_ZERO (fd_set *@var{set})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 This macro initializes the file descriptor set @var{set} to be the
 empty set.
 @end deftypefn
@@ -1538,6 +1585,9 @@ empty set.
 @comment sys/types.h
 @comment BSD
 @deftypefn Macro void FD_SET (int @var{filedes}, fd_set *@var{set})
+@safety{@mtsafe{xguargs}@assafe{}@acsafe{}}
+@c Setting a bit isn't necessarily atomic, so there's a potential race
+@c here if set is not used exclusively.
 This macro adds @var{filedes} to the file descriptor set @var{set}.
 
 The @var{filedes} parameter must not have side effects since it is
@@ -1547,6 +1597,9 @@ evaluated more than once.
 @comment sys/types.h
 @comment BSD
 @deftypefn Macro void FD_CLR (int @var{filedes}, fd_set *@var{set})
+@safety{@mtsafe{xguargs}@assafe{}@acsafe{}}
+@c Setting a bit isn't necessarily atomic, so there's a potential race
+@c here if set is not used exclusively.
 This macro removes @var{filedes} from the file descriptor set @var{set}.
 
 The @var{filedes} parameter must not have side effects since it is
@@ -1556,6 +1609,7 @@ evaluated more than once.
 @comment sys/types.h
 @comment BSD
 @deftypefn Macro int FD_ISSET (int @var{filedes}, const fd_set *@var{set})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 This macro returns a nonzero value (true) if @var{filedes} is a member
 of the file descriptor set @var{set}, and zero (false) otherwise.
 
@@ -1568,6 +1622,10 @@ Next, here is the description of the @code{select} function itself.
 @comment sys/types.h
 @comment BSD
 @deftypefun int select (int @var{nfds}, fd_set *@var{read-fds}, fd_set *@var{write-fds}, fd_set *@var{except-fds}, struct timeval *@var{timeout})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
+@c The select syscall is preferred, but pselect6 may be used instead,
+@c which requires converting timeout to a timespec and back.  The
+@c conversions are not atomic.
 The @code{select} function blocks the calling process until there is
 activity on any of the specified sets of file descriptors, or until the
 timeout period has expired.
@@ -1670,6 +1728,7 @@ they return.
 @comment unistd.h
 @comment X/Open
 @deftypefun void sync (void)
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 A call to this function will not return as long as there is data which
 has not been written to the device.  All dirty buffers in the kernel will
 be written and so an overall consistent system can be achieved (if no
@@ -1685,6 +1744,7 @@ committed, rather than all data in the system.  For this, @code{sync} is overkil
 @comment unistd.h
 @comment POSIX
 @deftypefun int fsync (int @var{fildes})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 The @code{fsync} function can be used to make sure all data associated with
 the open file @var{fildes} is written to the device associated with the
 descriptor.  The function call does not return unless all actions have
@@ -1722,6 +1782,7 @@ recovering of the file in case of a problem.
 @comment unistd.h
 @comment POSIX
 @deftypefun int fdatasync (int @var{fildes})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 When a call to the @code{fdatasync} function returns, it is ensured
 that all of the file data is written to the device.  For all pending I/O
 operations, the parts guaranteeing data integrity finished.
@@ -1923,6 +1984,158 @@ aiocb64}, since the LFS transparently replaces the old interface.
 @comment aio.h
 @comment POSIX.1b
 @deftypefun int aio_read (struct aiocb *@var{aiocbp})
+@safety{@mtsafe{}@asunsafe{selfdeadlock, asmalloc}@acunsafe{lockleak, memleak}}
+@c Calls aio_enqueue_request.
+@c aio_enqueue_request selfdeadlock, asmalloc, lockleak, memleak
+@c  pthread_self ok
+@c  pthread_getschedparam selfdeadlock, lockleak
+@c   lll_lock (pthread descriptor's lock) selfdeadlock, lockleak
+@c   sched_getparam ok
+@c   sched_getscheduler ok
+@c   lll_unlock lockleak
+@c  pthread_mutex_lock (aio_requests_mutex) selfdeadlock, lockleak
+@c  get_elem asmalloc, memleak, [asynconsist, incansist], [xguargs]
+@c   realloc asmalloc, memleak
+@c   calloc asmalloc, memleak
+@c  aio_create_helper_thread selfdeadlock, asmalloc, lockleak, memleak
+@c   pthread_attr_init ok
+@c   pthread_attr_setdetachstate ok
+@c   pthread_get_minstack ok
+@c   pthread_attr_setstacksize ok
+@c   sigfillset ok
+@c    memset ok
+@c    sigdelset ok [xguargs, but the caller's sigset is automatic]
+@c   SYSCALL rt_sigprocmask ok
+@c   pthread_create selfdeadlock, asmalloc, lockleak, memleak
+@c    lll_lock (default_pthread_attr_lock) selfdeadlock, lockleak
+@c    alloca/malloc asmalloc, memleak
+@c    lll_unlock lockleak
+@c    allocate_stack selfdeadlock, asmalloc, lockleak, memleak
+@c     getpagesize dup
+@c     lll_lock (default_pthread_attr_lock) selfdeadlock, lockleak
+@c     lll_unlock lockleak
+@c     _dl_allocate_tls asmalloc, memleak
+@c      _dl_allocate_tls_storage asmalloc, memleak
+@c       memalign asmalloc, memleak
+@c       memset ok
+@c       allocate_dtv dup
+@c       free asmalloc, memleak
+@c      allocate_dtv asmalloc, memleak
+@c       calloc asmalloc, memleak
+@c       INSTALL_DTV ok
+@c     list_add dup
+@c     get_cached_stack
+@c      lll_lock (stack_cache_lock) selfdeadlock, lockleak
+@c      list_for_each ok
+@c      list_entry dup
+@c      FREE_P dup
+@c      stack_list_del dup
+@c      stack_list_add dup
+@c      lll_unlock lockleak
+@c      _dl_allocate_tls_init ok
+@c       GET_DTV ok
+@c     mmap ok
+@c     atomic_increment_val ok
+@c     munmap ok
+@c     change_stack_perm ok
+@c      mprotect ok
+@c     mprotect ok
+@c     stack_list_del dup
+@c     _dl_deallocate_tls dup
+@c     munmap ok
+@c    THREAD_COPY_STACK_GUARD ok
+@c    THREAD_COPY_POINTER_GUARD ok
+@c    atomic_exchange_acq ok
+@c    lll_futex_wake ok
+@c    deallocate_stack selfdeadlock, asmalloc, lockleak, memleak
+@c     lll_lock (state_cache_lock) selfdeadlock, lockleak
+@c     stack_list_del ok
+@c      atomic_write_barrier ok
+@c      list_del ok [uunguard]
+@c      atomic_write_barrier ok
+@c     queue_stack asmalloc, memleak
+@c      stack_list_add ok
+@c       atomic_write_barrier ok
+@c       list_add ok [uunguard]
+@c       atomic_write_barrier ok
+@c      free_stacks asmalloc, memleak
+@c       list_for_each_prev_safe ok
+@c       list_entry ok
+@c       FREE_P ok
+@c       stack_list_del dup
+@c       _dl_deallocate_tls dup
+@c       munmap ok
+@c     _dl_deallocate_tls asmalloc, memleak
+@c      free asmalloc, memleak
+@c     lll_unlock lockleak
+@c    create_thread selfdeadlock, asmalloc, lockleak, memleak
+@c     td_eventword
+@c     td_eventmask
+@c     do_clone selfdeadlock, asmalloc, lockleak, memleak
+@c      PREPARE_CREATE ok
+@c      lll_lock (pd->lock) selfdeadlock, lockleak
+@c      atomic_increment ok
+@c      clone ok
+@c      atomic_decrement ok
+@c      atomic_exchange_acq ok
+@c      lll_futex_wake ok
+@c      deallocate_stack dup
+@c      sched_setaffinity ok
+@c      tgkill ok
+@c      sched_setscheduler ok
+@c     atomic_compare_and_exchange_bool_acq ok
+@c     nptl_create_event ok
+@c     lll_unlock (pd->lock) lockleak
+@c    free asmalloc, memleak
+@c   pthread_attr_destroy ok (cpuset won't be set, so free isn't called)
+@c  add_request_to_runlist ok [xguargs]
+@c  pthread_cond_signal ok
+@c  aio_free_request ok [xguargs]
+@c  pthread_mutex_unlock lockleak
+
+@c (in the new thread, initiated with clone)
+@c    start_thread ok
+@c     HP_TIMING_NOW ok
+@c     ctype_init [glocale] (in theory, but optimized into safety)
+@c     atomic_exchange_acq ok
+@c     lll_futex_wake ok
+@c     sigemptyset ok
+@c     sigaddset ok
+@c     setjmp ok
+@c     CANCEL_ASYNC -> pthread_enable_asynccancel ok
+@c      do_cancel ok
+@c       pthread_unwind ok
+@c        Unwind_ForcedUnwind or longjmp ok [asmalloc, memleak?]
+@c     lll_lock selfdeadlock, lockleak
+@c     lll_unlock selfdeadlock, lockleak
+@c     CANCEL_RESET -> pthread_disable_asynccancel ok
+@c      lll_futex_wait ok
+@c     ->start_routine ok -----
+@c     call_tls_dtors selfdeadlock, asmalloc, lockleak, memleak
+@c      user-supplied dtor
+@c      rtld_lock_lock_recursive (dl_load_lock) selfdeadlock, lockleak
+@c      rtld_lock_unlock_recursive lockleak
+@c      free asmalloc, memleak
+@c     nptl_deallocate_tsd asmalloc, memleak
+@c      tsd user-supplied dtors ok
+@c      free asmalloc, memleak
+@c     libc_thread_freeres
+@c      libc_thread_subfreeres ok
+@c     atomic_decrement_and_test ok
+@c     td_eventword ok
+@c     td_eventmask ok
+@c     atomic_compare_exchange_bool_acq ok
+@c     nptl_death_event ok
+@c     lll_robust_dead ok
+@c     getpagesize ok
+@c     madvise ok
+@c     free_tcb selfdeadlock, asmalloc, lockleak, memleak
+@c      free asmalloc, memleak
+@c      deallocate_stack selfdeadlock, asmalloc, lockleak, memleak
+@c     lll_futex_wait ok
+@c     exit_thread_inline ok
+@c      syscall(exit) ok
+
 This function initiates an asynchronous read operation.  It
 immediately returns after the operation was enqueued or when an
 error was encountered.
@@ -1988,6 +2201,7 @@ replaces the normal implementation.
 @comment aio.h
 @comment Unix98
 @deftypefun int aio_read64 (struct aiocb64 *@var{aiocbp})
+@safety{@mtsafe{}@asunsafe{selfdeadlock, asmalloc}@acunsafe{lockleak, memleak}}
 This function is similar to the @code{aio_read} function.  The only
 difference is that on @w{32 bit} machines, the file descriptor should
 be opened in the large file mode.  Internally, @code{aio_read64} uses
@@ -2006,6 +2220,7 @@ of functions with a very similar interface.
 @comment aio.h
 @comment POSIX.1b
 @deftypefun int aio_write (struct aiocb *@var{aiocbp})
+@safety{@mtsafe{}@asunsafe{selfdeadlock, asmalloc}@acunsafe{lockleak, memleak}}
 This function initiates an asynchronous write operation.  The function
 call immediately returns after the operation was enqueued or if before
 this happens an error was encountered.
@@ -2072,6 +2287,7 @@ replaces the normal implementation.
 @comment aio.h
 @comment Unix98
 @deftypefun int aio_write64 (struct aiocb64 *@var{aiocbp})
+@safety{@mtsafe{}@asunsafe{selfdeadlock, asmalloc}@acunsafe{lockleak, memleak}}
 This function is similar to the @code{aio_write} function.  The only
 difference is that on @w{32 bit} machines the file descriptor should
 be opened in the large file mode.  Internally @code{aio_write64} uses
@@ -2093,6 +2309,12 @@ operations.  It is therefore similar to a combination of @code{readv} and
 @comment aio.h
 @comment POSIX.1b
 @deftypefun int lio_listio (int @var{mode}, struct aiocb *const @var{list}[], int @var{nent}, struct sigevent *@var{sig})
+@safety{@mtsafe{}@asunsafe{selfdeadlock, asmalloc}@acunsafe{lockleak, memleak}}
+@c Call lio_listio_internal, that takes the aio_requests_mutex lock and
+@c enqueues each request.  Then, it waits for notification or prepares
+@c for it before releasing the lock.  Even though it performs memory
+@c allocation and locking of its own, it doesn't add any classes of
+@c safety issues that aren't already covered by aio_enqueue_request.
 The @code{lio_listio} function can be used to enqueue an arbitrary
 number of read and write requests at one time.  The requests can all be
 meant for the same file, all for different files or every solution in
@@ -2176,6 +2398,7 @@ transparently replaces the normal implementation.
 @comment aio.h
 @comment Unix98
 @deftypefun int lio_listio64 (int @var{mode}, struct aiocb64 *const @var{list}[], int @var{nent}, struct sigevent *@var{sig})
+@safety{@mtsafe{}@asunsafe{selfdeadlock, asmalloc}@acunsafe{lockleak, memleak}}
 This function is similar to the @code{lio_listio} function.  The only
 difference is that on @w{32 bit} machines, the file descriptor should
 be opened in the large file mode.  Internally, @code{lio_listio64} uses
@@ -2204,6 +2427,7 @@ The following two functions allow you to get this kind of information.
 @comment aio.h
 @comment POSIX.1b
 @deftypefun int aio_error (const struct aiocb *@var{aiocbp})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 This function determines the error state of the request described by the
 @code{struct aiocb} variable pointed to by @var{aiocbp}.  If the
 request has not yet terminated the value returned is always
@@ -2225,6 +2449,7 @@ transparently replaces the normal implementation.
 @comment aio.h
 @comment Unix98
 @deftypefun int aio_error64 (const struct aiocb64 *@var{aiocbp})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 This function is similar to @code{aio_error} with the only difference
 that the argument is a reference to a variable of type @code{struct
 aiocb64}.
@@ -2238,6 +2463,7 @@ machines.
 @comment aio.h
 @comment POSIX.1b
 @deftypefun ssize_t aio_return (struct aiocb *@var{aiocbp})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 This function can be used to retrieve the return status of the operation
 carried out by the request described in the variable pointed to by
 @var{aiocbp}.  As long as the error status of this request as returned
@@ -2261,6 +2487,7 @@ transparently replaces the normal implementation.
 @comment aio.h
 @comment Unix98
 @deftypefun ssize_t aio_return64 (struct aiocb64 *@var{aiocbp})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 This function is similar to @code{aio_return} with the only difference
 that the argument is a reference to a variable of type @code{struct
 aiocb64}.
@@ -2289,6 +2516,9 @@ if the symbol @code{_POSIX_SYNCHRONIZED_IO} is defined in @file{unistd.h}.
 @comment aio.h
 @comment POSIX.1b
 @deftypefun int aio_fsync (int @var{op}, struct aiocb *@var{aiocbp})
+@safety{@mtsafe{}@asunsafe{selfdeadlock, asmalloc}@acunsafe{lockleak, memleak}}
+@c After fcntl to check that the FD is open, it calls
+@c aio_enqueue_request.
 Calling this function forces all I/O operations operating queued at the
 time of the function call operating on the file descriptor
 @code{aiocbp->aio_fildes} into the synchronized I/O completion state
@@ -2336,6 +2566,7 @@ transparently replaces the normal implementation.
 @comment aio.h
 @comment Unix98
 @deftypefun int aio_fsync64 (int @var{op}, struct aiocb64 *@var{aiocbp})
+@safety{@mtsafe{}@asunsafe{selfdeadlock, asmalloc}@acunsafe{lockleak, memleak}}
 This function is similar to @code{aio_fsync} with the only difference
 that the argument is a reference to a variable of type @code{struct
 aiocb64}.
@@ -2362,6 +2593,9 @@ before the current client is served.  For situations like this
 @comment aio.h
 @comment POSIX.1b
 @deftypefun int aio_suspend (const struct aiocb *const @var{list}[], int @var{nent}, const struct timespec *@var{timeout})
+@safety{@mtsafe{}@asunsafe{selfdeadlock}@acunsafe{lockleak}}
+@c Take aio_requests_mutex, set up waitlist and requestlist, wait
+@c for completion or timeout, and release the mutex.
 When calling this function, the calling thread is suspended until at
 least one of the requests pointed to by the @var{nent} elements of the
 array @var{list} has completed.  If any of the requests has already
@@ -2400,6 +2634,7 @@ transparently replaces the normal implementation.
 @comment aio.h
 @comment Unix98
 @deftypefun int aio_suspend64 (const struct aiocb64 *const @var{list}[], int @var{nent}, const struct timespec *@var{timeout})
+@safety{@mtsafe{}@asunsafe{selfdeadlock}@acunsafe{lockleak}}
 This function is similar to @code{aio_suspend} with the only difference
 that the argument is a reference to a variable of type @code{struct
 aiocb64}.
@@ -2427,6 +2662,16 @@ or not.  Therefore using this function is merely a hint.
 @comment aio.h
 @comment POSIX.1b
 @deftypefun int aio_cancel (int @var{fildes}, struct aiocb *@var{aiocbp})
+@safety{@mtsafe{}@asunsafe{selfdeadlock, asmalloc}@acunsafe{lockleak, memleak}}
+@c After fcntl to check the fd is open, hold aio_requests_mutex, call
+@c aio_find_req_fd, aio_remove_request, then aio_notify and
+@c aio_free_request each request before releasing the lock.
+@c aio_notify calls aio_notify_only and free, besides cond signal or
+@c similar.  aio_notify_only calls pthread_attr_init,
+@c pthread_attr_setdetachstate, malloc, pthread_create,
+@c notify_func_wrapper, aio_sigqueue, getpid, raise.
+@c notify_func_wraper calls aio_start_notify_thread, free and then the
+@c notifier function.
 The @code{aio_cancel} function can be used to cancel one or more
 outstanding requests.  If the @var{aiocbp} parameter is @code{NULL}, the
 function tries to cancel all of the outstanding requests which would process
@@ -2474,6 +2719,7 @@ transparently replaces the normal implementation.
 @comment aio.h
 @comment Unix98
 @deftypefun int aio_cancel64 (int @var{fildes}, struct aiocb64 *@var{aiocbp})
+@safety{@mtsafe{}@asunsafe{selfdeadlock, asmalloc}@acunsafe{lockleak, memleak}}
 This function is similar to @code{aio_cancel} with the only difference
 that the argument is a reference to a variable of type @code{struct
 aiocb64}.
@@ -2529,6 +2775,8 @@ Unused.
 @comment aio.h
 @comment GNU
 @deftypefun void aio_init (const struct aioinit *@var{init})
+@safety{@mtsafe{}@asunsafe{selfdeadlock}@acunsafe{lockleak}}
+@c All changes to global objects are guarded by aio_requests_mutex.
 This function must be called before any other AIO function.  Calling it
 is completely voluntary, as it is only meant to help the AIO
 implementation perform better.
@@ -2563,6 +2811,7 @@ function; see @ref{Opening and Closing Files}.
 @comment fcntl.h
 @comment POSIX.1
 @deftypefun int fcntl (int @var{filedes}, int @var{command}, @dots{})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 The @code{fcntl} function performs the operation specified by
 @var{command} on the file descriptor @var{filedes}.  Some commands
 require additional arguments to be supplied.  These additional arguments
@@ -2645,6 +2894,7 @@ while prototypes for @code{dup} and @code{dup2} are in the header file
 @comment unistd.h
 @comment POSIX.1
 @deftypefun int dup (int @var{old})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 This function copies descriptor @var{old} to the first available
 descriptor number (the first number not currently open).  It is
 equivalent to @code{fcntl (@var{old}, F_DUPFD, 0)}.
@@ -2653,6 +2903,7 @@ equivalent to @code{fcntl (@var{old}, F_DUPFD, 0)}.
 @comment unistd.h
 @comment POSIX.1
 @deftypefun int dup2 (int @var{old}, int @var{new})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 This function copies the descriptor @var{old} to descriptor number
 @var{new}.
 
@@ -3631,6 +3882,7 @@ different headers.
 @comment sys/ioctl.h
 @comment BSD
 @deftypefun int ioctl (int @var{filedes}, int @var{command}, @dots{})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 
 The @code{ioctl} function performs the generic I/O operation
 @var{command} on @var{filedes}.
@@ -3650,3 +3902,6 @@ unknown device.
 Most IOCTLs are OS-specific and/or only used in special system utilities,
 and are thus beyond the scope of this document.  For an example of the use
 of an IOCTL, see @ref{Out-of-Band Data}.
+
+@c FIXME this is undocumented:
+@c dup3

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=d33bc54e514f28c76cee39f9732d14f74511bdc7

commit d33bc54e514f28c76cee39f9732d14f74511bdc7
Author: Alexandre Oliva <aoliva@redhat.com>
Date:   Fri Nov 8 06:08:19 2013 -0200

    MT-, AS- and AC-safety docs: manual/lang.texi
    
    for ChangeLog
    
    	* manual/lang.texi: Document MTASC-safety properties.

diff --git a/manual/lang.texi b/manual/lang.texi
index ee04e23..d6cd90c 100644
--- a/manual/lang.texi
+++ b/manual/lang.texi
@@ -51,6 +51,8 @@ without indicating anything might be wrong.
 @comment assert.h
 @comment ISO
 @deftypefn Macro void assert (int @var{expression})
+@safety{@mtsafe{}@asunsafe{asmalloc, asynconsist}@acsafe{memleak, lockleak, incansist}}
+@c assert_fail_base calls asprintf, and fflushes stderr.
 Verify the programmer's belief that @var{expression} is nonzero at
 this point in the program.
 
@@ -91,6 +93,8 @@ The @code{assert_perror} macro makes this easy.
 @comment assert.h
 @comment GNU
 @deftypefn Macro void assert_perror (int @var{errnum})
+@safety{@mtsafe{}@asunsafe{asmalloc, asynconsist}@acsafe{memleak, lockleak, incansist}}
+@c assert_fail_base calls asprintf, and fflushes stderr.
 Similar to @code{assert}, but verifies that @var{errnum} is zero.
 
 If @code{NDEBUG} is not defined, @code{assert_perror} tests the value of
@@ -423,6 +427,8 @@ The type @code{va_list} is used for argument pointer variables.
 @comment stdarg.h
 @comment ISO
 @deftypefn {Macro} void va_start (va_list @var{ap}, @var{last-required})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
+@c This is no longer provided by glibc, but rather by the compiler.
 This macro initializes the argument pointer variable @var{ap} to point
 to the first of the optional arguments of the current function;
 @var{last-required} must be the last required argument to the function.
@@ -431,6 +437,8 @@ to the first of the optional arguments of the current function;
 @comment stdarg.h
 @comment ISO
 @deftypefn {Macro} @var{type} va_arg (va_list @var{ap}, @var{type})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
+@c This is no longer provided by glibc, but rather by the compiler.
 The @code{va_arg} macro returns the value of the next optional argument,
 and modifies the value of @var{ap} to point to the subsequent argument.
 Thus, successive uses of @code{va_arg} return successive optional
@@ -445,6 +453,8 @@ of the actual argument.
 @comment stdarg.h
 @comment ISO
 @deftypefn {Macro} void va_end (va_list @var{ap})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
+@c This is no longer provided by glibc, but rather by the compiler.
 This ends the use of @var{ap}.  After a @code{va_end} call, further
 @code{va_arg} calls with the same @var{ap} may not work.  You should invoke
 @code{va_end} before returning from the function in which @code{va_start}
@@ -466,6 +476,8 @@ of the same type.
 @comment ISO
 @deftypefn {Macro} void va_copy (va_list @var{dest}, va_list @var{src})
 @deftypefnx {Macro} void __va_copy (va_list @var{dest}, va_list @var{src})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
+@c This is no longer provided by glibc, but rather by the compiler.
 The @code{va_copy} macro allows copying of objects of type
 @code{va_list} even if this is not an integral type.  The argument pointer
 in @var{dest} is initialized to point to the same argument as the
@@ -1212,6 +1224,8 @@ type of a particular structure member.
 @comment stddef.h
 @comment ISO
 @deftypefn {Macro} size_t offsetof (@var{type}, @var{member})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
+@c This is no longer provided by glibc, but rather by the compiler.
 This expands to a integer constant expression that is the offset of the
 structure member named @var{member} in the structure type @var{type}.
 For example, @code{offsetof (struct s, elem)} is the offset, in bytes,

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=4bcab2d91b3c38aeb250c1fa16a097e5b3f1444b

commit 4bcab2d91b3c38aeb250c1fa16a097e5b3f1444b
Author: Alexandre Oliva <aoliva@redhat.com>
Date:   Fri Nov 8 06:08:19 2013 -0200

    MT-, AS- and AC-safety docs: manual/job.texi
    
    for ChangeLog
    
    	* manual/job.texi: Document MTASC-safety properties.

diff --git a/manual/job.texi b/manual/job.texi
index 4efeed3..7ce1947 100644
--- a/manual/job.texi
+++ b/manual/job.texi
@@ -1039,6 +1039,10 @@ The function @code{ctermid} is declared in the header file
 @comment stdio.h
 @comment POSIX.1
 @deftypefun {char *} ctermid (char *@var{string})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
+@c This function is a stub by default; the actual implementation, for
+@c posix systems, returns an internal buffer if passed a NULL string,
+@c but the internal buffer is always set to /dev/tty.
 The @code{ctermid} function returns a string containing the file name of
 the controlling terminal for the current process.  If @var{string} is
 not a null pointer, it should be an array that can hold at least
@@ -1075,6 +1079,12 @@ Your program should include the header files @file{sys/types.h} and
 @comment unistd.h
 @comment POSIX.1
 @deftypefun pid_t setsid (void)
+@safety{@mtsafe{}@assafe{}@acsafe{}}
+@c This is usually a direct syscall, but if a syscall is not available,
+@c we use a stub, or Hurd- and BSD-specific implementations.  The former
+@c uses a mutex and a hurd critical section, and the latter issues a few
+@c syscalls, so both seem safe, the locking on Hurd is safe because of
+@c the critical section.
 The @code{setsid} function creates a new session.  The calling process
 becomes the session leader, and is put in a new process group whose
 process group ID is the same as the process ID of that process.  There
@@ -1098,6 +1108,8 @@ already another process group around that has the same process group ID.
 @comment unistd.h
 @comment SVID
 @deftypefun pid_t getsid (pid_t @var{pid})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
+@c Stub or direct syscall, except on hurd, where it is equally safe.
 
 The @code{getsid} function returns the process group ID of the session
 leader of the specified process.  If a @var{pid} is @code{0}, the
@@ -1134,6 +1146,8 @@ programs with the @code{-lbsd-compat} option to get the BSD definition.@refill
 @comment unistd.h
 @comment POSIX.1
 @deftypefn {POSIX.1 Function} pid_t getpgrp (void)
+@safety{@mtsafe{}@assafe{}@acsafe{}}
+@c Wrapper for getpgid.
 The POSIX.1 definition of @code{getpgrp} returns the process group ID of
 the calling process.
 @end deftypefn
@@ -1141,6 +1155,8 @@ the calling process.
 @comment unistd.h
 @comment BSD
 @deftypefn {BSD Function} pid_t getpgrp (pid_t @var{pid})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
+@c Wrapper for getpgid.
 The BSD definition of @code{getpgrp} returns the process group ID of the
 process @var{pid}.  You can supply a value of @code{0} for the @var{pid}
 argument to get information about the calling process.
@@ -1149,6 +1165,8 @@ argument to get information about the calling process.
 @comment unistd.h
 @comment SVID
 @deftypefn {System V Function} int getpgid (pid_t @var{pid})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
+@c Stub or direct syscall, except on hurd, where it is equally safe.
 
 @code{getpgid} is the same as the BSD function @code{getpgrp}.  It
 returns the process group ID of the process @var{pid}.  You can supply a
@@ -1171,6 +1189,8 @@ process.
 @comment unistd.h
 @comment POSIX.1
 @deftypefun int setpgid (pid_t @var{pid}, pid_t @var{pgid})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
+@c Stub or direct syscall, except on hurd, where it is equally safe.
 The @code{setpgid} function puts the process @var{pid} into the process
 group @var{pgid}.  As a special case, either @var{pid} or @var{pgid} can
 be zero to indicate the process ID of the calling process.
@@ -1208,6 +1228,8 @@ process or a child of the calling process.
 @comment unistd.h
 @comment BSD
 @deftypefun int setpgrp (pid_t @var{pid}, pid_t @var{pgid})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
+@c Direct syscall or setpgid wrapper.
 This is the BSD Unix name for @code{setpgid}.  Both functions do exactly
 the same thing.
 @end deftypefun
@@ -1230,6 +1252,8 @@ file itself and not a particular open file descriptor.
 @comment unistd.h
 @comment POSIX.1
 @deftypefun pid_t tcgetpgrp (int @var{filedes})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
+@c Stub, or ioctl on BSD and GNU/Linux.
 This function returns the process group ID of the foreground process
 group associated with the terminal open on descriptor @var{filedes}.
 
@@ -1258,6 +1282,8 @@ controlling terminal of the calling process.
 @comment unistd.h
 @comment POSIX.1
 @deftypefun int tcsetpgrp (int @var{filedes}, pid_t @var{pgid})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
+@c Stub, or ioctl on BSD and GNU/Linux.
 This function is used to set a terminal's foreground process group ID.
 The argument @var{filedes} is a descriptor which specifies the terminal;
 @var{pgid} specifies the process group.  The calling process must be a
@@ -1297,6 +1323,8 @@ process.
 @comment termios.h
 @comment Unix98
 @deftypefun pid_t tcgetsid (int @var{fildes})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
+@c Ioctl call, if avaialble, or tcgetpgrp followed by getsid.
 This function is used to obtain the process group ID of the session
 for which the terminal specified by @var{fildes} is the controlling terminal.
 If the call is successful the group ID is returned.  Otherwise the

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=8daa637bf75df1ed390cf9aabe94b40439e16876

commit 8daa637bf75df1ed390cf9aabe94b40439e16876
Author: Alexandre Oliva <aoliva@redhat.com>
Date:   Fri Nov 8 06:08:19 2013 -0200

    MT-, AS- and AC-safety docs: manual/message.texi
    
    for ChangeLog
    
    	* manual/message.texi: Document MTASC-safety properties.

diff --git a/manual/message.texi b/manual/message.texi
index bb5b11b..1fbffcf 100644
--- a/manual/message.texi
+++ b/manual/message.texi
@@ -86,7 +86,32 @@ are defined/declared in the @file{nl_types.h} header file.
 @comment nl_types.h
 @comment X/Open
 @deftypefun nl_catd catopen (const char *@var{cat_name}, int @var{flag})
-The @code{catgets} function tries to locate the message data file names
+@safety{@mtunsafe{envromt}@asunsafe{selfdeadlock}@acunsafe{lockleak, fdleak, memleak}}
+@c catopen envromt, selfdeadlock, lockleak, fdleak, memleak
+@c  strchr ok
+@c  setlocale(,NULL) ok
+@c  getenv envromt
+@c  strlen ok
+@c  alloca ok
+@c  stpcpy ok
+@c  malloc selfdeadlock, lockleak, fdleak, memleak
+@c  __open_catalog selfdeadlock, lockleak, fdleak, memleak
+@c   strchr ok
+@c   open_not_cancel_2 fdleak
+@c   strlen ok
+@c   ENOUGH ok
+@c    alloca ok
+@c    memcpy ok
+@c   fxstat64 ok
+@c   __set_errno ok
+@c   mmap memleak
+@c   malloc dup selfdeadlock, lockleak, fdleak, memleak
+@c   read_not_cancel ok
+@c   free dup selfdeadlock, lockleak, fdleak, memleak
+@c   munmap ok
+@c   close_not_cancel_no_status ok
+@c  free selfdeadlock, lockleak, fdleak, memleak
+The @code{catopen} function tries to locate the message data file names
 @var{cat_name} and loads it when found.  The return value is of an
 opaque type and can be used in calls to the other functions to refer to
 this loaded catalog.
@@ -243,6 +268,7 @@ variables.
 
 
 @deftypefun {char *} catgets (nl_catd @var{catalog_desc}, int @var{set}, int @var{message}, const char *@var{string})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 The function @code{catgets} has to be used to access the massage catalog
 previously opened using the @code{catopen} function.  The
 @var{catalog_desc} parameter must be a value previously returned by
@@ -281,6 +307,11 @@ We will see some how these problems can be relaxed a bit (@pxref{Common
 Usage}).
 
 @deftypefun int catclose (nl_catd @var{catalog_desc})
+@safety{@mtsafe{}@asunsafe{selfdeadlock}@acunsafe{incansist, lockleak, fdleak, memleak}}
+@c catclose selfdeadlock, incansist, lockleak, fdleak, memleak
+@c  __set_errno ok
+@c  munmap ok
+@c  free selfdeadlock, lockleak, fdleak, memleak
 The @code{catclose} function can be used to free the resources
 associated with a message catalog which previously was opened by a call
 to @code{catopen}.  If the resources can be successfully freed the
@@ -803,12 +834,14 @@ not part of the C library they can be found in a separate library named
 @comment libintl.h
 @comment GNU
 @deftypefun {char *} gettext (const char *@var{msgid})
+@safety{@mtunsafe{envromt}@asunsafe{asynconsist, asmalloc, selfdeadlock, shlimb}@acunsafe{incansist, lockleak, fdleak, memleak, shlimb}}
+@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
 string available it is returned.  Otherwise the argument string
 @var{msgid} is returned.
 
-Please note that all though the return value is @code{char *} the
+Please note that although the return value is @code{char *} the
 returned string must not be changed.  This broken type results from the
 history of the function and does not reflect the way the function should
 be used.
@@ -850,6 +883,8 @@ information.
 @comment libintl.h
 @comment GNU
 @deftypefun {char *} dgettext (const char *@var{domainname}, const char *@var{msgid})
+@safety{@mtunsafe{envromt}@asunsafe{asynconsist, asmalloc, selfdeadlock, shlimb}@acunsafe{incansist, lockleak, fdleak, memleak, shlimb}}
+@c Wrapper for dcgettext.
 The @code{dgettext} functions acts just like the @code{gettext}
 function.  It only takes an additional first argument @var{domainname}
 which guides the selection of the message catalogs which are searched
@@ -864,6 +899,102 @@ anachronism.  The returned string must never be modified.
 @comment libintl.h
 @comment GNU
 @deftypefun {char *} dcgettext (const char *@var{domainname}, const char *@var{msgid}, int @var{category})
+@safety{@mtunsafe{envromt}@asunsafe{asynconsist, asmalloc, selfdeadlock, shlimb}@acunsafe{incansist, lockleak, fdleak, memleak, shlimb}}
+@c dcgettext envromt, asynconsist, asmalloc, selfdeadlock, shlimb, incansist, lockleak, fdleak, memleak, shlimb
+@c  dcigettext envromt, asynconsist, asmalloc, selfdeadlock, shlimb, incansist, lockleak, fdleak, memleak, shlimb
+@c   libc_rwlock_rdlock selfdeadlock, lockleak
+@c   current_locale_name ok [protected from glocale]
+@c   tfind ok
+@c   libc_rwlock_unlock ok
+@c   plural_lookup ok
+@c    plural_eval ok
+@c    rawmemchr ok
+@c   DETERMINE_SECURE ok, nothing
+@c   strcmp ok
+@c   strlen ok
+@c   getcwd asmalloc, memleak, fdleak
+@c   strchr ok
+@c   stpcpy ok
+@c   category_to_name ok
+@c   guess_category_value envromt
+@c    getenv envromt
+@c    current_locale_name dup ok [protected from glocale by dcigettext]
+@c    strcmp ok
+@c   ENABLE_SECURE ok
+@c   _nl_find_domain envromt, asynconsist, asmalloc, selfdeadlock, shlimb, incansist, lockleak, fdleak, memleak, shlimb
+@c    libc_rwlock_rdlock dup selfdeadlock, lockleak
+@c    _nl_make_l10nflist dup asmalloc, memleak
+@c    libc_rwlock_unlock dup ok
+@c    _nl_load_domain envromt, asynconsist, asmalloc, selfdeadlock, shlimb, incansist, lockleak, fdleak, memleak, shlimb
+@c     libc_lock_lock_recursive lockleak
+@c     libc_lock_unlock_recursive lockleak
+@c     open->open_not_cancel_2 fdleak
+@c     fstat ok
+@c     mmap dup memleak
+@c     close->close_not_cancel_no_status fdleak
+@c     malloc dup selfdeadlock, lockleak, fdleak, memleak
+@c     read->read_not_cancel ok
+@c     munmap dup memleak
+@c     W dup ok
+@c     strlen dup ok
+@c     get_sysdep_segment_value ok
+@c     memcpy dup ok
+@c     hash_string dup ok
+@c     free dup selfdeadlock, lockleak, fdleak, memleak
+@c     libc_rwlock_init ok
+@c     _nl_find_msg dup envromt, asynconsist, asmalloc, selfdeadlock, shlimb, incansist, lockleak, fdleak, memleak, shlimb
+@c     libc_rwlock_fini ok
+@c     EXTRACT_PLURAL_EXPRESSION selfdeadlock, lockleak, fdleak, memleak
+@c      strstr dup ok
+@c      isspace ok [protected from glocale by dcigettext]
+@c      strtoul ok [protected from glocale by dcigettext]
+@c      PLURAL_PARSE selfdeadlock, lockleak, fdleak, memleak
+@c       malloc dup selfdeadlock, lockleak, fdleak, memleak
+@c       free dup selfdeadlock, lockleak, fdleak, memleak
+@c      INIT_GERMANIC_PLURAL ok, nothing
+@c       (pre-C99 variant is incansist [protected from 1stcall by dcigettext])
+@c    _nl_expand_alias dup asmalloc, selfdeadlock, memleak, fdleak, lockleak
+@c    _nl_explode_name dup asmalloc, memleak
+@c    libc_rwlock_wrlock dup selfdeadlock, lockleak
+@c    free dup selfdeadlock, lockleak, fdleak, memleak
+@c   _nl_find_msg envromt, asynconsist, asmalloc, selfdeadlock, shlimb, incansist, lockleak, fdleak, memleak, shlimb
+@c    _nl_load_domain dup envromt, asynconsist, asmalloc, selfdeadlock, shlimb, incansist, lockleak, fdleak, memleak, shlimb
+@c    strlen ok
+@c    hash_string ok
+@c    W ok
+@c     SWAP ok
+@c      bswap_32 ok
+@c    strcmp ok
+@c    get_output_charset envromt, selfdeadlock, lockleak, fdleak, memleak
+@c     getenv dup envromt
+@c     strlen dup ok
+@c     malloc dup selfdeadlock, lockleak, fdleak, memleak
+@c     memcpy dup ok
+@c    libc_rwlock_rdlock dup selfdeadlock, lockleak
+@c    libc_rwlock_unlock dup ok
+@c    libc_rwlock_wrlock dup selfdeadlock, lockleak
+@c    realloc selfdeadlock, lockleak, fdleak, memleak
+@c    strdup selfdeadlock, lockleak, fdleak, memleak
+@c    strstr ok
+@c    strcspn ok
+@c    mempcpy dup ok
+@c    norm_add_slashes dup ok
+@c    gconv_open asynconsist, asmalloc, selfdeadlock, shlimb, incansist, lockleak, memleak, fdleak, shlimb
+@c     [protected from glocale by dcigettext locale lock]
+@c    free dup selfdeadlock, lockleak, fdleak, memleak
+@c    libc_lock_lock selfdeadlock, lockleak
+@c    calloc selfdeadlock, lockleak, fdleak, memleak
+@c    gconv dup incansist [protected from xguargs and asynconsist by lock]
+@c    libc_lock_unlock ok
+@c   malloc selfdeadlock, lockleak, fdleak, memleak
+@c   mempcpy ok
+@c   memcpy ok
+@c   strcpy ok
+@c   libc_rwlock_wrlock selfdeadlock, lockleak
+@c   tsearch asmalloc, incansist, memleak [protected from xguargs and asynconsist]
+@c    transcmp ok
+@c     strmp dup ok
+@c   free selfdeadlock, lockleak, fdleak, memleak
 The @code{dcgettext} adds another argument to those which
 @code{dgettext} takes.  This argument @var{category} specifies the last
 piece of information needed to localize the message catalog.  I.e., the
@@ -988,6 +1119,13 @@ function.
 @comment libintl.h
 @comment GNU
 @deftypefun {char *} textdomain (const char *@var{domainname})
+@safety{@mtsafe{}@asunsafe{selfdeadlock, asmalloc}@acunsafe{lockleak, memleak}}
+@c textdomain selfdeadlock, asmalloc, lockleak, memleak
+@c  libc_rwlock_wrlock selfdeadlock, lockleak
+@c  strcmp ok
+@c  strdup asmalloc, memleak
+@c  free memleak
+@c  libc_rwlock_unlock ok
 The @code{textdomain} function sets the default domain, which is used in
 all future @code{gettext} calls, to @var{domainname}.  Please note that
 @code{dgettext} and @code{dcgettext} calls are not influenced if the
@@ -1019,6 +1157,14 @@ really never should be used.
 @comment libintl.h
 @comment GNU
 @deftypefun {char *} bindtextdomain (const char *@var{domainname}, const char *@var{dirname})
+@safety{@mtsafe{}@asunsafe{selfdeadlock}@acunsafe{lockleak, fdleak, memleak}}
+@c bindtextdomain selfdeadlock, lockleak, fdleak, memleak
+@c  set_binding_values selfdeadlock, lockleak, fdleak, memleak
+@c   libc_rwlock_wrlock dup selfdeadlock, lockleak
+@c   strcmp dup ok
+@c   strdup dup selfdeadlock, lockleak, fdleak, memleak
+@c   free dup selfdeadlock, lockleak, fdleak, memleak
+@c   malloc dup selfdeadlock, lockleak, fdleak, memleak
 The @code{bindtextdomain} function can be used to specify the directory
 which contains the message catalogs for domain @var{domainname} for the
 different languages.  To be correct, this is the directory where the
@@ -1134,6 +1280,8 @@ purpose.
 @comment libintl.h
 @comment GNU
 @deftypefun {char *} ngettext (const char *@var{msgid1}, const char *@var{msgid2}, unsigned long int @var{n})
+@safety{@mtunsafe{envromt}@asunsafe{asynconsist, asmalloc, selfdeadlock, shlimb}@acunsafe{incansist, lockleak, fdleak, memleak, shlimb}}
+@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
 extra arguments.  The @var{msgid1} parameter must contain the singular
@@ -1157,6 +1305,8 @@ Please note that the numeric value @var{n} has to be passed to the
 @comment libintl.h
 @comment GNU
 @deftypefun {char *} dngettext (const char *@var{domain}, const char *@var{msgid1}, const char *@var{msgid2}, unsigned long int @var{n})
+@safety{@mtunsafe{envromt}@asunsafe{asynconsist, asmalloc, selfdeadlock, shlimb}@acunsafe{incansist, lockleak, fdleak, memleak, shlimb}}
+@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
 two extra parameter to provide the correct plural form.  These two
@@ -1166,6 +1316,8 @@ parameters are handled in the same way @code{ngettext} handles them.
 @comment libintl.h
 @comment GNU
 @deftypefun {char *} dcngettext (const char *@var{domain}, const char *@var{msgid1}, const char *@var{msgid2}, unsigned long int @var{n}, int @var{category})
+@safety{@mtunsafe{envromt}@asunsafe{asynconsist, asmalloc, selfdeadlock, shlimb}@acunsafe{incansist, lockleak, fdleak, memleak, shlimb}}
+@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
 two extra parameter to provide the correct plural form.  These two
@@ -1422,6 +1574,9 @@ recommended that all @var{msgid}s be US-ASCII strings.
 @comment libintl.h
 @comment GNU
 @deftypefun {char *} bind_textdomain_codeset (const char *@var{domainname}, const char *@var{codeset})
+@safety{@mtsafe{}@asunsafe{selfdeadlock}@acunsafe{lockleak, fdleak, memleak}}
+@c bind_textdomain_codeset selfdeadlock, lockleak, fdleak, memleak
+@c  set_binding_values dup selfdeadlock, lockleak, fdleak, memleak
 The @code{bind_textdomain_codeset} function can be used to specify the
 output character set for message catalogs for domain @var{domainname}.
 The @var{codeset} argument must be a valid codeset name which can be used

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=c3a1bd06ca192a17b199444aabed2c389dbb57ee

commit c3a1bd06ca192a17b199444aabed2c389dbb57ee
Author: Alexandre Oliva <aoliva@redhat.com>
Date:   Fri Nov 8 06:08:19 2013 -0200

    MT-, AS- and AC-safety docs: manual/memory.texi
    
    for ChangeLog
    
    	* manual/memory.texi: Document MTASC-safety properties.

diff --git a/manual/memory.texi b/manual/memory.texi
index a80f87c..7216cb5 100644
--- a/manual/memory.texi
+++ b/manual/memory.texi
@@ -302,6 +302,248 @@ this function is in @file{stdlib.h}.
 @comment malloc.h stdlib.h
 @comment ISO
 @deftypefun {void *} malloc (size_t @var{size})
+@safety{@mtsafe{}@asunsafe{selfdeadlock}@acunsafe{lockleak, fdleak, memleak}}
+@c Malloc hooks and __morecore pointers, as well as such parameters as
+@c max_n_mmaps and max_mmapped_mem, are accessed without guards, so they
+@c could pose a thread safety issue; in order to not declare malloc
+@c MT-unsafe, it's modifying the hooks and parameters while multiple
+@c threads are active that is regarded as unsafe.  An arena's next field
+@c is initialized and never changed again, except for main_arena's,
+@c that's protected by list_lock; next_free is only modified while
+@c list_lock is held too.  All other data members of an arena, as well
+@c as the metadata of the memory areas assigned to it, are only modified
+@c while holding the arena's mutex (fastbin pointers use catomic ops
+@c because they may be modified by free without taking the arena's
+@c lock).  Some reassurance was needed for fastbins, for it wasn't clear
+@c how they were initialized.  It turns out they are always
+@c zero-initialized: main_arena's, for being static data, and other
+@c arena's, for being just-mmapped memory.
+
+@c Leaking file descriptors and memory in case of cancellation is
+@c unavoidable without disabling cancellation, but the lock situation is
+@c a bit more complicated: we don't have fallback arenas for malloc to
+@c be safe to call from within signal handlers.  Error-checking mutexes
+@c or trylock could enable us to try and use alternate arenas, even with
+@c -DPER_THREAD (enabled by default), but supporting interruption
+@c (cancellation or signal handling) while holding the arena list mutex
+@c would require more work; maybe blocking signals and disabling async
+@c cancellation while manipulating the arena lists?
+
+@c __libc_malloc selfdeadlock, lockleak, fdleak, memleak
+@c  force_reg ok
+@c  *malloc_hook unguarded
+@c  arena_lookup ok
+@c   tsd_getspecific ok, TLS
+@c  arena_lock selfdeadlock, lockleak, fdleak, memleak
+@c   mutex_lock selfdeadlock, lockleak
+@c   arena_get2 selfdeadlock, lockleak, fdleak, memleak
+@c    get_free_list selfdeadlock, lockleak
+@c     mutex_lock (list_lock) dup selfdeadlock, lockleak
+@c     mutex_unlock (list_lock) dup lockleak
+@c     mutex_lock (arena lock) dup selfdeadlock, lockleak, returns locked
+@c     tsd_setspecific ok, TLS
+@c    __get_nprocs ext ok fdleak
+@c    NARENAS_FROM_NCORES ok
+@c    catomic_compare_and_exchange_bool_acq ok
+@c    _int_new_arena ok selfdeadlock, lockleak, memleak
+@c     new_heap ok memleak
+@c      mmap ok memleak
+@c      munmap ok memleak
+@c      mprotect ok
+@c     chunk2mem ok
+@c     set_head ok
+@c     tsd_setspecific dup ok
+@c     mutex_init ok
+@c     mutex_lock (just-created mutex) ok, returns locked
+@c     mutex_lock (list_lock) dup selfdeadlock, lockleak
+@c     atomic_write_barrier ok
+@c     mutex_unlock (list_lock) lockleak
+@c    catomic_decrement ok
+@c    reused_arena selfdeadlock, lockleak
+@c      reads&writes next_to_use and iterates over arena next without guards
+@c      those are harmless as long as we don't drop arenas from the
+@c      NEXT list, and we never do; when a thread terminates,
+@c      arena_thread_freeres prepends the arena to the free_list
+@c      NEXT_FREE list, but NEXT is never modified, so it's safe!
+@c     mutex_trylock (arena lock) selfdeadlock, lockleak
+@c     mutex_lock (arena lock) dup selfdeadlock, lockleak
+@c     tsd_setspecific dup ok
+@c  _int_malloc fdleak, memleak
+@c   checked_request2size ok
+@c    REQUEST_OUT_OF_RANGE ok
+@c    request2size ok
+@c   get_max_fast ok
+@c   fastbin_index ok
+@c   fastbin ok
+@c   catomic_compare_and_exhange_val_acq ok
+@c   malloc_printerr dup envromt, but ok:
+@c     if we get to it, we're toast already, undefined behavior must have
+@c     been invoked before
+@c    libc_message envromt, no leaks with cancellation disabled
+@c     FATAL_PREPARE ok
+@c      pthread_setcancelstate disable ok
+@c     libc_secure_getenv envromt
+@c      getenv envromt
+@c     open_not_cancel_2 dup fdleak
+@c     strchrnul ok
+@c     WRITEV_FOR_FATAL ok
+@c      writev ok
+@c     mmap ok memleak
+@c     munmap ok memleak
+@c     BEFORE_ABORT fdleak
+@c      backtrace ok
+@c      write_not_cancel dup ok
+@c      backtrace_symbols_fd lockleak
+@c      open_not_cancel_2 dup fdleak
+@c      read_not_cancel dup ok
+@c      close_not_cancel_no_status dup fdleak
+@c     abort ok
+@c    itoa_word ok
+@c    abort ok
+@c   check_remalloced_chunk ok, disabled
+@c   chunk2mem dup ok
+@c   alloc_perturb ok
+@c   in_smallbin_range ok
+@c   smallbin_index ok
+@c   bin_at ok
+@c   last ok
+@c   malloc_consolidate ok
+@c    get_max_fast dup ok
+@c    clear_fastchunks ok
+@c    unsorted_chunks dup ok
+@c    fastbin dup ok
+@c    atomic_exchange_acq ok
+@c    check_inuse_chunk dup ok, disabled
+@c    chunk_at_offset dup ok
+@c    chunksize dup ok
+@c    inuse_bit_at_offset dup ok
+@c    unlink dup ok
+@c    clear_inuse_bit_at_offset dup ok
+@c    in_smallbin_range dup ok
+@c    set_head dup ok
+@c    malloc_init_state ok
+@c     bin_at dup ok
+@c     set_noncontiguous dup ok
+@c     set_max_fast dup ok
+@c     initial_top ok
+@c      unsorted_chunks dup ok
+@c    check_malloc_state ok, disabled
+@c   set_inuse_bit_at_offset ok
+@c   check_malloced_chunk ok, disabled
+@c   largebin_index ok
+@c   have_fastchunks ok
+@c   unsorted_chunks ok
+@c    bin_at ok
+@c   chunksize ok
+@c   chunk_at_offset ok
+@c   set_head ok
+@c   set_foot ok
+@c   mark_bin ok
+@c    idx2bit ok
+@c   first ok
+@c   unlink ok
+@c    malloc_printerr dup ok
+@c    in_smallbin_range dup ok
+@c   idx2block ok
+@c   idx2bit dup ok
+@c   next_bin ok
+@c   sysmalloc [uunguard], fdleak, memleak
+@c     n_mmaps and mmapped_mem and their max stats are modified
+@c     unguarded.  that is ok-ish, as it only affects statistics, but it
+@c     would be advisable to use catomic ops.
+@c    MMAP memleak
+@c    set_head dup ok
+@c    check_chunk ok, disabled
+@c    chunk2mem dup ok
+@c    chunksize dup ok
+@c    chunk_at_offset dup ok
+@c    heap_for_ptr ok
+@c    grow_heap ok
+@c     mprotect ok
+@c    set_head dup ok
+@c    new_heap memleak
+@c     MMAP dup memleak
+@c     munmap memleak
+@c    top ok
+@c    set_foot dup ok
+@c    contiguous ok
+@c    MORECORE ok
+@c     *__morecore ok unguarded
+@c      __default_morecore
+@c       sbrk ok
+@c    force_reg dup ok
+@c    *__after_morecore_hook unguarded
+@c    set_noncontiguous ok
+@c    malloc_printerr dup ok
+@c    _int_free (have_lock) [selfdeadlock, lockleak], fdleak, memleak
+@c     chunksize dup ok
+@c     mutex_unlock dup lockleak only if !have_lock
+@c     malloc_printerr dup ok
+@c     check_inuse_chunk ok, disabled
+@c     chunk_at_offset dup ok
+@c     mutex_lock dup selfdeadlock, lockleak only if !have_lock
+@c     chunk2mem dup ok
+@c     free_perturb ok
+@c     set_fastchunks ok
+@c      catomic_and ok
+@c     fastbin_index dup ok
+@c     fastbin dup ok
+@c     catomic_compare_and_exchange_val_rel ok
+@c     chunk_is_mmapped ok
+@c     contiguous dup ok
+@c     prev_inuse ok
+@c     unlink dup ok
+@c     inuse_bit_at_offset dup ok
+@c     clear_inuse_bit_at_offset ok
+@c     unsorted_chunks dup ok
+@c     in_smallbin_range dup ok
+@c     set_head dup ok
+@c     set_foot dup ok
+@c     check_free_chunk ok, disabled
+@c     check_chunk dup ok, disabled
+@c     have_fastchunks dup ok
+@c     malloc_consolidate dup ok
+@c     systrim ok
+@c      MORECORE dup ok
+@c      *__after_morecore_hook dup unguarded
+@c      set_head dup ok
+@c      check_malloc_state ok, disabled
+@c     top dup ok
+@c     heap_for_ptr dup ok
+@c     heap_trim fdleak, memleak
+@c      top dup ok
+@c      chunk_at_offset dup ok
+@c      prev_chunk ok
+@c      chunksize dup ok
+@c      prev_inuse dup ok
+@c      delete_heap memleak
+@c       munmap dup memleak
+@c      unlink dup ok
+@c      set_head dup ok
+@c      shrink_heap fdleak
+@c       check_may_shrink_heap fdleak
+@c        open_not_cancel_2 fdleak
+@c        read_not_cancel ok
+@c        close_not_cancel_no_status fdleak
+@c       MMAP dup ok
+@c       madvise ok
+@c     munmap_chunk memleak
+@c      chunksize dup ok
+@c      chunk_is_mmapped dup ok
+@c      chunk2mem dup ok
+@c      malloc_printerr dup ok
+@c      munmap dup memleak
+@c    check_malloc_state ok, disabled
+@c  arena_get_retry selfdeadlock, lockleak, fdleak, memleak
+@c   mutex_unlock dup lockleak
+@c   mutex_lock dup selfdeadlock, lockleak
+@c   arena_get2 dup selfdeadlock, lockleak, fdleak, memleak
+@c  mutex_unlock lockleak
+@c  mem2chunk ok
+@c  chunk_is_mmapped ok
+@c  arena_for_chunk ok
+@c   chunk_non_main_arena ok
+@c   heap_for_ptr ok
 This function returns a pointer to a newly allocated block @var{size}
 bytes long, or a null pointer if the block could not be allocated.
 @end deftypefun
@@ -407,6 +649,23 @@ The prototype for this function is in @file{stdlib.h}.
 @comment malloc.h stdlib.h
 @comment ISO
 @deftypefun void free (void *@var{ptr})
+@safety{@mtsafe{}@asunsafe{selfdeadlock}@acunsafe{lockleak, fdleak, memleak}}
+@c __libc_free selfdeadlock, lockleak, fdleak, memleak
+@c   releasing memory into fastbins modifies the arena without taking
+@c   its mutex, but catomic operations ensure safety.  If two (or more)
+@c   threads are running malloc and have their own arenas locked when
+@c   each gets a signal whose handler free()s large (non-fastbin-able)
+@c   blocks from each other's arena, we deadlock; this is a more general
+@c   case of selfdeadlock.
+@c  *__free_hook unguarded
+@c  mem2chunk ok
+@c  chunk_is_mmapped ok, chunk bits not modified after allocation
+@c  chunksize ok
+@c  munmap_chunk dup [uunguard], memleak
+@c    n_mmaps and mmapped_mem are modified unguarded.  stats only, but
+@c    catomic ops would be advisable
+@c  arena_for_chunk dup ok
+@c  _int_free (!have_lock) dup selfdeadlock, lockleak, fdleak, memleak
 The @code{free} function deallocates the block of memory pointed at
 by @var{ptr}.
 @end deftypefun
@@ -414,6 +673,8 @@ by @var{ptr}.
 @comment stdlib.h
 @comment Sun
 @deftypefun void cfree (void *@var{ptr})
+@safety{@mtsafe{}@asunsafe{selfdeadlock}@acunsafe{lockleak, fdleak, memleak}}
+@c alias to free
 This function does the same thing as @code{free}.  It's provided for
 backward compatibility with SunOS; you should use @code{free} instead.
 @end deftypefun
@@ -471,6 +732,48 @@ is declared in @file{stdlib.h}.
 @comment malloc.h stdlib.h
 @comment ISO
 @deftypefun {void *} realloc (void *@var{ptr}, size_t @var{newsize})
+@safety{@mtsafe{}@asunsafe{selfdeadlock}@acunsafe{lockleak, fdleak, memleak}}
+@c It may call the implementations of malloc and free, so all of their
+@c issues arise, plus the realloc hook, also accessed without guards.
+
+@c __libc_realloc selfdeadlock, lockleak, fdleak, memleak
+@c  *__realloc_hook unguarded
+@c  __libc_free dup selfdeadlock, lockleak, fdleak, memleak
+@c  __libc_malloc dup selfdeadlock, lockleak, fdleak, memleak
+@c  mem2chunk dup ok
+@c  chunksize dup ok
+@c  malloc_printerr dup ok
+@c  checked_request2size dup ok
+@c  chunk_is_mmapped dup ok
+@c  mremap_chunk
+@c   chunksize dup ok
+@c   __mremap ok
+@c   set_head dup ok
+@c  MALLOC_COPY ok
+@c   memcpy ok
+@c  munmap_chunk dup memleak
+@c  arena_for_chunk dup ok
+@c  mutex_lock (arena mutex) dup selfdeadlock, lockleak
+@c  _int_realloc fdleak, memleak
+@c   malloc_printerr dup ok
+@c   check_inuse_chunk dup ok, disabled
+@c   chunk_at_offset dup ok
+@c   chunksize dup ok
+@c   set_head_size dup ok
+@c   chunk_at_offset dup ok
+@c   set_head dup ok
+@c   chunk2mem dup ok
+@c   inuse dup ok
+@c   unlink dup ok
+@c   _int_malloc dup fdleak, memleak
+@c   mem2chunk dup ok
+@c   MALLOC_COPY dup ok
+@c   _int_free (have_lock) dup fdleak, memleak
+@c   set_inuse_bit_at_offset dup ok
+@c   set_head dup ok
+@c  mutex_unlock (arena mutex) dup lockleak
+@c  _int_free (!have_lock) dup selfdeadlock, lockleak, fdleak, memleak
+
 The @code{realloc} function changes the size of the block whose address is
 @var{ptr} to be @var{newsize}.
 
@@ -530,6 +833,25 @@ is declared in @file{stdlib.h}.
 @comment malloc.h stdlib.h
 @comment ISO
 @deftypefun {void *} calloc (size_t @var{count}, size_t @var{eltsize})
+@safety{@mtsafe{}@asunsafe{selfdeadlock}@acunsafe{lockleak, fdleak, memleak}}
+@c Same caveats as malloc.
+
+@c __libc_calloc selfdeadlock, lockleak, fdleak, memleak
+@c  *__malloc_hook dup unguarded
+@c  memset dup ok
+@c  arena_get selfdeadlock, lockleak, fdleak, memleak
+@c   arena_lookup dup ok
+@c   arena_lock dup selfdeadlock, lockleak, fdleak, memleak
+@c  top dup ok
+@c  chunksize dup ok
+@c  heap_for_ptr dup ok
+@c  _int_malloc dup fdleak, memleak
+@c  arena_get_retry dup selfdeadlock, lockleak, fdleak, memleak
+@c  mutex_unlock dup lockleak
+@c  mem2chunk dup ok
+@c  chunk_is_mmapped dup ok
+@c  MALLOC_ZERO ok
+@c   memset dup ok
 This function allocates a block long enough to contain a vector of
 @var{count} elements, each of size @var{eltsize}.  Its contents are
 cleared to zero before @code{calloc} returns.
@@ -628,6 +950,29 @@ such blocks.
 @comment malloc.h
 @comment BSD
 @deftypefun {void *} memalign (size_t @var{boundary}, size_t @var{size})
+@safety{@mtsafe{}@asunsafe{selfdeadlock}@acunsafe{lockleak, fdleak, memleak}}
+@c Same issues as malloc.  The padding bytes are safely freed in
+@c _int_memalign, with the arena still locked.
+
+@c __libc_memalign selfdeadlock, lockleak, fdleak, memleak
+@c  *__memalign_hook dup unguarded
+@c  __libc_malloc dup selfdeadlock, lockleak, fdleak, memleak
+@c  arena_get dup selfdeadlock, lockleak, fdleak, memleak
+@c  _int_memalign fdleak, memleak
+@c   _int_malloc dup fdleak, memleak
+@c   checked_request2size dup ok
+@c   mem2chunk dup ok
+@c   chunksize dup ok
+@c   chunk_is_mmapped dup ok
+@c   set_head dup ok
+@c   chunk2mem dup ok
+@c   set_inuse_bit_at_offset dup ok
+@c   set_head_size dup ok
+@c   _int_free (have_lock) dup fdleak, memleak
+@c   chunk_at_offset dup ok
+@c   check_inuse_chunk dup ok
+@c  arena_get_retry dup selfdeadlock, lockleak, fdleak, memleak
+@c  mutex_unlock dup lockleak
 The @code{memalign} function allocates a block of @var{size} bytes whose
 address is a multiple of @var{boundary}.  The @var{boundary} must be a
 power of two!  The function @code{memalign} works by allocating a
@@ -638,6 +983,10 @@ that is on the specified boundary.
 @comment stdlib.h
 @comment POSIX
 @deftypefun int posix_memalign (void **@var{memptr}, size_t @var{alignment}, size_t @var{size})
+@safety{@mtsafe{}@asunsafe{selfdeadlock}@acunsafe{lockleak, fdleak, memleak}}
+@c Calls memalign unless the requirements are not met (powerof2 macro is
+@c safe given an automatic variable as an argument) or there's a
+@c memalign hook (accessed unguarded, but safely).
 The @code{posix_memalign} function is similar to the @code{memalign}
 function in that it returns a buffer of @var{size} bytes aligned to a
 multiple of @var{alignment}.  But it adds one requirement to the
@@ -654,6 +1003,39 @@ This function was introduced in POSIX 1003.1d.
 @comment malloc.h stdlib.h
 @comment BSD
 @deftypefun {void *} valloc (size_t @var{size})
+@safety{@mtunsafe{1stcall}@asunsafe{oncesafe, selfdeadlock}@acunsafe{oncesafe, lockleak, fdleak, memleak}}
+@c __libc_valloc 1stcall, oncesafe, selfdeadlock, lockleak, fdleak, memleak
+@c  ptmalloc_init (once) envromt, selfdeadlock, lockleak, fdleak, memleak
+@c   _dl_addr asynconsist?, lockleak
+@c    __rtld_lock_lock_recursive (dl_load_lock) asynconsist?, lockleak
+@c    _dl_find_dso_for_object ok, iterates over dl_ns and its _ns_loaded objs
+@c      the ok above assumes no partial updates on dl_ns and _ns_loaded
+@c      that could confuse a _dl_addr call in a signal handler
+@c     _dl_addr_inside_object ok
+@c    determine_info ok
+@c    __rtld_lock_unlock_recursive (dl_load_lock) lockleak
+@c   thread_atfork selfdeadlock, lockleak, fdleak, memleak
+@c    __register_atfork selfdeadlock, lockleak, fdleak, memleak
+@c     lll_lock (__fork_lock) selfdeadlock, lockleak
+@c     fork_handler_alloc selfdeadlock, lockleak, fdleak, memleak
+@c      calloc dup selfdeadlock, lockleak, fdleak, memleak
+@c     __linkin_atfork ok
+@c      catomic_compare_and_exchange_bool_acq ok
+@c     lll_unlock (__fork_lock) lockleak
+@c   *_environ envromt
+@c   next_env_entry ok
+@c   strcspn dup ok
+@c   __libc_mallopt dup uunguard setting mp_
+@c   __malloc_check_init uunguard setting hooks
+@c   *__malloc_initialize_hook unguarded, ok
+@c  *__memalign_hook dup ok, unguarded
+@c  arena_get dup selfdeadlock, lockleak, fdleak, memleak
+@c  _int_valloc fdleak, memleak
+@c   malloc_consolidate dup ok
+@c   _int_memalign dup fdleak, memleak
+@c  arena_get_retry dup selfdeadlock, lockleak, fdleak, memleak
+@c  _int_memalign dup fdleak, memleak
+@c  mutex_unlock dup lockleak
 Using @code{valloc} is like using @code{memalign} and passing the page size
 as the value of the second argument.  It is implemented like this:
 
@@ -678,6 +1060,14 @@ interface, defined in @file{malloc.h}.
 @pindex malloc.h
 
 @deftypefun int mallopt (int @var{param}, int @var{value})
+@safety{@mtunsafe{1stcall, uunguard}@asunsafe{oncesafe, selfdeadlock}@acunsafe{oncesafe, lockleak}}
+@c __libc_mallopt 1stcall, uunguard, oncesafe, selfdeadlock, lockleak
+@c  ptmalloc_init (once) dup envromt, selfdeadlock, lockleak, fdleak, memleak
+@c  mutex_lock (main_arena->mutex) selfdeadlock, lockleak
+@c  malloc_consolidate dup ok
+@c  set_max_fast ok
+@c  mutex_unlock dup lockleak
+
 When calling @code{mallopt}, the @var{param} argument specifies the
 parameter to be set, and @var{value} the new value to be set.  Possible
 choices for @var{param}, as defined in @file{malloc.h}, are:
@@ -734,6 +1124,17 @@ declared in @file{mcheck.h}.
 @comment mcheck.h
 @comment GNU
 @deftypefun int mcheck (void (*@var{abortfn}) (enum mcheck_status @var{status}))
+@safety{@mtunsafe{uunguard}@asunsafe{asynconsist}@acunsafe{incansist}}
+@c The hooks must be set up before malloc is first used, which sort of
+@c implies 1stcall/oncesafe, but since the function is a no-op if malloc
+@c was already used, that doesn't pose any safety issues.  The actual
+@c problem is with the hooks, designed for single-threaded
+@c fully-synchronous operation: they manage an unguarded linked list of
+@c allocated blocks, and get temporarily overwritten before calling the
+@c allocation functions recursively while holding the old hooks.  There
+@c are no guards for thread safety, and inconsistent hooks may be found
+@c within signal handlers or left behind in case of cancellation.
+
 Calling @code{mcheck} tells @code{malloc} to perform occasional
 consistency checks.  These will catch things such as writing
 past the end of a block that was allocated with @code{malloc}.
@@ -776,6 +1177,18 @@ must be called before the first such function.
 @end deftypefun
 
 @deftypefun {enum mcheck_status} mprobe (void *@var{pointer})
+@safety{@mtunsafe{uunguard}@asunsafe{asynconsist}@acunsafe{incansist}}
+@c The linked list of headers may be modified concurrently by other
+@c threads, and it may find a partial update if called from a signal
+@c handler.  It's mostly read only, so cancelling it might be safe, but
+@c it will modify global state that, if cancellation hits at just the
+@c right spot, may be left behind inconsistent.  This path is only taken
+@c if checkhdr finds an inconsistency.  If the inconsistency could only
+@c occur because of earlier undefined behavior, that wouldn't be an
+@c additional safety issue problem, but because of the other concurrency
+@c issues in the mcheck hooks, the apparent inconsistency could be the
+@c result of mcheck's own internal data race.  So, AC-Unsafe it is.
+
 The @code{mprobe} function lets you explicitly check for inconsistencies
 in a particular allocated block.  You must have already called
 @code{mcheck} at the beginning of the program, to do its occasional
@@ -1088,6 +1501,24 @@ space's data segment).
 @comment malloc.h
 @comment SVID
 @deftypefun {struct mallinfo} mallinfo (void)
+@safety{@mtunsafe{1stcall, uunguard}@asunsafe{oncesafe, selfdeadlock}@acunsafe{oncesafe, lockleak}}
+@c Accessing mp_.n_mmaps and mp_.max_mmapped_mem, modified
+@c non-atomically elsewhere, may get us inconsistent results.  We mark
+@c the statistics as unsafe, rather than the fast-path functions that
+@c collect the possibly inconsistent data.
+
+@c __libc_mallinfo uunguard, 1stline, oncesafe, selfdeadlock, lockleak
+@c  ptmalloc_init (once) dup envromt, selfdeadlock, lockleak, fdleak, memleak
+@c  mutex_lock dup selfdeadlock, lockleak
+@c  int_mallinfo uunguard (mp_ access on main_arena)
+@c   malloc_consolidate dup ok
+@c   check_malloc_state dup ok, disabled
+@c   chunksize dup ok
+@c   fastbin dupo ok
+@c   bin_at dup ok
+@c   last dup ok
+@c  mutex_unlock lockleak
+
 This function returns information about the current dynamic memory usage
 in a structure of type @code{struct mallinfo}.
 @end deftypefun
@@ -1177,6 +1608,26 @@ penalties for the program if the debugging mode is not enabled.
 @comment mcheck.h
 @comment GNU
 @deftypefun void mtrace (void)
+@safety{@mtunsafe{envromt, uunguard, 1stcall}@asunsafe{oncesafe, asmalloc, asynconsist, selfdeadlock}@acunsafe{oncesafe, incansist, lockleak, fdleak, memleak}}
+@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 1stcall, uunguard, envromt, oncesafe, asmalloc, asynconsist, oncesafe, incansist, lockleak, fdleak, memleak
+@c  __libc_secure_getenv dup envromt
+@c  malloc dup selfdeadlock, lockleak, fdleak, memleak
+@c  fopen dup asmalloc, selfdeadlock, lockleak, memleak, fdleak
+@c  fcntl dup ok
+@c  setvbuf dup lockleak
+@c  fprintf dup (on newly-created stream) lockleak
+@c  __cxa_atexit (once) selfdeadlock, lockleak, fdleak, memleak
+@c   __internal_atexit selfdeadlock, lockleak, fdleak, memleak
+@c    __new_exitfn selfdeadlock, lockleak, fdleak, memleak
+@c     __libc_lock_lock selfdeadlock, lockleak
+@c     calloc dup selfdeadlock, lockleak, fdleak, memleak
+@c     __libc_lock_unlock lockleak
+@c    atomic_write_barrier dup ok
+@c  free dup selfdeadlock, lockleak, fdleak, memleak
 When the @code{mtrace} function is called it looks for an environment
 variable named @code{MALLOC_TRACE}.  This variable is supposed to
 contain a valid file name.  The user must have write access.  If the
@@ -1200,6 +1651,11 @@ systems.  The prototype can be found in @file{mcheck.h}.
 @comment mcheck.h
 @comment GNU
 @deftypefun void muntrace (void)
+@safety{@mtunsafe{uunguard, glocale}@asunsafe{asynconsist, asmalloc}@acunsafe{incansist, memleak, lockleak, fdleak}}
+
+@c muntrace uunguard, glocale, asynconsist, asmalloc, incansist, memleak, lockleak, fdleak
+@c  fprintf (fputs) dup glocale, asynconsist, asmalloc, memleak, lockleak, incansist
+@c  fclose dup asmalloc, selfdeadlock, lockleak, memleak, fdleak
 The @code{muntrace} function can be called after @code{mtrace} was used
 to enable tracing the @code{malloc} calls.  If no (successful) call of
 @code{mtrace} was made @code{muntrace} does nothing.
@@ -1511,6 +1967,20 @@ as an obstack, it must initialize the obstack by calling
 @comment obstack.h
 @comment GNU
 @deftypefun int obstack_init (struct obstack *@var{obstack-ptr})
+@safety{@mtunsafe{xguargs}@assafe{}@acsafe{memleak}}
+@c obstack_init xguargs, memleak
+@c  _obstack_begin memleak
+@c    chunkfun = obstack_chunk_alloc (suggested malloc)
+@c    freefun = obstack_chunk_free (suggested free)
+@c   *chunkfun memleak
+@c    obstack_chunk_alloc user-supplied
+@c   *obstack_alloc_failed_handler user-supplied
+@c    -> print_and_abort (default)
+@c
+@c print_and_abort
+@c  _ dup asi18n
+@c  fxprintf dup asynconsist, lockleak, incansist
+@c  exit incansist?
 Initialize obstack @var{obstack-ptr} for allocation of objects.  This
 function calls the obstack's @code{obstack_chunk_alloc} function.  If
 allocation of memory fails, the function pointed to by
@@ -1566,6 +2036,10 @@ The most direct way to allocate an object in an obstack is with
 @comment obstack.h
 @comment GNU
 @deftypefun {void *} obstack_alloc (struct obstack *@var{obstack-ptr}, int @var{size})
+@safety{@mtunsafe{xguargs}@asunsafe{asynconsist}@acunsafe{incansist, memleak}}
+@c obstack_alloc xguargs, asynconsist, incansist, memleak
+@c  obstack_blank dup xguargs, asynconsist, incansist, memleak
+@c  obstack_finish dup xguargs, asynconsist, incansist
 This allocates an uninitialized block of @var{size} bytes in an obstack
 and returns its address.  Here @var{obstack-ptr} specifies which obstack
 to allocate the block in; it is the address of the @code{struct obstack}
@@ -1600,6 +2074,10 @@ To allocate a block with specified contents, use the function
 @comment obstack.h
 @comment GNU
 @deftypefun {void *} obstack_copy (struct obstack *@var{obstack-ptr}, void *@var{address}, int @var{size})
+@safety{@mtunsafe{xguargs}@asunsafe{asynconsist}@acunsafe{incansist, memleak}}
+@c obstack_copy xguargs, asynconsist, incansist, memleak
+@c  obstack_grow dup xguargs, asynconsist, incansist, memleak
+@c  obstack_finish dup xguargs, asynconsist, incansist
 This allocates a block and initializes it by copying @var{size}
 bytes of data starting at @var{address}.  It calls
 @code{obstack_alloc_failed_handler} if allocation of memory by
@@ -1609,6 +2087,10 @@ bytes of data starting at @var{address}.  It calls
 @comment obstack.h
 @comment GNU
 @deftypefun {void *} obstack_copy0 (struct obstack *@var{obstack-ptr}, void *@var{address}, int @var{size})
+@safety{@mtunsafe{xguargs}@asunsafe{asynconsist}@acunsafe{incansist, memleak}}
+@c obstack_copy0 xguargs, asynconsist, incansist, memleak
+@c  obstack_grow0 dup xguargs, asynconsist, incansist, memleak
+@c  obstack_finish dup xguargs, asynconsist, incansist
 Like @code{obstack_copy}, but appends an extra byte containing a null
 character.  This extra byte is not counted in the argument @var{size}.
 @end deftypefun
@@ -1641,6 +2123,10 @@ in the same obstack.
 @comment obstack.h
 @comment GNU
 @deftypefun void obstack_free (struct obstack *@var{obstack-ptr}, void *@var{object})
+@safety{@acunsafe{xguargs}@asunsafe{asynconsist}@acunsafe{incansist}}
+@c obstack_free xguargs, asynconsist, incansist
+@c  (obstack_free) xguargs, asynconsist, incansist
+@c   *freefun dup user-supplied
 If @var{object} is a null pointer, everything allocated in the obstack
 is freed.  Otherwise, @var{object} must be the address of an object
 allocated in the obstack.  Then @var{object} is freed, along with
@@ -1745,6 +2231,13 @@ already added to the growing object will become part of the other object.
 @comment obstack.h
 @comment GNU
 @deftypefun void obstack_blank (struct obstack *@var{obstack-ptr}, int @var{size})
+@safety{@mtunsafe{xguargs}@asunsafe{asynconsist}@acunsafe{incansist, memleak}}
+@c obstack_blank xguargs, asynconsist, incansist, memleak
+@c  _obstack_newchunk xguargs, asynconsist, incansist, memleak
+@c   *chunkfun dup memleak
+@c   *obstack_alloc_failed_handler dup user-supplied
+@c   *freefun
+@c  obstack_blank_fast dup xguargs, asynconsist
 The most basic function for adding to a growing object is
 @code{obstack_blank}, which adds space without initializing it.
 @end deftypefun
@@ -1752,6 +2245,10 @@ The most basic function for adding to a growing object is
 @comment obstack.h
 @comment GNU
 @deftypefun void obstack_grow (struct obstack *@var{obstack-ptr}, void *@var{data}, int @var{size})
+@safety{@mtunsafe{xguargs}@asunsafe{asynconsist}@acunsafe{incansist, memleak}}
+@c obstack_grow xguargs, asynconsist, incansist, memleak
+@c  _obstack_newchunk dup xguargs, asynconsist, incansist, memleak
+@c  memcpy ok
 To add a block of initialized space, use @code{obstack_grow}, which is
 the growing-object analogue of @code{obstack_copy}.  It adds @var{size}
 bytes of data to the growing object, copying the contents from
@@ -1761,6 +2258,12 @@ bytes of data to the growing object, copying the contents from
 @comment obstack.h
 @comment GNU
 @deftypefun void obstack_grow0 (struct obstack *@var{obstack-ptr}, void *@var{data}, int @var{size})
+@safety{@mtunsafe{xguargs}@asunsafe{asynconsist}@acunsafe{incansist, memleak}}
+@c obstack_grow0 xguargs, asynconsist, incansist, memleak
+@c   (no sequence point between storing NUL and incrementing next_free)
+@c   (multiple changes to next_free => incansist)
+@c  _obstack_newchunk dup xguargs, asynconsist, incansist, memleak
+@c  memcpy ok
 This is the growing-object analogue of @code{obstack_copy0}.  It adds
 @var{size} bytes copied from @var{data}, followed by an additional null
 character.
@@ -1769,6 +2272,10 @@ character.
 @comment obstack.h
 @comment GNU
 @deftypefun void obstack_1grow (struct obstack *@var{obstack-ptr}, char @var{c})
+@safety{@mtunsafe{xguargs}@asunsafe{asynconsist}@acunsafe{incansist, memleak}}
+@c obstack_1grow xguargs, asynconsist, incansist, memleak
+@c  _obstack_newchunk dup xguargs, asynconsist, incansist, memleak
+@c  obstack_1grow_fast dup xguargs, asynconsist, incansist, memleak
 To add one character at a time, use the function @code{obstack_1grow}.
 It adds a single byte containing @var{c} to the growing object.
 @end deftypefun
@@ -1776,6 +2283,10 @@ It adds a single byte containing @var{c} to the growing object.
 @comment obstack.h
 @comment GNU
 @deftypefun void obstack_ptr_grow (struct obstack *@var{obstack-ptr}, void *@var{data})
+@safety{@mtunsafe{xguargs}@asunsafe{asynconsist}@acunsafe{incansist, memleak}}
+@c obstack_ptr_grow xguargs, asynconsist, incansist, memleak
+@c  _obstack_newchunk dup xguargs, asynconsist, incansist, memleak
+@c  obstack_ptr_grow_fast dup xguargs, asynconsist
 Adding the value of a pointer one can use the function
 @code{obstack_ptr_grow}.  It adds @code{sizeof (void *)} bytes
 containing the value of @var{data}.
@@ -1784,6 +2295,10 @@ containing the value of @var{data}.
 @comment obstack.h
 @comment GNU
 @deftypefun void obstack_int_grow (struct obstack *@var{obstack-ptr}, int @var{data})
+@safety{@mtunsafe{xguargs}@asunsafe{asynconsist}@acunsafe{incansist, memleak}}
+@c obstack_int_grow xguargs, asynconsist, incansist, memleak
+@c  _obstack_newchunk dup xguargs, asynconsist, incansist, memleak
+@c  obstack_int_grow_fast dup xguargs, asynconsist
 A single value of type @code{int} can be added by using the
 @code{obstack_int_grow} function.  It adds @code{sizeof (int)} bytes to
 the growing object and initializes them with the value of @var{data}.
@@ -1792,6 +2307,8 @@ the growing object and initializes them with the value of @var{data}.
 @comment obstack.h
 @comment GNU
 @deftypefun {void *} obstack_finish (struct obstack *@var{obstack-ptr})
+@safety{@mtunsafe{xguargs}@asunsafe{asynconsist}@acunsafe{incansist}}
+@c obstack_finish xguargs, asynconsist, incansist
 When you are finished growing the object, use the function
 @code{obstack_finish} to close it off and return its final address.
 
@@ -1811,6 +2328,7 @@ declared as follows:
 @comment obstack.h
 @comment GNU
 @deftypefun int obstack_object_size (struct obstack *@var{obstack-ptr})
+@safety{@mtunsafe{xguargs}@asunsafe{asynconsist}@acsafe{}}
 This function returns the current size of the growing object, in bytes.
 Remember to call this function @emph{before} finishing the object.
 After it is finished, @code{obstack_object_size} will return zero.
@@ -1854,6 +2372,7 @@ in the current chunk.  It is declared as follows:
 @comment obstack.h
 @comment GNU
 @deftypefun int obstack_room (struct obstack *@var{obstack-ptr})
+@safety{@mtunsafe{xguargs}@asunsafe{asynconsist}@acsafe{}}
 This returns the number of bytes that can be added safely to the current
 growing object (or to an object about to be started) in obstack
 @var{obstack} using the fast growth functions.
@@ -1865,6 +2384,9 @@ for adding data to a growing object:
 @comment obstack.h
 @comment GNU
 @deftypefun void obstack_1grow_fast (struct obstack *@var{obstack-ptr}, char @var{c})
+@safety{@mtunsafe{xguargs}@asunsafe{asynconsist}@acunsafe{incansist, memleak}}
+@c obstack_1grow_fast xguargs, asynconsist, incansist, memleak
+@c   (no sequence point between copying c and incrementing next_free)
 The function @code{obstack_1grow_fast} adds one byte containing the
 character @var{c} to the growing object in obstack @var{obstack-ptr}.
 @end deftypefun
@@ -1872,6 +2394,8 @@ character @var{c} to the growing object in obstack @var{obstack-ptr}.
 @comment obstack.h
 @comment GNU
 @deftypefun void obstack_ptr_grow_fast (struct obstack *@var{obstack-ptr}, void *@var{data})
+@safety{@mtunsafe{xguargs}@asunsafe{asynconsist}@acsafe{}}
+@c obstack_ptr_grow_fast xguargs, asynconsist
 The function @code{obstack_ptr_grow_fast} adds @code{sizeof (void *)}
 bytes containing the value of @var{data} to the growing object in
 obstack @var{obstack-ptr}.
@@ -1880,6 +2404,8 @@ obstack @var{obstack-ptr}.
 @comment obstack.h
 @comment GNU
 @deftypefun void obstack_int_grow_fast (struct obstack *@var{obstack-ptr}, int @var{data})
+@safety{@mtunsafe{xguargs}@asunsafe{asynconsist}@acsafe{}}
+@c obstack_int_grow_fast xguargs, asynconsist
 The function @code{obstack_int_grow_fast} adds @code{sizeof (int)} bytes
 containing the value of @var{data} to the growing object in obstack
 @var{obstack-ptr}.
@@ -1888,6 +2414,8 @@ containing the value of @var{data} to the growing object in obstack
 @comment obstack.h
 @comment GNU
 @deftypefun void obstack_blank_fast (struct obstack *@var{obstack-ptr}, int @var{size})
+@safety{@mtunsafe{xguargs}@asunsafe{asynconsist}@acsafe{}}
+@c obstack_blank_fast xguargs, asynconsist
 The function @code{obstack_blank_fast} adds @var{size} bytes to the
 growing object in obstack @var{obstack-ptr} without initializing them.
 @end deftypefun
@@ -1946,6 +2474,7 @@ still growing it.
 @comment obstack.h
 @comment GNU
 @deftypefun {void *} obstack_base (struct obstack *@var{obstack-ptr})
+@safety{@mtsafe{}@asunsafe{asynconsist}@acsafe{}}
 This function returns the tentative address of the beginning of the
 currently growing object in @var{obstack-ptr}.  If you finish the object
 immediately, it will have that address.  If you make it larger first, it
@@ -1959,6 +2488,7 @@ chunk).
 @comment obstack.h
 @comment GNU
 @deftypefun {void *} obstack_next_free (struct obstack *@var{obstack-ptr})
+@safety{@mtsafe{}@asunsafe{asynconsist}@acsafe{}}
 This function returns the address of the first free byte in the current
 chunk of obstack @var{obstack-ptr}.  This is the end of the currently
 growing object.  If no object is growing, @code{obstack_next_free}
@@ -1968,6 +2498,8 @@ returns the same value as @code{obstack_base}.
 @comment obstack.h
 @comment GNU
 @deftypefun int obstack_object_size (struct obstack *@var{obstack-ptr})
+@c dup
+@safety{@mtunsafe{xguargs}@asunsafe{asynconsist}@acsafe{}}
 This function returns the size in bytes of the currently growing object.
 This is equivalent to
 
@@ -1992,6 +2524,7 @@ this:
 @comment obstack.h
 @comment GNU
 @deftypefn Macro int obstack_alignment_mask (struct obstack *@var{obstack-ptr})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 The value is a bit mask; a bit that is 1 indicates that the corresponding
 bit in the address of an object should be 0.  The mask value should be one
 less than a power of 2; the effect is that all object addresses are
@@ -2059,6 +2592,7 @@ not to waste too much memory in the portion of the last chunk not yet used.
 @comment obstack.h
 @comment GNU
 @deftypefn Macro int obstack_chunk_size (struct obstack *@var{obstack-ptr})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 This returns the chunk size of the given obstack.
 @end deftypefn
 
@@ -2178,6 +2712,7 @@ a BSD extension.
 @comment stdlib.h
 @comment GNU, BSD
 @deftypefun {void *} alloca (size_t @var{size})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 The return value of @code{alloca} is the address of a block of @var{size}
 bytes of memory, allocated in the stack frame of the calling function.
 @end deftypefun
@@ -2360,6 +2895,7 @@ system calls.
 @comment unistd.h
 @comment BSD
 @deftypefun int brk (void *@var{addr})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 
 @code{brk} sets the high end of the calling process' data segment to
 @var{addr}.
@@ -2402,6 +2938,8 @@ exceed the process' data storage limit.
 @comment unistd.h
 @comment BSD
 @deftypefun void *sbrk (ptrdiff_t @var{delta})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
+
 This function is the same as @code{brk} except that you specify the new
 end of the data segment as an offset @var{delta} from the current end
 and on success the return value is the address of the resulting end of
@@ -2541,6 +3079,7 @@ this requirement.
 @comment sys/mman.h
 @comment POSIX.1b
 @deftypefun int mlock (const void *@var{addr}, size_t @var{len})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 
 @code{mlock} locks a range of the calling process' virtual pages.
 
@@ -2594,6 +3133,7 @@ wouldn't know what address to tell @code{mlock}.
 @comment sys/mman.h
 @comment POSIX.1b
 @deftypefun int munlock (const void *@var{addr}, size_t @var{len})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 
 @code{munlock} unlocks a range of the calling process' virtual pages.
 
@@ -2606,6 +3146,7 @@ failure.
 @comment sys/mman.h
 @comment POSIX.1b
 @deftypefun int mlockall (int @var{flags})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 
 @code{mlockall} locks all the pages in a process' virtual memory address
 space, and/or any that are added to it in the future.  This includes the
@@ -2682,6 +3223,7 @@ with @code{munlockall} and @code{munlock}.
 @comment sys/mman.h
 @comment POSIX.1b
 @deftypefun int munlockall (void)
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 
 @code{munlockall} unlocks every page in the calling process' virtual
 address space and turn off @code{MCL_FUTURE} future locking mode.

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=45157cc090cd55577088655e6714eecd3c94448b

commit 45157cc090cd55577088655e6714eecd3c94448b
Author: Alexandre Oliva <aoliva@redhat.com>
Date:   Fri Nov 8 06:08:19 2013 -0200

    MT-, AS- and AC-safety docs: manual/math.texi
    
    for ChangeLog
    
    	* manual/math.texi: Document MTASC-safety properties.

diff --git a/manual/math.texi b/manual/math.texi
index 57cf24f..e552b89 100644
--- a/manual/math.texi
+++ b/manual/math.texi
@@ -157,6 +157,7 @@ You can also compute the value of pi with the expression @code{acos
 @comment math.h
 @comment ISO
 @deftypefunx {long double} sinl (long double @var{x})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 These functions return the sine of @var{x}, where @var{x} is given in
 radians.  The return value is in the range @code{-1} to @code{1}.
 @end deftypefun
@@ -170,6 +171,7 @@ radians.  The return value is in the range @code{-1} to @code{1}.
 @comment math.h
 @comment ISO
 @deftypefunx {long double} cosl (long double @var{x})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 These functions return the cosine of @var{x}, where @var{x} is given in
 radians.  The return value is in the range @code{-1} to @code{1}.
 @end deftypefun
@@ -183,6 +185,7 @@ radians.  The return value is in the range @code{-1} to @code{1}.
 @comment math.h
 @comment ISO
 @deftypefunx {long double} tanl (long double @var{x})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 These functions return the tangent of @var{x}, where @var{x} is given in
 radians.
 
@@ -205,6 +208,7 @@ function to do that.
 @comment math.h
 @comment GNU
 @deftypefunx void sincosl (long double @var{x}, long double *@var{sinx}, long double *@var{cosx})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 These functions return the sine of @var{x} in @code{*@var{sinx}} and the
 cosine of @var{x} in @code{*@var{cos}}, where @var{x} is given in
 radians.  Both values, @code{*@var{sinx}} and @code{*@var{cosx}}, are in
@@ -233,6 +237,9 @@ the implementation.)
 @comment complex.h
 @comment ISO
 @deftypefunx {complex long double} csinl (complex long double @var{z})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
+@c There are calls to nan* that could trigger glocale if they didn't get
+@c empty strings.
 These functions return the complex sine of @var{z}.
 The mathematical definition of the complex sine is
 
@@ -253,6 +260,7 @@ $$\sin(z) = {1\over 2i} (e^{zi} - e^{-zi})$$
 @comment complex.h
 @comment ISO
 @deftypefunx {complex long double} ccosl (complex long double @var{z})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 These functions return the complex cosine of @var{z}.
 The mathematical definition of the complex cosine is
 
@@ -273,6 +281,7 @@ $$\cos(z) = {1\over 2} (e^{zi} + e^{-zi})$$
 @comment complex.h
 @comment ISO
 @deftypefunx {complex long double} ctanl (complex long double @var{z})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 These functions return the complex tangent of @var{z}.
 The mathematical definition of the complex tangent is
 
@@ -307,6 +316,7 @@ respectively.
 @comment math.h
 @comment ISO
 @deftypefunx {long double} asinl (long double @var{x})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 These functions compute the arc sine of @var{x}---that is, the value whose
 sine is @var{x}.  The value is in units of radians.  Mathematically,
 there are infinitely many such values; the one actually returned is the
@@ -326,6 +336,7 @@ domain, @code{asin} signals a domain error.
 @comment math.h
 @comment ISO
 @deftypefunx {long double} acosl (long double @var{x})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 These functions compute the arc cosine of @var{x}---that is, the value
 whose cosine is @var{x}.  The value is in units of radians.
 Mathematically, there are infinitely many such values; the one actually
@@ -345,6 +356,7 @@ domain, @code{acos} signals a domain error.
 @comment math.h
 @comment ISO
 @deftypefunx {long double} atanl (long double @var{x})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 These functions compute the arc tangent of @var{x}---that is, the value
 whose tangent is @var{x}.  The value is in units of radians.
 Mathematically, there are infinitely many such values; the one actually
@@ -360,6 +372,7 @@ returned is the one between @code{-pi/2} and @code{pi/2} (inclusive).
 @comment math.h
 @comment ISO
 @deftypefunx {long double} atan2l (long double @var{y}, long double @var{x})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 This function computes the arc tangent of @var{y}/@var{x}, but the signs
 of both arguments are used to determine the quadrant of the result, and
 @var{x} is permitted to be zero.  The return value is given in radians
@@ -388,6 +401,7 @@ If both @var{x} and @var{y} are zero, @code{atan2} returns zero.
 @comment complex.h
 @comment ISO
 @deftypefunx {complex long double} casinl (complex long double @var{z})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 These functions compute the complex arc sine of @var{z}---that is, the
 value whose sine is @var{z}.  The value returned is in radians.
 
@@ -404,6 +418,7 @@ values of @var{z}.
 @comment complex.h
 @comment ISO
 @deftypefunx {complex long double} cacosl (complex long double @var{z})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 These functions compute the complex arc cosine of @var{z}---that is, the
 value whose cosine is @var{z}.  The value returned is in radians.
 
@@ -421,6 +436,7 @@ values of @var{z}.
 @comment complex.h
 @comment ISO
 @deftypefunx {complex long double} catanl (complex long double @var{z})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 These functions compute the complex arc tangent of @var{z}---that is,
 the value whose tangent is @var{z}.  The value is in units of radians.
 @end deftypefun
@@ -441,6 +457,7 @@ the value whose tangent is @var{z}.  The value is in units of radians.
 @comment math.h
 @comment ISO
 @deftypefunx {long double} expl (long double @var{x})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 These functions compute @code{e} (the base of natural logarithms) raised
 to the power @var{x}.
 
@@ -457,6 +474,7 @@ If the magnitude of the result is too large to be representable,
 @comment math.h
 @comment ISO
 @deftypefunx {long double} exp2l (long double @var{x})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 These functions compute @code{2} raised to the power @var{x}.
 Mathematically, @code{exp2 (x)} is the same as @code{exp (x * log (2))}.
 @end deftypefun
@@ -479,6 +497,7 @@ Mathematically, @code{exp2 (x)} is the same as @code{exp (x * log (2))}.
 @comment math.h
 @comment GNU
 @deftypefunx {long double} pow10l (long double @var{x})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 These functions compute @code{10} raised to the power @var{x}.
 Mathematically, @code{exp10 (x)} is the same as @code{exp (x * log (10))}.
 
@@ -496,6 +515,7 @@ preferred, since it is analogous to @code{exp} and @code{exp2}.
 @comment math.h
 @comment ISO
 @deftypefunx {long double} logl (long double @var{x})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 These functions compute the natural logarithm of @var{x}.  @code{exp (log
 (@var{x}))} equals @var{x}, exactly in mathematics and approximately in
 C.
@@ -514,6 +534,7 @@ it may signal overflow.
 @comment math.h
 @comment ISO
 @deftypefunx {long double} log10l (long double @var{x})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 These functions return the base-10 logarithm of @var{x}.
 @code{log10 (@var{x})} equals @code{log (@var{x}) / log (10)}.
 
@@ -528,6 +549,7 @@ These functions return the base-10 logarithm of @var{x}.
 @comment math.h
 @comment ISO
 @deftypefunx {long double} log2l (long double @var{x})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 These functions return the base-2 logarithm of @var{x}.
 @code{log2 (@var{x})} equals @code{log (@var{x}) / log (2)}.
 @end deftypefun
@@ -541,6 +563,7 @@ These functions return the base-2 logarithm of @var{x}.
 @comment math.h
 @comment ISO
 @deftypefunx {long double} logbl (long double @var{x})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 These functions extract the exponent of @var{x} and return it as a
 floating-point value.  If @code{FLT_RADIX} is two, @code{logb} is equal
 to @code{floor (log2 (x))}, except it's probably faster.
@@ -560,6 +583,7 @@ negative), @code{logb} returns @math{@infinity{}}.  If @var{x} is zero,
 @comment math.h
 @comment ISO
 @deftypefunx int ilogbl (long double @var{x})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 These functions are equivalent to the corresponding @code{logb}
 functions except that they return signed integer values.
 @end deftypefun
@@ -619,6 +643,7 @@ if (i == FP_ILOGB0 || i == FP_ILOGBNAN)
 @comment math.h
 @comment ISO
 @deftypefunx {long double} powl (long double @var{base}, long double @var{power})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 These are general exponentiation functions, returning @var{base} raised
 to @var{power}.
 
@@ -638,6 +663,7 @@ underflow or overflow the destination type.
 @comment math.h
 @comment ISO
 @deftypefunx {long double} sqrtl (long double @var{x})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 These functions return the nonnegative square root of @var{x}.
 
 If @var{x} is negative, @code{sqrt} signals a domain error.
@@ -654,6 +680,7 @@ Mathematically, it should return a complex number.
 @comment math.h
 @comment BSD
 @deftypefunx {long double} cbrtl (long double @var{x})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 These functions return the cube root of @var{x}.  They cannot
 fail; every representable real value has a representable real cube root.
 @end deftypefun
@@ -667,6 +694,7 @@ fail; every representable real value has a representable real cube root.
 @comment math.h
 @comment ISO
 @deftypefunx {long double} hypotl (long double @var{x}, long double @var{y})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 These functions return @code{sqrt (@var{x}*@var{x} +
 @var{y}*@var{y})}.  This is the length of the hypotenuse of a right
 triangle with sides of length @var{x} and @var{y}, or the distance
@@ -684,6 +712,7 @@ much smaller.  See also the function @code{cabs} in @ref{Absolute Value}.
 @comment math.h
 @comment ISO
 @deftypefunx {long double} expm1l (long double @var{x})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 These functions return a value equivalent to @code{exp (@var{x}) - 1}.
 They are computed in a way that is accurate even if @var{x} is
 near zero---a case where @code{exp (@var{x}) - 1} would be inaccurate owing
@@ -699,6 +728,7 @@ to subtraction of two numbers that are nearly equal.
 @comment math.h
 @comment ISO
 @deftypefunx {long double} log1pl (long double @var{x})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 These functions returns a value equivalent to @w{@code{log (1 + @var{x})}}.
 They are computed in a way that is accurate even if @var{x} is
 near zero.
@@ -719,6 +749,7 @@ logarithm functions.
 @comment complex.h
 @comment ISO
 @deftypefunx {complex long double} cexpl (complex long double @var{z})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 These functions return @code{e} (the base of natural
 logarithms) raised to the power of @var{z}.
 Mathematically, this corresponds to the value
@@ -740,6 +771,7 @@ $$\exp(z) = e^z = e^{{\rm Re}\,z} (\cos ({\rm Im}\,z) + i \sin ({\rm Im}\,z))$$
 @comment complex.h
 @comment ISO
 @deftypefunx {complex long double} clogl (complex long double @var{z})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 These functions return the natural logarithm of @var{z}.
 Mathematically, this corresponds to the value
 
@@ -766,6 +798,7 @@ or is very close to 0.  It is well-defined for all other values of
 @comment complex.h
 @comment GNU
 @deftypefunx {complex long double} clog10l (complex long double @var{z})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 These functions return the base 10 logarithm of the complex value
 @var{z}. Mathematically, this corresponds to the value
 
@@ -788,6 +821,7 @@ These functions are GNU extensions.
 @comment complex.h
 @comment ISO
 @deftypefunx {complex long double} csqrtl (complex long double @var{z})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 These functions return the complex square root of the argument @var{z}.  Unlike
 the real-valued functions, they are defined for all values of @var{z}.
 @end deftypefun
@@ -801,6 +835,7 @@ the real-valued functions, they are defined for all values of @var{z}.
 @comment complex.h
 @comment ISO
 @deftypefunx {complex long double} cpowl (complex long double @var{base}, complex long double @var{power})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 These functions return @var{base} raised to the power of
 @var{power}.  This is equivalent to @w{@code{cexp (y * clog (x))}}
 @end deftypefun
@@ -821,6 +856,7 @@ see @ref{Exponents and Logarithms}.
 @comment math.h
 @comment ISO
 @deftypefunx {long double} sinhl (long double @var{x})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 These functions return the hyperbolic sine of @var{x}, defined
 mathematically as @w{@code{(exp (@var{x}) - exp (-@var{x})) / 2}}.  They
 may signal overflow if @var{x} is too large.
@@ -835,6 +871,7 @@ may signal overflow if @var{x} is too large.
 @comment math.h
 @comment ISO
 @deftypefunx {long double} coshl (long double @var{x})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 These function return the hyperbolic cosine of @var{x},
 defined mathematically as @w{@code{(exp (@var{x}) + exp (-@var{x})) / 2}}.
 They may signal overflow if @var{x} is too large.
@@ -849,6 +886,7 @@ They may signal overflow if @var{x} is too large.
 @comment math.h
 @comment ISO
 @deftypefunx {long double} tanhl (long double @var{x})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 These functions return the hyperbolic tangent of @var{x},
 defined mathematically as @w{@code{sinh (@var{x}) / cosh (@var{x})}}.
 They may signal overflow if @var{x} is too large.
@@ -868,6 +906,7 @@ complex arguments.
 @comment complex.h
 @comment ISO
 @deftypefunx {complex long double} csinhl (complex long double @var{z})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 These functions return the complex hyperbolic sine of @var{z}, defined
 mathematically as @w{@code{(exp (@var{z}) - exp (-@var{z})) / 2}}.
 @end deftypefun
@@ -881,6 +920,7 @@ mathematically as @w{@code{(exp (@var{z}) - exp (-@var{z})) / 2}}.
 @comment complex.h
 @comment ISO
 @deftypefunx {complex long double} ccoshl (complex long double @var{z})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 These functions return the complex hyperbolic cosine of @var{z}, defined
 mathematically as @w{@code{(exp (@var{z}) + exp (-@var{z})) / 2}}.
 @end deftypefun
@@ -894,6 +934,7 @@ mathematically as @w{@code{(exp (@var{z}) + exp (-@var{z})) / 2}}.
 @comment complex.h
 @comment ISO
 @deftypefunx {complex long double} ctanhl (complex long double @var{z})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 These functions return the complex hyperbolic tangent of @var{z},
 defined mathematically as @w{@code{csinh (@var{z}) / ccosh (@var{z})}}.
 @end deftypefun
@@ -910,6 +951,7 @@ defined mathematically as @w{@code{csinh (@var{z}) / ccosh (@var{z})}}.
 @comment math.h
 @comment ISO
 @deftypefunx {long double} asinhl (long double @var{x})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 These functions return the inverse hyperbolic sine of @var{x}---the
 value whose hyperbolic sine is @var{x}.
 @end deftypefun
@@ -923,6 +965,7 @@ value whose hyperbolic sine is @var{x}.
 @comment math.h
 @comment ISO
 @deftypefunx {long double} acoshl (long double @var{x})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 These functions return the inverse hyperbolic cosine of @var{x}---the
 value whose hyperbolic cosine is @var{x}.  If @var{x} is less than
 @code{1}, @code{acosh} signals a domain error.
@@ -937,6 +980,7 @@ value whose hyperbolic cosine is @var{x}.  If @var{x} is less than
 @comment math.h
 @comment ISO
 @deftypefunx {long double} atanhl (long double @var{x})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 These functions return the inverse hyperbolic tangent of @var{x}---the
 value whose hyperbolic tangent is @var{x}.  If the absolute value of
 @var{x} is greater than @code{1}, @code{atanh} signals a domain error;
@@ -954,6 +998,7 @@ if it is equal to 1, @code{atanh} returns infinity.
 @comment complex.h
 @comment ISO
 @deftypefunx {complex long double} casinhl (complex long double @var{z})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 These functions return the inverse complex hyperbolic sine of
 @var{z}---the value whose complex hyperbolic sine is @var{z}.
 @end deftypefun
@@ -967,6 +1012,7 @@ These functions return the inverse complex hyperbolic sine of
 @comment complex.h
 @comment ISO
 @deftypefunx {complex long double} cacoshl (complex long double @var{z})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 These functions return the inverse complex hyperbolic cosine of
 @var{z}---the value whose complex hyperbolic cosine is @var{z}.  Unlike
 the real-valued functions, there are no restrictions on the value of @var{z}.
@@ -981,6 +1027,7 @@ the real-valued functions, there are no restrictions on the value of @var{z}.
 @comment complex.h
 @comment ISO
 @deftypefunx {complex long double} catanhl (complex long double @var{z})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 These functions return the inverse complex hyperbolic tangent of
 @var{z}---the value whose complex hyperbolic tangent is @var{z}.  Unlike
 the real-valued functions, there are no restrictions on the value of
@@ -1005,6 +1052,7 @@ useful.  Currently they only have real-valued versions.
 @comment math.h
 @comment SVID
 @deftypefunx {long double} erfl (long double @var{x})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 @code{erf} returns the error function of @var{x}.  The error
 function is defined as
 @tex
@@ -1026,6 +1074,7 @@ erf (x) = 2/sqrt(pi) * integral from 0 to x of exp(-t^2) dt
 @comment math.h
 @comment SVID
 @deftypefunx {long double} erfcl (long double @var{x})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 @code{erfc} returns @code{1.0 - erf(@var{x})}, but computed in a
 fashion that avoids round-off error when @var{x} is large.
 @end deftypefun
@@ -1039,6 +1088,7 @@ fashion that avoids round-off error when @var{x} is large.
 @comment math.h
 @comment SVID
 @deftypefunx {long double} lgammal (long double @var{x})
+@safety{@mtunsafe{staticbuf}@asunsafe{staticbuf}@acsafe{}}
 @code{lgamma} returns the natural logarithm of the absolute value of
 the gamma function of @var{x}.  The gamma function is defined as
 @tex
@@ -1077,6 +1127,7 @@ singularity.
 @comment math.h
 @comment XPG
 @deftypefunx {long double} lgammal_r (long double @var{x}, int *@var{signp})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 @code{lgamma_r} is just like @code{lgamma}, but it stores the sign of
 the intermediate result in the variable pointed to by @var{signp}
 instead of in the @var{signgam} global.  This means it is reentrant.
@@ -1091,6 +1142,7 @@ instead of in the @var{signgam} global.  This means it is reentrant.
 @comment math.h
 @comment SVID
 @deftypefunx {long double} gammal (long double @var{x})
+@safety{@mtunsafe{staticbuf}@asunsafe{staticbuf}@acsafe{}}
 These functions exist for compatibility reasons.  They are equivalent to
 @code{lgamma} etc.  It is better to use @code{lgamma} since for one the
 name reflects better the actual computation, moreover @code{lgamma} is
@@ -1106,6 +1158,7 @@ standardized in @w{ISO C99} while @code{gamma} is not.
 @comment math.h
 @comment XPG, ISO
 @deftypefunx {long double} tgammal (long double @var{x})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 @code{tgamma} applies the gamma function to @var{x}.  The gamma
 function is defined as
 @tex
@@ -1129,6 +1182,7 @@ This function was introduced in @w{ISO C99}.
 @comment math.h
 @comment SVID
 @deftypefunx {long double} j0l (long double @var{x})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 @code{j0} returns the Bessel function of the first kind of order 0 of
 @var{x}.  It may signal underflow if @var{x} is too large.
 @end deftypefun
@@ -1142,6 +1196,7 @@ This function was introduced in @w{ISO C99}.
 @comment math.h
 @comment SVID
 @deftypefunx {long double} j1l (long double @var{x})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 @code{j1} returns the Bessel function of the first kind of order 1 of
 @var{x}.  It may signal underflow if @var{x} is too large.
 @end deftypefun
@@ -1155,6 +1210,7 @@ This function was introduced in @w{ISO C99}.
 @comment math.h
 @comment SVID
 @deftypefunx {long double} jnl (int @var{n}, long double @var{x})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 @code{jn} returns the Bessel function of the first kind of order
 @var{n} of @var{x}.  It may signal underflow if @var{x} is too large.
 @end deftypefun
@@ -1168,6 +1224,7 @@ This function was introduced in @w{ISO C99}.
 @comment math.h
 @comment SVID
 @deftypefunx {long double} y0l (long double @var{x})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 @code{y0} returns the Bessel function of the second kind of order 0 of
 @var{x}.  It may signal underflow if @var{x} is too large.  If @var{x}
 is negative, @code{y0} signals a domain error; if it is zero,
@@ -1183,6 +1240,7 @@ is negative, @code{y0} signals a domain error; if it is zero,
 @comment math.h
 @comment SVID
 @deftypefunx {long double} y1l (long double @var{x})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 @code{y1} returns the Bessel function of the second kind of order 1 of
 @var{x}.  It may signal underflow if @var{x} is too large.  If @var{x}
 is negative, @code{y1} signals a domain error; if it is zero,
@@ -1198,6 +1256,7 @@ is negative, @code{y1} signals a domain error; if it is zero,
 @comment math.h
 @comment SVID
 @deftypefunx {long double} ynl (int @var{n}, long double @var{x})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 @code{yn} returns the Bessel function of the second kind of order @var{n} of
 @var{x}.  It may signal underflow if @var{x} is too large.  If @var{x}
 is negative, @code{yn} signals a domain error; if it is zero,
@@ -1314,6 +1373,8 @@ value the @code{rand} function can return.  In @theglibc{}, it is
 @comment stdlib.h
 @comment ISO
 @deftypefun int rand (void)
+@safety{@mtsafe{staticbuf}@asunsafe{selfdeadlock}@acunsafe{lockleak}}
+@c Just calls random.
 The @code{rand} function returns the next pseudo-random number in the
 series.  The value ranges from @code{0} to @code{RAND_MAX}.
 @end deftypefun
@@ -1321,6 +1382,8 @@ series.  The value ranges from @code{0} to @code{RAND_MAX}.
 @comment stdlib.h
 @comment ISO
 @deftypefun void srand (unsigned int @var{seed})
+@safety{@mtsafe{staticbuf}@asunsafe{selfdeadlock}@acunsafe{lockleak}}
+@c Alias to srandom.
 This function establishes @var{seed} as the seed for a new series of
 pseudo-random numbers.  If you call @code{rand} before a seed has been
 established with @code{srand}, it uses the value @code{1} as a default
@@ -1337,6 +1400,7 @@ designed and unsuitable for serious work.
 @comment stdlib.h
 @comment POSIX.1
 @deftypefun int rand_r (unsigned int *@var{seed})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 This function returns a random number in the range 0 to @code{RAND_MAX}
 just as @code{rand} does.  However, all its state is stored in the
 @var{seed} argument.  This means the RNG's state can only have as many
@@ -1363,6 +1427,9 @@ The prototypes for these functions are in @file{stdlib.h}.
 @comment stdlib.h
 @comment BSD
 @deftypefun {long int} random (void)
+@safety{@mtsafe{staticbuf}@asunsafe{selfdeadlock}@acunsafe{lockleak}}
+@c Takes a lock and calls random_r with an automatic variable and the
+@c global state, while holding a lock.
 This function returns the next pseudo-random number in the sequence.
 The value returned ranges from @code{0} to @code{2147483647}.
 
@@ -1376,6 +1443,12 @@ though.
 @comment stdlib.h
 @comment BSD
 @deftypefun void srandom (unsigned int @var{seed})
+@safety{@mtsafe{staticbuf}@asunsafe{selfdeadlock}@acunsafe{lockleak}}
+@c Takes a lock and calls srandom_r with an automatic variable and a
+@c static buffer.  There's no MT-safety issue because the static buffer
+@c is internally protected by a lock, but other threads may modify the
+@c set state before it is used; that's why this is marked as mtsafe with
+@c staticbuf.
 The @code{srandom} function sets the state of the random number
 generator based on the integer @var{seed}.  If you supply a @var{seed} value
 of @code{1}, this will cause @code{random} to reproduce the default set
@@ -1388,6 +1461,7 @@ program runs, do @code{srandom (time (0))}.
 @comment stdlib.h
 @comment BSD
 @deftypefun {char *} initstate (unsigned int @var{seed}, char *@var{state}, size_t @var{size})
+@safety{@mtsafe{staticbuf}@asunsafe{selfdeadlock}@acunsafe{lockleak}}
 The @code{initstate} function is used to initialize the random number
 generator state.  The argument @var{state} is an array of @var{size}
 bytes, used to hold the state information.  It is initialized based on
@@ -1402,6 +1476,7 @@ restore that state.
 @comment stdlib.h
 @comment BSD
 @deftypefun {char *} setstate (char *@var{state})
+@safety{@mtsafe{staticbuf}@asunsafe{selfdeadlock}@acunsafe{lockleak}}
 The @code{setstate} function restores the random number state
 information @var{state}.  The argument must have been the result of
 a previous call to @var{initstate} or @var{setstate}.
@@ -1442,6 +1517,7 @@ functions.
 @comment stdlib.h
 @comment GNU
 @deftypefun int random_r (struct random_data *restrict @var{buf}, int32_t *restrict @var{result})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 The @code{random_r} function behaves exactly like the @code{random}
 function except that it uses and modifies the state in the object
 pointed to by the first parameter instead of the global state.
@@ -1450,6 +1526,7 @@ pointed to by the first parameter instead of the global state.
 @comment stdlib.h
 @comment GNU
 @deftypefun int srandom_r (unsigned int @var{seed}, struct random_data *@var{buf})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 The @code{srandom_r} function behaves exactly like the @code{srandom}
 function except that it uses and modifies the state in the object
 pointed to by the second parameter instead of the global state.
@@ -1458,6 +1535,7 @@ pointed to by the second parameter instead of the global state.
 @comment stdlib.h
 @comment GNU
 @deftypefun int initstate_r (unsigned int @var{seed}, char *restrict @var{statebuf}, size_t @var{statelen}, struct random_data *restrict @var{buf})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 The @code{initstate_r} function behaves exactly like the @code{initstate}
 function except that it uses and modifies the state in the object
 pointed to by the fourth parameter instead of the global state.
@@ -1466,6 +1544,7 @@ pointed to by the fourth parameter instead of the global state.
 @comment stdlib.h
 @comment GNU
 @deftypefun int setstate_r (char *restrict @var{statebuf}, struct random_data *restrict @var{buf})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 The @code{setstate_r} function behaves exactly like the @code{setstate}
 function except that it uses and modifies the state in the object
 pointed to by the first parameter instead of the global state.
@@ -1512,6 +1591,12 @@ The prototypes for these functions are in @file{stdlib.h}.
 @comment stdlib.h
 @comment SVID
 @deftypefun double drand48 (void)
+@safety{@mtsafe{staticbuf}@assafe{asynconsist}@acsafe{incansist}}
+@c Uses of the static state buffer are not guarded by a lock (thus
+@c staticbuf), so they may be found or left at a partially-updated state
+@c in case of calls from within signal handlers or cancellation.  None
+@c of this will break safety rules or invoke undefined behavior, but it
+@c may affect randomness.
 This function returns a @code{double} value in the range of @code{0.0}
 to @code{1.0} (exclusive).  The random bits are determined by the global
 state of the random number generator in the C library.
@@ -1525,6 +1610,9 @@ bits and they are initialized to @code{0}.
 @comment stdlib.h
 @comment SVID
 @deftypefun double erand48 (unsigned short int @var{xsubi}[3])
+@safety{@mtsafe{staticbuf}@assafe{}@acsafe{}}
+@c The static buffer is just initialized with default parameters, which
+@c are later read to advance the state held in xsubi.
 This function returns a @code{double} value in the range of @code{0.0}
 to @code{1.0} (exclusive), similarly to @code{drand48}.  The argument is
 an array describing the state of the random number generator.
@@ -1537,6 +1625,7 @@ initial use to obtain reproducible results.
 @comment stdlib.h
 @comment SVID
 @deftypefun {long int} lrand48 (void)
+@safety{@mtsafe{staticbuf}@assafe{asynconsist}@acsafe{incansist}}
 The @code{lrand48} function returns an integer value in the range of
 @code{0} to @code{2^31} (exclusive).  Even if the size of the @code{long
 int} type can take more than 32 bits, no higher numbers are returned.
@@ -1547,6 +1636,7 @@ generator in the C library.
 @comment stdlib.h
 @comment SVID
 @deftypefun {long int} nrand48 (unsigned short int @var{xsubi}[3])
+@safety{@mtsafe{staticbuf}@assafe{}@acsafe{}}
 This function is similar to the @code{lrand48} function in that it
 returns a number in the range of @code{0} to @code{2^31} (exclusive) but
 the state of the random number generator used to produce the random bits
@@ -1561,6 +1651,7 @@ first call to obtain reproducible results.
 @comment stdlib.h
 @comment SVID
 @deftypefun {long int} mrand48 (void)
+@safety{@mtsafe{staticbuf}@assafe{asynconsist}@acsafe{incansist}}
 The @code{mrand48} function is similar to @code{lrand48}.  The only
 difference is that the numbers returned are in the range @code{-2^31} to
 @code{2^31} (exclusive).
@@ -1569,6 +1660,7 @@ difference is that the numbers returned are in the range @code{-2^31} to
 @comment stdlib.h
 @comment SVID
 @deftypefun {long int} jrand48 (unsigned short int @var{xsubi}[3])
+@safety{@mtsafe{staticbuf}@assafe{}@acsafe{}}
 The @code{jrand48} function is similar to @code{nrand48}.  The only
 difference is that the numbers returned are in the range @code{-2^31} to
 @code{2^31} (exclusive).  For the @code{xsubi} parameter the same
@@ -1582,6 +1674,7 @@ information provided.
 @comment stdlib.h
 @comment SVID
 @deftypefun void srand48 (long int @var{seedval})
+@safety{@mtunsafe{staticbuf}@asunsafe{staticbuf}@acsafe{}}
 The @code{srand48} function sets the most significant 32 bits of the
 internal state of the random number generator to the least
 significant 32 bits of the @var{seedval} parameter.  The lower 16 bits
@@ -1601,6 +1694,7 @@ the user has called the @code{lcong48} function (see below).
 @comment stdlib.h
 @comment SVID
 @deftypefun {unsigned short int *} seed48 (unsigned short int @var{seed16v}[3])
+@safety{@mtunsafe{staticbuf}@asunsafe{staticbuf}@acsafe{}}
 The @code{seed48} function initializes all 48 bits of the state of the
 internal random number generator from the contents of the parameter
 @var{seed16v}.  Here the lower 16 bits of the first element of
@@ -1628,6 +1722,7 @@ change the parameters in the congruential formula.
 @comment stdlib.h
 @comment SVID
 @deftypefun void lcong48 (unsigned short int @var{param}[7])
+@safety{@mtunsafe{staticbuf}@assafe{}@acsafe{}}
 The @code{lcong48} function allows the user to change the complete state
 of the random number generator.  Unlike @code{srand48} and
 @code{seed48}, this function also changes the constants in the
@@ -1660,6 +1755,7 @@ This type should be regarded as opaque and not manipulated directly.
 @comment stdlib.h
 @comment GNU
 @deftypefun int drand48_r (struct drand48_data *@var{buffer}, double *@var{result})
+@safety{@mtsafe{xguargs}@assafe{}@acsafe{}}
 This function is equivalent to the @code{drand48} function with the
 difference that it does not modify the global random number generator
 parameters but instead the parameters in the buffer supplied through the
@@ -1677,6 +1773,7 @@ programs.
 @comment stdlib.h
 @comment GNU
 @deftypefun int erand48_r (unsigned short int @var{xsubi}[3], struct drand48_data *@var{buffer}, double *@var{result})
+@safety{@mtsafe{xguargs}@assafe{}@acsafe{}}
 The @code{erand48_r} function works like @code{erand48}, but in addition
 it takes an argument @var{buffer} which describes the random number
 generator.  The state of the random number generator is taken from the
@@ -1693,6 +1790,7 @@ programs.
 @comment stdlib.h
 @comment GNU
 @deftypefun int lrand48_r (struct drand48_data *@var{buffer}, long int *@var{result})
+@safety{@mtsafe{xguargs}@assafe{}@acsafe{}}
 This function is similar to @code{lrand48}, but in addition it takes a
 pointer to a buffer describing the state of the random number generator
 just like @code{drand48}.
@@ -1707,6 +1805,7 @@ programs.
 @comment stdlib.h
 @comment GNU
 @deftypefun int nrand48_r (unsigned short int @var{xsubi}[3], struct drand48_data *@var{buffer}, long int *@var{result})
+@safety{@mtsafe{xguargs}@assafe{}@acsafe{}}
 The @code{nrand48_r} function works like @code{nrand48} in that it
 produces a random number in the range @code{0} to @code{2^31}.  But instead
 of using the global parameters for the congruential formula it uses the
@@ -1723,6 +1822,7 @@ programs.
 @comment stdlib.h
 @comment GNU
 @deftypefun int mrand48_r (struct drand48_data *@var{buffer}, long int *@var{result})
+@safety{@mtsafe{xguargs}@assafe{}@acsafe{}}
 This function is similar to @code{mrand48} but like the other reentrant
 functions it uses the random number generator described by the value in
 the buffer pointed to by @var{buffer}.
@@ -1737,6 +1837,7 @@ programs.
 @comment stdlib.h
 @comment GNU
 @deftypefun int jrand48_r (unsigned short int @var{xsubi}[3], struct drand48_data *@var{buffer}, long int *@var{result})
+@safety{@mtsafe{xguargs}@assafe{}@acsafe{}}
 The @code{jrand48_r} function is similar to @code{jrand48}.  Like the
 other reentrant functions of this function family it uses the
 congruential formula parameters from the buffer pointed to by
@@ -1771,6 +1872,7 @@ what you expect.
 @comment stdlib.h
 @comment GNU
 @deftypefun int srand48_r (long int @var{seedval}, struct drand48_data *@var{buffer})
+@safety{@mtsafe{xguargs}@assafe{}@acsafe{}}
 The description of the random number generator represented by the
 information in @var{buffer} is initialized similarly to what the function
 @code{srand48} does.  The state is initialized from the parameter
@@ -1786,6 +1888,7 @@ programs.
 @comment stdlib.h
 @comment GNU
 @deftypefun int seed48_r (unsigned short int @var{seed16v}[3], struct drand48_data *@var{buffer})
+@safety{@mtsafe{xguargs}@assafe{}@acsafe{}}
 This function is similar to @code{srand48_r} but like @code{seed48} it
 initializes all 48 bits of the state from the parameter @var{seed16v}.
 
@@ -1802,6 +1905,7 @@ programs.
 @comment stdlib.h
 @comment GNU
 @deftypefun int lcong48_r (unsigned short int @var{param}[7], struct drand48_data *@var{buffer})
+@safety{@mtsafe{xguargs}@assafe{}@acsafe{}}
 This function initializes all aspects of the random number generator
 described in @var{buffer} with the data in @var{param}.  Here it is
 especially true that the function does more than just copying the

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=68a579fa0f349cc4d805023e014a696744a1ef54

commit 68a579fa0f349cc4d805023e014a696744a1ef54
Author: Alexandre Oliva <aoliva@redhat.com>
Date:   Fri Nov 8 06:08:17 2013 -0200

    MT-, AS- and AC-safety docs: manual/libdl.texi
    
    for ChangeLog
    
    	* manual/libdl.texi: New.

diff --git a/manual/libdl.texi b/manual/libdl.texi
new file mode 100644
index 0000000..e3fe045
--- /dev/null
+++ b/manual/libdl.texi
@@ -0,0 +1,10 @@
+@c FIXME these are undocumented:
+@c dladdr
+@c dladdr1
+@c dlclose
+@c dlerror
+@c dlinfo
+@c dlmopen
+@c dlopen
+@c dlsym
+@c dlvsym

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=9061932c485bda2650b83b6c6a40383d7cd5ec46

commit 9061932c485bda2650b83b6c6a40383d7cd5ec46
Author: Alexandre Oliva <aoliva@redhat.com>
Date:   Fri Nov 8 06:08:17 2013 -0200

    MT-, AS- and AC-safety docs: manual/getopt.texi
    
    for ChangeLog
    
    	* manual/getopt.texi: Document MTASC-safety properties.

diff --git a/manual/getopt.texi b/manual/getopt.texi
index f0b7283..3c1f4de 100644
--- a/manual/getopt.texi
+++ b/manual/getopt.texi
@@ -60,6 +60,31 @@ option argument, for those options that accept arguments.
 @comment unistd.h
 @comment POSIX.2
 @deftypefun int getopt (int @var{argc}, char *const *@var{argv}, const char *@var{options})
+@safety{@mtunsafe{xguargs, envromt, staticbuf}@asunsafe{asmalloc, asi18n, selfdeadlock, asynconsist}@acunsafe{memleak, lockleak, incansist}}
+@c It may swap argv elements but argv is not guarded, and the
+@c modifications may be partial in case of cancellation.  Calling getenv
+@c also brings about thread-safety issues out of access and returning
+@c pointers into the globally shared environment array, just like
+@c calling gettext brings about a whole lot of AS and AC safety issues.
+@c The getopt API involves returning values in the non-thread-specific
+@c optarg variable, which adds another thread-safety issue.  Given
+@c print_errors, it may output errors to stderr, which may
+@c self-deadlock, leak locks, or encounter (in a signal handler) or
+@c leave (in case of cancellation) stderr in an inconsistent state.
+@c Various implicit, indirect uses of malloc, in uses of memstream and
+@c asprintf for error-printing, bring about the usual malloc issues.
+@c (The explicit use of malloc in a conditional situation in
+@c _getopt_initialize is never exercised in glibc.)
+@c
+@c _getopt_internal
+@c  _getopt_internal_r
+@c   gettext
+@c   _getopt_initialize
+@c    getenv
+@c    malloc if USE_NONOPTION_FLAGS, never defined in libc
+@c   open_memstream
+@c   lockfile, unlockfile, __fxprintf -> stderr
+@c   asprintf
 The @code{getopt} function gets the next option argument from the
 argument list specified by the @var{argv} and @var{argc} arguments.
 Normally these values come directly from the arguments received by
@@ -225,6 +250,8 @@ was seen.
 @comment getopt.h
 @comment GNU
 @deftypefun int getopt_long (int @var{argc}, char *const *@var{argv}, const char *@var{shortopts}, const struct option *@var{longopts}, int *@var{indexptr})
+@safety{@mtunsafe{xguargs, envromt, staticbuf}@asunsafe{asmalloc, asi18n, selfdeadlock, asynconsist}@acunsafe{memleak, lockleak, incansist}}
+@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
 it does in @code{getopt}.  The argument @var{longopts} describes the long
@@ -278,6 +305,8 @@ getopt functionality there is one more function available.
 @comment getopt.h
 @comment GNU
 @deftypefun int getopt_long_only (int @var{argc}, char *const *@var{argv}, const char *@var{shortopts}, const struct option *@var{longopts}, int *@var{indexptr})
+@safety{@mtunsafe{xguargs, envromt, staticbuf}@asunsafe{asmalloc, asi18n, selfdeadlock, asynconsist}@acunsafe{memleak, lockleak, incansist}}
+@c Same issues as getopt.
 
 The @code{getopt_long_only} function is equivalent to the
 @code{getopt_long} function but it allows to specify the user of the

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=789c3737aa66ffb84bfceb34c4ae8eebecf8bfd8

commit 789c3737aa66ffb84bfceb34c4ae8eebecf8bfd8
Author: Alexandre Oliva <aoliva@redhat.com>
Date:   Fri Nov 8 06:08:16 2013 -0200

    MT-, AS- and AC-safety docs: manual/filesys.texi
    
    for ChangeLog
    
    	* manual/filesys.texi: Document MTASC-safety properties.

diff --git a/manual/filesys.texi b/manual/filesys.texi
index 1cac453..cd23ff6 100644
--- a/manual/filesys.texi
+++ b/manual/filesys.texi
@@ -58,6 +58,25 @@ Prototypes for these functions are declared in the header file
 @comment unistd.h
 @comment POSIX.1
 @deftypefun {char *} getcwd (char *@var{buffer}, size_t @var{size})
+@safety{@mtsafe{}@asunsafe{asmalloc}@acsafe{memleak, fdleak}}
+@c If buffer is NULL, this function calls malloc and realloc, and, in
+@c case of error, free.  Linux offers a getcwd syscall that we use on
+@c GNU/Linux systems, but it may fail if the pathname is too long.  As a
+@c fallback, and on other systems, the generic implementation opens each
+@c parent directory with opendir, which allocates memory for the
+@c directory stream with malloc.  If a fstatat64 syscall is not
+@c available, very deep directory trees may also have to malloc to build
+@c longer sequences of ../../../... than those supported by a global
+@c const read-only string.
+
+@c linux/__getcwd
+@c  posix/__getcwd
+@c   malloc/realloc/free if buffer is NULL, or if dir is too deep
+@c   lstat64 -> see its own entry
+@c   fstatat64
+@c     direct syscall if possible, alloca+snprintf+*stat64 otherwise
+@c   openat64_not_cancel_3, close_not_cancel_no_status
+@c   __fdopendir, __opendir, __readdir, rewinddir
 The @code{getcwd} function returns an absolute file name representing
 the current working directory, storing it in the character array
 @var{buffer} that you provide.  The @var{size} argument is how you tell
@@ -116,6 +135,9 @@ software.
 @comment unistd.h
 @comment BSD
 @deftypefn {Deprecated Function} {char *} getwd (char *@var{buffer})
+@safety{@mtsafe{}@asunsafe{asmalloc, asi18n}@acsafe{memleak, fdleak}}
+@c Besides the getcwd safety issues, it calls strerror_r on error, which
+@c brings in all of the i18n issues.
 This is similar to @code{getcwd}, but has no way to specify the size of
 the buffer.  @Theglibc{} provides @code{getwd} only
 for backwards compatibility with BSD.
@@ -130,6 +152,9 @@ this function is deprecated.
 @comment unistd.h
 @comment GNU
 @deftypefun {char *} get_current_dir_name (void)
+@safety{@mtunsafe{envromt}@asunsafe{asmalloc}@acsafe{memleak, fdleak}}
+@c Besides getcwd, which this function calls as a fallback, it calls
+@c getenv, with the usual thread-safety issues that brings about.
 @vindex PWD
 This @code{get_current_dir_name} function is basically equivalent to
 @w{@code{getcwd (NULL, 0)}}.  The only difference is that the value of
@@ -145,6 +170,7 @@ This function is a GNU extension.
 @comment unistd.h
 @comment POSIX.1
 @deftypefun int chdir (const char *@var{filename})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 This function is used to set the process's working directory to
 @var{filename}.
 
@@ -158,6 +184,7 @@ file @var{filename} is not a directory.
 @comment unistd.h
 @comment XPG
 @deftypefun int fchdir (int @var{filedes})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 This function is used to set the process's working directory to
 directory associated with the file descriptor @var{filedes}.
 
@@ -294,12 +321,14 @@ values and @code{st_mode} values:
 @comment dirent.h
 @comment BSD
 @deftypefun int IFTODT (mode_t @var{mode})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 This returns the @code{d_type} value corresponding to @var{mode}.
 @end deftypefun
 
 @comment dirent.h
 @comment BSD
 @deftypefun mode_t DTTOIF (int @var{dtype})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 This returns the @code{st_mode} value corresponding to @var{dtype}.
 @end deftypefun
 @end table
@@ -342,6 +371,9 @@ the following functions.
 @comment dirent.h
 @comment POSIX.1
 @deftypefun {DIR *} opendir (const char *@var{dirname})
+@safety{@mtsafe{}@asunsafe{asmalloc}@acsafe{memleak, fdleak}}
+@c Besides the safe syscall, we have to allocate the DIR object with
+@c __alloc_dir, that calls malloc.
 The @code{opendir} function opens and returns a directory stream for
 reading the directory whose file name is @var{dirname}.  The stream has
 type @code{DIR *}.
@@ -381,6 +413,8 @@ alternative interface can be used.
 @comment dirent.h
 @comment GNU
 @deftypefun {DIR *} fdopendir (int @var{fd})
+@safety{@mtsafe{}@asunsafe{asmalloc}@acsafe{memleak, fdleak}}
+@c The DIR object is allocated with __alloc_dir, that calls malloc.
 The @code{fdopendir} function works just like @code{opendir} but
 instead of taking a file name and opening a file descriptor for the
 directory the caller is required to provide a file descriptor.  This
@@ -425,6 +459,7 @@ access.
 @comment dirent.h
 @comment GNU
 @deftypefun int dirfd (DIR *@var{dirstream})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 The function @code{dirfd} returns the file descriptor associated with
 the directory stream @var{dirstream}.  This descriptor can be used until
 the directory is closed with @code{closedir}.  If the directory stream
@@ -443,6 +478,12 @@ symbols are declared in the header file @file{dirent.h}.
 @comment dirent.h
 @comment POSIX.1
 @deftypefun {struct dirent *} readdir (DIR *@var{dirstream})
+@safety{@mtunsafe{staticbuf}@asunsafe{selfdeadlock}@acunsafe{lockleak}}
+@c This function holds dirstream's non-recursive lock, which brings
+@c about the usual issues with locks and async signals and cancellation,
+@c but the lock taking is not enough to make the returned value safe to
+@c use, since it points to a stream's internal buffer that can be
+@c overwritten by subsequent calls or even released by closedir.
 This function reads the next entry from the directory.  It normally
 returns a pointer to a structure containing information about the
 file.  This structure is associated with the @var{dirstream} handle
@@ -478,6 +519,7 @@ locking if multiple threads access the same @var{dirstream}.
 @comment dirent.h
 @comment GNU
 @deftypefun int readdir_r (DIR *@var{dirstream}, struct dirent *@var{entry}, struct dirent **@var{result})
+@safety{@mtsafe{}@asunsafe{selfdeadlock}@acunsafe{lockleak}}
 This function is a version of @code{readdir} which performs internal
 locking.  Like @code{readdir} it returns the next entry from the
 directory.  To prevent conflicts between simultaneously running
@@ -549,6 +591,7 @@ of the last two functions.
 @comment dirent.h
 @comment LFS
 @deftypefun {struct dirent64 *} readdir64 (DIR *@var{dirstream})
+@safety{@mtunsafe{staticbuf}@asunsafe{selfdeadlock}@acunsafe{lockleak}}
 The @code{readdir64} function is just like the @code{readdir} function
 except that it returns a pointer to a record of type @code{struct
 dirent64}.  Some of the members of this data type (notably @code{d_ino})
@@ -560,6 +603,7 @@ In all other aspects this function is equivalent to @code{readdir}.
 @comment dirent.h
 @comment LFS
 @deftypefun int readdir64_r (DIR *@var{dirstream}, struct dirent64 *@var{entry}, struct dirent64 **@var{result})
+@safety{@mtsafe{}@asunsafe{selfdeadlock}@acunsafe{lockleak}}
 The @code{readdir64_r} function is equivalent to the @code{readdir_r}
 function except that it takes parameters of base type @code{struct
 dirent64} instead of @code{struct dirent} in the second and third
@@ -570,6 +614,10 @@ position.  The same precautions mentioned in the documentation of
 @comment dirent.h
 @comment POSIX.1
 @deftypefun int closedir (DIR *@var{dirstream})
+@safety{@mtsafe{}@asunsafe{asmalloc, selfdeadlock (hurd)}@acsafe{memleak, fdleak, lockleak (hurd)}}
+@c No synchronization in the posix implementation, only in the hurd
+@c one.  This is regarded as safe because it is undefined behavior if
+@c other threads could still be using the dir stream while it's closed.
 This function closes the directory stream @var{dirstream}.  It returns
 @code{0} on success and @code{-1} on failure.
 
@@ -609,6 +657,7 @@ declared in the header file @file{dirent.h}.
 @comment dirent.h
 @comment POSIX.1
 @deftypefun void rewinddir (DIR *@var{dirstream})
+@safety{@mtsafe{}@asunsafe{selfdeadlock}@acunsafe{lockleak}}
 The @code{rewinddir} function is used to reinitialize the directory
 stream @var{dirstream}, so that if you call @code{readdir} it
 returns information about the first entry in the directory again.  This
@@ -622,6 +671,10 @@ added or removed since you last called @code{opendir} or
 @comment dirent.h
 @comment BSD
 @deftypefun {long int} telldir (DIR *@var{dirstream})
+@safety{@mtsafe{}@asunsafe{asmalloc (bsd), selfdeadlock (bsd)}@acunsafe{memleak (bsd), lockleak (bsd)}}
+@c The implementation is safe on most platforms, but on BSD it uses
+@c cookies, buckets and records, and the global array of pointers to
+@c dynamically allocated records is guarded by a non-recursive lock.
 The @code{telldir} function returns the file position of the directory
 stream @var{dirstream}.  You can use this value with @code{seekdir} to
 restore the directory stream to that position.
@@ -630,6 +683,10 @@ restore the directory stream to that position.
 @comment dirent.h
 @comment BSD
 @deftypefun void seekdir (DIR *@var{dirstream}, long int @var{pos})
+@safety{@mtsafe{}@asunsafe{asmalloc (bsd), selfdeadlock (bsd)}@acunsafe{memleak (bsd), lockleak (bsd)}}
+@c The implementation is safe on most platforms, but on BSD it uses
+@c cookies, buckets and records, and the global array of pointers to
+@c dynamically allocated records is guarded by a non-recursive lock.
 The @code{seekdir} function sets the file position of the directory
 stream @var{dirstream} to @var{pos}.  The value @var{pos} must be the
 result of a previous call to @code{telldir} on this particular stream;
@@ -649,6 +706,19 @@ the result.
 @comment dirent.h
 @comment BSD/SVID
 @deftypefun int scandir (const char *@var{dir}, struct dirent ***@var{namelist}, int (*@var{selector}) (const struct dirent *), int (*@var{cmp}) (const struct dirent **, const struct dirent **))
+@safety{@mtsafe{}@asunsafe{asmalloc}@acunsafe{memleak, fdleak}}
+@c The scandir function calls __opendirat, __readdir, and __closedir to
+@c go over the named dir; malloc and realloc to allocate the namelist
+@c and copies of each selected dirent, besides the selector, if given,
+@c and qsort and the cmp functions if the latter is given.  In spite of
+@c the cleanup handler that releases memory and the file descriptor in
+@c case of synchronous cancellation, an asynchronous cancellation may
+@c still leak memory and a file descriptor.  Although readdir is unsafe
+@c in general, the use of an internal dir stream for sequential scanning
+@c of the directory with copying of dirents before subsequent calls
+@c makes the use safe, and the fact that the dir stream is private to
+@c each scandir call does away with the lock issues in readdir and
+@c closedir.
 
 The @code{scandir} function scans the contents of the directory selected
 by @var{dir}.  The result in *@var{namelist} is an array of pointers to
@@ -679,6 +749,8 @@ are very helpful for this purpose.
 @comment dirent.h
 @comment BSD/SVID
 @deftypefun int alphasort (const void *@var{a}, const void *@var{b})
+@safety{@mtsafe{glocale}@asunsafe{asmalloc}@acsafe{memleak}}
+@c Calls strcoll.
 The @code{alphasort} function behaves like the @code{strcoll} function
 (@pxref{String/Array Comparison}).  The difference is that the arguments
 are not string pointers but instead they are of type
@@ -691,6 +763,8 @@ than zero depending on the order of the two entries @var{a} and @var{b}.
 @comment dirent.h
 @comment GNU
 @deftypefun int versionsort (const void *@var{a}, const void *@var{b})
+@safety{@mtsafe{glocale}@assafe{}@acsafe{}}
+@c Calls strverscmp, which will evaluate .
 The @code{versionsort} function is like @code{alphasort} except that it
 uses the @code{strverscmp} function internally.
 @end deftypefun
@@ -703,6 +777,8 @@ dirent64}}.  To use this we need a new function.
 @comment dirent.h
 @comment GNU
 @deftypefun int scandir64 (const char *@var{dir}, struct dirent64 ***@var{namelist}, int (*@var{selector}) (const struct dirent64 *), int (*@var{cmp}) (const struct dirent64 **, const struct dirent64 **))
+@safety{@mtsafe{}@asunsafe{asmalloc}@acunsafe{memleak, fdleak}}
+@c See scandir.
 The @code{scandir64} function works like the @code{scandir} function
 except that the directory entries it returns are described by elements
 of type @w{@code{struct dirent64}}.  The function pointed to by
@@ -721,6 +797,8 @@ argument.  Instead we provide the two replacement functions below.
 @comment dirent.h
 @comment GNU
 @deftypefun int alphasort64 (const void *@var{a}, const void *@var{b})
+@safety{@mtsafe{glocale}@asunsafe{asmalloc}@acsafe{memleak}}
+@c See alphasort.
 The @code{alphasort64} function behaves like the @code{strcoll} function
 (@pxref{String/Array Comparison}).  The difference is that the arguments
 are not string pointers but instead they are of type
@@ -733,6 +811,8 @@ than zero depending on the order of the two entries @var{a} and @var{b}.
 @comment dirent.h
 @comment GNU
 @deftypefun int versionsort64 (const void *@var{a}, const void *@var{b})
+@safety{@mtsafe{glocale}@assafe{}@acsafe{}}
+@c See versionsort.
 The @code{versionsort64} function is like @code{alphasort64}, excepted that it
 uses the @code{strverscmp} function internally.
 @end deftypefun
@@ -913,6 +993,8 @@ file was passed).
 @comment ftw.h
 @comment SVID
 @deftypefun int ftw (const char *@var{filename}, __ftw_func_t @var{func}, int @var{descriptors})
+@safety{@mtsafe{xguargs}, @asunsafe{asmalloc}, @acsafe{memleak, fdleak}}
+@c see nftw for safety details
 The @code{ftw} function calls the callback function given in the
 parameter @var{func} for every item which is found in the directory
 specified by @var{filename} and all directories below.  The function
@@ -963,6 +1045,7 @@ interface transparently replaces the old interface.
 @comment ftw.h
 @comment Unix98
 @deftypefun int ftw64 (const char *@var{filename}, __ftw64_func_t @var{func}, int @var{descriptors})
+@safety{@mtsafe{xguargs}, @asunsafe{asmalloc}, @acsafe{memleak, fdleak}}
 This function is similar to @code{ftw} but it can work on filesystems
 with large files.  File information is reported using a variable of type
 @code{struct stat64} which is passed by reference to the callback
@@ -976,6 +1059,17 @@ transparently replaces the old implementation.
 @comment ftw.h
 @comment XPG4.2
 @deftypefun int nftw (const char *@var{filename}, __nftw_func_t @var{func}, int @var{descriptors}, int @var{flag})
+@safety{@mtsafe{xguargs, tempchwd}@asunsafe{asmalloc}@acsafe{memleak, fdleak}}
+@c ftw_startup calls alloca, malloc, free, xstat/lxstat, tdestroy, and ftw_dir
+@c  if FTW_CHDIR, call open, and fchdir, or chdir and getcwd
+@c ftw_dir calls open_dir_stream, readdir64, process_entry, closedir
+@c  if FTW_CHDIR, also calls fchdir
+@c open_dir_stream calls malloc, realloc, readdir64, free, closedir,
+@c  then openat64_not_cancel_3 and fdopendir or opendir, then dirfd.
+@c process_entry may cal realloc, fxstatat/lxstat/xstat, ftw_dir, and
+@c  find_object (tsearch) and add_object (tfind).
+@c Since each invocation of *ftw uses its own private search tree, none
+@c  of the search tree concurrency issues apply.
 The @code{nftw} function works like the @code{ftw} functions.  They call
 the callback function @var{func} for all items found in the directory
 @var{filename} and below.  At most @var{descriptors} file descriptors
@@ -1036,6 +1130,7 @@ interface transparently replaces the old interface.
 @comment ftw.h
 @comment Unix98
 @deftypefun int nftw64 (const char *@var{filename}, __nftw64_func_t @var{func}, int @var{descriptors}, int @var{flag})
+@safety{@mtsafe{xguargs, tempchwd}@asunsafe{asmalloc}@acsafe{memleak, fdleak}}
 This function is similar to @code{nftw} but it can work on filesystems
 with large files.  File information is reported using a variable of type
 @code{struct stat64} which is passed by reference to the callback
@@ -1079,6 +1174,7 @@ file @file{unistd.h}.
 @comment unistd.h
 @comment POSIX.1
 @deftypefun int link (const char *@var{oldname}, const char *@var{newname})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 The @code{link} function makes a new link to the existing file named by
 @var{oldname}, under the new name @var{newname}.
 
@@ -1186,6 +1282,7 @@ Prototypes for most of the functions listed in this section are in
 @comment unistd.h
 @comment BSD
 @deftypefun int symlink (const char *@var{oldname}, const char *@var{newname})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 The @code{symlink} function makes a symbolic link to @var{oldname} named
 @var{newname}.
 
@@ -1223,6 +1320,7 @@ exceeded.
 @comment unistd.h
 @comment BSD
 @deftypefun ssize_t readlink (const char *@var{filename}, char *@var{buffer}, size_t @var{size})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 The @code{readlink} function gets the value of the symbolic link
 @var{filename}.  The file name that the link points to is copied into
 @var{buffer}.  This file name string is @emph{not} null-terminated;
@@ -1282,6 +1380,8 @@ names can refer to the same inode.
 @comment stdlib.h
 @comment GNU
 @deftypefun {char *} canonicalize_file_name (const char *@var{name})
+@safety{@mtsafe{xguargs}@asunsafe{asmalloc}@acsafe{memleak, fdleak}}
+@c Calls realpath.
 
 The @code{canonicalize_file_name} function returns the absolute name of
 the file named by @var{name} which contains no @code{.}, @code{..}
@@ -1323,6 +1423,8 @@ where the result is placed in.
 @comment stdlib.h
 @comment XPG
 @deftypefun {char *} realpath (const char *restrict @var{name}, char *restrict @var{resolved})
+@safety{@mtsafe{xguargs}@asunsafe{asmalloc}@acsafe{memleak, fdleak}}
+@c Calls malloc, realloc, getcwd, lxstat64, readlink, alloca.
 
 A call to @code{realpath} where the @var{resolved} parameter is
 @code{NULL} behaves exactly like @code{canonicalize_file_name}.  The
@@ -1362,6 +1464,7 @@ then the file is deleted as well.  If the file has other remaining names
 @comment unistd.h
 @comment POSIX.1
 @deftypefun int unlink (const char *@var{filename})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 The @code{unlink} function deletes the file name @var{filename}.  If
 this is a file's sole name, the file itself is also deleted.  (Actually,
 if any process has the file open when this happens, deletion is
@@ -1404,6 +1507,7 @@ file system and can't be modified.
 @comment unistd.h
 @comment POSIX.1
 @deftypefun int rmdir (const char *@var{filename})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 @cindex directories, deleting
 @cindex deleting a directory
 The @code{rmdir} function deletes a directory.  The directory must be
@@ -1431,6 +1535,8 @@ The prototype for this function is declared in the header file
 @comment stdio.h
 @comment ISO
 @deftypefun int remove (const char *@var{filename})
+@safety{@mtsafe{xguargs}@assafe{}@acsafe{}}
+@c Calls unlink and rmdir.
 This is the @w{ISO C} function to remove a file.  It works like
 @code{unlink} for files and like @code{rmdir} for directories.
 @code{remove} is declared in @file{stdio.h}.
@@ -1446,6 +1552,10 @@ The @code{rename} function is used to change a file's name.
 @comment stdio.h
 @comment ISO
 @deftypefun int rename (const char *@var{oldname}, const char *@var{newname})
+@safety{@mtsafe{xguargs}@assafe{}@acsafe{}}
+@c In the absence of a rename syscall, there's an emulation with link
+@c and unlink, but it's racy, even more so if newname exists and is
+@c unlinked first.
 The @code{rename} function renames the file @var{oldname} to
 @var{newname}.  The file formerly accessible under the name
 @var{oldname} is afterwards accessible as @var{newname} instead.  (If
@@ -1541,6 +1651,7 @@ a shell command @code{mkdir} which does the same thing.)
 @comment sys/stat.h
 @comment POSIX.1
 @deftypefun int mkdir (const char *@var{filename}, mode_t @var{mode})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 The @code{mkdir} function creates a new, empty directory with name
 @var{filename}.
 
@@ -1882,6 +1993,7 @@ header file @file{sys/stat.h}.
 @comment sys/stat.h
 @comment POSIX.1
 @deftypefun int stat (const char *@var{filename}, struct stat *@var{buf})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 The @code{stat} function returns information about the attributes of the
 file named by @w{@var{filename}} in the structure pointed to by @var{buf}.
 
@@ -1908,6 +2020,7 @@ replaces the normal implementation.
 @comment sys/stat.h
 @comment Unix98
 @deftypefun int stat64 (const char *@var{filename}, struct stat64 *@var{buf})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 This function is similar to @code{stat} but it is also able to work on
 files larger than @math{2^31} bytes on 32-bit systems.  To be able to do
 this the result is stored in a variable of type @code{struct stat64} to
@@ -1921,6 +2034,7 @@ replaces the interface for small files on 32-bit machines.
 @comment sys/stat.h
 @comment POSIX.1
 @deftypefun int fstat (int @var{filedes}, struct stat *@var{buf})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 The @code{fstat} function is like @code{stat}, except that it takes an
 open file descriptor as an argument instead of a file name.
 @xref{Low-Level I/O}.
@@ -1942,6 +2056,7 @@ replaces the normal implementation.
 @comment sys/stat.h
 @comment Unix98
 @deftypefun int fstat64 (int @var{filedes}, struct stat64 *@var{buf})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 This function is similar to @code{fstat} but is able to work on large
 files on 32-bit platforms.  For large files the file descriptor
 @var{filedes} should be obtained by @code{open64} or @code{creat64}.
@@ -1953,9 +2068,16 @@ function is available under the name @code{fstat} and so transparently
 replaces the interface for small files on 32-bit machines.
 @end deftypefun
 
+@c fstatat will call alloca and snprintf if the syscall is not
+@c available.
+@c @safety{@mtsafe{}@assafe{asmalloc}@acsafe{memleak}}
+
 @comment sys/stat.h
 @comment BSD
 @deftypefun int lstat (const char *@var{filename}, struct stat *@var{buf})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
+@c Direct system call through lxstat, sometimes with an xstat conv call
+@c afterwards.
 The @code{lstat} function is like @code{stat}, except that it does not
 follow symbolic links.  If @var{filename} is the name of a symbolic
 link, @code{lstat} returns information about the link itself; otherwise
@@ -1969,6 +2091,9 @@ replaces the normal implementation.
 @comment sys/stat.h
 @comment Unix98
 @deftypefun int lstat64 (const char *@var{filename}, struct stat64 *@var{buf})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
+@c Direct system call through lxstat64, sometimes with an xstat conv
+@c call afterwards.
 This function is similar to @code{lstat} but it is also able to work on
 files larger than @math{2^31} bytes on 32-bit systems.  To be able to do
 this the result is stored in a variable of type @code{struct stat64} to
@@ -2007,12 +2132,14 @@ that file:
 @comment sys/stat.h
 @comment POSIX
 @deftypefn Macro int S_ISDIR (mode_t @var{m})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 This macro returns non-zero if the file is a directory.
 @end deftypefn
 
 @comment sys/stat.h
 @comment POSIX
 @deftypefn Macro int S_ISCHR (mode_t @var{m})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 This macro returns non-zero if the file is a character special file (a
 device like a terminal).
 @end deftypefn
@@ -2020,6 +2147,7 @@ device like a terminal).
 @comment sys/stat.h
 @comment POSIX
 @deftypefn Macro int S_ISBLK (mode_t @var{m})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 This macro returns non-zero if the file is a block special file (a device
 like a disk).
 @end deftypefn
@@ -2027,12 +2155,14 @@ like a disk).
 @comment sys/stat.h
 @comment POSIX
 @deftypefn Macro int S_ISREG (mode_t @var{m})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 This macro returns non-zero if the file is a regular file.
 @end deftypefn
 
 @comment sys/stat.h
 @comment POSIX
 @deftypefn Macro int S_ISFIFO (mode_t @var{m})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 This macro returns non-zero if the file is a FIFO special file, or a
 pipe.  @xref{Pipes and FIFOs}.
 @end deftypefn
@@ -2040,6 +2170,7 @@ pipe.  @xref{Pipes and FIFOs}.
 @comment sys/stat.h
 @comment GNU
 @deftypefn Macro int S_ISLNK (mode_t @var{m})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 This macro returns non-zero if the file is a symbolic link.
 @xref{Symbolic Links}.
 @end deftypefn
@@ -2047,6 +2178,7 @@ This macro returns non-zero if the file is a symbolic link.
 @comment sys/stat.h
 @comment GNU
 @deftypefn Macro int S_ISSOCK (mode_t @var{m})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 This macro returns non-zero if the file is a socket.  @xref{Sockets}.
 @end deftypefn
 
@@ -2129,6 +2261,7 @@ the whole @code{struct stat} structure.
 @comment sys/stat.h
 @comment POSIX
 @deftypefn Macro int S_TYPEISMQ (struct stat *@var{s})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 If the system implement POSIX message queues as distinct objects and the
 file is a message queue object, this macro returns a non-zero value.
 In all other cases the result is zero.
@@ -2137,6 +2270,7 @@ In all other cases the result is zero.
 @comment sys/stat.h
 @comment POSIX
 @deftypefn Macro int S_TYPEISSEM (struct stat *@var{s})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 If the system implement POSIX semaphores as distinct objects and the
 file is a semaphore object, this macro returns a non-zero value.
 In all other cases the result is zero.
@@ -2145,6 +2279,7 @@ In all other cases the result is zero.
 @comment sys/stat.h
 @comment POSIX
 @deftypefn Macro int S_TYPEISSHM (struct stat *@var{s})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 If the system implement POSIX shared memory objects as distinct objects
 and the file is an shared memory object, this macro returns a non-zero
 value.  In all other cases the result is zero.
@@ -2189,6 +2324,7 @@ The prototype for this function is declared in @file{unistd.h}.
 @comment unistd.h
 @comment POSIX.1
 @deftypefun int chown (const char *@var{filename}, uid_t @var{owner}, gid_t @var{group})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 The @code{chown} function changes the owner of the file @var{filename} to
 @var{owner}, and its group owner to @var{group}.
 
@@ -2223,6 +2359,7 @@ The file is on a read-only file system.
 @comment unistd.h
 @comment BSD
 @deftypefun int fchown (int @var{filedes}, uid_t @var{owner}, gid_t @var{group})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 This is like @code{chown}, except that it changes the owner of the open
 file with descriptor @var{filedes}.
 
@@ -2502,6 +2639,7 @@ The functions in this section are declared in @file{sys/stat.h}.
 @comment sys/stat.h
 @comment POSIX.1
 @deftypefun mode_t umask (mode_t @var{mask})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 The @code{umask} function sets the file creation mask of the current
 process to @var{mask}, and returns the previous value of the file
 creation mask.
@@ -2527,6 +2665,7 @@ you just want to read the mask value, because it is reentrant.
 @comment sys/stat.h
 @comment GNU
 @deftypefun mode_t getumask (void)
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 Return the current value of the file creation mask for the current
 process.  This function is a GNU extension and is only available on
 @gnuhurdsystems{}.
@@ -2535,6 +2674,7 @@ process.  This function is a GNU extension and is only available on
 @comment sys/stat.h
 @comment POSIX.1
 @deftypefun int chmod (const char *@var{filename}, mode_t @var{mode})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 The @code{chmod} function sets the access permission bits for the file
 named by @var{filename} to @var{mode}.
 
@@ -2575,6 +2715,7 @@ for full details on the sticky bit.
 @comment sys/stat.h
 @comment BSD
 @deftypefun int fchmod (int @var{filedes}, mode_t @var{mode})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 This is like @code{chmod}, except that it changes the permissions of the
 currently open file given by @var{filedes}.
 
@@ -2645,6 +2786,7 @@ The symbols in this section are declared in @file{unistd.h}.
 @comment unistd.h
 @comment POSIX.1
 @deftypefun int access (const char *@var{filename}, int @var{how})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 The @code{access} function checks to see whether the file named by
 @var{filename} can be accessed in the way specified by the @var{how}
 argument.  The @var{how} argument either can be the bitwise OR of the
@@ -2765,6 +2907,9 @@ This is the modification time for the file.
 @comment utime.h
 @comment POSIX.1
 @deftypefun int utime (const char *@var{filename}, const struct utimbuf *@var{times})
+@safety{@mtsafe{xguargs}@assafe{}@acsafe{}}
+@c In the absence of a utime syscall, it non-atomically converts times
+@c to a struct timeval and calls utimes.
 This function is used to modify the file times associated with the file
 named @var{filename}.
 
@@ -2816,6 +2961,10 @@ in the header file @file{sys/time.h}.
 @comment sys/time.h
 @comment BSD
 @deftypefun int utimes (const char *@var{filename}, const struct timeval @var{tvp}@t{[2]})
+@safety{@mtsafe{xguargs}@assafe{}@acsafe{}}
+@c In the absence of a utimes syscall, it non-atomically converts tvp
+@c to struct timespec array and issues a utimensat syscall, or to
+@c struct utimbuf and calls utime.
 This function sets the file access and modification times of the file
 @var{filename}.  The new file access time is specified by
 @code{@var{tvp}[0]}, and the new modification time by
@@ -2830,6 +2979,9 @@ function.
 @comment sys/time.h
 @comment BSD
 @deftypefun int lutimes (const char *@var{filename}, const struct timeval @var{tvp}@t{[2]})
+@safety{@mtsafe{xguargs}@assafe{}@acsafe{}}
+@c Since there's no lutimes syscall, it non-atomically converts tvp
+@c to struct timespec array and issues a utimensat syscall.
 This function is like @code{utimes}, except that it does not follow
 symbolic links.  If @var{filename} is the name of a symbolic link,
 @code{lutimes} sets the file access and modification times of the
@@ -2846,6 +2998,10 @@ function.
 @comment sys/time.h
 @comment BSD
 @deftypefun int futimes (int @var{fd}, const struct timeval @var{tvp}@t{[2]})
+@safety{@mtsafe{xguargs}@assafe{}@acsafe{}}
+@c Since there's no futimes syscall, it non-atomically converts tvp
+@c to struct timespec array and issues a utimensat syscall, falling back
+@c to utimes on a /proc/self/fd symlink.
 This function is like @code{utimes}, except that it takes an open file
 descriptor as an argument instead of a file name.  @xref{Low-Level
 I/O}.  This function comes from FreeBSD, and is not available on all
@@ -2900,6 +3056,8 @@ succeed, without actually accomplishing anything.
 @comment unistd.h
 @comment X/Open
 @deftypefun int truncate (const char *@var{filename}, off_t @var{length})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
+@c In the absence of a truncate syscall, we use open and ftruncate.
 
 The @code{truncate} function changes the size of @var{filename} to
 @var{length}.  If @var{length} is shorter than the previous length, data
@@ -2944,6 +3102,8 @@ The operation was interrupted by a signal.
 @comment unistd.h
 @comment Unix98
 @deftypefun int truncate64 (const char *@var{name}, off64_t @var{length})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
+@c In the absence of a syscall, try truncate if length fits.
 This function is similar to the @code{truncate} function.  The
 difference is that the @var{length} argument is 64 bits wide even on 32
 bits machines, which allows the handling of files with sizes up to
@@ -2957,6 +3117,7 @@ When the source file is compiled with @code{_FILE_OFFSET_BITS == 64} on a
 @comment unistd.h
 @comment POSIX
 @deftypefun int ftruncate (int @var{fd}, off_t @var{length})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 
 This is like @code{truncate}, but it works on a file descriptor @var{fd}
 for an opened file instead of a file name to identify the object.  The
@@ -3021,6 +3182,8 @@ The operation was interrupted by a signal.
 @comment unistd.h
 @comment Unix98
 @deftypefun int ftruncate64 (int @var{id}, off64_t @var{length})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
+@c In the absence of a syscall, try ftruncate if length fits.
 This function is similar to the @code{ftruncate} function.  The
 difference is that the @var{length} argument is 64 bits wide even on 32
 bits machines which allows the handling of files with sizes up to
@@ -3083,6 +3246,10 @@ The prototype for @code{mknod} is declared in @file{sys/stat.h}.
 @comment sys/stat.h
 @comment BSD
 @deftypefun int mknod (const char *@var{filename}, mode_t @var{mode}, dev_t @var{dev})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
+@c Instead of issuing the syscall directly, we go through xmknod.
+@c Although the internal xmknod takes a dev_t*, that could lead to
+@c xguargs races, it's passed a pointer to mknod's dev.
 The @code{mknod} function makes a special file with name @var{filename}.
 The @var{mode} specifies the mode of the file, and may include the various
 special file bits, such as @code{S_IFCHR} (for a character special file)
@@ -3134,6 +3301,20 @@ These facilities are declared in the header file @file{stdio.h}.
 @comment stdio.h
 @comment ISO
 @deftypefun {FILE *} tmpfile (void)
+@safety{@mtsafe{}@asunsafe{asmalloc, selfdeadlock}@acunsafe{memleak, fdleak, lockleak}}
+@c The unsafety issues are those of fdopen, plus fdleak because of the
+@c open.
+@c __path_search (internal buf, !dir, const pfx, !try_tmpdir) ok
+@c  libc_secure_genenv only if try_tmpdir
+@c  xstat64, strlen, strcmp, sprintf
+@c __gen_tempname (internal tmpl, __GT_FILE) ok
+@c  strlen, memcmp, getpid, open/mkdir/lxstat64 ok
+@c  HP_TIMING_NOW if available ok
+@c  gettimeofday (!tz) first time, or every time if no HP_TIMING_NOW ok
+@c  static value is used and modified without synchronization ok
+@c   but the use is as a source of non-cryptographic randomness
+@c   with retries in case of collision, so it should be safe
+@c unlink, fdopen
 This function creates a temporary binary file for update mode, as if by
 calling @code{fopen} with mode @code{"wb+"}.  The file is deleted
 automatically when it is closed or when the program terminates.  (On
@@ -3150,6 +3331,7 @@ interface transparently replaces the old interface.
 @comment stdio.h
 @comment Unix98
 @deftypefun {FILE *} tmpfile64 (void)
+@safety{@mtsafe{}@asunsafe{asmalloc, selfdeadlock}@acunsafe{memleak, fdleak, lockleak}}
 This function is similar to @code{tmpfile}, but the stream it returns a
 pointer to was opened using @code{tmpfile64}.  Therefore this stream can
 be used for files larger than @math{2^31} bytes on 32-bit machines.
@@ -3165,6 +3347,11 @@ and so transparently replaces the old interface.
 @comment stdio.h
 @comment ISO
 @deftypefun {char *} tmpnam (char *@var{result})
+@safety{@mtunsafe{xguargs, staticbuf}@asunsafe{staticbuf}@acsafe{}}
+@c The passed-in buffer should not be modified concurrently with the
+@c call.
+@c __path_search (static or passed-in buf, !dir, !pfx, !try_tmpdir) ok
+@c __gen_tempname (internal tmpl, __GT_NOCREATE) ok
 This function constructs and returns a valid file name that does not
 refer to any existing file.  If the @var{result} argument is a null
 pointer, the return value is a pointer to an internal static string,
@@ -3189,6 +3376,7 @@ opening the file you should use the @code{O_EXCL} flag.  Using
 @comment stdio.h
 @comment GNU
 @deftypefun {char *} tmpnam_r (char *@var{result})
+@safety{@mtsafe{xguargs}@assafe{}@acsafe{}}
 This function is nearly identical to the @code{tmpnam} function, except
 that if @var{result} is a null pointer it returns a null pointer.
 
@@ -3225,6 +3413,13 @@ never less than @code{25}.
 @comment stdio.h
 @comment SVID
 @deftypefun {char *} tempnam (const char *@var{dir}, const char *@var{prefix})
+@safety{@mtunsafe{xguargs, envromt}@assafe{asmalloc}@acsafe{memleak}}
+@c There's no way (short of being setuid) to avoid getenv("TMPDIR"),
+@c even with a non-NULL dir, which makes this thread-unsafe.
+@c
+@c __path_search (internal buf, dir, pfx, try_tmpdir) unsafe getenv
+@c __gen_tempname (internal tmpl, __GT_NOCREATE) ok
+@c strdup
 This function generates a unique temporary file name.  If @var{prefix}
 is not a null pointer, up to five characters of this string are used as
 a prefix for the file name.  The return value is a string newly
@@ -3288,6 +3483,8 @@ string.  These functions are declared in the header file @file{stdlib.h}.
 @comment stdlib.h
 @comment Unix
 @deftypefun {char *} mktemp (char *@var{template})
+@safety{@mtunsafe{xguargs}@assafe{}@acsafe{}}
+@c __gen_tempname (caller tmpl, __GT_NOCREATE) ok
 The @code{mktemp} function generates a unique file name by modifying
 @var{template} as described above.  If successful, it returns
 @var{template} as modified.  If @code{mktemp} cannot find a unique file
@@ -3306,6 +3503,8 @@ opening the file you should use the @code{O_EXCL} flag.  Using
 @comment stdlib.h
 @comment BSD
 @deftypefun int mkstemp (char *@var{template})
+@safety{@mtunsafe{xguargs}@assafe{}@acsafe{fdleak}}
+@c __gen_tempname (caller tmpl, __GT_FILE) ok
 The @code{mkstemp} function generates a unique file name just as
 @code{mktemp} does, but it also opens the file for you with @code{open}
 (@pxref{Opening and Closing Files}).  If successful, it modifies
@@ -3328,6 +3527,8 @@ new file and get an error if the file already exists.
 @comment stdlib.h
 @comment BSD
 @deftypefun {char *} mkdtemp (char *@var{template})
+@safety{@mtunsafe{xguargs}@assafe{}@acsafe{}}
+@c __gen_tempname (caller tmpl, __GT_DIR) ok
 The @code{mkdtemp} function creates a directory with a unique name.  If
 it succeeds, it overwrites @var{template} with the name of the
 directory, and returns @var{template}.  As with @code{mktemp} and
@@ -3349,3 +3550,23 @@ creation always works like @code{open} with @code{O_EXCL}.
 @xref{Creating Directories}.
 
 The @code{mkdtemp} function comes from OpenBSD.
+
+@c FIXME these are undocumented:
+@c faccessat
+@c fchmodat
+@c fchownat
+@c futimesat
+@c fstatat (there's a commented-out safety assessment for this one)
+@c linkat
+@c mkdirat
+@c mkfifoat
+@c name_to_handle_at
+@c openat
+@c open_by_handle_at
+@c readlinkat
+@c renameat
+@c scandirat
+@c symlinkat
+@c unlinkat
+@c utimensat
+@c mknodat

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=a619aa2c300df658d288647fad97ba9fd921a2a7

commit a619aa2c300df658d288647fad97ba9fd921a2a7
Author: Alexandre Oliva <aoliva@redhat.com>
Date:   Fri Nov 8 06:08:16 2013 -0200

    MT-, AS- and AC-safety docs: manual/errno.texi
    
    for ChangeLog
    
    	* manual/errno.texi: Document MTASC-safety properties.

diff --git a/manual/errno.texi b/manual/errno.texi
index 6c9fa86..eb3f412 100644
--- a/manual/errno.texi
+++ b/manual/errno.texi
@@ -1293,6 +1293,9 @@ name of the program that encountered the error.
 @comment string.h
 @comment ISO
 @deftypefun {char *} strerror (int @var{errnum})
+@safety{@mtunsafe{staticbuf}@asunsafe{staticbuf, asmalloc, asi18n}@acsafe{memleak}}
+@c Calls strerror_r with a static buffer allocated with malloc on the
+@c first use.
 The @code{strerror} function maps the error code (@pxref{Checking for
 Errors}) specified by the @var{errnum} argument to a descriptive error
 message string.  The return value is a pointer to this string.
@@ -1310,6 +1313,7 @@ The function @code{strerror} is declared in @file{string.h}.
 @comment string.h
 @comment GNU
 @deftypefun {char *} strerror_r (int @var{errnum}, char *@var{buf}, size_t @var{n})
+@safety{@mtsafe{}@asunsafe{asi18n}@acsafe{}}
 The @code{strerror_r} function works like @code{strerror} but instead of
 returning the error message in a statically allocated buffer shared by
 all threads in the process, it returns a private copy for the
@@ -1331,6 +1335,10 @@ This function @code{strerror_r} is a GNU extension and it is declared in
 @comment stdio.h
 @comment ISO
 @deftypefun void perror (const char *@var{message})
+@safety{@mtsafe{xguargs}@asunsafe{asynconsist, asi18n, asmalloc, selfdeadlock}@acunsafe{incansist, lockleak, memleak, fdleak}}
+@c Besides strerror_r's and some of fprintf's issues, if stderr is not
+@c oriented yet, create a new stream with a dup of stderr's fd and write
+@c to that instead of stderr, to avoid orienting it.
 This function prints an error message to the stream @code{stderr};
 see @ref{Standard Streams}.  The orientation of @code{stderr} is not
 changed.
@@ -1442,6 +1450,13 @@ These functions are declared in @file{error.h}.
 @comment error.h
 @comment GNU
 @deftypefun void error (int @var{status}, int @var{errnum}, const char *@var{format}, @dots{})
+@safety{@mtsafe{glocale}@asunsafe{asynconsist, asmalloc, asi18n}@acsafe{}}
+@c Cancellation is disabled throught the execution.  It flushes stdout
+@c and then holds a lock on stderr while printing the program name and
+@c then running error_tail.  The non-wide case just runs vfprintf; the
+@c wide case converts the message to an alloca/malloc-allocated buffer
+@c with mbsrtowcs, then prints it with vfwprintf.  Afterwards,
+@c print_errno_message calls strerror_r and fxprintf.
 The @code{error} function can be used to report general problems during
 program execution.  The @var{format} argument is a format string just
 like those given to the @code{printf} family of functions.  The
@@ -1477,6 +1492,15 @@ incremented by one to keep track of the number of errors reported.
 @comment error.h
 @comment GNU
 @deftypefun void error_at_line (int @var{status}, int @var{errnum}, const char *@var{fname}, unsigned int @var{lineno}, const char *@var{format}, @dots{})
+@safety{@mtunsafe{staticbuf, glocale}@asunsafe{asynconsist, asmalloc, asi18n}@acunsafe{incansist}}
+@c The error_one_per_line variable is accessed (without any form of
+@c synchronization, but since it's an int used once, it should be safe
+@c enough) and, if this mode is enabled, static variables used to hold
+@c the last printed file name and line number are accessed and modified
+@c without synchronization; the update is not atomic and it occurs
+@c before disabling cancellation, so it can be interrupted after only
+@c one of the two variables is modified.  After that, it's very much
+@c like error.
 
 The @code{error_at_line} function is very similar to the @code{error}
 function.  The only difference are the additional parameters @var{fname}
@@ -1582,6 +1606,8 @@ are included only for compatibility.
 @comment err.h
 @comment BSD
 @deftypefun void warn (const char *@var{format}, @dots{})
+@safety{@mtsafe{glocale}@asunsafe{asynconsist, asmalloc, asi18n}@acunsafe{incansist, lockleak, memleak}}
+@c Just calls vwarn with the va_list.
 The @code{warn} function is roughly equivalent to a call like
 @smallexample
   error (0, errno, format, @r{the parameters})
@@ -1594,6 +1620,11 @@ are not used.
 @comment err.h
 @comment BSD
 @deftypefun void vwarn (const char *@var{format}, va_list @var{ap})
+@safety{@mtsafe{glocale}@asunsafe{asynconsist, asmalloc, asi18n}@acunsafe{incansist, lockleak, memleak}}
+@c While holding stderr's recursive lock, it prints the programname, the
+@c given message, and the error string with fw?printf's %m.  When the
+@c stream is wide, convert_and_print converts the format string to an
+@c alloca/malloc-created buffer using mbsrtowcs and then calls fwprintf.
 The @code{vwarn} function is just like @code{warn} except that the
 parameters for the handling of the format string @var{format} are passed
 in as an value of type @code{va_list}.
@@ -1602,6 +1633,8 @@ in as an value of type @code{va_list}.
 @comment err.h
 @comment BSD
 @deftypefun void warnx (const char *@var{format}, @dots{})
+@safety{@mtsafe{glocale}@asunsafe{asynconsist, asmalloc}@acunsafe{incansist, lockleak, memleak}}
+@c Same as warn, but without the strerror translation issues.
 The @code{warnx} function is roughly equivalent to a call like
 @smallexample
   error (0, 0, format, @r{the parameters})
@@ -1615,6 +1648,8 @@ string is printed.
 @comment err.h
 @comment BSD
 @deftypefun void vwarnx (const char *@var{format}, va_list @var{ap})
+@safety{@mtsafe{glocale}@asunsafe{asynconsist, asmalloc}@acunsafe{incansist, lockleak, memleak}}
+@c Same as vwarn, but without the strerror translation issues.
 The @code{vwarnx} function is just like @code{warnx} except that the
 parameters for the handling of the format string @var{format} are passed
 in as an value of type @code{va_list}.
@@ -1623,6 +1658,8 @@ in as an value of type @code{va_list}.
 @comment err.h
 @comment BSD
 @deftypefun void err (int @var{status}, const char *@var{format}, @dots{})
+@safety{@mtsafe{glocale}@asunsafe{asynconsist, asmalloc, asi18n}@acunsafe{incansist, lockleak, memleak}}
+@c Same as warn followed by exit.
 The @code{err} function is roughly equivalent to a call like
 @smallexample
   error (status, errno, format, @r{the parameters})
@@ -1635,6 +1672,8 @@ are not used and that the program is exited even if @var{status} is zero.
 @comment err.h
 @comment BSD
 @deftypefun void verr (int @var{status}, const char *@var{format}, va_list @var{ap})
+@safety{@mtsafe{glocale}@asunsafe{asynconsist, asmalloc, asi18n}@acunsafe{incansist, lockleak, memleak}}
+@c Same as vwarn followed by exit.
 The @code{verr} function is just like @code{err} except that the
 parameters for the handling of the format string @var{format} are passed
 in as an value of type @code{va_list}.
@@ -1643,6 +1682,8 @@ in as an value of type @code{va_list}.
 @comment err.h
 @comment BSD
 @deftypefun void errx (int @var{status}, const char *@var{format}, @dots{})
+@safety{@mtsafe{glocale}@asunsafe{asynconsist, asmalloc}@acunsafe{incansist, lockleak, memleak}}
+@c Same as warnx followed by exit.
 The @code{errx} function is roughly equivalent to a call like
 @smallexample
   error (status, 0, format, @r{the parameters})
@@ -1657,6 +1698,8 @@ string is printed.
 @comment err.h
 @comment BSD
 @deftypefun void verrx (int @var{status}, const char *@var{format}, va_list @var{ap})
+@safety{@mtsafe{glocale}@asunsafe{asynconsist, asmalloc}@acunsafe{incansist, lockleak, memleak}}
+@c Same as vwarnx followed by exit.
 The @code{verrx} function is just like @code{errx} except that the
 parameters for the handling of the format string @var{format} are passed
 in as an value of type @code{va_list}.

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=818a7812257551d150ff5fe95d3d0ae0597d6228

commit 818a7812257551d150ff5fe95d3d0ae0597d6228
Author: Alexandre Oliva <aoliva@redhat.com>
Date:   Fri Nov 8 06:08:16 2013 -0200

    MT-, AS- and AC-safety docs: manual/debug.texi
    
    for ChangeLog
    
    	* manual/debug.texi: Document MTASC-safety properties.

diff --git a/manual/debug.texi b/manual/debug.texi
index 1db9c18..a7c5289 100644
--- a/manual/debug.texi
+++ b/manual/debug.texi
@@ -36,6 +36,16 @@ and manipulate backtraces of the current thread.
 @comment execinfo.h
 @comment GNU
 @deftypefun int backtrace (void **@var{buffer}, int @var{size})
+@safety{@mtsafe{}@asunsafe{oncesafe, asmalloc, selfdeadlock}@acunsafe{oncesafe, memleak, lockleak, fdleak}}
+@c The generic implementation just does pointer chasing within the local
+@c stack, without any guarantees that this will handle signal frames
+@c correctly, so it's AS-Unsafe to begin with.  However, most (all?)
+@c arches defer to libgcc_s's _Unwind_* implementation, dlopening
+@c libgcc_s.so to that end except in a static version of libc.
+@c libgcc_s's implementation may in turn defer to libunwind.  We can't
+@c assume those implementations are AS- or AC-safe, but even if we
+@c could, our own initialization path isn't, and libgcc's implementation
+@c calls malloc and performs internal locking, so...
 The @code{backtrace} function obtains a backtrace for the current
 thread, as a list of pointers, and places the information into
 @var{buffer}.  The argument @var{size} should be the number of
@@ -56,6 +66,17 @@ interpreting the stack contents correctly.
 @comment execinfo.h
 @comment GNU
 @deftypefun {char **} backtrace_symbols (void *const *@var{buffer}, int @var{size})
+@safety{@mtsafe{}@asunsafe{asmalloc}@acunsafe{memleak, lockleak}}
+@c Collects info returned by _dl_addr in auto array, allocates memory
+@c for the whole return buffer with malloc then sprintfs into it storing
+@c pointers to the strings into the array entries in the buffer.
+@c _dl_addr takes the recursive dl_load_lock then calls
+@c _dl_find_dso_for_object and determine_info.
+@c _dl_find_dso_for_object calls _dl-addr_inside_object.
+@c All of them are safe as long as the lock is held.
+@c asynconsist?  It doesn't looke like the dynamic loader's data
+@c structures could be in an inconsistent state that would cause
+@c malfunction here.
 The @code{backtrace_symbols} function translates the information
 obtained from the @code{backtrace} function into an array of strings.
 The argument @var{buffer} should be a pointer to an array of addresses
@@ -88,6 +109,11 @@ cannot be obtained.
 @comment execinfo.h
 @comment GNU
 @deftypefun void backtrace_symbols_fd (void *const *@var{buffer}, int @var{size}, int @var{fd})
+@safety{@mtsafe{}@assafe{}@acunsafe{lockleak}}
+@c Single loop of _dl_addr over addresses, collecting info into an iovec
+@c written out with a writev call per iteration.  Addresses and offsets
+@c are converted to hex in auto buffers, so the only potential issue
+@c here is leaking the dl lock in case of cancellation.
 The @code{backtrace_symbols_fd} function performs the same translation
 as the function @code{backtrace_symbols} function.  Instead of returning
 the strings to the caller, it writes the strings to the file descriptor

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=53dbd3be24427a49b8826517e36d89eb61fcc104

commit 53dbd3be24427a49b8826517e36d89eb61fcc104
Author: Alexandre Oliva <aoliva@redhat.com>
Date:   Fri Nov 8 06:08:16 2013 -0200

    MT-, AS- and AC-safety docs: manual/ctype.texi
    
    for ChangeLog
    
    	* manual/ctype.texi: Document MTASC-safety properties.

diff --git a/manual/ctype.texi b/manual/ctype.texi
index 3d13571..ddf38ce 100644
--- a/manual/ctype.texi
+++ b/manual/ctype.texi
@@ -66,6 +66,13 @@ These functions are declared in the header file @file{ctype.h}.
 @comment ctype.h
 @comment ISO
 @deftypefun int islower (int @var{c})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
+@c The is* macros call __ctype_b_loc to get the ctype array from the
+@c current locale, and then index it by c.  __ctype_b_loc reads from
+@c thread-local memory the (indirect) pointer to the ctype array, which
+@c may involve one word access to the global locale object, if that's
+@c the active locale for the thread, and the array, being part of the
+@c locale data, is undeletable, so there's no thread-safety issue.
 Returns true if @var{c} is a lower-case letter.  The letter need not be
 from the Latin alphabet, any alphabet representable is valid.
 @end deftypefun
@@ -74,6 +81,7 @@ from the Latin alphabet, any alphabet representable is valid.
 @comment ctype.h
 @comment ISO
 @deftypefun int isupper (int @var{c})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 Returns true if @var{c} is an upper-case letter.  The letter need not be
 from the Latin alphabet, any alphabet representable is valid.
 @end deftypefun
@@ -82,6 +90,7 @@ from the Latin alphabet, any alphabet representable is valid.
 @comment ctype.h
 @comment ISO
 @deftypefun int isalpha (int @var{c})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 Returns true if @var{c} is an alphabetic character (a letter).  If
 @code{islower} or @code{isupper} is true of a character, then
 @code{isalpha} is also true.
@@ -97,6 +106,7 @@ additional characters.
 @comment ctype.h
 @comment ISO
 @deftypefun int isdigit (int @var{c})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 Returns true if @var{c} is a decimal digit (@samp{0} through @samp{9}).
 @end deftypefun
 
@@ -104,6 +114,7 @@ Returns true if @var{c} is a decimal digit (@samp{0} through @samp{9}).
 @comment ctype.h
 @comment ISO
 @deftypefun int isalnum (int @var{c})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 Returns true if @var{c} is an alphanumeric character (a letter or
 number); in other words, if either @code{isalpha} or @code{isdigit} is
 true of a character, then @code{isalnum} is also true.
@@ -113,6 +124,7 @@ true of a character, then @code{isalnum} is also true.
 @comment ctype.h
 @comment ISO
 @deftypefun int isxdigit (int @var{c})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 Returns true if @var{c} is a hexadecimal digit.
 Hexadecimal digits include the normal decimal digits @samp{0} through
 @samp{9} and the letters @samp{A} through @samp{F} and
@@ -123,6 +135,7 @@ Hexadecimal digits include the normal decimal digits @samp{0} through
 @comment ctype.h
 @comment ISO
 @deftypefun int ispunct (int @var{c})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 Returns true if @var{c} is a punctuation character.
 This means any printing character that is not alphanumeric or a space
 character.
@@ -132,6 +145,7 @@ character.
 @comment ctype.h
 @comment ISO
 @deftypefun int isspace (int @var{c})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 Returns true if @var{c} is a @dfn{whitespace} character.  In the standard
 @code{"C"} locale, @code{isspace} returns true for only the standard
 whitespace characters:
@@ -161,6 +175,7 @@ vertical tab
 @comment ctype.h
 @comment ISO
 @deftypefun int isblank (int @var{c})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 Returns true if @var{c} is a blank character; that is, a space or a tab.
 This function was originally a GNU extension, but was added in @w{ISO C99}.
 @end deftypefun
@@ -169,6 +184,7 @@ This function was originally a GNU extension, but was added in @w{ISO C99}.
 @comment ctype.h
 @comment ISO
 @deftypefun int isgraph (int @var{c})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 Returns true if @var{c} is a graphic character; that is, a character
 that has a glyph associated with it.  The whitespace characters are not
 considered graphic.
@@ -178,6 +194,7 @@ considered graphic.
 @comment ctype.h
 @comment ISO
 @deftypefun int isprint (int @var{c})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 Returns true if @var{c} is a printing character.  Printing characters
 include all the graphic characters, plus the space (@samp{ }) character.
 @end deftypefun
@@ -186,6 +203,7 @@ include all the graphic characters, plus the space (@samp{ }) character.
 @comment ctype.h
 @comment ISO
 @deftypefun int iscntrl (int @var{c})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 Returns true if @var{c} is a control character (that is, a character that
 is not a printing character).
 @end deftypefun
@@ -194,6 +212,7 @@ is not a printing character).
 @comment ctype.h
 @comment SVID, BSD
 @deftypefun int isascii (int @var{c})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 Returns true if @var{c} is a 7-bit @code{unsigned char} value that fits
 into the US/UK ASCII character set.  This function is a BSD extension
 and is also an SVID extension.
@@ -227,6 +246,10 @@ These functions are declared in the header file @file{ctype.h}.
 @comment ctype.h
 @comment ISO
 @deftypefun int tolower (int @var{c})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
+@c The to* macros/functions call different functions that use different
+@c arrays than those of__ctype_b_loc, but the access patterns and
+@c thus safety guarantees are the same.
 If @var{c} is an upper-case letter, @code{tolower} returns the corresponding
 lower-case letter.  If @var{c} is not an upper-case letter,
 @var{c} is returned unchanged.
@@ -235,6 +258,7 @@ lower-case letter.  If @var{c} is not an upper-case letter,
 @comment ctype.h
 @comment ISO
 @deftypefun int toupper (int @var{c})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 If @var{c} is a lower-case letter, @code{toupper} returns the corresponding
 upper-case letter.  Otherwise @var{c} is returned unchanged.
 @end deftypefun
@@ -242,6 +266,7 @@ upper-case letter.  Otherwise @var{c} is returned unchanged.
 @comment ctype.h
 @comment SVID, BSD
 @deftypefun int toascii (int @var{c})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 This function converts @var{c} to a 7-bit @code{unsigned char} value
 that fits into the US/UK ASCII character set, by clearing the high-order
 bits.  This function is a BSD extension and is also an SVID extension.
@@ -250,6 +275,7 @@ bits.  This function is a BSD extension and is also an SVID extension.
 @comment ctype.h
 @comment SVID
 @deftypefun int _tolower (int @var{c})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 This is identical to @code{tolower}, and is provided for compatibility
 with the SVID.  @xref{SVID}.@refill
 @end deftypefun
@@ -257,6 +283,7 @@ with the SVID.  @xref{SVID}.@refill
 @comment ctype.h
 @comment SVID
 @deftypefun int _toupper (int @var{c})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 This is identical to @code{toupper}, and is provided for compatibility
 with the SVID.
 @end deftypefun
@@ -303,6 +330,15 @@ This type is defined in @file{wctype.h}.
 @comment wctype.h
 @comment ISO
 @deftypefun wctype_t wctype (const char *@var{property})
+@safety{@mtsafe{glocale}@assafe{}@acsafe{}}
+@c Although the source code of wctype contains multiple references to
+@c the locale, that could each reference different locale_data objects
+@c should the global locale object change while active, the compiler can
+@c and does combine them all into a single dereference that resolves
+@c once to the LCTYPE locale object used throughout the function, so it
+@c is safe in practice, if not in theory.  Ideally we'd explicitly save
+@c the resolved locale_data object to make it visibly safe instead of
+@c safe only under compiler optimizations.
 The @code{wctype} returns a value representing a class of wide
 characters which is identified by the string @var{property}.  Beside
 some standard properties each locale can define its own ones.  In case
@@ -331,6 +367,8 @@ the @w{ISO C} standard defines a completely new function.
 @comment wctype.h
 @comment ISO
 @deftypefun int iswctype (wint_t @var{wc}, wctype_t @var{desc})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
+@c The compressed lookup table returned by wctype is read-only.
 This function returns a nonzero value if @var{wc} is in the character
 class specified by @var{desc}.  @var{desc} must previously be returned
 by a successful call to @code{wctype}.
@@ -350,6 +388,15 @@ standard classes.
 @comment wctype.h
 @comment ISO
 @deftypefun int iswalnum (wint_t @var{wc})
+@safety{@mtsafe{glocale}@assafe{}@acsafe{}}
+@c The implicit wctype call in the isw* functions is actually an
+@c optimized version because the category has a known offset, but the
+@c wctype is equally safe when optimized, unsafe if not optimized.
+@c Since it's not a macro, and we always optimize, it's fine.  The test
+@c whether wc is ASCII to use the non-wide is* macro/funciton doesn't
+@c bring any other safety issues: the test does not depend on the
+@c locale, and each path after the decision resolves the locale object
+@c only once.
 This function returns a nonzero value if @var{wc} is an alphanumeric
 character (a letter or number); in other words, if either @code{iswalpha}
 or @code{iswdigit} is true of a character, then @code{iswalnum} is also
@@ -370,6 +417,7 @@ It is declared in @file{wctype.h}.
 @comment wctype.h
 @comment ISO
 @deftypefun int iswalpha (wint_t @var{wc})
+@safety{@mtsafe{glocale}@assafe{}@acsafe{}}
 Returns true if @var{wc} is an alphabetic character (a letter).  If
 @code{iswlower} or @code{iswupper} is true of a character, then
 @code{iswalpha} is also true.
@@ -394,6 +442,7 @@ It is declared in @file{wctype.h}.
 @comment wctype.h
 @comment ISO
 @deftypefun int iswcntrl (wint_t @var{wc})
+@safety{@mtsafe{glocale}@assafe{}@acsafe{}}
 Returns true if @var{wc} is a control character (that is, a character that
 is not a printing character).
 
@@ -412,6 +461,7 @@ It is declared in @file{wctype.h}.
 @comment wctype.h
 @comment ISO
 @deftypefun int iswdigit (wint_t @var{wc})
+@safety{@mtsafe{glocale}@assafe{}@acsafe{}}
 Returns true if @var{wc} is a digit (e.g., @samp{0} through @samp{9}).
 Please note that this function does not only return a nonzero value for
 @emph{decimal} digits, but for all kinds of digits.  A consequence is
@@ -442,6 +492,7 @@ It is declared in @file{wctype.h}.
 @comment wctype.h
 @comment ISO
 @deftypefun int iswgraph (wint_t @var{wc})
+@safety{@mtsafe{glocale}@assafe{}@acsafe{}}
 Returns true if @var{wc} is a graphic character; that is, a character
 that has a glyph associated with it.  The whitespace characters are not
 considered graphic.
@@ -461,6 +512,7 @@ It is declared in @file{wctype.h}.
 @comment ctype.h
 @comment ISO
 @deftypefun int iswlower (wint_t @var{wc})
+@safety{@mtsafe{glocale}@assafe{}@acsafe{}}
 Returns true if @var{wc} is a lower-case letter.  The letter need not be
 from the Latin alphabet, any alphabet representable is valid.
 
@@ -479,6 +531,7 @@ It is declared in @file{wctype.h}.
 @comment wctype.h
 @comment ISO
 @deftypefun int iswprint (wint_t @var{wc})
+@safety{@mtsafe{glocale}@assafe{}@acsafe{}}
 Returns true if @var{wc} is a printing character.  Printing characters
 include all the graphic characters, plus the space (@samp{ }) character.
 
@@ -497,6 +550,7 @@ It is declared in @file{wctype.h}.
 @comment wctype.h
 @comment ISO
 @deftypefun int iswpunct (wint_t @var{wc})
+@safety{@mtsafe{glocale}@assafe{}@acsafe{}}
 Returns true if @var{wc} is a punctuation character.
 This means any printing character that is not alphanumeric or a space
 character.
@@ -516,6 +570,7 @@ It is declared in @file{wctype.h}.
 @comment wctype.h
 @comment ISO
 @deftypefun int iswspace (wint_t @var{wc})
+@safety{@mtsafe{glocale}@assafe{}@acsafe{}}
 Returns true if @var{wc} is a @dfn{whitespace} character.  In the standard
 @code{"C"} locale, @code{iswspace} returns true for only the standard
 whitespace characters:
@@ -555,6 +610,7 @@ It is declared in @file{wctype.h}.
 @comment wctype.h
 @comment ISO
 @deftypefun int iswupper (wint_t @var{wc})
+@safety{@mtsafe{glocale}@assafe{}@acsafe{}}
 Returns true if @var{wc} is an upper-case letter.  The letter need not be
 from the Latin alphabet, any alphabet representable is valid.
 
@@ -573,6 +629,7 @@ It is declared in @file{wctype.h}.
 @comment wctype.h
 @comment ISO
 @deftypefun int iswxdigit (wint_t @var{wc})
+@safety{@mtsafe{glocale}@assafe{}@acsafe{}}
 Returns true if @var{wc} is a hexadecimal digit.
 Hexadecimal digits include the normal decimal digits @samp{0} through
 @samp{9} and the letters @samp{A} through @samp{F} and
@@ -597,6 +654,7 @@ characters as well.
 @comment wctype.h
 @comment ISO
 @deftypefun int iswblank (wint_t @var{wc})
+@safety{@mtsafe{glocale}@assafe{}@acsafe{}}
 Returns true if @var{wc} is a blank character; that is, a space or a tab.
 This function was originally a GNU extension, but was added in @w{ISO C99}.
 It is declared in @file{wchar.h}.
@@ -691,6 +749,8 @@ This type is defined in @file{wctype.h}.
 @comment wctype.h
 @comment ISO
 @deftypefun wctrans_t wctrans (const char *@var{property})
+@safety{@mtsafe{glocale}@assafe{}@acsafe{}}
+@c Similar implementation, same caveats as wctype.
 The @code{wctrans} function has to be used to find out whether a named
 mapping is defined in the current locale selected for the
 @code{LC_CTYPE} category.  If the returned value is non-zero, you can use
@@ -713,6 +773,8 @@ These functions are declared in @file{wctype.h}.
 @comment wctype.h
 @comment ISO
 @deftypefun wint_t towctrans (wint_t @var{wc}, wctrans_t @var{desc})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
+@c Same caveats as iswctype.
 @code{towctrans} maps the input character @var{wc}
 according to the rules of the mapping for which @var{desc} is a
 descriptor, and returns the value it finds.  @var{desc} must be
@@ -730,6 +792,9 @@ for them.
 @comment wctype.h
 @comment ISO
 @deftypefun wint_t towlower (wint_t @var{wc})
+@safety{@mtsafe{glocale}@assafe{}@acsafe{}}
+@c Same caveats as iswalnum, just using a wctrans rather than a wctype
+@c table.
 If @var{wc} is an upper-case letter, @code{towlower} returns the corresponding
 lower-case letter.  If @var{wc} is not an upper-case letter,
 @var{wc} is returned unchanged.
@@ -749,6 +814,7 @@ This function is declared in @file{wctype.h}.
 @comment wctype.h
 @comment ISO
 @deftypefun wint_t towupper (wint_t @var{wc})
+@safety{@mtsafe{glocale}@assafe{}@acsafe{}}
 If @var{wc} is a lower-case letter, @code{towupper} returns the corresponding
 upper-case letter.  Otherwise @var{wc} is returned unchanged.
 

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=a9629cfd1f18fb18fdcf1d47dd60c87f53adbc65

commit a9629cfd1f18fb18fdcf1d47dd60c87f53adbc65
Author: Alexandre Oliva <aoliva@redhat.com>
Date:   Fri Nov 8 06:08:16 2013 -0200

    MT-, AS- and AC-safety docs: manual/crypt.texi
    
    for ChangeLog
    
    	* manual/crypt.texi: Document MTASC-safety properties.

diff --git a/manual/crypt.texi b/manual/crypt.texi
index 9c65b95..e1c5ddc 100644
--- a/manual/crypt.texi
+++ b/manual/crypt.texi
@@ -99,6 +99,13 @@ in a convenient way.
 @comment unistd.h
 @comment BSD
 @deftypefun {char *} getpass (const char *@var{prompt})
+@safety{@mtunsafe{tempterm}@asunsafe{asmalloc, selfdeadlock, asynconsist}@acunsafe{tempterm, lockleak, incansist}}
+@c This function will attempt to create a stream for terminal I/O, but
+@c will fallback to stdio/stderr.  It attempts to change the terminal
+@c mode in a thread-unsafe way, write out the prompt, read the password,
+@c then restore the terminal mode.  It has a cleanup to close the stream
+@c in case of (synchronous) cancellation, but not to restore the
+@c terminal mode.
 
 @code{getpass} outputs @var{prompt}, then reads a string in from the
 terminal without echoing it.  It tries to connect to the real terminal,
@@ -134,6 +141,13 @@ The substitute takes the same parameters as @code{getline}
 @comment crypt.h
 @comment BSD, SVID
 @deftypefun {char *} crypt (const char *@var{key}, const char *@var{salt})
+@safety{@mtunsafe{staticbuf}@asunsafe{asynconsist, selfdeadlock, asmalloc, shlimb}@acunsafe{lockleak, memleak, shlimb}}
+@c Besides the obvious problem of returning a pointer into static
+@c storage, the DES initializer takes an internal lock with the usual
+@c set of problems for AS- and AC-Safety.  The FIPS mode checker and the
+@c NSS implementations of may leak file descriptors if canceled.  The
+@c The MD5, SHA256 and SHA512 implementations will malloc on long keys,
+@c and NSS relies on dlopening, which brings about another can of worms.
 
 The @code{crypt} function takes a password, @var{key}, as a string, and
 a @var{salt} character array which is described below, and returns a
@@ -195,6 +209,9 @@ for a password and prints ``Access granted.'' if the user types
 @comment crypt.h
 @comment GNU
 @deftypefun {char *} crypt_r (const char *@var{key}, const char *@var{salt}, {struct crypt_data *} @var{data})
+@safety{@mtsafe{}@asunsafe{asynconsist, selfdeadlock, asmalloc, shlimb}@acunsafe{lockleak, memleak, shlimb}}
+@c Compared with crypt, this function fixes the staticbuf problem, but
+@c nothing else.
 
 The @code{crypt_r} function does the same thing as @code{crypt}, but
 takes an extra parameter which includes space for its result (among
@@ -241,6 +258,11 @@ specifies the unused bits.
 @comment crypt.h
 @comment BSD, SVID
 @deftypefun void setkey (const char *@var{key})
+@safety{@mtunsafe{staticbuf}@asunsafe{asynconsist, selfdeadlock}@acunsafe{lockleak}}
+@c The static buffer stores the key, making it fundamentally
+@c thread-unsafe.  The locking issues are only in the initialization
+@c path; cancelling the initialization will leave the lock held, it
+@c would otherwise repeat the initialization on the next call.
 
 The @code{setkey} function sets an internal data structure to be an
 expanded form of @var{key}.  @var{key} is specified as an array of 64
@@ -252,6 +274,8 @@ parity.
 @comment crypt.h
 @comment BSD, SVID
 @deftypefun void encrypt (char *@var{block}, int @var{edflag})
+@safety{@mtunsafe{staticbuf}@asunsafe{asynconsist, selfdeadlock}@acunsafe{lockleak}}
+@c Same issues as setkey.
 
 The @code{encrypt} function encrypts @var{block} if
 @var{edflag} is 0, otherwise it decrypts @var{block}, using a key
@@ -265,9 +289,11 @@ stored in a @code{char}, but there are no parity bits in @var{block}.
 @comment crypt.h
 @comment GNU
 @deftypefun void setkey_r (const char *@var{key}, {struct crypt_data *} @var{data})
+@safety{@mtsafe{}@asunsafe{asynconsist, selfdeadlock}@acunsafe{lockleak}}
 @comment crypt.h
 @comment GNU
 @deftypefunx void encrypt_r (char *@var{block}, int @var{edflag}, {struct crypt_data *} @var{data})
+@safety{@mtsafe{}@asunsafe{asynconsist, selfdeadlock}@acunsafe{lockleak}}
 
 These are reentrant versions of @code{setkey} and @code{encrypt}.  The
 only difference is the extra parameter, which stores the expanded
@@ -282,6 +308,7 @@ defined in @file{crypt.h}.
 @comment rpc/des_crypt.h
 @comment SUNRPC
 @deftypefun int ecb_crypt (char *@var{key}, char *@var{blocks}, unsigned @var{len}, unsigned @var{mode})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 
 The function @code{ecb_crypt} encrypts or decrypts one or more blocks
 using DES.  Each block is encrypted independently.
@@ -363,6 +390,7 @@ This macro returns 1 if @var{err} is a `success' result code from
 @comment rpc/des_crypt.h
 @comment SUNRPC
 @deftypefun int cbc_crypt (char *@var{key}, char *@var{blocks}, unsigned @var{len}, unsigned @var{mode}, char *@var{ivec})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 
 The function @code{cbc_crypt} encrypts or decrypts one or more blocks
 using DES in Cipher Block Chaining mode.
@@ -389,6 +417,7 @@ Otherwise, all the parameters are similar to those for @code{ecb_crypt}.
 @comment rpc/des_crypt.h
 @comment SUNRPC
 @deftypefun void des_setparity (char *@var{key})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 
 The function @code{des_setparity} changes the 64-bit @var{key}, stored
 packed in 8-bit bytes, to have odd parity by altering the low bits of

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=276f4eaac6f1e576e8e33653715b0709bcddcc05

commit 276f4eaac6f1e576e8e33653715b0709bcddcc05
Author: Alexandre Oliva <aoliva@redhat.com>
Date:   Fri Nov 8 06:08:15 2013 -0200

    MT-, AS- and AC-safety docs: manual/conf.texi
    
    for ChangeLog
    
    	* manual/conf.texi: Document MTASC-safety properties.

diff --git a/manual/conf.texi b/manual/conf.texi
index c720063..79bfcdb 100644
--- a/manual/conf.texi
+++ b/manual/conf.texi
@@ -288,6 +288,17 @@ constants are declared in the header file @file{unistd.h}.
 @comment unistd.h
 @comment POSIX.1
 @deftypefun {long int} sysconf (int @var{parameter})
+@safety{@mtsafe{envromt}@asunsafe{selfdeadlock, asmalloc}@acunsafe{lockleak, memleak, fdleak}}
+@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.  _SC_TZNAME_MAX calls __tzname_max, that (while holding a lock)
+@c calls tzset_internal, that calls getenv if it's called the first
+@c time; there are free and strdup calls in there too.  The returned max
+@c value may change over time for TZNAME_MAX, depending on selected
+@c timezones; NPROCS, NPROCS_CONF, PHYS_PAGES, AVPHYS_PAGES,
+@c NGROUPS_MAX, SIGQUEUE_MAX, depending on variable values read from
+@c /proc at each call, and from rlimit-obtained values CHILD_MAX,
+@c OPEN_MAX, ARG_MAX, SIGQUEUE_MAX.
 This function is used to inquire about runtime system parameters.  The
 @var{parameter} argument should be one of the @samp{_SC_} symbols listed
 below.
@@ -1348,6 +1359,11 @@ argument are declared in the header file @file{unistd.h}.
 @comment unistd.h
 @comment POSIX.1
 @deftypefun {long int} pathconf (const char *@var{filename}, int @var{parameter})
+@safety{@mtsafe{}@asunsafe{selfdeadlock, asmalloc}@acunsafe{lockleak, fdleak, memleak}}
+@c When __statfs_link_max finds an ext* filesystem, it may read
+@c /proc/mounts or similar as a mntent stream.
+@c __statfs_chown_restricted may read from
+@c /proc/sys/fs/xfs/restrict_chown as a file descriptor.
 This function is used to inquire about the limits that apply to
 the file named @var{filename}.
 
@@ -1375,6 +1391,8 @@ support the @var{parameter} for the specific file.
 @comment unistd.h
 @comment POSIX.1
 @deftypefun {long int} fpathconf (int @var{filedes}, int @var{parameter})
+@safety{@mtsafe{}@asunsafe{selfdeadlock, asmalloc}@acunsafe{lockleak, fdleak, memleak}}
+@c Same caveats as pathconf.
 This is just like @code{pathconf} except that an open file descriptor
 is used to specify the file for which information is requested, instead
 of a file name.
@@ -1624,6 +1642,7 @@ system with the function @code{confstr}:
 @comment unistd.h
 @comment POSIX.2
 @deftypefun size_t confstr (int @var{parameter}, char *@var{buf}, size_t @var{len})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 This function reads the value of a string-valued system parameter,
 storing the string into @var{len} bytes of memory space starting at
 @var{buf}.  The @var{parameter} argument should be one of the

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=b0254307d17f8bc4cffea372c77e926c7ecc48ff

commit b0254307d17f8bc4cffea372c77e926c7ecc48ff
Author: Alexandre Oliva <aoliva@redhat.com>
Date:   Fri Nov 8 06:08:15 2013 -0200

    MT-, AS- and AC-safety docs: manual/charset.texi
    
    for ChangeLog
    
    	* manual/charset.texi: Document MTASC-safety properties.

diff --git a/manual/charset.texi b/manual/charset.texi
index 4042639..2199aee 100644
--- a/manual/charset.texi
+++ b/manual/charset.texi
@@ -504,6 +504,8 @@ sequence points.  Communication protocols often require this.
 @comment wchar.h
 @comment ISO
 @deftypefun int mbsinit (const mbstate_t *@var{ps})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
+@c ps is dereferenced once, unguarded.  Potential harmless data race.
 The @code{mbsinit} function determines whether the state object pointed
 to by @var{ps} is in the initial state.  If @var{ps} is a null pointer or
 the object is in the initial state the return value is nonzero.  Otherwise
@@ -559,6 +561,14 @@ that is beyond the range @math{0} to @math{127}.
 @comment wchar.h
 @comment ISO
 @deftypefun wint_t btowc (int @var{c})
+@safety{@mtsafe{}@asunsafe{asynconsist, asmalloc, selfdeadlock, shlimb}@acunsafe{incansist, lockleak, memleak, fdleak, shlimb}}
+@c Calls btowc_fct or __fct; reads from locale, and from the
+@c get_gconv_fcts result multiple times.  get_gconv_fcts calls
+@c __wcsmbs_load_conv to initialize the ctype if it's null.
+@c wcsmbs_load_conv takes a non-recursive wrlock before allocating
+@c memory for the fcts structure, initializing it, and then storing it
+@c in the locale object.  The initialization involves dlopening and a
+@c lot more.
 The @code{btowc} function (``byte to wide character'') converts a valid
 single byte character @var{c} in the initial shift state into the wide
 character equivalent using the conversion rules from the currently
@@ -615,6 +625,7 @@ There is also a function for the conversion in the other direction.
 @comment wchar.h
 @comment ISO
 @deftypefun int wctob (wint_t @var{c})
+@safety{@mtsafe{}@asunsafe{asynconsist, asmalloc, selfdeadlock, shlimb}@acunsafe{incansist, lockleak, memleak, fdleak, shlimb}}
 The @code{wctob} function (``wide character to byte'') takes as the
 parameter a valid wide character.  If the multibyte representation for
 this character in the initial state is exactly one byte long, the return
@@ -634,6 +645,7 @@ and they also do not require it to be in the initial state.
 @comment wchar.h
 @comment ISO
 @deftypefun size_t mbrtowc (wchar_t *restrict @var{pwc}, const char *restrict @var{s}, size_t @var{n}, mbstate_t *restrict @var{ps})
+@safety{@mtunsafe{staticbuf (if ps is null)}@asunsafe{asynconsist, asmalloc, selfdeadlock, shlimb}@acunsafe{incansist, lockleak, memleak, fdleak, shlimb}}
 @cindex stateful
 The @code{mbrtowc} function (``multibyte restartable to wide
 character'') converts the next multibyte character in the string pointed
@@ -728,6 +740,7 @@ function that does part of the work.
 @comment wchar.h
 @comment ISO
 @deftypefun size_t mbrlen (const char *restrict @var{s}, size_t @var{n}, mbstate_t *@var{ps})
+@safety{@mtunsafe{staticbuf (if ps is null)}@asunsafe{asynconsist, asmalloc, selfdeadlock, shlimb}@acunsafe{incansist, lockleak, memleak, fdleak, shlimb}}
 The @code{mbrlen} function (``multibyte restartable length'') computes
 the number of at most @var{n} bytes starting at @var{s}, which form the
 next valid and complete multibyte character.
@@ -811,6 +824,50 @@ doing the work twice.
 @comment wchar.h
 @comment ISO
 @deftypefun size_t wcrtomb (char *restrict @var{s}, wchar_t @var{wc}, mbstate_t *restrict @var{ps})
+@safety{@mtunsafe{staticbuf (if ps is null)}@asunsafe{asynconsist, asmalloc, selfdeadlock, shlimb}@acunsafe{incansist, lockleak, memleak, fdleak, shlimb}}
+@c wcrtomb uses a static, non-thread-local unguarded state variable when
+@c PS is NULL.  When a state is passed in, and it's not used
+@c concurrently in other threads, this function behaves safely as long
+@c as gconv modules don't bring MT safety issues of their own.
+@c Attempting to load gconv modules or to build conversion chains in
+@c signal handlers may encounter gconv databases or caches in a
+@c partially-updated state, and asynchronous cancellation may leave them
+@c in such states, besides leaking the lock that guards them.
+@c get_gconv_fcts ok
+@c    wcsmbs_load_conv ok
+@c      norm_add_slashes ok
+@c      wcsmbs_getfct ok
+@c        gconv_find_transform ok
+@c          gconv_read_conf (libc_once)
+@c          gconv_lookup_cache ok
+@c            find_module_idx ok
+@c            find_module ok
+@c              gconv_find_shlib (ok)
+@c              ->init_fct (assumed ok)
+@c            gconv_get_builtin_trans ok
+@c            gconv_release_step ok
+@c          do_lookup_alias ok
+@c          find_derivation ok
+@c            derivation_lookup ok
+@c            increment_counter ok
+@c              gconv_find_shlib ok
+@c              step->init_fct (assumed ok)
+@c            gen_steps ok
+@c              gconv_find_shlib ok
+@c                dlopen (presumed ok)
+@c                dlsym (presumed ok)
+@c              step->init_fct (assumed ok)
+@c              step->end_fct (assumed ok)
+@c              gconv_get_builtin_trans ok
+@c              gconv_release_step ok
+@c            add_derivation ok
+@c      gconv_close_transform ok
+@c        gconv_release_step ok
+@c          step->end_fct (assumed ok)
+@c          gconv_release_shlib ok
+@c            dlclose (presumed ok)
+@c        gconv_release_cache ok
+@c  ->tomb->__fct (assumed ok)
 The @code{wcrtomb} function (``wide character restartable to
 multibyte'') converts a single wide character into a multibyte string
 corresponding to that wide character.
@@ -955,6 +1012,7 @@ extensions that can help in some important situations.
 @comment wchar.h
 @comment ISO
 @deftypefun size_t mbsrtowcs (wchar_t *restrict @var{dst}, const char **restrict @var{src}, size_t @var{len}, mbstate_t *restrict @var{ps})
+@safety{@mtunsafe{staticbuf (if ps is null)}@asunsafe{asynconsist, asmalloc, selfdeadlock, shlimb}@acunsafe{incansist, lockleak, memleak, fdleak, shlimb}}
 The @code{mbsrtowcs} function (``multibyte string restartable to wide
 character string'') converts an NUL-terminated multibyte character
 string at @code{*@var{src}} into an equivalent wide character string,
@@ -1039,6 +1097,7 @@ length and passing this length to the function.
 @comment wchar.h
 @comment ISO
 @deftypefun size_t wcsrtombs (char *restrict @var{dst}, const wchar_t **restrict @var{src}, size_t @var{len}, mbstate_t *restrict @var{ps})
+@safety{@mtunsafe{staticbuf (if ps is null)}@asunsafe{asynconsist, asmalloc, selfdeadlock, shlimb}@acunsafe{incansist, lockleak, memleak, fdleak, shlimb}}
 The @code{wcsrtombs} function (``wide character string restartable to
 multibyte string'') converts the NUL-terminated wide character string at
 @code{*@var{src}} into an equivalent multibyte character string and
@@ -1084,6 +1143,7 @@ array size (the @var{len} parameter).
 @comment wchar.h
 @comment GNU
 @deftypefun size_t mbsnrtowcs (wchar_t *restrict @var{dst}, const char **restrict @var{src}, size_t @var{nmc}, size_t @var{len}, mbstate_t *restrict @var{ps})
+@safety{@mtunsafe{staticbuf (if ps is null)}@asunsafe{asynconsist, asmalloc, selfdeadlock, shlimb}@acunsafe{incansist, lockleak, memleak, fdleak, shlimb}}
 The @code{mbsnrtowcs} function is very similar to the @code{mbsrtowcs}
 function.  All the parameters are the same except for @var{nmc}, which is
 new.  The return value is the same as for @code{mbsrtowcs}.
@@ -1136,6 +1196,7 @@ of the given buffer, there is no problem with altering the state.
 @comment wchar.h
 @comment GNU
 @deftypefun size_t wcsnrtombs (char *restrict @var{dst}, const wchar_t **restrict @var{src}, size_t @var{nwc}, size_t @var{len}, mbstate_t *restrict @var{ps})
+@safety{@mtunsafe{staticbuf (if ps is null)}@asunsafe{asynconsist, asmalloc, selfdeadlock, shlimb}@acunsafe{incansist, lockleak, memleak, fdleak, shlimb}}
 The @code{wcsnrtombs} function implements the conversion from wide
 character strings to multibyte character strings.  It is similar to
 @code{wcsrtombs} but, just like @code{mbsnrtowcs}, it takes an extra
@@ -1280,6 +1341,7 @@ conversion functions.}
 @comment stdlib.h
 @comment ISO
 @deftypefun int mbtowc (wchar_t *restrict @var{result}, const char *restrict @var{string}, size_t @var{size})
+@safety{@mtunsafe{staticbuf}@asunsafe{asynconsist, asmalloc, selfdeadlock, shlimb}@acunsafe{incansist, lockleak, memleak, fdleak, shlimb}}
 The @code{mbtowc} (``multibyte to wide character'') function when called
 with non-null @var{string} converts the first multibyte character
 beginning at @var{string} to its corresponding wide character code.  It
@@ -1314,6 +1376,7 @@ shift state.  @xref{Shift State}.
 @comment stdlib.h
 @comment ISO
 @deftypefun int wctomb (char *@var{string}, wchar_t @var{wchar})
+@safety{@mtunsafe{staticbuf}@asunsafe{asynconsist, asmalloc, selfdeadlock, shlimb}@acunsafe{incansist, lockleak, memleak, fdleak, shlimb}}
 The @code{wctomb} (``wide character to multibyte'') function converts
 the wide character code @var{wchar} to its corresponding multibyte
 character sequence, and stores the result in bytes starting at
@@ -1353,6 +1416,7 @@ terms of @code{mbtowc}.
 @comment stdlib.h
 @comment ISO
 @deftypefun int mblen (const char *@var{string}, size_t @var{size})
+@safety{@mtunsafe{staticbuf}@asunsafe{asynconsist, asmalloc, selfdeadlock, shlimb}@acunsafe{incansist, lockleak, memleak, fdleak, shlimb}}
 The @code{mblen} function with a non-null @var{string} argument returns
 the number of bytes that make up the multibyte character beginning at
 @var{string}, never examining more than @var{size} bytes.  (The idea is
@@ -1391,6 +1455,9 @@ suffer from the same problems as their reentrant counterparts from
 @comment stdlib.h
 @comment ISO
 @deftypefun size_t mbstowcs (wchar_t *@var{wstring}, const char *@var{string}, size_t @var{size})
+@safety{@mtsafe{}@asunsafe{asynconsist, asmalloc, selfdeadlock, shlimb}@acunsafe{incansist, lockleak, memleak, fdleak, shlimb}}
+@c Odd...  Although this is in the non-reentrant section, the state
+@c object is automatic, not a static buffer.
 The @code{mbstowcs} (``multibyte string to wide character string'')
 function converts the null-terminated string of multibyte characters
 @var{string} to an array of wide character codes, storing not more than
@@ -1431,6 +1498,7 @@ mbstowcs_alloc (const char *string)
 @comment stdlib.h
 @comment ISO
 @deftypefun size_t wcstombs (char *@var{string}, const wchar_t *@var{wstring}, size_t @var{size})
+@safety{@mtsafe{}@asunsafe{asynconsist, asmalloc, selfdeadlock, shlimb}@acunsafe{incansist, lockleak, memleak, fdleak, shlimb}}
 The @code{wcstombs} (``wide character string to multibyte string'')
 function converts the null-terminated wide character array @var{wstring}
 into a string containing multibyte characters, storing not more than
@@ -1618,6 +1686,16 @@ The first step is the function to create a handle.
 @comment iconv.h
 @comment XPG2
 @deftypefun iconv_t iconv_open (const char *@var{tocode}, const char *@var{fromcode})
+@safety{@mtsafe{glocale}@asunsafe{asynconsist, asmalloc, selfdeadlock, shlimb}@acunsafe{incansist, lockleak, memleak, fdleak, shlimb}}
+@c Calls malloc if tocode and/or fromcode are too big for alloca.  Calls
+@c strip and upstr on both, then gconv_open.  strip and upstr call
+@c isalnum_l and toupper_l with the C locale.  gconv_open may MT-safely
+@c tokenize toset, replace unspecified codesets with the current locale
+@c (posibly two different accesses), and finally it calls
+@c gconv_find_transform and initializes the gconv_t result with all the
+@c steps in the conversion sequence, running each one's initializer,
+@c destructing and releasing them all if anything fails.
+
 The @code{iconv_open} function has to be used before starting a
 conversion.  The two parameters this function takes determine the
 source and destination character set for the conversion, and if the
@@ -1682,6 +1760,12 @@ conversion is not needed anymore.
 @comment iconv.h
 @comment XPG2
 @deftypefun int iconv_close (iconv_t @var{cd})
+@safety{@mtsafe{}@asunsafe{asynconsist, asmalloc, selfdeadlock, shlimb}@acunsafe{incansist, lockleak, memleak, shlimb}}
+@c Calls gconv_close to destruct and release each of the conversion
+@c steps, release the gconv_t object, then call gconv_close_transform.
+@c Access to the gconv_t object is not guarded, but calling iconv_close
+@c concurrently with any other use is undefined.
+
 The @code{iconv_close} function frees all resources associated with the
 handle @var{cd}, which must have been returned by a successful call to
 the @code{iconv_open} function.
@@ -1708,6 +1792,10 @@ even file to file can be implemented on top of it.
 @comment iconv.h
 @comment XPG2
 @deftypefun size_t iconv (iconv_t @var{cd}, char **@var{inbuf}, size_t *@var{inbytesleft}, char **@var{outbuf}, size_t *@var{outbytesleft})
+@safety{@mtunsafe{xguargs}@asunsafe{asynconsist}@acunsafe{incansist}}
+@c Without guarding access to the gconv_t object pointed to by cd, call
+@c the conversion function to convert inbuf or flush the internal
+@c conversion state.
 @cindex stateful
 The @code{iconv} function converts the text in the input buffer
 according to the rules associated with the descriptor @var{cd} and

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=147179305ddd9f1e8a8e2e955e0630ddbb01c139

commit 147179305ddd9f1e8a8e2e955e0630ddbb01c139
Author: Alexandre Oliva <aoliva@redhat.com>
Date:   Fri Nov 8 06:08:15 2013 -0200

    MT-, AS- and AC-safety docs: manual/arith.texi
    
    for  ChangeLog
    
    	* manual/arith.texi: Document MTASC-safety properties.

diff --git a/manual/arith.texi b/manual/arith.texi
index 85aa197..3b08f1a 100644
--- a/manual/arith.texi
+++ b/manual/arith.texi
@@ -160,6 +160,8 @@ The remainder from the division.
 @comment stdlib.h
 @comment ISO
 @deftypefun div_t div (int @var{numerator}, int @var{denominator})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
+@c Functions in this section are pure, and thus safe.
 This function @code{div} computes the quotient and remainder from
 the division of @var{numerator} by @var{denominator}, returning the
 result in a structure of type @code{div_t}.
@@ -199,6 +201,7 @@ type @code{long int} rather than @code{int}.)
 @comment stdlib.h
 @comment ISO
 @deftypefun ldiv_t ldiv (long int @var{numerator}, long int @var{denominator})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 The @code{ldiv} function is similar to @code{div}, except that the
 arguments are of type @code{long int} and the result is returned as a
 structure of type @code{ldiv_t}.
@@ -225,6 +228,7 @@ type @code{long long int} rather than @code{int}.)
 @comment stdlib.h
 @comment ISO
 @deftypefun lldiv_t lldiv (long long int @var{numerator}, long long int @var{denominator})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 The @code{lldiv} function is like the @code{div} function, but the
 arguments are of type @code{long long int} and the result is returned as
 a structure of type @code{lldiv_t}.
@@ -256,6 +260,7 @@ See @ref{Integers} for a description of the @code{intmax_t} type.
 @comment inttypes.h
 @comment ISO
 @deftypefun imaxdiv_t imaxdiv (intmax_t @var{numerator}, intmax_t @var{denominator})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 The @code{imaxdiv} function is like the @code{div} function, but the
 arguments are of type @code{intmax_t} and the result is returned as
 a structure of type @code{imaxdiv_t}.
@@ -318,6 +323,7 @@ floating-point number a variable holds.
 @comment math.h
 @comment ISO
 @deftypefn {Macro} int fpclassify (@emph{float-type} @var{x})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 This is a generic macro which works on all floating-point types and
 which returns a value of type @code{int}.  The possible values are:
 
@@ -354,6 +360,7 @@ You should therefore use the specific macros whenever possible.
 @comment math.h
 @comment ISO
 @deftypefn {Macro} int isfinite (@emph{float-type} @var{x})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 This macro returns a nonzero value if @var{x} is finite: not plus or
 minus infinity, and not NaN.  It is equivalent to
 
@@ -368,6 +375,7 @@ floating-point type.
 @comment math.h
 @comment ISO
 @deftypefn {Macro} int isnormal (@emph{float-type} @var{x})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 This macro returns a nonzero value if @var{x} is finite and normalized.
 It is equivalent to
 
@@ -379,6 +387,7 @@ It is equivalent to
 @comment math.h
 @comment ISO
 @deftypefn {Macro} int isnan (@emph{float-type} @var{x})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 This macro returns a nonzero value if @var{x} is NaN.  It is equivalent
 to
 
@@ -390,6 +399,7 @@ to
 @comment math.h
 @comment GNU
 @deftypefn {Macro} int issignaling (@emph{float-type} @var{x})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 This macro returns a nonzero value if @var{x} is a signaling NaN
 (sNaN).  It is based on draft TS 18661 and currently enabled as a GNU
 extension.
@@ -410,6 +420,7 @@ not have to worry about the type of their argument.
 @comment math.h
 @comment BSD
 @deftypefunx int isinfl (long double @var{x})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 This function returns @code{-1} if @var{x} represents negative infinity,
 @code{1} if @var{x} represents positive infinity, and @code{0} otherwise.
 @end deftypefun
@@ -423,6 +434,7 @@ This function returns @code{-1} if @var{x} represents negative infinity,
 @comment math.h
 @comment BSD
 @deftypefunx int isnanl (long double @var{x})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 This function returns a nonzero value if @var{x} is a ``not a number''
 value, and zero otherwise.
 
@@ -445,6 +457,7 @@ function for some reason, you can write
 @comment math.h
 @comment BSD
 @deftypefunx int finitel (long double @var{x})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 This function returns a nonzero value if @var{x} is finite or a ``not a
 number'' value, and zero otherwise.
 @end deftypefun
@@ -713,6 +726,14 @@ and save and restore the set of exceptions flagged.
 @comment fenv.h
 @comment ISO
 @deftypefun int feclearexcept (int @var{excepts})
+@safety{@mtsafe{}@assafe{unposix}@acsafe{unposix}}
+@c The other functions in this section that modify FP status register
+@c mostly do so with non-atomic load-modify-store sequences, but since
+@c the register is thread-specific, this should be fine, and safe for
+@c cancellation.  As long as the FP environment is restored before the
+@c signal handler returns control to the interrupted thread (like any
+@c kernel should do), the functions are also safe for use in signal
+@c handlers.
 This function clears all of the supported exception flags indicated by
 @var{excepts}.
 
@@ -723,6 +744,7 @@ non-zero value otherwise.
 @comment fenv.h
 @comment ISO
 @deftypefun int feraiseexcept (int @var{excepts})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 This function raises the supported exceptions indicated by
 @var{excepts}.  If more than one exception bit in @var{excepts} is set
 the order in which the exceptions are raised is undefined except that
@@ -738,6 +760,7 @@ non-zero value otherwise.
 @comment fenv.h
 @comment ISO
 @deftypefun int fetestexcept (int @var{excepts})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 Test whether the exception flags indicated by the parameter @var{except}
 are currently set.  If any of them are, a nonzero value is returned
 which specifies which exceptions are set.  Otherwise the result is zero.
@@ -774,6 +797,7 @@ following functions:
 @comment fenv.h
 @comment ISO
 @deftypefun int fegetexceptflag (fexcept_t *@var{flagp}, int @var{excepts})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 This function stores in the variable pointed to by @var{flagp} an
 implementation-defined value representing the current setting of the
 exception flags indicated by @var{excepts}.
@@ -785,6 +809,7 @@ non-zero value otherwise.
 @comment fenv.h
 @comment ISO
 @deftypefun int fesetexceptflag (const fexcept_t *@var{flagp}, int @var{excepts})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 This function restores the flags for the exceptions indicated by
 @var{excepts} to the values stored in the variable pointed to by
 @var{flagp}.
@@ -940,6 +965,7 @@ find out which one with this function:
 @comment fenv.h
 @comment ISO
 @deftypefun int fegetround (void)
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 Returns the currently selected rounding mode, represented by one of the
 values of the defined rounding mode macros.
 @end deftypefun
@@ -950,6 +976,7 @@ To change the rounding mode, use this function:
 @comment fenv.h
 @comment ISO
 @deftypefun int fesetround (int @var{round})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 Changes the currently selected rounding mode to @var{round}.  If
 @var{round} does not correspond to one of the supported rounding modes
 nothing is changed.  @code{fesetround} returns zero if it changed the
@@ -994,6 +1021,7 @@ To save the state of the FPU, use one of these functions:
 @comment fenv.h
 @comment ISO
 @deftypefun int fegetenv (fenv_t *@var{envp})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 Store the floating-point environment in the variable pointed to by
 @var{envp}.
 
@@ -1004,6 +1032,7 @@ non-zero value otherwise.
 @comment fenv.h
 @comment ISO
 @deftypefun int feholdexcept (fenv_t *@var{envp})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 Store the current floating-point environment in the object pointed to by
 @var{envp}.  Then clear all exception flags, and set the FPU to trap no
 exceptions.  Not all FPUs support trapping no exceptions; if
@@ -1042,6 +1071,7 @@ functions:
 @comment fenv.h
 @comment ISO
 @deftypefun int fesetenv (const fenv_t *@var{envp})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 Set the floating-point environment to that described by @var{envp}.
 
 The function returns zero in case the operation was successful, a
@@ -1051,6 +1081,7 @@ non-zero value otherwise.
 @comment fenv.h
 @comment ISO
 @deftypefun int feupdateenv (const fenv_t *@var{envp})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 Like @code{fesetenv}, this function sets the floating-point environment
 to that described by @var{envp}.  However, if any exceptions were
 flagged in the status word before @code{feupdateenv} was called, they
@@ -1071,6 +1102,7 @@ occur, you can use the following two functions.
 @comment fenv.h
 @comment GNU
 @deftypefun int feenableexcept (int @var{excepts})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 This functions enables traps for each of the exceptions as indicated by
 the parameter @var{except}.  The individual exceptions are described in
 @ref{Status bit operations}.  Only the specified exceptions are
@@ -1083,6 +1115,7 @@ operation was successful, @code{-1} otherwise.
 @comment fenv.h
 @comment GNU
 @deftypefun int fedisableexcept (int @var{excepts})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 This functions disables traps for each of the exceptions as indicated by
 the parameter @var{except}.  The individual exceptions are described in
 @ref{Status bit operations}.  Only the specified exceptions are
@@ -1095,6 +1128,7 @@ operation was successful, @code{-1} otherwise.
 @comment fenv.h
 @comment GNU
 @deftypefun int fegetexcept (void)
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 The function returns a bitmask of all currently enabled exceptions.  It
 returns @code{-1} in case of failure.
 @end deftypefun
@@ -1146,6 +1180,7 @@ Prototypes for @code{abs}, @code{labs} and @code{llabs} are in @file{stdlib.h};
 @comment inttypes.h
 @comment ISO
 @deftypefunx intmax_t imaxabs (intmax_t @var{number})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 These functions return the absolute value of @var{number}.
 
 Most computers use a two's complement integer representation, in which
@@ -1167,6 +1202,7 @@ See @ref{Integers} for a description of the @code{intmax_t} type.
 @comment math.h
 @comment ISO
 @deftypefunx {long double} fabsl (long double @var{number})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 This function returns the absolute value of the floating-point number
 @var{number}.
 @end deftypefun
@@ -1180,6 +1216,7 @@ This function returns the absolute value of the floating-point number
 @comment complex.h
 @comment ISO
 @deftypefunx {long double} cabsl (complex long double @var{z})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 These functions return the absolute  value of the complex number @var{z}
 (@pxref{Complex Numbers}).  The absolute value of a complex number is:
 
@@ -1217,6 +1254,7 @@ All these functions are declared in @file{math.h}.
 @comment math.h
 @comment ISO
 @deftypefunx {long double} frexpl (long double @var{value}, int *@var{exponent})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 These functions are used to split the number @var{value}
 into a normalized fraction and an exponent.
 
@@ -1242,6 +1280,7 @@ zero is stored in @code{*@var{exponent}}.
 @comment math.h
 @comment ISO
 @deftypefunx {long double} ldexpl (long double @var{value}, int @var{exponent})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 These functions return the result of multiplying the floating-point
 number @var{value} by 2 raised to the power @var{exponent}.  (It can
 be used to reassemble floating-point numbers that were taken apart
@@ -1263,6 +1302,7 @@ equivalent to those of @code{ldexp} and @code{frexp}.  See also the
 @comment math.h
 @comment BSD
 @deftypefunx {long double} scalbl (long double @var{value}, long double @var{exponent})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 The @code{scalb} function is the BSD name for @code{ldexp}.
 @end deftypefun
 
@@ -1275,6 +1315,7 @@ The @code{scalb} function is the BSD name for @code{ldexp}.
 @comment math.h
 @comment BSD
 @deftypefunx {long double} scalbnl (long double @var{x}, int @var{n})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 @code{scalbn} is identical to @code{scalb}, except that the exponent
 @var{n} is an @code{int} instead of a floating-point number.
 @end deftypefun
@@ -1288,6 +1329,7 @@ The @code{scalb} function is the BSD name for @code{ldexp}.
 @comment math.h
 @comment BSD
 @deftypefunx {long double} scalblnl (long double @var{x}, long int @var{n})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 @code{scalbln} is identical to @code{scalb}, except that the exponent
 @var{n} is a @code{long int} instead of a floating-point number.
 @end deftypefun
@@ -1301,6 +1343,7 @@ The @code{scalb} function is the BSD name for @code{ldexp}.
 @comment math.h
 @comment BSD
 @deftypefunx {long double} significandl (long double @var{x})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 @code{significand} returns the mantissa of @var{x} scaled to the range
 @math{[1, 2)}.
 It is equivalent to @w{@code{scalb (@var{x}, (double) -ilogb (@var{x}))}}.
@@ -1335,6 +1378,7 @@ result as a @code{double} instead to get around this problem.
 @comment math.h
 @comment ISO
 @deftypefunx {long double} ceill (long double @var{x})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 These functions round @var{x} upwards to the nearest integer,
 returning that value as a @code{double}.  Thus, @code{ceil (1.5)}
 is @code{2.0}.
@@ -1349,6 +1393,7 @@ is @code{2.0}.
 @comment math.h
 @comment ISO
 @deftypefunx {long double} floorl (long double @var{x})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 These functions round @var{x} downwards to the nearest
 integer, returning that value as a @code{double}.  Thus, @code{floor
 (1.5)} is @code{1.0} and @code{floor (-1.5)} is @code{-2.0}.
@@ -1363,6 +1408,7 @@ integer, returning that value as a @code{double}.  Thus, @code{floor
 @comment math.h
 @comment ISO
 @deftypefunx {long double} truncl (long double @var{x})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 The @code{trunc} functions round @var{x} towards zero to the nearest
 integer (returned in floating-point format).  Thus, @code{trunc (1.5)}
 is @code{1.0} and @code{trunc (-1.5)} is @code{-1.0}.
@@ -1377,6 +1423,7 @@ is @code{1.0} and @code{trunc (-1.5)} is @code{-1.0}.
 @comment math.h
 @comment ISO
 @deftypefunx {long double} rintl (long double @var{x})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 These functions round @var{x} to an integer value according to the
 current rounding mode.  @xref{Floating Point Parameters}, for
 information about the various rounding modes.  The default
@@ -1397,6 +1444,7 @@ inexact exception.
 @comment math.h
 @comment ISO
 @deftypefunx {long double} nearbyintl (long double @var{x})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 These functions return the same value as the @code{rint} functions, but
 do not raise the inexact exception if @var{x} is not an integer.
 @end deftypefun
@@ -1410,6 +1458,7 @@ do not raise the inexact exception if @var{x} is not an integer.
 @comment math.h
 @comment ISO
 @deftypefunx {long double} roundl (long double @var{x})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 These functions are similar to @code{rint}, but they round halfway
 cases away from zero instead of to the nearest integer (or other
 current rounding mode).
@@ -1424,6 +1473,7 @@ current rounding mode).
 @comment math.h
 @comment ISO
 @deftypefunx {long int} lrintl (long double @var{x})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 These functions are just like @code{rint}, but they return a
 @code{long int} instead of a floating-point number.
 @end deftypefun
@@ -1437,6 +1487,7 @@ These functions are just like @code{rint}, but they return a
 @comment math.h
 @comment ISO
 @deftypefunx {long long int} llrintl (long double @var{x})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 These functions are just like @code{rint}, but they return a
 @code{long long int} instead of a floating-point number.
 @end deftypefun
@@ -1450,6 +1501,7 @@ These functions are just like @code{rint}, but they return a
 @comment math.h
 @comment ISO
 @deftypefunx {long int} lroundl (long double @var{x})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 These functions are just like @code{round}, but they return a
 @code{long int} instead of a floating-point number.
 @end deftypefun
@@ -1463,6 +1515,7 @@ These functions are just like @code{round}, but they return a
 @comment math.h
 @comment ISO
 @deftypefunx {long long int} llroundl (long double @var{x})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 These functions are just like @code{round}, but they return a
 @code{long long int} instead of a floating-point number.
 @end deftypefun
@@ -1477,6 +1530,7 @@ These functions are just like @code{round}, but they return a
 @comment math.h
 @comment ISO
 @deftypefunx {long double} modfl (long double @var{value}, long double *@var{integer-part})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 These functions break the argument @var{value} into an integer part and a
 fractional part (between @code{-1} and @code{1}, exclusive).  Their sum
 equals @var{value}.  Each of the parts has the same sign as @var{value},
@@ -1503,6 +1557,7 @@ suits your problem.
 @comment math.h
 @comment ISO
 @deftypefunx {long double} fmodl (long double @var{numerator}, long double @var{denominator})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 These functions compute the remainder from the division of
 @var{numerator} by @var{denominator}.  Specifically, the return value is
 @code{@var{numerator} - @w{@var{n} * @var{denominator}}}, where @var{n}
@@ -1525,6 +1580,7 @@ If @var{denominator} is zero, @code{fmod} signals a domain error.
 @comment math.h
 @comment BSD
 @deftypefunx {long double} dreml (long double @var{numerator}, long double @var{denominator})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 These functions are like @code{fmod} except that they round the
 internal quotient @var{n} to the nearest integer instead of towards zero
 to an integer.  For example, @code{drem (6.5, 2.3)} returns @code{-0.4},
@@ -1548,6 +1604,7 @@ If @var{denominator} is zero, @code{drem} signals a domain error.
 @comment math.h
 @comment BSD
 @deftypefunx {long double} remainderl (long double @var{numerator}, long double @var{denominator})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 This function is another name for @code{drem}.
 @end deftypefun
 
@@ -1569,6 +1626,7 @@ bits.
 @comment math.h
 @comment ISO
 @deftypefunx {long double} copysignl (long double @var{x}, long double @var{y})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 These functions return @var{x} but with the sign of @var{y}.  They work
 even if @var{x} or @var{y} are NaN or zero.  Both of these can carry a
 sign (although not all implementations support it) and this is one of
@@ -1584,6 +1642,7 @@ recommended functions in @w{IEEE 754}/@w{IEEE 854}).
 @comment math.h
 @comment ISO
 @deftypefun int signbit (@emph{float-type} @var{x})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 @code{signbit} is a generic macro which can work on all floating-point
 types.  It returns a nonzero value if the value of @var{x} has its sign
 bit set.
@@ -1602,6 +1661,7 @@ false, but @code{signbit (-0.0)} will return a nonzero value.
 @comment math.h
 @comment ISO
 @deftypefunx {long double} nextafterl (long double @var{x}, long double @var{y})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 The @code{nextafter} function returns the next representable neighbor of
 @var{x} in the direction towards @var{y}.  The size of the step between
 @var{x} and the result depends on the type of the result.  If
@@ -1625,6 +1685,7 @@ recommended functions in @w{IEEE 754}/@w{IEEE 854}).
 @comment math.h
 @comment ISO
 @deftypefunx {long double} nexttowardl (long double @var{x}, long double @var{y})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 These functions are identical to the corresponding versions of
 @code{nextafter} except that their second argument is a @code{long
 double}.
@@ -1640,6 +1701,8 @@ double}.
 @comment math.h
 @comment ISO
 @deftypefunx {long double} nanl (const char *@var{tagp})
+@safety{@mtsafe{glocale}@assafe{glocale}@acsafe{}}
+@c The unsafe-but-ruled-safe locale use comes from strtod.
 The @code{nan} function returns a representation of NaN, provided that
 NaN is supported by the target platform.
 @code{nan ("@var{n-char-sequence}")} is equivalent to
@@ -1674,6 +1737,7 @@ arguments only once.
 @comment math.h
 @comment ISO
 @deftypefn Macro int isgreater (@emph{real-floating} @var{x}, @emph{real-floating} @var{y})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 This macro determines whether the argument @var{x} is greater than
 @var{y}.  It is equivalent to @code{(@var{x}) > (@var{y})}, but no
 exception is raised if @var{x} or @var{y} are NaN.
@@ -1682,6 +1746,7 @@ exception is raised if @var{x} or @var{y} are NaN.
 @comment math.h
 @comment ISO
 @deftypefn Macro int isgreaterequal (@emph{real-floating} @var{x}, @emph{real-floating} @var{y})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 This macro determines whether the argument @var{x} is greater than or
 equal to @var{y}.  It is equivalent to @code{(@var{x}) >= (@var{y})}, but no
 exception is raised if @var{x} or @var{y} are NaN.
@@ -1690,6 +1755,7 @@ exception is raised if @var{x} or @var{y} are NaN.
 @comment math.h
 @comment ISO
 @deftypefn Macro int isless (@emph{real-floating} @var{x}, @emph{real-floating} @var{y})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 This macro determines whether the argument @var{x} is less than @var{y}.
 It is equivalent to @code{(@var{x}) < (@var{y})}, but no exception is
 raised if @var{x} or @var{y} are NaN.
@@ -1698,6 +1764,7 @@ raised if @var{x} or @var{y} are NaN.
 @comment math.h
 @comment ISO
 @deftypefn Macro int islessequal (@emph{real-floating} @var{x}, @emph{real-floating} @var{y})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 This macro determines whether the argument @var{x} is less than or equal
 to @var{y}.  It is equivalent to @code{(@var{x}) <= (@var{y})}, but no
 exception is raised if @var{x} or @var{y} are NaN.
@@ -1706,6 +1773,7 @@ exception is raised if @var{x} or @var{y} are NaN.
 @comment math.h
 @comment ISO
 @deftypefn Macro int islessgreater (@emph{real-floating} @var{x}, @emph{real-floating} @var{y})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 This macro determines whether the argument @var{x} is less or greater
 than @var{y}.  It is equivalent to @code{(@var{x}) < (@var{y}) ||
 (@var{x}) > (@var{y})} (although it only evaluates @var{x} and @var{y}
@@ -1718,6 +1786,7 @@ expression is true if @var{x} or @var{y} are NaN.
 @comment math.h
 @comment ISO
 @deftypefn Macro int isunordered (@emph{real-floating} @var{x}, @emph{real-floating} @var{y})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 This macro determines whether its arguments are unordered.  In other
 words, it is true if @var{x} or @var{y} are NaN, and false otherwise.
 @end deftypefn
@@ -1751,6 +1820,7 @@ perform these operations faster than the equivalent C code.
 @comment math.h
 @comment ISO
 @deftypefunx {long double} fminl (long double @var{x}, long double @var{y})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 The @code{fmin} function returns the lesser of the two values @var{x}
 and @var{y}.  It is similar to the expression
 @smallexample
@@ -1771,6 +1841,7 @@ are NaN, NaN is returned.
 @comment math.h
 @comment ISO
 @deftypefunx {long double} fmaxl (long double @var{x}, long double @var{y})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 The @code{fmax} function returns the greater of the two values @var{x}
 and @var{y}.
 
@@ -1787,6 +1858,7 @@ are NaN, NaN is returned.
 @comment math.h
 @comment ISO
 @deftypefunx {long double} fdiml (long double @var{x}, long double @var{y})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 The @code{fdim} function returns the positive difference between
 @var{x} and @var{y}.  The positive difference is @math{@var{x} -
 @var{y}} if @var{x} is greater than @var{y}, and @math{0} otherwise.
@@ -1804,6 +1876,7 @@ If @var{x}, @var{y}, or both are NaN, NaN is returned.
 @comment ISO
 @deftypefunx {long double} fmal (long double @var{x}, long double @var{y}, long double @var{z})
 @cindex butterfly
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 The @code{fma} function performs floating-point multiply-add.  This is
 the operation @math{(@var{x} @mul{} @var{y}) + @var{z}}, but the
 intermediate result is not rounded to the destination type.  This can
@@ -1933,6 +2006,7 @@ available in three variants, one for each of the three complex types.
 @comment complex.h
 @comment ISO
 @deftypefunx {long double} creall (complex long double @var{z})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 These functions return the real part of the complex number @var{z}.
 @end deftypefun
 
@@ -1945,6 +2019,7 @@ These functions return the real part of the complex number @var{z}.
 @comment complex.h
 @comment ISO
 @deftypefunx {long double} cimagl (complex long double @var{z})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 These functions return the imaginary part of the complex number @var{z}.
 @end deftypefun
 
@@ -1957,6 +2032,7 @@ These functions return the imaginary part of the complex number @var{z}.
 @comment complex.h
 @comment ISO
 @deftypefunx {complex long double} conjl (complex long double @var{z})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 These functions return the conjugate value of the complex number
 @var{z}.  The conjugate of a complex number has the same real part and a
 negated imaginary part.  In other words, @samp{conj(a + bi) = a + -bi}.
@@ -1971,6 +2047,7 @@ negated imaginary part.  In other words, @samp{conj(a + bi) = a + -bi}.
 @comment complex.h
 @comment ISO
 @deftypefunx {long double} cargl (complex long double @var{z})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 These functions return the argument of the complex number @var{z}.
 The argument of a complex number is the angle in the complex plane
 between the positive real axis and a line passing through zero and the
@@ -1989,6 +2066,7 @@ number.  This angle is measured in the usual fashion and ranges from
 @comment complex.h
 @comment ISO
 @deftypefunx {complex long double} cprojl (complex long double @var{z})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 These functions return the projection of the complex value @var{z} onto
 the Riemann sphere.  Values with a infinite imaginary part are projected
 to positive infinity on the real axis, even if the real part is NaN.  If
@@ -2034,6 +2112,16 @@ as well.
 @comment stdlib.h
 @comment ISO
 @deftypefun {long int} strtol (const char *restrict @var{string}, char **restrict @var{tailptr}, int @var{base})
+@safety{@mtsafe{glocale}@assafe{glocale}@acsafe{}}
+@c strtol uses the thread-local pointer to the locale in effect, and
+@c strtol_l loads the LC_NUMERIC locale data from it early on and once,
+@c but if the locale is the global locale, and another thread calls
+@c setlocale in a way that modifies the pointer to the LC_CTYPE locale
+@c category, the behavior of e.g. IS*, TOUPPER will vary throughout the
+@c execution of the function, because they re-read the locale data from
+@c the given locale pointer.  We solved this by documenting setlocale as
+@c MT-Unsafe, but there might be other reasons why it's neither MT- nor
+@c AS-Safe; recheck.
 The @code{strtol} (``string-to-long'') function converts the initial
 part of @var{string} to a signed integer, which is returned as a value
 of type @code{long int}.
@@ -2097,6 +2185,7 @@ There is an example at the end of this section.
 @comment wchar.h
 @comment ISO
 @deftypefun {long int} wcstol (const wchar_t *restrict @var{string}, wchar_t **restrict @var{tailptr}, int @var{base})
+@safety{@mtsafe{glocale}@assafe{glocale}@acsafe{}}
 The @code{wcstol} function is equivalent to the @code{strtol} function
 in nearly all aspects but handles wide character strings.
 
@@ -2106,6 +2195,7 @@ The @code{wcstol} function was introduced in @w{Amendment 1} of @w{ISO C90}.
 @comment stdlib.h
 @comment ISO
 @deftypefun {unsigned long int} strtoul (const char *retrict @var{string}, char **restrict @var{tailptr}, int @var{base})
+@safety{@mtsafe{glocale}@assafe{glocale}@acsafe{}}
 The @code{strtoul} (``string-to-unsigned-long'') function is like
 @code{strtol} except it converts to an @code{unsigned long int} value.
 The syntax is the same as described above for @code{strtol}.  The value
@@ -2124,6 +2214,7 @@ range, or @code{ERANGE} on overflow.
 @comment wchar.h
 @comment ISO
 @deftypefun {unsigned long int} wcstoul (const wchar_t *restrict @var{string}, wchar_t **restrict @var{tailptr}, int @var{base})
+@safety{@mtsafe{glocale}@assafe{glocale}@acsafe{}}
 The @code{wcstoul} function is equivalent to the @code{strtoul} function
 in nearly all aspects but handles wide character strings.
 
@@ -2133,6 +2224,7 @@ The @code{wcstoul} function was introduced in @w{Amendment 1} of @w{ISO C90}.
 @comment stdlib.h
 @comment ISO
 @deftypefun {long long int} strtoll (const char *restrict @var{string}, char **restrict @var{tailptr}, int @var{base})
+@safety{@mtsafe{glocale}@assafe{glocale}@acsafe{}}
 The @code{strtoll} function is like @code{strtol} except that it returns
 a @code{long long int} value, and accepts numbers with a correspondingly
 larger range.
@@ -2149,6 +2241,7 @@ The @code{strtoll} function was introduced in @w{ISO C99}.
 @comment wchar.h
 @comment ISO
 @deftypefun {long long int} wcstoll (const wchar_t *restrict @var{string}, wchar_t **restrict @var{tailptr}, int @var{base})
+@safety{@mtsafe{glocale}@assafe{glocale}@acsafe{}}
 The @code{wcstoll} function is equivalent to the @code{strtoll} function
 in nearly all aspects but handles wide character strings.
 
@@ -2158,12 +2251,14 @@ The @code{wcstoll} function was introduced in @w{Amendment 1} of @w{ISO C90}.
 @comment stdlib.h
 @comment BSD
 @deftypefun {long long int} strtoq (const char *restrict @var{string}, char **restrict @var{tailptr}, int @var{base})
+@safety{@mtsafe{glocale}@assafe{glocale}@acsafe{}}
 @code{strtoq} (``string-to-quad-word'') is the BSD name for @code{strtoll}.
 @end deftypefun
 
 @comment wchar.h
 @comment GNU
 @deftypefun {long long int} wcstoq (const wchar_t *restrict @var{string}, wchar_t **restrict @var{tailptr}, int @var{base})
+@safety{@mtsafe{glocale}@assafe{glocale}@acsafe{}}
 The @code{wcstoq} function is equivalent to the @code{strtoq} function
 in nearly all aspects but handles wide character strings.
 
@@ -2173,6 +2268,7 @@ The @code{wcstoq} function is a GNU extension.
 @comment stdlib.h
 @comment ISO
 @deftypefun {unsigned long long int} strtoull (const char *restrict @var{string}, char **restrict @var{tailptr}, int @var{base})
+@safety{@mtsafe{glocale}@assafe{glocale}@acsafe{}}
 The @code{strtoull} function is related to @code{strtoll} the same way
 @code{strtoul} is related to @code{strtol}.
 
@@ -2182,6 +2278,7 @@ The @code{strtoull} function was introduced in @w{ISO C99}.
 @comment wchar.h
 @comment ISO
 @deftypefun {unsigned long long int} wcstoull (const wchar_t *restrict @var{string}, wchar_t **restrict @var{tailptr}, int @var{base})
+@safety{@mtsafe{glocale}@assafe{glocale}@acsafe{}}
 The @code{wcstoull} function is equivalent to the @code{strtoull} function
 in nearly all aspects but handles wide character strings.
 
@@ -2191,12 +2288,14 @@ The @code{wcstoull} function was introduced in @w{Amendment 1} of @w{ISO C90}.
 @comment stdlib.h
 @comment BSD
 @deftypefun {unsigned long long int} strtouq (const char *restrict @var{string}, char **restrict @var{tailptr}, int @var{base})
+@safety{@mtsafe{glocale}@assafe{glocale}@acsafe{}}
 @code{strtouq} is the BSD name for @code{strtoull}.
 @end deftypefun
 
 @comment wchar.h
 @comment GNU
 @deftypefun {unsigned long long int} wcstouq (const wchar_t *restrict @var{string}, wchar_t **restrict @var{tailptr}, int @var{base})
+@safety{@mtsafe{glocale}@assafe{glocale}@acsafe{}}
 The @code{wcstouq} function is equivalent to the @code{strtouq} function
 in nearly all aspects but handles wide character strings.
 
@@ -2206,6 +2305,7 @@ The @code{wcstouq} function is a GNU extension.
 @comment inttypes.h
 @comment ISO
 @deftypefun intmax_t strtoimax (const char *restrict @var{string}, char **restrict @var{tailptr}, int @var{base})
+@safety{@mtsafe{glocale}@assafe{glocale}@acsafe{}}
 The @code{strtoimax} function is like @code{strtol} except that it returns
 a @code{intmax_t} value, and accepts numbers of a corresponding range.
 
@@ -2222,6 +2322,7 @@ See @ref{Integers} for a description of the @code{intmax_t} type.  The
 @comment wchar.h
 @comment ISO
 @deftypefun intmax_t wcstoimax (const wchar_t *restrict @var{string}, wchar_t **restrict @var{tailptr}, int @var{base})
+@safety{@mtsafe{glocale}@assafe{glocale}@acsafe{}}
 The @code{wcstoimax} function is equivalent to the @code{strtoimax} function
 in nearly all aspects but handles wide character strings.
 
@@ -2231,6 +2332,7 @@ The @code{wcstoimax} function was introduced in @w{ISO C99}.
 @comment inttypes.h
 @comment ISO
 @deftypefun uintmax_t strtoumax (const char *restrict @var{string}, char **restrict @var{tailptr}, int @var{base})
+@safety{@mtsafe{glocale}@assafe{glocale}@acsafe{}}
 The @code{strtoumax} function is related to @code{strtoimax}
 the same way that @code{strtoul} is related to @code{strtol}.
 
@@ -2241,6 +2343,7 @@ See @ref{Integers} for a description of the @code{intmax_t} type.  The
 @comment wchar.h
 @comment ISO
 @deftypefun uintmax_t wcstoumax (const wchar_t *restrict @var{string}, wchar_t **restrict @var{tailptr}, int @var{base})
+@safety{@mtsafe{glocale}@assafe{glocale}@acsafe{}}
 The @code{wcstoumax} function is equivalent to the @code{strtoumax} function
 in nearly all aspects but handles wide character strings.
 
@@ -2250,6 +2353,7 @@ The @code{wcstoumax} function was introduced in @w{ISO C99}.
 @comment stdlib.h
 @comment ISO
 @deftypefun {long int} atol (const char *@var{string})
+@safety{@mtsafe{glocale}@assafe{glocale}@acsafe{}}
 This function is similar to the @code{strtol} function with a @var{base}
 argument of @code{10}, except that it need not detect overflow errors.
 The @code{atol} function is provided mostly for compatibility with
@@ -2259,6 +2363,7 @@ existing code; using @code{strtol} is more robust.
 @comment stdlib.h
 @comment ISO
 @deftypefun int atoi (const char *@var{string})
+@safety{@mtsafe{glocale}@assafe{glocale}@acsafe{}}
 This function is like @code{atol}, except that it returns an @code{int}.
 The @code{atoi} function is also considered obsolete; use @code{strtol}
 instead.
@@ -2267,6 +2372,7 @@ instead.
 @comment stdlib.h
 @comment ISO
 @deftypefun {long long int} atoll (const char *@var{string})
+@safety{@mtsafe{glocale}@assafe{glocale}@acsafe{}}
 This function is similar to @code{atol}, except it returns a @code{long
 long int}.
 
@@ -2331,6 +2437,35 @@ as well.
 @comment stdlib.h
 @comment ISO
 @deftypefun double strtod (const char *restrict @var{string}, char **restrict @var{tailptr})
+@safety{@mtsafe{glocale}@assafe{glocale}@acsafe{}}
+@c Besides the unsafe-but-ruled-safe locale uses, this uses a lot of
+@c mpn, but it's all safe.
+@c
+@c round_and_return
+@c   get_rounding_mode ok
+@c   mpn_add_1 ok
+@c   mpn_rshift ok
+@c   MPN_ZERO ok
+@c   MPN2FLOAT -> mpn_construct_(float|double|long_double) ok
+@c str_to_mpn
+@c   mpn_mul_1 -> umul_ppmm ok
+@c   mpn_add_1 ok
+@c mpn_lshift_1 -> mpn_lshift ok
+@c STRTOF_INTERNAL
+@c   MPN_VAR ok
+@c   SET_MANTISSA ok
+@c   STRNCASECMP ok, wide and narrow
+@c   round_and_return ok
+@c   mpn_mul ok
+@c     mpn_addmul_1 ok
+@c     ... mpn_sub
+@c   mpn_lshift ok
+@c   udiv_qrnnd ok
+@c   count_leading_zeros ok
+@c   add_ssaaaa ok
+@c   sub_ddmmss ok
+@c   umul_ppmm ok
+@c   mpn_submul_1 ok
 The @code{strtod} (``string-to-double'') function converts the initial
 part of @var{string} to a floating-point number, which is returned as a
 value of type @code{double}.
@@ -2416,6 +2551,7 @@ examining @var{errno} and @var{tailptr}.
 @comment stdlib.h
 @comment ISO
 @deftypefunx {long double} strtold (const char *@var{string}, char **@var{tailptr})
+@safety{@mtsafe{glocale}@assafe{glocale}@acsafe{}}
 These functions are analogous to @code{strtod}, but return @code{float}
 and @code{long double} values respectively.  They report errors in the
 same way as @code{strtod}.  @code{strtof} can be substantially faster
@@ -2435,6 +2571,7 @@ These functions have been GNU extensions and are new to @w{ISO C99}.
 @comment stdlib.h
 @comment ISO
 @deftypefunx {long double} wcstold (const wchar_t *@var{string}, wchar_t **@var{tailptr})
+@safety{@mtsafe{glocale}@assafe{glocale}@acsafe{}}
 The @code{wcstod}, @code{wcstof}, and @code{wcstol} functions are
 equivalent in nearly all aspect to the @code{strtod}, @code{strtof}, and
 @code{strtold} functions but it handles wide character string.
@@ -2447,6 +2584,7 @@ C90}.  The @code{wcstof} and @code{wcstold} functions were introduced in
 @comment stdlib.h
 @comment ISO
 @deftypefun double atof (const char *@var{string})
+@safety{@mtsafe{glocale}@assafe{glocale}@acsafe{}}
 This function is similar to the @code{strtod} function, except that it
 need not detect overflow and underflow errors.  The @code{atof} function
 is provided mostly for compatibility with existing code; using
@@ -2474,6 +2612,7 @@ All these functions are defined in @file{stdlib.h}.
 @comment stdlib.h
 @comment SVID, Unix98
 @deftypefun {char *} ecvt (double @var{value}, int @var{ndigit}, int *@var{decpt}, int *@var{neg})
+@safety{@mtunsafe{staticbuf}@assafe{staticbuf}@acsafe{}}
 The function @code{ecvt} converts the floating-point number @var{value}
 to a string with at most @var{ndigit} decimal digits.  The
 returned string contains no decimal point or sign. The first digit of
@@ -2499,6 +2638,7 @@ and sets @var{d} to @code{2} and @var{n} to @code{0}.
 @comment stdlib.h
 @comment SVID, Unix98
 @deftypefun {char *} fcvt (double @var{value}, int @var{ndigit}, int *@var{decpt}, int *@var{neg})
+@safety{@mtunsafe{staticbuf}@assafe{staticbuf}@acsafe{}}
 The function @code{fcvt} is like @code{ecvt}, but @var{ndigit} specifies
 the number of digits after the decimal point.  If @var{ndigit} is less
 than zero, @var{value} is rounded to the @math{@var{ndigit}+1}'th place to the
@@ -2517,6 +2657,9 @@ to @code{fcvt}.
 @comment stdlib.h
 @comment SVID, Unix98
 @deftypefun {char *} gcvt (double @var{value}, int @var{ndigit}, char *@var{buf})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
+@c gcvt calls sprintf, that ultimately calls vfprintf, which malloc()s
+@c args_value if it's too large, but gcvt never exercises this path.
 @code{gcvt} is functionally equivalent to @samp{sprintf(buf, "%*g",
 ndigit, value}.  It is provided only for compatibility's sake.  It
 returns @var{buf}.
@@ -2531,6 +2674,7 @@ functions that take @code{long double} arguments.
 @comment stdlib.h
 @comment GNU
 @deftypefun {char *} qecvt (long double @var{value}, int @var{ndigit}, int *@var{decpt}, int *@var{neg})
+@safety{@mtunsafe{staticbuf}@assafe{staticbuf}@acsafe{}}
 This function is equivalent to @code{ecvt} except that it takes a
 @code{long double} for the first parameter and that @var{ndigit} is
 restricted by the precision of a @code{long double}.
@@ -2539,6 +2683,7 @@ restricted by the precision of a @code{long double}.
 @comment stdlib.h
 @comment GNU
 @deftypefun {char *} qfcvt (long double @var{value}, int @var{ndigit}, int *@var{decpt}, int *@var{neg})
+@safety{@mtunsafe{staticbuf}@assafe{staticbuf}@acsafe{}}
 This function is equivalent to @code{fcvt} except that it
 takes a @code{long double} for the first parameter and that @var{ndigit} is
 restricted by the precision of a @code{long double}.
@@ -2547,6 +2692,7 @@ restricted by the precision of a @code{long double}.
 @comment stdlib.h
 @comment GNU
 @deftypefun {char *} qgcvt (long double @var{value}, int @var{ndigit}, char *@var{buf})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 This function is equivalent to @code{gcvt} except that it takes a
 @code{long double} for the first parameter and that @var{ndigit} is
 restricted by the precision of a @code{long double}.
@@ -2567,6 +2713,7 @@ user-supplied buffer.
 @comment stdlib.h
 @comment GNU
 @deftypefun int ecvt_r (double @var{value}, int @var{ndigit}, int *@var{decpt}, int *@var{neg}, char *@var{buf}, size_t @var{len})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 The @code{ecvt_r} function is the same as @code{ecvt}, except
 that it places its result into the user-specified buffer pointed to by
 @var{buf}, with length @var{len}.  The return value is @code{-1} in
@@ -2578,6 +2725,7 @@ This function is a GNU extension.
 @comment stdlib.h
 @comment SVID, Unix98
 @deftypefun int fcvt_r (double @var{value}, int @var{ndigit}, int *@var{decpt}, int *@var{neg}, char *@var{buf}, size_t @var{len})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 The @code{fcvt_r} function is the same as @code{fcvt}, except that it
 places its result into the user-specified buffer pointed to by
 @var{buf}, with length @var{len}.  The return value is @code{-1} in
@@ -2589,6 +2737,7 @@ This function is a GNU extension.
 @comment stdlib.h
 @comment GNU
 @deftypefun int qecvt_r (long double @var{value}, int @var{ndigit}, int *@var{decpt}, int *@var{neg}, char *@var{buf}, size_t @var{len})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 The @code{qecvt_r} function is the same as @code{qecvt}, except
 that it places its result into the user-specified buffer pointed to by
 @var{buf}, with length @var{len}.  The return value is @code{-1} in
@@ -2600,6 +2749,7 @@ This function is a GNU extension.
 @comment stdlib.h
 @comment GNU
 @deftypefun int qfcvt_r (long double @var{value}, int @var{ndigit}, int *@var{decpt}, int *@var{neg}, char *@var{buf}, size_t @var{len})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
 The @code{qfcvt_r} function is the same as @code{qfcvt}, except
 that it places its result into the user-specified buffer pointed to by
 @var{buf}, with length @var{len}.  The return value is @code{-1} in

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=0808d692007e3c666ed55dd61a80daf14a4cfb10

commit 0808d692007e3c666ed55dd61a80daf14a4cfb10
Author: Alexandre Oliva <aoliva@redhat.com>
Date:   Fri Nov 8 06:08:15 2013 -0200

    MT-, AS- and AC-safety docs: manual/argp.texi
    
    for ChangeLog
    
    	* manual/argp.texi: Document MTASC-safety properties.

diff --git a/manual/argp.texi b/manual/argp.texi
index c9fbe97..22e7b9e 100644
--- a/manual/argp.texi
+++ b/manual/argp.texi
@@ -36,6 +36,35 @@ needed in @code{main}.
 @comment argp.h
 @comment GNU
 @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})
+@safety{@mtunsafe{xguargs, envromt}@asunsafe{asmalloc, asi18n, selfdeadlock, asynconsist}@acunsafe{memleak, lockleak, incansist}}
+@c Optionally alloca()tes standard help options, initializes the parser,
+@c then parses individual args in a loop, and then finalizes.
+@c  parser_init
+@c   calc_sizes ok
+@c    option_is_end ok
+@c   malloc
+@c   parser_convert glocale
+@c    convert_options glocale
+@c     option_is_end ok
+@c     option_is_short ok
+@c      isprint, but locale may change within the loop
+@c     find_long_option ok
+@c   group_parse
+@c    group->parser (from argp->parser)
+@c  parser_parse_next
+@c   getopt_long(_only)_r many issues, same as non_r minus staticbuf
+@c   parser_parse_arg
+@c    group_parse
+@c   parser_parse_opt
+@c    group_parse
+@c    argp_error
+@c    dgettext (bad key error)
+@c  parser_finalize
+@c   group_parse
+@c   fprintf
+@c   dgettext
+@c   arg_state_help
+@c   free
 The @code{argp_parse} function parses the arguments in @var{argv}, of
 length @var{argc}, using the argp parser @var{argp}.  @xref{Argp
 Parsers}.  Passing a null pointer for @var{argp} is the same as using
@@ -660,6 +689,8 @@ parser function.  @xref{Argp Parsing State}.
 @comment argp.h
 @comment GNU
 @deftypefun void argp_usage (const struct argp_state *@var{state})
+@safety{@mtunsafe{staticbuf, envromt, glocale}@asunsafe{asmalloc, asi18n, asynconsist}@acunsafe{memleak, incansist, lockleak}}
+@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 terminate the program
 with @code{exit (argp_err_exit_status)}.  @xref{Argp Global Variables}.
@@ -669,6 +700,13 @@ with @code{exit (argp_err_exit_status)}.  @xref{Argp Global Variables}.
 @comment argp.h
 @comment GNU
 @deftypefun void argp_error (const struct argp_state *@var{state}, const char *@var{fmt}, @dots{})
+@safety{@mtunsafe{staticbuf, envromt, glocale}@asunsafe{asmalloc, asi18n, asynconsist}@acunsafe{memleak, incansist, lockleak}}
+@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
+@c program_invocation_short_name), releases the buffer, then call
+@c argp_state_help with stream and ARGP_HELP_STD_ERR, unlocking the
+@c stream at the end.
 Prints the printf format string @var{fmt} and following args, preceded
 by the program name and @samp{:}, and followed by a @w{@samp{Try @dots{}
 --help}} message, and terminates the program with an exit status of
@@ -679,6 +717,12 @@ by the program name and @samp{:}, and followed by a @w{@samp{Try @dots{}
 @comment argp.h
 @comment GNU
 @deftypefun void argp_failure (const struct argp_state *@var{state}, int @var{status}, int @var{errnum}, const char *@var{fmt}, @dots{})
+@safety{@mtsafe{}@asunsafe{asynconsist, asmalloc}@acunsafe{lockleak, incansist, memleak}}
+@c Lock stream, write out the short program name, vasprintf the optional
+@c formatted message to a buffer, print the buffer prefixed by colon and
+@c blank, release the buffer, call strerror_r with an automatic buffer,
+@c print it out after colon and blank, put[w]c a line break, unlock the
+@c stream, then exit unless ARGP_NO_EXIT.
 Similar to the standard gnu error-reporting function @code{error}, this
 prints the program name and @samp{:}, the printf format string
 @var{fmt}, and the appropriate following args.  If it is non-zero, the
@@ -695,6 +739,141 @@ for options, bad phase of the moon, etc.
 @comment argp.h
 @comment GNU
 @deftypefun void argp_state_help (const struct argp_state *@var{state}, FILE *@var{stream}, unsigned @var{flags})
+@safety{@mtunsafe{staticbuf, envromt, glocale}@asunsafe{asmalloc, asi18n, asynconsist}@acunsafe{memleak, incansist, lockleak}}
+@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) that makes
+@c the whole thing thread-unsafe, reading from the environment for
+@c ARGP_HELP_FMT, accessing the locale object multiple times.
+
+@c _help envromt, staticbuf (uparams), glocale, asmalloc, asi18n, asynconsist, memleak, incansist, lockleak
+@c  dgettext asi18n
+@c  flockfile lockleak
+@c  funlockfile lockleak
+@c  fill_in_uparams envromt, staticbuf (uparams), glocale, asynconsist, asmalloc, lockleak, incansist, memleak
+@c   argp_failure dup (status = errnum = 0)
+@c   atoi dup
+@c  argp_hol asmalloc, memleak
+@c   make_hol asmalloc, memleak
+@c   hol_add_cluster asmalloc, memleak
+@c   hol_append asmalloc, memleak
+@c  hol_set_group ok
+@c   hol_find_entry ok
+@c  hol_sort glocale, asmalloc, memleak
+@c   qsort asmalloc, memleak
+@c    hol_entry_qcmp glocale
+@c     hol_entry_cmp glocale
+@c      group_cmp ok
+@c      hol_cluster_cmp ok
+@c       group_cmp ok
+@c      hol_entry_first_short glocale
+@c       hol_entry_short_iterate [glocale]
+@c        until_short ok
+@c         oshort ok
+@c          isprint ok
+@c      odoc ok
+@c      hol_entry_first_long ok
+@c      canon_doc_option glocale
+@c      tolower dup
+@c  hol_usage glocale, asi18n, asmalloc, memleak
+@c   hol_entry_short_iterate ok
+@c    add_argless_short_opt ok
+@c   argp_fmtstream_printf dup
+@c   hol_entry_short_iterate glocale, asi18n, asmalloc, memleak
+@c    usage_argful_short_opt glocale, asi18n, asmalloc, memleak
+@c     dgettext dup
+@c     argp_fmtstream_printf dup
+@c   hol_entry_long_iterate glocale, asi18n, asmalloc, memleak
+@c    usage_long_opt glocale, asi18n, asmalloc, memleak
+@c     dgettext dup
+@c     argp_fmtstream_printf dup
+@c  hol_help glocale, staticbuf (uparams), asmalloc, asi18n, asynconsist, memleak, incansist, lockleak
+@c   hol_entry_help glocale, staticbuf (uparams), asmalloc, asi18n, asynconsist, memleak, incansist, lockleak
+@c    argp_fmtstream_set_lmargin dup
+@c    argp_fmtstream_wmargin dup
+@c    argp_fmtstream_set_wmargin dup
+@c    comma glocale, asmalloc, asi18n, asynconsist, memleak, incansist, lockleak
+@c     argp_fmtstream_putc dup
+@c     hol_cluster_is_child ok
+@c     argp_fmtstream_wmargin dup
+@c     print_header dup
+@c     argp_fmtstream_set_wmargin dup
+@c     argp_fmtstream_puts dup
+@c     indent_to dup
+@c    argp_fmtstream_putc dup
+@c    arg glocale, asmalloc, memleak
+@c     argp_fmtstream_printf dup
+@c    odoc dup
+@c    argp_fmtstream_puts dup
+@c    argp_fmtstream_printf dup
+@c    print_header glocale, staticbuf (uparams), asmalloc, asi18n, asynconsist, memleak, incansist, lockleak
+@c     dgettext dup
+@c     filter_doc dup
+@c     argp_fmtstream_putc dup
+@c     indent_to dup
+@c     argp_fmtstream_set_lmargin dup
+@c     argp_fmtstream_set_wmargin dup
+@c     argp_fmtstream_puts dup
+@c     free dup
+@c    filter_doc dup
+@c    argp_fmtstream_point dup
+@c    indent_to glocale, asmalloc, asynconsist, memleak, incansist, lockleak
+@c     argp_fmtstream_point dup
+@c     argp_fmtstream_putc dup
+@c   dgettext dup
+@c   filter_doc dup
+@c   argp_fmtstream_putc dup
+@c   argp_fmtstream_puts dup
+@c   free dup
+@c  hol_free asmalloc, memleak
+@c   free dup
+@c  argp_args_levels ok
+@c  argp_args_usage glocale, asi18n, asmalloc, asynconsist, memleak, incansist, lockleak
+@c   dgettext dup
+@c   filter_doc ok
+@c    argp_input ok
+@c    argp->help_filter
+@c   space glocale, asmalloc, asynconsist, memleak, incansist, lockleak
+@c    argp_fmtstream_point dup
+@c    argp_fmtstream_rmargin glocale, asynconsist, incansist, lockleak
+@c     argp_fmtstream_update dup
+@c    argp_fmtstream_putc dup
+@c   argp_fmtstream_write dup
+@c   free dup
+@c  argp_doc glocale, asmalloc, asi18n, asynconsist, memleak, incansist, lockleak
+@c   dgettext asi18n
+@c   strndup asmalloc, memleak
+@c   argp_input dup
+@c   argp->help_filter
+@c   argp_fmtstream_putc glocale, asmalloc, asynconsist, memleak, incansist, lockleak
+@c    argp_fmtstream_ensure dup
+@c   argp_fmtstream_write dup
+@c   argp_fmtstream_puts dup
+@c   argp_fmtstream_point glocale, asynconsist, incansist, lockleak
+@c    argp_fmtstream_update dup
+@c   argp_fmtstream_lmargin dup
+@c   free dup
+@c  argp_make_fmtstream asmalloc, memleak
+@c  argp_fmtstream_free glocale, asmalloc, asynconsist, memleak, incansist, lockleak
+@c   argp_fmtstream_update glocale, asynconsist, incansist, lockleak
+@c    put[w]c_unlocked dup
+@c    isblank in loop glocale
+@c    fxprintf lockleak
+@c   fxprintf lockleak
+@c   free dup
+@c  argp_fmtstream_set_wmargin glocale, asynconsist, incansist, lockleak
+@c   argp_fmtstream_update dup
+@c  argp_fmtstream_printf glocale, asmalloc, memleak
+@c   argp_fmtstream_ensure dup
+@c   vsnprintf dup
+@c  argp_fmtstream_set_lmargin glocale, asynconsist, incansist, lockleak
+@c   argp_fmtstream_update dup
+@c  argp_fmtstream_puts glocale, asmalloc, asynconsist, memleak, incansist, lockleak
+@c   argp_fmtstream_write glocale, asmalloc, asynconsist, memleak, incansist, lockleak
+@c    argp_fmtstream_ensure glocale, asmalloc, asynconsist, memleak, incansist, lockleak
+@c     argp_fmtstream_update dup
+@c     fxprintf lockleak
+@c     realloc asmalloc, memleak
 Outputs a help message for the argp parser referred to by @var{state},
 to @var{stream}.  The @var{flags} argument determines what sort of help
 message is produced.  @xref{Argp Help Flags}.
@@ -928,6 +1107,8 @@ program options, argp offers the @code{argp_help} interface.
 @comment argp.h
 @comment GNU
 @deftypefun void argp_help (const struct argp *@var{argp}, FILE *@var{stream}, unsigned @var{flags}, char *@var{name})
+@safety{@mtunsafe{staticbuf, envromt, glocale}@asunsafe{asmalloc, asi18n, asynconsist}@acunsafe{memleak, incansist, lockleak}}
+@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
 @var{flags}.

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=36d4952f6a38f469c1d88dc69ddaa1a743a5f86e

commit 36d4952f6a38f469c1d88dc69ddaa1a743a5f86e
Author: Alexandre Oliva <aoliva@redhat.com>
Date:   Fri Nov 8 06:08:14 2013 -0200

    Multi Thread, Async Signal and Async Cancel safety documentation: intro
    
    for  ChangeLog
    
    	* manual/macros.texi: Introduce macros to document multi
    	thread, asynchronous signal and asynchronous cancellation
    	safety properties.
    	* manual/intro.texi: Introduce the properties themselves.

diff --git a/manual/intro.texi b/manual/intro.texi
index deaf089..c87f190 100644
--- a/manual/intro.texi
+++ b/manual/intro.texi
@@ -172,6 +172,493 @@ pattern matching facilities (@pxref{Pattern Matching}).
 @comment <wordexp.h> (not yet implemented)
 @comment confstr
 
+The safety properties of @glibcadj{} functions, documented as MT-, AS-
+and AC- -Safe and -Unsafe are assessed according to the criteria set
+forth in the POSIX standard for Thread-, Async-Signal- and Async-Cancel-
+safety.
+
+Intuitive definitions of these properties, attempting to capture the
+meaning of the standard definitions, follow:
+
+@itemize @bullet
+
+@item
+@cindex MT-Safe
+MT-Safe functions are safe to call in the presence of other threads.  MT
+stands for Multi Thread.
+
+@item
+@cindex AS-Safe
+AS-Safe functions are safe to call from asynchronous signal handlers.
+AS stands for Asynchronous Signal.
+
+@item
+@cindex AC-Safe
+AC-Safe functions are safe to call when asynchronous cancellation is
+enabled.  AC stands for Asynchronous Cancellation.
+
+@item
+@cindex MT-Unsafe
+@cindex AS-Unsafe
+@cindex AC-Unsafe
+MT-Unsafe, AS-Unsafe, AC-Unsafe functions are not safe to call within
+the contexts described above: they may cause deviations from the
+specification in the behavior of the calls themselves, or of any other
+concurrent, ongoing or subsequent calls.
+
+Functions not explicitly documented as Safe should be regarded as
+Unsafe.
+
+@end itemize
+
+By ``safe to call'', we mean that, as long as the program does not
+invoke undefined or unspecified behavior, the called functions will
+behave as documented, and they will not cause any other functions to
+deviate from their documented behavior.
+
+Although we strive to abide by the standards, in some cases our
+implementation is safe even when the standard does not demand safety,
+and in other cases our implementation does not meet the standard safety
+requirements.  At this point, we document the result of an assessment of
+the properties of our implementation, so the safety documentation in
+this manual is not to be regarded as a promise of future behavior: in
+future releases, functions that are documented as safe may become
+unsafe, and safety constraints may be removed or introduced.  We
+envision turning the results of the assessment into a set of promises as
+stable as our interfaces, but we are not there yet.
+
+When a function is safe to call only under certain constraints, we will
+add keywords to the safety notes whose meanings are defined as follows:
+
+@itemize @bullet
+
+@item @code{glocale}
+@cindex glocale
+
+In threads that have not overridden the thread-local locale object by
+calling @code{uselocale}, calling functions annotated with
+@code{glocale} concurrently with @code{setlocale} may cause the
+functions to behave in ways that do not correspond to either the
+previous or the subsequent global locale.
+
+Although the @code{setlocale} function modifies the global locale object
+while holding a lock, @code{glocale}-annotated functions may access this
+global object multiple times, without any measures to ensure it does not
+change while it is in use.
+
+Each of these unprotected uses will use either the previous or the
+subsequent locale information, so they will not cause crashes or access
+to uninitialized, unmapped or recycled memory.  However, since some
+cases use cached locale information while others access the effective
+locale object anew, concurrent changes to the global locale object may
+cause these functions to behave in ways that they could not behave
+should the execution of @code{setlocale} and of the so-annotated
+functions be atomic, or even should @code{setlocale} alone be atomic.
+
+The @code{glocale} constraint indicates functions are only safe to call
+if the effective thread-local locale is not the global locale object
+(because it was overridden with @code{uselocale}).  Failing that,
+@code{setlocale} should not be called while these functions are active.
+
+
+@item @code{envromt}
+@cindex envromt
+
+Functions marked with @code{envromt} access the environment with
+@code{getenv} or similar, requiring the environment to be effectively
+read-only for MT-Safe operation.
+
+Environment-modifying functions do not protect in any way against
+concurrent modifications or access.  Calling @code{envromt}-marked
+functions concurrently with @code{setenv}, @code{putenv},
+@code{unsetenv} or direct modifications of the global environment data
+structures is ill-advised; external concurrency control must be
+introduced by callers of these environment-modifying and
+@code{envromt}-marked functions.
+
+Functions that modify the environment are also marked with
+@code{envromt}, but they are not MT-Safe for the reasons above.  Since
+all environment-modifying functions are MT-Unsafe, functions that only
+access the environment are marked as MT-Safe when no other safety issue
+applies.
+
+
+@item @code{oncesafe}
+@cindex oncesafe
+
+Functions marked with @code{oncesafe} use the internal @code{libc_once}
+machinery or similar to initialize internal data structures.
+
+If a signal handler interrupts such an initializer, and calls any
+function that also performs @code{libc_once} initialization, it will
+deadlock if the thread library is linked in.
+
+Furthermore, if an initializer is partially complete before it is
+canceled or interrupted by a signal whose handler requires the same
+initialization, some or all of the initialization may be performed more
+than once, leaking resources or even result in corrupt internal data
+structures.
+
+Applications that need to call functions marked with @code{oncesafe}
+should ensure the initialization is performed before configuring signal
+handlers or enabling cancellation, so that the AS- and AC-Safety issues
+related with @code{libc_once} do not arise.
+
+
+@item @code{1stcall}
+@cindex 1stcall
+
+Functions marked with @code{1stcall} perform MT-unsafe initialization
+when they are first called.  
+
+Calling such a function at least once in single-threaded mode removes
+this specific cause for the function to be regarded as MT-Unsafe.  If no
+other cause for that remains, the function can then be safely called
+after other threads are started.
+
+
+@item @code{uunguard}
+@cindex uunguard
+
+Functions marked with @code{uunguard} modify non-atomically arguments or
+global objects that other functions access without synchronization.  To
+ensure MT- and AS-Safe behavior, callers should refrain from calling
+so-marked functions concurrently with readers of those objects.  A
+consequence of regarding modifiers of these objects as unsafe is that
+the covered objects can be regarded as constant (subject to the
+observation of safety constraints), so that all readers can be
+considered safe in this regard.
+
+Unguarded users of the global locale object modified by @code{setlocale}
+are marked with @code{glocale}.
+
+Unguarded users of the @code{printf} extension objects modified by
+@code{register_printf_function} are the entire family of printf
+functions.
+
+Unguarded users of file streams configured with @code{__fsetlocking} for
+locking by the caller are the entire family of stdio functions.
+
+
+@item @code{xguargs}
+@cindex xguargs
+
+Functions marked with @code{xguargs} may use or modify objects passed
+(indirectly) as arguments, without any guards to guarantee consistency.
+To ensure MT- and AS-Safe behavior, callers must ensure that the objects
+passed in are not accessed or modified concurrently by other threads or
+signal handlers.
+
+This mark is only applied with regard to an object when the
+@code{uunguard} mark is not applied because of the same object, and the
+object is opaque or not intended to be modified by code outside of
+@theglibc{}.  The rationale is that, for such an object, there could be
+a reasonable (but unsatisfied) expectation that the library would take
+care of synchronization to modify the object.
+
+Strings, structs and other object types whose members are meant to be
+modified by users are @emph{not} marked with @code{xguargs}.
+User-initiated inspection and modification are already constrained by
+the standard synchronization requirements, plus any other type- or
+object-specific additional requirements, such as user-initiated locking
+of streams configured to avoid internal locking.  (File streams happen
+to be opaque types, but the principle stands.)  Users must satisfy these
+requirements regardless of whether modifications are coded by users or
+the library, so the mark would be redundant.  The mark, when present,
+clarifies that users remain responsible for satisfying any
+synchronization requirements when calling the marked function, because
+the library will not take care of them on its own.
+
+
+@item @code{tempchwd}
+@cindex tempchwd
+
+Functions marked with @code{tempchwd} may temporarily change the current
+working directory during their execution, which may cause relative
+pathnames to be resolved in unexpected ways in other threads or within
+asynchronous signal or cancellation handlers.
+
+This is not enough of a reason to mark so-marked functions as MT-Unsafe,
+but when this behavior is optional (e.g., @code{nftw} with
+@code{FTW_CHDIR}), avoiding the option in multi-threaded programs may be
+a good alternative to using full pathnames or file descriptor-relative
+(e.g. @code{openat}) system calls.
+
+
+@item @code{tempsig}
+@cindex tempsig
+
+Functions marked with @code{tempsig} may temporarily install signal
+handlers for internal purposes, which may interfere with other uses of
+those signals.  
+
+This makes such functions MT-Unsafe and AS-Unsafe to begin with.  If
+this note appears as an AC-Safety issue, however, the problem is more
+complex: the temporarily-installed signal handler may remain in place if
+the thread is cancelled.  Safety for all these situations can be
+achieved by refraining from using the specific signals while calling the
+function.
+
+
+@item @code{tempterm}
+@cindex tempterm
+
+Functions marked with @code{tempterm} may temporarily change the
+terminal settings.
+
+This would not be enough of a reason to mark so-marked functions as
+MT-Unsafe, but the recommended mode to modify terminal settings is to
+call @code{tcgetattr}, modify some flags, and then call
+@code{tcsetattr}.  Functions marked with @code{tempterm} do that, so
+they leave a window in which changes made by other threads are lost.
+
+It is thus advisable for applications using the terminal to avoid
+concurrent interactions with it, more so if they expect different
+terminal modes.
+
+If this mark appears as an AC-Safety note, it means the function may
+also fail to restore the original terminal mode in case of asynchronous
+cancellation.
+
+
+@item @code{stimer}
+@cindex stimer
+
+Functions marked with @code{stimer} use the @code{alarm} function or
+similar to set a time-out for a system call or a long-running operation.
+In a multi-threaded program, there is a risk that the time-out signal
+will be delivered to a different thread, thus failing to interrupt the
+intended thread.
+
+Keeping @code{SIGALRM} blocked on all threads, and refraining from
+concurrently calling functions that may set up such timers, is the only
+way to avoid this safety issue.
+
+
+@end itemize
+
+
+Additional safety issues that cannot be worked around by constraining
+the program (other than by refraining from calling the affected
+functions) are also documented with keywords, whose meanings are defined
+as follows:
+
+@itemize @bullet
+
+@item @code{staticbuf}
+@cindex staticbuf
+
+Functions annotated with @code{staticbuf} use internal objects in ways
+that may cause concurrent calls to interfere destructively.  In this
+case internal does not mean the objects are not exposed to callers, just
+that they are not supplied by callers (contrast with the @code{uunguard}
+and @code{xguargs} keywords).
+
+These functions are all MT-Unsafe and AS-Unsafe.  However, many of them
+offer reentrant variants for MT-Safe and, in some cases, AS-Safe use.
+
+In many of these cases, the static buffer is only used to hold a return
+value; in a few of these, such as @code{tmpnam}, the use of the internal
+buffer can be avoided by passing the buffer as an argument, which makes
+the call MT-Safe and AS-Safe.
+
+
+@item @code{asi18n}
+@cindex asi18n
+
+Functions marked with @code{asi18n} use internationalization functions
+(@code{gettext}), which brings in a number of dependencies and issues
+yet to be documented.
+
+
+@item @code{shlimb}
+@cindex shlimb
+
+Functions marked with @code{shlimb} use the dynamic loader to bring in
+additional code modules.  This involves opening files, mapping them into
+memory, allocating additional memory, resolving symbols, applying
+relocations and more, all of this while holding internal dynamic loader
+locks.
+
+The locks are enough for these functions to be AS- and AC-Unsafe, but
+other issues may arise.
+
+
+@item @code{fdleak}
+@cindex fdleak
+
+Functions annotated with @code{fdleak} may leak file descriptors if
+asynchronous thread cancellation interrupts their execution.
+
+Functions that allocate or deallocate file descriptors will generally be
+marked as such, because even if they attempted to protect the file
+descriptor allocation and deallocation with cleanup regions, allocating
+a new descriptor and storing its number where the cleanup region could
+release it cannot be performed as a single atomic operation, just like
+releasing it and taking it out of the data structure normally
+responsible for releasing it cannot be performed atomically, always
+leaving a window in which the descriptor cannot be released because it
+was not stored in the cleanup handler argument yet, or in which it was
+already taken out of it before releasing it in the normal flow (we
+cannot keep it there because, in case of cancellation, we would not be
+able to tell whether it was already released, and the same number could
+have been already assigned to another descriptor by another thread, so
+we could not just release it again).
+
+Such leaks could be internally avoided, with some performance penalty,
+by temporarily disabling asynchronous thread cancellation.  However,
+since callers of allocation or deallocation functions would have to do
+this themselves, to avoid the same sort of leak in their own layer, it
+makes more sense for the library to assume they are taking care of it
+than to impose a performance penalty that is redundant when the problem
+is solved in upper layers, and insufficient when it is not.
+
+This remark by itself does not cause a function to be regarded as
+AC-Unsafe.  However, cumulative effects of such leaks may pose a
+problem for some programs.  If this is the case, suspending asynchronous
+cancellation for the duration of calls to such functions is recommended.
+
+
+@item @code{memleak}
+@cindex memleak
+
+Functions annotated with @code{memleak} may leak memory if asynchronous
+thread cancellation interrupts their execution.
+
+The problem is similar to that of file descriptors: there is no atomic
+interface to allocate memory and store its address in the argument to a
+cleanup handler, or to release it and remove its address from that
+argument, without at least temporarily disabling asynchronous
+cancellation, which these functions do not do.
+
+This remark does not by itself cause a function to be regarded as
+generally AC-Unsafe.  However, cumulative effects of such leaks may be
+severe enough for some programs that disabling asynchronous cancellation
+for the duration of calls to such functions may be required.
+
+
+@item @code{lockleak}
+@cindex lockleak
+
+Functions annotated with @code{lockleak} may leak locks if asynchronous
+thread cancellation interrupts their execution.
+
+While the problem is similar to that of file descriptors, in that there
+is not any atomic interface to lock and take note of the need for
+unlocking in a cleanup, or to unlock and take note that there is no
+longer such a need, the problem posed by lock leaks is far more serious:
+when a file descriptor or a piece of memory is leaked, it becomes
+inaccessible and subsequent attempts to allocate a file descriptor or
+some memory will just use another resource.  However, once a lock is
+left taken, attempts to take that lock will block indefinitely.
+(Recursive locks will only block other threads, and read locks will only
+block writer threads, but the point still holds in general).
+
+For the reasons above, functions that leak locks are all AC-Unsafe.
+
+
+@item @code{selfdeadlock}
+@cindex selfdeadlock
+
+Functions marked with @code{selfdeadlock} take a non-recursive lock to
+ensure MT-Safety while modifying data structures guarded by the lock.
+
+If such a function is called by a signal handler that interrupted
+another such function that took the lock, the result is a deadlock.
+
+Blocking asynchronous signal delivery while calling such functions is
+the only safe way to avoid a deadlock if any signal handler might need
+to call them.
+
+
+@item @code{asynconsist}
+@cindex asynconsist
+
+Functions marked with @code{asynconsist} take a recursive lock to ensure
+MT-Safety while accessing or modifying data structures guarded by the
+lock.
+
+If such a function is called by a signal handler that interrupted
+another such function that took the lock, both may misbehave for
+observing inconsistent (partially updated or cached) data structures.
+
+Blocking asynchronous signal delivery while calling such functions is
+the only safe way to avoid the misbehavior that may ensue if any signal
+handler might need to call them.
+
+
+@item @code{asmalloc}
+@cindex asmalloc
+
+This is a sub-case of @code{asynconsist}.  Functions marked with
+@code{asmalloc} perform memory allocation or deallocation with the
+@code{malloc}/@code{free} family of functions.
+
+If heap management functions are interrupted by asynchronous signals,
+and the signal handlers attempt to perform memory allocation or
+deallocation of their own, they may encounter heap data structures in a
+partially updated state, and the interrupted calls may malfunction
+because of the changes made within the signal handler.
+
+The @code{asmalloc} mark implies @code{selfdeadlock} (AS-unsafe) and
+@code{lockleak} (AC-Unsafe).
+
+
+@item @code{incansist}
+@cindex incansist
+
+Functions marked with @code{incansist} modify data structures in a
+non-atomic way.
+
+If such a function is asynchronously cancelled, it may leave the data
+structure in a partially updated, inconsistent state.  Subsequent uses
+of the data structure may misbehave.
+
+Disabling asynchronous cancellation while calling such functions is the
+only safe way to avoid the misbehavior if the thread is cancelled while
+the function is running.
+
+@c A special case, probably not worth documenting separately, involves
+@c reallocing, or even freeing pointers.  Any case involving free could
+@c be easily turned into an ac-safe memleak by resetting the pointer
+@c before releasing it; I don't think we have any case that calls for
+@c this sort of fixing.  Fixing the realloc cases would require a new
+@c interface: instead of @code{ptr=realloc(ptr,size)} we'd have to
+@c introduce @code{acsafe_realloc(&ptr,size)} that would modify ptr
+@c before releasing the old memory.  The ac-unsafe realloc could be
+@c implemented in terms of an internal interface with this semantics
+@c (say __acsafe_realloc), but since realloc can be overridden, the
+@c function we call to implement realloc should not be this internal
+@c interface, but another internal interface that calls __acsafe_realloc
+@c if realloc was not overridden, and calls the overridden realloc with
+@c async cancel disabled.  --lxoliva
+
+
+@item @code{uplugin}
+@cindex uplugin
+
+Functions annotated with @code{uplugin} may run code from plugins that
+may be external to @theglibc{}.  Such plug-in functions are assumed to
+be MT-Safe, AS-Unsafe and AC-Unsafe.
+
+Examples of such plugins are stack unwinding libraries and nss
+back-ends.
+
+
+@item @code{unposix}
+@cindex unposix
+
+This remark indicates our safety documentation is known to differ from
+the requirements set by the POSIX standard.  For example, POSIX does not
+require a function to be Safe, but our implementation is Safe, or
+vice-versa.
+
+For the time being, the absence of this remark does not imply the safety
+properties we documented are identical to those mandated by POSIX for
+the corresponding functions.
+
+@end itemize
+
 
 @node Berkeley Unix, SVID, POSIX, Standards and Portability
 @subsection Berkeley Unix
diff --git a/manual/macros.texi b/manual/macros.texi
index daaf1c0..6955f32 100644
--- a/manual/macros.texi
+++ b/manual/macros.texi
@@ -47,4 +47,46 @@ GNU/Hurd systems
 GNU/Linux systems
 @end macro
 
+@c Document a function as thread safe.
+@macro mtsafe {comments}
+| MT-Safe \comments\
+|
+@end macro
+@c Document a function as thread unsafe.
+@macro mtunsafe {comments}
+| MT-Unsafe \comments\
+|
+@end macro
+@c Document a function as safe for use in asynchronous signal handlers.
+@macro assafe {comments}
+| AS-Safe \comments\
+|
+@end macro
+@c Document a function as unsafe for use in asynchronous signal
+@c handlers.  This distinguishes unmarked functions, for which this
+@c property has not been assessed, from those that have been analyzed.
+@macro asunsafe {comments}
+| AS-Unsafe \comments\
+|
+@end macro
+@c Document a function as safe for use when asynchronous cancellation is
+@c enabled.
+@macro acsafe {comments}
+| AC-Safe \comments\
+|
+@end macro
+@c Document a function as unsafe for use when asynchronous cancellation
+@c is enabled.  This distinguishes unmarked functions, for which this
+@c property has not been assessed, from those that have been analyzed.
+@macro acunsafe {comments}
+| AC-Unsafe \comments\
+|
+@end macro
+@c Format the thread and async safety properties of a function.
+@macro safety {notes}
+\notes\
+
+
+@end macro
+
 @end ifclear

-----------------------------------------------------------------------


hooks/post-receive
-- 
GNU C Library master sources


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]