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-777-gaea9b9a


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  aea9b9a2855546d2476d31f8d400206b05d552f8 (commit)

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

commit aea9b9a2855546d2476d31f8d400206b05d552f8
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..9ccf78c 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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @acsmem{} @acsfd{} @aculock{}}}
+@c initgroups @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c  sysconf(_SC_NGROUPS_MAX) dup @acsfd
+@c  MIN dup ok
+@c  malloc @ascuheap @acsmem
+@c  internal_getgrouplist @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c   nscd_getgrouplist @ascuheap @acsfd @acsmem
+@c    nscd_get_map_ref dup @ascuheap @acsfd @acsmem
+@c    nscd_cache_search dup ok
+@c    nscd_open_socket dup @acsfd
+@c    realloc dup @ascuheap @acsmem
+@c    readall dup ok
+@c    memcpy dup ok
+@c    close_not_cancel_no_status dup @acsfd
+@c    nscd_drop_map_ref dup @ascuheap @acsmem
+@c    nscd_unmap dup @ascuheap @acsmem
+@c   nss_database_lookup dup @mtslocale @ascuheap @asulock @acucorrupt @acsmem @acsfd @aculock
+@c   nss_lookup_function dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c   compat_call @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c    sysconf(_SC_GETGR_R_SIZE_MAX) ok
+@c    nss_lookup_function dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c    *getgrent_fct @ascuplugin
+@c    *setgrent_fct @ascuplugin
+@c    *endgrent_fct @ascuplugin
+@c    realloc dup @ascuheap @acsmem
+@c    free dup @ascuheap @acsmem
+@c   *initgroups_dyn_fct @ascuplugin
+@c   nss_next_action dup ok
+@c  setgroups dup ok
+@c  free dup @ascuheap @acsmem
 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{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @acsmem{} @acsfd{} @aculock{}}}
+@c getgrouplist @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c  MAX dup ok
+@c  malloc dup @ascuheap @acsmem
+@c  internal_getgrouplist dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c  memcpy dup ok
+@c  free dup @ascuheap @acsmem
 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{@prelim{}@mtunsafe{@mtasurace{:getlogin} @mtasurace{:utent} @mtasusig{:ALRM} @mtutimer{} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
+@c getlogin (linux) @mtasurace:getlogin @mtasurace:utent @mtascusig:ALRM @mtutimer @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c  getlogin_r_loginuid dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c  getlogin_fd0 (unix) @mtasurace:getlogin @mtasurace:utent @mtascusig:ALRM @mtutimer @ascuheap @asulock @aculock @acsfd @acsmem
+@c    uses static buffer name => @mtasurace:getlogin
+@c   ttyname_r dup @ascuheap @acsmem @acsfd
+@c   strncpy dup ok
+@c   setutent dup @mtasurace:utent @asulock @aculock @acsfd
+@c   getutline_r dup @mtasurace:utent @mtascusig:ALRM @mtutimer @asulock @aculock @acsfd
+@c   endutent dup @mtasurace:utent @asulock @aculock
+@c   libc_lock_unlock dup ok
+@c   strlen dup ok
+@c   memcpy dup ok
+@c
+@c getlogin_r (linux) @mtasurace:utent @mtascusig:ALRM @mtutimer @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c  getlogin_r_loginuid @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c   open_not_cancel_2 dup @acsfd
+@c   read_not_cancel dup ok
+@c   close_not_cancel_no_status dup @acsfd
+@c   strtoul @mtslocale @mtslocale
+@c   getpwuid_r dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c   realloc dup @asulock @aculock @acsfd @acsmem
+@c   strlen dup ok
+@c   memcpy dup ok
+@c   free dup @asulock @aculock @acsfd @acsmem
+@c  getlogin_r_fd0 (unix) @mtasurace:utent @mtascusig:ALRM @mtutimer @ascuheap @asulock @aculock @acsmem @acsfd
+@c   ttyname_r dup @ascuheap @acsmem @acsfd
+@c   strncpy dup ok
+@c   libc_lock_lock dup @asulock @aculock
+@c   *libc_utmp_jump_table->setutent dup @mtasurace:utent @acsfd
+@c   *libc_utmp_jump_table->getutline_r dup @mtasurace:utent @mtascusig:ALRM @mtutimer
+@c   *libc_utmp_jump_table->endutent dup @mtasurace:utent @asulock @aculock
+@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{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
+@c cuserid @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c  geteuid dup ok
+@c  getpwuid_r dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@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{@prelim{}@mtunsafe{@mtasurace{:utent}}@asunsafe{@asulock{}}@acunsafe{@aculock{} @acsfd{}}}
+@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 @mtasurace:utent @asulock @aculock @acsfd
+@c  libc_lock_lock dup @asulock @aculock
+@c  *libc_utmp_jump_table->setutent @mtasurace:utent @acsfd
+@c   setutent_unknown @mtasurace:utent @acsfd
+@c    *libc_utmp_file_functions.setutent = setutent_file @mtasurace:utent @acsfd
+@c      open_not_cancel_2 dup @acsfd
+@c      fcntl_not_cancel dup ok
+@c      close_not_cancel_no_status dup @acsfd
+@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{@prelim{}@mtunsafe{@mtuinit{} @mtasurace{:utent} @mtasurace{:utentbuf} @mtasusig{:ALRM} @mtutimer{}}@asunsafe{@ascuheap{} @asulock{} @mtutimer{}}@acunsafe{@acusig{:ALRM} @mtutimer{} @aculock{} @acsfd{} @acsmem{}}}
+@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 @mtuinit @mtasurace:utent @mtasurace:utentbuf @mtascusig:ALRM @mtutimer @ascuheap @asulock @aculock @acsfd @acsmem
+@c  malloc @asulock @aculock @acsfd @acsmem
+@c  getutent_r dup @mtasurace:utent @mtascusig:ALRM @mtutimer @asulock @aculock @acsfd
+
 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{@prelim{}@mtunsafe{@mtasurace{:utent}}@asunsafe{@asulock{}}@acunsafe{@aculock{} @acsfd{}}}
+@c endutent @mtasurace:utent @asulock @aculock @acsfd
+@c  libc_lock_lock dup @asulock @aculock
+@c  *libc_utmp_jump_table->endutent @mtasurace:utent @acsfd
+@c   endutent_unknown ok
+@c   endutent_file @mtasurace:utent @acsfd
+@c    close_not_cancel_no_status dup @acsfd
+@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{@prelim{}@mtunsafe{@mtuinit{} @mtasurace{:utent} @mtasusig{:ALRM} @mtutimer{}}@asunsafe{@asulock{} @ascuheap{} @mtutimer{}}@acunsafe{@acusig{:ALRM} @mtutimer{} @aculock{} @acsmem{} @acsfd{}}}
+@c Same caveats as getutline.
+@c
+@c getutid @mtuinit @mtasurace:utent @mtascusig:ALRM @mtutimer @ascuheap @asulock @aculock @acsmem @acsfd
+@c   uses a static buffer malloced on the first call
+@c  malloc dup @ascuheap @acsmem
+@c  getutid_r dup @mtasurace:utent @mtascusig:ALRM @mtutimer @asulock @aculock @acsfd
 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{@prelim{}@mtunsafe{@mtuinit{} @mtasurace{:utent} @mtasusig{:ALRM} @mtutimer{}}@asunsafe{@ascuheap{} @asulock{} @mtutimer{}}@acunsafe{@acusig{:ALRM} @mtutimer{} @aculock{} @acsfd{} @acsmem{}}}
+@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 @mtuinit @mtasurace:utent @mtascusig:ALRM @mtutimer @ascuheap @asulock @aculock @acsfd @acsmem
+@c  malloc @asulock @aculock @acsfd @acsmem
+@c  getutline_r dup @mtasurace:utent @mtascusig:ALRM @mtutimer @asulock @aculock @acsfd
 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{@prelim{}@mtunsafe{@mtasurace{:utent} @mtasusig{:ALRM} @mtutimer{}}@asunsafe{@asulock{} @mtutimer{}}@acunsafe{@acusig{:ALRM} @mtutimer{} @aculock{} @acsfd{}}}
+@c pututline @mtasurace:utent @mtascusig:ALRM @mtutimer @asulock @aculock @acsfd
+@c  libc_lock_lock dup @asulock @aculock
+@c  *libc_utmp_jump_table->pututline @mtuasrace:utent @mtascusig:ALRM @mtutimer @acsfd
+@c   pututline_unknown @mtasurace:utent @acsfd
+@c    setutent_unknown dup @mtasurace:utent @acsfd
+@c   pututline_file @mtascusig:ALRM @mtutimer @acsfd
+@c    TRANSFORM_UTMP_FILE_NAME ok
+@c     strcmp dup ok
+@c     acesss dup ok
+@c    open_not_cancel_2 dup @acsfd
+@c    fcntl_not_cancel dup ok
+@c    close_not_cancel_no_status dup @acsfd
+@c    llseek dup ok
+@c    dup2 dup ok
+@c    utmp_equal dup ok
+@c    internal_getut_r dup @mtascusig:ALRM @mtutimer
+@c    LOCK_FILE dup @mtascusig:ALRM @mtutimer
+@c    LOCKING_FAILED dup ok
+@c    ftruncate64 dup ok
+@c    write_not_cancel dup ok
+@c    UNLOCK_FILE dup @mtutimer
+@c  libc_lock_unlock dup @aculock
 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{@prelim{}@mtunsafe{@mtasurace{:utent} @mtasusig{:ALRM} @mtutimer{}}@asunsafe{@asulock{} @mtutimer{}}@acunsafe{@acusig{:ALRM} @mtutimer{} @aculock{} @acsfd{}}}
+@c getutent_r @mtasurace:utent @mtascusig:ALRM @mtutimer @asulock @aculock @acsfd
+@c  libc_lock_lock dup @asulock @aculock
+@c  *libc_utmp_jump_table->getutent_r @mtasurace:utent @mtascusig:ALRM @mtutimer @acsfd
+@c   getutent_r_unknown @mtasurace:utent @acsfd
+@c    setutent_unknown dup @mtasurace:utent @acsfd
+@c   getutent_r_file @mtasurace:utent @mtascusig:ALRM @mtutimer
+@c    LOCK_FILE @mtascusig:ALRM @mtutimer
+@c     alarm dup @mtutimer
+@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 @mtutimer
+@c     fcntl_not_cancel dup ok
+@c     alarm dup @mtutimer
+@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{@prelim{}@mtunsafe{@mtasurace{:utent} @mtasusig{:ALRM} @mtutimer{}}@asunsafe{@asulock{} @mtutimer{}}@acunsafe{@acusig{:ALRM} @mtutimer{} @aculock{} @acsfd{}}}
+@c getutid_r @mtasurace:utent @mtascusig:ALRM @mtutimer @asulock @aculock @acsfd
+@c  libc_lock_lock dup @asulock @aculock
+@c  *libc_utmp_jump_table->getutid_r @mtasurace:utent @mtascusig:ALRM @mtutimer @acsfd
+@c   getutid_r_unknown @mtasurace:utent @acsfd
+@c    setutent_unknown dup @mtasurace:utent @acsfd
+@c   getutid_r_file @mtascusig:ALRM @mtutimer
+@c    internal_getut_r @mtascusig:ALRM @mtutimer
+@c     LOCK_FILE dup @mtascusig:ALRM @mtutimer
+@c     LOCKING_FAILED dup ok
+@c     read_not_cancel dup ok
+@c     utmp_equal ok
+@c      strncmp dup ok
+@c     UNLOCK_FILE dup @mtutimer
+@c    memcpy dup ok
+@c  libc_lock_unlock dup @aculock
 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{@prelim{}@mtunsafe{@mtasurace{:utent} @mtasusig{:ALRM} @mtutimer{}}@asunsafe{@asulock{} @mtutimer{}}@acunsafe{@acusig{:ALRM} @mtutimer{} @aculock{} @acsfd{}}}
+@c getutline_r @mtasurace:utent @mtascusig:ALRM @mtutimer @asulock @aculock @acsfd
+@c  libc_lock_lock dup @asulock @aculock
+@c  *libc_utmp_jump_table->getutline_r @mtasurace:utent @mtascusig:ALRM @mtutimer @acsfd
+@c   getutline_r_unknown @mtasurace:utent @acsfd
+@c    setutent_unknown dup @mtasurace:utent @acsfd
+@c   getutline_r_file @mtasurace:utent @mtascusig:ALRM @mtutimer
+@c    LOCK_FILE @mtascusig:ALRM @mtutimer
+@c     alarm dup @mtutimer
+@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 @mtutimer
+@c     fcntl_not_cancel dup ok
+@c     alarm dup @mtutimer
+@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{@prelim{}@mtunsafe{@mtasurace{:utent}}@asunsafe{@asulock{} @ascuheap{}}@acunsafe{@aculock{} @acsmem{}}}
+@c utmpname @mtasurace:utent @asulock @ascuheap @aculock @acsmem
+@c  libc_lock_lock dup @asulock @aculock
+@c  *libc_utmp_jump_table->endutent dup @mtasurace:utent
+@c  strcmp dup ok
+@c  free dup @ascuheap @acsmem
+@c  strdup dup @ascuheap @acsmem
+@c  libc_lock_unlock dup @aculock
 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{@prelim{}@mtunsafe{@mtasusig{:ALRM} @mtutimer{}}@asunsafe{@mtutimer{}}@acunsafe{@acusig{:ALRM} @mtutimer{} @acsfd{}}}
+@c updwtmp @mtascusig:ALRM @mtutimer @acsfd
+@c  TRANSFORM_UTMP_FILE_NAME dup ok
+@c  *libc_utmp_file_functions->updwtmp = updwtmp_file @mtascusig:ALRM @mtutimer @acsfd
+@c   open_not_cancel_2 dup @acsfd
+@c   LOCK_FILE dup @mtascusig:ALRM @mtutimer
+@c   LOCKING_FAILED dup ok
+@c   lseek64 dup ok
+@c   ftruncate64 dup ok
+@c   write_not_cancel dup ok
+@c   UNLOCK_FILE dup @mtutimer
+@c   close_not_cancel_no_status dup @acsfd
 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{@prelim{}@mtunsafe{@mtasurace{:utent}}@asunsafe{@asulock{}}@acunsafe{@aculock{} @acsfd{}}}
 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{@prelim{}@mtunsafe{@mtuinit{} @mtasurace{:utent} @mtasusig{:ALRM} @mtutimer{}}@asunsafe{@ascuheap{} @asulock{} @mtutimer{}}@acunsafe{@acusig{:ALRM} @mtutimer{} @aculock{} @acsfd{} @acsmem{}}}
 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{@prelim{}@mtunsafe{@mtasurace{:utent}}@asunsafe{@asulock{}}@acunsafe{@aculock{}}}
 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{@prelim{}@mtunsafe{@mtuinit{} @mtasurace{:utent} @mtasusig{:ALRM} @mtutimer{}}@asunsafe{@asulock{} @ascuheap{} @mtutimer{}}@acunsafe{@acusig{:ALRM} @mtutimer{} @aculock{} @acsmem{} @acsfd{}}}
 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{@prelim{}@mtunsafe{@mtuinit{} @mtasurace{:utent} @mtasusig{:ALRM} @mtutimer{}}@asunsafe{@ascuheap{} @asulock{} @mtutimer{}}@acunsafe{@acusig{:ALRM} @mtutimer{} @aculock{} @acsfd{} @acsmem{}}}
 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{@prelim{}@mtunsafe{@mtasurace{:utent} @mtasusig{:ALRM} @mtutimer{}}@asunsafe{@asulock{} @mtutimer{}}@acunsafe{@acusig{:ALRM} @mtutimer{} @aculock{} @acsfd{}}}
 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{@prelim{}@mtunsafe{@mtasurace{:utent}}@asunsafe{@asulock{} @ascuheap{}}@acunsafe{@aculock{} @acsmem{}}}
 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{@prelim{}@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{@prelim{}@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{@prelim{}@mtunsafe{@mtasurace{:ttyname}}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsfd{} @acsmem{}}}
+@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 @mtasurace:ttyname @ascuheap @asulock @aculock @acsmem @acsfd
+@c  setsid dup ok
+@c  ioctl dup ok
+@c  ttyname dup @mtasurace:ttyname @ascuheap @asulock @aculock @acsmem @acsfd
+@c  close dup @acsfd
+@c  open dup @acsfd
+@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{@prelim{}@mtunsafe{@mtasurace{:utent} @mtasusig{:ALRM} @mtutimer{}}@asunsafe{@asulock{} @ascuheap{} @mtutimer{}}@acunsafe{@acusig{:ALRM} @mtutimer{} @aculock{} @acucorrupt{} @acsfd{} @acsmem{}}}
+@c login @mtasurace:utent @mtascusig:ALRM @mtutimer @asulock @ascuheap @aculock @acucorrupt @acsfd @acsmem
+@c  getpid dup ok
+@c  tty_name @ascuheap @acucorrupt @acsmem @acsfd
+@c   ttyname_r dup @ascuheap @acsmem @acsfd
+@c   memchr dup ok
+@c   realloc dup @ascuheap @acsmem
+@c   malloc dup @ascuheap @acsmem
+@c   free dup @ascuheap @acsmem
+@c  strncmp dup ok
+@c  basename dup ok
+@c  strncpy dup ok
+@c  utmpname dup @mtasurace:utent @asulock @ascuheap @aculock @acsmem
+@c  setutent dup @mtasurace:utent @asulock @aculock @acsfd
+@c  pututline dup @mtasurace:utent @mtascusig:ALRM @mtutimer @asulock @aculock @acsfd
+@c  endutent dup @mtasurace:utent @asulock @aculock
+@c  free dup @ascuheap @acsmem
+@c  updwtmp dup @mtascusig:ALRM @mtutimer @acsfd
 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{@prelim{}@mtunsafe{@mtasurace{:utent} @mtasusig{:ALRM} @mtutimer{}}@asunsafe{@asulock{} @ascuheap{} @mtutimer{}}@acunsafe{@acusig{:ALRM} @mtutimer{} @aculock{} @acsfd{} @acsmem{}}}
+@c logout @mtasurace:utent @mtascusig:ALRM @mtutimer @asulock @ascuheap @aculock @acsfd @acsmem
+@c  utmpname dup @mtasurace:utent @asulock @ascuheap @aculock @acsmem
+@c  setutent dup @mtasurace:utent @asulock @aculock @acsfd
+@c  strncpy dup ok
+@c  getutline_r dup @mtasurace:utent @mtascusig:ALRM @mtutimer @asulock @aculock @acsfd
+@c  bzero dup ok
+@c  gettimeofday dup ok
+@c  time dup ok
+@c  pututline dup @mtasurace:utent @mtascusig:ALRM @mtutimer @asulock @aculock @acsfd
+@c  endutent dup @mtasurace:utent @asulock @aculock
 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{@prelim{}@mtunsafe{@mtasusig{:ALRM} @mtutimer{}}@asunsafe{@mtutimer{}}@acunsafe{@acusig{:ALRM} @mtutimer{} @acsfd{}}}
+@c logwtmp @mtascusig:ALRM @mtutimer @acsfd
+@c  memset dup ok
+@c  getpid dup ok
+@c  strncpy dup ok
+@c  gettimeofday dup ok
+@c  time dup ok
+@c  updwtmp dup @mtascusig:ALRM @mtutimer @acsfd
 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{@prelim{}@mtunsafe{@mtasurace{:pwuid} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
+@c getpwuid @mtasurace:pwuid @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c  libc_lock_lock dup @asulock @aculock
+@c  malloc dup @ascuheap @acsmem
+@c  getpwuid_r dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c  realloc dup @ascuheap @acsmem
+@c  free dup @ascuheap @acsmem
+@c  libc_lock_unlock dup @aculock
 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{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
+@c getpwuid_r @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c  nscd_getpwuid_r @ascuheap @acsfd @acsmem
+@c   itoa_word dup ok
+@c   nscd_getpw_r @ascuheap @acsfd @acsmem
+@c    nscd_get_map_ref @ascuheap @acsfd @acsmem
+@c     nscd_acquire_maplock ok
+@c     nscd_get_mapping @ascuheap @acsfd @acsmem
+@c      open_socket dup @acsfd
+@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 @acsmem
+@c      munmap dup @acsmem
+@c      malloc dup @ascuheap @acsmem
+@c      close dup ok
+@c      nscd_unmap dup @ascuheap @acsmem
+@c    nscd_cache_search ok
+@c     nis_hash ok
+@c     memcmp dup ok
+@c    nscd_open_socket @acsfd
+@c     open_socket @acsfd
+@c      socket dup @acsfd
+@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 @acsfd
+@c     wait_on_socket dup ok
+@c     read dup ok
+@c     close_not_cancel_no_status dup @acsfd
+@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 @acsfd
+@c    nscd_drop_map_ref @ascuheap @acsmem
+@c     nscd_unmap dup @ascuheap @acsmem
+@c    nscd_unmap @ascuheap @acsmem
+@c     munmap dup ok
+@c     free dup @ascuheap @acsmem
+@c  nss_passwd_lookup2 @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c   nss_database_lookup @mtslocale @ascuheap @asulock @acucorrupt @acsmem @acsfd @aculock
+@c    libc_lock_lock @asulock @aculock
+@c    libc_lock_unlock @aculock
+@c    nss_parse_file @mtslocale @ascuheap @asulock @acucorrupt @acsmem @acsfd @aculock
+@c     fopen dup @ascuheap @asulock @acsmem @acsfd @aculock
+@c     fsetlocking dup ok [no concurrent uses]
+@c     malloc dup @asulock @aculock @acsfd @acsmem
+@c     fclose dup @ascuheap @asulock @acsmem @acsfd @aculock
+@c     getline dup @ascuheap @aculock @acucorrupt @acsmem
+@c     strchrnul dup ok
+@c     nss_getline @mtslocale @ascuheap @acsmem
+@c      isspace @mtslocale^^
+@c      strlen dup ok
+@c      malloc dup @asulock @aculock @acsfd @acsmem
+@c      memcpy dup ok
+@c      nss_parse_service_list dup @mtslocale^, @ascuheap @acsmem
+@c     feof_unlocked dup ok
+@c     free dup @asulock @aculock @acsfd @acsmem
+@c    strcmp dup ok
+@c    nss_parse_service_list @mtslocale^, @ascuheap @acsmem
+@c     isspace @mtslocale^^
+@c     malloc dup @asulock @aculock @acsfd @acsmem
+@c     mempcpy dup ok
+@c     strncasecmp dup ok
+@c     free dup @asulock @aculock @acsfd @acsmem
+@c    malloc dup @asulock @aculock @acsfd @acsmem
+@c   nss_lookup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c    nss_lookup_function @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c     libc_lock_lock @asulock @aculock
+@c     tsearch @ascuheap @acucorrupt @acsmem [no @mtsrace or @asucorrupt due to locking]
+@c      known_compare ok
+@c       strcmp dup ok
+@c     malloc dup @ascuheap @acsmem
+@c     tdelete @ascuheap @acucorrupt @acsmem [no @mtsrace or @asucorrupt due to locking]
+@c     free dup @ascuheap @acsmem
+@c     nss_load_library @ascudlopen @ascuplugin @ascuheap @asulock @aculock @acsfd @acsmem
+@c      nss_new_service @ascuheap @acsmem
+@c       strcmp dup ok
+@c       malloc dup @ascuheap @acsmem
+@c      strlen dup ok
+@c      stpcpy dup ok
+@c      libc_dlopen @ascudlopen @ascuheap @asulock @aculock @acsfd @acsmem
+@c      libc_dlsym dup @asulock @aculock @acsfd @acsmem
+@c      *ifct(*nscd_init_cb) @ascuplugin
+@c     stpcpy dup ok
+@c     libc_dlsym dup @asulock @aculock @acsfd @acsmem
+@c     libc_lock_unlock dup ok
+@c    nss_next_action ok
+@c  *fct.l -> _nss_*_getpwuid_r @ascuplugin
+@c  nss_next2 @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c   nss_next_action dup ok
+@c   nss_lookup_function dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+
+@c _nss_files_getpwuid_r @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@c  libc_lock_lock dup @asulock @aculock
+@c  internal_setent @ascuheap @asulock @aculock @acsmem @acsfd
+@c   fopen dup @ascuheap @asulock @acsmem @acsfd @aculock
+@c   fileno dup ok
+@c   fcntl dup ok
+@c   fclose dup @ascuheap @asulock @aculock @acsmem @acsfd
+@c   rewind dup @aculock [stream guarded by non-recursive pwent lock]
+@c  internal_getent @mtslocale^
+@c   fgets_unlocked dup ok [stream guarded by non-recursive pwent lock]
+@c   isspace dup @mtslocale^^
+@c   _nss_files_parse_pwent = parse_line ok
+@c    strpbrk dup ok
+@c  internal_endent @ascuheap @asulock @aculock @acsmem @acsfd
+@c   fclose dup @ascuheap @asulock @aculock @acsmem @acsfd
+@c  libc_lock_unlock dup @aculock
+
+@c _nss_nis_getpwuid_r ... not fully reviewed (assumed) @asuinit @asulock @acucorrupt @aculock
+@c  yp_get_default_domain @asulock @aculock
+@c   libc_lock_lock dup @asulock @aculock
+@c   getdomainname dup ok
+@c   strcmp dup ok
+@c   libc_lock_unlock dup @aculock
+@c  snprintf dup @ascuheap @acsmem
+@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 @asulock @aculock
+@c     strcmp
+@c     yp_bind
+@c     ypclnt_call
+@c      clnt_call
+@c      clnt_perror
+@c     libc_lock_unlock @aculock
+@c     yp_unbind_locked
+@c     yp_unbind
+@c      strcmp dup ok
+@c      calloc dup @asulock @aculock @acsfd @acsmem
+@c      yp_bind_file
+@c       strlen dup ok
+@c       snprintf dup @ascuheap @acsmem
+@c       open dup @acsfd cancelpt
+@c       pread dup cancelpt
+@c       yp_bind_client_create
+@c       close dup @acsfd 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 @asulock @aculock @acsfd @acsmem
+@c     calloc dup @asulock @aculock @acsfd @acsmem
+@c     free dup @asulock @aculock @acsfd @acsmem
+@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 @ascuheap @acsmem
+@c        malloc dup @ascuheap @acsmem
+@c       xdr_opaque
+@c        XDR_GETBYTES
+@c         *x_getbytes
+@c        XDR_PUTBYTES
+@c         *x_putbytes
+@c       mem_free @ascuheap @acsmem
+@c        free dup @ascuheap @acsmem
+@c  yperr2nss ok
+@c  strchr dup ok
+@c  _nls_default_nss @asuinit @ascuheap @asulock @acucorrupt @acsmem @acsfd @aculock
+@c   init @asuinit^, @ascuheap @asulock @acucorrupt @acsmem @acsfd @aculock
+@c    fopen dup @ascuheap @asulock @acsmem @acsfd @aculock
+@c    fsetlocking ok [no concurrent uses]
+@c    feof_unlocked dup ok
+@c    getline dup @ascuheap @aculock @acucorrupt @acsmem
+@c    isspace dup @mtslocale^^
+@c    strncmp dup ok
+@c    free dup @asulock @acsmem @acsfd @aculock
+@c    fclose dup @ascuheap @asulock @aculock @acsmem @acsfd
+@c  free dup @asulock @acsmem @acsfd @aculock
+@c  mempcpy dup ok
+@c  strncpy dup ok
+@c  isspace dup @mtslocale^^
+@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{@prelim{}@mtunsafe{@mtasurace{:pwnam} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
+@c getpwnam @mtasurace:pwnam @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c  libc_lock_lock dup @asulock @aculock
+@c  malloc dup @ascuheap @acsmem
+@c  getpwnam_r dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c  realloc dup @ascuheap @acsmem
+@c  free dup @ascuheap @acsmem
+@c  libc_lock_unlock dup @aculock
 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{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
+@c getpwnam_r @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c  nscd_getpwnam_r @ascuheap @asulock @aculock @acsfd @acsmem
+@c   strlen dup ok
+@c   nscd_getpw_r dup @ascuheap @asulock @aculock @acsfd @acsmem
+@c  nss_passwd_lookup2 dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c  *fct.l @ascuplugin
+@c  nss_next2 dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c
+@c _nss_files_getpwnam_r @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@c  libc_lock_lock dup @asulock @aculock
+@c  internal_setent dup @ascuheap @asulock @aculock @acsmem @acsfd
+@c  internal_getent dup @mtslocale^
+@c  strcmp dup ok
+@c  internal_endent dup @ascuheap @asulock @aculock @acsmem @acsfd
+@c  libc_lock_unlock dup @aculock
+@c
+@c _nss_*_getpwnam_r (assumed) @asuinit @asulock @acucorrupt @aculock
+
 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{@prelim{}@mtunsafe{@mtasurace{:fpwent}}@asunsafe{@asucorrupt{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{}}}
+@c fgetpwent @mtasurace:fpwent @asucorrupt @asulock @acucorrupt @aculock
+@c  fgetpos dup @asucorrupt @aculock @acucorrupt
+@c  libc_lock_lock dup @asulock @aculock
+@c  malloc dup @ascuheap @acsmem
+@c  fgetpwent_r dup @asucorrupt @acucorrupt @aculock
+@c  realloc dup @ascuheap @acsmem
+@c  free dup @ascuheap @acsmem
+@c  fsetpos dup @asucorrupt @aculock @acucorrupt
+@c  libc_lock_unlock dup @aculock
 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{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{} @aculock{}}}
+@c fgetpwent_r @asucorrupt @acucorrupt @aculock
+@c  flockfile dup @aculock
+@c  fgets_unlocked @asucorrupt @acucorrupt [no @mtsrace due to explicit locking]
+@c  feof_unlocked dup ok
+@c  funlockfile dup @aculock
+@c  isspace dup @mtslocale^^
+@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{@prelim{}@mtunsafe{@mtasurace{:pwent} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
+@c setpwent @mtasurace:pwent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c  libc_lock_lock @asulock @aculock
+@c  nss_setent(nss_passwd_lookup2) @mtasurace:pwent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c    ** resolv's res_maybe_init not called here
+@c   setup(nss_passwd_lookup2) @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c    *lookup_fct = nss_passwd_lookup2 dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c    nss_lookup dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c   *fct.f @mtasurace:pwent @ascuplugin
+@c   nss_next2 dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c  libc_lock_unlock @aculock
 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{@prelim{}@mtunsafe{@mtasurace{:pwent} @mtasurace{:pwentbuf} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
+@c getpwent @mtasurace:pwent @mtasurace:pwentbuf @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c  libc_lock_lock dup @asulock @aculock
+@c  nss_getent(getpwent_r) @mtasurace:pwent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c   malloc dup @ascuheap @acsmem
+@c   *func = getpwent_r dup @mtasurace:pwent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c   realloc dup @ascuheap @acsmem
+@c   free dup @ascuheap @acsmem
+@c  libc_lock_unlock dup @aculock
 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{@prelim{}@mtunsafe{@mtasurace{:pwent} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
+@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 @mtasurace:pwent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c  libc_lock_lock dup @asulock @aculock
+@c  nss_getent_r(nss_passwd_lookup2) @mtasurace:pwent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c   setup(nss_passwd_lookup2) dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c   *fct.f @mtasurace:pwent @ascuplugin
+@c   nss_next2 dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c   nss_lookup dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c   *sfct.f @mtasurace:pwent @ascuplugin
+@c  libc_lock_unlock dup @aculock
 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{@prelim{}@mtunsafe{@mtasurace{:pwent} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
+@c endpwent @mtasurace:pwent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c  libc_lock_lock @asulock @aculock
+@c  nss_endent(nss_passwd_lookup2) @mtasurace:pwent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c    ** resolv's res_maybe_init not called here
+@c   setup(nss_passwd_lookup2) dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c   *fct.f @mtasurace:pwent @ascuplugin
+@c   nss_next2 dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c  libc_lock_unlock @aculock
 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{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@asucorrupt{}}@acunsafe{@aculock{} @acucorrupt{}}}
+@c putpwent @mtslocale @asucorrupt @aculock @acucorrupt
+@c  fprintf dup @mtslocale @asucorrupt @aculock @acucorrupt [no @ascuheap @acsmem]
 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{@prelim{}@mtunsafe{@mtasurace{:grgid} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
+@c getgrgid =~ getpwuid dup @mtasurace:grgid @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c  getgrgid_r dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
 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{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
+@c getgrgid_r =~ getpwuid_r dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c  nscd_getgrgid_r @ascuheap @acsfd @acsmem
+@c   itoa_word dup ok
+@c   nscd_getgr_r @ascuheap @acsfd @acsmem
+@c    nscd_get_map_ref dup @ascuheap @acsfd @acsmem
+@c    nscd_cache_search dup ok
+@c    nscd_open_socket dup @acsfd
+@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 @acsfd
+@c    nscd_drop_map_ref dup @ascuheap @acsmem
+@c    nscd_unmap dup @ascuheap @acsmem
+@c  nss_group_lookup2 =~ nss_passwd_lookup2 dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c  *fct.l -> _nss_*_getgrgid_r @ascuplugin
+@c  nss_next2 dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
 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{@prelim{}@mtunsafe{@mtasurace{:grnam} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
+@c getgrnam =~ getpwnam dup @mtasurace:grnam @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c  getgrnam_r dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
 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{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
+@c getgrnam_r =~ getpwnam_r dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c  nscd_getgrnam_r @ascuheap @asulock @aculock @acsfd @acsmem
+@c   strlen dup ok
+@c   nscd_getgr_r dup @ascuheap @asulock @aculock @acsfd @acsmem
+@c  nss_group_lookup2 dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c  *fct.l @ascuplugin
+@c  nss_next2 dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
 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{@prelim{}@mtunsafe{@mtasurace{:fgrent}}@asunsafe{@asucorrupt{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{}}}
+@c fgetgrent @mtasurace:fgrent @asucorrupt @asulock @acucorrupt @aculock
+@c  fgetpos dup @asucorrupt @aculock @acucorrupt
+@c  libc_lock_lock dup @asulock @aculock
+@c  malloc dup @ascuheap @acsmem
+@c  fgetgrent_r dup @asucorrupt @acucorrupt @aculock
+@c  realloc dup @ascuheap @acsmem
+@c  free dup @ascuheap @acsmem
+@c  fsetpos dup @asucorrupt @aculock @acucorrupt
+@c  libc_lock_unlock dup @aculock
 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{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{} @aculock{}}}
+@c fgetgrent_r @asucorrupt @acucorrupt @aculock
+@c  flockfile dup @aculock
+@c  fgets_unlocked @asucorrupt @acucorrupt [no @mtsrace due to explicit locking]
+@c  feof_unlocked dup ok
+@c  funlockfile dup @aculock
+@c  isspace dup @mtslocale^^
+@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{@prelim{}@mtunsafe{@mtasurace{:grent} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
+@c setgrent =~ setpwent dup @mtasurace:grent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c ...*lookup_fct = nss_group_lookup2 dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
 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{@prelim{}@mtunsafe{@mtasurace{:grent} @mtasurace{:grentbuf} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
+@c getgrent =~ getpwent dup @mtasurace:grent @mtasurace:grentbuf @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c   *func = getgrent_r dup @mtasurace:grent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
 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{@prelim{}@mtunsafe{@mtasurace{:grent} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
+@c getgrent_r =~ getpwent_r dup @mtasurace:grent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
 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{@prelim{}@mtunsafe{@mtasurace{:grent} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
+@c endgrent =~ endpwent dup @mtasurace:grent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
 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{@prelim{}@mtunsafe{@mtasurace{:netgrent} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
+@c setnetgrent @mtasurace:netgrent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c  libc_lock_lock dup @asulock @aculock
+@c  nscd_setnetgrent @ascuheap @acsfd @acsmem
+@c   __nscd_setnetgrent @ascuheap @acsfd @acsmem
+@c    strlen dup ok
+@c    nscd_get_map_ref dup @ascuheap @acsfd @acsmem
+@c    nscd_cache_search dup ok
+@c    nscd_open_socket dup @acsfd
+@c    malloc dup @ascuheap @acsmem
+@c    readall dup ok
+@c    free dup @ascuheap @acsmem
+@c    close_not_cancel_no_status dup @acsfd
+@c    nscd_drop_map_ref dup @ascuheap @acsmem
+@c    nscd_unmap dup @ascuheap @acsmem
+@c  internal_setnetgrent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c   free_memory dup @ascuheap @acsmem
+@c    free dup @ascuheap @acsmem
+@c   internal_setnetgrent_reuse @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c    endnetgrent_hook dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c     nss_lookup_function dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c     *endfct @ascuplugin
+@c    (netgroup::)setup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c     nss_netgroup_lookup dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c      nss_netgroup_lookup2 =~ nss_passwd_lookup2 dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c     nss_lookup dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c    *fct.f @ascuplugin
+@c    nss_next2 dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c    nss_lookup_function dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c    *endfct @ascuplugin
+@c    strlen dup ok
+@c    malloc dup @ascuheap @acsmem
+@c    memcpy dup ok
+@c  libc_lock_unlock dup @aculock
 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{@prelim{}@mtunsafe{@mtasurace{:netgrent} @mtasurace{:netgrentbuf} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
+@c getnetgrent @mtasurace:netgrent @mtasurace:netgrentbuf @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c   uses unsafely a static buffer allocated within a libc_once call
+@c  allocate (libc_once) @ascuheap @acsmem
+@c   malloc dup @ascuheap @acsmem
+@c  getnetgrent_r dup @mtasurace:netgrent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
 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{@prelim{}@mtunsafe{@mtasurace{:netgrent} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
+@c getnetgrent_r @mtasurace:netgrent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c  libc_lock_lock dup @asulock @aculock
+@c  internal_getnetgrent_r @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c   nss_lookup_function dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c   *fct @ascuplugin
+@c   nscd_getnetgrent ok
+@c    rawmemchr dup ok
+@c   internal_setnetgrent_reuse dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c   strcmp dup ok
+@c   malloc dup @ascuheap @acsmem
+@c   memcpy dup ok
+@c  libc_lock_unlock dup @aculock
 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{@prelim{}@mtunsafe{@mtasurace{:netgrent}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
+@c endnetgrent @mtasurace:netgrent @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c  libc_lock_lock dup @asulock @aculock
+@c  internal_endnetgrent @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c   endnetgrent_hook dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c   free_memory dup @ascuheap @acsmem
+@c  libc_lock_unlock dup @aculock
 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{@prelim{}@mtunsafe{@mtasurace{:netgrent} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
+@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 @mtasurace:netgrent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c  nscd_innetgr @ascuheap @acsfd @acsmem
+@c   strlen dup ok
+@c   malloc dup @ascuheap @acsmem
+@c   stpcpy dup ok
+@c   nscd_get_map_ref dup @ascuheap @acsfd @acsmem
+@c   nscd_cache_search dup ok
+@c   nscd_open_socket dup @acsfd
+@c   close_not_cancel_no_status dup @acsfd
+@c   nscd_drop_map_ref dup @ascuheap @acsmem
+@c   nscd_unmap dup @ascuheap @acsmem
+@c   free dup @ascuheap @acsmem
+@c  memset dup ok
+@c  (netgroup::)setup dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c  *setfct.f @ascuplugin
+@c  nss_lookup_function dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c  *getfct @ascuplugin
+@c  strcmp dup ok
+@c  strlen dup ok
+@c  malloc dup @ascuheap @acsmem
+@c  memcpy dup ok
+@c  strcasecmp dup
+@c  *endfct @ascuplugin
+@c  nss_next2 dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c  free_memory dup @ascuheap @acsmem
 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=a0d8bc067e9a8a493f4ce44043b8d08b1f7931eb

commit a0d8bc067e9a8a493f4ce44043b8d08b1f7931eb
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 5b6e098..e679963 100644
--- a/manual/time.texi
+++ b/manual/time.texi
@@ -79,6 +79,7 @@ two calendar times.  This function is declared in @file{time.h}.
 @comment time.h
 @comment ISO
 @deftypefun double difftime (time_t @var{time1}, time_t @var{time0})
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
 The @code{difftime} function returns the number of seconds of elapsed
 time between calendar time @var{time1} and calendar time @var{time0}, as
 a value of type @code{double}.  The difference ignores leap seconds
@@ -246,6 +247,12 @@ Values of type @code{clock_t} are numbers of clock ticks.
 @comment time.h
 @comment ISO
 @deftypefun clock_t clock (void)
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+@c On Hurd, this calls task_info twice and adds user and system time
+@c from both basic and thread time info structs.  On generic posix,
+@c calls times and adds utime and stime.  On bsd, calls getrusage and
+@c safely converts stime and utime to clock.  On linux, calls
+@c clock_gettime.
 This function returns the calling process' current CPU time.  If the CPU
 time is not available or cannot be represented, @code{clock} returns the
 value @code{(clock_t)(-1)}.
@@ -310,6 +317,12 @@ This is an obsolete name for the number of clock ticks per second.  Use
 @comment sys/times.h
 @comment POSIX.1
 @deftypefun clock_t times (struct tms *@var{buffer})
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+@c On HURD, this calls task_info twice, for basic and thread times info,
+@c adding user and system times into tms, and then gettimeofday, to
+@c compute the real time.  On BSD, it calls getclktck, getrusage (twice)
+@c and time.  On Linux, it's a syscall with special handling to account
+@c for clock_t counts that look like error values.
 The @code{times} function stores the processor time information for
 the calling process in @var{buffer}.
 
@@ -409,6 +422,7 @@ subtracting.  @xref{Elapsed Time}.
 @comment time.h
 @comment ISO
 @deftypefun time_t time (time_t *@var{result})
+@safety{@prelim{}@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
@@ -421,6 +435,8 @@ current calendar time is not available, the value
 @comment time.h
 @comment SVID, XPG
 @deftypefun int stime (const time_t *@var{newtime})
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+@c On unix, this is implemented in terms of settimeofday.
 @code{stime} sets the system clock, i.e., it tells the system that the
 current calendar time is @var{newtime}, where @code{newtime} is
 interpreted as described in the above definition of @code{time_t}.
@@ -475,6 +491,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{@prelim{}@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
@@ -498,6 +520,9 @@ Instead, use the facilities described in @ref{Time Zone Functions}.
 @comment sys/time.h
 @comment BSD
 @deftypefun int settimeofday (const struct timeval *@var{tp}, const struct timezone *@var{tzp})
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+@c On HURD, it calls host_set_time with a privileged port.  On other
+@c unix systems, it's a syscall.
 The @code{settimeofday} function sets the current calendar time in the
 system clock according to the arguments.  As for @code{gettimeofday},
 the calendar time is represented as the elapsed time since the epoch.
@@ -539,6 +564,10 @@ The operating system does not support setting time zone information, and
 @comment sys/time.h
 @comment BSD
 @deftypefun int adjtime (const struct timeval *@var{delta}, struct timeval *@var{olddelta})
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+@c On hurd and mach, call host_adjust_time with a privileged port.  On
+@c Linux, it's implemented in terms of adjtimex.  On other unixen, it's
+@c a syscall.
 This function speeds up or slows down the system clock in order to make
 a gradual adjustment.  This ensures that the calendar time reported by
 the system clock is always monotonically increasing, which might not
@@ -577,7 +606,8 @@ Symbols for the following function are declared in @file{sys/timex.h}.
 @comment sys/timex.h
 @comment GNU
 @deftypefun int adjtimex (struct timex *@var{timex})
-
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+@c It's a syscall, only available on linux.
 @code{adjtimex} is functionally identical to @code{ntp_adjtime}.
 @xref{High Accuracy Clock}.
 
@@ -674,6 +704,10 @@ GNU extension, and is not visible in a strict @w{ISO C} environment.
 @comment time.h
 @comment ISO
 @deftypefun {struct tm *} localtime (const time_t *@var{time})
+@safety{@prelim{}@mtunsafe{@mtasurace{:tmbuf} @mtsenv{} @mtslocale{}}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsmem{} @acsfd{}}}
+@c Calls tz_convert with a static buffer.
+@c localtime @mtasurace:tmbuf @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@c  tz_convert dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
 The @code{localtime} function converts the simple time pointed to by
 @var{time} to broken-down time representation, expressed relative to the
 user's specified time zone.
@@ -698,6 +732,87 @@ all threads.  POSIX.1c introduced a variant of this function.
 @comment time.h
 @comment POSIX.1c
 @deftypefun {struct tm *} localtime_r (const time_t *@var{time}, struct tm *@var{resultp})
+@safety{@prelim{}@mtsafe{@mtsenv{} @mtslocale{}}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsmem{} @acsfd{}}}
+@c localtime_r @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@c  tz_convert(use_localtime) @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@c   libc_lock_lock dup @asulock @aculock
+@c   tzset_internal @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@c     always called with tzset_lock held
+@c     sets static is_initialized before initialization;
+@c     reads and sets old_tz; sets tz_rules.
+@c     some of the issues only apply on the first call.
+@c     subsequent calls only trigger these when called by localtime;
+@c     otherwise, they're ok.
+@c    getenv dup @mtsenv
+@c    strcmp dup ok
+@c    strdup @ascuheap
+@c    tzfile_read @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@c     memcmp dup ok
+@c     strstr dup ok
+@c     getenv dup @mtsenv
+@c     asprintf dup @mtslocale @ascuheap @acsmem
+@c     stat64 dup ok
+@c     fopen dup @ascuheap @asulock @acsmem @acsfd @aculock
+@c     fileno dup ok
+@c     fstat64 dup ok
+@c     fclose dup @ascuheap @asulock @aculock @acsmem @acsfd
+@c     free dup @ascuheap @acsmem
+@c     fsetlocking dup ok [no @mtasurace:stream @asulock, exclusive]
+@c     fread_unlocked dup ok [no @mtasurace:stream @asucorrupt @acucorrupt]
+@c     memcpy dup ok
+@c     decode ok
+@c      bswap_32 dup ok
+@c     fseek dup ok [no @mtasurace:stream @asucorrupt @acucorrupt]
+@c     ftello dup ok [no @mtasurace:stream @asucorrupt @acucorrupt]
+@c     malloc dup @ascuheap @acsmem
+@c     decode64 ok
+@c      bswap_64 dup ok
+@c     getc_unlocked ok [no @mtasurace:stream @asucorrupt @acucorrupt]
+@c     tzstring dup @ascuheap @acsmem
+@c     compute_tzname_max dup ok [guarded by tzset_lock]
+@c    memset dup ok
+@c    update_vars ok [guarded by tzset_lock]
+@c      sets daylight, timezone, tzname and tzname_cur_max;
+@c      called only with tzset_lock held, unless tzset_parse_tz
+@c      (internal, but not static) gets called by users; given the its
+@c      double-underscore-prefixed name, this interface violation could
+@c      be regarded as undefined behavior.
+@c     strlen ok
+@c    tzset_parse_tz @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@c     sscanf dup @mtslocale @ascuheap @acsmem
+@c     isalnum dup @mtsenv
+@c     tzstring @ascuheap @acsmem
+@c       reads and changes tzstring_list without synchronization, but
+@c       only called with tzset_lock held (save for interface violations)
+@c      strlen dup ok
+@c      malloc dup @ascuheap @acsmem
+@c      strcpy dup ok
+@c     isdigit dup @mtslocale
+@c     compute_offset ok
+@c     tzfile_default @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@c       sets tzname, timezone, types, zone_names, rule_*off, etc; no guards
+@c      strlen dup ok
+@c      tzfile_read dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@c      mempcpy dup ok
+@c      compute_tzname_max ok [if guarded by tzset_lock]
+@c        iterates over zone_names; no guards
+@c     free dup @ascuheap @acsmem
+@c     strtoul dup @mtslocale
+@c     update_vars dup ok
+@c   tzfile_compute(use_localtime) @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@c     sets tzname; no guards.  with !use_localtime, as in gmtime, it's ok
+@c    tzstring dup @acsuheap @acsmem
+@c    tzset_parse_tz dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@c    offtime dup ok
+@c    tz_compute dup ok
+@c    strcmp dup ok
+@c   offtime ok
+@c    isleap dup ok
+@c   tz_compute ok
+@c    compute_change ok
+@c     isleap ok
+@c   libc_lock_unlock dup @aculock
+
 The @code{localtime_r} function works just like the @code{localtime}
 function.  It takes a pointer to a variable containing a simple time
 and converts it to the broken-down time format.
@@ -714,6 +829,10 @@ object the result was written into, i.e., it returns @var{resultp}.
 @comment time.h
 @comment ISO
 @deftypefun {struct tm *} gmtime (const time_t *@var{time})
+@safety{@prelim{}@mtunsafe{@mtasurace{:tmbuf} @mtsenv{} @mtslocale{}}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsmem{} @acsfd{}}}
+@c gmtime @mtasurace:tmbuf @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@c  tz_convert dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+
 This function is similar to @code{localtime}, except that the broken-down
 time is expressed as Coordinated Universal Time (UTC) (formerly called
 Greenwich Mean Time (GMT)) rather than relative to a local time zone.
@@ -727,6 +846,15 @@ is placed in a static variable.  POSIX.1c also provides a replacement for
 @comment time.h
 @comment POSIX.1c
 @deftypefun {struct tm *} gmtime_r (const time_t *@var{time}, struct tm *@var{resultp})
+@safety{@prelim{}@mtsafe{@mtsenv{} @mtslocale{}}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsmem{} @acsfd{}}}
+@c You'd think tz_convert could avoid some safety issues with
+@c !use_localtime, but no such luck: tzset_internal will always bring
+@c about all possible AS and AC problems when it's first called.
+@c Calling any of localtime,gmtime_r once would run the initialization
+@c and avoid the heap, mem and fd issues in gmtime* in subsequent calls,
+@c but the unsafe locking would remain.
+@c gmtime_r @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@c  tz_convert(gmtime_r) dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
 This function is similar to @code{localtime_r}, except that it converts
 just like @code{gmtime} the given time as Coordinated Universal Time.
 
@@ -738,6 +866,29 @@ object the result was written into, i.e., it returns @var{resultp}.
 @comment time.h
 @comment ISO
 @deftypefun time_t mktime (struct tm *@var{brokentime})
+@safety{@prelim{}@mtsafe{@mtsenv{} @mtslocale{}}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsmem{} @acsfd{}}}
+@c mktime @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@c   passes a static localtime_offset to mktime_internal; it is read
+@c   once, used as an initial guess, and updated at the end, but not
+@c   used except as a guess for subsequent calls, so it should be safe.
+@c   Even though a compiler might delay the load and perform it multiple
+@c   times (bug 16346), there are at least two unconditional uses of the
+@c   auto variable in which the first load is stored, separated by a
+@c   call to an external function, and a conditional change of the
+@c   variable before the external call, so refraining from allocating a
+@c   local variable at the first load would be a very bad optimization.
+@c  tzset dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@c  mktime_internal(localtime_r) @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@c   ydhms_diff ok
+@c   ranged_convert(localtime_r) @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@c    *convert = localtime_r dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@c    time_t_avg dup ok
+@c   guess_time_tm dup ok
+@c    ydhms_diff dup ok
+@c    time_t_add_ok ok
+@c     time_t_avg ok
+@c   isdst_differ ok
+@c   time_t_int_add_ok ok
 The @code{mktime} function converts a broken-down time structure to a
 simple time representation.  It also normalizes the contents of the
 broken-down time structure, and fills in some components based on the
@@ -765,6 +916,8 @@ members.  @xref{Time Zone Functions}.
 @comment time.h
 @comment ???
 @deftypefun time_t timelocal (struct tm *@var{brokentime})
+@safety{@prelim{}@mtsafe{@mtsenv{} @mtslocale{}}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsmem{} @acsfd{}}}
+@c Alias to mktime.
 
 @code{timelocal} is functionally identical to @code{mktime}, but more
 mnemonically named.  Note that it is the inverse of the @code{localtime}
@@ -778,6 +931,19 @@ available.  @code{timelocal} is rather rare.
 @comment time.h
 @comment ???
 @deftypefun time_t timegm (struct tm *@var{brokentime})
+@safety{@prelim{}@mtsafe{@mtsenv{} @mtslocale{}}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsmem{} @acsfd{}}}
+@c timegm @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@c   gmtime_offset triggers the same caveats as localtime_offset in mktime.
+@c   although gmtime_r, as called by mktime, might save some issues,
+@c   tzset calls tzset_internal with always, which forces
+@c   reinitialization, so all issues may arise.
+@c  tzset dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@c  mktime_internal(gmtime_r) @asulock @aculock
+@c...gmtime_r @asulock{} @aculock{}
+@c    ... dup ok
+@c    tz_convert(!use_localtime) @asulock @aculock
+@c     ... dup @asulock @aculock
+@c     tzfile_compute(!use_localtime) ok
 
 @code{timegm} is functionally identical to @code{mktime} except it
 always takes the input values to be Coordinated Universal Time (UTC)
@@ -839,6 +1005,8 @@ system clock from the true calendar time.
 @comment sys/timex.h
 @comment GNU
 @deftypefun int ntp_gettime (struct ntptimeval *@var{tptr})
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+@c Wrapper for adjtimex.
 The @code{ntp_gettime} function sets the structure pointed to by
 @var{tptr} to current values.  The elements of the structure afterwards
 contain the values the timer implementation in the kernel assumes.  They
@@ -956,6 +1124,8 @@ exceeded the threshold.
 @comment sys/timex.h
 @comment GNU
 @deftypefun int ntp_adjtime (struct timex *@var{tptr})
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+@c Alias to adjtimex syscall.
 The @code{ntp_adjtime} function sets the structure specified by
 @var{tptr} to current values.
 
@@ -1010,6 +1180,13 @@ strings.  These functions are declared in the header file @file{time.h}.
 @comment time.h
 @comment ISO
 @deftypefun {char *} asctime (const struct tm *@var{brokentime})
+@safety{@prelim{}@mtunsafe{@mtasurace{:asctime} @mtslocale{}}@asunsafe{}@acsafe{}}
+@c asctime @mtasurace:asctime @mtslocale
+@c   Uses a static buffer.
+@c  asctime_internal @mtslocale
+@c   snprintf dup @mtslocale [no @acsuheap @acsmem]
+@c   ab_day_name @mtslocale
+@c   ab_month_name @mtslocale
 The @code{asctime} function converts the broken-down time value that
 @var{brokentime} points to into a string in a standard format:
 
@@ -1033,6 +1210,9 @@ string.)
 @comment time.h
 @comment POSIX.1c
 @deftypefun {char *} asctime_r (const struct tm *@var{brokentime}, char *@var{buffer})
+@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{}@acsafe{}}
+@c asctime_r @mtslocale
+@c  asctime_internal dup @mtslocale
 This function is similar to @code{asctime} but instead of placing the
 result in a static buffer it writes the string in the buffer pointed to
 by the parameter @var{buffer}.  This buffer should have room
@@ -1047,6 +1227,10 @@ return @code{NULL}.
 @comment time.h
 @comment ISO
 @deftypefun {char *} ctime (const time_t *@var{time})
+@safety{@prelim{}@mtunsafe{@mtasurace{:tmbuf} @mtasurace{:asctime} @mtsenv{} @mtslocale{}}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsmem{} @acsfd{}}}
+@c ctime @mtasurace:tmbuf @mturace:asctime @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@c  localtime dup @mtasurace:tmbuf @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@c  asctime dup @mturace:asctime @mtslocale
 The @code{ctime} function is similar to @code{asctime}, except that you
 specify the calendar time argument as a @code{time_t} simple time value
 rather than in broken-down local time format.  It is equivalent to
@@ -1062,6 +1246,10 @@ Calling @code{ctime} also sets the current time zone as if
 @comment time.h
 @comment POSIX.1c
 @deftypefun {char *} ctime_r (const time_t *@var{time}, char *@var{buffer})
+@safety{@prelim{}@mtsafe{@mtsenv{} @mtslocale{}}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsmem{} @acsfd{}}}
+@c ctime_r @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@c  localtime_r dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@c  asctime_r dup @mtslocale
 This function is similar to @code{ctime}, but places the result in the
 string pointed to by @var{buffer}.  It is equivalent to (written using
 gcc extensions, @pxref{Statement Exprs,,,gcc,Porting and Using gcc}):
@@ -1079,6 +1267,63 @@ return @code{NULL}.
 @comment time.h
 @comment ISO
 @deftypefun size_t strftime (char *@var{s}, size_t @var{size}, const char *@var{template}, const struct tm *@var{brokentime})
+@safety{@prelim{}@mtsafe{@mtsenv{} @mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{} @asulock{} @ascudlopen{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{} @acsfd{}}}
+@c strftime @mtsenv @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
+@c  strftime_l @mtsenv @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
+@c   strftime_internal @mtsenv @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
+@c    add ok
+@c     memset_zero dup ok
+@c     memset_space dup ok
+@c    strlen dup ok
+@c    mbrlen @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd [no @mtasurace:mbstate/!ps]
+@c    mbsinit dup ok
+@c    cpy ok
+@c     add dup ok
+@c     memcpy_lowcase ok
+@c      TOLOWER ok
+@c       tolower_l ok
+@c     memcpy_uppcase ok
+@c      TOUPPER ok
+@c       toupper_l ok
+@c     MEMCPY ok
+@c      memcpy dup ok
+@c    ISDIGIT ok
+@c    STRLEN ok
+@c     strlen dup ok
+@c    strftime_internal dup @mtsenv @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
+@c    TOUPPER dup ok
+@c    nl_get_era_entry @ascuheap @asulock @acsmem @aculock
+@c     nl_init_era_entries @ascuheap @asulock @acsmem @aculock
+@c      libc_rwlock_wrlock dup @asulock @aculock
+@c      malloc dup @ascuheap @acsmem
+@c      memset dup ok
+@c      free dup @ascuheap @acsmem
+@c      realloc dup @ascuheap @acsmem
+@c      memcpy dup ok
+@c      strchr dup ok
+@c      wcschr dup ok
+@c      libc_rwlock_unlock dup @asulock @aculock
+@c     ERA_DATE_CMP ok
+@c    DO_NUMBER ok
+@c    DO_NUMBER_SPACEPAD ok
+@c    nl_get_alt_digit @ascuheap @asulock @acsmem @aculock
+@c     libc_rwlock_wrlock dup @asulock @aculock
+@c     nl_init_alt_digit @ascuheap @acsmem
+@c      malloc dup @ascuheap @acsmem
+@c      memset dup ok
+@c      strchr dup ok
+@c     libc_rwlock_unlock dup @aculock
+@c    memset_space ok
+@c     memset dup ok
+@c    memset_zero ok
+@c     memset dup ok
+@c    mktime dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@c    iso_week_days ok
+@c    isleap ok
+@c    tzset dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@c    localtime_r dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@c    gmtime_r dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@c    tm_diff ok
 This function is similar to the @code{sprintf} function (@pxref{Formatted
 Input}), but the conversion specifications that can appear in the format
 template @var{template} are specialized for printing components of the date
@@ -1406,6 +1651,53 @@ For an example of @code{strftime}, see @ref{Time Functions Example}.
 @comment time.h
 @comment ISO/Amend1
 @deftypefun size_t wcsftime (wchar_t *@var{s}, size_t @var{size}, const wchar_t *@var{template}, const struct tm *@var{brokentime})
+@safety{@prelim{}@mtsafe{@mtsenv{} @mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{} @asulock{} @ascudlopen{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{} @acsfd{}}}
+@c wcsftime @mtsenv @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
+@c  wcsftime_l @mtsenv @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
+@c   wcsftime_internal @mtsenv @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
+@c    add ok
+@c     memset_zero dup ok
+@c     memset_space dup ok
+@c    wcslen dup ok
+@c    cpy ok
+@c     add dup ok
+@c     memcpy_lowcase ok
+@c      TOLOWER ok
+@c       towlower_l dup ok
+@c     memcpy_uppcase ok
+@c      TOUPPER ok
+@c       towupper_l dup ok
+@c     MEMCPY ok
+@c      wmemcpy dup ok
+@c    widen @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
+@c     memset dup ok
+@c     mbsrtowcs_l @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd [no @mtasurace:mbstate/!ps]
+@c    ISDIGIT ok
+@c    STRLEN ok
+@c     wcslen dup ok
+@c    wcsftime_internal dup @mtsenv @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
+@c    TOUPPER dup ok
+@c    nl_get_era_entry dup @ascuheap @asulock @acsmem @aculock
+@c    DO_NUMBER ok
+@c    DO_NUMBER_SPACEPAD ok
+@c    nl_get_walt_digit dup @ascuheap @asulock @acsmem @aculock
+@c     libc_rwlock_wrlock dup @asulock @aculock
+@c     nl_init_alt_digit dup @ascuheap @acsmem
+@c     malloc dup @ascuheap @acsmem
+@c     memset dup ok
+@c     wcschr dup ok
+@c     libc_rwlock_unlock dup @aculock
+@c    memset_space ok
+@c     wmemset dup ok
+@c    memset_zero ok
+@c     wmemset dup ok
+@c    mktime dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@c    iso_week_days ok
+@c    isleap ok
+@c    tzset dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@c    localtime_r dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@c    gmtime_r dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@c    tm_diff ok
 The @code{wcsftime} function is equivalent to the @code{strftime}
 function with the difference that it operates on wide character
 strings.  The buffer where the result is stored, pointed to by @var{s},
@@ -1456,6 +1748,32 @@ which is defined and implemented in terms of calls to @code{strptime}.
 @comment time.h
 @comment XPG4
 @deftypefun {char *} strptime (const char *@var{s}, const char *@var{fmt}, struct tm *@var{tp})
+@safety{@prelim{}@mtsafe{@mtsenv{} @mtslocale{}}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsmem{} @acsfd{}}}
+@c strptime @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@c  strptime_internal @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@c   memset dup ok
+@c   ISSPACE ok
+@c    isspace_l dup ok
+@c   match_char ok
+@c   match_string ok
+@c    strlen dup ok
+@c    strncasecmp_l dup ok
+@c   strcmp dup ok
+@c   recursive @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@c    strptime_internal dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@c   get_number ok
+@c    ISSPACE dup ok
+@c   localtime_r dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@c   nl_select_era_entry @ascuheap @asulock @acsmem @aculock
+@c    nl_init_era_entries dup @ascuheap @asulock @acsmem @aculock
+@c   get_alt_number dup @ascuheap @asulock @acsmem @aculock
+@c    nl_parse_alt_digit dup @ascuheap @asulock @acsmem @aculock
+@c     libc_rwlock_wrlock dup @asulock @aculock
+@c     nl_init_alt_digit dup @ascuheap @acsmem
+@c     libc_rwlock_unlock dup @aculock
+@c    get_number dup ok
+@c   day_of_the_week ok
+@c   day_of_the_year ok
 The @code{strptime} function parses the input string @var{s} according
 to the format string @var{fmt} and stores its results in the
 structure @var{tp}.
@@ -1869,6 +2187,9 @@ in a @code{time_t} variable.
 @comment time.h
 @comment Unix98
 @deftypefun {struct tm *} getdate (const char *@var{string})
+@safety{@prelim{}@mtunsafe{@mtasurace{:getdate} @mtsenv{} @mtslocale{}}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsmem{} @acsfd{}}}
+@c getdate @mtasurace{:getdate} @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@c  getdate_r dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
 The interface to @code{getdate} is the simplest possible for a function
 to parse a string and return the value.  @var{string} is the input
 string and the result is returned in a statically-allocated variable.
@@ -1980,6 +2301,30 @@ any arbitrary file and chances are high that with some bogus input
 @comment time.h
 @comment GNU
 @deftypefun int getdate_r (const char *@var{string}, struct tm *@var{tp})
+@safety{@prelim{}@mtsafe{@mtsenv{} @mtslocale{}}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsmem{} @acsfd{}}}
+@c getdate_r @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@c  getenv dup @mtsenv
+@c  stat64 dup ok
+@c  access dup ok
+@c  fopen dup @ascuheap @asulock @acsmem @acsfd @aculock
+@c  fsetlocking dup ok [no @mtasurace:stream @asulock, exclusive]
+@c  isspace dup @mtslocale
+@c  strlen dup ok
+@c  malloc dup @ascuheap @acsmem
+@c  fclose dup @ascuheap @asulock @aculock @acsmem @acsfd
+@c  memcpy dup ok
+@c  getline dup @ascuheap @acsmem [no @asucorrupt @aculock @acucorrupt, exclusive]
+@c  strptime dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@c  feof_unlocked dup ok
+@c  free dup @ascuheap @acsmem
+@c  ferror_unlocked dup dup ok
+@c  time dup ok
+@c  localtime_r dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@c  first_wday @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@c   memset dup ok
+@c   mktime dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@c  check_mday ok
+@c  mktime dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
 The @code{getdate_r} function is the reentrant counterpart of
 @code{getdate}.  It does not use the global variable @code{getdate_err}
 to signal an error, but instead returns an error code.  The same error
@@ -2215,6 +2560,11 @@ lead to trouble.
 @comment time.h
 @comment POSIX.1
 @deftypefun void tzset (void)
+@safety{@prelim{}@mtsafe{@mtsenv{} @mtslocale{}}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsmem{} @acsfd{}}}
+@c tzset @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@c  libc_lock_lock dup @asulock @aculock
+@c  tzset_internal dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@c  libc_lock_unlock dup @aculock
 The @code{tzset} function initializes the @code{tzname} variable from
 the value of the @code{TZ} environment variable.  It is not usually
 necessary for your program to call this function, because it is called
@@ -2302,7 +2652,7 @@ timer sends a @code{SIGPROF} signal to the process when it expires.
 This timer is useful for profiling in interpreters.  The interval timer
 mechanism does not have the fine granularity necessary for profiling
 native code.
-@c @xref{profil} !!!
+@c @xrefprofil !!!
 @end itemize
 
 You can only have one timer of each kind set at any given time.  If you
@@ -2353,6 +2703,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{@prelim{}@mtsafe{@mtutimer{}}@assafe{}@acsafe{}}
+@c This function is marked with @mtutimer because the same set of timers
+@c is shared by all threads of a process, so calling it in one thread
+@c may interfere with timers set by another thread.  This interference
+@c is 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}.
@@ -2373,6 +2732,7 @@ The timer period is too large.
 @comment sys/time.h
 @comment BSD
 @deftypefun int getitimer (int @var{which}, struct itimerval *@var{old})
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
 The @code{getitimer} function stores information about the timer specified
 by @var{which} in the structure pointed at by @var{old}.
 
@@ -2405,6 +2765,8 @@ timer.
 @comment unistd.h
 @comment POSIX.1
 @deftypefun {unsigned int} alarm (unsigned int @var{seconds})
+@safety{@prelim{}@mtsafe{@mtutimer{}}@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
@@ -2464,6 +2826,10 @@ any descriptors to wait for.
 @comment unistd.h
 @comment POSIX.1
 @deftypefun {unsigned int} sleep (unsigned int @var{seconds})
+@safety{@prelim{}@mtunsafe{@mtasusig{:SIGCHLD/Linux}}@asunsafe{}@acunsafe{@acusig{:SIGCHLD/Linux}}}
+@c On Mach, it uses ports and calls time.  On generic posix, it calls
+@c nanosleep.  On Linux, it temporarily blocks SIGCHLD, which is MT- and
+@c AS-Unsafe, and in a way that makes it AC-Unsafe (C-unsafe, even!).
 The @code{sleep} function waits for @var{seconds} or until a signal
 is delivered, whichever happens first.
 
@@ -2508,6 +2874,9 @@ the same program, because @code{sleep} does not work by means of
 @comment time.h
 @comment POSIX.1
 @deftypefun int nanosleep (const struct timespec *@var{requested_time}, struct timespec *@var{remaining})
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+@c On Linux, it's a syscall.  On Mach, it calls gettimeofday and uses
+@c ports.
 If resolution to seconds is not enough the @code{nanosleep} function can
 be used.  As the name suggests the sleep interval can be specified in
 nanoseconds.  The actual elapsed time of the sleep interval might be

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

commit f6063ddbbcb6416524716f89aeb630c753aff166
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..7cf5be2 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
@@ -64,12 +65,28 @@ the standard.
 attributes used in the creation of threads in a process.
 
 @deftypefun int pthread_getattr_default_np (pthread_attr_t *@var{attr})
+@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{}}}
+@c Takes lock around read from default_pthread_attr.
 Get the default attribute values and set @var{attr} to match.  This
 function returns @math{0} on success and a non-zero error code on
 failure.
 @end deftypefun
 
 @deftypefun int pthread_setattr_default_np (pthread_attr_t *@var{attr})
+@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsmem{}}}
+@c pthread_setattr_default_np @ascuheap @asulock @aculock @acsmem
+@c  check_sched_policy_attr ok
+@c  check_sched_priority_attr ok
+@c   sched_get_priority_min dup ok
+@c   sched_get_priority_max dup ok
+@c  check_cpuset_attr ok
+@c   determine_cpumask_size ok
+@c  check_stacksize_attr ok
+@c  lll_lock @asulock @aculock
+@c  free dup @ascuheap @acsmem
+@c  realloc dup @ascuheap @acsmem
+@c  memcpy dup ok
+@c  lll_unlock @asulock @aculock
 Set the default attribute values to match the values in @var{attr}.  The
 function returns @math{0} on success and a non-zero error code on failure.
 The following error codes are defined for this function:
@@ -82,3 +99,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=b88bb67e99a14d1b717b96d3dc8e858ab4dd593d

commit b88bb67e99a14d1b717b96d3dc8e858ab4dd593d
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/intro.texi b/manual/intro.texi
index 30c9b4a..45cce77 100644
--- a/manual/intro.texi
+++ b/manual/intro.texi
@@ -640,7 +640,9 @@ also AS-Unsafe, but the corresponding mark is omitted as redundant.
 It is thus advisable for applications using the terminal to avoid
 concurrent and reentrant interactions with it, by not using it in signal
 handlers or blocking signals that might use it, and holding a lock while
-calling these functions and interacting with the terminal.
+calling these functions and interacting with the terminal.  This lock
+should also be used for mutual exclusion with functions marked with
+@code{@mtasurace{:tcattr}}.
 
 Functions marked with @code{term} as an AC-Safety issue are supposed to
 restore terminal settings to their original state, after temporarily
diff --git a/manual/terminal.texi b/manual/terminal.texi
index 9e9c057..e24e30b 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{@prelim{}@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{@prelim{}@mtunsafe{@mtasurace{:ttyname}}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsfd{} @acsmem{}}}
+@c ttyname @mtasurace:ttyname @ascuheap @asulock @aculock @acsmem @acsfd
+@c  isatty dup ok
+@c  fstat dup ok
+@c  memcpy dup ok
+@c  getttyname @mtasurace:ttyname @ascuheap @asulock @aculock @acsmem @acsfd
+@c   opendir @ascuheap @acsmem @acsfd
+@c   readdir ok [protected by exclusive access]
+@c   strcmp dup ok
+@c   free dup @asulock @aculock @acsfd @acsmem
+@c   malloc dup @asulock @aculock @acsfd @acsmem
+@c   closedir @ascuheap @acsmem @acsfd
+@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{@prelim{}@mtsafe{}@asunsafe{@ascuheap{}}@acsafe{@acsmem{} @acsfd{}}}
+@c ttyname_r @ascuheap @acsmem @acsfd
+@c  isatty dup ok
+@c  fstat dup ok
+@c  memcpy dup ok
+@c  getttyname_r @ascuheap @acsmem @acsfd
+@c   opendir @ascuheap @acsmem @acsfd
+@c   readdir ok [protected by exclusive access]
+@c   strcmp dup ok
+@c   closedir @ascuheap @acsmem @acsfd
+@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{@prelim{}@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{@prelim{}@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.
@@ -1016,6 +1051,10 @@ store them:
 @comment termios.h
 @comment POSIX.1
 @deftypefun speed_t cfgetospeed (const struct termios *@var{termios-p})
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+@c Direct access to a single termios field, except on Linux, where
+@c multiple accesses may take place.  No worries either way, callers
+@c must ensure mutual exclusion on such non-opaque types.
 This function returns the output line speed stored in the structure
 @code{*@var{termios-p}}.
 @end deftypefun
@@ -1023,6 +1062,7 @@ This function returns the output line speed stored in the structure
 @comment termios.h
 @comment POSIX.1
 @deftypefun speed_t cfgetispeed (const struct termios *@var{termios-p})
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
 This function returns the input line speed stored in the structure
 @code{*@var{termios-p}}.
 @end deftypefun
@@ -1030,6 +1070,7 @@ This function returns the input line speed stored in the structure
 @comment termios.h
 @comment POSIX.1
 @deftypefun int cfsetospeed (struct termios *@var{termios-p}, speed_t @var{speed})
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
 This function stores @var{speed} in @code{*@var{termios-p}} as the output
 speed.  The normal return value is @math{0}; a value of @math{-1}
 indicates an error.  If @var{speed} is not a speed, @code{cfsetospeed}
@@ -1039,6 +1080,7 @@ returns @math{-1}.
 @comment termios.h
 @comment POSIX.1
 @deftypefun int cfsetispeed (struct termios *@var{termios-p}, speed_t @var{speed})
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
 This function stores @var{speed} in @code{*@var{termios-p}} as the input
 speed.  The normal return value is @math{0}; a value of @math{-1}
 indicates an error.  If @var{speed} is not a speed, @code{cfsetospeed}
@@ -1048,6 +1090,14 @@ returns @math{-1}.
 @comment termios.h
 @comment BSD
 @deftypefun int cfsetspeed (struct termios *@var{termios-p}, speed_t @var{speed})
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+@c There's no guarantee that the two calls are atomic, but since this is
+@c not an opaque type, callers ought to ensure mutual exclusion to the
+@c termios object.
+
+@c cfsetspeed ok
+@c  cfsetispeed ok
+@c  cfsetospeed ok
 This function stores @var{speed} in @code{*@var{termios-p}} as both the
 input and output speeds.  The normal return value is @math{0}; a value
 of @math{-1} indicates an error.  If @var{speed} is not a speed,
@@ -1625,6 +1675,10 @@ uses.
 @comment termios.h
 @comment BSD
 @deftypefun void cfmakeraw (struct termios *@var{termios-p})
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+@c There's no guarantee the changes are atomic, but since this is not an
+@c opaque type, callers ought to ensure mutual exclusion to the termios
+@c object.
 This function provides an easy way to set up @code{*@var{termios-p}} for
 what has traditionally been called ``raw mode'' in BSD.  This uses
 noncanonical input, and turns off most processing to give an unmodified
@@ -1678,6 +1732,8 @@ Various flags
 @comment sgtty.h
 @comment BSD
 @deftypefun int gtty (int @var{filedes}, struct sgttyb *@var{attributes})
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+@c Direct ioctl, BSD only.
 This function gets the attributes of a terminal.
 
 @code{gtty} sets *@var{attributes} to describe the terminal attributes
@@ -1687,6 +1743,8 @@ of the terminal which is open with file descriptor @var{filedes}.
 @comment sgtty.h
 @comment BSD
 @deftypefun int stty (int @var{filedes}, const struct sgttyb *@var{attributes})
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+@c Direct ioctl, BSD only.
 
 This function sets the attributes of a terminal.
 
@@ -1710,6 +1768,12 @@ operation is performed and no signal is sent.  @xref{Job Control}.
 @comment termios.h
 @comment POSIX.1
 @deftypefun int tcsendbreak (int @var{filedes}, int @var{duration})
+@safety{@prelim{}@mtunsafe{@mtasurace{:filedes::brk/BSD}}@asunsafe{}@acunsafe{@acucorrupt{/BSD}}}
+@c On Linux, this calls just one out of two ioctls; on BSD, it's two
+@c ioctls with a select (for the delay only) in between, the first
+@c setting and the latter clearing the break status.  The BSD
+@c implementation may leave the break enabled if cancelled, and threads
+@c and signals may cause the break to be interrupted before requested.
 This function generates a break condition by transmitting a stream of
 zero bits on the terminal associated with the file descriptor
 @var{filedes}.  The duration of the break is controlled by the
@@ -1738,6 +1802,8 @@ The @var{filedes} is not associated with a terminal device.
 @comment termios.h
 @comment POSIX.1
 @deftypefun int tcdrain (int @var{filedes})
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+@c Direct ioctl.
 The @code{tcdrain} function waits until all queued
 output to the terminal @var{filedes} has been transmitted.
 
@@ -1772,6 +1838,8 @@ The operation was interrupted by delivery of a signal.
 @comment termios.h
 @comment POSIX.1
 @deftypefun int tcflush (int @var{filedes}, int @var{queue})
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+@c Direct ioctl.
 The @code{tcflush} function is used to clear the input and/or output
 queues associated with the terminal file @var{filedes}.  The @var{queue}
 argument specifies which queue(s) to clear, and can be one of the
@@ -1822,6 +1890,11 @@ from POSIX and we cannot change it.
 @comment termios.h
 @comment POSIX.1
 @deftypefun int tcflow (int @var{filedes}, int @var{action})
+@safety{@prelim{}@mtunsafe{@mtasurace{:tcattr(filedes)/BSD}}@asunsafe{}@acsafe{}}
+@c Direct ioctl on Linux.  On BSD, the TCO* actions are a sngle ioctl,
+@c whereas the TCI actions first call tcgetattr and then write to the fd
+@c the c_cc character corresponding to the action; there's a window for
+@c another thread to change the xon/xoff characters.
 The @code{tcflow} function is used to perform operations relating to
 XON/XOFF flow control on the terminal file specified by @var{filedes}.
 
@@ -1931,6 +2004,14 @@ functions are declared in the header file @file{stdlib.h}.
 @comment stdlib.h
 @comment GNU
 @deftypefun int getpt (void)
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{@acsfd{}}}
+@c On BSD, tries to open multiple potential pty names, returning on the
+@c first success.  On Linux, try posix_openpt first, then fallback to
+@c the BSD implementation.  The posix implementation opens the ptmx
+@c device, checks with statfs that /dev/pts is a devpts or that /dev is
+@c a devfs, and returns the fd; static variables devpts_mounted and
+@c have_no_dev_ptmx are safely initialized so as to avoid repeated
+@c tests.
 The @code{getpt} function returns a new file descriptor for the next
 available master pseudo-terminal.  The normal return value from
 @code{getpt} is a non-negative integer file descriptor.  In the case of
@@ -1948,6 +2029,32 @@ This function is a GNU extension.
 @comment stdlib.h
 @comment SVID, XPG4.2
 @deftypefun int grantpt (int @var{filedes})
+@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
+@c grantpt @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c  unix/grantpt:pts_name @acsuheap @acsmem
+@c   ptsname_internal dup ok (but this is Linux-only!)
+@c   memchr dup ok
+@c   realloc dup @acsuheap @acsmem
+@c   malloc dup @acsuheap @acsmem
+@c   free dup @acsuheap @acsmem
+@c  fcntl dup ok
+@c  getuid dup ok
+@c  chown dup ok
+@c  sysconf(_SC_GETGR_R_SIZE_MAX) ok
+@c  getgrnam_r @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c  getgid dup ok
+@c  chmod dup ok
+@c  fork dup @aculock
+@c  [child]
+@c   setrlimit
+@c   dup2
+@c   CLOSE_ALL_FDS
+@c   execle
+@c   _exit
+@c  waitpid dup ok
+@c  WIFEXITED dup ok
+@c  WEXITSTATUS dup ok
+@c  free dup @ascuheap @acsmem
 The @code{grantpt} function changes the ownership and access permission
 of the slave pseudo-terminal device corresponding to the master
 pseudo-terminal device associated with the file descriptor
@@ -1985,6 +2092,13 @@ with @var{filedes} could not be accessed.
 @comment stdlib.h
 @comment SVID, XPG4.2
 @deftypefun int unlockpt (int @var{filedes})
+@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{/BSD}}@acunsafe{@acsmem{} @acsfd{}}}
+@c unlockpt @ascuheap/BSD @acsmem @acsfd
+@c /BSD
+@c  ptsname_r dup @ascuheap @acsmem @acsfd
+@c  revoke ok (syscall)
+@c /Linux
+@c  ioctl dup ok
 The @code{unlockpt} function unlocks the slave pseudo-terminal device
 corresponding to the master pseudo-terminal device associated with the
 file descriptor @var{filedes}.  On many systems, the slave can only be
@@ -2008,6 +2122,9 @@ device.
 @comment stdlib.h
 @comment SVID, XPG4.2
 @deftypefun {char *} ptsname (int @var{filedes})
+@safety{@prelim{}@mtunsafe{@mtasurace{:ptsname}}@asunsafe{@ascuheap{/BSD}}@acunsafe{@acsmem{} @acsfd{}}}
+@c ptsname @mtasurace{:ptsname} @ascuheap/BSD @acsmem @acsfd
+@c  ptsname_r dup @ascuheap/BSD @acsmem @acsfd
 If the file descriptor @var{filedes} is associated with a
 master pseudo-terminal device, the @code{ptsname} function returns a
 pointer to a statically-allocated, null-terminated string containing the
@@ -2018,6 +2135,37 @@ might be overwritten by subsequent calls to @code{ptsname}.
 @comment stdlib.h
 @comment GNU
 @deftypefun int ptsname_r (int @var{filedes}, char *@var{buf}, size_t @var{len})
+@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{/BSD}}@acunsafe{@acsmem{} @acsfd{}}}
+@c ptsname_r @ascuheap/BSD @acsmem @acsfd
+@c /HURD
+@c  term_get_peername ok
+@c  strlen dup ok
+@c  memcpy dup ok
+@c /BSD
+@c  isatty dup ok
+@c  strlen dup ok
+@c  ttyname_r dup @ascuheap @acsmem @acsfd
+@c  stat dup ok
+@c /Linux
+@c  ptsname_internal ok
+@c   isatty dup ok
+@c   ioctl dup ok
+@c   strlen dup ok
+@c   itoa_word dup ok
+@c   stpcpy dup ok
+@c   memcpy dup ok
+@c   fxstat64 dup ok
+@c   MASTER_P ok
+@c    major ok
+@c     gnu_dev_major ok
+@c    minor ok
+@c     gnu_dev_minor ok
+@c   minor dup ok
+@c   xstat64 dup ok
+@c   S_ISCHR dup ok
+@c   SLAVE_P ok
+@c    major dup ok
+@c    minor dup ok
 The @code{ptsname_r} function is similar to the @code{ptsname} function
 except that it places its result into the user-specified buffer starting
 at @var{buf} with length @var{len}.
@@ -2083,6 +2231,22 @@ These functions, derived from BSD, are available in the separate
 @comment pty.h
 @comment BSD
 @deftypefun int openpty (int *@var{amaster}, int *@var{aslave}, char *@var{name}, const struct termios *@var{termp}, const struct winsize *@var{winp})
+@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
+@c openpty @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c  getpt @acsfd
+@c  grantpt @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c  unlockpt dup @ascuheap/BSD @acsmem @acsfd
+@c  openpty:pts_name @acsuheap @acsmem @acsfd
+@c   ptsname_r dup @ascuheap/BSD @acsmem @acsfd
+@c   realloc dup @acsuheap @acsmem
+@c   malloc dup @acsuheap @acsmem
+@c   free dup @acsuheap @acsmem
+@c  open dup @acsfd
+@c  free dup @acsuheap @acsmem
+@c  tcsetattr dup ok
+@c  ioctl dup ok
+@c  strcpy dup ok
+@c  close dup @acsfd
 This function allocates and opens a pseudo-terminal pair, returning the
 file descriptor for the master in @var{*amaster}, and the file
 descriptor for the slave in @var{*aslave}.  If the argument @var{name}
@@ -2114,6 +2278,16 @@ device instead.
 @comment pty.h
 @comment BSD
 @deftypefun int forkpty (int *@var{amaster}, char *@var{name}, const struct termios *@var{termp}, const struct winsize *@var{winp})
+@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
+@c forkpty @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c  openpty dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c  fork dup @aculock
+@c  close dup @acsfd
+@c  /child
+@c   close dup @acsfd
+@c   login_tty dup @mtasurace:ttyname @ascuheap @asulock @aculock @acsmem @acsfd
+@c   _exit dup ok
+@c  close dup @acsfd
 This function is similar to the @code{openpty} function, but in
 addition, forks a new process (@pxref{Creating a Process}) and makes the
 newly opened slave pseudo-terminal device the controlling terminal

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

commit 8d013c18a7836cac150e4a03c35732cf59143f39
Author: Alexandre Oliva <aoliva@redhat.com>
Date:   Sat Jan 4 02:56:20 2014 -0200

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

diff --git a/manual/syslog.texi b/manual/syslog.texi
index 4e64d2a..ad6523c 100644
--- a/manual/syslog.texi
+++ b/manual/syslog.texi
@@ -147,6 +147,17 @@ The symbols referred to in this section are declared in the file
 @comment syslog.h
 @comment BSD
 @deftypefun void openlog (const char *@var{ident}, int @var{option}, int @var{facility})
+@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{} @acsfd{}}}
+@c openlog @asulock @aculock @acsfd
+@c  libc_lock_lock @asulock @aculock
+@c  openlog_internal @acsfd [always guarded by syslog_lock, so no race]
+@c   strncpy dup ok
+@c   socket dup @acsfd
+@c   fcntl dup ok
+@c   connect dup ok
+@c   close dup @acsfd
+@c  cancel_handler(NULL) @aculock
+@c   libc_lock_unlock @aculock
 
 @code{openlog} opens or reopens a connection to Syslog in preparation
 for submitting messages.
@@ -276,6 +287,38 @@ The symbols referred to in this section are declared in the file
 @comment syslog.h
 @comment BSD
 @deftypefun void syslog (int @var{facility_priority}, const char *@var{format}, @dots{})
+@safety{@prelim{}@mtsafe{@mtsenv{} @mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{} @asulock{} @ascudlopen{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{} @acsfd{}}}
+@c syslog @mtsenv @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
+@c  va_start dup ok
+@c  vsyslog_chk @mtsenv @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
+@c   syslog(INTERNALLOG) dup @mtsenv @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
+@c   open_memstream @ascuheap @acsmem
+@c   stpcpy dup ok
+@c   getpid dup ok
+@c   mempcpy dup ok
+@c   fsetlocking [no @mtasurace:stream @asulock for exclusive stream]
+@c   fprintf @mtslocale @ascuheap @acsmem [no @asucorrupt @aculock @acucorrupt on temp memstream]
+@c   time dup ok
+@c   localtime_r dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@c   strftime_l(C) dup @mtsenv @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
+@c   ftell dup ok [no @asucorrupt @aculock @acucorrupt on temp memstream] 
+@c   fputs_unlocked [no @mtasurace:stream @asucorrupt @acucorrupt on temp memstream] 
+@c   putc_unlocked [no @mtasurace:stream @asucorrupt @acucorrupt on temp memstream] 
+@c   vfprintf/vfprintf_chk @mtslocale @ascuheap @acsmem [no @mtasurace:stream @asucorrupt @acucorrupt on temp memstream] 
+@c   fclose dup @ascuheap @acsmem [no @asulock @aculock @acsfd on caller-locked memstream]
+@c   writev dup ok
+@c   libc_lock_lock dup @asulock @aculock
+@c   memset dup ok
+@c   sigemptyset dup ok
+@c   sigaction(SIGPIPE) dup @mtasusig:PIPE @acusig:PIPE
+@c   openlog_internal dup @acsfd
+@c   send dup ok
+@c   closelog_internal dup @acsfd
+@c   open dup @acsfd
+@c   dprintf dup ok
+@c   libc_lock_unlock @asulock @aculock
+@c   free dup @acsuheap @acsmem
+@c  va_end dup ok
 
 @code{syslog} submits a message to the Syslog facility.  It does this by
 writing to the Unix domain socket @code{/dev/log}.
@@ -404,6 +447,9 @@ syslog (LOG_MAKEPRI(LOG_LOCAL1, LOG_ERROR),
 @comment syslog.h
 @comment BSD
 @deftypefun void vsyslog (int @var{facility_priority}, const char *@var{format}, va_list @var{arglist})
+@safety{@prelim{}@mtsafe{@mtsenv{} @mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{} @asulock{} @ascudlopen{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{} @acsfd{}}}
+@c vsyslog @mtsenv @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
+@c  vsyslog_chk dup @mtsenv @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
 
 This is functionally identical to @code{syslog}, with the BSD style variable
 length argument.
@@ -420,6 +466,13 @@ The symbols referred to in this section are declared in the file
 @comment syslog.h
 @comment BSD
 @deftypefun void closelog (void)
+@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{} @acsfd{}}}
+@c closelog @asulock @aculock @acsfd
+@c  libc_lock_lock @asulock @aculock
+@c  closelog_internal @acsfd [always guarded by syslog_lock, so no race]
+@c   close dup@acsfd
+@c  cancel_handler(NULL) @aculock
+@c   libc_lock_unlock @aculock
 
 @code{closelog} closes the current Syslog connection, if there is one.
 This includes closing the @file{/dev/log} socket, if it is open.
@@ -450,6 +503,10 @@ The symbols referred to in this section are declared in the file
 @comment syslog.h
 @comment BSD
 @deftypefun int setlogmask (int @var{mask})
+@safety{@prelim{}@mtunsafe{@mtasurace{:LogMask}}@asunsafe{}@acsafe{}}
+@c Read and modify are not guarded by syslog_lock, so concurrent changes
+@c or even uses are undefined.  This should use an atomic swap instead,
+@c at least for modifications.
 
 @code{setlogmask} sets a mask (the ``logmask'') that determines which
 future @code{syslog} calls shall be ignored.  If a program has not

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

commit 9caeb3db94c49f204639201ba0e00ccf7d01a176
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 5b6e8d0..9212d34 100644
--- a/manual/sysinfo.texi
+++ b/manual/sysinfo.texi
@@ -91,6 +91,9 @@ by calling these functions.
 @comment unistd.h
 @comment BSD
 @deftypefun int gethostname (char *@var{name}, size_t @var{size})
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+@c Direct syscall on unix; implemented in terms of uname on posix and of
+@c hurd_get_host_config on hurd.
 This function returns the host name of the system on which it is called,
 in the array @var{name}.  The @var{size} argument specifies the size of
 this array, in bytes.  Note that this is @emph{not} the DNS hostname.
@@ -121,6 +124,9 @@ error code.
 @comment unistd.h
 @comment BSD
 @deftypefun int sethostname (const char *@var{name}, size_t @var{length})
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+@c Direct syscall on unix; implemented in terms of hurd_set_host_config
+@c on hurd.
 The @code{sethostname} function sets the host name of the system that
 calls it to @var{name}, a string with length @var{length}.  Only
 privileged processes are permitted to do this.
@@ -145,6 +151,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{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+@c Syscalls uname, then strlen and memcpy.
 @cindex NIS domain name
 @cindex YP domain name
 
@@ -159,6 +167,8 @@ The specifics of this function are analogous to @code{gethostname}, above.
 @comment unistd.h
 @comment ???
 @deftypefun int setdomainname (const char *@var{name}, size_t @var{length})
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+@c Direct syscall.
 @cindex NIS domain name
 @cindex YP domain name
 
@@ -173,6 +183,10 @@ The specifics of this function are analogous to @code{sethostname}, above.
 @comment unistd.h
 @comment BSD
 @deftypefun {long int} gethostid (void)
+@safety{@prelim{}@mtsafe{hostid @mtsenv{} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @asucorrupt{} @ascuheap{} @asulock{}}@acunsafe{@aculock{} @acucorrupt{} @acsmem{} @acsfd{}}}
+@c On HURD, calls _hurd_get_host_config and strtol.  On Linux, open
+@c HOSTIDFILE, reads an int32_t and closes; if that fails, it calls
+@c gethostname and gethostbyname_r to use the h_addr.
 This function returns the ``host ID'' of the machine the program is
 running on.  By convention, this is usually the primary Internet IP address
 of that machine, converted to a @w{@code{long int}}.  However, on some
@@ -190,6 +204,7 @@ on the results of @code{gethostname}.  For more information on IP addresses,
 @comment unistd.h
 @comment BSD
 @deftypefun int sethostid (long int @var{id})
+@safety{@prelim{}@mtunsafe{@mtasuconst{:hostid}}@asunsafe{}@acunsafe{@acucorrupt{} @acsfd{}}}
 The @code{sethostid} function sets the ``host ID'' of the host machine
 to @var{id}.  Only privileged processes are permitted to do this.  Usually
 it happens just once, at system boot time.
@@ -296,6 +311,10 @@ use of the rest of the structure.
 @comment sys/utsname.h
 @comment POSIX.1
 @deftypefun int uname (struct utsname *@var{info})
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+@c Direct syscall on unix; the posix fallback is to call gethostname and
+@c then fills in the other fields with constants; on HURD, it calls
+@c proc_uname and then gethostname.
 The @code{uname} function fills in the structure pointed to by
 @var{info} with information about the operating system and host machine.
 A non-negative value indicates that the data was successfully stored.
@@ -471,6 +490,12 @@ contains a set of three functions which are designed in the usual way.
 @comment fstab.h
 @comment BSD
 @deftypefun int setfsent (void)
+@safety{@prelim{}@mtunsafe{@mtasurace{:fsent}}@asunsafe{@ascuheap{} @asucorrupt{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{} @acsfd{}}}
+@c setfsent @mtasurace:fsent @ascuheap @acucorrupt @asulock @acucorrupt @aculock @acsmem @acsfd
+@c  fstab_init(1) @mtasurace:fsent @ascuheap @acucorrupt @asulock @acucorrupt @aculock @acsmem @acsfd
+@c   malloc dup @ascuheap @acsmem
+@c   rewind dup @asucorrupt @acucorrupt [no @aculock]
+@c   setmntent dup @ascuheap @asulock @acsmem @acsfd @aculock
 This function makes sure that the internal read pointer for the
 @file{fstab} file is at the beginning of the file.  This is done by
 either opening the file or resetting the read pointer.
@@ -486,6 +511,9 @@ file.
 @comment fstab.h
 @comment BSD
 @deftypefun void endfsent (void)
+@safety{@prelim{}@mtunsafe{@mtasurace{:fsent}}@asunsafe{@ascuheap{} @asucorrupt{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{} @acsfd{}}}
+@c endfsent @mtasurace{:fsent} @ascuheap @asucorrupt @asulock @acucorrupt @aculock @acsmem @acsfd
+@c  endmntent dup @ascuheap @asulock @aculock @acsmem @acsfd
 This function makes sure that all resources acquired by a prior call to
 @code{setfsent} (explicitly or implicitly by calling @code{getfsent}) are
 freed.
@@ -494,6 +522,13 @@ freed.
 @comment fstab.h
 @comment BSD
 @deftypefun {struct fstab *} getfsent (void)
+@safety{@prelim{}@mtunsafe{@mtasurace{:fsent} @mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{}}}
+@c getfsent @mtasurace:fsent @mtslocale @asucorrupt @ascuheap @asulock @acucorrupt @aculock @acsmem
+@c  fstab_init(0) dup @mtasurace:fsent @ascuheap @asucorrupt @asulock @acucorrupt @aculock @acsmem @acsfd
+@c  fstab_fetch @mtasurace:fsent @mtslocale @asucorrupt @ascuheap @acucorrupt @aculock @acsmem
+@c   getmntent_r dup @mtslocale @asucorrupt @ascuheap @acucorrupt @aculock @acsmem
+@c  fstab_convert @mtasurace:fsent
+@c   hasmntopt dup ok
 This function returns the next entry of the @file{fstab} file.  If this
 is the first call to any of the functions handling @file{fstab} since
 program start or the last call of @code{endfsent}, the file will be
@@ -508,6 +543,12 @@ returns a @code{NULL} pointer.
 @comment fstab.h
 @comment BSD
 @deftypefun {struct fstab *} getfsspec (const char *@var{name})
+@safety{@prelim{}@mtunsafe{@mtasurace{:fsent} @mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{}}}
+@c getffsspec @mtasurace:fsent @mtslocale @asucorrupt @ascuheap @asulock @acucorrupt @aculock @acsmem
+@c  fstab_init(1) dup @mtasurace:fsent @ascuheap @asucorrupt @asulock @acucorrupt @aculock @acsmem @acsfd
+@c  fstab_fetch dup @mtasurace:fsent @mtslocale @asucorrupt @ascuheap @acucorrupt @aculock @acsmem
+@c  strcmp dup ok
+@c  fstab_convert dup @mtasurace:fsent
 This function returns the next entry of the @file{fstab} file which has
 a string equal to @var{name} pointed to by the @code{fs_spec} element.
 Since there is normally exactly one entry for each special device it
@@ -525,6 +566,12 @@ returns a @code{NULL} pointer.
 @comment fstab.h
 @comment BSD
 @deftypefun {struct fstab *} getfsfile (const char *@var{name})
+@safety{@prelim{}@mtunsafe{@mtasurace{:fsent} @mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{}}}
+@c getffsfile @mtasurace:fsent @mtslocale @asucorrupt @ascuheap @asulock @acucorrupt @aculock @acsmem
+@c  fstab_init(1) dup @mtasurace:fsent @ascuheap @asucorrupt @asulock @acucorrupt @aculock @acsmem @acsfd
+@c  fstab_fetch dup @mtasurace:fsent @mtslocale @asucorrupt @ascuheap @acucorrupt @aculock @acsmem
+@c  strcmp dup ok
+@c  fstab_convert dup @mtasurace:fsent
 This function returns the next entry of the @file{fstab} file which has
 a string equal to @var{name} pointed to by the @code{fs_file} element.
 Since there is normally exactly one entry for each mount point it
@@ -640,6 +687,13 @@ contains functions to alter the file and test for specific options.
 @comment mntent.h
 @comment BSD
 @deftypefun {FILE *} setmntent (const char *@var{file}, const char *@var{mode})
+@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@acsmem{} @acsfd{} @aculock{}}}
+@c setmntent @ascuheap @asulock @acsmem @acsfd @aculock
+@c  strlen dup ok
+@c  mempcpy dup ok
+@c  memcpy dup ok
+@c  fopen dup @ascuheap @asulock @acsmem @acsfd @aculock
+@c  fsetlocking dup ok [no @mtasurace:stream @asulock: exclusive stream]
 The @code{setmntent} function prepares the file named @var{FILE} which
 must be in the format of a @file{fstab} and @file{mtab} file for the
 upcoming processing through the other functions of the family.  The
@@ -655,6 +709,9 @@ and @code{errno} is set accordingly.
 @comment mntent.h
 @comment BSD
 @deftypefun int endmntent (FILE *@var{stream})
+@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsmem{} @acsfd{}}}
+@c endmntent @ascuheap @asulock @aculock @acsmem @acsfd
+@c  fclose dup @ascuheap @asulock @aculock @acsmem @acsfd
 This function takes for the @var{stream} parameter a file handle which
 previously was returned from the @code{setmntent} call.
 @code{endmntent} closes the stream and frees all resources.
@@ -666,6 +723,12 @@ is @math{0}.
 @comment mntent.h
 @comment BSD
 @deftypefun {struct mntent *} getmntent (FILE *@var{stream})
+@safety{@prelim{}@mtunsafe{@mtasurace{:mntentbuf} @mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{} @asuinit{}}@acunsafe{@acuinit{} @acucorrupt{} @aculock{} @acsmem{}}}
+@c getmntent @mtasurace:mntentbuf @mtslocale @asucorrupt @ascuheap @asuinit @acuinit @acucorrupt @aculock @acsmem
+@c  libc_once @ascuheap @asuinit @acuinit @acsmem
+@c   allocate @ascuheap @acsmem
+@c    malloc dup @ascuheap @acsmem
+@c  getmntent_r dup @mtslocale @asucorrupt @ascuheap @acucorrupt @aculock @acsmem
 The @code{getmntent} function takes as the parameter a file handle
 previously returned by successful call to @code{setmntent}.  It returns
 a pointer to a static variable of type @code{struct mntent} which is
@@ -692,6 +755,16 @@ used in situations where multiple threads access the file.
 @comment mntent.h
 @comment BSD
 @deftypefun {struct mntent *} getmntent_r (FILE *@var{stream}, struct mntent *@var{result}, char *@var{buffer}, int @var{bufsize})
+@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{}}}
+@c getmntent_r @mtslocale @asucorrupt @ascuheap @acucorrupt @aculock @acsmem
+@c  flockfile dup @aculock
+@c  fgets_unlocked dup @asucorrupt @acucorrupt [locked, so no @mtsrace:stream]
+@c  funlockfile dup @aculock
+@c  strchr dup ok
+@c  strspn dup ok
+@c  strsep dup ok
+@c  decode_name ok
+@c  sscanf dup @mtslocale @ascuheap @acsmem
 The @code{getmntent_r} function is the reentrant variant of
 @code{getmntent}.  It also returns the next entry from the file and
 returns a pointer.  The actual variable the values are stored in is not
@@ -717,6 +790,12 @@ end of file reached,
 @comment mntent.h
 @comment BSD
 @deftypefun int addmntent (FILE *@var{stream}, const struct mntent *@var{mnt})
+@safety{@prelim{}@mtunsafe{@mtasurace{:stream} @mtslocale{}}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{}}}
+@c addmntent @mtasurace:stream @mtslocale @asucorrupt @acucorrupt
+@c  fseek dup @asucorrupt @acucorrupt [no @aculock]
+@c  encode_name ok
+@c  fprintf dup @mtslocale @asucorrupt @acucorrupt [no @ascuheap @acsmem, no @aculock]
+@c  fflush dup @asucorrupt @acucorrupt [no @aculock]
 The @code{addmntent} function allows adding a new entry to the file
 previously opened with @code{setmntent}.  The new entries are always
 appended.  I.e., even if the position of the file descriptor is not at
@@ -740,6 +819,11 @@ appropriately.
 @comment mntent.h
 @comment BSD
 @deftypefun {char *} hasmntopt (const struct mntent *@var{mnt}, const char *@var{opt})
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+@c hasmntopt ok
+@c  strlen dup ok
+@c  strstr dup ok
+@c  strchr dup ok
 This function can be used to check whether the string pointed to by the
 @code{mnt_opts} element of the variable pointed to by @var{mnt} contains
 the option @var{opt}.  If this is true a pointer to the beginning of the
@@ -778,6 +862,8 @@ The symbols in this section are declared in @file{sys/mount.h}.
 @comment sys/mount.h
 @comment SVID, BSD
 @deftypefun {int} mount (const char *@var{special_file}, const char *@var{dir}, const char *@var{fstype}, unsigned long int @var{options}, const void *@var{data})
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+@c Direct syscall.
 
 @code{mount} mounts or remounts a filesystem.  The two operations are
 quite different and are merged rather unnaturally into this one function.
@@ -982,6 +1068,8 @@ not one that uses a device.
 @comment sys/mount.h
 @comment GNU
 @deftypefun {int} umount2 (const char *@var{file}, int @var{flags})
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+@c Direct syscall.
 
 @code{umount2} unmounts a filesystem.
 
@@ -1047,6 +1135,8 @@ This function is not available on all systems.
 @comment sys/mount.h
 @comment SVID, GNU
 @deftypefun {int} umount (const char *@var{file})
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+@c Direct syscall or wrapper for umount2.
 
 @code{umount} does the same thing as @code{umount2} with @var{flags} set
 to zeroes.  It is more widely available than @code{umount2} but since it
@@ -1067,6 +1157,8 @@ The symbols used in this section are declared in the file @file{sys/sysctl.h}.
 @comment sys/sysctl.h
 @comment BSD
 @deftypefun int sysctl (int *@var{names}, int @var{nlen}, void *@var{oldval}, size_t *@var{oldlenp}, void *@var{newval}, size_t @var{newlen})
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+@c Direct syscall, Linux only.
 
 @code{sysctl} gets or sets a specified system parameter.  There are so
 many of these parameters that it is not practical to list them all here,

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

commit d2cd82eeb239ac9be9d200d6a68032c226299ce0
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 e59f18c..f59ce1e 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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@mtsafe{}@asunsafe{@ascuheap{}}@acsafe{@acsmem{}}}
 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{@prelim{}@mtsafe{}@asunsafe{@ascuheap{}}@acsafe{@acsmem{}}}
 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{@prelim{}@mtsafe{}@asunsafe{@ascuheap{}}@acsafe{@acsmem{}}}
 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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@mtsafe{@mtslocale{}}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@mtsafe{@mtslocale{}}@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{@prelim{}@mtsafe{@mtslocale{}}@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{@prelim{}@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{@prelim{}@mtsafe{}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{}}}
+@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{@prelim{}@mtsafe{}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{}}}
+@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{@prelim{}@mtsafe{}@asunsafe{@ascuheap{}}@acsafe{@acsmem{}}}
 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{@prelim{}@mtsafe{}@asunsafe{@ascuheap{}}@acsafe{@acsmem{}}}
 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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
 @code{wcswcs} is a 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{@prelim{}@mtsafe{@mtslocale{}}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@mtunsafe{@mtasurace{}}@asunsafe{@mtasurace{}}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@mtunsafe{@mtasurace{}}@asunsafe{@mtasurace{}}@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{@prelim{}@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{@prelim{}@mtsafe{}@asunsafe{@ascuheap{}}@acsafe{@acsmem{}}}
 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{@prelim{}@mtsafe{}@asunsafe{@ascuheap{}}@acsafe{@acsmem{}}}
 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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@mtsafe{}@asunsafe{@ascuheap{}}@acsafe{@acsmem{}}}
+@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{@prelim{}@mtsafe{}@asunsafe{@ascuheap{}}@acsafe{@acsmem{}}}
 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{@prelim{}@mtsafe{}@asunsafe{@ascuheap{}}@acsafe{@acsmem{}}}
 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{@prelim{}@mtsafe{}@asunsafe{@ascuheap{}}@acsafe{@acsmem{}}}
+@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{@prelim{}@mtsafe{}@asunsafe{@ascuheap{}}@acsafe{@acsmem{}}}
+@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{@prelim{}@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{@prelim{}@mtsafe{}@asunsafe{@ascuheap{}}@acsafe{@acsmem{}}}
 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{@prelim{}@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{@prelim{}@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{@prelim{}@mtsafe{}@asunsafe{@ascuheap{}}@acsafe{@acsmem{}}}
+@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{@prelim{}@mtsafe{}@asunsafe{@ascuheap{}}@acsafe{@acsmem{}}}
 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{@prelim{}@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=0e8c27c9e649adc1cd5fe65558c1ba9270615527

commit 0e8c27c9e649adc1cd5fe65558c1ba9270615527
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 7957a2a..babb20c 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{@prelim{}@mtsafe{}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@acsmem{} @acsfd{} @aculock{}}}
+@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{@prelim{}@mtsafe{}@asunsafe{@ascuheap{} @asulock{}}@acsafe{@acsmem{} @acsfd{} @aculock{}}}
 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{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{} @acsfd{}}}
+@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{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{} @acsfd{}}}
 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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@mtsafe{}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsmem{} @acsfd{}}}
+@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{@prelim{}@mtunsafe{@mtasurace{}}@asunsafe{@mtasurace{}}@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{@prelim{}@mtsafe{}@assafe{}@acunsafe{@aculock{}}}
+@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{@prelim{}@mtsafe{}@assafe{}@acunsafe{@aculock{}}}
 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{@prelim{}@mtsafe{}@assafe{}@acunsafe{@aculock{}}}
 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{@prelim{}@mtunsafe{@mtasurace{:stream}}@asunsafe{@asulock{}}@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{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@aculock{}}}
+@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{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{} @aculock{}}}
+@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{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{} @aculock{}}}
 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{@prelim{}@mtunsafe{@mtasurace{:stream}}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{}}}
+@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{@prelim{}@mtunsafe{@mtasurace{:stream}}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{}}}
 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{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{} @aculock{}}}
 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{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{} @aculock{}}}
 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{@prelim{}@mtunsafe{@mtasurace{:stream}}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{}}}
 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{@prelim{}@mtunsafe{@mtasurace{:stream}}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{}}}
 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{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{} @aculock{}}}
 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{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{} @aculock{}}}
 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{@prelim{}@mtunsafe{@mtasurace{:stream}}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{}}}
 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{@prelim{}@mtunsafe{@mtasurace{:stream}}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{}}}
 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{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{} @aculock{}}}
 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{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{} @aculock{}}}
 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{@prelim{}@mtunsafe{@mtasurace{:stream}}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{}}}
 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{@prelim{}@mtunsafe{@mtasurace{:stream}}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{}}}
 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{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@aculock{} @acucorrupt{}}}
 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{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@aculock{} @acucorrupt{}}}
 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{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@aculock{} @acucorrupt{}}}
+@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{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@aculock{} @acucorrupt{}}}
 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{@prelim{}@mtunsafe{@mtasurace{:stream}}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{}}}
 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{@prelim{}@mtunsafe{@mtasurace{:stream}}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{}}}
 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{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@aculock{} @acucorrupt{}}}
 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{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@aculock{} @acucorrupt{}}}
 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{@prelim{}@mtunsafe{@mtasurace{:stream}}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{}}}
 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{@prelim{}@mtunsafe{@mtasurace{:stream}}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{}}}
 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{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@aculock{} @acucorrupt{}}}
 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{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@aculock{} @acucorrupt{}}}
 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{@prelim{}@mtunsafe{@mtasurace{:stream}}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{}}}
 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{@prelim{}@mtunsafe{@mtasurace{:stream}}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{}}}
 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{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@aculock{} @acucorrupt{}}}
 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{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{} @ascuheap{}}@acunsafe{@aculock{} @acucorrupt{} @acsmem{}}}
+@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 @acucorrupt.
 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{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{} @ascuheap{}}@acunsafe{@aculock{} @acucorrupt{} @acsmem{}}}
+@c See the getline @acucorrupt 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{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@aculock{} @acucorrupt{}}}
 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{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@aculock{} @acucorrupt{}}}
 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{@prelim{}@mtunsafe{@mtasurace{:stream}}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{}}}
 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{@prelim{}@mtunsafe{@mtasurace{:stream}}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{}}}
 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{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@aculock{} @acucorrupt{}}}
 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{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@aculock{} @acucorrupt{}}}
 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{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@aculock{} @acucorrupt{}}}
 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{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@aculock{} @acucorrupt{}}}
 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{@prelim{}@mtunsafe{@mtasurace{:stream}}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{}}}
 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{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@aculock{} @acucorrupt{}}}
 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{@prelim{}@mtunsafe{@mtasurace{:stream}}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{}}}
 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{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{}}@acunsafe{@acsmem{} @aculock{} @acucorrupt{}}}
 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{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{}}@acunsafe{@acsmem{} @aculock{} @acucorrupt{}}}
 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{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{}}@acunsafe{@acsmem{} @aculock{} @acucorrupt{}}}
 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{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{}}@acunsafe{@acsmem{} @aculock{} @acucorrupt{}}}
 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{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@ascuheap{} @mtslocale{}}@acsafe{@acsmem{}}}
 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{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@ascuheap{}}@acsafe{@acsmem{}}}
 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 a 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{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@ascuheap{}}@acsafe{@acsmem{}}}
 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{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@ascuheap{}}@acsafe{@acsmem{}}}
 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{@prelim{}@mtunsafe{@mtsrace{} @mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{}}@acsafe{@acucorrupt{} @acsmem{}}}
 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{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{}}@acunsafe{@acsmem{} @aculock{} @acucorrupt{}}}
 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{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{}}@acunsafe{@acsmem{} @aculock{} @acucorrupt{}}}
 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{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{}}@acunsafe{@acsmem{} @aculock{} @acucorrupt{}}}
+@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 @mtslocale
+@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 @mtslocale @ascuheap @acsmem
+@c __printf_fphex @mtslocale
+@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{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{}}@acunsafe{@acsmem{} @aculock{} @acucorrupt{}}}
 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{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@ascuheap{}}@acsafe{@acsmem{}}}
 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{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@ascuheap{}}@acsafe{@acsmem{}}}
 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{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@ascuheap{}}@acsafe{@acsmem{}}}
 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{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@ascuheap{}}@acsafe{@acsmem{}}}
 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{@prelim{}@mtunsafe{@mtsrace{} @mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{}}@acsafe{@acucorrupt{} @acsmem{}}}
+@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{@prelim{}@mtsafe{@mtslocale{}}@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{@prelim{}@mtunsafe{@mtasuconst{}}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@acsmem{} @aculock{}}}
+@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{@prelim{}@mtunsafe{@mtsrace{} @mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{}}@acunsafe{@acsmem{} @acucorrupt{}}}
+@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{@prelim{}@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.
@@ -3803,6 +4005,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{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{}}@acunsafe{@acsmem{} @aculock{} @acucorrupt{}}}
 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
@@ -3817,6 +4020,7 @@ template, then @code{EOF} is returned.
 @comment wchar.h
 @comment ISO
 @deftypefun int wscanf (const wchar_t *@var{template}, @dots{})
+@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{}}@acunsafe{@acsmem{} @aculock{} @acucorrupt{}}}
 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
@@ -3831,6 +4035,7 @@ template, then @code{WEOF} is returned.
 @comment stdio.h
 @comment ISO
 @deftypefun int fscanf (FILE *@var{stream}, const char *@var{template}, @dots{})
+@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{}}@acunsafe{@acsmem{} @aculock{} @acucorrupt{}}}
 This function is just like @code{scanf}, except that the input is read
 from the stream @var{stream} instead of @code{stdin}.
 @end deftypefun
@@ -3838,6 +4043,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{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{}}@acunsafe{@acsmem{} @aculock{} @acucorrupt{}}}
 This function is just like @code{wscanf}, except that the input is read
 from the stream @var{stream} instead of @code{stdin}.
 @end deftypefun
@@ -3845,6 +4051,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{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@ascuheap{}}@acsafe{@acsmem{}}}
 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.
@@ -3858,6 +4065,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{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@ascuheap{}}@acsafe{@acsmem{}}}
 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.
@@ -3884,6 +4092,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{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{}}@acunsafe{@acsmem{} @aculock{} @acucorrupt{}}}
 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}).
@@ -3892,6 +4101,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{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{}}@acunsafe{@acsmem{} @aculock{} @acucorrupt{}}}
 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}).
@@ -3900,6 +4110,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{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{}}@acunsafe{@acsmem{} @aculock{} @acucorrupt{}}}
 This is the equivalent of @code{fscanf} with the variable argument list
 specified directly as for @code{vscanf}.
 @end deftypefun
@@ -3907,6 +4118,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{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{}}@acunsafe{@acsmem{} @aculock{} @acucorrupt{}}}
 This is the equivalent of @code{fwscanf} with the variable argument list
 specified directly as for @code{vwscanf}.
 @end deftypefun
@@ -3914,6 +4126,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{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@ascuheap{}}@acsafe{@acsmem{}}}
 This is the equivalent of @code{sscanf} with the variable argument list
 specified directly as for @code{vscanf}.
 @end deftypefun
@@ -3921,6 +4134,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{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@ascuheap{}}@acsafe{@acsmem{}}}
 This is the equivalent of @code{swscanf} with the variable argument list
 specified directly as for @code{vwscanf}.
 @end deftypefun
@@ -3970,6 +4184,7 @@ This symbol is declared in @file{wchar.h}.
 @comment stdio.h
 @comment ISO
 @deftypefun int feof (FILE *@var{stream})
+@safety{@prelim{}@mtsafe{}@assafe{}@acunsafe{@aculock{}}}
 The @code{feof} function returns nonzero if and only if the end-of-file
 indicator for the stream @var{stream} is set.
 
@@ -3979,6 +4194,9 @@ This symbol is declared in @file{stdio.h}.
 @comment stdio.h
 @comment GNU
 @deftypefun int feof_unlocked (FILE *@var{stream})
+@safety{@prelim{}@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.
 
@@ -3990,6 +4208,7 @@ This symbol is declared in @file{stdio.h}.
 @comment stdio.h
 @comment ISO
 @deftypefun int ferror (FILE *@var{stream})
+@safety{@prelim{}@mtsafe{}@assafe{}@acunsafe{@aculock{}}}
 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.
@@ -4000,6 +4219,7 @@ This symbol is declared in @file{stdio.h}.
 @comment stdio.h
 @comment GNU
 @deftypefun int ferror_unlocked (FILE *@var{stream})
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
 The @code{ferror_unlocked} function is equivalent to the @code{ferror}
 function except that it does not implicitly lock the stream.
 
@@ -4027,6 +4247,7 @@ function.
 @comment stdio.h
 @comment ISO
 @deftypefun void clearerr (FILE *@var{stream})
+@safety{@prelim{}@mtsafe{}@assafe{}@acunsafe{@aculock{}}}
 This function clears the end-of-file and error indicators for the
 stream @var{stream}.
 
@@ -4037,6 +4258,7 @@ end-of-file indicator for the stream.
 @comment stdio.h
 @comment GNU
 @deftypefun void clearerr_unlocked (FILE *@var{stream})
+@safety{@prelim{}@mtunsafe{@mtasurace{:stream}}@assafe{}@acunsafe{@aculock{}}}
 The @code{clearerr_unlocked} function is equivalent to the @code{clearerr}
 function except that it does not implicitly lock the stream.
 
@@ -4150,6 +4372,7 @@ are declared in the header file @file{stdio.h}.
 @comment stdio.h
 @comment ISO
 @deftypefun {long int} ftell (FILE *@var{stream})
+@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@aculock{} @acucorrupt{}}}
 This function returns the current file position of the stream
 @var{stream}.
 
@@ -4162,6 +4385,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{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@aculock{} @acucorrupt{}}}
 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
@@ -4185,6 +4409,7 @@ LFS interface transparently replaces the old interface.
 @comment stdio.h
 @comment Unix98
 @deftypefun off64_t ftello64 (FILE *@var{stream})
+@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@aculock{} @acucorrupt{}}}
 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},
@@ -4200,6 +4425,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{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@aculock{} @acucorrupt{}}}
 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
@@ -4219,6 +4445,7 @@ place in the file.
 @comment stdio.h
 @comment Unix98
 @deftypefun int fseeko (FILE *@var{stream}, off_t @var{offset}, int @var{whence})
+@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@aculock{} @acucorrupt{}}}
 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.
@@ -4242,6 +4469,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{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@aculock{} @acucorrupt{}}}
 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
@@ -4290,6 +4518,7 @@ the offset provided is relative to the end of the file.
 @comment stdio.h
 @comment ISO
 @deftypefun void rewind (FILE *@var{stream})
+@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@aculock{} @acucorrupt{}}}
 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
@@ -4411,6 +4640,7 @@ representation.
 @comment stdio.h
 @comment ISO
 @deftypefun int fgetpos (FILE *@var{stream}, fpos_t *@var{position})
+@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@aculock{} @acucorrupt{}}}
 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
@@ -4425,6 +4655,7 @@ interface transparently replaces the old interface.
 @comment stdio.h
 @comment Unix98
 @deftypefun int fgetpos64 (FILE *@var{stream}, fpos64_t *@var{position})
+@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@aculock{} @acucorrupt{}}}
 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.
@@ -4437,6 +4668,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{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@aculock{} @acucorrupt{}}}
 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}
@@ -4453,6 +4685,7 @@ interface transparently replaces the old interface.
 @comment stdio.h
 @comment Unix98
 @deftypefun int fsetpos64 (FILE *@var{stream}, const fpos64_t *@var{position})
+@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@aculock{} @acucorrupt{}}}
 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.
@@ -4564,6 +4797,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{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@aculock{} @acucorrupt{}}}
 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
@@ -4576,6 +4810,7 @@ otherwise.
 @comment stdio.h
 @comment POSIX
 @deftypefun int fflush_unlocked (FILE *@var{stream})
+@safety{@prelim{}@mtunsafe{@mtasurace{:stream}}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{}}}
 The @code{fflush_unlocked} function is equivalent to the @code{fflush}
 function except that it does not implicitly lock the stream.
 @end deftypefun
@@ -4592,6 +4827,7 @@ exported.
 @comment stdio_ext.h
 @comment GNU
 @deftypefun void _flushlbf (void)
+@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@aculock{} @acucorrupt{}}}
 The @code{_flushlbf} function flushes all line buffered streams
 currently opened.
 
@@ -4613,6 +4849,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{@prelim{}@mtunsafe{@mtsrace{}}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{}}}
 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
@@ -4637,6 +4874,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{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@aculock{} @acucorrupt{}}}
 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
@@ -4714,6 +4952,7 @@ efficient size.
 @comment stdio.h
 @comment ISO
 @deftypefun void setbuf (FILE *@var{stream}, char *@var{buf})
+@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@aculock{} @acucorrupt{}}}
 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}
@@ -4727,6 +4966,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{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@aculock{} @acucorrupt{}}}
 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}.
@@ -4738,6 +4978,7 @@ This function is provided for compatibility with old BSD code.  Use
 @comment stdio.h
 @comment BSD
 @deftypefun void setlinebuf (FILE *@var{stream})
+@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@aculock{} @acucorrupt{}}}
 This function makes @var{stream} be line buffered, and allocates the
 buffer for you.
 
@@ -4752,6 +4993,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{@prelim{}@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.
@@ -4765,6 +5007,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{@prelim{}@mtunsafe{@mtsrace{}}@asunsafe{@asucorrupt{}}@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.
@@ -4775,6 +5018,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{@prelim{}@mtunsafe{@mtsrace{}}@asunsafe{@asucorrupt{}}@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
@@ -4822,6 +5066,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{@prelim{}@mtsafe{}@asunsafe{@ascuheap{} @asulock{}}@acsafe{@acsmem{} @aculock{}}}
+@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.
@@ -4874,6 +5122,7 @@ Got r
 @comment stdio.h
 @comment GNU
 @deftypefun {FILE *} open_memstream (char **@var{ptr}, size_t *@var{sizeloc})
+@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{}}@acsafe{@acsmem{}}}
 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
@@ -4989,6 +5238,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{@prelim{}@mtsafe{}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@acsmem{} @aculock{}}}
 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};
@@ -5170,6 +5420,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{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@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
@@ -5310,6 +5561,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{@prelim{}@mtsafe{}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsmem{}}}
 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=0741b22e96be02b31e08efe4892fd3b11ad828ac

commit 0741b22e96be02b31e08efe4892fd3b11ad828ac
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 edd1de4..8078a53 100644
--- a/manual/startup.texi
+++ b/manual/startup.texi
@@ -221,6 +221,11 @@ available.
 
 @comment stdlib.h
 @deftypefun int getsubopt (char **@var{optionp}, char *const *@var{tokens}, char **@var{valuep})
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+@c getsubopt ok
+@c  strchrnul dup ok
+@c  memchr dup ok
+@c  strncmp dup ok
 
 The @var{optionp} parameter must be a pointer to a variable containing
 the address of the string to process.  When the function returns the
@@ -322,6 +327,8 @@ functions can be safely used in multi-threaded programs.
 @comment stdlib.h
 @comment ISO
 @deftypefun {char *} getenv (const char *@var{name})
+@safety{@prelim{}@mtsafe{@mtsenv{}}@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 +340,8 @@ pointer.
 @comment stdlib.h
 @comment GNU
 @deftypefun {char *} secure_getenv (const char *@var{name})
+@safety{@prelim{}@mtsafe{@mtsenv{}}@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
@@ -346,6 +355,13 @@ This function is a GNU extension.
 @comment stdlib.h
 @comment SVID
 @deftypefun int putenv (char *@var{string})
+@safety{@prelim{}@mtunsafe{@mtasuconst{:@mtsenv{}}}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{}}}
+@c putenv @mtasuconst:@mtsenv @ascuheap @asulock @acucorrupt @aculock @acsmem
+@c  strchr dup ok
+@c  strndup dup @ascuheap @acsmem
+@c  add_to_environ dup @mtasuconst:@mtsenv @ascuheap @asulock @acucorrupt @aculock @acsmem
+@c  free dup @ascuheap @acsmem
+@c  unsetenv dup @mtasuconst:@mtsenv @asulock @aculock
 The @code{putenv} function adds or removes definitions from the environment.
 If the @var{string} is of the form @samp{@var{name}=@var{value}}, the
 definition is added to the environment.  Otherwise, the @var{string} is
@@ -358,8 +374,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 +388,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{@prelim{}@mtunsafe{@mtasuconst{:@mtsenv{}}}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{}}}
+@c setenv @mtasuconst:@mtsenv @ascuheap @asulock @acucorrupt @aculock @acsmem
+@c  add_to_environ @mtasuconst:@mtsenv @ascuheap @asulock @acucorrupt @aculock @acsmem
+@c   strlen dup ok
+@c   libc_lock_lock @asulock @aculock
+@c   strncmp dup ok
+@c   realloc dup @ascuheap @acsmem
+@c   libc_lock_unlock @aculock
+@c   malloc dup @ascuheap @acsmem
+@c   free dup @ascuheap @acsmem
+@c   mempcpy dup ok
+@c   memcpy dup ok
+@c   KNOWN_VALUE ok
+@c    tfind(strcmp) [no @mtsrace guarded access]
+@c     strcmp dup ok
+@c   STORE_VALUE @ascuheap @acucorrupt @acsmem
+@c    tsearch(strcmp) @ascuheap @acucorrupt @acsmem [no @mtsrace or @asucorrupt guarded access makes for mtsafe and @asulock]
+@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
@@ -395,6 +429,13 @@ the Unix standard.
 @comment stdlib.h
 @comment BSD
 @deftypefun int unsetenv (const char *@var{name})
+@safety{@prelim{}@mtunsafe{@mtasuconst{:@mtsenv{}}}@asunsafe{@asulock{}}@acunsafe{@aculock{}}}
+@c unsetenv @mtasuconst:@mtsenv @asulock @aculock
+@c  strchr dup ok
+@c  strlen dup ok
+@c  libc_lock_lock @asulock @aculock
+@c  strncmp dup ok
+@c  libc_lock_unlock @aculock
 Using this function one can remove an entry completely from the
 environment.  If the environment contains an entry with the key
 @var{name} this whole entry is removed.  A call to this function is
@@ -418,6 +459,11 @@ to enable writing standard compliant Fortran environments.
 @comment stdlib.h
 @comment GNU
 @deftypefun int clearenv (void)
+@safety{@prelim{}@mtunsafe{@mtasuconst{:@mtsenv{}}}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsmem{}}}
+@c clearenv @mtasuconst:@mtsenv @ascuheap @asulock @aculock @acsmem
+@c  libc_lock_lock @asulock @aculock
+@c  free dup @ascuheap @acsmem
+@c  libc_lock_unlock @aculock
 The @code{clearenv} function removes all entries from the environment.
 Using @code{putenv} and @code{setenv} new entries can be added again
 later.
@@ -622,6 +668,8 @@ basis there may be information that is not available any other way.
 @subsection Definition of @code{getauxval}
 @comment sys/auxv.h
 @deftypefun {unsigned long int} getauxval (unsigned long int @var{type})
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+@c Reads from hwcap or iterates over constant auxv.
 This function is used to inquire about the entries in the auxiliary
 vector.  The @var{type} argument should be one of the @samp{AT_} symbols
 defined in @file{elf.h}.  If a matching entry is found, the value is
@@ -678,6 +726,7 @@ anyway.
 @comment unistd.h
 @comment ???
 @deftypefun {long int} syscall (long int @var{sysno}, @dots{})
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
 
 @code{syscall} performs a generic system call.
 
@@ -783,6 +832,10 @@ the argument to @code{exit}.
 @comment stdlib.h
 @comment ISO
 @deftypefun void exit (int @var{status})
+@safety{@prelim{}@mtunsafe{@mtasurace{:exit}}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{} @aculock{}}}
+@c Access to the atexit/on_exit list, the libc_atexit hook and tls dtors
+@c is not guarded.  Streams must be flushed, and that triggers the usual
+@c AS and AC issues with streams.
 The @code{exit} function tells the system that the program is done, which
 causes it to terminate the process.
 
@@ -899,6 +952,15 @@ using @code{atexit} or @code{on_exit}.
 @comment stdlib.h
 @comment ISO
 @deftypefun int atexit (void (*@var{function}) (void))
+@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsmem{}}}
+@c atexit @ascuheap @asulock @aculock @acsmem
+@c  cxa_atexit @ascuheap @asulock @aculock @acsmem
+@c   __internal_atexit @ascuheap @asulock @aculock @acsmem
+@c    __new_exitfn @ascuheap @asulock @aculock @acsmem
+@c     __libc_lock_lock @asulock @aculock
+@c     calloc dup @ascuheap @acsmem
+@c     __libc_lock_unlock @aculock
+@c    atomic_write_barrier dup ok
 The @code{atexit} function registers the function @var{function} to be
 called at normal program termination.  The @var{function} is called with
 no arguments.
@@ -910,6 +972,10 @@ the function cannot be registered.
 @comment stdlib.h
 @comment SunOS
 @deftypefun int on_exit (void (*@var{function})(int @var{status}, void *@var{arg}), void *@var{arg})
+@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsmem{}}}
+@c on_exit @ascuheap @asulock @aculock @acsmem
+@c  new_exitfn dup @ascuheap @asulock @aculock @acsmem
+@c  atomic_write_barrier dup ok
 This function is a somewhat more powerful variant of @code{atexit}.  It
 accepts two arguments, a function @var{function} and an arbitrary
 pointer @var{arg}.  At normal program termination, the @var{function} is
@@ -941,6 +1007,10 @@ for this function is in @file{stdlib.h}.
 @comment stdlib.h
 @comment ISO
 @deftypefun void abort (void)
+@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@aculock{} @acucorrupt{}}}
+@c The implementation takes a recursive lock and attempts to support
+@c calls from signal handlers, but if we're in the middle of flushing or
+@c using streams, we may encounter them in inconsistent states.
 The @code{abort} function causes abnormal program termination.  This
 does not execute cleanup functions registered with @code{atexit} or
 @code{on_exit}.
@@ -968,6 +1038,9 @@ by @code{exit}.  It is declared in the header file @file{unistd.h}.
 @comment unistd.h
 @comment POSIX.1
 @deftypefun void _exit (int @var{status})
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+@c Direct syscall (exit_group or exit); calls __task_terminate on hurd,
+@c and abort in the generic posix implementation.
 The @code{_exit} function is the primitive for causing a process to
 terminate with status @var{status}.  Calling this function does not
 execute cleanup functions registered with @code{atexit} or
@@ -977,6 +1050,8 @@ execute cleanup functions registered with @code{atexit} or
 @comment stdlib.h
 @comment ISO
 @deftypefun void _Exit (int @var{status})
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+@c Alias for _exit.
 The @code{_Exit} function is the @w{ISO C} equivalent to @code{_exit}.
 The @w{ISO C} committee members were not sure whether the definitions of
 @code{_exit} and @code{_Exit} were compatible so they have not used the

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

commit 9f9b377232691e82c233571d5f60d0fdfd15a859
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/macros.texi b/manual/macros.texi
index 6ee58ef..e7b13a2 100644
--- a/manual/macros.texi
+++ b/manual/macros.texi
@@ -106,6 +106,9 @@ GNU/Linux systems
 @macro mtasurace {comments}
 race\comments\
 @end macro
+@macro asurace {comments}
+race\comments\
+@end macro
 @macro mtsrace {comments}
 race\comments\
 @end macro
diff --git a/manual/socket.texi b/manual/socket.texi
index 4c7e623..52c96a0 100644
--- a/manual/socket.texi
+++ b/manual/socket.texi
@@ -394,6 +394,8 @@ For examples of use, see @ref{Local Socket Example}, or see @ref{Inet Example}.
 @comment sys/socket.h
 @comment BSD
 @deftypefun int bind (int @var{socket}, struct sockaddr *@var{addr}, socklen_t @var{length})
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+@c Direct syscall, except on Hurd.
 The @code{bind} function assigns an address to the socket
 @var{socket}.  The @var{addr} and @var{length} arguments specify the
 address; the detailed format of the address depends on the namespace.
@@ -442,6 +444,9 @@ Internet socket.  The prototype for this function is in the header file
 @comment sys/socket.h
 @comment BSD
 @deftypefun int getsockname (int @var{socket}, struct sockaddr *@var{addr}, socklen_t *@var{length-ptr})
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{@acsmem{/hurd}}}
+@c Direct syscall, except on Hurd, where it seems like it might leak
+@c VM if cancelled.
 The @code{getsockname} function returns information about the
 address of the socket @var{socket} in the locations specified by the
 @var{addr} and @var{length-ptr} arguments.  Note that the
@@ -501,6 +506,14 @@ interface name, including its terminating zero byte.
 @comment net/if.h
 @comment IPv6 basic API
 @deftypefun {unsigned int} if_nametoindex (const char *@var{ifname})
+@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acsafe{@aculock{} @acsfd{}}}
+@c It opens a socket to use ioctl on the fd to get the index.
+@c opensock may call socket and access multiple times until it finds a
+@c socket family that works.  The Linux implementation has a potential
+@c concurrency issue WRT last_type and last_family not being updated
+@c atomically, but it is harmless; the generic implementation, OTOH,
+@c takes a lock, which makes all callers AS- and AC-Unsafe.
+@c  opensock @asulock @aculock @acsfd
 This function yields the interface index corresponding to a particular
 name.  If no interface exists with the name given, it returns 0.
 @end deftypefun
@@ -508,6 +521,9 @@ name.  If no interface exists with the name given, it returns 0.
 @comment net/if.h
 @comment IPv6 basic API
 @deftypefun {char *} if_indextoname (unsigned int @var{ifindex}, char *@var{ifname})
+@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acsafe{@aculock{} @acsfd{}}}
+@c It opens a socket with opensock to use ioctl on the fd to get the
+@c name from the index.
 This function maps an interface index to its corresponding name.  The
 returned name is placed in the buffer pointed to by @code{ifname}, which
 must be at least @code{IFNAMSIZ} bytes in length.  If the index was
@@ -534,6 +550,39 @@ This is the null-terminated index name.
 @comment net/if.h
 @comment IPv6 basic API
 @deftypefun {struct if_nameindex *} if_nameindex (void)
+@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{} @asulock{/hurd}}@acunsafe{@aculock{/hurd} @acsfd{} @acsmem{}}}
+@c if_nameindex @ascuheap @asulock/hurd @aculock/hurd @acsfd @acsmem
+@c  [linux]
+@c   netlink_open @acsfd @acsmem/hurd
+@c    socket dup @acsfd
+@c    memset dup ok
+@c    bind dup ok
+@c    netlink_close dup @acsfd
+@c    getsockname dup @acsmem/hurd
+@c   netlink_request @ascuheap @acsmem
+@c    getpagesize dup ok
+@c    malloc dup @ascuheap @acsmem
+@c    netlink_sendreq ok
+@c     memset dup ok
+@c     sendto dup ok
+@c    recvmsg dup ok
+@c    memcpy dup ok
+@c    free dup @ascuheap @acsmem
+@c   netlink_free_handle @ascuheap @acsmem
+@c    free dup @ascuheap @acsmem
+@c   netlink_close @acsfd
+@c    close dup @acsfd
+@c   malloc dup @asuheap @acsmem
+@c   strndup @ascuheap @acsmem
+@c   if_freenameindex @ascuheap @acsmem
+@c  [hurd]
+@c   opensock dup @asulock @aculock @acsfd
+@c   hurd_socket_server ok
+@c   pfinet_siocgifconf ok
+@c   malloc @ascuheap @acsmem
+@c   strdup @ascuheap @acsmem
+@c   ioctl dup ok
+@c   free @ascuheap @acsmem
 This function returns an array of @code{if_nameindex} structures, one
 for every interface that is present.  The end of the list is indicated
 by a structure with an interface of 0 and a null name pointer.  If an
@@ -546,6 +595,9 @@ use.
 @comment net/if.h
 @comment IPv6 basic API
 @deftypefun void if_freenameindex (struct if_nameindex *@var{ptr})
+@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{}}}
+@c if_freenameindex @ascuheap @acsmem
+@c  free dup @ascuheap @acsmem
 This function frees the structure returned by an earlier call to
 @code{if_nameindex}.
 @end deftypefun
@@ -660,6 +712,7 @@ the file name string.  This can be done using the macro @code{SUN_LEN}:
 @comment sys/un.h
 @comment BSD
 @deftypefn {Macro} int SUN_LEN (@emph{struct sockaddr_un *} @var{ptr})
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
 The macro computes the length of socket address in the local namespace.
 @end deftypefn
 
@@ -1035,6 +1088,13 @@ Order}, for an explanation of network and host byte order.
 @comment arpa/inet.h
 @comment BSD
 @deftypefun int inet_aton (const char *@var{name}, struct in_addr *@var{addr})
+@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{}@acsafe{}}
+@c inet_aton @mtslocale
+@c  isdigit dup @mtslocale
+@c  strtoul dup @mtslocale
+@c  isascii dup @mtslocale
+@c  isspace dup @mtslocale
+@c  htonl dup ok
 This function converts the IPv4 Internet host address @var{name}
 from the standard numbers-and-dots notation into binary data and stores
 it in the @code{struct in_addr} that @var{addr} points to.
@@ -1044,6 +1104,9 @@ it in the @code{struct in_addr} that @var{addr} points to.
 @comment arpa/inet.h
 @comment BSD
 @deftypefun {uint32_t} inet_addr (const char *@var{name})
+@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{}@acsafe{}}
+@c inet_addr @mtslocale
+@c  inet_aton dup @mtslocale
 This function converts the IPv4 Internet host address @var{name} from the
 standard numbers-and-dots notation into binary data.  If the input is
 not valid, @code{inet_addr} returns @code{INADDR_NONE}.  This is an
@@ -1056,6 +1119,12 @@ indicate error return.
 @comment arpa/inet.h
 @comment BSD
 @deftypefun {uint32_t} inet_network (const char *@var{name})
+@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{}@acsafe{}}
+@c inet_network @mtslocale
+@c  isdigit dup @mtslocale
+@c  isxdigit dup @mtslocale
+@c  tolower dup @mtslocale
+@c  isspace dup @mtslocale
 This function extracts the network number from the address @var{name},
 given in the standard numbers-and-dots notation. The returned address is
 in host order. If the input is not valid, @code{inet_network} returns
@@ -1069,6 +1138,10 @@ anymore.
 @comment arpa/inet.h
 @comment BSD
 @deftypefun {char *} inet_ntoa (struct in_addr @var{addr})
+@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@asurace{}}@acsafe{}}
+@c inet_ntoa @mtslocale @asurace
+@c   writes to a thread-local static buffer
+@c  snprintf @mtslocale [no @ascuheap or @acsmem]
 This function converts the IPv4 Internet host address @var{addr} to a
 string in the standard numbers-and-dots notation.  The return value is
 a pointer into a statically-allocated buffer.  Subsequent calls will
@@ -1087,6 +1160,9 @@ addresses.
 @comment arpa/inet.h
 @comment BSD
 @deftypefun {struct in_addr} inet_makeaddr (uint32_t @var{net}, uint32_t @var{local})
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+@c inet_makeaddr ok
+@c  htonl dup ok
 This function makes an IPv4 Internet host address by combining the network
 number @var{net} with the local-address-within-network number
 @var{local}.
@@ -1095,6 +1171,11 @@ number @var{net} with the local-address-within-network number
 @comment arpa/inet.h
 @comment BSD
 @deftypefun uint32_t inet_lnaof (struct in_addr @var{addr})
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+@c inet_lnaof ok
+@c  ntohl dup ok
+@c  IN_CLASSA ok
+@c  IN_CLASSB ok
 This function returns the local-address-within-network part of the
 Internet host address @var{addr}.
 
@@ -1106,6 +1187,11 @@ anymore.
 @comment arpa/inet.h
 @comment BSD
 @deftypefun uint32_t inet_netof (struct in_addr @var{addr})
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+@c inet_netof ok
+@c  ntohl dup ok
+@c  IN_CLASSA ok
+@c  IN_CLASSB ok
 This function returns the network number part of the Internet host
 address @var{addr}.
 
@@ -1117,6 +1203,16 @@ anymore.
 @comment arpa/inet.h
 @comment IPv6 basic API
 @deftypefun int inet_pton (int @var{af}, const char *@var{cp}, void *@var{buf})
+@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{}@acsafe{}}
+@c inet_pton @mtslocale
+@c  inet_pton4 ok
+@c   memcpy dup ok
+@c  inet_pton6 @mtslocale
+@c   memset dup ok
+@c   tolower dup @mtslocale
+@c   strchr dup ok
+@c   inet_pton4 dup ok
+@c   memcpy dup ok
 This function converts an Internet address (either IPv4 or IPv6) from
 presentation (textual) to network (binary) format.  @var{af} should be
 either @code{AF_INET} or @code{AF_INET6}, as appropriate for the type of
@@ -1128,6 +1224,16 @@ responsibility to make sure the buffer is large enough.
 @comment arpa/inet.h
 @comment IPv6 basic API
 @deftypefun {const char *} inet_ntop (int @var{af}, const void *@var{cp}, char *@var{buf}, socklen_t @var{len})
+@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{}@acsafe{}}
+@c inet_ntop @mtslocale
+@c  inet_ntop4 @mtslocale
+@c   sprintf dup @mtslocale [no @ascuheap or @acsmem]
+@c   strcpy dup ok
+@c  inet_ntop6 @mtslocale
+@c   memset dup ok
+@c   inet_ntop4 dup @mtslocale
+@c   sprintf dup @mtslocale [no @ascuheap or @acsmem]
+@c   strcpy dup ok
 This function converts an Internet address (either IPv4 or IPv6) from
 network (binary) to presentation (textual) form.  @var{af} should be
 either @code{AF_INET} or @code{AF_INET6}, as appropriate.  @var{cp} is a
@@ -1211,6 +1317,71 @@ need to save it across calls.  You can also use @code{getaddrinfo} and
 @comment netdb.h
 @comment BSD
 @deftypefun {struct hostent *} gethostbyname (const char *@var{name})
+@safety{@prelim{}@mtunsafe{@mtasurace{:hostbyname} @mtsenv{} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @asucorrupt{} @ascuheap{} @asulock{}}@acunsafe{@aculock{} @acucorrupt{} @acsmem{} @acsfd{}}}
+@c gethostbyname @mtasurace:hostbyname @mtsenv @mtslocale @ascudlopen @ascuplugin @asucorrupt @ascuheap @asulock @aculock @acucorrupt @acsmem @acsfd
+@c  libc_lock_lock dup @asulock @aculock
+@c  malloc dup @ascuheap @acsmem
+@c  nss_hostname_digits_dots @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@c   res_maybe_init(!preinit) @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@c    res_iclose @acsuheap @acsmem @acsfd
+@c     close_not_cancel_no_status dup @acsfd
+@c     free dup @acsuheap @acsmem
+@c    res_vinit @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@c     res_randomid ok
+@c      getpid dup ok
+@c     getenv dup @mtsenv
+@c     strncpy dup ok
+@c     fopen dup @ascuheap @asulock @acsmem @acsfd @aculock
+@c     fsetlocking dup ok [no concurrent uses]
+@c     fgets_unlocked dup ok [no concurrent uses]
+@c     MATCH ok
+@c      strncmp dup ok
+@c     strpbrk dup ok
+@c     strchr dup ok
+@c     inet_aton dup @mtslocale
+@c     htons dup
+@c     inet_pton dup @mtslocale
+@c     malloc dup @ascuheap @acsmem
+@c     IN6_IS_ADDR_LINKLOCAL ok
+@c      htonl dup ok
+@c     IN6_IS_ADDR_MC_LINKLOCAL ok
+@c     if_nametoindex dup @asulock @aculock @acsfd
+@c     strtoul dup @mtslocale
+@c     ISSORTMASK ok
+@c      strchr dup ok
+@c     isascii dup @mtslocale
+@c     isspace dup @mtslocale
+@c     net_mask ok
+@c      ntohl dup ok
+@c      IN_CLASSA dup ok
+@c      htonl dup ok
+@c      IN_CLASSB dup ok
+@c     res_setoptions @mtslocale
+@c      strncmp dup ok
+@c      atoi dup @mtslocale
+@c     fclose dup @ascuheap @asulock @aculock @acsmem @acsfd
+@c     inet_makeaddr dup ok
+@c     gethostname dup ok
+@c     strcpy dup ok
+@c     rawmemchr dup ok
+@c    res_ninit @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@c     res_vinit dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@c   isdigit dup @mtslocale
+@c   isxdigit dup @mtslocale
+@c   strlen dup ok
+@c   realloc dup @ascuheap @acsmem
+@c   free dup @ascuheap @acsmem
+@c   memset dup ok
+@c   inet_aton dup @mtslocale
+@c   inet_pton dup @mtslocale
+@c   strcpy dup ok
+@c   memcpy dup ok
+@c   strchr dup ok
+@c  gethostbyname_r dup @mtsenv @mtslocale @ascudlopen @ascuplugin @asucorrupt @ascuheap @asulock @aculock @acucorrupt @acsmem @acsfd
+@c  realloc dup @ascuheap @acsmem
+@c  free dup @ascuheap @acsmem
+@c  libc_lock_unlock dup @aculock
+@c  set_h_errno ok
 The @code{gethostbyname} function returns information about the host
 named @var{name}.  If the lookup fails, it returns a null pointer.
 @end deftypefun
@@ -1218,6 +1389,16 @@ named @var{name}.  If the lookup fails, it returns a null pointer.
 @comment netdb.h
 @comment IPv6 Basic API
 @deftypefun {struct hostent *} gethostbyname2 (const char *@var{name}, int @var{af})
+@safety{@prelim{}@mtunsafe{@mtasurace{:hostbyname2} @mtsenv{} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @asucorrupt{} @ascuheap{} @asulock{}}@acunsafe{@aculock{} @acucorrupt{} @acsmem{} @acsfd{}}}
+@c gethostbyname2 @mtasurace:hostbyname2 @mtsenv @mtslocale @ascudlopen @ascuplugin @asucorrupt @ascuheap @asulock @aculock @acucorrupt @acsmem @acsfd
+@c  libc_lock_lock dup @asulock @aculock
+@c  malloc dup @ascuheap @acsmem
+@c  nss_hostname_digits_dots dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@c  gethostbyname2_r dup @mtsenv @mtslocale @ascudlopen @ascuplugin @asucorrupt @ascuheap @asulock @aculock @acucorrupt @acsmem @acsfd
+@c  realloc dup @ascuheap @acsmem
+@c  free dup @ascuheap @acsmem
+@c  libc_lock_unlock dup @aculock
+@c  set_h_errno dup ok
 The @code{gethostbyname2} function is like @code{gethostbyname}, but
 allows the caller to specify the desired address family (e.g.@:
 @code{AF_INET} or @code{AF_INET6}) of the result.
@@ -1226,6 +1407,15 @@ allows the caller to specify the desired address family (e.g.@:
 @comment netdb.h
 @comment BSD
 @deftypefun {struct hostent *} gethostbyaddr (const void *@var{addr}, socklen_t @var{length}, int @var{format})
+@safety{@prelim{}@mtunsafe{@mtasurace{:hostbyaddr} @mtsenv{} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @asucorrupt{} @ascuheap{} @asulock{}}@acunsafe{@aculock{} @acucorrupt{} @acsmem{} @acsfd{}}}
+@c gethostbyaddr @mtasurace:hostbyaddr @mtsenv @mtslocale @ascudlopen @ascuplugin @asucorrupt @ascuheap @asulock @aculock @acucorrupt @acsmem @acsfd
+@c  libc_lock_lock dup @asulock @aculock
+@c  malloc dup @ascuheap @acsmem
+@c  gethostbyaddr_r dup @mtsenv @mtslocale @ascudlopen @ascuplugin @asucorrupt @ascuheap @asulock @aculock @acucorrupt @acsmem @acsfd
+@c  realloc dup @ascuheap @acsmem
+@c  free dup @ascuheap @acsmem
+@c  libc_lock_unlock dup @aculock
+@c  set_h_errno dup ok
 The @code{gethostbyaddr} function returns information about the host
 with Internet address @var{addr}.  The parameter @var{addr} is not
 really a pointer to char - it can be a pointer to an IPv4 or an IPv6
@@ -1282,6 +1472,76 @@ used in this context.
 @comment netdb.h
 @comment GNU
 @deftypefun int gethostbyname_r (const char *restrict @var{name}, struct hostent *restrict @var{result_buf}, char *restrict @var{buf}, size_t @var{buflen}, struct hostent **restrict @var{result}, int *restrict @var{h_errnop})
+@safety{@prelim{}@mtsafe{@mtsenv{} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @asucorrupt{} @ascuheap{} @asulock{}}@acunsafe{@aculock{} @acucorrupt{} @acsmem{} @acsfd{}}}
+@c gethostbyname_r @mtsenv @mtslocale @ascudlopen @ascuplugin @asucorrupt @ascuheap @asulock @aculock @acucorrupt @acsmem @acsfd
+@c  nss_hostname_digits_dots dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@c  nscd_gethostbyname_r @mtsenv @ascuheap @acsfd @acsmem
+@c   nscd_gethst_r @mtsenv @ascuheap @acsfd @acsmem
+@c    getenv dup @mtsenv
+@c    nscd_get_map_ref dup @ascuheap @acsfd @acsmem
+@c    nscd_cache_search dup ok
+@c    memcpy dup ok
+@c    nscd_open_socket dup @acsfd
+@c    readvall dup ok
+@c    readall dup ok
+@c    close_not_cancel_no_status dup @acsfd
+@c    nscd_drop_map_ref dup @ascuheap @acsmem
+@c    nscd_unmap dup @ascuheap @acsmem
+@c  res_maybe_init(!preinit) dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@c  res_hconf_init @mtsenv @mtslocale @asucorrupt @ascuheap @aculock @acucorrupt @acsmem [no @asuinit:reshconf @acuinit:reshconf, conditionally called]
+@c   res_hconf.c:do_init @mtsenv @mtslocale @asucorrupt @ascuheap @aculock @acucorrupt @acsmem
+@c    memset dup ok
+@c    getenv dup @mtsenv
+@c    fopen dup @ascuheap @asulock @acsmem @acsfd @aculock
+@c    fsetlocking dup ok [no concurrent uses]
+@c    fgets_unlocked dup ok [no concurrent uses]
+@c    strchrnul dup ok
+@c    res_hconf.c:parse_line @mtslocale @asucorrupt @ascuheap @aculock @acucorrupt @acsmem
+@c     skip_ws dup @mtslocale
+@c     skip_string dup @mtslocale
+@c     strncasecmp dup @mtslocale
+@c     strlen dup ok
+@c     asprintf dup @mtslocale @ascuheap @acsmem
+@c     fxprintf dup @asucorrupt @aculock @acucorrupt
+@c     free dup @ascuheap @acsmem
+@c     arg_trimdomain_list dup @mtslocale @asucorrupt @ascuheap @aculock @acucorrupt @acsmem
+@c     arg_spoof dup @mtslocale
+@c     arg_bool dup @mtslocale @asucorrupt @ascuheap @aculock @acucorrupt @acsmem
+@c     isspace dup @mtslocale
+@c    fclose dup @ascuheap @asulock @acsmem @acsfd @aculock
+@c    arg_spoof @mtslocale
+@c     skip_string @mtslocale
+@c      isspace dup @mtslocale
+@c     strncasecmp dup @mtslocale
+@c    arg_bool @mtslocale @asucorrupt @ascuheap @aculock @acucorrupt @acsmem
+@c     strncasecmp dup @mtslocale
+@c     asprintf dup @mtslocale @ascuheap @acsmem
+@c     fxprintf dup @asucorrupt @aculock @acucorrupt
+@c     free dup @ascuheap @acsmem
+@c    arg_trimdomain_list @mtslocale @asucorrupt @ascuheap @aculock @acucorrupt @acsmem
+@c     skip_string dup @mtslocale
+@c     asprintf dup @mtslocale @ascuheap @acsmem
+@c     fxprintf dup @asucorrupt @aculock @acucorrupt
+@c     free dup @ascuheap @acsmem
+@c     strndup dup @ascuheap @acsmem
+@c     skip_ws @mtslocale
+@c      isspace dup @mtslocale
+@c  nss_hosts_lookup2 @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c   nss_database_lookup dup @mtslocale @ascuheap @asulock @acucorrupt @acsmem @acsfd @aculock
+@c   nss_lookup dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c  *fct.l -> _nss_*_gethostbyname_r @ascuplugin
+@c  nss_next2 dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c  res_hconf_reorder_addrs @asulock @ascuheap @aculock @acsmem @acsfd
+@c   socket dup @acsfd
+@c   libc_lock_lock dup @asulock @aculock
+@c   ifreq @ascuheap @acsmem
+@c   malloc dup @ascuheap @acsmem
+@c   if_nextreq dup ok
+@c   ioctl dup ok
+@c   realloc dup @ascuheap @acsmem
+@c   if_freereq dup @acsmem
+@c   libc_lock_unlock dup @aculock
+@c   close dup @acsfd
 The @code{gethostbyname_r} function returns information about the host
 named @var{name}.  The caller must pass a pointer to an object of type
 @code{struct hostent} in the @var{result_buf} parameter.  In addition
@@ -1337,6 +1597,17 @@ gethostname (char *host)
 @comment netdb.h
 @comment GNU
 @deftypefun int gethostbyname2_r (const char *@var{name}, int @var{af}, struct hostent *restrict @var{result_buf}, char *restrict @var{buf}, size_t @var{buflen}, struct hostent **restrict @var{result}, int *restrict @var{h_errnop})
+@safety{@prelim{}@mtsafe{@mtsenv{} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @asucorrupt{} @ascuheap{} @asulock{}}@acunsafe{@aculock{} @acucorrupt{} @acsmem{} @acsfd{}}}
+@c gethostbyname2_r @mtsenv @mtslocale @ascudlopen @ascuplugin @asucorrupt @ascuheap @asulock @aculock @acucorrupt @acsmem @acsfd
+@c  nss_hostname_digits_dots dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@c  nscd_gethostbyname2_r @mtsenv @ascuheap @asulock @aculock @acsfd @acsmem
+@c   nscd_gethst_r dup @mtsenv @ascuheap @asulock @aculock @acsfd @acsmem
+@c  res_maybe_init(!preinit) dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@c  res_hconf_init dup @mtsenv @mtslocale @asucorrupt @ascuheap @aculock @acucorrupt @acsmem [no @asuinit:reshconf @acuinit:reshconf, conditionally called]
+@c  nss_hosts_lookup2 dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c  *fct.l -> _nss_*_gethostbyname2_r @ascuplugin
+@c  nss_next2 dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c  res_hconf_reorder_addrs dup @asulock @ascuheap @aculock @acsmem @acsfd
 The @code{gethostbyname2_r} function is like @code{gethostbyname_r}, but
 allows the caller to specify the desired address family (e.g.@:
 @code{AF_INET} or @code{AF_INET6}) for the result.
@@ -1345,6 +1616,21 @@ allows the caller to specify the desired address family (e.g.@:
 @comment netdb.h
 @comment GNU
 @deftypefun int gethostbyaddr_r (const void *@var{addr}, socklen_t @var{length}, int @var{format}, struct hostent *restrict @var{result_buf}, char *restrict @var{buf}, size_t @var{buflen}, struct hostent **restrict @var{result}, int *restrict @var{h_errnop})
+@safety{@prelim{}@mtsafe{@mtsenv{} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @asucorrupt{} @ascuheap{} @asulock{}}@acunsafe{@aculock{} @acucorrupt{} @acsmem{} @acsfd{}}}
+@c gethostbyaddr_r @mtsenv @mtslocale @ascudlopen @ascuplugin @asucorrupt @ascuheap @asulock @aculock @acucorrupt @acsmem @acsfd
+@c  memcmp dup ok
+@c  nscd_gethostbyaddr_r @mtsenv @ascuheap @asulock @aculock @acsfd @acsmem
+@c   nscd_gethst_r dup @mtsenv @ascuheap @asulock @aculock @acsfd @acsmem
+@c  res_maybe_init(!preinit) dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@c  res_hconf_init dup @mtsenv @mtslocale @asucorrupt @ascuheap @aculock @acucorrupt @acsmem [no @asuinit:reshconf @acuinit:reshconf, conditionally called]
+@c  nss_hosts_lookup2 dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c  *fct.l -> _nss_*_gethostbyaddr_r @ascuplugin
+@c  nss_next2 dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c  res_hconf_reorder_addrs dup @asulock @ascuheap @aculock @acsmem @acsfd
+@c  res_hconf_trim_domains @mtslocale
+@c   res_hconf_trim_domain @mtslocale
+@c    strlen dup ok
+@c    strcasecmp dup @mtslocale
 The @code{gethostbyaddr_r} function returns information about the host
 with Internet address @var{addr}.  The parameter @var{addr} is not
 really a pointer to char - it can be a pointer to an IPv4 or an IPv6
@@ -1367,6 +1653,18 @@ when using these functions because they are not reentrant.
 @comment netdb.h
 @comment BSD
 @deftypefun void sethostent (int @var{stayopen})
+@safety{@prelim{}@mtunsafe{@mtasurace{:hostent} @mtsenv{} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
+@c sethostent @mtasurace:hostent @mtsenv @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c  libc_lock_lock dup @asulock @aculock
+@c  nss_setent(nss_hosts_lookup2) @mtasurace:hostent @mtsenv @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c   res_maybe_init(!preinit) dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@c   set_h_errno dup ok
+@c   setup(nss_hosts_lookup2) @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c    *lookup_fct = nss_hosts_lookup2 dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c    nss_lookup dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c   *fct.f @mtasurace:hostent @ascuplugin
+@c   nss_next2 dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c  libc_lock_unlock dup @aculock
 This function opens the hosts database to begin scanning it.  You can
 then call @code{gethostent} to read the entries.
 
@@ -1382,6 +1680,27 @@ reopening the database for each call.
 @comment netdb.h
 @comment BSD
 @deftypefun {struct hostent *} gethostent (void)
+@safety{@prelim{}@mtunsafe{@mtasurace{:hostent} @mtasurace{:hostentbuf} @mtsenv{} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
+@c gethostent @mtasurace:hostent @mtasurace:hostentbuf @mtsenv @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c  libc_lock_lock dup @asulock @aculock
+@c  nss_getent(gethostent_r) @mtasurace:hostent @mtsenv @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c   malloc dup @ascuheap @acsmem
+@c   *func = gethostent_r dup @mtasurace:hostent @mtsenv @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c   realloc dup @ascuheap @acsmem
+@c   free dup @ascuheap @acsmem
+@c  libc_lock_unlock dup @aculock
+@c
+@c gethostent_r @mtasurace:hostent @mtsenv @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c  libc_lock_lock dup @asulock @aculock
+@c  nss_getent_r(nss_hosts_lookup2) @mtasurace:hostent @mtsenv @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c   res_maybe_init(!preinit) dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@c   setup(nss_hosts_lookup2) dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c   *fct.f @mtasurace:hostent @ascuplugin
+@c   nss_next2 dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c   nss_lookup dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c   *sfct.f @mtasurace:hostent @ascuplugin
+@c  libc_lock_unlock dup @aculock
+
 This function returns the next entry in the hosts database.  It
 returns a null pointer if there are no more entries.
 @end deftypefun
@@ -1389,6 +1708,15 @@ returns a null pointer if there are no more entries.
 @comment netdb.h
 @comment BSD
 @deftypefun void endhostent (void)
+@safety{@prelim{}@mtunsafe{@mtasurace{:hostent} @mtsenv{} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
+@c endhostent @mtasurace:hostent @mtsenv @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c  libc_lock_lock @asulock @aculock
+@c  nss_endent(nss_hosts_lookup2) @mtasurace:hostent @mtsenv @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c   res_maybe_init(!preinit) dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@c   setup(nss_passwd_lookup2) dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c   *fct.f @mtasurace:hostent @ascuplugin
+@c   nss_next2 dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c  libc_lock_unlock @aculock
 This function closes the hosts database.
 @end deftypefun
 
@@ -1488,6 +1816,34 @@ information if you need to save it across calls.
 @comment netdb.h
 @comment BSD
 @deftypefun {struct servent *} getservbyname (const char *@var{name}, const char *@var{proto})
+@safety{@prelim{}@mtunsafe{@mtasurace{:servbyname} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
+@c getservbyname =~ getpwuid @mtasurace:servbyname @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c  libc_lock_lock dup @asulock @aculock
+@c  malloc dup @ascuheap @acsmem
+@c  getservbyname_r dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c  realloc dup @ascuheap @acsmem
+@c  free dup @ascuheap @acsmem
+@c  libc_lock_unlock dup @aculock
+@c
+@c getservbyname_r =~ getpwuid_r @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c  nscd_getservbyname_r @ascuheap @acsfd @acsmem
+@c   nscd_getserv_r @ascuheap @acsfd @acsmem
+@c    nscd_get_map_ref dup @ascuheap @acsfd @acsmem
+@c    strlen dup ok
+@c    malloc dup @ascuheap @acsmem
+@c    mempcpy dup ok
+@c    memcpy dup ok
+@c    nscd_cache_search dup ok
+@c    nscd_open_socket dup @acsfd
+@c    readvall dup ok
+@c    readall dup ok
+@c    close_not_cancel_no_status dup @acsfd
+@c    nscd_drop_map_ref dup @ascuheap @acsmem
+@c    nscd_unmap dup @ascuheap @acsmem
+@c    free dup @ascuheap @acsmem
+@c  nss_services_lookup2 =~ nss_passwd_lookup2 @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c  *fct.l -> _nss_*_getservbyname_r @ascuplugin
+@c  nss_next2 dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
 The @code{getservbyname} function returns information about the
 service named @var{name} using protocol @var{proto}.  If it can't find
 such a service, it returns a null pointer.
@@ -1499,6 +1855,21 @@ use it to determine which port they should listen on (@pxref{Listening}).
 @comment netdb.h
 @comment BSD
 @deftypefun {struct servent *} getservbyport (int @var{port}, const char *@var{proto})
+@safety{@prelim{}@mtunsafe{@mtasurace{:servbyport} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
+@c getservbyport =~ getservbyname @mtasurace:servbyport @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c  libc_lock_lock dup @asulock @aculock
+@c  malloc dup @ascuheap @acsmem
+@c  getservbyport_r dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c  realloc dup @ascuheap @acsmem
+@c  free dup @ascuheap @acsmem
+@c  libc_lock_unlock dup @aculock
+@c
+@c getservbyport_r =~ getservbyname_r @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c  nscd_getservbyport_r @ascuheap @acsfd @acsmem
+@c   nscd_getserv_r dup @ascuheap @acsfd @acsmem
+@c  nss_services_lookup2 =~ nss_passwd_lookup2 @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c  *fct.l -> _nss_*_getservbyport_r @ascuplugin
+@c  nss_next2 dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
 The @code{getservbyport} function returns information about the
 service at port @var{port} using protocol @var{proto}.  If it can't
 find such a service, it returns a null pointer.
@@ -1512,6 +1883,16 @@ functions because they are not reentrant.
 @comment netdb.h
 @comment BSD
 @deftypefun void setservent (int @var{stayopen})
+@safety{@prelim{}@mtunsafe{@mtasurace{:servent} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
+@c setservent @mtasurace:servent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c  libc_lock_lock dup @asulock @aculock
+@c  nss_setent(nss_services_lookup2) @mtasurace:servenv @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c   setup(nss_services_lookup2) @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c    *lookup_fct = nss_services_lookup2 dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c    nss_lookup dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c   *fct.f @mtasurace:servent @ascuplugin
+@c   nss_next2 dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c  libc_lock_unlock dup @aculock
 This function opens the services database to begin scanning it.
 
 If the @var{stayopen} argument is nonzero, this sets a flag so that
@@ -1524,6 +1905,25 @@ reopening the database for each call.
 @comment netdb.h
 @comment BSD
 @deftypefun {struct servent *} getservent (void)
+@safety{@prelim{}@mtunsafe{@mtasurace{:servent} @mtasurace{:serventbuf} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
+@c getservent @mtasurace:servent @mtasurace:serventbuf @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c  libc_lock_lock dup @asulock @aculock
+@c  nss_getent(getservent_r) @mtasurace:servent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c   malloc dup @ascuheap @acsmem
+@c   *func = getservent_r dup @mtasurace:servent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c   realloc dup @ascuheap @acsmem
+@c   free dup @ascuheap @acsmem
+@c  libc_lock_unlock dup @aculock
+@c
+@c getservent_r @mtasurace:servent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c  libc_lock_lock dup @asulock @aculock
+@c  nss_getent_r(nss_services_lookup2) @mtasurace:servent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c   setup(nss_services_lookup2) dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c   *fct.f @mtasurace:servent @ascuplugin
+@c   nss_next2 dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c   nss_lookup dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c   *sfct.f @mtasurace:servent @ascuplugin
+@c  libc_lock_unlock dup @aculock
 This function returns the next entry in the services database.  If
 there are no more entries, it returns a null pointer.
 @end deftypefun
@@ -1531,6 +1931,14 @@ there are no more entries, it returns a null pointer.
 @comment netdb.h
 @comment BSD
 @deftypefun void endservent (void)
+@safety{@prelim{}@mtunsafe{@mtasurace{:servent} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
+@c endservent @mtasurace:servent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c  libc_lock_lock @asulock @aculock
+@c  nss_endent(nss_services_lookup2) @mtasurace:servent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c   setup(nss_services_lookup2) dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c   *fct.f @mtasurace:servent @ascuplugin
+@c   nss_next2 dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c  libc_lock_unlock @aculock
 This function closes the services database.
 @end deftypefun
 
@@ -1576,6 +1984,11 @@ to @code{uint32_t}.)  These functions are declared in
 @comment netinet/in.h
 @comment BSD
 @deftypefun {uint16_t} htons (uint16_t @var{hostshort})
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+@c htons ok
+@c  bswap_16 ok
+@c   bswap_constant_16 ok
+
 This function converts the @code{uint16_t} integer @var{hostshort} from
 host byte order to network byte order.
 @end deftypefun
@@ -1583,6 +1996,8 @@ host byte order to network byte order.
 @comment netinet/in.h
 @comment BSD
 @deftypefun {uint16_t} ntohs (uint16_t @var{netshort})
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+@c Alias to htons.
 This function converts the @code{uint16_t} integer @var{netshort} from
 network byte order to host byte order.
 @end deftypefun
@@ -1590,6 +2005,9 @@ network byte order to host byte order.
 @comment netinet/in.h
 @comment BSD
 @deftypefun {uint32_t} htonl (uint32_t @var{hostlong})
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+@c htonl ok
+@c  bswap_32 dup ok
 This function converts the @code{uint32_t} integer @var{hostlong} from
 host byte order to network byte order.
 
@@ -1599,6 +2017,8 @@ This is used for IPv4 Internet addresses.
 @comment netinet/in.h
 @comment BSD
 @deftypefun {uint32_t} ntohl (uint32_t @var{netlong})
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+@c Alias to htonl.
 This function converts the @code{uint32_t} integer @var{netlong} from
 network byte order to host byte order.
 
@@ -1663,6 +2083,20 @@ information if you need to save it across calls.
 @comment netdb.h
 @comment BSD
 @deftypefun {struct protoent *} getprotobyname (const char *@var{name})
+@safety{@prelim{}@mtunsafe{@mtasurace{:protobyname} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
+@c getprotobyname =~ getpwuid @mtasurace:protobyname @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c  libc_lock_lock dup @asulock @aculock
+@c  malloc dup @ascuheap @acsmem
+@c  getprotobyname_r dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c  realloc dup @ascuheap @acsmem
+@c  free dup @ascuheap @acsmem
+@c  libc_lock_unlock dup @aculock
+@c
+@c getprotobyname_r =~ getpwuid_r @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c   no nscd support
+@c  nss_protocols_lookup2 =~ nss_passwd_lookup2 @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c  *fct.l -> _nss_*_getprotobyname_r @ascuplugin
+@c  nss_next2 dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
 The @code{getprotobyname} function returns information about the
 network protocol named @var{name}.  If there is no such protocol, it
 returns a null pointer.
@@ -1671,6 +2105,20 @@ returns a null pointer.
 @comment netdb.h
 @comment BSD
 @deftypefun {struct protoent *} getprotobynumber (int @var{protocol})
+@safety{@prelim{}@mtunsafe{@mtasurace{:protobynumber} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
+@c getprotobynumber =~ getpwuid @mtasurace:protobynumber @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c  libc_lock_lock dup @asulock @aculock
+@c  malloc dup @ascuheap @acsmem
+@c  getprotobynumber_r dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c  realloc dup @ascuheap @acsmem
+@c  free dup @ascuheap @acsmem
+@c  libc_lock_unlock dup @aculock
+@c
+@c getprotobynumber_r =~ getpwuid_r @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c   no nscd support
+@c  nss_protocols_lookup2 =~ nss_passwd_lookup2 @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c  *fct.l -> _nss_*_getprotobynumber_r @ascuplugin
+@c  nss_next2 dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
 The @code{getprotobynumber} function returns information about the
 network protocol with number @var{protocol}.  If there is no such
 protocol, it returns a null pointer.
@@ -1683,6 +2131,16 @@ Be careful when using these functions because they are not reentrant.
 @comment netdb.h
 @comment BSD
 @deftypefun void setprotoent (int @var{stayopen})
+@safety{@prelim{}@mtunsafe{@mtasurace{:protoent} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
+@c setprotoent @mtasurace:protoent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c  libc_lock_lock dup @asulock @aculock
+@c  nss_setent(nss_protocols_lookup2) @mtasurace:protoent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c   setup(nss_protocols_lookup2) @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c    *lookup_fct = nss_protocols_lookup2 dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c    nss_lookup dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c   *fct.f @mtasurace:protoent @ascuplugin
+@c   nss_next2 dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c  libc_lock_unlock dup @aculock
 This function opens the protocols database to begin scanning it.
 
 If the @var{stayopen} argument is nonzero, this sets a flag so that
@@ -1695,6 +2153,25 @@ reopening the database for each call.
 @comment netdb.h
 @comment BSD
 @deftypefun {struct protoent *} getprotoent (void)
+@safety{@prelim{}@mtunsafe{@mtasurace{:protoent} @mtasurace{:protoentbuf} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
+@c getprotoent @mtasurace:protoent @mtasurace:protoentbuf @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c  libc_lock_lock dup @asulock @aculock
+@c  nss_getent(getprotoent_r) @mtasurace:protoent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c   malloc dup @ascuheap @acsmem
+@c   *func = getprotoent_r dup @mtasurace:protoent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c   realloc dup @ascuheap @acsmem
+@c   free dup @ascuheap @acsmem
+@c  libc_lock_unlock dup @aculock
+@c
+@c getprotoent_r @mtasurace:protoent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c  libc_lock_lock dup @asulock @aculock
+@c  nss_getent_r(nss_protocols_lookup2) @mtasurace:protoent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c   setup(nss_protocols_lookup2) dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c   *fct.f @mtasurace:servent @ascuplugin
+@c   nss_next2 dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c   nss_lookup dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c   *sfct.f @mtasurace:protoent @ascuplugin
+@c  libc_lock_unlock dup @aculock
 This function returns the next entry in the protocols database.  It
 returns a null pointer if there are no more entries.
 @end deftypefun
@@ -1702,6 +2179,14 @@ returns a null pointer if there are no more entries.
 @comment netdb.h
 @comment BSD
 @deftypefun void endprotoent (void)
+@safety{@prelim{}@mtunsafe{@mtasurace{:protoent} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
+@c endprotoent @mtasurace:protoent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c  libc_lock_lock @asulock @aculock
+@c  nss_endent(nss_protocols_lookup2) @mtasurace:protoent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c   setup(nss_protocols_lookup2) dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c   *fct.f @mtasurace:protoent @ascuplugin
+@c   nss_next2 dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c  libc_lock_unlock @aculock
 This function closes the protocols database.
 @end deftypefun
 
@@ -1771,6 +2256,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{@prelim{}@mtsafe{}@assafe{}@acsafe{@acsfd{}}}
 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
@@ -1833,6 +2319,7 @@ connection by calling @code{shutdown}, which is declared in
 @comment sys/socket.h
 @comment BSD
 @deftypefun int shutdown (int @var{socket}, int @var{how})
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
 The @code{shutdown} function shuts down the connection of socket
 @var{socket}.  The argument @var{how} specifies what action to
 perform:
@@ -1884,6 +2371,7 @@ FIFOs}).
 @comment sys/socket.h
 @comment BSD
 @deftypefun int socketpair (int @var{namespace}, int @var{style}, int @var{protocol}, int @var{filedes}@t{[2]})
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{@acsfd{}}}
 This function creates a socket pair, returning the file descriptors in
 @code{@var{filedes}[0]} and @code{@var{filedes}[1]}.  The socket pair
 is a full-duplex communications channel, so that both reading and writing
@@ -1977,6 +2465,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{@prelim{}@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
@@ -2076,6 +2565,7 @@ access to connect to the socket.
 @comment sys/socket.h
 @comment BSD
 @deftypefun int listen (int @var{socket}, int @var{n})
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{@acsfd{}}}
 The @code{listen} function enables the socket @var{socket} to accept
 connections, thus making it a server socket.
 
@@ -2128,6 +2618,7 @@ queue.
 @comment sys/socket.h
 @comment BSD
 @deftypefun int accept (int @var{socket}, struct sockaddr *@var{addr}, socklen_t *@var{length_ptr})
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{@acsfd{}}}
 This function is used to accept a connection request on the server
 socket @var{socket}.
 
@@ -2186,6 +2677,7 @@ connectionless communication styles.
 @comment sys/socket.h
 @comment BSD
 @deftypefun int getpeername (int @var{socket}, struct sockaddr *@var{addr}, socklen_t *@var{length-ptr})
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
 The @code{getpeername} function returns the address of the socket that
 @var{socket} is connected to; it stores the address in the memory space
 specified by @var{addr} and @var{length-ptr}.  It stores the length of
@@ -2254,6 +2746,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{@prelim{}@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}.
@@ -2321,6 +2814,7 @@ Primitives}.
 @comment sys/socket.h
 @comment BSD
 @deftypefun ssize_t recv (int @var{socket}, void *@var{buffer}, size_t @var{size}, int @var{flags})
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
 The @code{recv} function is like @code{read}, but with the additional
 flags @var{flags}.  The possible values of @var{flags} are described
 in @ref{Socket Data Options}.
@@ -2649,6 +3143,7 @@ more information about the @code{connect} function.
 @comment sys/socket.h
 @comment BSD
 @deftypefun ssize_t sendto (int @var{socket}, const void *@var{buffer}, size_t @var{size}, int @var{flags}, struct sockaddr *@var{addr}, socklen_t @var{length})
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
 The @code{sendto} function transmits the data in the @var{buffer}
 through the socket @var{socket} to the destination address specified
 by the @var{addr} and @var{length} arguments.  The @var{size} argument
@@ -2684,6 +3179,7 @@ also tells you where it was sent from.  This function is declared in
 @comment sys/socket.h
 @comment BSD
 @deftypefun ssize_t recvfrom (int @var{socket}, void *@var{buffer}, size_t @var{size}, int @var{flags}, struct sockaddr *@var{addr}, socklen_t *@var{length-ptr})
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
 The @code{recvfrom} function reads one packet from the socket
 @var{socket} into the buffer @var{buffer}.  The @var{size} argument
 specifies the maximum number of bytes to be read.
@@ -2731,6 +3227,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{@prelim{}@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 +3239,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{@prelim{}@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
@@ -2929,6 +3427,7 @@ They are declared in @file{sys/socket.h}.
 @comment sys/socket.h
 @comment BSD
 @deftypefun int getsockopt (int @var{socket}, int @var{level}, int @var{optname}, void *@var{optval}, socklen_t *@var{optlen-ptr})
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
 The @code{getsockopt} function gets information about the value of
 option @var{optname} at level @var{level} for socket @var{socket}.
 
@@ -2959,6 +3458,7 @@ The @var{optname} doesn't make sense for the given @var{level}.
 @comment sys/socket.h
 @comment BSD
 @deftypefun int setsockopt (int @var{socket}, int @var{level}, int @var{optname}, const void *@var{optval}, socklen_t @var{optlen})
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
 This function is used to set the socket option @var{optname} at level
 @var{level} for socket @var{socket}.  The value of the option is passed
 in the buffer @var{optval} of size @var{optlen}.
@@ -3155,6 +3655,21 @@ copy the information if you need to save it.
 @comment netdb.h
 @comment BSD
 @deftypefun {struct netent *} getnetbyname (const char *@var{name})
+@safety{@prelim{}@mtunsafe{@mtasurace{:netbyname} @mtsenv{} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
+@c getnetbyname =~ getpwuid @mtasurace:netbyname @mtsenv @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c  libc_lock_lock dup @asulock @aculock
+@c  malloc dup @ascuheap @acsmem
+@c  getnetbyname_r dup @mtsenv @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c  realloc dup @ascuheap @acsmem
+@c  free dup @ascuheap @acsmem
+@c  libc_lock_unlock dup @aculock
+@c
+@c getnetbyname_r =~ getpwuid_r @mtsenv @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c   no nscd support
+@c  res_maybe_init(!preinit) dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@c  nss_networks_lookup2 =~ nss_passwd_lookup2 @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c  *fct.l -> _nss_*_getnetbyname_r @ascuplugin
+@c  nss_next2 dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
 The @code{getnetbyname} function returns information about the network
 named @var{name}.  It returns a null pointer if there is no such
 network.
@@ -3163,6 +3678,20 @@ network.
 @comment netdb.h
 @comment BSD
 @deftypefun {struct netent *} getnetbyaddr (uint32_t @var{net}, int @var{type})
+@safety{@prelim{}@mtunsafe{@mtasurace{:netbyaddr} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
+@c getnetbyaddr =~ getpwuid @mtasurace:netbyaddr @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c  libc_lock_lock dup @asulock @aculock
+@c  malloc dup @ascuheap @acsmem
+@c  getnetbyaddr_r dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c  realloc dup @ascuheap @acsmem
+@c  free dup @ascuheap @acsmem
+@c  libc_lock_unlock dup @aculock
+@c
+@c getnetbyaddr_r =~ getpwuid_r @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c   no nscd support
+@c  nss_networks_lookup2 =~ nss_passwd_lookup2 @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c  *fct.l -> _nss_*_getnetbyaddr_r @ascuplugin
+@c  nss_next2 dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
 The @code{getnetbyaddr} function returns information about the network
 of type @var{type} with number @var{net}.  You should specify a value of
 @code{AF_INET} for the @var{type} argument for Internet networks.
@@ -3178,6 +3707,17 @@ functions because they are not reentrant.
 @comment netdb.h
 @comment BSD
 @deftypefun void setnetent (int @var{stayopen})
+@safety{@prelim{}@mtunsafe{@mtasurace{:netent} @mtsenv{} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
+@c setnetent @mtasurace:netent @mtsenv @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c  libc_lock_lock dup @asulock @aculock
+@c  nss_setent(nss_networks_lookup2) @mtasurace:netent @mtsenv @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c   res_maybe_init(!preinit) dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@c   setup(nss_networks_lookup2) @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c    *lookup_fct = nss_networks_lookup2 dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c    nss_lookup dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c   *fct.f @mtasurace:netent @ascuplugin
+@c   nss_next2 dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c  libc_lock_unlock dup @aculock
 This function opens and rewinds the networks database.
 
 If the @var{stayopen} argument is nonzero, this sets a flag so that
@@ -3190,6 +3730,26 @@ reopening the database for each call.
 @comment netdb.h
 @comment BSD
 @deftypefun {struct netent *} getnetent (void)
+@safety{@prelim{}@mtunsafe{@mtasurace{:netent} @mtasurace{:netentbuf} @mtsenv{} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
+@c getnetent @mtasurace:netent @mtasurace:netentbuf @mtsenv @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c  libc_lock_lock dup @asulock @aculock
+@c  nss_getent(getnetent_r) @mtasurace:netent @mtsenv @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c   malloc dup @ascuheap @acsmem
+@c   *func = getnetent_r dup @mtasurace:netent @mtsenv @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c   realloc dup @ascuheap @acsmem
+@c   free dup @ascuheap @acsmem
+@c  libc_lock_unlock dup @aculock
+@c
+@c getnetent_r @mtasurace:netent @mtsenv @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c  libc_lock_lock dup @asulock @aculock
+@c  nss_getent_r(nss_networks_lookup2) @mtasurace:netent @mtsenv @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c   res_maybe_init(!preinit) dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@c   setup(nss_networks_lookup2) dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c   *fct.f @mtasurace:servent @ascuplugin
+@c   nss_next2 dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c   nss_lookup dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c   *sfct.f @mtasurace:netent @ascuplugin
+@c  libc_lock_unlock dup @aculock
 This function returns the next entry in the networks database.  It
 returns a null pointer if there are no more entries.
 @end deftypefun
@@ -3197,5 +3757,14 @@ returns a null pointer if there are no more entries.
 @comment netdb.h
 @comment BSD
 @deftypefun void endnetent (void)
+@safety{@prelim{}@mtunsafe{@mtasurace{:netent} @mtsenv{} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
+@c endnetent @mtasurace:netent @mtsenv @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c  libc_lock_lock @asulock @aculock
+@c  nss_endent(nss_networks_lookup2) @mtasurace:netent @mtsenv @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c   res_maybe_init(!preinit) dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@c   setup(nss_networks_lookup2) dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c   *fct.f @mtasurace:netent @ascuplugin
+@c   nss_next2 dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c  libc_lock_unlock @aculock
 This function closes the networks database.
 @end deftypefun

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

commit 926b6a50007119c543268d2a8e2c85c1b6b06185
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/intro.texi b/manual/intro.texi
index 55234cc..30c9b4a 100644
--- a/manual/intro.texi
+++ b/manual/intro.texi
@@ -719,6 +719,21 @@ signals are enabled, and so the environment can be considered
 effectively constant in these contexts, which makes the former safe.
 
 
+@item @code{sigintr}
+@cindex sigintr
+
+Functions marked with @code{sigintr} as an MT-Safety issue access the
+@code{_sigintr} internal data structure without any guards to ensure
+safety in the presence of concurrent modifications.
+
+We do not mark these functions as MT- or AS-Unsafe, however, because
+functions that modify the this data structure are all marked with
+@code{const:sigintr} and regarded as unsafe.  Being unsafe, the latter
+are not to be called when multiple threads are running or asynchronous
+signals are enabled, and so the data structure can be considered
+effectively constant in these contexts, which makes the former safe.
+
+
 @item @code{fd}
 @cindex fd
 
diff --git a/manual/macros.texi b/manual/macros.texi
index 7b3b0f9..6ee58ef 100644
--- a/manual/macros.texi
+++ b/manual/macros.texi
@@ -118,6 +118,9 @@ locale\comments\
 @macro mtsenv {comments}
 env\comments\
 @end macro
+@macro mtssigintr {comments}
+sigintr\comments\
+@end macro
 @macro mtuinit {comments}
 init\comments\
 @end macro
diff --git a/manual/signal.texi b/manual/signal.texi
index adcda37..1d4444a 100644
--- a/manual/signal.texi
+++ b/manual/signal.texi
@@ -889,6 +889,29 @@ may come from a signal handler in the same process.
 @comment string.h
 @comment GNU
 @deftypefun {char *} strsignal (int @var{signum})
+@safety{@prelim{}@mtunsafe{@mtasurace{:strsignal} @mtslocale{}}@asunsafe{@asuinit{} @ascuintl{} @asucorrupt{} @ascuheap{}}@acunsafe{@acuinit{} @acucorrupt{} @acsmem{}}}
+@c strsignal @mtasurace:strsignal @mtslocale @asuinit @ascuintl @asucorrupt @ascuheap @acucorrupt @acsmem
+@c   uses a static buffer if tsd key creation fails
+@c  [once] init
+@c   libc_key_create ok
+@c    pthread_key_create ok
+@c     KEY_UNUSED ok
+@c     KEY_USABLE ok
+@c  getbuffer @asucorrupt @ascuheap @acsmem
+@c   libc_getspecific ok
+@c    pthread_getspecific ok
+@c   malloc dup @ascuheap @acsmem
+@c   libc_setspecific @asucorrupt @ascuheap @acucorrupt @acsmem
+@c    pthread_setspecific @asucorrupt @ascuheap @acucorrupt @acsmem
+@c      a level2 block may be allocated by a signal handler after
+@c      another call already made a decision to allocate it, thus losing
+@c      the allocated value.  the seq number is updated before the
+@c      value, which might cause an earlier-generation value to seem
+@c      current if setspecific is cancelled or interrupted by a signal
+@c     KEY_UNUSED ok
+@c     calloc dup @ascuheap @acsmem
+@c  snprintf dup @mtslocale @ascuheap @acsmem
+@c  _ @ascuintl
 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
@@ -903,6 +926,12 @@ This function is a GNU extension, declared in the header file
 @comment signal.h
 @comment BSD
 @deftypefun void psignal (int @var{signum}, const char *@var{message})
+@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@asucorrupt{} @ascuintl{} @ascuheap{}}@acunsafe{@aculock{} @acucorrupt{} @acsmem{}}}
+@c psignal @mtslocale @asucorrupt @ascuintl @ascuheap @aculock @acucorrupt @acsmem
+@c  _ @ascuintl
+@c  fxprintf @asucorrupt @aculock @acucorrupt
+@c  asprintf @mtslocale @ascuheap @acsmem
+@c  free dup @ascuheap @acsmem
 This function prints a message describing the signal @var{signum} to the
 standard error output stream @code{stderr}; see @ref{Standard Streams}.
 
@@ -972,6 +1001,12 @@ The name @code{sighandler_t} for this data type is a GNU extension.
 @comment signal.h
 @comment ISO
 @deftypefun sighandler_t signal (int @var{signum}, sighandler_t @var{action})
+@safety{@prelim{}@mtsafe{@mtssigintr{}}@assafe{}@acsafe{}}
+@c signal ok
+@c  sigemptyset dup ok
+@c  sigaddset dup ok
+@c  sigismember dup ok
+@c  sigaction dup ok
 The @code{signal} function establishes @var{action} as the action for
 the signal @var{signum}.
 
@@ -1094,6 +1129,10 @@ example because these are designed to provide information for debugging
 @comment signal.h
 @comment GNU
 @deftypefun sighandler_t sysv_signal (int @var{signum}, sighandler_t @var{action})
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+@c sysv_signal ok
+@c  sigemptyset dup ok
+@c  sigaction dup ok
 The @code{sysv_signal} implements the behavior of the standard
 @code{signal} function as found on SVID systems.  The difference to BSD
 systems is that the handler is deinstalled after a delivery of a signal.
@@ -1106,6 +1145,8 @@ preferred method.
 @comment signal.h
 @comment SVID
 @deftypefun sighandler_t ssignal (int @var{signum}, sighandler_t @var{action})
+@safety{@prelim{}@mtsafe{@mtssigintr{}}@assafe{}@acsafe{}}
+@c Aliases signal and bsd_signal.
 The @code{ssignal} function does the same thing as @code{signal}; it is
 provided only for compatibility with SVID.
 @end deftypefun
@@ -1172,6 +1213,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{@prelim{}@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.
@@ -2168,6 +2210,14 @@ function is declared in @file{signal.h}.
 @comment signal.h
 @comment ISO
 @deftypefun int raise (int @var{signum})
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+@c raise ok
+@c [posix]
+@c  getpid dup ok
+@c  kill dup ok
+@c [linux]
+@c  syscall(gettid) ok
+@c  syscall(tgkill) ok
 The @code{raise} function sends the signal @var{signum} to the calling
 process.  It returns zero if successful and a nonzero value if it fails.
 About the only reason for failure would be if the value of @var{signum}
@@ -2177,6 +2227,8 @@ is invalid.
 @comment signal.h
 @comment SVID
 @deftypefun int gsignal (int @var{signum})
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+@c Aliases raise.
 The @code{gsignal} function does the same thing as @code{raise}; it is
 provided only for compatibility with SVID.
 @end deftypefun
@@ -2269,6 +2321,11 @@ The @code{kill} function is declared in @file{signal.h}.
 @comment signal.h
 @comment POSIX.1
 @deftypefun int kill (pid_t @var{pid}, int @var{signum})
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+@c The hurd implementation is not a critical section, so it's not
+@c immediately obvious that, in case of cancellation, it won't leak
+@c ports or the memory allocated by proc_getpgrppids when pid <= 0.
+@c Since none of these make it AC-Unsafe, I'm leaving them out.
 The @code{kill} function sends the signal @var{signum} to the process
 or process group specified by @var{pid}.  Besides the signals listed in
 @ref{Standard Signals}, @var{signum} can also have a value of zero to
@@ -2325,6 +2382,8 @@ The @var{pid} argument does not refer to an existing process or group.
 @comment signal.h
 @comment BSD
 @deftypefun int killpg (int @var{pgid}, int @var{signum})
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+@c Calls kill with -pgid.
 This is similar to @code{kill}, but sends signal @var{signum} to the
 process group @var{pgid}.  This function is provided for compatibility
 with BSD; using @code{kill} to do this is more portable.
@@ -2497,6 +2556,8 @@ about.)
 @comment signal.h
 @comment POSIX.1
 @deftypefun int sigemptyset (sigset_t *@var{set})
+@safety{@prelim{}@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 +2565,7 @@ defined signals.  It always returns @code{0}.
 @comment signal.h
 @comment POSIX.1
 @deftypefun int sigfillset (sigset_t *@var{set})
+@safety{@prelim{}@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 +2573,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{@prelim{}@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 +2590,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{@prelim{}@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 +2602,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{@prelim{}@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 +2641,10 @@ 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{@prelim{}@mtunsafe{@mtasurace{:sigprocmask/bsd(SIG_UNBLOCK)}}@asunsafe{@asulock{/hurd}}@acunsafe{@aculock{/hurd}}}
+@c This takes the hurd_self_sigstate-returned object's lock on HURD.  On
+@c BSD, SIG_UNBLOCK is emulated with two sigblock calls, which
+@c introduces a race window.
 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:
@@ -2759,6 +2828,10 @@ You can find out which signals are pending at any time by calling
 @comment signal.h
 @comment POSIX.1
 @deftypefun int sigpending (sigset_t *@var{set})
+@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{/hurd}}@acunsafe{@aculock{/hurd}}}
+@c Direct rt_sigpending syscall on most systems.  On hurd, calls
+@c hurd_self_sigstate, it copies the sigstate's pending while holding
+@c its lock.
 The @code{sigpending} function stores information about pending signals
 in @var{set}.  If there is a pending signal that is blocked from
 delivery, then that signal is a member of the returned set.  (You can
@@ -2922,6 +2995,17 @@ you use it.
 @comment unistd.h
 @comment POSIX.1
 @deftypefun int pause (void)
+@safety{@prelim{}@mtunsafe{@mtasurace{:sigprocmask/!bsd!linux}}@asunsafe{@asulock{/hurd}}@acunsafe{@aculock{/hurd}}}
+@c  The signal mask read by sigprocmask may be overridden by another
+@c  thread or by a signal handler before we call sigsuspend.  Is this a
+@c  safety issue?  Probably not.
+@c pause @mtasurace:sigprocmask/!bsd!linux @asulock/hurd @aculock/hurd
+@c [ports/linux/generic]
+@c  syscall_pause ok
+@c [posix]
+@c  sigemptyset dup ok
+@c  sigprocmask(SIG_BLOCK) dup @asulock/hurd @aculock/hurd [no @mtasurace:sigprocmask/bsd(SIG_UNBLOCK)] ok
+@c  sigsuspend dup @mtasurace:sigprocmask/!bsd!linux @asulock/hurd @aculock/hurd
 The @code{pause} function suspends program execution until a signal
 arrives whose action is either to execute a handler function, or to
 terminate the process.
@@ -3017,6 +3101,17 @@ signals be handled by their handlers.
 @comment signal.h
 @comment POSIX.1
 @deftypefun int sigsuspend (const sigset_t *@var{set})
+@safety{@prelim{}@mtunsafe{@mtasurace{:sigprocmask/!bsd!linux}}@asunsafe{@asulock{/hurd}}@acunsafe{@aculock{/hurd}}}
+@c sigsuspend @mtasurace:sigprocmask/!bsd!linux @asulock/hurd @aculock/hurd
+@c [posix] @mtasurace on saving and restoring the procmask
+@c  sigprocmask(SIG_SETMASK) dup @asulock/hurd @aculock/hurd [no @mtasurace:sgprocmask/bsd(SIG_UNBLOCK)]
+@c  pause @asulock/hurd @aculock/hurd
+@c [bsd]
+@c  sigismember dup ok
+@c  sigmask dup ok
+@c  sigpause dup ok [no @mtasurace:sigprocmask/!bsd!linux @asulock/hurd @aculock/hurd]
+@c [linux]
+@c  do_sigsuspend ok
 This function replaces the process's signal mask with @var{set} and then
 suspends the process until a signal is delivered whose action is either
 to terminate the process or invoke a signal handling function.  In other
@@ -3150,6 +3245,9 @@ delivered on the normal user stack.
 @comment signal.h
 @comment XPG
 @deftypefun int sigaltstack (const stack_t *restrict @var{stack}, stack_t *restrict @var{oldstack})
+@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{/hurd}}@acunsafe{@aculock{/hurd}}}
+@c Syscall on Linux and BSD; the HURD implementation takes a lock on
+@c the hurd_self_sigstate-returned struct.
 The @code{sigaltstack} function specifies an alternate stack for use
 during signal handling.  When a signal is received by the process and
 its action indicates that the signal stack is used, the system arranges
@@ -3196,6 +3294,8 @@ This field is true if the process is currently using this stack.
 @comment signal.h
 @comment BSD
 @deftypefun int sigstack (struct sigstack *@var{stack}, struct sigstack *@var{oldstack})
+@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{/hurd}}@acunsafe{@aculock{/hurd}}}
+@c Lossy and dangerous (no size limit) wrapper for sigaltstack.
 The @code{sigstack} function specifies an alternate stack for use during
 signal handling.  When a signal is received by the process and its
 action indicates that the signal stack is used, the system arranges a
@@ -3301,6 +3401,13 @@ structure, it means to reset the action for the signal back to
 @comment signal.h
 @comment BSD
 @deftypefun int sigvec (int @var{signum}, const struct sigvec *@var{action}, struct sigvec *@var{old-action})
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+@c This is mostly a safe wrapper for sigaction.  The exception are
+@c systems that lack SA_RESETHAND, in which a signal handler wrapper is
+@c used that calls sigaction to reset the handler before calling the
+@c user-supplied handler; it's unlikely that this emulation is used
+@c anywhere, for user-supplied flags and mask don't seem to be used
+@c the way one would expect.
 This function is the equivalent of @code{sigaction} (@pxref{Advanced Signal
 Handling}); it installs the action @var{action} for the signal @var{signum},
 returning information about the previous action in effect for that signal
@@ -3310,6 +3417,14 @@ in @var{old-action}.
 @comment signal.h
 @comment BSD
 @deftypefun int siginterrupt (int @var{signum}, int @var{failflag})
+@safety{@prelim{}@mtunsafe{@mtasuconst{:@mtssigintr{}}}@asunsafe{}@acunsafe{@acucorrupt{}}}
+@c This calls sigaction twice, once to get the current sigaction for the
+@c specified signal, another to apply the flags change.  This could
+@c override the effects of a concurrent sigaction call.  It also
+@c modifies without any guards the global _sigintr variable, that
+@c bsd_signal reads from, and it may leave _sigintr modified without
+@c overriding the active handler if cancelled between the two
+@c operations.
 This function specifies which approach to use when certain primitives
 are interrupted by handling signal @var{signum}.  If @var{failflag} is
 false, signal @var{signum} restarts primitives.  If @var{failflag} is
@@ -3323,6 +3438,8 @@ code @code{EINTR}.  @xref{Interrupted Primitives}.
 @comment signal.h
 @comment BSD
 @deftypefn Macro int sigmask (int @var{signum})
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+@c This just shifts signum.
 This macro returns a signal mask that has the bit for signal @var{signum}
 set.  You can bitwise-OR the results of several calls to @code{sigmask}
 together to specify more than one signal.  For example,
@@ -3339,6 +3456,11 @@ specifies a mask that includes all the job-control stop signals.
 @comment signal.h
 @comment BSD
 @deftypefun int sigblock (int @var{mask})
+@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{/hurd}}@acunsafe{@aculock{/hurd}}}
+@c On most POSIX systems, this is a wrapper for sigprocmask(SIG_BLOCK).
+@c The exception are BSD systems other than 4.4, where it is a syscall.
+@c sigblock @asulock/hurd @aculock/hurd
+@c  sigprocmask(SIG_BLOCK) dup @asulock/hurd @aculock/hurd [no @mtasurace:sigprocmask/bsd(SIG_UNBLOCK)]
 This function is equivalent to @code{sigprocmask} (@pxref{Process Signal
 Mask}) with a @var{how} argument of @code{SIG_BLOCK}: it adds the
 signals specified by @var{mask} to the calling process's set of blocked
@@ -3348,6 +3470,11 @@ signals.  The return value is the previous set of blocked signals.
 @comment signal.h
 @comment BSD
 @deftypefun int sigsetmask (int @var{mask})
+@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{/hurd}}@acunsafe{@aculock{/hurd}}}
+@c On most POSIX systems, this is a wrapper for sigprocmask(SIG_SETMASK).
+@c The exception are BSD systems other than 4.4, where it is a syscall.
+@c sigsetmask @asulock/hurd @aculock/hurd
+@c  sigprocmask(SIG_SETMASK) dup @asulock/hurd @aculock/hurd [no @mtasurace:sigprocmask/bsd(SIG_UNBLOCK)]
 This function equivalent to @code{sigprocmask} (@pxref{Process
 Signal Mask}) with a @var{how} argument of @code{SIG_SETMASK}: it sets
 the calling process's signal mask to @var{mask}.  The return value is
@@ -3357,6 +3484,15 @@ the previous set of blocked signals.
 @comment signal.h
 @comment BSD
 @deftypefun int sigpause (int @var{mask})
+@safety{@prelim{}@mtunsafe{@mtasurace{:sigprocmask/!bsd!linux}}@asunsafe{@asulock{/hurd}}@acunsafe{@asulock{/hurd}}}
+@c sigpause @mtasurace:sigprocmask/!bsd!linux @asulock/hurd @aculock/hurd
+@c [posix]
+@c  __sigpause @mtasurace:sigprocmask/!bsd!linux @asulock/hurd @aculock/hurd
+@c   do_sigpause @mtasurace:sigprocmask/!bsd!linux @asulock/hurd @aculock/hurd
+@c    sigprocmask(0) dup @asulock/hurd @aculock/hurd [no @mtasurace:sigprocmask/bsd(SIG_UNBLOCK)]
+@c    sigdelset dup ok
+@c    sigset_set_old_mask dup ok
+@c    sigsuspend dup @mtasurace:sigprocmask/!bsd!linux @asulock/hurd @aculock/hurd
 This function is the equivalent of @code{sigsuspend} (@pxref{Waiting
 for a Signal}):  it sets the calling process's signal mask to @var{mask},
 and waits for a signal to arrive.  On return the previous set of blocked

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

commit 3d56491d603abbcad6008fbf748aa181cf8f68b5
Author: Alexandre Oliva <aoliva@redhat.com>
Date:   Sat Jan 4 02:56:51 2014 -0200

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

diff --git a/manual/setjmp.texi b/manual/setjmp.texi
index b3c0a7b..84911c4 100644
--- a/manual/setjmp.texi
+++ b/manual/setjmp.texi
@@ -107,6 +107,10 @@ identify a specific place to return to.
 @comment setjmp.h
 @comment ISO
 @deftypefn Macro int setjmp (jmp_buf @var{state})
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+@c _setjmp ok
+@c  __sigsetjmp(!savemask) ok
+@c   __sigjmp_save(!savemask) ok, does not call sigprocmask
 When called normally, @code{setjmp} stores information about the
 execution state of the program in @var{state} and returns zero.  If
 @code{longjmp} is later used to perform a non-local exit to this
@@ -116,6 +120,20 @@ execution state of the program in @var{state} and returns zero.  If
 @comment setjmp.h
 @comment ISO
 @deftypefun void longjmp (jmp_buf @var{state}, int @var{value})
+@safety{@prelim{}@mtsafe{}@asunsafe{@ascuplugin{} @asucorrupt{} @asulock{/hurd}}@acunsafe{@acucorrupt{} @aculock{/hurd}}}
+@c __libc_siglongjmp @ascuplugin @asucorrupt @asulock/hurd @acucorrupt @aculock/hurd
+@c  _longjmp_unwind @ascuplugin @asucorrupt @acucorrupt
+@c   __pthread_cleanup_upto @ascuplugin @asucorrupt @acucorrupt
+@c     plugins may be unsafe themselves, but even if they weren't, this
+@c     function isn't robust WRT async signals and cancellation:
+@c     cleanups aren't taken off the stack right away, only after all
+@c     cleanups have been run.  This means that async-cancelling
+@c     longjmp, or interrupting longjmp with an async signal handler
+@c     that calls longjmp may run the same cleanups multiple times.
+@c    _JMPBUF_UNWINDS_ADJ ok
+@c    *cleanup_buf->__routine @ascuplugin
+@c  sigprocmask(SIG_SETMASK) dup @asulock/hurd @aculock/hurd
+@c  __longjmp ok
 This function restores current execution to the state saved in
 @var{state}, and continues execution from the call to @code{setjmp} that
 established that return point.  Returning from @code{setjmp} by means of
@@ -199,6 +217,11 @@ information about the set of blocked signals.
 @comment setjmp.h
 @comment POSIX.1
 @deftypefun int sigsetjmp (sigjmp_buf @var{state}, int @var{savesigs})
+@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{/hurd}}@acunsafe{@aculock{/hurd}}}
+@c sigsetjmp @asulock/hurd @aculock/hurd
+@c  __sigsetjmp(savemask) @asulock/hurd @aculock/hurd
+@c   __sigjmp_save(savemask) @asulock/hurd @aculock/hurd
+@c    sigprocmask(SIG_BLOCK probe) dup @asulock/hurd @aculock/hurd
 This is similar to @code{setjmp}.  If @var{savesigs} is nonzero, the set
 of blocked signals is saved in @var{state} and will be restored if a
 @code{siglongjmp} is later performed with this @var{state}.
@@ -207,6 +230,8 @@ of blocked signals is saved in @var{state} and will be restored if a
 @comment setjmp.h
 @comment POSIX.1
 @deftypefun void siglongjmp (sigjmp_buf @var{state}, int @var{value})
+@safety{@prelim{}@mtsafe{}@asunsafe{@ascuplugin{} @asucorrupt{} @asulock{/hurd}}@acunsafe{@acucorrupt{} @aculock{/hurd}}}
+@c Alias to longjmp.
 This is similar to @code{longjmp} except for the type of its @var{state}
 argument.  If the @code{sigsetjmp} call that set this @var{state} used a
 nonzero @var{savesigs} flag, @code{siglongjmp} also restores the set of
@@ -267,6 +292,10 @@ and modification happens through one of the following functions:
 @comment ucontext.h
 @comment SVID
 @deftypefun int getcontext (ucontext_t *@var{ucp})
+@safety{@prelim{}@mtsafe{@mtsrace{:ucp}}@assafe{}@acsafe{}}
+@c Linux-only implementations in assembly, including sigprocmask
+@c syscall.  A few cases call the sigprocmask function, but that's safe
+@c too.  The ppc case is implemented in terms of a swapcontext syscall.
 The @code{getcontext} function initializes the variable pointed to by
 @var{ucp} with the context of the calling thread.  The context contains
 the content of the registers, the signal mask, and the current stack.
@@ -293,6 +322,8 @@ used to do that.
 @comment ucontext.h
 @comment SVID
 @deftypefun void makecontext (ucontext_t *@var{ucp}, void (*@var{func}) (void), int @var{argc}, @dots{})
+@safety{@prelim{}@mtsafe{@mtsrace{:ucp}}@assafe{}@acsafe{}}
+@c Linux-only implementations mostly in assembly, nothing unsafe.
 
 The @var{ucp} parameter passed to the @code{makecontext} shall be
 initialized by a call to @code{getcontext}.  The context will be
@@ -339,6 +370,15 @@ requires detection of the platform at compile time.
 @comment ucontext.h
 @comment SVID
 @deftypefun int setcontext (const ucontext_t *@var{ucp})
+@safety{@prelim{}@mtsafe{@mtsrace{:ucp}}@asunsafe{@asucorrupt{}}@acunsafe{@asucorrupt{}}}
+@c Linux-only implementations mostly in assembly.  Some ports use
+@c sigreturn or swapcontext syscalls; others restore the signal mask
+@c first and then proceed restore other registers in userland, which
+@c leaves a window for cancellation or async signals with misaligned or
+@c otherwise corrupt stack.  ??? Switching to a different stack, or even
+@c to an earlier state on the same stack, may conflict with pthread
+@c cleanups.  This is not quite MT-Unsafe, it's a different kind of
+@c safety issue.
 
 The @code{setcontext} function restores the context described by
 @var{ucp}.  The context is not modified and can be reused as often as
@@ -372,6 +412,10 @@ there are situations where the current context has to be preserved.
 @comment ucontext.h
 @comment SVID
 @deftypefun int swapcontext (ucontext_t *restrict @var{oucp}, const ucontext_t *restrict @var{ucp})
+@safety{@prelim{}@mtsafe{@mtsrace{:oucp} @mtsrace{:ucp}}@asunsafe{@asucorrupt{}}@acunsafe{@asucorrupt{}}}
+@c Linux-only implementations mostly in assembly.  Some ports call or
+@c inline getcontext and/or setcontext, adjusting the saved context in
+@c between, so we inherit the potential issues of both.
 
 The @code{swapcontext} function is similar to @code{setcontext} but
 instead of just replacing the current context the latter is first saved

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

commit 6010f49d13a53a5f43ff99f5fb9279df00292963
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 a714ba7..baaaa84 100644
--- a/manual/search.texi
+++ b/manual/search.texi
@@ -72,6 +72,7 @@ two functions can be found in @file{search.h}.
 @comment search.h
 @comment SVID
 @deftypefun {void *} lfind (const void *@var{key}, const void *@var{base}, size_t *@var{nmemb}, size_t @var{size}, comparison_fn_t @var{compar})
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
 The @code{lfind} function searches in the array with @code{*@var{nmemb}}
 elements of @var{size} bytes pointed to by @var{base} for an element
 which matches the one pointed to by @var{key}.  The function pointed to
@@ -90,6 +91,21 @@ searching.
 @comment search.h
 @comment SVID
 @deftypefun {void *} lsearch (const void *@var{key}, void *@var{base}, size_t *@var{nmemb}, size_t @var{size}, comparison_fn_t @var{compar})
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+@c A signal handler that interrupted an insertion and performed an
+@c insertion itself would leave the array in a corrupt state (e.g. one
+@c new element initialized twice, with parts of both initializations
+@c prevailing, and another uninitialized element), but this is just a
+@c special case of races on user-controlled objects, that have to be
+@c avoided by users.
+
+@c In case of cancellation, we know the array won't be left in a corrupt
+@c state; the new element is initialized before the element count is
+@c incremented, and the compiler can't reorder these operations because
+@c it can't know that they don't alias.  So, we'll either cancel after
+@c the increment and the initialization are both complete, or the
+@c increment won't have taken place, and so how far the initialization
+@c got doesn't matter.
 The @code{lsearch} function is similar to the @code{lfind} function.  It
 searches the given array for an element and returns it if found.  The
 difference is that if no matching element is found the @code{lsearch}
@@ -113,6 +129,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{@prelim{}@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 +163,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{@prelim{}@mtsafe{}@assafe{}@acunsafe{@acucorrupt{}}}
 The @var{qsort} function sorts the array @var{array}.  The array contains
 @var{count} elements, each of which is of size @var{size}.
 
@@ -256,6 +274,9 @@ The following functions are declared in the header file @file{search.h}.
 @comment search.h
 @comment SVID
 @deftypefun int hcreate (size_t @var{nel})
+@safety{@prelim{}@mtunsafe{@mtasurace{:hsearch}}@asunsafe{@ascuheap{}}@acunsafe{@acucorrupt{} @acsmem{}}}
+@c hcreate @mtasurace{:hsearch} @ascuheap @acucorrupt @acsmem
+@c  hcreate_r dup @mtsrace:htab @ascuheap @acucorrupt @acsmem
 The @code{hcreate} function creates a hashing table which can contain at
 least @var{nel} elements.  There is no possibility to grow this table so
 it is necessary to choose the value for @var{nel} wisely.  The method
@@ -285,6 +306,9 @@ table in use or the program runs out of memory.
 @comment search.h
 @comment SVID
 @deftypefun void hdestroy (void)
+@safety{@prelim{}@mtunsafe{@mtasurace{:hsearch}}@asunsafe{@ascuheap{}}@acunsafe{@acucorrupt{} @acsmem{}}}
+@c hdestroy @mtasurace:hsearch @ascuheap @acucorrupt @acsmem
+@c  hdestroy_r dup @mtsrace:htab @ascuheap @acucorrupt @acsmem
 The @code{hdestroy} function can be used to free all the resources
 allocated in a previous call of @code{hcreate}.  After a call to this
 function it is again possible to call @code{hcreate} and allocate a new
@@ -328,6 +352,9 @@ this element might stay undefined since it is not used.
 @comment search.h
 @comment SVID
 @deftypefun {ENTRY *} hsearch (ENTRY @var{item}, ACTION @var{action})
+@safety{@prelim{}@mtunsafe{@mtasurace{:hsearch}}@asunsafe{}@acunsafe{@acucorrupt{/action==ENTER}}}
+@c hsearch @mtasurace:hsearch @acucorrupt/action==ENTER
+@c  hsearch_r dup @mtsrace:htab @acucorrupt/action==ENTER
 To search in a hashing table created using @code{hcreate} the
 @code{hsearch} function must be used.  This function can perform simple
 search for an element (if @var{action} has the @code{FIND}) or it can
@@ -358,6 +385,24 @@ members should be changed directly.
 @comment search.h
 @comment GNU
 @deftypefun int hcreate_r (size_t @var{nel}, struct hsearch_data *@var{htab})
+@safety{@prelim{}@mtsafe{@mtsrace{:htab}}@asunsafe{@ascuheap{}}@acunsafe{@acucorrupt{} @acsmem{}}}
+@c Unlike the lsearch array, the htab is (at least in part) opaque, so
+@c let's make it absolutely clear that ensuring exclusive access is a
+@c caller responsibility.
+
+@c Cancellation is unlikely to leave the htab in a corrupt state: the
+@c last field to be initialized is the one that tells whether the entire
+@c data structure was initialized, and there's a function call (calloc)
+@c in between that will often ensure all other fields are written before
+@c the table.  However, should this call be inlined (say with LTO), this
+@c assumption may not hold.  The calloc call doesn't cross our library
+@c interface barrier, so let's consider this could happen and mark this
+@c with @acucorrupt.  It's no safety loss, since we already have
+@c @ascuheap anyway...
+
+@c hcreate_r @mtsrace:htab @ascuheap @acucorrupt @acsmem
+@c  isprime ok
+@c  calloc dup @ascuheap @acsmem
 The @code{hcreate_r} function initializes the object pointed to by
 @var{htab} to contain a hashing table with at least @var{nel} elements.
 So this function is equivalent to the @code{hcreate} function except
@@ -376,6 +421,16 @@ programs ran out of memory.
 @comment search.h
 @comment GNU
 @deftypefun void hdestroy_r (struct hsearch_data *@var{htab})
+@safety{@prelim{}@mtsafe{@mtsrace{:htab}}@asunsafe{@ascuheap{}}@acunsafe{@acucorrupt{} @acsmem{}}}
+@c The table is released while the table pointer still points to it.
+@c Async cancellation is thus unsafe, but it already was because we call
+@c free().  Using the table in a handler while it's being released would
+@c also be dangerous, but calling free() already makes it unsafe, and
+@c the requirement on the caller to ensure exclusive access already
+@c guarantees this doesn't happen, so we don't get @asucorrupt.
+
+@c hdestroy_r @mtsrace:htab @ascuheap @acucorrupt @acsmem
+@c  free dup @ascuheap @acsmem
 The @code{hdestroy_r} function frees all resources allocated by the
 @code{hcreate_r} function for this very same object @var{htab}.  As for
 @code{hdestroy} it is the programs responsibility to free the strings
@@ -385,6 +440,13 @@ for the elements of the table.
 @comment search.h
 @comment GNU
 @deftypefun int hsearch_r (ENTRY @var{item}, ACTION @var{action}, ENTRY **@var{retval}, struct hsearch_data *@var{htab})
+@safety{@prelim{}@mtsafe{@mtsrace{:htab}}@assafe{}@acunsafe{@acucorrupt{/action==ENTER}}}
+@c Callers have to ensure mutual exclusion; insertion, if cancelled,
+@c leaves the table in a corrupt state.
+
+@c hsearch_r @mtsrace:htab @acucorrupt/action==ENTER
+@c  strlen dup ok
+@c  strcmp dup ok
 The @code{hsearch_r} function is equivalent to @code{hsearch}.  The
 meaning of the first two arguments is identical.  But instead of
 operating on a single global hashing table the function works on the
@@ -436,6 +498,12 @@ 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{@prelim{}@mtsafe{@mtsrace{:rootp}}@asunsafe{@ascuheap{}}@acunsafe{@acucorrupt{} @acsmem{}}}
+@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 (except for the caller-synchronization
+@c requirement) or after asynchronous cancellation of the thread
+@c 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 +533,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{@prelim{}@mtsafe{@mtsrace{:rootp}}@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 +548,7 @@ elements.
 @comment search.h
 @comment SVID
 @deftypefun {void *} tdelete (const void *@var{key}, void **@var{rootp}, comparison_fn_t @var{compar})
+@safety{@prelim{}@mtsafe{@mtsrace{:rootp}}@asunsafe{@ascuheap{}}@acunsafe{@acucorrupt{} @acsmem{}}}
 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 +562,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{@prelim{}@mtsafe{}@assafe{@ascuheap{}}@acsafe{@acsmem{}}}
 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 +617,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{@prelim{}@mtsafe{@mtsrace{:root}}@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=74f85a50567a0ccce2875ea321141293eeda5837

commit 74f85a50567a0ccce2875ea321141293eeda5837
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 5a1bb04..8c97fb9 100644
--- a/manual/resource.texi
+++ b/manual/resource.texi
@@ -25,6 +25,8 @@ in @file{sys/resource.h}.
 @comment sys/resource.h
 @comment BSD
 @deftypefun int getrusage (int @var{processes}, struct rusage *@var{rusage})
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+@c On HURD, this calls task_info 3 times.  On UNIX, it's a syscall.
 This function reports resource usage totals for processes specified by
 @var{processes}, storing the information in @code{*@var{rusage}}.
 
@@ -132,6 +134,8 @@ scheduled).
 
 @comment sys/vtimes.h
 @deftypefun int vtimes (struct vtimes *@var{current}, struct vtimes *@var{child})
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+@c Calls getrusage twice.
 
 @code{vtimes} reports resource usage totals for a process.
 
@@ -223,6 +227,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{@prelim{}@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 +243,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{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+@c Direct syscall on most systems, wrapper to 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
@@ -250,6 +258,8 @@ If the sources are compiled with @code{_FILE_OFFSET_BITS == 64} on a
 @comment sys/resource.h
 @comment BSD
 @deftypefun int setrlimit (int @var{resource}, const struct rlimit *@var{rlp})
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+@c Direct syscall on most systems; lock-taking critical section on HURD.
 Store the current and maximum limits for the resource @var{resource}
 in @code{*@var{rlp}}.
 
@@ -275,6 +285,8 @@ LFS interface transparently replaces the old interface.
 @comment sys/resource.h
 @comment Unix98
 @deftypefun int setrlimit64 (int @var{resource}, const struct rlimit64 *@var{rlp})
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+@c Wrapper for setrlimit or direct syscall.
 This function is similar to @code{setrlimit} but its second parameter is
 a pointer to a variable of type @code{struct rlimit64} which allows it
 to set values which wouldn't fit in the member of a @code{struct
@@ -434,6 +446,9 @@ above do.  The functions above are better choices.
 @comment ulimit.h
 @comment BSD
 @deftypefun {long int} ulimit (int @var{cmd}, @dots{})
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+@c Wrapper for getrlimit, setrlimit or
+@c sysconf(_SC_OPEN_MAX)->getdtablesize->getrlimit.
 
 @code{ulimit} gets the current limit or sets the current and maximum
 limit for a particular resource for the calling process according to the
@@ -480,6 +495,10 @@ A process tried to increase a maximum limit, but is not superuser.
 @comment sys/vlimit.h
 @comment BSD
 @deftypefun int vlimit (int @var{resource}, int @var{limit})
+@safety{@prelim{}@mtunsafe{@mtasurace{setrlimit}}@asunsafe{}@acsafe{}}
+@c It calls getrlimit and modifies the rlim_cur field before calling
+@c setrlimit.  There's a window for a concurrent call to setrlimit that
+@c modifies e.g. rlim_max, which will be lost if running as super-user.
 
 @code{vlimit} sets the current limit for a resource for a process.
 
@@ -778,6 +797,8 @@ absolute priority value
 @comment sched.h
 @comment POSIX
 @deftypefun int sched_setscheduler (pid_t @var{pid}, int @var{policy}, const struct sched_param *@var{param})
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+@c Direct syscall, Linux only.
 
 This function sets both the absolute priority and the scheduling policy
 for a process.
@@ -848,6 +869,8 @@ tell you what the valid range is.
 @comment sched.h
 @comment POSIX
 @deftypefun int sched_getscheduler (pid_t @var{pid})
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+@c Direct syscall, Linux only.
 
 This function returns the scheduling policy assigned to the process with
 Process ID (pid) @var{pid}, or the calling process if @var{pid} is zero.
@@ -881,6 +904,8 @@ absolute priority, use @code{sched_getparam}.
 @comment sched.h
 @comment POSIX
 @deftypefun int sched_setparam (pid_t @var{pid}, const struct sched_param *@var{param})
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+@c Direct syscall, Linux only.
 
 This function sets a process' absolute priority.
 
@@ -894,6 +919,8 @@ It is functionally identical to @code{sched_setscheduler} with
 @comment sched.h
 @comment POSIX
 @deftypefun int sched_getparam (pid_t @var{pid}, struct sched_param *@var{param})
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+@c Direct syscall, Linux only.
 
 This function returns a process' absolute priority.
 
@@ -923,6 +950,8 @@ There is no process with pid @var{pid} and it is not zero.
 @comment sched.h
 @comment POSIX
 @deftypefun int sched_get_priority_min (int @var{policy})
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+@c Direct syscall, Linux only.
 
 This function returns the lowest absolute priority value that is
 allowable for a process with scheduling policy @var{policy}.
@@ -943,6 +972,8 @@ to this function are:
 @comment sched.h
 @comment POSIX
 @deftypefun int sched_get_priority_max (int @var{policy})
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+@c Direct syscall, Linux only.
 
 This function returns the highest absolute priority value that is
 allowable for a process that with scheduling policy @var{policy}.
@@ -963,6 +994,8 @@ to this function are:
 @comment sched.h
 @comment POSIX
 @deftypefun int sched_rr_get_interval (pid_t @var{pid}, struct timespec *@var{interval})
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+@c Direct syscall, Linux only.
 
 This function returns the length of the quantum (time slice) used with
 the Round Robin scheduling policy, if it is used, for the process with
@@ -987,6 +1020,8 @@ function, so there are no specific @code{errno} values.
 @comment sched.h
 @comment POSIX
 @deftypefun int sched_yield (void)
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+@c Direct syscall on Linux; alias to swtch on HURD.
 
 This function voluntarily gives up the process' claim on the CPU.
 
@@ -1138,6 +1173,8 @@ The highest valid nice value.
 @comment sys/resource.h
 @comment BSD,POSIX
 @deftypefun int getpriority (int @var{class}, int @var{id})
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+@c Direct syscall on UNIX.  On HURD, calls _hurd_priority_which_map.
 Return the nice value of a set of processes; @var{class} and @var{id}
 specify which ones (see below).  If the processes specified do not all
 have the same nice value, this returns the lowest value that any of them
@@ -1165,6 +1202,8 @@ afterward as the criterion for failure.
 @comment sys/resource.h
 @comment BSD,POSIX
 @deftypefun int setpriority (int @var{class}, int @var{id}, int @var{niceval})
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+@c Direct syscall on UNIX.  On HURD, calls _hurd_priority_which_map.
 Set the nice value of a set of processes to @var{niceval}; @var{class}
 and @var{id} specify which ones (see below).
 
@@ -1222,6 +1261,11 @@ process group, or its owner (real uid), according to @var{class}.
 @comment unistd.h
 @comment BSD
 @deftypefun int nice (int @var{increment})
+@safety{@prelim{}@mtunsafe{@mtasurace{:setpriority}}@asunsafe{}@acsafe{}}
+@c Calls getpriority before and after setpriority, using the result of
+@c the first call to compute the argument for setpriority.  This creates
+@c a window for a concurrent setpriority (or nice) call to be lost or
+@c exhibit surprising behavior.
 Increment the nice value of the calling process by @var{increment}.
 The return value is the new nice value on success, and @code{-1} on
 failure.  In the case of failure, @code{errno} will be set to the
@@ -1319,6 +1363,10 @@ manipulation should happen via the next four macros.
 @comment sched.h
 @comment GNU
 @deftypefn Macro void CPU_ZERO (cpu_set_t *@var{set})
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+@c CPU_ZERO ok
+@c  __CPU_ZERO_S ok
+@c   memset dup ok
 This macro initializes the CPU set @var{set} to be the empty set.
 
 This macro is a GNU extension and is defined in @file{sched.h}.
@@ -1327,6 +1375,11 @@ This macro is a GNU extension and is defined in @file{sched.h}.
 @comment sched.h
 @comment GNU
 @deftypefn Macro void CPU_SET (int @var{cpu}, cpu_set_t *@var{set})
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+@c CPU_SET ok
+@c  __CPU_SET_S ok
+@c   __CPUELT ok
+@c   __CPUMASK ok
 This macro adds @var{cpu} to the CPU set @var{set}.
 
 The @var{cpu} parameter must not have side effects since it is
@@ -1338,6 +1391,11 @@ This macro is a GNU extension and is defined in @file{sched.h}.
 @comment sched.h
 @comment GNU
 @deftypefn Macro void CPU_CLR (int @var{cpu}, cpu_set_t *@var{set})
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+@c CPU_CLR ok
+@c  __CPU_CLR_S ok
+@c   __CPUELT dup ok
+@c   __CPUMASK dup ok
 This macro removes @var{cpu} from the CPU set @var{set}.
 
 The @var{cpu} parameter must not have side effects since it is
@@ -1349,6 +1407,11 @@ This macro is a GNU extension and is defined in @file{sched.h}.
 @comment sched.h
 @comment GNU
 @deftypefn Macro int CPU_ISSET (int @var{cpu}, const cpu_set_t *@var{set})
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+@c CPU_ISSET ok
+@c  __CPU_ISSET_S ok
+@c   __CPUELT dup ok
+@c   __CPUMASK dup ok
 This macro returns a nonzero value (true) if @var{cpu} is a member
 of the CPU set @var{set}, and zero (false) otherwise.
 
@@ -1365,6 +1428,9 @@ affinity mask can be retrieved from the system.
 @comment sched.h
 @comment GNU
 @deftypefun int sched_getaffinity (pid_t @var{pid}, size_t @var{cpusetsize}, cpu_set_t *@var{cpuset})
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+@c Wrapped syscall to zero out past the kernel cpu set size; Linux
+@c only.
 
 This functions stores the CPU affinity mask for the process or thread
 with the ID @var{pid} in the @var{cpusetsize} bytes long bitmap
@@ -1393,6 +1459,9 @@ interface must be provided for that.
 @comment sched.h
 @comment GNU
 @deftypefun int sched_setaffinity (pid_t @var{pid}, size_t @var{cpusetsize}, const cpu_set_t *@var{cpuset})
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+@c Wrapped syscall to detect attempts to set bits past the kernel cpu
+@c set size; Linux only.
 
 This function installs the @var{cpusetsize} bytes long affinity mask
 pointed to by @var{cpuset} for the process or thread with the ID @var{pid}.
@@ -1516,6 +1585,9 @@ There is a much older interface available, too.
 @comment unistd.h
 @comment BSD
 @deftypefun int getpagesize (void)
+@safety{@prelim{}@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 +1631,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{@prelim{}@mtsafe{}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsfd{} @acsmem{}}}
+@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 +1643,7 @@ This function is a GNU extension.
 @comment sys/sysinfo.h
 @comment GNU
 @deftypefun {long int} get_avphys_pages (void)
+@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsfd{} @acsmem{}}}
 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 +1689,10 @@ in @file{sys/sysinfo.h}.
 @comment sys/sysinfo.h
 @comment GNU
 @deftypefun int get_nprocs_conf (void)
+@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsfd{} @acsmem{}}}
+@c This function reads from from /sys using dir streams (single user, so
+@c no @mturace 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 +1702,8 @@ This function is a GNU extension.
 @comment sys/sysinfo.h
 @comment GNU
 @deftypefun int get_nprocs (void)
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{@acsfd{}}}
+@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.
@@ -1638,6 +1719,10 @@ running.  This number is average over different periods of times
 @comment stdlib.h
 @comment BSD
 @deftypefun int getloadavg (double @var{loadavg}[], int @var{nelem})
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{@acsfd{}}}
+@c Calls host_info on HURD; on Linux, opens /proc/loadavg, reads from
+@c it, closes it, without cancellation point, and calls strtod_l with
+@c the C locale to convert the strings to doubles.
 This function gets the 1, 5 and 15 minute load averages of the
 system. The values are placed in @var{loadavg}.  @code{getloadavg} will
 place at most @var{nelem} elements into the array but never more than

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

commit f2650546c47bcfffd2800b971677aaa61c278284
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..d6bd3dd 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{@prelim{}@mtsafe{}@asunsafe{@ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsmem{}}}
+@c system @ascuplugin @ascuheap @asulock @aculock @acsmem
+@c  do_system @ascuplugin @ascuheap @asulock @aculock @acsmem
+@c   sigemptyset dup ok
+@c   libc_lock_lock @asulock @aculock
+@c   ADD_REF ok
+@c   sigaction dup ok
+@c   SUB_REF ok
+@c   libc_lock_unlock @aculock
+@c   sigaddset dup ok
+@c   sigprocmask dup ok
+@c   CLEANUP_HANDLER @ascuplugin @ascuheap @acsmem
+@c    libc_cleanup_region_start @ascuplugin @ascuheap @acsmem
+@c     pthread_cleanup_push_defer @ascuplugin @ascuheap @acsmem
+@c      CANCELLATION_P @ascuplugin @ascuheap @acsmem
+@c       CANCEL_ENABLED_AND_CANCELED ok
+@c       do_cancel @ascuplugin @ascuheap @acsmem
+@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 @ascuplugin @ascuheap @acsmem
+@c   libc_enable_asynccancel @ascuplugin @ascuheap @acsmem
+@c    CANCEL_ENABLED_AND_CANCELED_AND_ASYNCHRONOUS dup ok
+@c    do_cancel dup @ascuplugin @ascuheap @acsmem
+@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{@prelim{}@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{@prelim{}@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{@prelim{}@mtsafe{@ascuplugin{}}@assafe{@ascuplugin{}}@acunsafe{@aculock{}}}
+@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{@prelim{}@mtsafe{@ascuplugin{}}@assafe{@ascuplugin{}}@acunsafe{@aculock{}}}
+@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{@prelim{}@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{@prelim{}@mtsafe{}@asunsafe{@ascuheap{}}@acsafe{@acsmem{}}}
 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{@prelim{}@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{@prelim{}@mtsafe{}@asunsafe{@ascuheap{}}@acsafe{@acsmem{}}}
 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{@prelim{}@mtunsafe{@mtsenv{}}@asunsafe{@ascuheap{}}@acsafe{@acsmem{}}}
 The @code{execvp} function is similar to @code{execv}, except that it
 searches the directories listed in the @code{PATH} environment variable
 (@pxref{Standard Environment}) to find the full file name of a
@@ -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{@prelim{}@mtunsafe{@mtsenv{}}@asunsafe{@ascuheap{}}@acsafe{@acsmem{}}}
 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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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=f8c7e6bffb28ca3600d2beb1372a1f2c71f913b9

commit f8c7e6bffb28ca3600d2beb1372a1f2c71f913b9
Author: Alexandre Oliva <aoliva@redhat.com>
Date:   Sat Jan 4 02:56:19 2014 -0200

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

diff --git a/manual/platform.texi b/manual/platform.texi
index 99f4675..872e32e 100644
--- a/manual/platform.texi
+++ b/manual/platform.texi
@@ -15,6 +15,7 @@ Facilities specific to PowerPC that are not specific to a particular
 operating system are declared in @file{sys/platform/ppc.h}.
 
 @deftypefun {uint64_t} __ppc_get_timebase (void)
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
 Read the current value of the Time Base Register.
 
 The @dfn{Time Base Register} is a 64-bit register that stores a monotonically
@@ -28,6 +29,17 @@ efficient.
 @end deftypefun
 
 @deftypefun {uint64_t} __ppc_get_timebase_freq (void)
+@safety{@prelim{}@mtunsafe{@mtuinit{}}@asunsafe{@asucorrupt{:init}}@acunsafe{@acucorrupt{:init}}}
+@c __ppc_get_timebase_freq=__get_timebase_freq @mtuinit @acsfd
+@c  __get_clockfreq @mtuinit @asucorrupt:init @acucorrupt:init @acsfd
+@c    the initialization of the static timebase_freq is not exactly
+@c    safe, because hp_timing_t cannot be atomically set up.
+@c   syscall:get_tbfreq ok
+@c   open dup @acsfd
+@c   read dup ok
+@c   memcpy dup ok
+@c   memmem dup ok
+@c   close dup @acsfd
 Read the current frequency at which the Time Base Register is updated.
 
 This frequency is not related to the processor clock or the bus clock.
@@ -42,17 +54,20 @@ processors.  More information is available in @cite{Power ISA 2.06b - Book II -
 Section 3.2}.
 
 @deftypefun {void} __ppc_yield (void)
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
 Provide a hint that performance will probably be improved if shared resources
 dedicated to the executing processor are released for use by other processors.
 @end deftypefun
 
 @deftypefun {void} __ppc_mdoio (void)
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
 Provide a hint that performance will probably be improved if shared resources
 dedicated to the executing processor are released until all outstanding storage
 accesses to caching-inhibited storage have been completed.
 @end deftypefun
 
 @deftypefun {void} __ppc_mdoom (void)
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
 Provide a hint that performance will probably be improved if shared resources
 dedicated to the executing processor are released until all outstanding storage
 accesses to cacheable storage for which the data is not in the cache have been
@@ -60,6 +75,7 @@ completed.
 @end deftypefun
 
 @deftypefun {void} __ppc_set_ppr_med (void)
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
 Set the Program Priority Register to medium value (default).
 
 The @dfn{Program Priority Register} (PPR) is a 64-bit register that controls
@@ -73,9 +89,11 @@ available in @cite{Power ISA 2.06b - Book II - Section 3.1}.
 @end deftypefun
 
 @deftypefun {void} __ppc_set_ppr_low (void)
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
 Set the Program Priority Register to low value.
 @end deftypefun
 
 @deftypefun {void} __ppc_set_ppr_med_low (void)
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
 Set the Program Priority Register to medium low value.
 @end deftypefun

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

commit 4dc5192e4e788db7427c04df7d46be1fc818c6bf
Author: Alexandre Oliva <aoliva@redhat.com>
Date:   Sat Jan 4 02:56:19 2014 -0200

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

diff --git a/manual/pipe.texi b/manual/pipe.texi
index 21a8a34..2d7e30e 100644
--- a/manual/pipe.texi
+++ b/manual/pipe.texi
@@ -56,6 +56,8 @@ The @code{pipe} function is declared in the header file
 @comment unistd.h
 @comment POSIX.1
 @deftypefun int pipe (int @var{filedes}@t{[2]})
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{@acsfd{}}}
+@c On Linux, syscall pipe2.  On HURD, call socketpair.
 The @code{pipe} function creates a pipe and puts the file descriptors
 for the reading and writing ends of the pipe (respectively) into
 @code{@var{filedes}[0]} and @code{@var{filedes}[1]}.
@@ -108,6 +110,41 @@ much flexibility as using the low-level functions directly.
 @comment stdio.h
 @comment POSIX.2, SVID, BSD
 @deftypefun {FILE *} popen (const char *@var{command}, const char *@var{mode})
+@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{} @asucorrupt{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
+@c popen @ascuheap @asucorrupt @acucorrupt @aculock @acsfd @acsmem
+@c  malloc dup @ascuheap @acsmem
+@c  _IO_init ok
+@c   _IO_no_init ok
+@c    _IO_old_init ok
+@c     _IO_lock_init ok
+@c  _IO_new_file_init @asucorrupt @acucorrupt @aculock @acsfd
+@c   _IO_link_in @asucorrupt @acucorrupt @aculock @acsfd
+@c     the linked list is guarded by a recursive lock;
+@c     it may get corrupted with async signals and cancellation
+@c    _IO_lock_lock dup @aculock
+@c    _IO_flockfile dup @aculock
+@c    _IO_funlockfile dup @aculock
+@c    _IO_lock_unlock dup @aculock
+@c  _IO_new_proc_open @asucorrupt @acucorrupt @aculock @acsfd
+@c    the linked list is guarded by a recursive lock;
+ @c   it may get corrupted with async signals and cancellation
+@c   _IO_file_is_open ok
+@c   pipe2 dup @acsfd
+@c   pipe dup @acsfd
+@c   _IO_fork=fork @aculock
+@c   _IO_close=close_not_cancel dup @acsfd
+@c   fcntl dup ok
+@c   _IO_lock_lock @aculock
+@c   _IO_lock_unlock @aculock
+@c   _IO_mask_flags ok [no @mtasurace:stream, nearly but sufficiently exclusive access]
+@c  _IO_un_link @asucorrupt @acucorrupt @aculock @acsfd
+@c    the linked list is guarded by a recursive lock;
+@c    it may get corrupted with async signals and cancellation
+@c   _IO_lock_lock dup @aculock
+@c   _IO_flockfile dup @aculock
+@c   _IO_funlockfile dup @aculock
+@c   _IO_lock_unlock dup @aculock
+@c  free dup @ascuheap @acsmem
 The @code{popen} function is closely related to the @code{system}
 function; see @ref{Running a Command}.  It executes the shell command
 @var{command} as a subprocess.  However, instead of waiting for the
@@ -131,6 +168,77 @@ cannot be forked, or if the program cannot be executed.
 @comment stdio.h
 @comment POSIX.2, SVID, BSD
 @deftypefun int pclose (FILE *@var{stream})
+@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{} @ascuplugin{} @asucorrupt{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
+@c Although the stream cannot be used after the call, even in case of
+@c async cancellation, because the stream must not be used after pclose
+@c is called, other stdio linked lists and their locks may be left in
+@c corrupt states; that's where the corrupt and lock annotations come
+@c from.
+@c
+@c pclose @ascuheap @ascuplugin @asucorrupt @asulock @acucorrupt @aculock @acsfd @acsmem
+@c  _IO_new_fclose @ascuheap @ascuplugin @asucorrupt @asulock @acucorrupt @aculock @acsfd @acsmem
+@c   _IO_un_link dup @asucorrupt @acucorrupt @aculock @acsfd
+@c   _IO_acquire_lock dup @aculock
+@c    _IO_flockfile dup @aculock
+@c   _IO_file_close_it @ascuheap @ascuplugin @asucorrupt @aculock @acucorrupt @acsfd @acsmem
+@c    _IO_file_is_open dup ok
+@c    _IO_do_flush @asucorrupt @ascuplugin @acucorrupt
+@c     _IO_do_write @asucorrupt @acucorrupt
+@c      new_do_write @asucorrupt @acucorrupt
+@c       _IO_SYSSEEK ok
+@c        lseek64 dup ok
+@c       _IO_SYSWRITE ok
+@c        write_not_cancel dup ok
+@c        write dup ok
+@c       _IO_adjust_column ok
+@c       _IO_setg dup @asucorrupt @acucorrupt [no @mtasurace:stream, locked]
+@c     _IO_wdo_write @asucorrupt @ascuplugin @acucorrupt
+@c      _IO_new_do_write=_IO_do_write dup @asucorrupt @acucorrupt
+@c      *cc->__codecvt_do_out @ascuplugin
+@c      _IO_wsetg dup @asucorrupt @acucorrupt [no @mtasurace:stream, locked]
+@c    _IO_unsave_markers @ascuheap @asucorrupt @acucorrupt @acsmem
+@c     _IO_have_backup dup ok
+@c     _IO_free_backup_area dup @ascuheap @asucorrupt @acucorrupt @acsmem
+@c    _IO_SYSCLOSE @aculock @acucorrupt @acsfd
+@c     _IO_lock_lock dup @aculock
+@c     _IO_close=close_not_cancel dup @acsfd
+@c     _IO_lock_unlock dup @aculock
+@c     _IO_waitpid=waitpid_not_cancel dup ok
+@c    _IO_have_wbackup ok
+@c    _IO_free_wbackup_area @ascuheap @asucorrupt @acucorrupt @acsmem
+@c     _IO_in_backup dup ok
+@c     _IO_switch_to_main_wget_area @asucorrupt @acucorrupt
+@c     free dup @ascuheap @acsmem
+@c    _IO_wsetb @asucorrupt @acucorrupt [no @mtasurace:stream, locked]
+@c    _IO_wsetg @asucorrupt @acucorrupt [no @mtasurace:stream, locked]
+@c    _IO_wsetp @asucorrupt @acucorrupt [no @mtasurace:stream, locked]
+@c    _IO_setb @asucorrupt @acucorrupt [no @mtasurace:stream, locked]
+@c    _IO_setg @asucorrupt @acucorrupt [no @mtasurace:stream, locked]
+@c    _IO_setp @asucorrupt @acucorrupt [no @mtasurace:stream, locked]
+@c    _IO_un_link dup @asucorrupt @acucorrupt @aculock @acsfd
+@c   _IO_release_lock dup @aculock
+@c    _IO_funlockfile dup @aculock
+@c   _IO_FINISH @ascuheap @ascuplugin @asucorrupt @acucorrupt @aculock @acsfd @acsmem
+@c    _IO_new_file_finish @ascuheap @ascuplugin @asucorrupt @acucorrupt @aculock @acsfd @acsmem
+@c     _IO_file_is_open dup ok
+@c     _IO_do_flush dup @ascuplugin @asucorrupt @acucorrupt
+@c     _IO_SYSCLOSE dup @aculock @acucorrupt @acsfd
+@c     _IO_default_finish @ascuheap @asucorrupt @acucorrupt @aculock @acsfd @acsmem
+@c      FREE_BUF @acsmem
+@c       munmap dup @acsmem
+@c      free dup @ascuheap @acsmem
+@c      _IO_un_link dup @asucorrupt @acucorrupt @aculock @acsfd
+@c      _IO_lock_fini ok
+@c       libc_lock_fini_recursive ok
+@c   libc_lock_lock dup @asulock @aculock
+@c   gconv_release_step ok
+@c   libc_lock_unlock dup @asulock @aculock
+@c   _IO_have_backup ok
+@c   _IO_free_backup_area @ascuheap @asucorrupt @acucorrupt @acsmem
+@c    _IO_in_backup ok
+@c    _IO_switch_to_main_get_area @asucorrupt @acucorrupt
+@c    free dup @ascuheap @acsmem
+@c   free dup @ascuheap @acsmem
 The @code{pclose} function is used to close a stream created by @code{popen}.
 It waits for the child process to terminate and returns its status value,
 as for the @code{system} function.
@@ -168,6 +276,8 @@ The @code{mkfifo} function is declared in the header file
 @comment sys/stat.h
 @comment POSIX.1
 @deftypefun int mkfifo (const char *@var{filename}, mode_t @var{mode})
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+@c On generic Posix, calls xmknod.
 The @code{mkfifo} function makes a FIFO special file with name
 @var{filename}.  The @var{mode} argument is used to set the file's
 permissions; see @ref{Setting Permissions}.

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

commit 81cfcf66bce85163c1b9f17487e98a8828284482
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..9a29b55 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{@prelim{}@mtunsafe{@mtsenv{} @mtslocale{}}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{}}}
+@c fnmatch @mtsenv @mtslocale @ascuheap @acsmem
+@c  strnlen dup ok
+@c  mbsrtowcs
+@c  memset dup ok
+@c  malloc dup @ascuheap @acsmem
+@c  mbsinit dup ok
+@c  free dup @ascuheap @acsmem
+@c  FCT = internal_fnwmatch @mtsenv @mtslocale @ascuheap @acsmem
+@c   FOLD @mtslocale
+@c    towlower @mtslocale
+@c   EXT @mtsenv @mtslocale @ascuheap @acsmem
+@c    STRLEN = wcslen dup ok
+@c    getenv @mtsenv
+@c    malloc dup @ascuheap @acsmem
+@c    MEMPCPY = wmempcpy dup ok
+@c    FCT dup @mtsenv @mtslocale @ascuheap @acsmem
+@c    STRCAT = wcscat dup ok
+@c    free dup @ascuheap @acsmem
+@c   END @mtsenv
+@c    getenv @mtsenv
+@c   MEMCHR = wmemchr dup ok
+@c   getenv @mtsenv
+@c   IS_CHAR_CLASS = is_char_class @mtslocale
+@c    wctype @mtslocale
+@c   BTOWC ok
+@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{@prelim{}@mtunsafe{@mtasurace{} @mtsenv{} @mtasusig{:ALRM} @mtutimer{} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @asucorrupt{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
+@c glob @mturace @mtsenv @mtascusig:ALRM @mtutimer @mtslocale @ascudlopen @ascuplugin @asucorrupt @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c  strlen dup ok
+@c  strchr dup ok
+@c  malloc dup @ascuheap @acsmem
+@c  mempcpy dup ok
+@c  next_brace_sub ok
+@c  free dup @ascuheap @acsmem
+@c  globfree dup @asucorrupt @ascuheap @acucorrupt @acsmem
+@c  glob_pattern_p ok
+@c   glob_pattern_type dup ok
+@c  getenv dup @mtsenv
+@c  GET_LOGIN_NAME_MAX ok
+@c  getlogin_r dup @mturace @mtascusig:ALRM @mtutimer @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c  GETPW_R_SIZE_MAX ok
+@c  getpwnam_r dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c  realloc dup @ascuheap @acsmem
+@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 @ascuheap @acsmem
+@c  glob_pattern_type ok
+@c  glob_in_dir @mtsenv @mtslocale @asucorrupt @ascuheap @acucorrupt @acsfd @acsmem
+@c   strlen dup ok
+@c   glob_pattern_type dup ok
+@c   malloc dup @ascuheap @acsmem
+@c   mempcpy dup ok
+@c   *pglob->gl_stat user-supplied
+@c   stat64 dup ok
+@c   free dup @ascuheap @acsmem
+@c   *pglob->gl_opendir user-supplied
+@c   opendir dup @ascuheap @acsmem @acsfd
+@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 @mtsenv @mtslocale @ascuheap @acsmem
+@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 @ascuheap @acsmem
+@c   pglob->gl_closedir user-supplied
+@c   closedir @ascuheap @acsmem @acsfd
+@c  prefix_array dup @asucorrupt @ascuheap @acucorrupt @acsmem
+@c   strlen dup ok
+@c   malloc dup @ascuheap @acsmem
+@c   free dup @ascuheap @acsmem
+@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{@prelim{}@mtunsafe{@mtasurace{} @mtsenv{} @mtasusig{:ALRM} @mtutimer{} @mtslocale{}}@asunsafe{@ascudlopen{} synconsist, @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
+@c Same code as glob, but with glob64_t #defined as glob_t.
 The @code{glob64} function was added as part of the Large File Summit
 extensions but is not part of the original LFS proposal.  The reason for
 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{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{} @ascuheap{}}@acunsafe{@acucorrupt{} @acsmem{}}}
+@c globfree dup @asucorrupt @ascuheap @acucorrupt @acsmem
+@c  free dup @ascuheap @acsmem
 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{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
 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{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{} @asulock{} @ascudlopen{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{} @acsfd{}}}
+@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 @ascuheap @acsmem
+@c re_compile_internal @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
+@c  (re_)realloc @ascuheap @acsmem (@asucorrupt @acucorrupt for other
+@c    callers that don't zero the buffer)
+@c  init_dfa @mtslocale @asucorrupt @ascuheap sefldeadlock, @ascudlopen @acucorrupt @aculock @acsmem @acsfd
+@c   (re_)malloc @ascuheap @acsmem
+@c   calloc @ascuheap @acsmem
+@c   _NL_CURRENT ok
+@c   _NL_CURRENT_WORD ok
+@c   btowc @asucorrupt @ascuheap sefldeadlock, @ascudlopen @acucorrupt @aculock @acsmem @acsfd
+@c  libc_lock_init ok
+@c  re_string_construct @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
+@c   re_string_construct_common ok
+@c   re_string_realloc_buffers @ascuheap @acsmem
+@c    (re_)realloc dup @ascuheap @acsmem
+@c   build_wcs_upper_buffer @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
+@c    isascii ok
+@c    mbsinit ok
+@c    toupper ok
+@c    mbrtowc dup @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
+@c    iswlower @mtslocale
+@c    towupper @mtslocale
+@c    wcrtomb dup @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
+@c    (re_)malloc dup @ascuheap @acsmem
+@c   build_upper_buffer ok (@mtslocale but optimized)
+@c    islower ok
+@c    toupper ok
+@c   build_wcs_buffer @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
+@c    mbrtowc dup @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
+@c   re_string_translate_buffer ok
+@c  parse (maybe @mtslocale), @asucorrupt @ascuheap sefldeadlock, @ascudlopen @acucorrupt @aculock @acsmem @acsfd
+@c   fetch_token (maybe @mtslocale), @asucorrupt @ascuheap sefldeadlock, @ascudlopen @acucorrupt @aculock @acsmem @acsfd
+@c    peek_token ok (maybe @mtslocale)
+@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 @mtslocale)
+@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 @mtslocale), @asucorrupt @ascuheap sefldeadlock, @ascudlopen @acucorrupt @aculock @acsmem @acsfd
+@c    parse_branch (maybe @mtslocale), @asucorrupt @ascuheap sefldeadlock, @ascudlopen @acucorrupt @aculock @acsmem @acsfd
+@c     parse_expression (maybe @mtslocale), @asucorrupt @ascuheap sefldeadlock, @ascudlopen @acucorrupt @aculock @acsmem @acsfd
+@c      create_token_tree dup @ascuheap @acsmem
+@c      re_string_eoi dup ok
+@c      re_string_first_byte ok
+@c      fetch_token dup (maybe @mtslocale), @asucorrupt @ascuheap sefldeadlock, @ascudlopen @acucorrupt @aculock @acsmem @acsfd
+@c      create_tree dup @ascuheap @acsmem
+@c      parse_sub_exp (maybe @mtslocale), @asucorrupt @ascuheap sefldeadlock, @ascudlopen @acucorrupt @aculock @acsmem @acsfd
+@c       fetch_token dup (maybe @mtslocale), @asucorrupt @ascuheap sefldeadlock, @ascudlopen @acucorrupt @aculock @acsmem @acsfd
+@c       parse_reg_exp dup (maybe @mtslocale), @asucorrupt @ascuheap sefldeadlock, @ascudlopen @acucorrupt @aculock @acsmem @acsfd
+@c       postorder() @ascuheap @acsmem
+@c        free_tree @ascuheap @acsmem
+@c         free_token dup @ascuheap @acsmem
+@c       create_tree dup @ascuheap @acsmem
+@c      parse_bracket_exp (maybe @mtslocale), @asucorrupt @ascuheap sefldeadlock, @ascudlopen @acucorrupt @aculock @acsmem @acsfd
+@c       _NL_CURRENT dup ok
+@c       _NL_CURRENT_WORD dup ok
+@c       calloc dup @ascuheap @acsmem
+@c       (re_)free dup @ascuheap @acsmem
+@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 @mtslocale)
+@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 @mtslocale)
+@c         re_string_eoi dup ok
+@c         re_string_fetch_byte_case ok (maybe @mtslocale)
+@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 @asucorrupt @ascuheap sefldeadlock, @ascudlopen @acucorrupt @aculock @acsmem @acsfd
+@c        auto lookup_collation_sequence_value @asucorrupt @ascuheap sefldeadlock, @ascudlopen @acucorrupt @aculock @acsmem @acsfd
+@c         btowc dup @asucorrupt @ascuheap sefldeadlock, @ascudlopen @acucorrupt @aculock @acsmem @acsfd
+@c         collseq_table_lookup ok
+@c         auto seek_collating_symbol_entry dup ok
+@c        (re_)realloc dup @ascuheap @acsmem
+@c        collseq_table_lookup dup ok
+@c       bitset_set dup ok
+@c       (re_)realloc dup @ascuheap @acsmem
+@c       build_equiv_class (maybe @mtslocale), @ascuheap @acsmem
+@c        _NL_CURRENT ok
+@c        auto findidx ok
+@c        bitset_set dup ok
+@c        (re_)realloc dup @ascuheap @acsmem
+@c       auto build_collating_symbol @ascuheap @acsmem
+@c        auto seek_collating_symbol_entry ok
+@c        bitset_set dup ok
+@c        (re_)realloc dup @ascuheap @acsmem
+@c       build_charclass (maybe @mtslocale), @ascuheap @acsmem
+@c        (re_)realloc dup @ascuheap @acsmem
+@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 @ascuheap @acsmem
+@c       create_tree dup @ascuheap @acsmem
+@c       free_charset dup @ascuheap @acsmem
+@c      init_word_char (maybe @mtslocale)
+@c       isalnum ok
+@c      build_charclass_op (maybe @mtslocale), @ascuheap @acsmem
+@c       calloc dup @ascuheap @acsmem
+@c       build_charclass dup (maybe @mtslocale), @ascuheap @acsmem
+@c       (re_)free dup @ascuheap @acsmem
+@c       free_charset dup @ascuheap @acsmem
+@c       bitset_set dup ok
+@c       bitset_not dup ok
+@c       bitset_mask dup ok
+@c       create_token_tree dup @ascuheap @acsmem
+@c       create_tree dup @ascuheap @acsmem
+@c      parse_dup_op (maybe @mtslocale), @asucorrupt @ascuheap sefldeadlock, @ascudlopen @acucorrupt @aculock @acsmem @acsfd
+@c       re_string_cur_idx dup ok
+@c       fetch_number ok (maybe @mtslocale), @asucorrupt @ascuheap sefldeadlock, @ascudlopen @acucorrupt @aculock @acsmem @acsfd
+@c        fetch_token dup (maybe @mtslocale), @asucorrupt @ascuheap sefldeadlock, @ascudlopen @acucorrupt @aculock @acsmem @acsfd
+@c       re_string_set_index ok
+@c       postorder() @ascuheap @acsmem
+@c        free_tree dup @ascuheap @acsmem
+@c        mark_opt_subexp ok
+@c       duplicate_tree @ascuheap @acsmem
+@c        create_token_tree dup @ascuheap @acsmem
+@c       create_tree dup @ascuheap @acsmem
+@c     postorder() @ascuheap @acsmem
+@c      free_tree dup @ascuheap @acsmem
+@c    fetch_token dup (maybe @mtslocale), @asucorrupt @ascuheap sefldeadlock, @ascudlopen @acucorrupt @aculock @acsmem @acsfd
+@c    parse_branch dup (maybe @mtslocale), @asucorrupt @ascuheap sefldeadlock, @ascudlopen @acucorrupt @aculock @acsmem @acsfd
+@c    create_tree dup @ascuheap @acsmem
+@c   create_tree @ascuheap @acsmem
+@c    create_token_tree @ascuheap @acsmem
+@c     (re_)malloc dup @ascuheap @acsmem
+@c  analyze @ascuheap @acsmem
+@c   (re_)malloc dup @ascuheap @acsmem
+@c   preorder() @ascuheap @acsmem
+@c    optimize_subexps ok
+@c    calc_next ok
+@c    link_nfa_nodes @ascuheap @acsmem
+@c     re_node_set_init_1 @ascuheap @acsmem
+@c      (re_)malloc dup @ascuheap @acsmem
+@c     re_node_set_init_2 @ascuheap @acsmem
+@c      (re_)malloc dup @ascuheap @acsmem
+@c   postorder() @ascuheap @acsmem
+@c    lower_subexps @ascuheap @acsmem
+@c     lower_subexp @ascuheap @acsmem
+@c      create_tree dup @ascuheap @acsmem
+@c    calc_first @ascuheap @acsmem
+@c     re_dfa_add_node @ascuheap @acsmem
+@c      (re_)realloc dup @ascuheap @acsmem
+@c      re_node_set_init_empty ok
+@c   calc_eclosure @ascuheap @acsmem
+@c    calc_eclosure_iter @ascuheap @acsmem
+@c     re_node_set_alloc @ascuheap @acsmem
+@c      (re_)malloc dup @ascuheap @acsmem
+@c     duplicate_node_closure @ascuheap @acsmem
+@c      re_node_set_empty ok
+@c      duplicate_node @ascuheap @acsmem
+@c       re_dfa_add_node dup @ascuheap @acsmem
+@c      re_node_set_insert @ascuheap @acsmem
+@c       (re_)realloc dup @ascuheap @acsmem
+@c      search_duplicated_node ok
+@c     re_node_set_merge @ascuheap @acsmem
+@c      (re_)realloc dup @ascuheap @acsmem
+@c     re_node_set_free @ascuheap @acsmem
+@c      (re_)free dup @ascuheap @acsmem
+@c     re_node_set_insert dup @ascuheap @acsmem
+@c    re_node_set_free dup @ascuheap @acsmem
+@c   calc_inveclosure @ascuheap @acsmem
+@c    re_node_set_init_empty dup ok
+@c    re_node_set_insert_last @ascuheap @acsmem
+@c     (re_)realloc dup @ascuheap @acsmem
+@c  optimize_utf8 ok
+@c  create_initial_state @ascuheap @acsmem
+@c   re_node_set_init_copy @ascuheap @acsmem
+@c    (re_)malloc dup @ascuheap @acsmem
+@c    re_node_set_init_empty dup ok
+@c   re_node_set_contains ok
+@c   re_node_set_merge dup @ascuheap @acsmem
+@c   re_acquire_state_context @ascuheap @acsmem
+@c    calc_state_hash ok
+@c    re_node_set_compare ok
+@c    create_cd_newstate @ascuheap @acsmem
+@c     calloc dup @ascuheap @acsmem
+@c     re_node_set_init_copy dup @ascuheap @acsmem
+@c     (re_)free dup @ascuheap @acsmem
+@c     free_state @ascuheap @acsmem
+@c      re_node_set_free dup @ascuheap @acsmem
+@c      (re_)free dup @ascuheap @acsmem
+@c     NOT_SATISFY_PREV_CONSTRAINT ok
+@c     re_node_set_remove_at ok
+@c     register_state @ascuheap @acsmem
+@c      re_node_set_alloc dup @ascuheap @acsmem
+@c      re_node_set_insert_last dup @ascuheap @acsmem
+@c      (re_)realloc dup @ascuheap @acsmem
+@c   re_node_set_free dup @ascuheap @acsmem
+@c  free_workarea_compile @ascuheap @acsmem
+@c   (re_)free dup @ascuheap @acsmem
+@c  re_string_destruct @ascuheap @acsmem
+@c   (re_)free dup @ascuheap @acsmem
+@c  free_dfa_content @ascuheap @acsmem
+@c   free_token @ascuheap @acsmem
+@c    free_charset @ascuheap @acsmem
+@c     (re_)free dup @ascuheap @acsmem
+@c    (re_)free dup @ascuheap @acsmem
+@c   (re_)free dup @ascuheap @acsmem
+@c   re_node_set_free dup @ascuheap @acsmem
+@c re_compile_fastmap @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
+@c  re_compile_fastmap_iter @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
+@c   re_set_fastmap ok
+@c    tolower ok
+@c   mbrtowc dup @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
+@c   wcrtomb dup @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
+@c   towlower @mtslocale
+@c   _NL_CURRENT ok
+@c (re_)free @ascuheap @acsmem
 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{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{} @asulock{} @ascudlopen{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{} @acsfd{}}}
+@c libc_lock_lock @asulock @aculock
+@c re_search_internal @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
+@c  re_string_allocate @ascuheap @acsmem
+@c   re_string_construct_common dup ok
+@c   re_string_realloc_buffers dup @ascuheap @acsmem
+@c  match_ctx_init @ascuheap @acsmem
+@c   (re_)malloc dup @ascuheap @acsmem
+@c  re_string_byte_at ok
+@c  re_string_first_byte dup ok
+@c  check_matching @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
+@c   re_string_cur_idx dup ok
+@c   acquire_init_state_context dup @ascuheap @acsmem
+@c    re_string_context_at ok
+@c     re_string_byte_at dup ok
+@c     bitset_contain ok
+@c    re_acquire_state_context dup @ascuheap @acsmem
+@c   check_subexp_matching_top @ascuheap @acsmem
+@c    match_ctx_add_subtop @ascuheap @acsmem
+@c     (re_)realloc dup @ascuheap @acsmem
+@c     calloc dup @ascuheap @acsmem
+@c   transit_state_bkref @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
+@c    re_string_cur_idx dup ok
+@c    re_string_context_at dup ok
+@c    NOT_SATISFY_NEXT_CONSTRAINT ok
+@c    get_subexp @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
+@c     re_string_get_buffer ok
+@c     search_cur_bkref_entry ok
+@c     clean_state_log_if_needed @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
+@c      extend_buffers @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
+@c       re_string_realloc_buffers dup @ascuheap @acsmem
+@c       (re_)realloc dup @ascuheap @acsmem
+@c       build_wcs_upper_buffer dup @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
+@c       build_upper_buffer dup ok (@mtslocale but optimized)
+@c       build_wcs_buffer dup @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
+@c       re_string_translate_buffer dup ok
+@c     get_subexp_sub @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
+@c      check_arrival @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
+@c       (re_)realloc dup @ascuheap @acsmem
+@c       re_string_context_at dup ok
+@c       re_node_set_init_1 dup @ascuheap @acsmem
+@c       check_arrival_expand_ecl @ascuheap @acsmem
+@c        re_node_set_alloc dup @ascuheap @acsmem
+@c        find_subexp_node ok
+@c        re_node_set_merge dup @ascuheap @acsmem
+@c        re_node_set_free dup @ascuheap @acsmem
+@c        check_arrival_expand_ecl_sub @ascuheap @acsmem
+@c         re_node_set_contains dup ok
+@c         re_node_set_insert dup @ascuheap @acsmem
+@c       re_node_set_free dup @ascuheap @acsmem
+@c       re_node_set_init_copy dup @ascuheap @acsmem
+@c       re_node_set_init_empty dup ok
+@c       expand_bkref_cache @ascuheap @acsmem
+@c        search_cur_bkref_entry dup ok
+@c        re_node_set_contains dup ok
+@c        re_node_set_init_1 dup @ascuheap @acsmem
+@c        check_arrival_expand_ecl dup @ascuheap @acsmem
+@c        re_node_set_merge dup @ascuheap @acsmem
+@c        re_node_set_init_copy dup @ascuheap @acsmem
+@c        re_node_set_insert dup @ascuheap @acsmem
+@c        re_node_set_free dup @ascuheap @acsmem
+@c        re_acquire_state @ascuheap @acsmem
+@c         calc_state_hash dup ok
+@c         re_node_set_compare dup ok
+@c         create_ci_newstate @ascuheap @acsmem
+@c          calloc dup @ascuheap @acsmem
+@c          re_node_set_init_copy dup @ascuheap @acsmem
+@c          (re_)free dup @ascuheap @acsmem
+@c          register_state dup @ascuheap @acsmem
+@c          free_state dup @ascuheap @acsmem
+@c       re_acquire_state_context dup @ascuheap @acsmem
+@c       re_node_set_merge dup @ascuheap @acsmem
+@c       check_arrival_add_next_nodes @mtslocale @ascuheap @acsmem
+@c        re_node_set_init_empty dup ok
+@c        check_node_accept_bytes @mtslocale @ascuheap @acsmem
+@c         re_string_byte_at dup ok
+@c         re_string_char_size_at dup ok
+@c         re_string_elem_size_at (maybe @mtslocale)
+@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 @mtslocale)
+@c          _NL_CURRENT_WORD dup ok
+@c          _NL_CURRENT dup ok
+@c         auto findidx dup ok
+@c         wcscoll @mtslocale @ascuheap @acsmem
+@c        re_node_set_empty dup ok
+@c        re_node_set_merge dup @ascuheap @acsmem
+@c        re_node_set_free dup @ascuheap @acsmem
+@c        re_node_set_insert dup @ascuheap @acsmem
+@c        re_acquire_state dup @ascuheap @acsmem
+@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 @ascuheap @acsmem
+@c       (re_)realloc dup @ascuheap @acsmem
+@c       (re_)free dup @ascuheap @acsmem
+@c      clean_state_log_if_needed dup @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
+@c     extend_buffers dup @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
+@c     find_subexp_node dup ok
+@c     calloc dup @ascuheap @acsmem
+@c     check_arrival dup ***
+@c     match_ctx_add_sublast @ascuheap @acsmem
+@c      (re_)realloc dup @ascuheap @acsmem
+@c    re_acquire_state_context dup @ascuheap @acsmem
+@c    re_node_set_init_union @ascuheap @acsmem
+@c     (re_)malloc dup @ascuheap @acsmem
+@c     re_node_set_init_copy dup @ascuheap @acsmem
+@c     re_node_set_init_empty dup ok
+@c    re_node_set_free dup @ascuheap @acsmem
+@c    check_subexp_matching_top dup @ascuheap @acsmem
+@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 @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
+@c   transit_state @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
+@c    transit_state_mb @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
+@c     re_string_context_at dup ok
+@c     NOT_SATISFY_NEXT_CONSTRAINT dup ok
+@c     check_node_accept_bytes dup @mtslocale @ascuheap @acsmem
+@c     re_string_cur_idx dup ok
+@c     clean_state_log_if_needed @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
+@c     re_node_set_init_union dup @ascuheap @acsmem
+@c     re_acquire_state_context dup @ascuheap @acsmem
+@c    re_string_fetch_byte dup ok
+@c    re_string_context_at dup ok
+@c    build_trtable @ascuheap @acsmem
+@c     (re_)malloc dup @ascuheap @acsmem
+@c     group_nodes_into_DFAstates @ascuheap @acsmem
+@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 @ascuheap @acsmem
+@c      re_node_set_insert dup @ascuheap @acsmem
+@c      re_node_set_init_1 dup @ascuheap @acsmem
+@c      re_node_set_free dup @ascuheap @acsmem
+@c     re_node_set_alloc dup @ascuheap @acsmem
+@c     malloc dup @ascuheap @acsmem
+@c     free dup @ascuheap @acsmem
+@c     re_node_set_free dup @ascuheap @acsmem
+@c     bitset_empty ok
+@c     re_node_set_empty dup ok
+@c     re_node_set_merge dup @ascuheap @acsmem
+@c     re_acquire_state_context dup @ascuheap @acsmem
+@c     bitset_merge ok
+@c     calloc dup @ascuheap @acsmem
+@c     bitset_contain dup ok
+@c   merge_state_with_log @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
+@c    re_string_cur_idx dup ok
+@c    re_node_set_init_union dup @ascuheap @acsmem
+@c    re_string_context_at dup ok
+@c    re_node_set_free dup @ascuheap @acsmem
+@c    check_subexp_matching_top @ascuheap @acsmem
+@c     match_ctx_add_subtop dup @ascuheap @acsmem
+@c    transit_state_bkref dup @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
+@c   find_recover_state
+@c    re_string_cur_idx dup ok
+@c    re_string_skip_bytes dup ok
+@c    merge_state_with_log dup @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
+@c  check_halt_state_context dup ok
+@c  prune_impossible_nodes @mtslocale @ascuheap @acsmem
+@c   (re_)malloc dup @ascuheap @acsmem
+@c   sift_ctx_init ok
+@c    re_node_set_init_empty dup ok
+@c   sift_states_backward @mtslocale @ascuheap @acsmem
+@c    re_node_set_init_1 dup @ascuheap @acsmem
+@c    update_cur_sifted_state @mtslocale @ascuheap @acsmem
+@c     add_epsilon_src_nodes @ascuheap @acsmem
+@c      re_acquire_state dup @ascuheap @acsmem
+@c      re_node_set_alloc dup @ascuheap @acsmem
+@c      re_node_set_merge dup @ascuheap @acsmem
+@c      re_node_set_add_intersect @ascuheap @acsmem
+@c       (re_)realloc dup @ascuheap @acsmem
+@c     check_subexp_limits @ascuheap @acsmem
+@c      sub_epsilon_src_nodes @ascuheap @acsmem
+@c       re_node_set_init_empty dup ok
+@c       re_node_set_contains dup ok
+@c       re_node_set_add_intersect dup @ascuheap @acsmem
+@c       re_node_set_free dup @ascuheap @acsmem
+@c       re_node_set_remove_at dup ok
+@c      re_node_set_contains dup ok
+@c     re_acquire_state dup @ascuheap @acsmem
+@c     sift_states_bkref @mtslocale @ascuheap @acsmem
+@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 @ascuheap @acsmem
+@c      re_node_set_insert dup @ascuheap @acsmem
+@c      sift_states_backward dup @mtslocale @ascuheap @acsmem
+@c      merge_state_array dup @ascuheap @acsmem
+@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 @ascuheap @acsmem
+@c    re_node_set_free dup @ascuheap @acsmem
+@c    re_node_set_empty dup ok
+@c    build_sifted_states @mtslocale @ascuheap @acsmem
+@c     sift_states_iter_mb @mtslocale @ascuheap @acsmem
+@c      check_node_accept_bytes dup @mtslocale @ascuheap @acsmem
+@c     check_node_accept dup ok
+@c     check_dst_limits dup ok
+@c     re_node_set_insert dup @ascuheap @acsmem
+@c   re_node_set_free dup @ascuheap @acsmem
+@c   check_halt_state_context dup ok
+@c   merge_state_array @ascuheap @acsmem
+@c    re_node_set_init_union dup @ascuheap @acsmem
+@c    re_acquire_state dup @ascuheap @acsmem
+@c    re_node_set_free dup @ascuheap @acsmem
+@c   (re_)free dup @ascuheap @acsmem
+@c  set_regs @ascuheap @acsmem
+@c   (re_)malloc dup @ascuheap @acsmem
+@c   re_node_set_init_empty dup ok
+@c   free_fail_stack_return @ascuheap @acsmem
+@c    re_node_set_free dup @ascuheap @acsmem
+@c    (re_)free dup @ascuheap @acsmem
+@c   update_regs ok
+@c   re_node_set_free dup @ascuheap @acsmem
+@c   pop_fail_stack @ascuheap @acsmem
+@c    re_node_set_free dup @ascuheap @acsmem
+@c    (re_)free dup @ascuheap @acsmem
+@c   (re_)free dup @ascuheap @acsmem
+@c  (re_)free dup @ascuheap @acsmem
+@c  match_ctx_free @ascuheap @acsmem
+@c   match_ctx_clean @ascuheap @acsmem
+@c    (re_)free dup @ascuheap @acsmem
+@c   (re_)free dup @ascuheap @acsmem
+@c  re_string_destruct dup @ascuheap @acsmem
+@c libc_lock_unlock @aculock
 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{@prelim{}@mtsafe{}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{}}}
+@c (re_)free dup @ascuheap @acsmem
+@c free_dfa_content dup @ascuheap @acsmem
 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{@prelim{}@mtunsafe{@mtsenv{}}@asunsafe{@asucorrupt{} @ascuheap{} @asulock{} @ascudlopen{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
+@c regerror calls gettext, strcmp and mempcpy or memcpy.
 This function produces an error message string for the error code
 @var{errcode}, and stores the string in @var{length} bytes of memory
 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{@prelim{}@mtunsafe{@mtasurace{} @mtasuconst{:@mtsenv{}} @mtsenv{} @mtasusig{:ALRM} @mtutimer{} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuintl{} @ascuheap{} @asucorrupt{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
+@c wordexp @mturace @mtasuconst:@mtsenv @mtsenv @mtascusig:ALRM @mtutimer @mtslocale @ascudlopen @ascuplugin @ascuintl @ascuheap @asucorrupt @asulock @acucorrupt @aculock @acsfd @acsmem
+@c  w_newword ok
+@c  wordfree dup @asucorrupt @ascuheap @acucorrupt @acsmem
+@c  calloc dup @ascuheap @acsmem
+@c  getenv dup @mtsenv
+@c  strcpy dup ok
+@c  parse_backslash @ascuheap @acsmem
+@c   w_addchar dup @ascuheap @acsmem
+@c  parse_dollars @mtasuconst:@mtsenv @mtslocale @mtsenv @ascudlopen @ascuplugin @ascuintl @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c   w_addchar dup @ascuheap @acsmem
+@c   parse_arith @mtasuconst:@mtsenv @mtslocale @mtsenv @ascudlopen @ascuplugin @ascuintl @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c    w_newword dup ok
+@c    parse_dollars dup @mtasuconst:@mtsenv @mtslocale @mtsenv @ascudlopen @ascuplugin @ascuintl @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c    parse_backtick dup @ascuplugin @ascuheap @aculock @acsfd @acsmem
+@c    parse_qtd_backslash dup @ascuheap @acsmem
+@c    eval_expr @mtslocale
+@c     eval_expr_multidiv @mtslocale
+@c      eval_expr_val @mtslocale^
+@c       isspace dup @mtslocale^^
+@c       eval_expr dup @mtslocale
+@c      isspace dup @mtslocale^^
+@c     isspace dup @mtslocale^^
+@c    free dup @ascuheap @acsmem
+@c    w_addchar dup @ascuheap @acsmem
+@c    w_addstr dup @ascuheap @acsmem
+@c    itoa_word dup ok
+@c   parse_comm @ascuplugin @ascuheap @aculock @acsfd @acsmem
+@c    w_newword dup ok
+@c    pthread_setcancelstate @ascuplugin @ascuheap @acsmem
+@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 @ascuplugin @ascuheap @acsmem
+@c      THREAD_ATOMIC_BIT_SET dup ok
+@c      pthread_unwind @ascuplugin @ascuheap @acsmem
+@c       Unwind_ForcedUnwind if available @ascuplugin @ascuheap @acsmem
+@c       libc_unwind_longjmp otherwise
+@c       cleanups
+@c    exec_comm @ascuplugin @ascuheap @aculock @acsfd @acsmem
+@c     pipe2 dup ok
+@c     pipe dup ok
+@c     fork dup @ascuplugin @aculock
+@c     close dup @acsfd
+@c     on child: exec_comm_child -> exec or abort
+@c     waitpid dup ok
+@c     read dup ok
+@c     w_addmem dup @ascuheap @acsmem
+@c     strchr dup ok
+@c     w_addword dup @ascuheap @acsmem
+@c     w_newword dup ok
+@c     w_addchar dup @ascuheap @acsmem
+@c     free dup @ascuheap @acsmem
+@c     kill dup ok
+@c    free dup @ascuheap @acsmem
+@c   parse_param @mtasuconst:@mtsenv @mtslocale @mtsenv @ascudlopen @ascuplugin @ascuintl @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c     reads from __libc_argc and __libc_argv without guards
+@c    w_newword dup ok
+@c    isalpha dup @mtslocale^^
+@c    w_addchar dup @ascuheap @acsmem
+@c    isalnum dup @mtslocale^^
+@c    isdigit dup @mtslocale^^
+@c    strchr dup ok
+@c    itoa_word dup ok
+@c    atoi dup @mtslocale
+@c    getpid dup ok
+@c    w_addstr dup @ascuheap @acsmem
+@c    free dup @ascuheap @acsmem
+@c    strlen dup ok
+@c    malloc dup @ascuheap @acsmem
+@c    stpcpy dup ok
+@c    w_addword dup @ascuheap @acsmem
+@c    strdup dup @ascuheap @acsmem
+@c    getenv dup @mtsenv
+@c    parse_dollars dup @mtasuconst:@mtsenv @mtslocale @mtsenv @ascudlopen @ascuplugin @ascuintl @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c    parse_tilde dup @mtslocale @mtsenv @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c    fnmatch dup @mtsenv @mtslocale @ascuheap @acsmem
+@c    mempcpy dup ok
+@c    _ dup @ascuintl
+@c    fxprintf dup @aculock
+@c    setenv dup @mtasuconst:@mtsenv @ascuheap @asulock @acucorrupt @aculock @acsmem
+@c    strspn dup ok
+@c    strcspn dup ok
+@c  parse_backtick @ascuplugin @ascuheap @aculock @acsfd @acsmem
+@c   w_newword dup ok
+@c   exec_comm dup @ascuplugin @ascuheap @aculock @acsfd @acsmem
+@c   free dup @ascuheap @acsmem
+@c   parse_qtd_backslash dup @ascuheap @acsmem
+@c   parse_backslash dup @ascuheap @acsmem
+@c   w_addchar dup @ascuheap @acsmem
+@c  parse_dquote @mtasuconst:@mtsenv @mtslocale @mtsenv @ascudlopen @ascuplugin @ascuintl @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c   parse_dollars dup @mtasuconst:@mtsenv @mtslocale @mtsenv @ascudlopen @ascuplugin @ascuintl @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c   parse_backtick dup @ascuplugin @ascuheap @aculock @acsfd @acsmem
+@c   parse_qtd_backslash dup @ascuheap @acsmem
+@c   w_addchar dup @ascuheap @acsmem
+@c  w_addword dup @ascuheap @acsmem
+@c   strdup dup @ascuheap @acsmem
+@c   realloc dup @ascuheap @acsmem
+@c   free dup @ascuheap @acsmem
+@c  parse_squote dup @ascuheap @acsmem
+@c   w_addchar dup @ascuheap @acsmem
+@c  parse_tilde @mtslocale @mtsenv @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c   strchr dup ok
+@c   w_addchar dup @ascuheap @acsmem
+@c   getenv dup @mtsenv
+@c   w_addstr dup @ascuheap @acsmem
+@c    strlen dup ok
+@c    w_addmem dup @ascuheap @acsmem
+@c     realloc dup @ascuheap @acsmem
+@c     free dup @ascuheap @acsmem
+@c     mempcpy dup ok
+@c   getuid dup ok
+@c   getpwuid_r dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c   getpwnam_r dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c  parse_glob @mturace @mtasuconst:@mtsenv @mtsenv @mtascusig:ALRM @mtutimer @mtslocale @ascudlopen @ascuplugin @ascuintl @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c   strchr dup ok
+@c   parse_dollars dup @mtasuconst:@mtsenv @mtslocale @mtsenv @ascudlopen @ascuplugin @ascuintl @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
+@c   parse_qtd_backslash @ascuheap @acsmem
+@c    w_addchar dup @ascuheap @acsmem
+@c   parse_backslash dup @ascuheap @acsmem
+@c   w_addchar dup @ascuheap @acsmem
+@c   w_addword dup @ascuheap @acsmem
+@c   w_newword dup ok
+@c   do_parse_glob @mturace @mtsenv @mtascusig:ALRM @mtutimer @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @aculock @acsfd @acsmem
+@c    glob dup @mturace @mtsenv @mtascusig:ALRM @mtutimer @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @aculock @acsfd @acsmem [auto glob_t avoids @asucorrupt @acucorrupt]
+@c    w_addstr dup @ascuheap @acsmem
+@c    w_addchar dup @ascuheap @acsmem
+@c    globfree dup @ascuheap @acsmem [auto glob_t avoids @asucorrupt @acucorrupt]
+@c    free dup @ascuheap @acsmem
+@c    w_newword dup ok
+@c    strdup dup @ascuheap @acsmem
+@c    w_addword dup @ascuheap @acsmem
+@c   wordfree dup @asucorrupt @ascuheap @acucorrupt @acsmem
+@c  strchr dup ok
+@c  w_addchar dup @ascuheap @acsmem
+@c   realloc dup @ascuheap @acsmem
+@c   free dup @ascuheap @acsmem
+@c  free dup @ascuheap @acsmem
 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{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{} @ascuheap{}}@acunsafe{@acucorrupt{} @acsmem{}}}
+@c wordfree dup @asucorrupt @ascuheap @acucorrupt @acsmem
+@c  free dup @ascuheap @acsmem
 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=04e49d067509b03f6d78092c11471e13cf073c1f

commit 04e49d067509b03f6d78092c11471e13cf073c1f
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 a11c7d8..bebf527 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{@prelim{}@mtunsafe{@mtasuconst{} @mtsenv{}}@asunsafe{@asuinit{} @asulock{} @ascuheap{} @asucorrupt{}}@acunsafe{@acuinit{} @acucorrupt{} @aculock{} @acsmem{} @acsfd{}}}
+@c Uses of the global locale object are unguarded in functions that
+@c ought to be MT-Safe, so we're ruling out the use of this function
+@c once threads are started.  It takes a write lock itself, but it may
+@c return a pointer loaded from the global locale object after releasing
+@c the lock, or before taking it.
+@c This function returns a pointer read...
+@c setlocale @mtsenv @asuinit @ascuheap @asulock @asucorrupt @acucorrupt @acsmem @acsfd @aculock
+@c  libc_rwlock_wrlock @asulock @aculock
+@c  libc_rwlock_unlock @aculock
+@c  getenv LOCPATH @mtsenv
+@c  malloc @ascuheap @acsmem
+@c  free @ascuheap @acsmem
+@c  new_composite_name ok
+@c  setdata ok
+@c  setname ok
+@c  _nl_find_locale @mtsenv @asuinit @ascuheap @asulock @asucorrupt @acucorrupt @acsmem @acsfd @aculock
+@c   getenv LC_ALL and LANG @mtsenv
+@c   _nl_load_locale_from_archive @ascuheap @acucorrupt @acsmem @acsfd
+@c    sysconf _SC_PAGE_SIZE ok
+@c    _nl_normalize_codeset @ascuheap @acsmem
+@c     isalnum_l ok (C locale)
+@c     isdigit_l ok (C locale)
+@c     malloc @ascuheap @acsmem
+@c     tolower_l ok (C locale)
+@c    open_not_cancel_2 @acsfd
+@c    fxstat64 ok
+@c    close_not_cancel_no_status ok
+@c    __mmap64 @acsmem
+@c    calculate_head_size ok
+@c    __munmap ok
+@c    compute_hashval ok
+@c    qsort dup @acucorrupt
+@c     rangecmp ok
+@c    malloc @ascuheap @acsmem
+@c    strdup @ascuheap @acsmem
+@c    _nl_intern_locale_data @ascuheap @acsmem
+@c     malloc @ascuheap @acsmem
+@c     free @ascuheap @acsmem
+@c   _nl_expand_alias @ascuheap @asulock @acsmem @acsfd @aculock
+@c    libc_lock_lock @asulock @aculock
+@c    bsearch ok
+@c     alias_compare ok
+@c      strcasecmp ok
+@c    read_alias_file @ascuheap @asulock @acsmem @acsfd @aculock
+@c     fopen @ascuheap @asulock @acsmem @acsfd @aculock
+@c     fsetlocking ok
+@c     feof_unlocked ok
+@c     fgets_unlocked ok
+@c     isspace ok (locale mutex is locked)
+@c     extend_alias_table @acsmem @ascuheap
+@c      realloc @acsmem @ascuheap
+@c     realloc @acsmem @ascuheap
+@c     fclose @ascuheap @asulock @acsmem @acsfd @aculock
+@c     qsort @ascuheap @acsmem
+@c      alias_compare dup
+@c    libc_lock_unlock @aculock
+@c   _nl_explode_name @ascuheap @acsmem
+@c    _nl_find_language ok
+@c    _nl_normalize_codeset dup @ascuheap @acsmem
+@c   _nl_make_l10nflist @ascuheap @acsmem
+@c    malloc @ascuheap @acsmem
+@c    free @ascuheap @acsmem
+@c    __argz_stringify ok
+@c    __argz_count ok
+@c    __argz_next ok
+@c   _nl_load_locale @ascuheap @acsmem @acsfd
+@c    open_not_cancel_2 @acsfd
+@c    __fxstat64 ok
+@c    close_not_cancel_no_status ok
+@c    mmap @acsmem
+@c    malloc @ascuheap @acsmem
+@c    read_not_cancel ok
+@c    free @ascuheap @acsmem
+@c    _nl_intern_locale_data dup @ascuheap @acsmem
+@c    munmap ok
+@c   __gconv_compare_alias @asuinit @ascuheap @asucorrupt @asulock @acsmem@acucorrupt @acsfd @aculock
+@c    __gconv_read_conf @asuinit @ascuheap @asucorrupt @asulock @acsmem@acucorrupt @acsfd @aculock
+@c     (libc_once-initializes gconv_cache and gconv_path_envvar; they're
+@c      never modified afterwards)
+@c     __gconv_load_cache @ascuheap @acsmem @acsfd
+@c      getenv GCONV_PATH @mtsenv
+@c      open_not_cancel @acsfd
+@c      __fxstat64 ok
+@c      close_not_cancel_no_status ok
+@c      mmap @acsmem
+@c      malloc @ascuheap @acsmem
+@c      __read ok
+@c      free @ascuheap @acsmem
+@c      munmap ok
+@c     __gconv_get_path @asulock @ascuheap @aculock @acsmem @acsfd
+@c      getcwd @ascuheap @acsmem @acsfd
+@c      libc_lock_lock @asulock @aculock
+@c      malloc @ascuheap @acsmem
+@c      strtok_r ok
+@c      libc_lock_unlock @aculock
+@c     read_conf_file @ascuheap @asucorrupt @asulock @acsmem @acucorrupt @acsfd @aculock
+@c      fopen @ascuheap @asulock @acsmem @acsfd @aculock
+@c      fsetlocking ok
+@c      feof_unlocked ok
+@c      getdelim @ascuheap @asucorrupt @acsmem @acucorrupt
+@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 @ascuheap @acucorrupt @acsmem
+@c      add_module @ascuheap @acsmem
+@c       isspace_l ok (C locale)
+@c       toupper_l ok (C locale)
+@c       strtol ok (@mtslocale but we hold the locale lock)
+@c       tfind __gconv_alias_db ok
+@c        __gconv_alias_compare dup ok
+@c       calloc @ascuheap @acsmem
+@c       insert_module dup @ascuheap
+@c     __tfind ok (because the tree is read only by then)
+@c      __gconv_alias_compare dup ok
+@c     insert_module @ascuheap
+@c      free @ascuheap
+@c     add_alias2 @ascuheap @acucorrupt @acsmem
+@c      detect_conflict ok, reads __gconv_modules_db
+@c      malloc @ascuheap @acsmem
+@c      tsearch __gconv_alias_db @ascuheap @acucorrupt @acsmem [exclusive tree, no @mtsrace]
+@c       __gconv_alias_compare ok
+@c      free @ascuheap
+@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 @ascuheap @acsmem
+@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{@prelim{}@mtunsafe{@mtasurace{} @mtslocale{}}@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{@prelim{}@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 @mtslocale 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{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@ascuheap{}}@acsafe{@acsmem{}}}
+@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 (@mtslocale @ascuheap @acsmem) 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{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{} @asulock{} @ascudlopen{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{} @acsfd{}}}
+@c Calls nl_langinfo with YESEXPR and NOEXPR, triggering @mtslocale 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=c2c08bcb1a23fbc643b1901765c27e874c222233

commit c2c08bcb1a23fbc643b1901765c27e874c222233
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 916edbd..ab40e55 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{@prelim{}@mtsafe{}@assafe{}@acsafe{@acsfd{}}}
 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{@prelim{}@mtsafe{}@assafe{}@acsafe{@acsfd{}}}
 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{@prelim{}@mtsafe{}@assafe{}@acsafe{@acsfd{}}}
 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{@prelim{}@mtsafe{}@assafe{}@acsafe{@acsfd{}}}
 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{@prelim{}@mtsafe{}@assafe{}@acsafe{@acsfd{}}}
 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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@mtsafe{}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@acsmem{} @aculock{}}}
 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{@prelim{}@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{@prelim{}@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{@prelim{}@mtsafe{}@assafe{@ascuheap{}}@acsafe{@acsmem{}}}
+@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{@prelim{}@mtsafe{}@assafe{@ascuheap{}}@acsafe{@acsmem{}}}
+@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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}
@@ -1474,6 +1520,24 @@ There is no existing mapping in at least part of the given region.
 @comment sys/mman.h
 @comment POSIX
 @deftypefn Function int shm_open (const char *@var{name}, int @var{oflag}, mode_t @var{mode})
+@safety{@prelim{}@mtsafe{@mtslocale}@asunsafe{@asuinit{} @ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsmem{} @acsfd{}}}
+@c shm_open @mtslocale @asuinit @ascuheap @asulock @aculock @acsmem @acsfd
+@c  libc_once(where_is_shmfs) @mtslocale @asuinit @ascuheap @asulock @aculock @acsmem @acsfd
+@c   where_is_shmfs @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
+@c    statfs dup ok
+@c    setmntent dup @ascuheap @asulock @acsmem @acsfd @aculock
+@c    getmntent_r dup @mtslocale @ascuheap @aculock @acsmem [no @asucorrupt @acucorrupt; exclusive stream]
+@c    strcmp dup ok
+@c    strlen dup ok
+@c    malloc dup @ascuheap @acsmem
+@c    mempcpy dup ok
+@c    endmntent dup @ascuheap @asulock @aculock @acsmem @acsfd
+@c  strlen dup ok
+@c  strchr dup ok
+@c  mempcpy dup ok
+@c  open dup @acsfd
+@c  fcntl dup ok
+@c  close dup @acsfd
 
 This function returns a file descriptor that can be used to allocate shared
 memory via mmap. Unrelated processes can use same @var{name} to create or
@@ -1490,6 +1554,13 @@ On failure @code{errno} is set.
 @end deftypefn
 
 @deftypefn Function int shm_unlink (const char *@var{name})
+@safety{@prelim{}@mtsafe{@mtslocale}@asunsafe{@asuinit{} @ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsmem{} @acsfd{}}}
+@c shm_unlink @mtslocale @asuinit @ascuheap @asulock @aculock @acsmem @acsfd
+@c  libc_once(where_is_shmfs) dup @mtslocale @asuinit @ascuheap @asulock @aculock @acsmem @acsfd
+@c  strlen dup ok
+@c  strchr dup ok
+@c  mempcpy dup ok
+@c  unlink dup ok
 
 This function is inverse of @code{shm_open} and removes the object with
 the given @var{name} previously created by @code{shm_open}.
@@ -1558,6 +1629,7 @@ that descriptor into an @code{fd_set}.
 @comment sys/types.h
 @comment BSD
 @deftypefn Macro void FD_ZERO (fd_set *@var{set})
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
 This macro initializes the file descriptor set @var{set} to be the
 empty set.
 @end deftypefn
@@ -1565,6 +1637,9 @@ empty set.
 @comment sys/types.h
 @comment BSD
 @deftypefn Macro void FD_SET (int @var{filedes}, fd_set *@var{set})
+@safety{@prelim{}@mtsafe{@mtsrace{}}@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
@@ -1574,6 +1649,9 @@ evaluated more than once.
 @comment sys/types.h
 @comment BSD
 @deftypefn Macro void FD_CLR (int @var{filedes}, fd_set *@var{set})
+@safety{@prelim{}@mtsafe{@mtsrace{}}@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
@@ -1583,6 +1661,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{@prelim{}@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.
 
@@ -1595,6 +1674,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{@prelim{}@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.
@@ -1697,6 +1780,7 @@ they return.
 @comment unistd.h
 @comment X/Open
 @deftypefun void sync (void)
+@safety{@prelim{}@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
@@ -1712,6 +1796,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{@prelim{}@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
@@ -1749,6 +1834,7 @@ recovering of the file in case of a problem.
 @comment unistd.h
 @comment POSIX
 @deftypefun int fdatasync (int @var{fildes})
+@safety{@prelim{}@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.
@@ -1950,6 +2036,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{@prelim{}@mtsafe{}@asunsafe{@asulock{} @ascuheap{}}@acunsafe{@aculock{} @acsmem{}}}
+@c Calls aio_enqueue_request.
+@c aio_enqueue_request @asulock @ascuheap @aculock @acsmem
+@c  pthread_self ok
+@c  pthread_getschedparam @asulock @aculock
+@c   lll_lock (pthread descriptor's lock) @asulock @aculock
+@c   sched_getparam ok
+@c   sched_getscheduler ok
+@c   lll_unlock @aculock
+@c  pthread_mutex_lock (aio_requests_mutex) @asulock @aculock
+@c  get_elem @ascuheap @acsmem [@asucorrupt @acucorrupt], [@mtsrace]
+@c   realloc @ascuheap @acsmem
+@c   calloc @ascuheap @acsmem
+@c  aio_create_helper_thread @asulock @ascuheap @aculock @acsmem
+@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 [@mtsrace but the caller's sigset is automatic]
+@c   SYSCALL rt_sigprocmask ok
+@c   pthread_create @asulock @ascuheap @aculock @acsmem
+@c    lll_lock (default_pthread_attr_lock) @asulock @aculock
+@c    alloca/malloc @ascuheap @acsmem
+@c    lll_unlock @aculock
+@c    allocate_stack @asulock @ascuheap @aculock @acsmem
+@c     getpagesize dup
+@c     lll_lock (default_pthread_attr_lock) @asulock @aculock
+@c     lll_unlock @aculock
+@c     _dl_allocate_tls @ascuheap @acsmem
+@c      _dl_allocate_tls_storage @ascuheap @acsmem
+@c       memalign @ascuheap @acsmem
+@c       memset ok
+@c       allocate_dtv dup
+@c       free @ascuheap @acsmem
+@c      allocate_dtv @ascuheap @acsmem
+@c       calloc @ascuheap @acsmem
+@c       INSTALL_DTV ok
+@c     list_add dup
+@c     get_cached_stack
+@c      lll_lock (stack_cache_lock) @asulock @aculock
+@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 @aculock
+@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 @asulock @ascuheap @aculock @acsmem
+@c     lll_lock (state_cache_lock) @asulock @aculock
+@c     stack_list_del ok
+@c      atomic_write_barrier ok
+@c      list_del ok [@mtuconst]
+@c      atomic_write_barrier ok
+@c     queue_stack @ascuheap @acsmem
+@c      stack_list_add ok
+@c       atomic_write_barrier ok
+@c       list_add ok [@mtuconst]
+@c       atomic_write_barrier ok
+@c      free_stacks @ascuheap @acsmem
+@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 @ascuheap @acsmem
+@c      free @ascuheap @acsmem
+@c     lll_unlock @aculock
+@c    create_thread @asulock @ascuheap @aculock @acsmem
+@c     td_eventword
+@c     td_eventmask
+@c     do_clone @asulock @ascuheap @aculock @acsmem
+@c      PREPARE_CREATE ok
+@c      lll_lock (pd->lock) @asulock @aculock
+@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) @aculock
+@c    free @ascuheap @acsmem
+@c   pthread_attr_destroy ok (cpuset won't be set, so free isn't called)
+@c  add_request_to_runlist ok [@mtsrace]
+@c  pthread_cond_signal ok
+@c  aio_free_request ok [@mtsrace]
+@c  pthread_mutex_unlock @aculock
+
+@c (in the new thread, initiated with clone)
+@c    start_thread ok
+@c     HP_TIMING_NOW ok
+@c     ctype_init [@mtslocale] (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 [@ascuheap @acsmem?]
+@c     lll_lock @asulock @aculock
+@c     lll_unlock @asulock @aculock
+@c     CANCEL_RESET -> pthread_disable_asynccancel ok
+@c      lll_futex_wait ok
+@c     ->start_routine ok -----
+@c     call_tls_dtors @asulock @ascuheap @aculock @acsmem
+@c      user-supplied dtor
+@c      rtld_lock_lock_recursive (dl_load_lock) @asulock @aculock
+@c      rtld_lock_unlock_recursive @aculock
+@c      free @ascuheap @acsmem
+@c     nptl_deallocate_tsd @ascuheap @acsmem
+@c      tsd user-supplied dtors ok
+@c      free @ascuheap @acsmem
+@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 @asulock @ascuheap @aculock @acsmem
+@c      free @ascuheap @acsmem
+@c      deallocate_stack @asulock @ascuheap @aculock @acsmem
+@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.
@@ -2015,6 +2253,7 @@ replaces the normal implementation.
 @comment aio.h
 @comment Unix98
 @deftypefun int aio_read64 (struct aiocb64 *@var{aiocbp})
+@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{} @ascuheap{}}@acunsafe{@aculock{} @acsmem{}}}
 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
@@ -2033,6 +2272,7 @@ of functions with a very similar interface.
 @comment aio.h
 @comment POSIX.1b
 @deftypefun int aio_write (struct aiocb *@var{aiocbp})
+@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{} @ascuheap{}}@acunsafe{@aculock{} @acsmem{}}}
 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.
@@ -2099,6 +2339,7 @@ replaces the normal implementation.
 @comment aio.h
 @comment Unix98
 @deftypefun int aio_write64 (struct aiocb64 *@var{aiocbp})
+@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{} @ascuheap{}}@acunsafe{@aculock{} @acsmem{}}}
 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
@@ -2120,6 +2361,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{@prelim{}@mtsafe{}@asunsafe{@asulock{} @ascuheap{}}@acunsafe{@aculock{} @acsmem{}}}
+@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
@@ -2203,6 +2450,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{@prelim{}@mtsafe{}@asunsafe{@asulock{} @ascuheap{}}@acunsafe{@aculock{} @acsmem{}}}
 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
@@ -2231,6 +2479,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{@prelim{}@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
@@ -2252,6 +2501,7 @@ transparently replaces the normal implementation.
 @comment aio.h
 @comment Unix98
 @deftypefun int aio_error64 (const struct aiocb64 *@var{aiocbp})
+@safety{@prelim{}@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}.
@@ -2265,6 +2515,7 @@ machines.
 @comment aio.h
 @comment POSIX.1b
 @deftypefun ssize_t aio_return (struct aiocb *@var{aiocbp})
+@safety{@prelim{}@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
@@ -2288,6 +2539,7 @@ transparently replaces the normal implementation.
 @comment aio.h
 @comment Unix98
 @deftypefun ssize_t aio_return64 (struct aiocb64 *@var{aiocbp})
+@safety{@prelim{}@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}.
@@ -2316,6 +2568,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{@prelim{}@mtsafe{}@asunsafe{@asulock{} @ascuheap{}}@acunsafe{@aculock{} @acsmem{}}}
+@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
@@ -2363,6 +2618,7 @@ transparently replaces the normal implementation.
 @comment aio.h
 @comment Unix98
 @deftypefun int aio_fsync64 (int @var{op}, struct aiocb64 *@var{aiocbp})
+@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{} @ascuheap{}}@acunsafe{@aculock{} @acsmem{}}}
 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}.
@@ -2389,6 +2645,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{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{}}}
+@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
@@ -2427,6 +2686,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{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{}}}
 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}.
@@ -2454,6 +2714,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{@prelim{}@mtsafe{}@asunsafe{@asulock{} @ascuheap{}}@acunsafe{@aculock{} @acsmem{}}}
+@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
@@ -2501,6 +2771,7 @@ transparently replaces the normal implementation.
 @comment aio.h
 @comment Unix98
 @deftypefun int aio_cancel64 (int @var{fildes}, struct aiocb64 *@var{aiocbp})
+@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{} @ascuheap{}}@acunsafe{@aculock{} @acsmem{}}}
 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}.
@@ -2556,6 +2827,8 @@ Unused.
 @comment aio.h
 @comment GNU
 @deftypefun void aio_init (const struct aioinit *@var{init})
+@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{}}}
+@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.
@@ -2590,6 +2863,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{@prelim{}@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
@@ -2672,6 +2946,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{@prelim{}@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)}.
@@ -2680,6 +2955,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{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
 This function copies the descriptor @var{old} to descriptor number
 @var{new}.
 
@@ -3658,6 +3934,7 @@ different headers.
 @comment sys/ioctl.h
 @comment BSD
 @deftypefun int ioctl (int @var{filedes}, int @var{command}, @dots{})
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
 
 The @code{ioctl} function performs the generic I/O operation
 @var{command} on @var{filedes}.
@@ -3677,3 +3954,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=7ebbd77a5df178eb4066497ddd9e250c6cf4b4a6

commit 7ebbd77a5df178eb4066497ddd9e250c6cf4b4a6
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 7a55673..c19fbe1 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{@prelim{}@mtsafe{}@asunsafe{@ascuheap{} @asucorrupt{}}@acsafe{@acsmem{} @aculock{} @acucorrupt{}}}
+@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{@prelim{}@mtsafe{}@asunsafe{@ascuheap{} @asucorrupt{}}@acsafe{@acsmem{} @aculock{} @acucorrupt{}}}
+@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+@c This is no longer provided by glibc, but rather by the compiler.
 This expands to an 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=63d2d11a23136752672a4b2a85aec9ac389fe107

commit 63d2d11a23136752672a4b2a85aec9ac389fe107
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 d58dcd8..a303741 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{@prelim{}@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{@prelim{}@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{@prelim{}@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
@@ -1121,6 +1133,7 @@ from the calling process.
 @comment unistd.h
 @comment POSIX.1
 @deftypefun pid_t getpgrp (void)
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
 The @code{getpgrp} function returns the process group ID of
 the calling process.
 @end deftypefun
@@ -1128,7 +1141,8 @@ the calling process.
 @comment unistd.h
 @comment POSIX.1
 @deftypefun int getpgid (pid_t @var{pid})
-
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+@c Stub or direct syscall, except on hurd, where it is equally safe.
 The @code{getpgid} function
 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
@@ -1150,6 +1164,8 @@ process.
 @comment unistd.h
 @comment POSIX.1
 @deftypefun int setpgid (pid_t @var{pid}, pid_t @var{pgid})
+@safety{@prelim{}@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.
@@ -1187,6 +1203,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{@prelim{}@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
@@ -1209,6 +1227,8 @@ file itself and not a particular open file descriptor.
 @comment unistd.h
 @comment POSIX.1
 @deftypefun pid_t tcgetpgrp (int @var{filedes})
+@safety{@prelim{}@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}.
 
@@ -1237,6 +1257,8 @@ controlling terminal of the calling process.
 @comment unistd.h
 @comment POSIX.1
 @deftypefun int tcsetpgrp (int @var{filedes}, pid_t @var{pgid})
+@safety{@prelim{}@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
@@ -1276,6 +1298,8 @@ process.
 @comment termios.h
 @comment Unix98
 @deftypefun pid_t tcgetsid (int @var{fildes})
+@safety{@prelim{}@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=e1aeb0e5b95b08b74b8736556af6810651b8d781

commit e1aeb0e5b95b08b74b8736556af6810651b8d781
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 804da10..3d22900 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{@prelim{}@mtunsafe{@mtsenv{}}@asunsafe{@asulock{}}@acunsafe{@aculock{} @acsfd{} @acsmem{}}}
+@c catopen @mtsenv @asulock @aculock @acsfd @acsmem
+@c  strchr ok
+@c  setlocale(,NULL) ok
+@c  getenv @mtsenv
+@c  strlen ok
+@c  alloca ok
+@c  stpcpy ok
+@c  malloc @asulock @aculock @acsfd @acsmem
+@c  __open_catalog @asulock @aculock @acsfd @acsmem
+@c   strchr ok
+@c   open_not_cancel_2 @acsfd
+@c   strlen ok
+@c   ENOUGH ok
+@c    alloca ok
+@c    memcpy ok
+@c   fxstat64 ok
+@c   __set_errno ok
+@c   mmap @acsmem
+@c   malloc dup @asulock @aculock @acsfd @acsmem
+@c   read_not_cancel ok
+@c   free dup @asulock @aculock @acsfd @acsmem
+@c   munmap ok
+@c   close_not_cancel_no_status ok
+@c  free @asulock @aculock @acsfd @acsmem
+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{@prelim{}@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{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
+@c catclose @asulock @acucorrupt @aculock @acsfd @acsmem
+@c  __set_errno ok
+@c  munmap ok
+@c  free @asulock @aculock @acsfd @acsmem
 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{@prelim{}@mtunsafe{@mtsenv{}}@asunsafe{@asucorrupt{} @ascuheap{} @asulock{} @ascudlopen{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
+@c Wrapper for dcgettext.
 The @code{gettext} function searches the currently selected message
 catalogs for a string which is equal to @var{msgid}.  If there is such a
 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{@prelim{}@mtunsafe{@mtsenv{}}@asunsafe{@asucorrupt{} @ascuheap{} @asulock{} @ascudlopen{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
+@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{@prelim{}@mtunsafe{@mtsenv{}}@asunsafe{@asucorrupt{} @ascuheap{} @asulock{} @ascudlopen{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
+@c dcgettext @mtsenv @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsfd @acsmem
+@c  dcigettext @mtsenv @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsfd @acsmem
+@c   libc_rwlock_rdlock @asulock @aculock
+@c   current_locale_name ok [protected from @mtslocale]
+@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 @ascuheap @acsmem @acsfd
+@c   strchr ok
+@c   stpcpy ok
+@c   category_to_name ok
+@c   guess_category_value @mtsenv
+@c    getenv @mtsenv
+@c    current_locale_name dup ok [protected from @mtslocale by dcigettext]
+@c    strcmp ok
+@c   ENABLE_SECURE ok
+@c   _nl_find_domain @mtsenv @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsfd @acsmem
+@c    libc_rwlock_rdlock dup @asulock @aculock
+@c    _nl_make_l10nflist dup @ascuheap @acsmem
+@c    libc_rwlock_unlock dup ok
+@c    _nl_load_domain @mtsenv @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsfd @acsmem
+@c     libc_lock_lock_recursive @aculock
+@c     libc_lock_unlock_recursive @aculock
+@c     open->open_not_cancel_2 @acsfd
+@c     fstat ok
+@c     mmap dup @acsmem
+@c     close->close_not_cancel_no_status @acsfd
+@c     malloc dup @asulock @aculock @acsfd @acsmem
+@c     read->read_not_cancel ok
+@c     munmap dup @acsmem
+@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 @asulock @aculock @acsfd @acsmem
+@c     libc_rwlock_init ok
+@c     _nl_find_msg dup @mtsenv @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsfd @acsmem
+@c     libc_rwlock_fini ok
+@c     EXTRACT_PLURAL_EXPRESSION @asulock @aculock @acsfd @acsmem
+@c      strstr dup ok
+@c      isspace ok [protected from @mtslocale by dcigettext]
+@c      strtoul ok [protected from @mtslocale by dcigettext]
+@c      PLURAL_PARSE @asulock @aculock @acsfd @acsmem
+@c       malloc dup @asulock @aculock @acsfd @acsmem
+@c       free dup @asulock @aculock @acsfd @acsmem
+@c      INIT_GERMANIC_PLURAL ok, nothing
+@c       (pre-C99 variant is @acucorrupt [protected from @mtuinit by dcigettext])
+@c    _nl_expand_alias dup @ascuheap @asulock @acsmem @acsfd @aculock
+@c    _nl_explode_name dup @ascuheap @acsmem
+@c    libc_rwlock_wrlock dup @asulock @aculock
+@c    free dup @asulock @aculock @acsfd @acsmem
+@c   _nl_find_msg @mtsenv @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsfd @acsmem
+@c    _nl_load_domain dup @mtsenv @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsfd @acsmem
+@c    strlen ok
+@c    hash_string ok
+@c    W ok
+@c     SWAP ok
+@c      bswap_32 ok
+@c    strcmp ok
+@c    get_output_charset @mtsenv @asulock @aculock @acsfd @acsmem
+@c     getenv dup @mtsenv
+@c     strlen dup ok
+@c     malloc dup @asulock @aculock @acsfd @acsmem
+@c     memcpy dup ok
+@c    libc_rwlock_rdlock dup @asulock @aculock
+@c    libc_rwlock_unlock dup ok
+@c    libc_rwlock_wrlock dup @asulock @aculock
+@c    realloc @asulock @aculock @acsfd @acsmem
+@c    strdup @asulock @aculock @acsfd @acsmem
+@c    strstr ok
+@c    strcspn ok
+@c    mempcpy dup ok
+@c    norm_add_slashes dup ok
+@c    gconv_open @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd
+@c     [protected from @mtslocale by dcigettext locale lock]
+@c    free dup @asulock @aculock @acsfd @acsmem
+@c    libc_lock_lock @asulock @aculock
+@c    calloc @asulock @aculock @acsfd @acsmem
+@c    gconv dup @acucorrupt [protected from @mtsrace and @asucorrupt by lock]
+@c    libc_lock_unlock ok
+@c   malloc @asulock @aculock @acsfd @acsmem
+@c   mempcpy ok
+@c   memcpy ok
+@c   strcpy ok
+@c   libc_rwlock_wrlock @asulock @aculock
+@c   tsearch @ascuheap @acucorrupt @acsmem [protected from @mtsrace and @asucorrupt]
+@c    transcmp ok
+@c     strmp dup ok
+@c   free @asulock @aculock @acsfd @acsmem
 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{@prelim{}@mtsafe{}@asunsafe{@asulock{} @ascuheap{}}@acunsafe{@aculock{} @acsmem{}}}
+@c textdomain @asulock @ascuheap @aculock @acsmem
+@c  libc_rwlock_wrlock @asulock @aculock
+@c  strcmp ok
+@c  strdup @ascuheap @acsmem
+@c  free @acsmem
+@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{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{} @acsfd{} @acsmem{}}}
+@c bindtextdomain @asulock @aculock @acsfd @acsmem
+@c  set_binding_values @asulock @aculock @acsfd @acsmem
+@c   libc_rwlock_wrlock dup @asulock @aculock
+@c   strcmp dup ok
+@c   strdup dup @asulock @aculock @acsfd @acsmem
+@c   free dup @asulock @aculock @acsfd @acsmem
+@c   malloc dup @asulock @aculock @acsfd @acsmem
 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{@prelim{}@mtunsafe{@mtsenv{}}@asunsafe{@asucorrupt{} @ascuheap{} @asulock{} @ascudlopen{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
+@c Wrapper for dcngettext.
 The @code{ngettext} function is similar to the @code{gettext} function
 as it finds the message catalogs in the same way.  But it takes two
 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{@prelim{}@mtunsafe{@mtsenv{}}@asunsafe{@asucorrupt{} @ascuheap{} @asulock{} @ascudlopen{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
+@c Wrapper for dcngettext.
 The @code{dngettext} is similar to the @code{dgettext} function in the
 way the message catalog is selected.  The difference is that it takes
 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{@prelim{}@mtunsafe{@mtsenv{}}@asunsafe{@asucorrupt{} @ascuheap{} @asulock{} @ascudlopen{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
+@c Wrapper for dcigettext.
 The @code{dcngettext} is similar to the @code{dcgettext} function in the
 way the message catalog is selected.  The difference is that it takes
 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{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{} @acsfd{} @acsmem{}}}
+@c bind_textdomain_codeset @asulock @aculock @acsfd @acsmem
+@c  set_binding_values dup @asulock @aculock @acsfd @acsmem
 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=31638059a8c129e82a28a0a6eaf844cbc73cf6cc

commit 31638059a8c129e82a28a0a6eaf844cbc73cf6cc
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
    
    	[BZ #12751]
    	* manual/memory.texi: Document MTASC-safety properties.

diff --git a/NEWS b/NEWS
index b20097c..1bb1d1f 100644
--- a/NEWS
+++ b/NEWS
@@ -10,21 +10,21 @@ Version 2.19
 * The following bugs are resolved with this release:
 
   156, 387, 431, 832, 926, 2801, 4772, 6786, 6787, 6807, 6810, 7003, 9954,
-  10253, 10278, 11087, 11157, 11214, 12100, 12486, 12986, 13028, 13982,
-  13985, 14029, 14032, 14120, 14143, 14155, 14547, 14699, 14752, 14876,
-  14910, 15004, 15048, 15073, 15089, 15128, 15218, 15268, 15277, 15308,
-  15362, 15374, 15400, 15425, 15427, 15483, 15522, 15531, 15532, 15593,
-  15601, 15608, 15609, 15610, 15632, 15640, 15670, 15672, 15680, 15681,
-  15723, 15734, 15735, 15736, 15748, 15749, 15754, 15760, 15763, 15764,
-  15797, 15799, 15825, 15843, 15844, 15846, 15847, 15849, 15855, 15856,
-  15857, 15859, 15867, 15886, 15887, 15890, 15892, 15893, 15895, 15897,
-  15901, 15905, 15909, 15915, 15917, 15919, 15921, 15923, 15939, 15941,
-  15948, 15963, 15966, 15985, 15988, 15997, 16032, 16034, 16036, 16037,
-  16038, 16041, 16055, 16071, 16072, 16074, 16077, 16078, 16103, 16112,
-  16143, 16144, 16146, 16150, 16151, 16153, 16167, 16172, 16195, 16214,
-  16245, 16271, 16274, 16283, 16289, 16293, 16314, 16316, 16330, 16337,
-  16338, 16356, 16365, 16366, 16369, 16372, 16375, 16379, 16384, 16385,
-  16386, 16390.
+  10253, 10278, 11087, 11157, 11214, 12100, 12486, 12751, 12986, 13028,
+  13982, 13985, 14029, 14032, 14120, 14143, 14155, 14547, 14699, 14752,
+  14876, 14910, 15004, 15048, 15073, 15089, 15128, 15218, 15268, 15277,
+  15308, 15362, 15374, 15400, 15425, 15427, 15483, 15522, 15531, 15532,
+  15593, 15601, 15608, 15609, 15610, 15632, 15640, 15670, 15672, 15680,
+  15681, 15723, 15734, 15735, 15736, 15748, 15749, 15754, 15760, 15763,
+  15764, 15797, 15799, 15825, 15843, 15844, 15846, 15847, 15849, 15855,
+  15856, 15857, 15859, 15867, 15886, 15887, 15890, 15892, 15893, 15895,
+  15897, 15901, 15905, 15909, 15915, 15917, 15919, 15921, 15923, 15939,
+  15941, 15948, 15963, 15966, 15985, 15988, 15997, 16032, 16034, 16036,
+  16037, 16038, 16041, 16055, 16071, 16072, 16074, 16077, 16078, 16103,
+  16112, 16143, 16144, 16146, 16150, 16151, 16153, 16167, 16172, 16195,
+  16214, 16245, 16271, 16274, 16283, 16289, 16293, 16314, 16316, 16330,
+  16337, 16338, 16356, 16365, 16366, 16369, 16372, 16375, 16379, 16384,
+  16385, 16386, 16390.
 
 * Slovenian translations for glibc messages have been contributed by the
   Translation Project's Slovenian team of translators.
diff --git a/manual/memory.texi b/manual/memory.texi
index 55a6a50..bf58819 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{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{} @acsfd{} @acsmem{}}}
+@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 @asulock @aculock @acsfd @acsmem
+@c  force_reg ok
+@c  *malloc_hook unguarded
+@c  arena_lookup ok
+@c   tsd_getspecific ok, TLS
+@c  arena_lock @asulock @aculock @acsfd @acsmem
+@c   mutex_lock @asulock @aculock
+@c   arena_get2 @asulock @aculock @acsfd @acsmem
+@c    get_free_list @asulock @aculock
+@c     mutex_lock (list_lock) dup @asulock @aculock
+@c     mutex_unlock (list_lock) dup @aculock
+@c     mutex_lock (arena lock) dup @asulock @aculock returns locked
+@c     tsd_setspecific ok, TLS
+@c    __get_nprocs ext ok @acsfd
+@c    NARENAS_FROM_NCORES ok
+@c    catomic_compare_and_exchange_bool_acq ok
+@c    _int_new_arena ok @asulock @aculock @acsmem
+@c     new_heap ok @acsmem
+@c      mmap ok @acsmem
+@c      munmap ok @acsmem
+@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 @asulock @aculock
+@c     atomic_write_barrier ok
+@c     mutex_unlock (list_lock) @aculock
+@c    catomic_decrement ok
+@c    reused_arena @asulock @aculock
+@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) @asulock @aculock
+@c     mutex_lock (arena lock) dup @asulock @aculock
+@c     tsd_setspecific dup ok
+@c  _int_malloc @acsfd @acsmem
+@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 @mtsenv but ok:
+@c     if we get to it, we're toast already, undefined behavior must have
+@c     been invoked before
+@c    libc_message @mtsenv no leaks with cancellation disabled
+@c     FATAL_PREPARE ok
+@c      pthread_setcancelstate disable ok
+@c     libc_secure_getenv @mtsenv
+@c      getenv @mtsenv
+@c     open_not_cancel_2 dup @acsfd
+@c     strchrnul ok
+@c     WRITEV_FOR_FATAL ok
+@c      writev ok
+@c     mmap ok @acsmem
+@c     munmap ok @acsmem
+@c     BEFORE_ABORT @acsfd
+@c      backtrace ok
+@c      write_not_cancel dup ok
+@c      backtrace_symbols_fd @aculock
+@c      open_not_cancel_2 dup @acsfd
+@c      read_not_cancel dup ok
+@c      close_not_cancel_no_status dup @acsfd
+@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 [@mtuconst], @acsfd @acsmem
+@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 @acsmem
+@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 @acsmem
+@c     MMAP dup @acsmem
+@c     munmap @acsmem
+@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) [@asulock @aculock], @acsfd @acsmem
+@c     chunksize dup ok
+@c     mutex_unlock dup @aculock 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 @asulock @aculock 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 @acsfd @acsmem
+@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 @acsmem
+@c       munmap dup @acsmem
+@c      unlink dup ok
+@c      set_head dup ok
+@c      shrink_heap @acsfd
+@c       check_may_shrink_heap @acsfd
+@c        open_not_cancel_2 @acsfd
+@c        read_not_cancel ok
+@c        close_not_cancel_no_status @acsfd
+@c       MMAP dup ok
+@c       madvise ok
+@c     munmap_chunk @acsmem
+@c      chunksize dup ok
+@c      chunk_is_mmapped dup ok
+@c      chunk2mem dup ok
+@c      malloc_printerr dup ok
+@c      munmap dup @acsmem
+@c    check_malloc_state ok, disabled
+@c  arena_get_retry @asulock @aculock @acsfd @acsmem
+@c   mutex_unlock dup @aculock
+@c   mutex_lock dup @asulock @aculock
+@c   arena_get2 dup @asulock @aculock @acsfd @acsmem
+@c  mutex_unlock @aculock
+@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{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{} @acsfd{} @acsmem{}}}
+@c __libc_free @asulock @aculock @acsfd @acsmem
+@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 @asulock.
+@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 [@mtuconst], @acsmem
+@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 @asulock @aculock @acsfd @acsmem
 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{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{} @acsfd{} @acsmem{}}}
+@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{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{} @acsfd{} @acsmem{}}}
+@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 @asulock @aculock @acsfd @acsmem
+@c  *__realloc_hook unguarded
+@c  __libc_free dup @asulock @aculock @acsfd @acsmem
+@c  __libc_malloc dup @asulock @aculock @acsfd @acsmem
+@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 @acsmem
+@c  arena_for_chunk dup ok
+@c  mutex_lock (arena mutex) dup @asulock @aculock
+@c  _int_realloc @acsfd @acsmem
+@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 @acsfd @acsmem
+@c   mem2chunk dup ok
+@c   MALLOC_COPY dup ok
+@c   _int_free (have_lock) dup @acsfd @acsmem
+@c   set_inuse_bit_at_offset dup ok
+@c   set_head dup ok
+@c  mutex_unlock (arena mutex) dup @aculock
+@c  _int_free (!have_lock) dup @asulock @aculock @acsfd @acsmem
+
 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{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{} @acsfd{} @acsmem{}}}
+@c Same caveats as malloc.
+
+@c __libc_calloc @asulock @aculock @acsfd @acsmem
+@c  *__malloc_hook dup unguarded
+@c  memset dup ok
+@c  arena_get @asulock @aculock @acsfd @acsmem
+@c   arena_lookup dup ok
+@c   arena_lock dup @asulock @aculock @acsfd @acsmem
+@c  top dup ok
+@c  chunksize dup ok
+@c  heap_for_ptr dup ok
+@c  _int_malloc dup @acsfd @acsmem
+@c  arena_get_retry dup @asulock @aculock @acsfd @acsmem
+@c  mutex_unlock dup @aculock
+@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.
@@ -622,6 +944,8 @@ power of two than that, use @code{aligned_alloc} or @code{posix_memalign}.
 
 @comment stdlib.h
 @deftypefun {void *} aligned_alloc (size_t @var{alignment}, size_t @var{size})
+@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{} @acsfd{} @acsmem{}}}
+@c Alias to memalign.
 The @code{aligned_alloc} function allocates a block of @var{size} bytes whose
 address is a multiple of @var{alignment}.  The @var{alignment} must be a
 power of two and @var{size} must be a multiple of @var{alignment}.
@@ -645,6 +969,29 @@ portability to modern non-POSIX systems than @code{posix_memalign}.
 @comment malloc.h
 @comment BSD
 @deftypefun {void *} memalign (size_t @var{boundary}, size_t @var{size})
+@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{} @acsfd{} @acsmem{}}}
+@c Same issues as malloc.  The padding bytes are safely freed in
+@c _int_memalign, with the arena still locked.
+
+@c __libc_memalign @asulock @aculock @acsfd @acsmem
+@c  *__memalign_hook dup unguarded
+@c  __libc_malloc dup @asulock @aculock @acsfd @acsmem
+@c  arena_get dup @asulock @aculock @acsfd @acsmem
+@c  _int_memalign @acsfd @acsmem
+@c   _int_malloc dup @acsfd @acsmem
+@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 @acsfd @acsmem
+@c   chunk_at_offset dup ok
+@c   check_inuse_chunk dup ok
+@c  arena_get_retry dup @asulock @aculock @acsfd @acsmem
+@c  mutex_unlock dup @aculock
 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
@@ -670,6 +1017,10 @@ The @code{memalign} function is obsolete and @code{aligned_alloc} or
 @comment stdlib.h
 @comment POSIX
 @deftypefun int posix_memalign (void **@var{memptr}, size_t @var{alignment}, size_t @var{size})
+@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{} @acsfd{} @acsmem{}}}
+@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
@@ -698,6 +1049,39 @@ systems that do not support @w{ISO C11}.
 @comment malloc.h stdlib.h
 @comment BSD
 @deftypefun {void *} valloc (size_t @var{size})
+@safety{@prelim{}@mtunsafe{@mtuinit{}}@asunsafe{@asuinit{} @asulock{}}@acunsafe{@acuinit{} @aculock{} @acsfd{} @acsmem{}}}
+@c __libc_valloc @mtuinit @asuinit @asulock @aculock @acsfd @acsmem
+@c  ptmalloc_init (once) @mtsenv @asulock @aculock @acsfd @acsmem
+@c   _dl_addr @asucorrupt?, @aculock
+@c    __rtld_lock_lock_recursive (dl_load_lock) @asucorrupt?, @aculock
+@c    _dl_find_dso_for_object ok, iterates over dl_ns and its _ns_loaded objs
+@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) @aculock
+@c   thread_atfork @asulock @aculock @acsfd @acsmem
+@c    __register_atfork @asulock @aculock @acsfd @acsmem
+@c     lll_lock (__fork_lock) @asulock @aculock
+@c     fork_handler_alloc @asulock @aculock @acsfd @acsmem
+@c      calloc dup @asulock @aculock @acsfd @acsmem
+@c     __linkin_atfork ok
+@c      catomic_compare_and_exchange_bool_acq ok
+@c     lll_unlock (__fork_lock) @aculock
+@c   *_environ @mtsenv
+@c   next_env_entry ok
+@c   strcspn dup ok
+@c   __libc_mallopt dup @mtuconst setting mp_
+@c   __malloc_check_init @mtuconst setting hooks
+@c   *__malloc_initialize_hook unguarded, ok
+@c  *__memalign_hook dup ok, unguarded
+@c  arena_get dup @asulock @aculock @acsfd @acsmem
+@c  _int_valloc @acsfd @acsmem
+@c   malloc_consolidate dup ok
+@c   _int_memalign dup @acsfd @acsmem
+@c  arena_get_retry dup @asulock @aculock @acsfd @acsmem
+@c  _int_memalign dup @acsfd @acsmem
+@c  mutex_unlock dup @aculock
 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:
 
@@ -725,6 +1109,14 @@ interface, defined in @file{malloc.h}.
 @pindex malloc.h
 
 @deftypefun int mallopt (int @var{param}, int @var{value})
+@safety{@prelim{}@mtunsafe{@mtuinit{} @mtasuconst{}}@asunsafe{@asuinit{} @asulock{}}@acunsafe{@acuinit{} @aculock{}}}
+@c __libc_mallopt @mtuinit @mtuconst @asuinit @asulock @aculock
+@c  ptmalloc_init (once) dup @mtsenv @asulock @aculock @acsfd @acsmem
+@c  mutex_lock (main_arena->mutex) @asulock @aculock
+@c  malloc_consolidate dup ok
+@c  set_max_fast ok
+@c  mutex_unlock dup @aculock
+
 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:
@@ -781,6 +1173,17 @@ declared in @file{mcheck.h}.
 @comment mcheck.h
 @comment GNU
 @deftypefun int mcheck (void (*@var{abortfn}) (enum mcheck_status @var{status}))
+@safety{@prelim{}@mtunsafe{@mtasuconst{}}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{}}}
+@c The hooks must be set up before malloc is first used, which sort of
+@c implies @mtuinit/@asuinit 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}.
@@ -823,6 +1226,18 @@ must be called before the first such function.
 @end deftypefun
 
 @deftypefun {enum mcheck_status} mprobe (void *@var{pointer})
+@safety{@prelim{}@mtunsafe{@mtasuconst{}}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{}}}
+@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
@@ -1137,6 +1552,24 @@ space's data segment).
 @comment malloc.h
 @comment SVID
 @deftypefun {struct mallinfo} mallinfo (void)
+@safety{@prelim{}@mtunsafe{@mtuinit{} @mtasuconst{}}@asunsafe{@asuinit{} @asulock{}}@acunsafe{@acuinit{} @aculock{}}}
+@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 @mtuconst 1stline, @asuinit @asulock @aculock
+@c  ptmalloc_init (once) dup @mtsenv @asulock @aculock @acsfd @acsmem
+@c  mutex_lock dup @asulock @aculock
+@c  int_mallinfo @mtuconst (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 @aculock
+
 This function returns information about the current dynamic memory usage
 in a structure of type @code{struct mallinfo}.
 @end deftypefun
@@ -1235,6 +1668,20 @@ penalties for the program if the debugging mode is not enabled.
 @comment mcheck.h
 @comment GNU
 @deftypefun void mtrace (void)
+@safety{@prelim{}@mtunsafe{@mtsenv{} @mtasuconst{} @mtuinit{}}@asunsafe{@asuinit{} @ascuheap{} @asucorrupt{} @asulock{}}@acunsafe{@acuinit{} @acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
+@c Like the mcheck hooks, these are not designed with thread safety in
+@c mind, because the hook pointers are temporarily modified without
+@c regard to other threads, signals or cancellation.
+
+@c mtrace @mtuinit @mtuconst @mtsenv @asuinit @ascuheap @asucorrupt @acuinit @acucorrupt @aculock @acsfd @acsmem
+@c  __libc_secure_getenv dup @mtsenv
+@c  malloc dup @asulock @aculock @acsfd @acsmem
+@c  fopen dup @ascuheap @asulock @aculock @acsmem @acsfd
+@c  fcntl dup ok
+@c  setvbuf dup @aculock
+@c  fprintf dup (on newly-created stream) @aculock
+@c  __cxa_atexit (once) dup @asulock @aculock @acsmem
+@c  free dup @asulock @aculock @acsfd @acsmem
 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
@@ -1258,6 +1705,11 @@ systems.  The prototype can be found in @file{mcheck.h}.
 @comment mcheck.h
 @comment GNU
 @deftypefun void muntrace (void)
+@safety{@prelim{}@mtunsafe{@mtasuconst{} @mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{}}@acunsafe{@acucorrupt{} @acsmem{} @aculock{} @acsfd{}}}
+
+@c muntrace @mtuconst @mtslocale @asucorrupt @ascuheap @acucorrupt @acsmem @aculock @acsfd
+@c  fprintf (fputs) dup @mtslocale @asucorrupt @ascuheap @acsmem @aculock @acucorrupt
+@c  fclose dup @ascuheap @asulock @aculock @acsmem @acsfd
 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.
@@ -1569,6 +2021,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{@prelim{}@mtunsafe{@mtsrace{}}@assafe{}@acsafe{@acsmem{}}}
+@c obstack_init @mtsrace @acsmem
+@c  _obstack_begin @acsmem
+@c    chunkfun = obstack_chunk_alloc (suggested malloc)
+@c    freefun = obstack_chunk_free (suggested free)
+@c   *chunkfun @acsmem
+@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 @ascuintl
+@c  fxprintf dup @asucorrupt @aculock @acucorrupt
+@c  exit @acucorrupt?
 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
@@ -1624,6 +2090,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{@prelim{}@mtunsafe{@mtsrace{}}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{} @acsmem{}}}
+@c obstack_alloc @mtsrace @asucorrupt @acucorrupt @acsmem
+@c  obstack_blank dup @mtsrace @asucorrupt @acucorrupt @acsmem
+@c  obstack_finish dup @mtsrace @asucorrupt @acucorrupt
 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}
@@ -1658,6 +2128,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{@prelim{}@mtunsafe{@mtsrace{}}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{} @acsmem{}}}
+@c obstack_copy @mtsrace @asucorrupt @acucorrupt @acsmem
+@c  obstack_grow dup @mtsrace @asucorrupt @acucorrupt @acsmem
+@c  obstack_finish dup @mtsrace @asucorrupt @acucorrupt
 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
@@ -1667,6 +2141,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{@prelim{}@mtunsafe{@mtsrace{}}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{} @acsmem{}}}
+@c obstack_copy0 @mtsrace @asucorrupt @acucorrupt @acsmem
+@c  obstack_grow0 dup @mtsrace @asucorrupt @acucorrupt @acsmem
+@c  obstack_finish dup @mtsrace @asucorrupt @acucorrupt
 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
@@ -1699,6 +2177,10 @@ in the same obstack.
 @comment obstack.h
 @comment GNU
 @deftypefun void obstack_free (struct obstack *@var{obstack-ptr}, void *@var{object})
+@safety{@prelim{}@acunsafe{@mtsrace{}}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{}}}
+@c obstack_free @mtsrace @asucorrupt @acucorrupt
+@c  (obstack_free) @mtsrace @asucorrupt @acucorrupt
+@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
@@ -1803,6 +2285,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{@prelim{}@mtunsafe{@mtsrace{}}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{} @acsmem{}}}
+@c obstack_blank @mtsrace @asucorrupt @acucorrupt @acsmem
+@c  _obstack_newchunk @mtsrace @asucorrupt @acucorrupt @acsmem
+@c   *chunkfun dup @acsmem
+@c   *obstack_alloc_failed_handler dup user-supplied
+@c   *freefun
+@c  obstack_blank_fast dup @mtsrace @asucorrupt
 The most basic function for adding to a growing object is
 @code{obstack_blank}, which adds space without initializing it.
 @end deftypefun
@@ -1810,6 +2299,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{@prelim{}@mtunsafe{@mtsrace{}}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{} @acsmem{}}}
+@c obstack_grow @mtsrace @asucorrupt @acucorrupt @acsmem
+@c  _obstack_newchunk dup @mtsrace @asucorrupt @acucorrupt @acsmem
+@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
@@ -1819,6 +2312,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{@prelim{}@mtunsafe{@mtsrace{}}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{} @acsmem{}}}
+@c obstack_grow0 @mtsrace @asucorrupt @acucorrupt @acsmem
+@c   (no sequence point between storing NUL and incrementing next_free)
+@c   (multiple changes to next_free => @acucorrupt)
+@c  _obstack_newchunk dup @mtsrace @asucorrupt @acucorrupt @acsmem
+@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.
@@ -1827,6 +2326,10 @@ character.
 @comment obstack.h
 @comment GNU
 @deftypefun void obstack_1grow (struct obstack *@var{obstack-ptr}, char @var{c})
+@safety{@prelim{}@mtunsafe{@mtsrace{}}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{} @acsmem{}}}
+@c obstack_1grow @mtsrace @asucorrupt @acucorrupt @acsmem
+@c  _obstack_newchunk dup @mtsrace @asucorrupt @acucorrupt @acsmem
+@c  obstack_1grow_fast dup @mtsrace @asucorrupt @acucorrupt @acsmem
 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
@@ -1834,6 +2337,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{@prelim{}@mtunsafe{@mtsrace{}}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{} @acsmem{}}}
+@c obstack_ptr_grow @mtsrace @asucorrupt @acucorrupt @acsmem
+@c  _obstack_newchunk dup @mtsrace @asucorrupt @acucorrupt @acsmem
+@c  obstack_ptr_grow_fast dup @mtsrace @asucorrupt
 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}.
@@ -1842,6 +2349,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{@prelim{}@mtunsafe{@mtsrace{}}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{} @acsmem{}}}
+@c obstack_int_grow @mtsrace @asucorrupt @acucorrupt @acsmem
+@c  _obstack_newchunk dup @mtsrace @asucorrupt @acucorrupt @acsmem
+@c  obstack_int_grow_fast dup @mtsrace @asucorrupt
 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}.
@@ -1850,6 +2361,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{@prelim{}@mtunsafe{@mtsrace{}}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{}}}
+@c obstack_finish @mtsrace @asucorrupt @acucorrupt
 When you are finished growing the object, use the function
 @code{obstack_finish} to close it off and return its final address.
 
@@ -1869,6 +2382,7 @@ declared as follows:
 @comment obstack.h
 @comment GNU
 @deftypefun int obstack_object_size (struct obstack *@var{obstack-ptr})
+@safety{@prelim{}@mtunsafe{@mtsrace{}}@asunsafe{@asucorrupt{}}@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.
@@ -1912,6 +2426,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{@prelim{}@mtunsafe{@mtsrace{}}@asunsafe{@asucorrupt{}}@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.
@@ -1923,6 +2438,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{@prelim{}@mtunsafe{@mtsrace{}}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{} @acsmem{}}}
+@c obstack_1grow_fast @mtsrace @asucorrupt @acucorrupt @acsmem
+@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
@@ -1930,6 +2448,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{@prelim{}@mtunsafe{@mtsrace{}}@asunsafe{@asucorrupt{}}@acsafe{}}
+@c obstack_ptr_grow_fast @mtsrace @asucorrupt
 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}.
@@ -1938,6 +2458,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{@prelim{}@mtunsafe{@mtsrace{}}@asunsafe{@asucorrupt{}}@acsafe{}}
+@c obstack_int_grow_fast @mtsrace @asucorrupt
 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}.
@@ -1946,6 +2468,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{@prelim{}@mtunsafe{@mtsrace{}}@asunsafe{@asucorrupt{}}@acsafe{}}
+@c obstack_blank_fast @mtsrace @asucorrupt
 The function @code{obstack_blank_fast} adds @var{size} bytes to the
 growing object in obstack @var{obstack-ptr} without initializing them.
 @end deftypefun
@@ -2004,6 +2528,7 @@ still growing it.
 @comment obstack.h
 @comment GNU
 @deftypefun {void *} obstack_base (struct obstack *@var{obstack-ptr})
+@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@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
@@ -2017,6 +2542,7 @@ chunk).
 @comment obstack.h
 @comment GNU
 @deftypefun {void *} obstack_next_free (struct obstack *@var{obstack-ptr})
+@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@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}
@@ -2026,6 +2552,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{@prelim{}@mtunsafe{@mtsrace{}}@asunsafe{@asucorrupt{}}@acsafe{}}
 This function returns the size in bytes of the currently growing object.
 This is equivalent to
 
@@ -2050,6 +2578,7 @@ this:
 @comment obstack.h
 @comment GNU
 @deftypefn Macro int obstack_alignment_mask (struct obstack *@var{obstack-ptr})
+@safety{@prelim{}@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
@@ -2117,6 +2646,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{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
 This returns the chunk size of the given obstack.
 @end deftypefn
 
@@ -2236,6 +2766,7 @@ a BSD extension.
 @comment stdlib.h
 @comment GNU, BSD
 @deftypefun {void *} alloca (size_t @var{size})
+@safety{@prelim{}@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
@@ -2418,6 +2949,7 @@ system calls.
 @comment unistd.h
 @comment BSD
 @deftypefun int brk (void *@var{addr})
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
 
 @code{brk} sets the high end of the calling process' data segment to
 @var{addr}.
@@ -2460,6 +2992,8 @@ exceed the process' data storage limit.
 @comment unistd.h
 @comment BSD
 @deftypefun void *sbrk (ptrdiff_t @var{delta})
+@safety{@prelim{}@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
@@ -2599,6 +3133,7 @@ this requirement.
 @comment sys/mman.h
 @comment POSIX.1b
 @deftypefun int mlock (const void *@var{addr}, size_t @var{len})
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
 
 @code{mlock} locks a range of the calling process' virtual pages.
 
@@ -2652,6 +3187,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{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
 
 @code{munlock} unlocks a range of the calling process' virtual pages.
 
@@ -2664,6 +3200,7 @@ failure.
 @comment sys/mman.h
 @comment POSIX.1b
 @deftypefun int mlockall (int @var{flags})
+@safety{@prelim{}@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
@@ -2740,6 +3277,7 @@ with @code{munlockall} and @code{munlock}.
 @comment sys/mman.h
 @comment POSIX.1b
 @deftypefun int munlockall (void)
+@safety{@prelim{}@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=49d3395980c95fecbb4d36193bb492b9c86e68ed

commit 49d3395980c95fecbb4d36193bb492b9c86e68ed
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 5e7c90e..b54604a 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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+@c There are calls to nan* that could trigger @mtslocale 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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@mtunsafe{@mtasurace{}}@asunsafe{@mtasurace{}}@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{@prelim{}@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{@prelim{}@mtunsafe{@mtasurace{}}@asunsafe{@mtasurace{}}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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,
@@ -1384,6 +1443,8 @@ value the @code{rand} function can return.  In @theglibc{}, it is
 @comment stdlib.h
 @comment ISO
 @deftypefun int rand (void)
+@safety{@prelim{}@mtsafe{@mtasurace{}}@asunsafe{@asulock{}}@acunsafe{@aculock{}}}
+@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
@@ -1391,6 +1452,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{@prelim{}@mtsafe{@mtasurace{}}@asunsafe{@asulock{}}@acunsafe{@aculock{}}}
+@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
@@ -1407,6 +1470,7 @@ designed and unsuitable for serious work.
 @comment stdlib.h
 @comment POSIX.1
 @deftypefun int rand_r (unsigned int *@var{seed})
+@safety{@prelim{}@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
@@ -1433,6 +1497,9 @@ The prototypes for these functions are in @file{stdlib.h}.
 @comment stdlib.h
 @comment BSD
 @deftypefun {long int} random (void)
+@safety{@prelim{}@mtsafe{@mtasurace{}}@asunsafe{@asulock{}}@acunsafe{@aculock{}}}
+@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}.
 
@@ -1446,6 +1513,12 @@ though.
 @comment stdlib.h
 @comment BSD
 @deftypefun void srandom (unsigned int @var{seed})
+@safety{@prelim{}@mtsafe{@mtasurace{}}@asunsafe{@asulock{}}@acunsafe{@aculock{}}}
+@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 @mturace.
 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
@@ -1458,6 +1531,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{@prelim{}@mtsafe{@mtasurace{}}@asunsafe{@asulock{}}@acunsafe{@aculock{}}}
 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
@@ -1472,6 +1546,7 @@ restore that state.
 @comment stdlib.h
 @comment BSD
 @deftypefun {char *} setstate (char *@var{state})
+@safety{@prelim{}@mtsafe{@mtasurace{}}@asunsafe{@asulock{}}@acunsafe{@aculock{}}}
 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}.
@@ -1512,6 +1587,7 @@ functions.
 @comment stdlib.h
 @comment GNU
 @deftypefun int random_r (struct random_data *restrict @var{buf}, int32_t *restrict @var{result})
+@safety{@prelim{}@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.
@@ -1520,6 +1596,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{@prelim{}@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.
@@ -1528,6 +1605,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{@prelim{}@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.
@@ -1536,6 +1614,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{@prelim{}@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.
@@ -1582,6 +1661,12 @@ The prototypes for these functions are in @file{stdlib.h}.
 @comment stdlib.h
 @comment SVID
 @deftypefun double drand48 (void)
+@safety{@prelim{}@mtsafe{@mtasurace{}}@assafe{@asucorrupt{}}@acsafe{@acucorrupt{}}}
+@c Uses of the static state buffer are not guarded by a lock (thus
+@c @mturace), 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.
@@ -1595,6 +1680,9 @@ bits and they are initialized to @code{0}.
 @comment stdlib.h
 @comment SVID
 @deftypefun double erand48 (unsigned short int @var{xsubi}[3])
+@safety{@prelim{}@mtsafe{@mtasurace{}}@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.
@@ -1607,6 +1695,7 @@ initial use to obtain reproducible results.
 @comment stdlib.h
 @comment SVID
 @deftypefun {long int} lrand48 (void)
+@safety{@prelim{}@mtsafe{@mtasurace{}}@assafe{@asucorrupt{}}@acsafe{@acucorrupt{}}}
 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.
@@ -1617,6 +1706,7 @@ generator in the C library.
 @comment stdlib.h
 @comment SVID
 @deftypefun {long int} nrand48 (unsigned short int @var{xsubi}[3])
+@safety{@prelim{}@mtsafe{@mtasurace{}}@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
@@ -1631,6 +1721,7 @@ first call to obtain reproducible results.
 @comment stdlib.h
 @comment SVID
 @deftypefun {long int} mrand48 (void)
+@safety{@prelim{}@mtsafe{@mtasurace{}}@assafe{@asucorrupt{}}@acsafe{@acucorrupt{}}}
 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).
@@ -1639,6 +1730,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{@prelim{}@mtsafe{@mtasurace{}}@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
@@ -1652,6 +1744,7 @@ information provided.
 @comment stdlib.h
 @comment SVID
 @deftypefun void srand48 (long int @var{seedval})
+@safety{@prelim{}@mtunsafe{@mtasurace{}}@asunsafe{@mtasurace{}}@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
@@ -1671,6 +1764,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{@prelim{}@mtunsafe{@mtasurace{}}@asunsafe{@mtasurace{}}@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
@@ -1698,6 +1792,7 @@ change the parameters in the congruential formula.
 @comment stdlib.h
 @comment SVID
 @deftypefun void lcong48 (unsigned short int @var{param}[7])
+@safety{@prelim{}@mtunsafe{@mtasurace{}}@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
@@ -1730,6 +1825,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{@prelim{}@mtsafe{@mtsrace{}}@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
@@ -1747,6 +1843,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{@prelim{}@mtsafe{@mtsrace{}}@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
@@ -1763,6 +1860,7 @@ programs.
 @comment stdlib.h
 @comment GNU
 @deftypefun int lrand48_r (struct drand48_data *@var{buffer}, long int *@var{result})
+@safety{@prelim{}@mtsafe{@mtsrace{}}@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}.
@@ -1777,6 +1875,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{@prelim{}@mtsafe{@mtsrace{}}@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
@@ -1793,6 +1892,7 @@ programs.
 @comment stdlib.h
 @comment GNU
 @deftypefun int mrand48_r (struct drand48_data *@var{buffer}, long int *@var{result})
+@safety{@prelim{}@mtsafe{@mtsrace{}}@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}.
@@ -1807,6 +1907,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{@prelim{}@mtsafe{@mtsrace{}}@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
@@ -1841,6 +1942,7 @@ what you expect.
 @comment stdlib.h
 @comment GNU
 @deftypefun int srand48_r (long int @var{seedval}, struct drand48_data *@var{buffer})
+@safety{@prelim{}@mtsafe{@mtsrace{}}@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
@@ -1856,6 +1958,7 @@ programs.
 @comment stdlib.h
 @comment GNU
 @deftypefun int seed48_r (unsigned short int @var{seed16v}[3], struct drand48_data *@var{buffer})
+@safety{@prelim{}@mtsafe{@mtsrace{}}@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}.
 
@@ -1872,6 +1975,7 @@ programs.
 @comment stdlib.h
 @comment GNU
 @deftypefun int lcong48_r (unsigned short int @var{param}[7], struct drand48_data *@var{buffer})
+@safety{@prelim{}@mtsafe{@mtsrace{}}@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=e827571c4f1c93eb020fca6408aa431d8b12e404

commit e827571c4f1c93eb020fca6408aa431d8b12e404
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=c0f1670f24dab29abf773005150aeebb6ceec8a2

commit c0f1670f24dab29abf773005150aeebb6ceec8a2
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..07dc2bc 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{@prelim{}@mtunsafe{@mtsrace{} @mtsenv{} @mtasurace{}}@asunsafe{@ascuheap{} @ascuintl{} @asulock{} @asucorrupt{}}@acunsafe{@acsmem{} @aculock{} @acucorrupt{}}}
+@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{@prelim{}@mtunsafe{@mtsrace{} @mtsenv{} @mtasurace{}}@asunsafe{@ascuheap{} @ascuintl{} @asulock{} @asucorrupt{}}@acunsafe{@acsmem{} @aculock{} @acucorrupt{}}}
+@c Same issues as getopt.
 Decode options from the vector @var{argv} (whose length is @var{argc}).
 The argument @var{shortopts} describes the short options to accept, just as
 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{@prelim{}@mtunsafe{@mtsrace{} @mtsenv{} @mtasurace{}}@asunsafe{@ascuheap{} @ascuintl{} @asulock{} @asucorrupt{}}@acunsafe{@acsmem{} @aculock{} @acucorrupt{}}}
+@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=59e69a01ec8b2745c7081dda628a4c6bbd47fb94

commit 59e69a01ec8b2745c7081dda628a4c6bbd47fb94
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 459fb1f..5bdd307 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{@prelim{}@mtsafe{}@asunsafe{@ascuheap{}}@acsafe{@acsmem{} @acsfd{}}}
+@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{@prelim{}@mtsafe{}@asunsafe{@ascuheap{} @ascuintl{}}@acsafe{@acsmem{} @acsfd{}}}
+@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{@prelim{}@mtunsafe{@mtsenv{}}@asunsafe{@ascuheap{}}@acsafe{@acsmem{} @acsfd{}}}
+@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@mtsafe{}@asunsafe{@ascuheap{}}@acsafe{@acsmem{} @acsfd{}}}
+@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{@prelim{}@mtsafe{}@asunsafe{@ascuheap{}}@acsafe{@acsmem{} @acsfd{}}}
+@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{@prelim{}@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{@prelim{}@mtunsafe{@mtasurace{}}@asunsafe{@asulock{}}@acunsafe{@aculock{}}}
+@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{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{}}}
 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{@prelim{}@mtunsafe{@mtasurace{}}@asunsafe{@asulock{}}@acunsafe{@aculock{}}}
 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{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{}}}
 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{@prelim{}@mtsafe{}@asunsafe{@ascuheap{} @asulock{} (hurd)}@acsafe{@acsmem{} @acsfd{} @aculock{} (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{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{}}}
 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{@prelim{}@mtsafe{}@asunsafe{@ascuheap{} (bsd), @asulock{} (bsd)}@acunsafe{@acsmem{} (bsd), @aculock{} (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{@prelim{}@mtsafe{}@asunsafe{@ascuheap{} (bsd), @asulock{} (bsd)}@acunsafe{@acsmem{} (bsd), @aculock{} (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{@prelim{}@mtsafe{}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{} @acsfd{}}}
+@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{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@ascuheap{}}@acsafe{@acsmem{}}}
+@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{@prelim{}@mtsafe{@mtslocale{}}@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{@prelim{}@mtsafe{}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{} @acsfd{}}}
+@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{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@ascuheap{}}@acsafe{@acsmem{}}}
+@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{@prelim{}@mtsafe{@mtslocale{}}@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{@prelim{}@mtsafe{@mtsrace{}}, @asunsafe{@ascuheap{}}, @acsafe{@acsmem{} @acsfd{}}}
+@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{@prelim{}@mtsafe{@mtsrace{}}, @asunsafe{@ascuheap{}}, @acsafe{@acsmem{} @acsfd{}}}
 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{@prelim{}@mtsafe{@mtsrace{} @mtasscwd{}}@asunsafe{@ascuheap{}}@acsafe{@acsmem{} @acsfd{} @acscwd{}}}
+@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{@prelim{}@mtsafe{@mtsrace{} @mtasscwd{}}@asunsafe{@ascuheap{}}@acsafe{@acsmem{} @acsfd{} @acscwd{}}}
 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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@mtsafe{@mtsrace{}}@asunsafe{@ascuheap{}}@acsafe{@acsmem{} @acsfd{}}}
+@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{@prelim{}@mtsafe{@mtsrace{}}@asunsafe{@ascuheap{}}@acsafe{@acsmem{} @acsfd{}}}
+@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{@prelim{}@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{@prelim{}@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{@prelim{}@mtsafe{@mtsrace{}}@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{@prelim{}@mtsafe{@mtsrace{}}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@ascuheap}@acsafe{@acsmem}}
+
 @comment sys/stat.h
 @comment BSD
 @deftypefun int lstat (const char *@var{filename}, struct stat *@var{buf})
+@safety{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
 If the system implement POSIX shared memory objects as distinct objects
 and the file is a 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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@mtsafe{@mtsrace{}}@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{@prelim{}@mtsafe{@mtsrace{}}@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{@prelim{}@mtsafe{@mtsrace{}}@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{@prelim{}@mtsafe{@mtsrace{}}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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 @mtsrace 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{@prelim{}@mtsafe{}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@acsmem{} @acsfd{} @aculock{}}}
+@c The unsafety issues are those of fdopen, plus @acsfd 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{@prelim{}@mtsafe{}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@acsmem{} @acsfd{} @aculock{}}}
 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{@prelim{}@mtunsafe{@mtsrace{} @mtasurace{}}@asunsafe{@mtasurace{}}@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{@prelim{}@mtsafe{@mtsrace{}}@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{@prelim{}@mtunsafe{@mtsrace{} @mtsenv{}}@assafe{@ascuheap{}}@acsafe{@acsmem{}}}
+@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{@prelim{}@mtunsafe{@mtsrace{}}@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{@prelim{}@mtunsafe{@mtsrace{}}@assafe{}@acsafe{@acsfd{}}}
+@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{@prelim{}@mtunsafe{@mtsrace{}}@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=d1a76e17fc0331cbdfdc86cd655b883fc4d49c42

commit d1a76e17fc0331cbdfdc86cd655b883fc4d49c42
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 b1bfbe9..effb9ed 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{@prelim{}@mtunsafe{@mtasurace{}}@asunsafe{@mtasurace{} @ascuheap{} @ascuintl{}}@acsafe{@acsmem{}}}
+@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{@prelim{}@mtsafe{}@asunsafe{@ascuintl{}}@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{@prelim{}@mtsafe{@mtsrace{}}@asunsafe{@asucorrupt{} @ascuintl{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{} @acsfd{}}}
+@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{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{} @ascuintl{}}@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{@prelim{}@mtunsafe{@mtasurace{} @mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{} @ascuintl{}}@acunsafe{@acucorrupt{}}}
+@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{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{} @ascuintl{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{}}}
+@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{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{} @ascuintl{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{}}}
+@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 a value of type @code{va_list}.
@@ -1602,6 +1633,8 @@ in as a value of type @code{va_list}.
 @comment err.h
 @comment BSD
 @deftypefun void warnx (const char *@var{format}, @dots{})
+@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{}}}
+@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{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{}}}
+@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 a value of type @code{va_list}.
@@ -1623,6 +1658,8 @@ in as a value of type @code{va_list}.
 @comment err.h
 @comment BSD
 @deftypefun void err (int @var{status}, const char *@var{format}, @dots{})
+@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{} @ascuintl{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{}}}
+@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{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{} @ascuintl{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{}}}
+@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 a value of type @code{va_list}.
@@ -1643,6 +1682,8 @@ in as a value of type @code{va_list}.
 @comment err.h
 @comment BSD
 @deftypefun void errx (int @var{status}, const char *@var{format}, @dots{})
+@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{}}}
+@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{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{}}}
+@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 a value of type @code{va_list}.

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

commit a6bde994a4d49dcf2ab9c414709fd3c3c4c5a9e2
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..9fe715b 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{@prelim{}@mtsafe{}@asunsafe{@asuinit{} @ascuheap{} @asulock{}}@acunsafe{@acuinit{} @acsmem{} @aculock{} @acsfd{}}}
+@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{@prelim{}@mtsafe{}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{} @aculock{}}}
+@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 @asucorrupt?  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{@prelim{}@mtsafe{}@assafe{}@acunsafe{@aculock{}}}
+@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=9331b2a6e9d6051f7a5c5ea6606cba41a6bc7ed9

commit 9331b2a6e9d6051f7a5c5ea6606cba41a6bc7ed9
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..5bfbcec 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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@mtsafe{@mtslocale{}}@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{@prelim{}@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{@prelim{}@mtsafe{@mtslocale{}}@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{@prelim{}@mtsafe{@mtslocale{}}@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{@prelim{}@mtsafe{@mtslocale{}}@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{@prelim{}@mtsafe{@mtslocale{}}@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{@prelim{}@mtsafe{@mtslocale{}}@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{@prelim{}@mtsafe{@mtslocale{}}@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{@prelim{}@mtsafe{@mtslocale{}}@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{@prelim{}@mtsafe{@mtslocale{}}@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{@prelim{}@mtsafe{@mtslocale{}}@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{@prelim{}@mtsafe{@mtslocale{}}@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{@prelim{}@mtsafe{@mtslocale{}}@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{@prelim{}@mtsafe{@mtslocale{}}@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{@prelim{}@mtsafe{@mtslocale{}}@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{@prelim{}@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{@prelim{}@mtsafe{@mtslocale{}}@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{@prelim{}@mtsafe{@mtslocale{}}@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=b9b685e4bacdbabbc453be5232b12f2d97a97b87

commit b9b685e4bacdbabbc453be5232b12f2d97a97b87
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..ed2a479 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{@prelim{}@mtunsafe{@mtasuterm{}}@asunsafe{@ascuheap{} @asulock{} @asucorrupt{}}@acunsafe{@acuterm{} @aculock{} @acucorrupt{}}}
+@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{@prelim{}@mtunsafe{@mtasurace{}}@asunsafe{@asucorrupt{} @asulock{} @ascuheap{} @ascudlopen{}}@acunsafe{@aculock{} @acsmem{}}}
+@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{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{} @asulock{} @ascuheap{} @ascudlopen{}}@acunsafe{@aculock{} @acsmem{}}}
+@c Compared with crypt, this function fixes the @mturace 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{@prelim{}@mtunsafe{@mtasurace{}}@asunsafe{@asucorrupt{} @asulock{}}@acunsafe{@aculock{}}}
+@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{@prelim{}@mtunsafe{@mtasurace{}}@asunsafe{@asucorrupt{} @asulock{}}@acunsafe{@aculock{}}}
+@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})
+@c @safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{} @asulock{}}@acunsafe{@aculock{}}}
 @comment crypt.h
 @comment GNU
 @deftypefunx void encrypt_r (char *@var{block}, int @var{edflag}, {struct crypt_data *} @var{data})
+@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{} @asulock{}}@acunsafe{@aculock{}}}
 
 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{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
 
 The function @code{ecb_crypt} encrypts or decrypts one or more blocks
 using DES.  Each block is encrypted independently.
@@ -356,6 +383,7 @@ is not a multiple of 8 or @var{len} is larger than @code{DES_MAXDATA}.
 @comment rpc/des_crypt.h
 @comment SUNRPC
 @deftypefun int DES_FAILED (int @var{err})
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
 This macro returns 1 if @var{err} is a `success' result code from
 @code{ecb_crypt} or @code{cbc_crypt}, and 0 otherwise.
 @end deftypefun
@@ -363,6 +391,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{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
 
 The function @code{cbc_crypt} encrypts or decrypts one or more blocks
 using DES in Cipher Block Chaining mode.
@@ -389,6 +418,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{@prelim{}@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=29fd9503919bd00adcd86037352d3881665ae272

commit 29fd9503919bd00adcd86037352d3881665ae272
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..82a8766 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{@prelim{}@mtsafe{@mtsenv{}}@asunsafe{@asulock{} @ascuheap{}}@acunsafe{@aculock{} @acsmem{} @acsfd{}}}
+@c Some parts of the implementation open /proc and /sys files and dirs
+@c to collect system details, using fd and stream I/O depending on the
+@c case.  _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{@prelim{}@mtsafe{}@asunsafe{@asulock{} @ascuheap{}}@acunsafe{@aculock{} @acsfd{} @acsmem{}}}
+@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{@prelim{}@mtsafe{}@asunsafe{@asulock{} @ascuheap{}}@acunsafe{@aculock{} @acsfd{} @acsmem{}}}
+@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{@prelim{}@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=07b14fc9a96cabbb31892516dce0b7bfdd4478a5

commit 07b14fc9a96cabbb31892516dce0b7bfdd4478a5
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 a3e2577..aa5e0b0 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{@prelim{}@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{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{} @ascuheap{} @asulock{} @ascudlopen{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{} @acsfd{}}}
+@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{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{} @ascuheap{} @asulock{} @ascudlopen{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{} @acsfd{}}}
 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{@prelim{}@mtunsafe{@mtasurace{} (if ps is null)}@asunsafe{@asucorrupt{} @ascuheap{} @asulock{} @ascudlopen{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{} @acsfd{}}}
 @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{@prelim{}@mtunsafe{@mtasurace{} (if ps is null)}@asunsafe{@asucorrupt{} @ascuheap{} @asulock{} @ascudlopen{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{} @acsfd{}}}
 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{@prelim{}@mtunsafe{@mtasurace{} (if ps is null)}@asunsafe{@asucorrupt{} @ascuheap{} @asulock{} @ascudlopen{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{} @acsfd{}}}
+@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{@prelim{}@mtunsafe{@mtasurace{} (if ps is null)}@asunsafe{@asucorrupt{} @ascuheap{} @asulock{} @ascudlopen{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{} @acsfd{}}}
 The @code{mbsrtowcs} function (``multibyte string restartable to wide
 character string'') converts a 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{@prelim{}@mtunsafe{@mtasurace{} (if ps is null)}@asunsafe{@asucorrupt{} @ascuheap{} @asulock{} @ascudlopen{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{} @acsfd{}}}
 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{@prelim{}@mtunsafe{@mtasurace{} (if ps is null)}@asunsafe{@asucorrupt{} @ascuheap{} @asulock{} @ascudlopen{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{} @acsfd{}}}
 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{@prelim{}@mtunsafe{@mtasurace{} (if ps is null)}@asunsafe{@asucorrupt{} @ascuheap{} @asulock{} @ascudlopen{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{} @acsfd{}}}
 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{@prelim{}@mtunsafe{@mtasurace{}}@asunsafe{@asucorrupt{} @ascuheap{} @asulock{} @ascudlopen{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{} @acsfd{}}}
 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{@prelim{}@mtunsafe{@mtasurace{}}@asunsafe{@asucorrupt{} @ascuheap{} @asulock{} @ascudlopen{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{} @acsfd{}}}
 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{@prelim{}@mtunsafe{@mtasurace{}}@asunsafe{@asucorrupt{} @ascuheap{} @asulock{} @ascudlopen{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{} @acsfd{}}}
 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{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{} @ascuheap{} @asulock{} @ascudlopen{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{} @acsfd{}}}
+@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{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{} @ascuheap{} @asulock{} @ascudlopen{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{} @acsfd{}}}
 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{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{} @asulock{} @ascudlopen{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{} @acsfd{}}}
+@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{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{} @ascuheap{} @asulock{} @ascudlopen{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{}}}
+@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{@prelim{}@mtunsafe{@mtsrace{}}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{}}}
+@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=7026cfaa8fbb1b0e9723b5700063d8170e7d0b06

commit 7026cfaa8fbb1b0e9723b5700063d8170e7d0b06
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 d394c07..38a9886 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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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{@prelim{}@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
@@ -714,6 +727,14 @@ and save and restore the set of exceptions flagged.
 @comment fenv.h
 @comment ISO
 @deftypefun int feclearexcept (int @var{excepts})
+@safety{@prelim{}@mtsafe{}@assafe{@assposix{}}@acsafe{@acsposix{}}}
+@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}.
 
@@ -724,6 +745,7 @@ non-zero value otherwise.
 @comment fenv.h
 @comment ISO
 @deftypefun int feraiseexcept (int @var{excepts})
+@safety{@prelim{}@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
@@ -739,6 +761,7 @@ non-zero value otherwise.
 @comment fenv.h
 @comment ISO
 @deftypefun int fetestexcept (int @var{excepts})
+@safety{@prelim{}@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.
@@ -775,6 +798,7 @@ following functions:
 @comment fenv.h
 @comment ISO
 @deftypefun int fegetexceptflag (fexcept_t *@var{flagp}, int @var{excepts})
+@safety{@prelim{}@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}.
@@ -786,6 +810,7 @@ non-zero value otherwise.
 @comment fenv.h
 @comment ISO
 @deftypefun int fesetexceptflag (const fexcept_t *@var{flagp}, int @var{excepts})
+@safety{@prelim{}@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}.
@@ -951,6 +976,7 @@ find out which one with this function:
 @comment fenv.h
 @comment ISO
 @deftypefun int fegetround (void)
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
 Returns the currently selected rounding mode, represented by one of the
 values of the defined rounding mode macros.
 @end deftypefun
@@ -961,6 +987,7 @@ To change the rounding mode, use this function:
 @comment fenv.h
 @comment ISO
 @deftypefun int fesetround (int @var{round})
+@safety{@prelim{}@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
@@ -1005,6 +1032,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{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
 Store the floating-point environment in the variable pointed to by
 @var{envp}.
 
@@ -1015,6 +1043,7 @@ non-zero value otherwise.
 @comment fenv.h
 @comment ISO
 @deftypefun int feholdexcept (fenv_t *@var{envp})
+@safety{@prelim{}@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
@@ -1053,6 +1082,7 @@ functions:
 @comment fenv.h
 @comment ISO
 @deftypefun int fesetenv (const fenv_t *@var{envp})
+@safety{@prelim{}@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
@@ -1062,6 +1092,7 @@ non-zero value otherwise.
 @comment fenv.h
 @comment ISO
 @deftypefun int feupdateenv (const fenv_t *@var{envp})
+@safety{@prelim{}@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
@@ -1082,6 +1113,7 @@ occur, you can use the following two functions.
 @comment fenv.h
 @comment GNU
 @deftypefun int feenableexcept (int @var{excepts})
+@safety{@prelim{}@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
@@ -1094,6 +1126,7 @@ operation was successful, @code{-1} otherwise.
 @comment fenv.h
 @comment GNU
 @deftypefun int fedisableexcept (int @var{excepts})
+@safety{@prelim{}@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
@@ -1106,6 +1139,7 @@ operation was successful, @code{-1} otherwise.
 @comment fenv.h
 @comment GNU
 @deftypefun int fegetexcept (void)
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
 The function returns a bitmask of all currently enabled exceptions.  It
 returns @code{-1} in case of failure.
 @end deftypefun
@@ -1157,6 +1191,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{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
 These functions return the absolute value of @var{number}.
 
 Most computers use a two's complement integer representation, in which
@@ -1178,6 +1213,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{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
 This function returns the absolute value of the floating-point number
 @var{number}.
 @end deftypefun
@@ -1191,6 +1227,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{@prelim{}@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:
 
@@ -1228,6 +1265,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{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
 These functions are used to split the number @var{value}
 into a normalized fraction and an exponent.
 
@@ -1253,6 +1291,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{@prelim{}@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
@@ -1274,6 +1313,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{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
 The @code{scalb} function is the BSD name for @code{ldexp}.
 @end deftypefun
 
@@ -1286,6 +1326,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{@prelim{}@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
@@ -1299,6 +1340,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{@prelim{}@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
@@ -1312,6 +1354,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{@prelim{}@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}))}}.
@@ -1346,6 +1389,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{@prelim{}@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}.
@@ -1360,6 +1404,7 @@ is @code{2.0}.
 @comment math.h
 @comment ISO
 @deftypefunx {long double} floorl (long double @var{x})
+@safety{@prelim{}@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}.
@@ -1374,6 +1419,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{@prelim{}@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}.
@@ -1388,6 +1434,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{@prelim{}@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
@@ -1408,6 +1455,7 @@ inexact exception.
 @comment math.h
 @comment ISO
 @deftypefunx {long double} nearbyintl (long double @var{x})
+@safety{@prelim{}@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
@@ -1421,6 +1469,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{@prelim{}@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).
@@ -1435,6 +1484,7 @@ current rounding mode).
 @comment math.h
 @comment ISO
 @deftypefunx {long int} lrintl (long double @var{x})
+@safety{@prelim{}@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
@@ -1448,6 +1498,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{@prelim{}@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
@@ -1461,6 +1512,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{@prelim{}@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
@@ -1474,6 +1526,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{@prelim{}@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
@@ -1488,6 +1541,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{@prelim{}@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},
@@ -1514,6 +1568,7 @@ suits your problem.
 @comment math.h
 @comment ISO
 @deftypefunx {long double} fmodl (long double @var{numerator}, long double @var{denominator})
+@safety{@prelim{}@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}
@@ -1536,6 +1591,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{@prelim{}@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},
@@ -1559,6 +1615,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{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
 This function is another name for @code{drem}.
 @end deftypefun
 
@@ -1580,6 +1637,7 @@ bits.
 @comment math.h
 @comment ISO
 @deftypefunx {long double} copysignl (long double @var{x}, long double @var{y})
+@safety{@prelim{}@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
@@ -1595,6 +1653,7 @@ recommended functions in @w{IEEE 754}/@w{IEEE 854}).
 @comment math.h
 @comment ISO
 @deftypefun int signbit (@emph{float-type} @var{x})
+@safety{@prelim{}@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.
@@ -1613,6 +1672,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{@prelim{}@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
@@ -1636,6 +1696,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{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
 These functions are identical to the corresponding versions of
 @code{nextafter} except that their second argument is a @code{long
 double}.
@@ -1651,6 +1712,8 @@ double}.
 @comment math.h
 @comment ISO
 @deftypefunx {long double} nanl (const char *@var{tagp})
+@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{@mtslocale{}}@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
@@ -1685,6 +1748,7 @@ arguments only once.
 @comment math.h
 @comment ISO
 @deftypefn Macro int isgreater (@emph{real-floating} @var{x}, @emph{real-floating} @var{y})
+@safety{@prelim{}@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.
@@ -1693,6 +1757,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{@prelim{}@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.
@@ -1701,6 +1766,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{@prelim{}@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.
@@ -1709,6 +1775,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{@prelim{}@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.
@@ -1717,6 +1784,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{@prelim{}@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}
@@ -1729,6 +1797,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{@prelim{}@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
@@ -1762,6 +1831,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{@prelim{}@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
@@ -1782,6 +1852,7 @@ are NaN, NaN is returned.
 @comment math.h
 @comment ISO
 @deftypefunx {long double} fmaxl (long double @var{x}, long double @var{y})
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
 The @code{fmax} function returns the greater of the two values @var{x}
 and @var{y}.
 
@@ -1798,6 +1869,7 @@ are NaN, NaN is returned.
 @comment math.h
 @comment ISO
 @deftypefunx {long double} fdiml (long double @var{x}, long double @var{y})
+@safety{@prelim{}@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.
@@ -1815,6 +1887,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{@prelim{}@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
@@ -1944,6 +2017,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{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
 These functions return the real part of the complex number @var{z}.
 @end deftypefun
 
@@ -1956,6 +2030,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{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
 These functions return the imaginary part of the complex number @var{z}.
 @end deftypefun
 
@@ -1968,6 +2043,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{@prelim{}@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}.
@@ -1982,6 +2058,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{@prelim{}@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
@@ -2000,6 +2077,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{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
 These functions return the projection of the complex value @var{z} onto
 the Riemann sphere.  Values with an infinite imaginary part are projected
 to positive infinity on the real axis, even if the real part is NaN.  If
@@ -2045,6 +2123,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{@prelim{}@mtsafe{@mtslocale{}}@assafe{@mtslocale{}}@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}.
@@ -2108,6 +2196,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{@prelim{}@mtsafe{@mtslocale{}}@assafe{@mtslocale{}}@acsafe{}}
 The @code{wcstol} function is equivalent to the @code{strtol} function
 in nearly all aspects but handles wide character strings.
 
@@ -2117,6 +2206,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{@prelim{}@mtsafe{@mtslocale{}}@assafe{@mtslocale{}}@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
@@ -2135,6 +2225,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{@prelim{}@mtsafe{@mtslocale{}}@assafe{@mtslocale{}}@acsafe{}}
 The @code{wcstoul} function is equivalent to the @code{strtoul} function
 in nearly all aspects but handles wide character strings.
 
@@ -2144,6 +2235,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{@prelim{}@mtsafe{@mtslocale{}}@assafe{@mtslocale{}}@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.
@@ -2160,6 +2252,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{@prelim{}@mtsafe{@mtslocale{}}@assafe{@mtslocale{}}@acsafe{}}
 The @code{wcstoll} function is equivalent to the @code{strtoll} function
 in nearly all aspects but handles wide character strings.
 
@@ -2169,12 +2262,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{@prelim{}@mtsafe{@mtslocale{}}@assafe{@mtslocale{}}@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{@prelim{}@mtsafe{@mtslocale{}}@assafe{@mtslocale{}}@acsafe{}}
 The @code{wcstoq} function is equivalent to the @code{strtoq} function
 in nearly all aspects but handles wide character strings.
 
@@ -2184,6 +2279,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{@prelim{}@mtsafe{@mtslocale{}}@assafe{@mtslocale{}}@acsafe{}}
 The @code{strtoull} function is related to @code{strtoll} the same way
 @code{strtoul} is related to @code{strtol}.
 
@@ -2193,6 +2289,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{@prelim{}@mtsafe{@mtslocale{}}@assafe{@mtslocale{}}@acsafe{}}
 The @code{wcstoull} function is equivalent to the @code{strtoull} function
 in nearly all aspects but handles wide character strings.
 
@@ -2202,12 +2299,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{@prelim{}@mtsafe{@mtslocale{}}@assafe{@mtslocale{}}@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{@prelim{}@mtsafe{@mtslocale{}}@assafe{@mtslocale{}}@acsafe{}}
 The @code{wcstouq} function is equivalent to the @code{strtouq} function
 in nearly all aspects but handles wide character strings.
 
@@ -2217,6 +2316,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{@prelim{}@mtsafe{@mtslocale{}}@assafe{@mtslocale{}}@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.
 
@@ -2233,6 +2333,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{@prelim{}@mtsafe{@mtslocale{}}@assafe{@mtslocale{}}@acsafe{}}
 The @code{wcstoimax} function is equivalent to the @code{strtoimax} function
 in nearly all aspects but handles wide character strings.
 
@@ -2242,6 +2343,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{@prelim{}@mtsafe{@mtslocale{}}@assafe{@mtslocale{}}@acsafe{}}
 The @code{strtoumax} function is related to @code{strtoimax}
 the same way that @code{strtoul} is related to @code{strtol}.
 
@@ -2252,6 +2354,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{@prelim{}@mtsafe{@mtslocale{}}@assafe{@mtslocale{}}@acsafe{}}
 The @code{wcstoumax} function is equivalent to the @code{strtoumax} function
 in nearly all aspects but handles wide character strings.
 
@@ -2261,6 +2364,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{@prelim{}@mtsafe{@mtslocale{}}@assafe{@mtslocale{}}@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
@@ -2270,6 +2374,7 @@ existing code; using @code{strtol} is more robust.
 @comment stdlib.h
 @comment ISO
 @deftypefun int atoi (const char *@var{string})
+@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{@mtslocale{}}@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.
@@ -2278,6 +2383,7 @@ instead.
 @comment stdlib.h
 @comment ISO
 @deftypefun {long long int} atoll (const char *@var{string})
+@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{@mtslocale{}}@acsafe{}}
 This function is similar to @code{atol}, except it returns a @code{long
 long int}.
 
@@ -2342,6 +2448,35 @@ as well.
 @comment stdlib.h
 @comment ISO
 @deftypefun double strtod (const char *restrict @var{string}, char **restrict @var{tailptr})
+@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{@mtslocale{}}@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}.
@@ -2427,6 +2562,7 @@ examining @var{errno} and @var{tailptr}.
 @comment stdlib.h
 @comment ISO
 @deftypefunx {long double} strtold (const char *@var{string}, char **@var{tailptr})
+@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{@mtslocale{}}@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
@@ -2446,6 +2582,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{@prelim{}@mtsafe{@mtslocale{}}@assafe{@mtslocale{}}@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.
@@ -2458,6 +2595,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{@prelim{}@mtsafe{@mtslocale{}}@assafe{@mtslocale{}}@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
@@ -2485,6 +2623,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{@prelim{}@mtunsafe{@mtasurace{}}@assafe{@mtasurace{}}@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
@@ -2510,6 +2649,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{@prelim{}@mtunsafe{@mtasurace{}}@assafe{@mtasurace{}}@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
@@ -2528,6 +2668,9 @@ to @code{fcvt}.
 @comment stdlib.h
 @comment SVID, Unix98
 @deftypefun {char *} gcvt (double @var{value}, int @var{ndigit}, char *@var{buf})
+@safety{@prelim{}@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}.
@@ -2542,6 +2685,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{@prelim{}@mtunsafe{@mtasurace{}}@assafe{@mtasurace{}}@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}.
@@ -2550,6 +2694,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{@prelim{}@mtunsafe{@mtasurace{}}@assafe{@mtasurace{}}@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}.
@@ -2558,6 +2703,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{@prelim{}@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}.
@@ -2578,6 +2724,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{@prelim{}@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
@@ -2589,6 +2736,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{@prelim{}@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
@@ -2600,6 +2748,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{@prelim{}@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
@@ -2611,6 +2760,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{@prelim{}@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=59c022df81422763e615b9ff439b2cdd9d5ce844

commit 59c022df81422763e615b9ff439b2cdd9d5ce844
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..ce0d0b0 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{@prelim{}@mtunsafe{@mtsrace{} @mtsenv{}}@asunsafe{@ascuheap{} @ascuintl{} @asulock{} @asucorrupt{}}@acunsafe{@acsmem{} @aculock{} @acucorrupt{}}}
+@c Optionally alloca()tes standard help options, initializes the parser,
+@c then parses individual args in a loop, and then finalizes.
+@c  parser_init
+@c   calc_sizes ok
+@c    option_is_end ok
+@c   malloc
+@c   parser_convert @mtslocale
+@c    convert_options @mtslocale
+@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 @mturace
+@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{@prelim{}@mtunsafe{@mtasurace{} @mtsenv{} @mtslocale{}}@asunsafe{@ascuheap{} @ascuintl{} @asucorrupt{}}@acunsafe{@acsmem{} @acucorrupt{} @aculock{}}}
+@c Just calls argp_state_help with stderr and ARGP_HELP_STD_USAGE.
 Outputs the standard usage message for the argp parser referred to by
 @var{state} to @code{@var{state}->err_stream} and 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{@prelim{}@mtunsafe{@mtasurace{} @mtsenv{} @mtslocale{}}@asunsafe{@ascuheap{} @ascuintl{} @asucorrupt{}}@acunsafe{@acsmem{} @acucorrupt{} @aculock{}}}
+@c Lock stream, vasprintf the formatted message into a buffer, print the
+@c buffer prefixed by the short program name (in libc,
+@c argp_short_program_name is a macro that expands to
+@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{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{} @ascuheap{}}@acunsafe{@aculock{} @acucorrupt{} @acsmem{}}}
+@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{@prelim{}@mtunsafe{@mtasurace{} @mtsenv{} @mtslocale{}}@asunsafe{@ascuheap{} @ascuintl{} @asucorrupt{}}@acunsafe{@acsmem{} @acucorrupt{} @aculock{}}}
+@c Just calls _help with the short program name and optionally exit.
+@c The main problems in _help, besides the usual issues with stream I/O
+@c and translation, are the use of a static buffer (uparams) 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 @mtsenv @mturace (uparams), @mtslocale @ascuheap @ascuintl @asucorrupt @acsmem @acucorrupt @aculock
+@c  dgettext @ascuintl
+@c  flockfile @aculock
+@c  funlockfile @aculock
+@c  fill_in_uparams @mtsenv @mturace (uparams), @mtslocale @asucorrupt @ascuheap @aculock @acucorrupt @acsmem
+@c   argp_failure dup (status = errnum = 0)
+@c   atoi dup @mtslocale
+@c  argp_hol @ascuheap @acsmem
+@c   make_hol @ascuheap @acsmem
+@c   hol_add_cluster @ascuheap @acsmem
+@c   hol_append @ascuheap @acsmem
+@c  hol_set_group ok
+@c   hol_find_entry ok
+@c  hol_sort @mtslocale @acucorrupt
+@c   qsort dup @acucorrupt
+@c    hol_entry_qcmp @mtslocale
+@c     hol_entry_cmp @mtslocale
+@c      group_cmp ok
+@c      hol_cluster_cmp ok
+@c       group_cmp ok
+@c      hol_entry_first_short @mtslocale
+@c       hol_entry_short_iterate [@mtslocale]
+@c        until_short ok
+@c         oshort ok
+@c          isprint ok
+@c      odoc ok
+@c      hol_entry_first_long ok
+@c      canon_doc_option @mtslocale
+@c      tolower dup
+@c  hol_usage @mtslocale @ascuintl @ascuheap @acsmem
+@c   hol_entry_short_iterate ok
+@c    add_argless_short_opt ok
+@c   argp_fmtstream_printf dup
+@c   hol_entry_short_iterate @mtslocale @ascuintl @ascuheap @acsmem
+@c    usage_argful_short_opt @mtslocale @ascuintl @ascuheap @acsmem
+@c     dgettext dup
+@c     argp_fmtstream_printf dup
+@c   hol_entry_long_iterate @mtslocale @ascuintl @ascuheap @acsmem
+@c    usage_long_opt @mtslocale @ascuintl @ascuheap @acsmem
+@c     dgettext dup
+@c     argp_fmtstream_printf dup
+@c  hol_help @mtslocale @mturace (uparams), @ascuheap @ascuintl @asucorrupt @acsmem @acucorrupt @aculock
+@c   hol_entry_help @mtslocale @mturace (uparams), @ascuheap @ascuintl @asucorrupt @acsmem @acucorrupt @aculock
+@c    argp_fmtstream_set_lmargin dup
+@c    argp_fmtstream_wmargin dup
+@c    argp_fmtstream_set_wmargin dup
+@c    comma @mtslocale @ascuheap @ascuintl @asucorrupt @acsmem @acucorrupt @aculock
+@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 @mtslocale @ascuheap @acsmem
+@c     argp_fmtstream_printf dup
+@c    odoc dup
+@c    argp_fmtstream_puts dup
+@c    argp_fmtstream_printf dup
+@c    print_header @mtslocale @mturace (uparams), @ascuheap @ascuintl @asucorrupt @acsmem @acucorrupt @aculock
+@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 @mtslocale @ascuheap @asucorrupt @acsmem @acucorrupt @aculock
+@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 @ascuheap @acsmem
+@c   free dup
+@c  argp_args_levels ok
+@c  argp_args_usage @mtslocale @ascuintl @ascuheap @asucorrupt @acsmem @acucorrupt @aculock
+@c   dgettext dup
+@c   filter_doc ok
+@c    argp_input ok
+@c    argp->help_filter
+@c   space @mtslocale @ascuheap @asucorrupt @acsmem @acucorrupt @aculock
+@c    argp_fmtstream_point dup
+@c    argp_fmtstream_rmargin @mtslocale @asucorrupt @acucorrupt @aculock
+@c     argp_fmtstream_update dup
+@c    argp_fmtstream_putc dup
+@c   argp_fmtstream_write dup
+@c   free dup
+@c  argp_doc @mtslocale @ascuheap @ascuintl @asucorrupt @acsmem @acucorrupt @aculock
+@c   dgettext @ascuintl
+@c   strndup @ascuheap @acsmem
+@c   argp_input dup
+@c   argp->help_filter
+@c   argp_fmtstream_putc @mtslocale @ascuheap @asucorrupt @acsmem @acucorrupt @aculock
+@c    argp_fmtstream_ensure dup
+@c   argp_fmtstream_write dup
+@c   argp_fmtstream_puts dup
+@c   argp_fmtstream_point @mtslocale @asucorrupt @acucorrupt @aculock
+@c    argp_fmtstream_update dup
+@c   argp_fmtstream_lmargin dup
+@c   free dup
+@c  argp_make_fmtstream @ascuheap @acsmem
+@c  argp_fmtstream_free @mtslocale @ascuheap @asucorrupt @acsmem @acucorrupt @aculock
+@c   argp_fmtstream_update @mtslocale @asucorrupt @acucorrupt @aculock
+@c    put[w]c_unlocked dup
+@c    isblank in loop @mtslocale
+@c    fxprintf @aculock
+@c   fxprintf @aculock
+@c   free dup
+@c  argp_fmtstream_set_wmargin @mtslocale @asucorrupt @acucorrupt @aculock
+@c   argp_fmtstream_update dup
+@c  argp_fmtstream_printf @mtslocale @ascuheap @acsmem
+@c   argp_fmtstream_ensure dup
+@c   vsnprintf dup
+@c  argp_fmtstream_set_lmargin @mtslocale @asucorrupt @acucorrupt @aculock
+@c   argp_fmtstream_update dup
+@c  argp_fmtstream_puts @mtslocale @ascuheap @asucorrupt @acsmem @acucorrupt @aculock
+@c   argp_fmtstream_write @mtslocale @ascuheap @asucorrupt @acsmem @acucorrupt @aculock
+@c    argp_fmtstream_ensure @mtslocale @ascuheap @asucorrupt @acsmem @acucorrupt @aculock
+@c     argp_fmtstream_update dup
+@c     fxprintf @aculock
+@c     realloc @ascuheap @acsmem
 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{@prelim{}@mtunsafe{@mtasurace{} @mtsenv{} @mtslocale{}}@asunsafe{@ascuheap{} @ascuintl{} @asucorrupt{}}@acunsafe{@acsmem{} @acucorrupt{} @aculock{}}}
+@c Just calls _help.
 This outputs a help message for the argp parser @var{argp} to
 @var{stream}.  The type of messages printed will be determined by
 @var{flags}.

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

commit 20d1c4d9fad66814306c3552e51d0a7ea32775fa
Author: Alexandre Oliva <aoliva@redhat.com>
Date:   Sat Jan 4 03:08:08 2014 -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/NEWS b/NEWS
index 7757c32..b20097c 100644
--- a/NEWS
+++ b/NEWS
@@ -114,6 +114,9 @@ Version 2.19
 * The _BSD_SOURCE feature test macro no longer enables BSD interfaces that
   conflict with POSIX.  The libbsd-compat library (which was a dummy library
   that did nothing) has also been removed.
+
+* Preliminary documentation about Multi-Thread, Async-Signal and
+  Async-Cancel Safety has been added.
 
 Version 2.18
 
diff --git a/manual/intro.texi b/manual/intro.texi
index deaf089..55234cc 100644
--- a/manual/intro.texi
+++ b/manual/intro.texi
@@ -159,6 +159,15 @@ Utilities standard} (POSIX.2) are also implemented in @theglibc{}.
 These include utilities for dealing with regular expressions and other
 pattern matching facilities (@pxref{Pattern Matching}).
 
+@menu
+* POSIX Safety Concepts::       Safety concepts from POSIX.
+* Unconditional Unsafety::      Features that make functions
+                                 unconditionally unsafe.
+* Avoidable Unsafety::          Features that make functions unsafe,
+                                 but that can be worked around.
+* Other Safety Remarks::        Additional safety features and remarks.
+@end menu
+
 @comment Roland sez:
 @comment The GNU C library as it stands conforms to 1003.2 draft 11, which
 @comment specifies:
@@ -172,6 +181,628 @@ pattern matching facilities (@pxref{Pattern Matching}).
 @comment <wordexp.h> (not yet implemented)
 @comment confstr
 
+@node POSIX Safety Concepts, Unconditional Unsafety, , POSIX
+@subsubsection POSIX Safety Concepts
+@cindex POSIX Safety Concepts
+
+This manual documents various safety properties of @glibcadj{}
+functions, in lines that follow their prototypess and look like:
+
+@sampsafety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+
+The properties are assessed according to the criteria set forth in the
+POSIX standard for such safety contexts as 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
+@cindex Thread-Safe
+
+MT-Safe or Thread-Safe functions are safe to call in the presence of
+other threads.  MT, in MT-Safe, stands for Multi Thread.
+
+Being MT-Safe does not imply a function is atomic, nor that it uses any
+of the memory synchronization mechanisms POSIX exposes to users.  It is
+even possible that calling MT-Safe functions in sequence does not yield
+an MT-Safe combination.  For example, having a thread call two MT-Safe
+functions one right after the other does not guarantee behavior
+equivalent to atomic execution of a combination of both functions, since
+concurrent calls in other threads may interfere in a destructive way.
+
+In some cases, even expanding MT-Safe functions inline could cause
+combinations to become MT-Unsafe due to reordering that this could
+enable; this is never the case of @glibcadj{} functions defined in
+user-visible headers, because these are meant to be inlined, but it may
+be for functions that are exported by @glibcadj{} shared libraries;
+whole-program optimizations that might inline functions across library
+interfaces might expose this sort of problem, so performing inlining
+across the @glibcadj{} interface is not recommended, nor is the
+documented MT-Safety status guaranteed under such arrangements.
+
+
+@item
+@cindex AS-Safe
+@cindex Async-Signal-Safe
+
+AS-Safe or Async-Signal-Safe functions are safe to call from
+asynchronous signal handlers.  AS, in AS-Safe, stands for Asynchronous
+Signal.
+
+Many functions that are AS-Safe may set @code{errno}, or modify the
+floating-point environment, because their doing so does not make them
+unsuitable for use in signal handlers.  However, programs could
+misbehave should asynchronous signal handlers modify this thread-local
+state, and the signal handling machinery cannot be counted on to
+preserve it.  Therefore, signal handlers that call functions that may
+set @code{errno} or modify the floating-point environment @emph{must}
+save their original values, and restore them before returning.
+
+
+@item
+@cindex AC-Safe
+@cindex Async-Cancel-Safe
+
+AC-Safe or Async-Cancel-Safe functions are safe to call when
+asynchronous cancellation is enabled.  AC in AC-Safe stands for
+Asynchronous Cancellation.
+
+@item
+@cindex MT-Unsafe
+@cindex Thread-Unsafe
+@cindex AS-Unsafe
+@cindex Async-Signal-Unsafe
+@cindex AC-Unsafe
+@cindex Async-Cancel-Unsafe
+
+MT-Unsafe, AS-Unsafe, AC-Unsafe functions are not safe to call within
+the safety contexts described above.  Calling them within such contexts
+invokes undefined behavior.
+
+Functions not explicitly documented as Safe in a safety context should
+be regarded as Unsafe.
+
+
+@item
+@cindex Preliminary
+
+Preliminary safety properties are documented, indicating these
+properties may @emph{not} be counted on in future releases of
+@theglibc{}.
+
+Such preliminary properties are the result of an assessment of the
+properties of our current implementation, rather than of what is
+mandated and permitted by current and future standards.
+
+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.  The latter are most likely bugs; the former, when marked
+as @code{Preliminary}, should not be counted on: future standards may
+require changes that are not compatible with the additional safety
+properties afforded by the current implementation.
+
+Furthermore, the POSIX standard does not offer a detailed definition of
+safety.  We assume that, by ``safe to call'', POSIX means that, as long
+as the program does not invoke undefined behavior, the ``safe to call''
+function behaves as specified, and does not cause other functions to
+deviate from their specified behavior.  We have chosen to use its loose
+definitions of safety, not because they are the best definitions to use,
+but because choosing them harmonizes this manual with POSIX.
+
+Please keep in mind that these are preliminary definitions and
+annotations, and certain aspects of the definitions are still under
+discussion and might be subject to clarification or change.
+
+Over time, we envision evolving the preliminary safety notes into stable
+commitments, as stable as those of our interfaces.  As we do, we will
+remove the @code{Preliminary} keyword from safety notes.  As long as the
+keyword remains, however, they are not to be regarded as a promise of
+future behavior.
+
+
+@end itemize
+
+Other keywords that appear in safety notes are defined in subsequent
+sections.
+
+
+@node Unconditional Unsafety, Avoidable Unsafety, POSIX Safety Concepts, POSIX
+@subsubsection Unconditional Unsafety
+@cindex Unconditional Unsafety
+
+Functions that are unsafe to call in certain contexts are annotated with
+keywords that document their features that make them unsafe to call.
+AS-Unsafe features in this section indicate the functions are never safe
+to call when asynchronous signals are enabled; AC-Unsafe ones indicate
+they are never safe to call when asynchronous cancellation is enabled.
+There are no MT-Unsafe marks in this section.
+
+@itemize @bullet
+
+@item @code{lock}
+@cindex lock
+
+Functions marked with @code{lock} as an AS-Unsafe feature may be
+interrupted by a signal while holding a non-recursive lock.  If the
+signal handler calls another such function that takes the same lock, the
+result is a deadlock.
+
+Functions annotated with @code{lock} as an AC-Unsafe feature may, if
+cancelled asynchronously, fail to release a lock that would have been
+released if their execution had not been interrupted by asynchronous
+thread cancellation.  Once a lock is left taken, attempts to take that
+lock will block indefinitely.
+
+
+@item @code{corrupt}
+@cindex corrupt
+
+Functions marked with @code{corrupt} as an AS-Unsafe feature may corrupt
+data structures and misbehave when they interrupt, or are interrupted
+by, another such function.  Unlike functions marked with @code{lock},
+these take recursive locks to avoid MT-Safety problems, but this is not
+enough to stop a signal handler from observing a partially-updated data
+structure.  Further corruption may arise from the interrupted function's
+failure to notice updates made by signal handlers.
+
+Functions marked with @code{corrupt} as an AC-Unsafe feature may leave
+data structures in a corrupt, partially updated state.  Subsequent uses
+of the data structure may misbehave.
+
+@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 leak by resetting the pointer before
+@c releasing it; I don't think we have any case that calls for this sort
+@c of fixing.  Fixing the realloc cases would require a new interface:
+@c instead of @code{ptr=realloc(ptr,size)} we'd have to introduce
+@c @code{acsafe_realloc(&ptr,size)} that would modify ptr before
+@c releasing the old memory.  The ac-unsafe realloc could be implemented
+@c in terms of an internal interface with this semantics (say
+@c __acsafe_realloc), but since realloc can be overridden, the function
+@c we call to implement realloc should not be this internal interface,
+@c but another internal interface that calls __acsafe_realloc if realloc
+@c was not overridden, and calls the overridden realloc with async
+@c cancel disabled.  --lxoliva
+
+
+@item @code{heap}
+@cindex heap
+
+Functions marked with @code{heap} may call heap memory management
+functions in the @code{malloc}/@code{free} family, which brings in their
+safety issues.  This note is thus equivalent to:
+
+@sampsafety{@asunsafe{@asulock{}}@acunsafe{@aculock{} @acsfd{} @acsmem{}}}
+
+
+@c Check for cases that should have used plugin instead of or in
+@c addition to this.  Then, after rechecking gettext, adjust i18n if
+@c needed.
+@item @code{dlopen}
+@cindex dlopen
+
+Functions marked with @code{dlopen} 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; the safety documentation of @code{dlopen}, when
+available, shall list all the keywords implied by this one.
+
+@c dlopen runs init and fini sections of the module; does this mean
+@c dlopen always implies plugin?
+
+
+@item @code{plugin}
+@cindex plugin
+
+Functions annotated with @code{plugin} may run code from plugins that
+may be external to @theglibc{}.  Such plugin functions are assumed to be
+MT-Safe, AS-Unsafe and AC-Unsafe.  Examples of such plugins are stack
+unwinding libraries and nss back-ends.
+
+Although the plugins mentioned as examples are all brought in by means
+of dlopen, the @code{plugin} keyword does not imply any direct
+involvement of the dynamic loader or the @code{libdl} interfaces: those
+are covered by @code{dlopen}.  For example, if one function loads a
+module and finds the addresses of some of its functions, while another
+just calls those already-resolved functions, the former will be marked
+with @code{dlopen}, whereas the latter will get the @code{plugin}.  When
+a single function takes all of these actions, then it gets both marks.
+
+
+@item @code{i18n}
+@cindex i18n
+
+Functions marked with @code{i18n} may call internationalization
+functions of the @code{gettext} family, which brings in their safety
+issues.  This note is thus equivalent to:
+
+@sampsafety{@mtsafe{@mtsenv{}}@asunsafe{@asucorrupt{} @ascuheap{} @ascudlopen{}}@acunsafe{@acucorrupt{}}}
+
+
+@item @code{timer}
+@cindex timer
+
+Functions marked with @code{timer} 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 and thus disabling the time-out.
+
+
+@end itemize
+
+
+@node Avoidable Unsafety, Other Safety Remarks, Unconditional Unsafety, POSIX
+@subsubsection Avoidable Unsafety
+@cindex Avoidable Unsafety
+
+For some features that make functions unsafe to call in certain
+contexts, there are known ways to avoid the safety problem other than
+refraining from calling the function altogether.  The keywords that
+follow refer to such features, and each of their definitions indicate
+how the whole program needs to be constrained in order to remove the
+safety problem indicated by the keyword.  Only when all the reasons that
+make a function unsafe are observed and addressed by applying the
+documented constraints does the function become safe to call in a
+context.
+
+@itemize @bullet
+
+@item @code{init}
+@cindex init
+
+Functions marked with @code{init} as an MT-Unsafe feature 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.
+
+Functions marked with @code{init} as an AS- or AC-Unsafe feature 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{init} as an
+AS- or AC-Unsafe feature 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.
+
+@c We may have to extend the annotations to cover conditions in which
+@c initialization may or may not occur, since an initial call in a safe
+@c context is no use if the initialization doesn't take place at that
+@c time: it doesn't remove the risk for later calls.
+
+
+@item @code{race}
+@cindex race
+
+Functions annotated with @code{race} as an MT-Safety issue operate on
+objects in ways that may cause data races or similar forms of
+destructive interference out of concurrent execution.  In some cases,
+the objects are passed to the functions by users; in others, they are
+used by the functions to return values to users; in others, they are not
+even exposed to users.
+
+When the objects are passed by users, in some cases there might be
+uncertainty as to whether the library takes care of synchronization on
+its own, or whether callers are responsible for it.  We draw the line
+for objects passed by usersas follows: objects whose types are exposed
+to callers, and that callers are expected to access directly, such as
+memory buffers, strings, and various non-opaque structs, are @emph{not}
+annotated with @code{race}, because it would be noisy and redundant with
+the general requirement that users guard against data races.  As for
+objects that are only to be manipulated by passing them to library
+functions, there might be an expectation that the library will take care
+of synchronization on its own, as it does for e.g. @code{FILE} streams;
+when this expectation is not met because synchronization is entirely up
+to callers, for example in the case of @code{obstacks}, we will annotate
+functions that take such arguments with @code{race}, followed by a colon
+and the argument name.  We will not, however, regard such functions as
+MT-Unsafe for this reason; the notion that users are expected to
+safeguard from data races objects under their control prevail.
+
+@c The above describes @mtsrace; @mtasurace is described below.
+
+This user responsibility does not apply, however, to objects controlled
+by the library itself, such as internal objects and static buffers used
+to return values from certain calls.  When the library doesn't guard
+them against concurrent uses, these cases are regarded as MT-Unsafe and
+AS-Unsafe (although the @code{race} mark under AS-Unsafe will be omitted
+as redundant with the one under MT-Unsafe).  As in the case of
+user-exposed objects, the mark may be followed by a colon and an
+identifier.  The identifier groups all functions that operate on a
+certain unguarded object; users may avoid the MT-Safety issues related
+with unguarded concurrent access to such internal objects by creating a
+non-recursive mutex related with the identifier, and always holding the
+mutex when calling any function marked as racy on that identifier, as
+they would have to should the identifier be an object under user
+control.  The non-recursive mutex avoids the MT-Safety issue, but it
+trades one AS-Safety issue for another, so use in asynchronous signals
+remains undefined.
+
+When the identifier relates with a static buffer used to hold return
+values, the mutex must be held for as long as the buffer remains in use
+by the caller.  Many functions that return pointers to static buffers
+offer reentrant variants that store return values in caller-supplied
+buffers instead.  In some cases, such as @code{tmpname}, the variant is
+chosen not by calling an alternate entry point, but by passing a
+non-@code{NULL} pointer to the buffer in which the returned values are
+to be stored.  These variants are generally preferable in multi-threaded
+programs, although some of them are not MT-Safe because of other
+internal buffers, also documented with @code{race} notes.
+
+
+@item @code{const}
+@cindex const
+
+Functions marked with @code{const} as an MT-Safety issue modify
+non-atomically internal objects that are better regarded as constant,
+because a substantial portion of @theglibc{} accesses them without
+synchronization.  Unlike @code{race}, that causes both readers and
+writers of internal objects to be regarded as MT-Unsafe and AS-Unsafe,
+this mark is applied to writers only.  Writers remain equally MT- and
+AS-Unsafe to call, but the then-mandatory constness of objects they
+modify enables readers to be regarded as MT-Safe and AS-Safe (as long as
+no other reasons for them to be unsafe remain), since the lack of
+synchronization is not a problem when the objects are effectively
+constant.
+
+The identifier that follows the @code{const} mark will appear by itself
+as a safety note in readers.  Programs that wish to work around this
+safety issue, so as to call writers, may use a non-recursve
+@code{rwlock} associated with the identifier, and guard @emph{all} calls
+to functions marked with @code{const} followed by the identifier with a
+write lock, and @emph{all} calls to functions marked with the identifier
+by itself with a read lock.  The non-recursive locking removes the
+MT-Safety problem, but it trades one AS-Safety problem for another, so
+use in asynchronous signals remains undefined.
+
+@c But what if, instead of marking modifiers with const:id and readers
+@c with just id, we marked writers with race:id and readers with ro:id?
+
+
+@c -> locale
+@c Unguarded users of the global locale object modified by @code{setlocale}
+@c are marked with @code{glocale}.
+
+@c -> env
+@c Unguarded users of the global environment are marked with
+@c @code{envromt}.
+
+@c -> race ?
+@c Unguarded users of the @code{printf} extension objects modified by
+@c @code{register_printf_function} are the entire family of printf
+@c functions.
+
+@c -> race ?
+@c Unguarded users of file streams configured with @code{__fsetlocking} for
+@c locking by the caller are the entire family of stdio functions.
+
+
+@item @code{sig}
+@cindex sig
+
+Functions marked with @code{sig} as a MT-Safety issue (that implies an
+identical AS-Safety issue, omitted for brevity) may temporarily install
+a signal handler for internal purposes, which may interfere with other
+uses of the signal, identified after a colon.
+
+This safety problem can be worked around by ensuring that no other uses
+of the signal will take place for the duration of the call.  Holding a
+non-recursive mutex while calling all functions that use the same
+temporary signal; blocking that signal before the call and resetting its
+handler afterwards is recommended.
+
+In functions marked with @code{sig} also as an AC-Safety issue, the
+problem is more complex: the temporarily-installed signal handler may
+remain configured and enabled for the whole process if the thread is
+cancelled, even synchronously.
+
+@c fixme: at least sync cancellation should get it right, and would
+@c obviate the restoring bit below, and the qualifier above.
+
+Besides the measures recommended to work around the MT- and AS-Safety
+problem, in order to avert the cancellation problem, disabling
+asynchronous cancellation @emph{and} installing a cleanup handler to
+restores the signal to the desired state and to release the mutex are
+recommended.
+
+
+@item @code{term}
+@cindex term
+
+Functions marked with @code{term} as an MT-Safety issue may change the
+terminal settings in the recommended way, namely, call @code{tcgetattr},
+modify some flags, and then call @code{tcsetattr}.  Because this creates
+a window in which changes made by other threads are lost, functions
+marked with @code{term} are MT-Unsafe; because this same window enables
+changes made by asynchronous signals to be lost, these functions are
+also AS-Unsafe, but the corresponding mark is omitted as redundant.
+
+It is thus advisable for applications using the terminal to avoid
+concurrent and reentrant interactions with it, by not using it in signal
+handlers or blocking signals that might use it, and holding a lock while
+calling these functions and interacting with the terminal.
+
+Functions marked with @code{term} as an AC-Safety issue are supposed to
+restore terminal settings to their original state, after temporarily
+changing them, but they may fail to do so if cancelled, even
+synchronously.
+
+@c fixme: at least sync cancellation should get it right, and would
+@c obviate the restoring bit below, and the qualifier above.
+
+Besides the measures recommended to work around the MT- and AS-Safety
+problem, in order to avert the cancellation problem, disabling
+asynchronous cancellation @emph{and} installing a cleanup handler to
+restores the terminal settings to the original state and to release the
+mutex are recommended.
+
+
+@end itemize
+
+
+@node Other Safety Remarks, , Avoidable Unsafety, POSIX
+@subsubsection Other Safety Remarks
+@cindex Other Safety Remarks
+
+Additional keywords may be attached to functions, indicating features
+that do not make a function unsafe to call, but that may need to be
+taken into account in certain classes of programs:
+
+@itemize @bullet
+
+@c revisit: uses are mt-safe, distinguish from const:locale
+@item @code{locale}
+@cindex locale
+
+Functions annotated with @code{locale} as an MT-Safety issue read from
+the locale object without any form of synchronization.  Functions
+annotated with @code{locale} called concurrently with locale changes may
+behave in ways that do not correspond to any of the locales active
+during their execution, but an unpredictable mix thereof.
+
+We do not mark these functions as MT- or AS-Unsafe, however, because
+functions that modify the locale object are marked with
+@code{const:locale} and regarded as unsafe.  Being unsafe, the latter
+are not to be called when multiple threads are running or asynchronous
+signals are enabled, and so the locale can be considered effectively
+constant in these contexts, which makes the former safe.
+
+@c Should the following be mentioned in the manual at all?
+
+@c Should the locking strategy suggested under @code{const} be used,
+@c failure to guard locale uses is not as fatal as data races in
+@c general: unguarded uses will @emph{not} follow dangling pointers or
+@c access uninitialized, unmapped or recycled memory.  Each access will
+@c read from a consistent locale object that is or was active at some
+@c point during its execution.  Without synchronization, however, it
+@c cannot even be assumed that, after a change in locale, earlier
+@c locales will no longer be used, even after the newly-chosen one is
+@c used in the thread.  Nevertheless, even though unguarded reads from
+@c the locale will not violate type safety, functions that access the
+@c locale multiple times may invoke all sorts of undefined behavior
+@c because of the unexpected locale changes.
+
+
+@c revisit: this was incorrectly used as an mt-unsafe marker.
+@item @code{env}
+@cindex env
+
+Functions marked with @code{env} as an MT-Safety issue access the
+environment with @code{getenv} or similar, without any guards to ensure
+safety in the presence of concurrent modifications.
+
+We do not mark these functions as MT- or AS-Unsafe, however, because
+functions that modify the environment are all marked with
+@code{const:env} and regarded as unsafe.  Being unsafe, the latter are
+not to be called when multiple threads are running or asynchronous
+signals are enabled, and so the environment can be considered
+effectively constant in these contexts, which makes the former safe.
+
+
+@item @code{fd}
+@cindex fd
+
+Functions annotated with @code{fd} as an AC-Safety issue 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{mem}
+@cindex mem
+
+Functions annotated with @code{mem} as an AC-Safety issue 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{cwd}
+@cindex cwd
+
+Functions marked with @code{cwd} as an MT-Safety issue 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- or
+AS-Unsafe, but when this behavior is optional (e.g., @code{nftw} with
+@code{FTW_CHDIR}), avoiding the option may be a good alternative to
+using full pathnames or file descriptor-relative (e.g. @code{openat})
+system calls.
+
+
+@item @code{posix}
+@cindex posix
+
+This remark, as an MT-, AS- or AC-Safety note to a function, indicates
+the safety status of the function is known to differ from the specified
+status in the POSIX standard.  For example, POSIX does not require a
+function to be Safe, but our implementation is, 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..7b3b0f9 100644
--- a/manual/macros.texi
+++ b/manual/macros.texi
@@ -47,4 +47,154 @@ GNU/Hurd systems
 GNU/Linux systems
 @end macro
 
+@c Document the safety functions as preliminary.  It does NOT expand its
+@c comments.
+@macro prelim {comments}
+| Preliminary
+
+@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 safety properties without referencing the section of the
+@c definitions.  To be used in the definitions of the properties
+@c themselves.
+@macro sampsafety {notes}
+@noindent
+\notes\|
+
+
+@end macro
+@c Format the safety properties of a function.
+@macro safety {notes}
+\notes\| @xref{POSIX Safety Concepts}.
+
+
+@end macro
+@macro mtasurace {comments}
+race\comments\
+@end macro
+@macro mtsrace {comments}
+race\comments\
+@end macro
+@macro mtasuconst {comments}
+const\comments\
+@end macro
+@macro mtslocale {comments}
+locale\comments\
+@end macro
+@macro mtsenv {comments}
+env\comments\
+@end macro
+@macro mtuinit {comments}
+init\comments\
+@end macro
+@macro asuinit {comments}
+init\comments\
+@end macro
+@macro acuinit {comments}
+init\comments\
+@end macro
+@macro asulock {comments}
+lock\comments\
+@end macro
+@macro aculock {comments}
+lock\comments\
+@end macro
+@macro asucorrupt {comments}
+corrupt\comments\
+@end macro
+@macro acucorrupt {comments}
+corrupt\comments\
+@end macro
+@macro ascuheap {comments}
+heap\comments\
+@end macro
+@macro ascudlopen {comments}
+dlopen\comments\
+@end macro
+@macro ascuplugin {comments}
+plugin\comments\
+@end macro
+@macro ascuintl {comments}
+i18n\comments\
+@end macro
+@macro acsfd {comments}
+fd\comments\
+@end macro
+@macro acsmem {comments}
+mem\comments\
+@end macro
+@macro mtasusig {comments}
+sig\comments\
+@end macro
+@macro acusig {comments}
+sig\comments\
+@end macro
+@macro mtasuterm {comments}
+term\comments\
+@end macro
+@macro acuterm {comments}
+term\comments\
+@end macro
+@macro mtutimer {comments}
+timer\comments\
+@end macro
+@macro mtasscwd {comments}
+cwd\comments\
+@end macro
+@macro acscwd {comments}
+cwd\comments\
+@end macro
+@macro mtsposix {comments}
+posix\comments\
+@end macro
+@macro mtuposix {comments}
+posix\comments\
+@end macro
+@macro assposix {comments}
+posix\comments\
+@end macro
+@macro asuposix {comments}
+posix\comments\
+@end macro
+@macro acsposix {comments}
+posix\comments\
+@end macro
+@macro acuposix {comments}
+posix\comments\
+@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]