* manual/stdio.texi: Document MTASC-safety properties.
[jlayton/glibc.git] / manual / stdio.texi
index 3449a51d2b6414a7fcbc9cf4426eac225a2fecc6..1161a9a90a60d844372c02f574a16ad5c5d49dc7 100644 (file)
@@ -14,9 +14,11 @@ representing a communications channel to a file, device, or process.
 @menu
 * Streams::                     About the data type representing a stream.
 * Standard Streams::            Streams to the standard input and output
-                                 devices are created for you.
+                                devices are created for you.
 * Opening Streams::             How to create a stream to talk to a file.
 * Closing Streams::             Close a stream when you are finished with it.
+* Streams and Threads::         Issues with streams in threaded programs.
+* Streams and I18N::            Streams in internationalized applications.
 * Simple Output::               Unformatted output by characters and lines.
 * Character Input::             Unformatted input by characters and words.
 * Line Input::                  Reading a line or a record from a stream.
@@ -24,16 +26,17 @@ representing a communications channel to a file, device, or process.
 * Block Input/Output::          Input and output operations on blocks of data.
 * Formatted Output::            @code{printf} and related functions.
 * Customizing Printf::          You can define new conversion specifiers for
-                                 @code{printf} and friends.
+                                @code{printf} and friends.
 * Formatted Input::             @code{scanf} and related functions.
 * EOF and Errors::              How you can tell if an I/O error happens.
+* Error Recovery::             What you can do about errors.
 * Binary Streams::              Some systems distinguish between text files
-                                 and binary files.
+                                and binary files.
 * File Positioning::            About random-access streams.
 * Portable Positioning::        Random access on peculiar ISO C systems.
 * Stream Buffering::            How to control buffering of streams.
 * Other Kinds of Streams::      Streams that do not necessarily correspond
-                                 to an open file.
+                                to an open file.
 * Formatted Messages::          Print strictly formatted messages.
 @end menu
 
@@ -107,15 +110,15 @@ diagnostics issued by the program.
 @end deftypevar
 @cindex standard error stream
 
-In the GNU system, you can specify what files or processes correspond to
+On @gnusystems{}, you can specify what files or processes correspond to
 these streams using the pipe and redirection facilities provided by the
 shell.  (The primitives shells use to implement these facilities are
 described in @ref{File System Interface}.)  Most other operating systems
 provide similar mechanisms, but the details of how to use them can vary.
 
-In the GNU C library, @code{stdin}, @code{stdout}, and @code{stderr} are
-normal variables which you can set just like any others.  For example, to redirect
-the standard output to a file, you could do:
+In @theglibc{}, @code{stdin}, @code{stdout}, and @code{stderr} are
+normal variables which you can set just like any others.  For example,
+to redirect the standard output to a file, you could do:
 
 @smallexample
 fclose (stdout);
@@ -127,6 +130,9 @@ Note however, that in other systems @code{stdin}, @code{stdout}, and
 But you can use @code{freopen} to get the effect of closing one and
 reopening it.  @xref{Opening Streams}.
 
+The three streams @code{stdin}, @code{stdout}, and @code{stderr} are not
+unoriented at program start (@pxref{Streams and I18N}).
+
 @node Opening Streams
 @section Opening Streams
 
@@ -142,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.
 
@@ -180,39 +188,70 @@ but output is always appended to the end of the file.
 @end table
 
 As you can see, @samp{+} requests a stream that can do both input and
-output.  The ISO standard says that when using such a stream, you must
-call @code{fflush} (@pxref{Stream Buffering}) or a file positioning
-function such as @code{fseek} (@pxref{File Positioning}) when switching
-from reading to writing or vice versa.  Otherwise, internal buffers
-might not be emptied properly.  The GNU C library does not have this
-limitation; you can do arbitrary reading and writing operations on a
-stream in whatever order.
+output.  When using such a stream, you must call @code{fflush}
+(@pxref{Stream Buffering}) or a file positioning function such as
+@code{fseek} (@pxref{File Positioning}) when switching from reading
+to writing or vice versa.  Otherwise, internal buffers might not be
+emptied properly.
 
 Additional characters may appear after these to specify flags for the
 call.  Always put the mode (@samp{r}, @samp{w+}, etc.) first; that is
 the only part you are guaranteed will be understood by all systems.
 
-The GNU C library defines one additional character for use in
-@var{opentype}: the character @samp{x} insists on creating a new
-file---if a file @var{filename} already exists, @code{fopen} fails
-rather than opening it.  If you use @samp{x} you can are guaranteed that
-you will not clobber an existing file.  This is equivalent to the
-@code{O_EXCL} option to the @code{open} function (@pxref{Opening and
-Closing Files}).
+@Theglibc{} defines additional characters for use in @var{opentype}:
+
+@table @samp
+@item c
+The file is opened with cancellation in the I/O functions disabled.
+
+@item e
+The underlying file descriptor will be closed if you use any of the
+@code{exec@dots{}} functions (@pxref{Executing a File}).  (This is
+equivalent to having set @code{FD_CLOEXEC} on that descriptor.
+@xref{Descriptor Flags}.)
+
+@item m
+The file is opened and accessed using @code{mmap}.  This is only
+supported with files opened for reading.
+
+@item x
+Insist on creating a new file---if a file @var{filename} already
+exists, @code{fopen} fails rather than opening it.  If you use
+@samp{x} you are guaranteed that you will not clobber an existing
+file.  This is equivalent to the @code{O_EXCL} option to the
+@code{open} function (@pxref{Opening and Closing Files}).
+
+The @samp{x} modifier is part of @w{ISO C11}.
+@end table
 
 The character @samp{b} in @var{opentype} has a standard meaning; it
 requests a binary stream rather than a text stream.  But this makes no
-difference in POSIX systems (including the GNU system).  If both
+difference in POSIX systems (including @gnusystems{}).  If both
 @samp{+} and @samp{b} are specified, they can appear in either order.
 @xref{Binary Streams}.
 
+@cindex stream orientation
+@cindex orientation, stream
+If the @var{opentype} string contains the sequence
+@code{,ccs=@var{STRING}} then @var{STRING} is taken as the name of a
+coded character set and @code{fopen} will mark the stream as
+wide-oriented with appropriate conversion functions in place to convert
+from and to the character set @var{STRING}.  Any other stream
+is opened initially unoriented and the orientation is decided with the
+first file operation.  If the first operation is a wide character
+operation, the stream is not only marked as wide-oriented, also the
+conversion functions to convert to the coded character set used for the
+current locale are loaded.  This will not change anymore from this point
+on even if the locale selected for the @code{LC_CTYPE} category is
+changed.
+
 Any other characters in @var{opentype} are simply ignored.  They may be
 meaningful in other systems.
 
 If the open fails, @code{fopen} returns a null pointer.
 
 When the sources are compiling with @code{_FILE_OFFSET_BITS == 64} on a
-32 bits machine this function is in fact @code{fopen64} since the LFS
+32 bit machine this function is in fact @code{fopen64} since the LFS
 interface replaces transparently the old interface.
 @end deftypefun
 
@@ -228,9 +267,10 @@ Locks}.
 @comment stdio.h
 @comment Unix98
 @deftypefun {FILE *} fopen64 (const char *@var{filename}, const char *@var{opentype})
+@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@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 then @math{2^31} bytes on 32 bits machines.
+used even on files larger than @math{2^31} bytes on 32 bit machines.
 
 Please note that the return type is still @code{FILE *}.  There is no
 special @code{FILE} type for the LFS interface.
@@ -257,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,
@@ -271,20 +321,21 @@ If the operation fails, a null pointer is returned; otherwise,
 @code{freopen} has traditionally been used to connect a standard stream
 such as @code{stdin} with a file of your own choice.  This is useful in
 programs in which use of a standard stream for certain purposes is
-hard-coded.  In the GNU C library, you can simply close the standard
+hard-coded.  In @theglibc{}, you can simply close the standard
 streams and open new ones with @code{fopen}.  But other systems lack
 this ability, so using @code{freopen} is more portable.
 
 When the sources are compiling with @code{_FILE_OFFSET_BITS == 64} on a
-32 bits machine this function is in fact @code{freopen64} since the LFS
+32 bit machine this function is in fact @code{freopen64} since the LFS
 interface replaces transparently the old interface.
 @end deftypefun
 
 @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 bits machine the stream returned is able to read beyond the
+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
 noted that the stream pointed to by @var{stream} need not be opened
 using @code{fopen64} or @code{freopen64} since its mode is not important
@@ -295,18 +346,89 @@ bits machine this function is available under the name @code{freopen}
 and so transparently replaces the old interface.
 @end deftypefun
 
+In some situations it is useful to know whether a given stream is
+available for reading or writing.  This information is normally not
+available and would have to be remembered separately.  Solaris
+introduced a few functions to get this information from the stream
+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.
+
+This function is declared in @file{stdio_ext.h}.
+@end deftypefun
+
+@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.
+
+This function is declared in @file{stdio_ext.h}.
+@end deftypefun
+
+For slightly different kind of problems there are two more functions.
+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.
+Determining whether a stream opened for reading and writing was last
+used for writing allows to draw conclusions about the content about the
+buffer, among other things.
+
+This function is declared in @file{stdio_ext.h}.
+@end deftypefun
+
+@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.
+
+This function is declared in @file{stdio_ext.h}.
+@end deftypefun
+
 
 @node Closing Streams
 @section Closing Streams
 
 @cindex closing a stream
 When a stream is closed with @code{fclose}, the connection between the
-stream and the file is cancelled.  After you have closed a stream, you
+stream and the file is canceled.  After you have closed a stream, you
 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
@@ -323,23 +445,29 @@ you are using NFS.
 The function @code{fclose} is declared in @file{stdio.h}.
 @end deftypefun
 
-To close all streams currently available the GNU C Library provides
+To close all streams currently available @theglibc{} provides
 another function.
 
 @comment stdio.h
 @comment GNU
 @deftypefun int fcloseall (void)
+@safety{@prelim{}@mtunsafe{@mtasurace{:streams}}@asunsafe{}@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}
 function returns a value of @code{0} if all the files were closed
 successfully, and @code{EOF} if an error was detected.
 
-This function should be used only in special situation, e.g., when an
+This function should be used only in special situations, e.g., when an
 error occurred and the program must be aborted.  Normally each single
-stream should be closed separately so that problems with one stream can
-be identified.  It is also problematic since the standard streams
-(@pxref{Standard Streams}) will also be closed.
+stream should be closed separately so that problems with individual
+streams can be identified.  It is also problematic since the standard
+streams (@pxref{Standard Streams}) will also be closed.
 
 The function @code{fcloseall} is declared in @file{stdio.h}.
 @end deftypefun
@@ -353,6 +481,378 @@ might not be closed properly.  Buffered output might not be flushed and
 files may be incomplete.  For more information on buffering of streams,
 see @ref{Stream Buffering}.
 
+@node Streams and Threads
+@section Streams and Threads
+
+@cindex threads
+@cindex multi-threaded application
+Streams can be used in multi-threaded applications in the same way they
+are used in single-threaded applications.  But the programmer must be
+aware of the possible complications.  It is important to know about
+these also if the program one writes never use threads since the design
+and implementation of many stream functions is heavily influenced by the
+requirements added by multi-threaded programming.
+
+The POSIX standard requires that by default the stream operations are
+atomic.  I.e., issuing two stream operations for the same stream in two
+threads at the same time will cause the operations to be executed as if
+they were issued sequentially.  The buffer operations performed while
+reading or writing are protected from other uses of the same stream.  To
+do this each stream has an internal lock object which has to be
+(implicitly) acquired before any work can be done.
+
+But there are situations where this is not enough and there are also
+situations where this is not wanted.  The implicit locking is not enough
+if the program requires more than one stream function call to happen
+atomically.  One example would be if an output line a program wants to
+generate is created by several function calls.  The functions by
+themselves would ensure only atomicity of their own operation, but not
+atomicity over all the function calls.  For this it is necessary to
+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
+implicit through a call of a stream function lock the stream.  The
+thread will block until the lock is acquired.  An explicit call to
+@code{funlockfile} has to be used to release the lock.
+@end deftypefun
+
+@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
+block if the lock is not available.  @code{ftrylockfile} returns zero if
+the lock was successfully acquired.  Otherwise the stream is locked by
+another thread.
+@end deftypefun
+
+@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}.
+The implicit locking performed by the stream operations do not count.
+The @code{funlockfile} function does not return an error status and the
+behavior of a call for a stream which is not locked by the current
+thread is undefined.
+@end deftypefun
+
+The following example shows how the functions above can be used to
+generate an output line atomically even in multi-threaded applications
+(yes, the same job could be done with one @code{fprintf} call but it is
+sometimes not possible):
+
+@smallexample
+FILE *fp;
+@{
+   @dots{}
+   flockfile (fp);
+   fputs ("This is test number ", fp);
+   fprintf (fp, "%d\n", test);
+   funlockfile (fp)
+@}
+@end smallexample
+
+Without the explicit locking it would be possible for another thread to
+use the stream @var{fp} after the @code{fputs} call return and before
+@code{fprintf} was called with the result that the number does not
+follow the word @samp{number}.
+
+From this description it might already be clear that the locking objects
+in streams are no simple mutexes.  Since locking the same stream twice
+in the same thread is allowed the locking objects must be equivalent to
+recursive mutexes.  These mutexes keep track of the owner and the number
+of times the lock is acquired.  The same number of @code{funlockfile}
+calls by the same threads is necessary to unlock the stream completely.
+For instance:
+
+@smallexample
+void
+foo (FILE *fp)
+@{
+  ftrylockfile (fp);
+  fputs ("in foo\n", fp);
+  /* @r{This is very wrong!!!}  */
+  funlockfile (fp);
+@}
+@end smallexample
+
+It is important here that the @code{funlockfile} function is only called
+if the @code{ftrylockfile} function succeeded in locking the stream.  It
+is therefore always wrong to ignore the result of @code{ftrylockfile}.
+And it makes no sense since otherwise one would use @code{flockfile}.
+The result of code like that above is that either @code{funlockfile}
+tries to free a stream that hasn't been locked by the current thread or it
+frees the stream prematurely.  The code should look like this:
+
+@smallexample
+void
+foo (FILE *fp)
+@{
+  if (ftrylockfile (fp) == 0)
+    @{
+      fputs ("in foo\n", fp);
+      funlockfile (fp);
+    @}
+@}
+@end smallexample
+
+Now that we covered why it is necessary to have these locking it is
+necessary to talk about situations when locking is unwanted and what can
+be done.  The locking operations (explicit or implicit) don't come for
+free.  Even if a lock is not taken the cost is not zero.  The operations
+which have to be performed require memory operations that are safe in
+multi-processor environments.  With the many local caches involved in
+such systems this is quite costly.  So it is best to avoid the locking
+completely if it is not needed -- because the code in question is never
+used in a context where two or more threads may use a stream at a time.
+This can be determined most of the time for application code; for
+library code which can be used in many contexts one should default to be
+conservative and use locking.
+
+There are two basic mechanisms to avoid locking.  The first is to use
+the @code{_unlocked} variants of the stream operations.  The POSIX
+standard defines quite a few of those and @theglibc{} adds a few
+more.  These variants of the functions behave just like the functions
+with the name without the suffix except that they do not lock the
+stream.  Using these functions is very desirable since they are
+potentially much faster.  This is not only because the locking
+operation itself is avoided.  More importantly, functions like
+@code{putc} and @code{getc} are very simple and traditionally (before the
+introduction of threads) were implemented as macros which are very fast
+if the buffer is not empty.  With the addition of locking requirements
+these functions are no longer implemented as macros since they would
+expand to too much code.
+But these macros are still available with the same functionality under the new
+names @code{putc_unlocked} and @code{getc_unlocked}.  This possibly huge
+difference of speed also suggests the use of the @code{_unlocked}
+functions even if locking is required.  The difference is that the
+locking then has to be performed in the program:
+
+@smallexample
+void
+foo (FILE *fp, char *buf)
+@{
+  flockfile (fp);
+  while (*buf != '/')
+    putc_unlocked (*buf++, fp);
+  funlockfile (fp);
+@}
+@end smallexample
+
+If in this example the @code{putc} function would be used and the
+explicit locking would be missing the @code{putc} function would have to
+acquire the lock in every call, potentially many times depending on when
+the loop terminates.  Writing it the way illustrated above allows the
+@code{putc_unlocked} macro to be used which means no locking and direct
+manipulation of the buffer of the stream.
+
+A second way to avoid locking is by using a non-standard function which
+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{}@mtsafe{@mtsrace{: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
+stream @var{stream}.  By default this is done but it can be disabled and
+reinstated using this function.  There are three values defined for the
+@var{type} parameter.
+
+@vtable @code
+@item FSETLOCKING_INTERNAL
+The stream @code{stream} will from now on use the default internal
+locking.  Every stream operation with exception of the @code{_unlocked}
+variants will implicitly lock the stream.
+
+@item FSETLOCKING_BYCALLER
+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
+@code{FSETLOCKING_INTERNAL}.
+
+@item FSETLOCKING_QUERY
+@code{__fsetlocking} only queries the current locking state of the
+stream.  The return value will be @code{FSETLOCKING_INTERNAL} or
+@code{FSETLOCKING_BYCALLER} depending on the state.
+@end vtable
+
+The return value of @code{__fsetlocking} is either
+@code{FSETLOCKING_INTERNAL} or @code{FSETLOCKING_BYCALLER} depending on
+the state of the stream before the call.
+
+This function and the values for the @var{type} parameter are declared
+in @file{stdio_ext.h}.
+@end deftypefun
+
+This function is especially useful when program code has to be used
+which is written without knowledge about the @code{_unlocked} functions
+(or if the programmer was too lazy to use them).
+
+@node Streams and I18N
+@section Streams in Internationalized Applications
+
+@w{ISO C90} introduced the new type @code{wchar_t} to allow handling
+larger character sets.  What was missing was a possibility to output
+strings of @code{wchar_t} directly.  One had to convert them into
+multibyte strings using @code{mbstowcs} (there was no @code{mbsrtowcs}
+yet) and then use the normal stream functions.  While this is doable it
+is very cumbersome since performing the conversions is not trivial and
+greatly increases program complexity and size.
+
+The Unix standard early on (I think in XPG4.2) introduced two additional
+format specifiers for the @code{printf} and @code{scanf} families of
+functions.  Printing and reading of single wide characters was made
+possible using the @code{%C} specifier and wide character strings can be
+handled with @code{%S}.  These modifiers behave just like @code{%c} and
+@code{%s} only that they expect the corresponding argument to have the
+wide character type and that the wide character and string are
+transformed into/from multibyte strings before being used.
+
+This was a beginning but it is still not good enough.  Not always is it
+desirable to use @code{printf} and @code{scanf}.  The other, smaller and
+faster functions cannot handle wide characters.  Second, it is not
+possible to have a format string for @code{printf} and @code{scanf}
+consisting of wide characters.  The result is that format strings would
+have to be generated if they have to contain non-basic characters.
+
+@cindex C++ streams
+@cindex streams, C++
+In the @w{Amendment 1} to @w{ISO C90} a whole new set of functions was
+added to solve the problem.  Most of the stream functions got a
+counterpart which take a wide character or wide character string instead
+of a character or string respectively.  The new functions operate on the
+same streams (like @code{stdout}).  This is different from the model of
+the C++ runtime library where separate streams for wide and normal I/O
+are used.
+
+@cindex orientation, stream
+@cindex stream orientation
+Being able to use the same stream for wide and normal operations comes
+with a restriction: a stream can be used either for wide operations or
+for normal operations.  Once it is decided there is no way back.  Only a
+call to @code{freopen} or @code{freopen64} can reset the
+@dfn{orientation}.  The orientation can be decided in three ways:
+
+@itemize @bullet
+@item
+If any of the normal character functions is used (this includes the
+@code{fread} and @code{fwrite} functions) the stream is marked as not
+wide oriented.
+
+@item
+If any of the wide character functions is used the stream is marked as
+wide oriented.
+
+@item
+The @code{fwide} function can be used to set the orientation either way.
+@end itemize
+
+It is important to never mix the use of wide and not wide operations on
+a stream.  There are no diagnostics issued.  The application behavior
+will simply be strange or the application will simply crash.  The
+@code{fwide} function can help avoiding this.
+
+@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
+a positive value the streams get wide oriented, for negative values
+narrow oriented.  It is not possible to overwrite previous orientations
+with @code{fwide}.  I.e., if the stream @var{stream} was already
+oriented before the call nothing is done.
+
+If @var{mode} is zero the current orientation state is queried and
+nothing is changed.
+
+The @code{fwide} function returns a negative value, zero, or a positive
+value if the stream is narrow, not at all, or wide oriented
+respectively.
+
+This function was introduced in @w{Amendment 1} to @w{ISO C90} and is
+declared in @file{wchar.h}.
+@end deftypefun
+
+It is generally a good idea to orient a stream as early as possible.
+This can prevent surprise especially for the standard streams
+@code{stdin}, @code{stdout}, and @code{stderr}.  If some library
+function in some situations uses one of these streams and this use
+orients the stream in a different way the rest of the application
+expects it one might end up with hard to reproduce errors.  Remember
+that no errors are signal if the streams are used incorrectly.  Leaving
+a stream unoriented after creation is normally only necessary for
+library functions which create streams which can be used in different
+contexts.
+
+When writing code which uses streams and which can be used in different
+contexts it is important to query the orientation of the stream before
+using it (unless the rules of the library interface demand a specific
+orientation).  The following little, silly function illustrates this.
+
+@smallexample
+void
+print_f (FILE *fp)
+@{
+  if (fwide (fp, 0) > 0)
+    /* @r{Positive return value means wide orientation.}  */
+    fputwc (L'f', fp);
+  else
+    fputc ('f', fp);
+@}
+@end smallexample
+
+Note that in this case the function @code{print_f} decides about the
+orientation of the stream if it was unoriented before (will not happen
+if the advise above is followed).
+
+The encoding used for the @code{wchar_t} values is unspecified and the
+user must not make any assumptions about it.  For I/O of @code{wchar_t}
+values this means that it is impossible to write these values directly
+to the stream.  This is not what follows from the @w{ISO C} locale model
+either.  What happens instead is that the bytes read from or written to
+the underlying media are first converted into the internal encoding
+chosen by the implementation for @code{wchar_t}.  The external encoding
+is determined by the @code{LC_CTYPE} category of the current locale or
+by the @samp{ccs} part of the mode specification given to @code{fopen},
+@code{fopen64}, @code{freopen}, or @code{freopen64}.  How and when the
+conversion happens is unspecified and it happens invisible to the user.
+
+Since a stream is created in the unoriented state it has at that point
+no conversion associated with it.  The conversion which will be used is
+determined by the @code{LC_CTYPE} category selected at the time the
+stream is oriented.  If the locales are changed at the runtime this
+might produce surprising results unless one pays attention.  This is
+just another good reason to orient the stream explicitly as soon as
+possible, perhaps with a call to @code{fwide}.
+
 @node Simple Output
 @section Simple Output by Characters or Lines
 
@@ -360,21 +860,64 @@ see @ref{Stream Buffering}.
 This section describes functions for performing character- and
 line-oriented output.
 
-These functions are declared in the header file @file{stdio.h}.
+These narrow streams functions are declared in the header file
+@file{stdio.h} and the wide stream functions in @file{wchar.h}.
 @pindex stdio.h
+@pindex wchar.h
 
 @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
 character @var{c} is returned.
 @end deftypefun
 
+@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.
+@end deftypefun
+
+@comment stdio.h
+@comment POSIX
+@deftypefun int fputc_unlocked (int @var{c}, FILE *@var{stream})
+@safety{@prelim{}@mtsafe{@mtsrace{: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
+
+@comment wchar.h
+@comment POSIX
+@deftypefun wint_t fputwc_unlocked (wchar_t @var{wc}, FILE *@var{stream})
+@safety{@prelim{}@mtsafe{@mtsrace{: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.
+
+This function is a GNU extension.
+@end deftypefun
+
 @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
@@ -382,16 +925,73 @@ general rule for macros.  @code{putc} is usually the best function to
 use for writing a single character.
 @end deftypefun
 
+@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
+general rule for macros.  @code{putwc} is usually the best function to
+use for writing a single wide character.
+@end deftypefun
+
+@comment stdio.h
+@comment POSIX
+@deftypefun int putc_unlocked (int @var{c}, FILE *@var{stream})
+@safety{@prelim{}@mtsafe{@mtsrace{: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
+
+@comment wchar.h
+@comment GNU
+@deftypefun wint_t putwc_unlocked (wchar_t @var{wc}, FILE *@var{stream})
+@safety{@prelim{}@mtsafe{@mtsrace{: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.
+
+This function is a GNU extension.
+@end deftypefun
+
 @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
 
+@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
+
+@comment stdio.h
+@comment POSIX
+@deftypefun int putchar_unlocked (int @var{c})
+@safety{@prelim{}@mtunsafe{@mtasurace{:stdout}}@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
+
+@comment wchar.h
+@comment GNU
+@deftypefun wint_t putwchar_unlocked (wchar_t @var{wc})
+@safety{@prelim{}@mtunsafe{@mtasurace{:stdout}}@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.
+
+This function is a GNU extension.
+@end deftypefun
+
 @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.
@@ -412,9 +1012,43 @@ fputs ("hungry?\n", stdout);
 outputs the text @samp{Are you hungry?} followed by a newline.
 @end deftypefun
 
+@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
+outputs only the characters in the string.
+
+This function returns @code{WEOF} if a write error occurs, and otherwise
+a non-negative value.
+@end deftypefun
+
+@comment stdio.h
+@comment GNU
+@deftypefun int fputs_unlocked (const char *@var{s}, FILE *@var{stream})
+@safety{@prelim{}@mtsafe{@mtsrace{: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.
+
+This function is a GNU extension.
+@end deftypefun
+
+@comment wchar.h
+@comment GNU
+@deftypefun int fputws_unlocked (const wchar_t *@var{ws}, FILE *@var{stream})
+@safety{@prelim{}@mtsafe{@mtsrace{: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.
+
+This function is a GNU extension.
+@end deftypefun
+
 @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}
@@ -426,11 +1060,15 @@ messages.  For example:
 @smallexample
 puts ("This is a message.");
 @end smallexample
+
+@noindent
+outputs the text @samp{This is a message.} followed by a newline.
 @end deftypefun
 
 @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}).
@@ -440,34 +1078,71 @@ recommend you use @code{fwrite} instead (@pxref{Block Input/Output}).
 @section Character Input
 
 @cindex reading from a stream, by characters
-This section describes functions for performing character-oriented input.
-These functions are declared in the header file @file{stdio.h}.
+This section describes functions for performing character-oriented
+input.  These narrow streams functions are declared in the header file
+@file{stdio.h} and the wide character functions are declared in
+@file{wchar.h}.
 @pindex stdio.h
-
-These functions return an @code{int} value that is either a character of
-input, or the special value @code{EOF} (usually -1).  It is important to
-store the result of these functions in a variable of type @code{int}
-instead of @code{char}, even when you plan to use it only as a
-character.  Storing @code{EOF} in a @code{char} variable truncates its
-value to the size of a character, so that it is no longer
-distinguishable from the valid character @samp{(char) -1}.  So always
-use an @code{int} for the result of @code{getc} and friends, and check
-for @code{EOF} after the call; once you've verified that the result is
-not @code{EOF}, you can be sure that it will fit in a @samp{char}
-variable without loss of information.
+@pindex wchar.h
+
+These functions return an @code{int} or @code{wint_t} value (for narrow
+and wide stream functions respectively) that is either a character of
+input, or the special value @code{EOF}/@code{WEOF} (usually -1).  For
+the narrow stream functions it is important to store the result of these
+functions in a variable of type @code{int} instead of @code{char}, even
+when you plan to use it only as a character.  Storing @code{EOF} in a
+@code{char} variable truncates its value to the size of a character, so
+that it is no longer distinguishable from the valid character
+@samp{(char) -1}.  So always use an @code{int} for the result of
+@code{getc} and friends, and check for @code{EOF} after the call; once
+you've verified that the result is not @code{EOF}, you can be sure that
+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,
 @code{EOF} is returned instead.
 @end deftypefun
 
+@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.
+@end deftypefun
+
+@comment stdio.h
+@comment POSIX
+@deftypefun int fgetc_unlocked (FILE *@var{stream})
+@safety{@prelim{}@mtsafe{@mtsrace{: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
+
+@comment wchar.h
+@comment GNU
+@deftypefun wint_t fgetwc_unlocked (FILE *@var{stream})
+@safety{@prelim{}@mtsafe{@mtsrace{: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.
+
+This function is a GNU extension.
+@end deftypefun
+
 @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
@@ -475,16 +1150,72 @@ optimized, so it is usually the best function to use to read a single
 character.
 @end deftypefun
 
+@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
+best function to use to read a single wide character.
+@end deftypefun
+
+@comment stdio.h
+@comment POSIX
+@deftypefun int getc_unlocked (FILE *@var{stream})
+@safety{@prelim{}@mtsafe{@mtsrace{: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
+
+@comment wchar.h
+@comment GNU
+@deftypefun wint_t getwc_unlocked (FILE *@var{stream})
+@safety{@prelim{}@mtsafe{@mtsrace{: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.
+
+This function is a GNU extension.
+@end deftypefun
+
 @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
 
+@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
+
+@comment stdio.h
+@comment POSIX
+@deftypefun int getchar_unlocked (void)
+@safety{@prelim{}@mtunsafe{@mtasurace{:stdin}}@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
+
+@comment wchar.h
+@comment GNU
+@deftypefun wint_t getwchar_unlocked (void)
+@safety{@prelim{}@mtunsafe{@mtasurace{:stdin}}@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.
+
+This function is a GNU extension.
+@end deftypefun
+
 Here is an example of a function that does input using @code{fgetc}.  It
 would work just as well using @code{getc} instead, or using
-@code{getchar ()} instead of @w{@code{fgetc (stdin)}}.
+@code{getchar ()} instead of @w{@code{fgetc (stdin)}}.  The code would
+also work the same for the wide character stream functions.
 
 @smallexample
 int
@@ -497,17 +1228,17 @@ y_or_n_p (const char *question)
       /* @r{Write a space to separate answer from question.} */
       fputc (' ', stdout);
       /* @r{Read the first character of the line.}
-         @r{This should be the answer character, but might not be.} */
+        @r{This should be the answer character, but might not be.} */
       c = tolower (fgetc (stdin));
       answer = c;
       /* @r{Discard rest of input line.} */
       while (c != '\n' && c != EOF)
-        c = fgetc (stdin);
+       c = fgetc (stdin);
       /* @r{Obey the answer if it was valid.} */
       if (answer == 'y')
-        return 1;
+       return 1;
       if (answer == 'n')
-        return 0;
+       return 0;
       /* @r{Answer was invalid: ask for valid answer.} */
       fputs ("Please answer y or n:", stdout);
     @}
@@ -517,6 +1248,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},
@@ -528,12 +1260,12 @@ way to distinguish this from an input word with value -1.
 @node Line Input
 @section Line-Oriented Input
 
-Since many programs interpret input on the basis of lines, it's
+Since many programs interpret input on the basis of lines, it is
 convenient to have functions to read a line of text from a stream.
 
 Standard C has functions to do this, but they aren't very safe: null
 characters and even (for @code{gets}) long lines can confuse them.  So
-the GNU library provides the nonstandard @code{getline} function that
+@theglibc{} provides the nonstandard @code{getline} function that
 makes it easy to read lines reliably.
 
 Another GNU extension, @code{getdelim}, generalizes @code{getline}.  It
@@ -545,6 +1277,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}}.
@@ -573,13 +1311,15 @@ the line from the null character inserted as a terminator.
 This function is a GNU extension, but it is the recommended way to read
 lines from a stream.  The alternative standard functions are unreliable.
 
-If an error occurs or end of file is reached, @code{getline} returns
-@code{-1}.
+If an error occurs or end of file is reached without any bytes read,
+@code{getline} returns @code{-1}.
 @end deftypefun
 
 @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
@@ -604,6 +1344,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
@@ -624,9 +1365,56 @@ a null character, you should either handle it properly or print a clear
 error message.  We recommend using @code{getline} instead of @code{fgets}.
 @end deftypefun
 
+@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
+string.  You must supply @var{count} wide characters worth of space in
+@var{ws}, but the number of characters read is at most @var{count}
+@minus{} 1.  The extra character space is used to hold the null wide
+character at the end of the string.
+
+If the system is already at end of file when you call @code{fgetws}, then
+the contents of the array @var{ws} are unchanged and a null pointer is
+returned.  A null pointer is also returned if a read error occurs.
+Otherwise, the return value is the pointer @var{ws}.
+
+@strong{Warning:} If the input data has a null wide character (which are
+null bytes in the input stream), you can't tell.  So don't use
+@code{fgetws} unless you know the data cannot contain a null.  Don't use
+it to read files edited by the user because, if the user inserts a null
+character, you should either handle it properly or print a clear error
+message.
+@comment XXX We need getwline!!!
+@end deftypefun
+
+@comment stdio.h
+@comment GNU
+@deftypefun {char *} fgets_unlocked (char *@var{s}, int @var{count}, FILE *@var{stream})
+@safety{@prelim{}@mtsafe{@mtsrace{: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.
+
+This function is a GNU extension.
+@end deftypefun
+
+@comment wchar.h
+@comment GNU
+@deftypefun {wchar_t *} fgetws_unlocked (wchar_t *@var{ws}, int @var{count}, FILE *@var{stream})
+@safety{@prelim{}@mtsafe{@mtsrace{: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.
+
+This function is a GNU extension.
+@end deftypefun
+
 @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
@@ -636,7 +1424,7 @@ returns a null pointer; otherwise it returns @var{s}.
 
 @strong{Warning:} The @code{gets} function is @strong{very dangerous}
 because it provides no protection against overflowing the string
-@var{s}.  The GNU library includes it for compatibility only.  You
+@var{s}.  @Theglibc{} includes it for compatibility only.  You
 should @strong{always} use @code{fgets} or @code{getline} instead.  To
 remind you of this, the linker (if using GNU @code{ld}) will issue a
 warning whenever you use @code{gets}.
@@ -673,7 +1461,7 @@ situation looks like this:
 
 @smallexample
 f  o  o  b  a  r
-         ^
+        ^
 @end smallexample
 
 @noindent
@@ -685,7 +1473,7 @@ situation like this:
 
 @smallexample
 f  o  o  b  a  r
-         |
+        |
       o--
       ^
 @end smallexample
@@ -699,7 +1487,7 @@ If you unread @samp{9} instead of @samp{o}, you get this situation:
 
 @smallexample
 f  o  o  b  a  r
-         |
+        |
       9--
       ^
 @end smallexample
@@ -717,6 +1505,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.
@@ -728,11 +1517,12 @@ If @var{c} is @code{EOF}, @code{ungetc} does nothing and just returns
 The character that you push back doesn't have to be the same as the last
 character that was actually read from the stream.  In fact, it isn't
 necessary to actually read any characters from the stream before
-unreading them with @code{ungetc}!  But that is a strange way to write
-a program; usually @code{ungetc} is used only to unread a character
-that was just read from the same stream.
+unreading them with @code{ungetc}!  But that is a strange way to write a
+program; usually @code{ungetc} is used only to unread a character that
+was just read from the same stream.  @Theglibc{} supports this
+even on files opened in binary mode, but other systems might not.
 
-The GNU C library only supports one character of pushback---in other
+@Theglibc{} only supports one character of pushback---in other
 words, it does not work to call @code{ungetc} twice without doing input
 in between.  Other systems might let you push back multiple characters;
 then reading from the stream retrieves the characters in the reverse
@@ -750,6 +1540,14 @@ input available.  After you read that character, trying to read again
 will encounter end of file.
 @end deftypefun
 
+@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
+
 Here is an example showing the use of @code{getc} and @code{ungetc} to
 skip over whitespace characters.  When this function reaches a
 non-whitespace character, it unreads that character to be seen again on
@@ -804,6 +1602,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
@@ -816,15 +1615,36 @@ returns the number of complete objects read, and discards the partial
 object.  Therefore, the stream remains at the actual end of the file.
 @end deftypefun
 
+@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{}@mtsafe{@mtsrace{: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.
+
+This function is a GNU extension.
+@end deftypefun
+
 @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
 some sort of error, such as running out of space.
 @end deftypefun
 
+@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{}@mtsafe{@mtsrace{: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.
+
+This function is a GNU extension.
+@end deftypefun
+
 @node Formatted Output
 @section Formatted Output
 
@@ -846,19 +1666,19 @@ useful for printing error messages, tables of data, and the like.
 @menu
 * Formatted Output Basics::     Some examples to get you started.
 * Output Conversion Syntax::    General syntax of conversion
-                                 specifications.
+                                specifications.
 * Table of Output Conversions:: Summary of output conversions and
-                                 what they do.
+                                what they do.
 * Integer Conversions::         Details about formatting of integers.
 * Floating-Point Conversions::  Details about formatting of
-                                 floating-point numbers.
+                                floating-point numbers.
 * Other Output Conversions::    Details about formatting of strings,
-                                 characters, pointers, and the like.
+                                characters, pointers, and the like.
 * Formatted Output Functions::  Descriptions of the actual functions.
 * Dynamic Output::             Functions that allocate memory for the output.
 * Variable Arguments Output::   @code{vprintf} and friends.
 * Parsing a Template String::   What kinds of args does a given template
-                                 call for?
+                                call for?
 * Example of Parsing::          Sample program using @code{parse_printf_format}.
 @end menu
 
@@ -880,7 +1700,7 @@ formatted and written to the output stream.  For example,
 int pct = 37;
 char filename[] = "foo.txt";
 printf ("Processing of `%s' is %d%% finished.\nPlease be patient.\n",
-        filename, pct);
+       filename, pct);
 @end smallexample
 
 @noindent
@@ -937,9 +1757,16 @@ template string.
 The conversion specifications in a @code{printf} template string have
 the general form:
 
-@example
+@smallexample
 % @r{[} @var{param-no} @r{$]} @var{flags} @var{width} @r{[} . @var{precision} @r{]} @var{type} @var{conversion}
-@end example
+@end smallexample
+
+@noindent
+or
+
+@smallexample
+% @r{[} @var{param-no} @r{$]} @var{flags} @var{width} . @r{*} @r{[} @var{param-no} @r{$]} @var{type} @var{conversion}
+@end smallexample
 
 For example, in the conversion specifier @samp{%-10.8ld}, the @samp{-}
 is a flag, @samp{10} specifies the field width, the precision is
@@ -954,29 +1781,29 @@ initial @samp{%} character followed in sequence by:
 @itemize @bullet
 @item
 An optional specification of the parameter used for this format.
-Normally the parameters to the @code{printf} function a assigned to the
+Normally the parameters to the @code{printf} function are assigned to the
 formats in the order of appearance in the format string.  But in some
 situations (such as message translation) this is not desirable and this
-extension allows to specify and explicit parameter to be used.
+extension allows an explicit parameter to be specified.
 
-The @var{param-no} part of the format must be an integer in the range of
+The @var{param-no} parts of the format must be integers in the range of
 1 to the maximum number of arguments present to the function call.  Some
 implementations limit this number to a certainly upper bound.  The exact
 limit can be retrieved by the following constant.
 
 @defvr Macro NL_ARGMAX
-The value of @code{ARGMAX} is the maximum value allowed for the
-specification of an positional parameter in a @code{printf} call.  The
+The value of @code{NL_ARGMAX} is the maximum value allowed for the
+specification of a positional parameter in a @code{printf} call.  The
 actual value in effect at runtime can be retrieved by using
 @code{sysconf} using the @code{_SC_NL_ARGMAX} parameter @pxref{Sysconf
 Definition}.
 
 Some system have a quite low limit such as @math{9} for @w{System V}
-systems.  The GNU C library has no real limit.
+systems.  @Theglibc{} has no real limit.
 @end defvr
 
 If any of the formats has a specification for the parameter position all
-of them in the format string shall have one.  Otherwise the behaviour is
+of them in the format string shall have one.  Otherwise the behavior is
 undefined.
 
 @item
@@ -1088,9 +1915,17 @@ Conversions}, for details.
 @item @samp{%c}
 Print a single character.  @xref{Other Output Conversions}.
 
+@item @samp{%C}
+This is an alias for @samp{%lc} which is supported for compatibility
+with the Unix standard.
+
 @item @samp{%s}
 Print a string.  @xref{Other Output Conversions}.
 
+@item @samp{%S}
+This is an alias for @samp{%ls} which is supported for compatibility
+with the Unix standard.
+
 @item @samp{%p}
 Print the value of a pointer.  @xref{Other Output Conversions}.
 
@@ -1190,7 +2025,7 @@ char}, as appropriate.  A @code{char} argument is converted to an
 anyway, but the @samp{h} modifier says to convert it back to a
 @code{char} again.
 
-This modifier was introduced in @w{ISO C 9x}.
+This modifier was introduced in @w{ISO C99}.
 
 @item h
 Specifies that the argument is a @code{short int} or @code{unsigned
@@ -1203,13 +2038,17 @@ anyway, but the @samp{h} modifier says to convert it back to a
 Specifies that the argument is a @code{intmax_t} or @code{uintmax_t}, as
 appropriate.
 
-This modifier was introduced in @w{ISO C 9x}.
+This modifier was introduced in @w{ISO C99}.
 
 @item l
 Specifies that the argument is a @code{long int} or @code{unsigned long
 int}, as appropriate.  Two @samp{l} characters is like the @samp{L}
 modifier, below.
 
+If used with @samp{%c} or @samp{%s} the corresponding parameter is
+considered as a wide character or wide character string respectively.
+This use of @samp{l} was introduced in @w{Amendment 1} to @w{ISO C90}.
+
 @item L
 @itemx ll
 @itemx q
@@ -1224,14 +2063,14 @@ from 4.4 BSD; a @w{@code{long long int}} is sometimes called a ``quad''
 @item t
 Specifies that the argument is a @code{ptrdiff_t}.
 
-This modifier was introduced in @w{ISO C 9x}.
+This modifier was introduced in @w{ISO C99}.
 
 @item z
 @itemx Z
 Specifies that the argument is a @code{size_t}.
 
-@samp{z} was introduced in @w{ISO C 9x}.  @samp{Z} is a GNU extension
-predating this addition and should not be used anymore in new code.
+@samp{z} was introduced in @w{ISO C99}.  @samp{Z} is a GNU extension
+predating this addition and should not be used in new code.
 @end table
 
 Here is an example.  Using the template string:
@@ -1248,7 +2087,7 @@ conversion gives results like:
 |    0|0    |   +0|+0   |    0|00000|     |   00|0|
 |    1|1    |   +1|+1   |    1|00001|    1|   01|1|
 |   -1|-1   |   -1|-1   |   -1|-0001|   -1|  -01|-1|
-|100000|100000|+100000| 100000|100000|100000|100000|100000|
+|100000|100000|+100000|+100000| 100000|100000|100000|100000|100000|
 @end smallexample
 
 In particular, notice what happens in the last case where the number
@@ -1262,7 +2101,7 @@ various format options, using the template string:
 @end smallexample
 
 @smallexample
-|    0|    0|    0|    0|    0|  0x0|  0X0|0x00000000|
+|    0|    0|    0|    0|    0|    0|    0|  00000000|
 |    1|    1|    1|    1|   01|  0x1|  0X1|0x00000001|
 |100000|303240|186a0|186A0|0303240|0x186a0|0X186A0|0x000186a0|
 @end smallexample
@@ -1291,19 +2130,19 @@ the precision.  The exponent always contains at least two digits.  The
 
 The @samp{%g} and @samp{%G} conversions print the argument in the style
 of @samp{%e} or @samp{%E} (respectively) if the exponent would be less
-than -4 or greater than or equal to the precision; otherwise they use the
-@samp{%f} style.  Trailing zeros are removed from the fractional portion
-of the result and a decimal-point character appears only if it is
-followed by a digit.
+than -4 or greater than or equal to the precision; otherwise they use
+the @samp{%f} style.  A precision of @code{0}, is taken as 1.
+Trailing zeros are removed from the fractional portion of the result and
+a decimal-point character appears only if it is followed by a digit.
 
 The @samp{%a} and @samp{%A} conversions are meant for representing
-floating-point number exactly in textual form so that they can be
+floating-point numbers exactly in textual form so that they can be
 exchanged as texts between different programs and/or machines.  The
 numbers are represented is the form
 @w{[@code{-}]@code{0x}@var{h}@code{.}@var{hhh}@code{p}[@code{+}|@code{-}]@var{dd}}.
 At the left of the decimal-point character exactly one digit is print.
 This character is only @code{0} if the number is denormalized.
-Otherwise the value is unspecified; it is implemention dependent how many
+Otherwise the value is unspecified; it is implementation dependent how many
 bits are used.  The number of hexadecimal digits on the right side of
 the decimal-point character is equal to the precision.  If the precision
 is zero it is determined to be large enough to provide an exact
@@ -1410,11 +2249,13 @@ Notice how the @samp{%g} conversion drops trailing zeros.
 
 This section describes miscellaneous conversions for @code{printf}.
 
-The @samp{%c} conversion prints a single character.  The @code{int}
-argument is first converted to an @code{unsigned char}.  The @samp{-}
-flag can be used to specify left-justification in the field, but no
-other flags are defined, and no precision or type modifier can be given.
-For example:
+The @samp{%c} conversion prints a single character.  In case there is no
+@samp{l} modifier the @code{int} argument is first converted to an
+@code{unsigned char}.  Then, if used in a wide stream function, the
+character is converted into the corresponding wide character.  The
+@samp{-} flag can be used to specify left-justification in the field,
+but no other flags are defined, and no precision or type modifier can be
+given.  For example:
 
 @smallexample
 printf ("%c%c%c%c%c", 'h', 'e', 'l', 'l', 'o');
@@ -1423,9 +2264,16 @@ printf ("%c%c%c%c%c", 'h', 'e', 'l', 'l', 'o');
 @noindent
 prints @samp{hello}.
 
-The @samp{%s} conversion prints a string.  The corresponding argument
-must be of type @code{char *} (or @code{const char *}).  A precision can
-be specified to indicate the maximum number of characters to write;
+If there is a @samp{l} modifier present the argument is expected to be
+of type @code{wint_t}.  If used in a multibyte function the wide
+character is converted into a multibyte character before being added to
+the output.  In this case more than one output byte can be produced.
+
+The @samp{%s} conversion prints a string.  If no @samp{l} modifier is
+present the corresponding argument must be of type @code{char *} (or
+@code{const char *}).  If used in a wide stream function the string is
+first converted in a wide character string.  A precision can be
+specified to indicate the maximum number of characters to write;
 otherwise characters in the string up to but not including the
 terminating null character are written to the output stream.  The
 @samp{-} flag can be used to specify left-justification in the field,
@@ -1439,8 +2287,10 @@ printf ("%3s%-6s", "no", "where");
 @noindent
 prints @samp{ nowhere }.
 
+If there is a @samp{l} modifier present the argument is expected to be of type @code{wchar_t} (or @code{const wchar_t *}).
+
 If you accidentally pass a null pointer as the argument for a @samp{%s}
-conversion, the GNU library prints it as @samp{(null)}.  We think this
+conversion, @theglibc{} prints it as @samp{(null)}.  We think this
 is more useful than crashing.  But it's not good practice to pass a null
 argument intentionally.
 
@@ -1459,13 +2309,13 @@ fprintf (stderr, "can't open `%s': %s\n", filename, strerror (errno));
 @end smallexample
 
 @noindent
-The @samp{%m} conversion is a GNU C library extension.
+The @samp{%m} conversion is a @glibcadj{} extension.
 
 The @samp{%p} conversion prints a pointer value.  The corresponding
 argument must be of type @code{void *}.  In practice, you can use any
 type of pointer.
 
-In the GNU system, non-null pointers are printed as unsigned integers,
+In @theglibc{}, non-null pointers are printed as unsigned integers,
 as if a @samp{%#x} conversion were used.  Null pointers print as
 @samp{(nil)}.  (Pointers might print differently in other systems.)
 
@@ -1530,22 +2380,43 @@ 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
 negative value if there was an output error.
 @end deftypefun
 
+@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
+negative value if there was an output error.
+@end deftypefun
+
 @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
 
+@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
+
 @comment stdio.h
 @comment ISO
 @deftypefun int sprintf (char *@var{s}, const char *@var{template}, @dots{})
+@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@ascuheap{}}@acunsafe{@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.
@@ -1567,13 +2438,41 @@ To avoid this problem, you can use @code{snprintf} or @code{asprintf},
 described below.
 @end deftypefun
 
+@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{}}@acunsafe{@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}
+argument specifies the maximum number of characters to produce.  The
+trailing null character is counted towards this limit, so you should
+allocate at least @var{size} wide characters for the string @var{ws}.
+
+The return value is the number of characters generated for the given
+input, excluding the trailing null.  If not all output fits into the
+provided buffer a negative value is returned.  You should try again with
+a bigger output string.  @emph{Note:} this is different from how
+@code{snprintf} handles this situation.
+
+Note that the corresponding narrow stream function takes fewer
+parameters.  @code{swprintf} in fact corresponds to the @code{snprintf}
+function.  Since the @code{sprintf} function can be dangerous and should
+be avoided the @w{ISO C} committee refused to make the same mistake
+again and decided to not define a function exactly corresponding to
+@code{sprintf}.
+@end deftypefun
+
 @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{}}@acunsafe{@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
 you should allocate at least @var{size} characters for the string @var{s}.
+If @var{size} is zero, nothing, not even the null byte, shall be written and
+@var{s} may be a null pointer.
 
 The return value is the number of characters which would be generated
 for the given input, excluding the trailing null.  If this value is
@@ -1594,20 +2493,25 @@ make_message (char *name, char *value)
   int nchars;
 @end group
 @group
+  if (buffer == NULL)
+    return NULL;
+
  /* @r{Try to print in the allocated space.} */
   nchars = snprintf (buffer, size, "value of %s is %s",
-                     name, value);
+                    name, value);
 @end group
 @group
   if (nchars >= size)
     @{
       /* @r{Reallocate buffer now that we know
-         how much space is needed.} */
-      buffer = (char *) xrealloc (buffer, nchars + 1);
-
-      /* @r{Try again.} */
-      snprintf (buffer, size, "value of %s is %s",
-                name, value);
+        how much space is needed.} */
+      size = nchars + 1;
+      buffer = (char *) xrealloc (buffer, size);
+
+      if (buffer != NULL)
+       /* @r{Try again.} */
+       snprintf (buffer, size, "value of %s is %s",
+                 name, value);
     @}
   /* @r{The last call worked, return the string.} */
   return buffer;
@@ -1616,6 +2520,12 @@ make_message (char *name, char *value)
 @end smallexample
 
 In practice, it is often easier just to use @code{asprintf}, below.
+
+@strong{Attention:} In versions of @theglibc{} prior to 2.1 the
+return value is the number of characters stored, not including the
+terminating null; unless there was not enough space in @var{s} to
+store the result in which case @code{-1} is returned.  This was
+changed in order to comply with the @w{ISO C99} standard.
 @end deftypefun
 
 @node Dynamic Output
@@ -1627,12 +2537,18 @@ 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{}}@acunsafe{@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
 buffer you allocate in advance.  The @var{ptr} argument should be the
-address of a @code{char *} object, and @code{asprintf} stores a pointer
-to the newly allocated string at that location.
+address of a @code{char *} object, and a successful call to
+@code{asprintf} stores a pointer to the newly allocated string at that
+location.
+
+The return value is the number of characters allocated for the buffer, or
+less than zero if an error occurred. Usually this means that the buffer
+could not be allocated.
 
 Here is how to use @code{asprintf} to get the same result as the
 @code{snprintf} example, but more easily:
@@ -1644,7 +2560,8 @@ char *
 make_message (char *name, char *value)
 @{
   char *result;
-  asprintf (&result, "value of %s is %s", name, value);
+  if (asprintf (&result, "value of %s is %s", name, value) < 0)
+    return NULL;
   return result;
 @}
 @end smallexample
@@ -1653,6 +2570,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{}@mtsafe{@mtsrace{:obstack} @mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{}}@acunsafe{@acucorrupt{} @acsmem{}}}
 This function is similar to @code{asprintf}, except that it uses the
 obstack @var{obstack} to allocate the space.  @xref{Obstacks}.
 
@@ -1684,13 +2602,12 @@ For example:
 
 @smallexample
 #define myprintf(a, b, c, d, e, rest...) \
-            printf (mytemplate , ## rest...)
+           printf (mytemplate , ## rest)
 @end smallexample
 
 @noindent
-@xref{Macro Varargs, , Macros with Variable Numbers of Arguments,
-gcc.info, Using GNU CC}, for details.  But this is limited to macros,
-and does not apply to real functions at all.
+@xref{Variadic Macros,,, cpp, The C preprocessor}, for details.
+But this is limited to macros, and does not apply to real functions at all.
 
 Before calling @code{vprintf} or the other functions listed in this
 section, you @emph{must} call @code{va_start} (@pxref{Variadic
@@ -1724,28 +2641,98 @@ 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}.
 @end deftypefun
 
+@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}.
+@end deftypefun
+
 @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
 
+@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
+
 @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{}}@acunsafe{@acsmem{}}}
 This is the equivalent of @code{sprintf} with the variable argument list
 specified directly as for @code{vprintf}.
 @end deftypefun
 
+@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{}}@acunsafe{@acsmem{}}}
+This is the equivalent of @code{swprintf} with the variable argument list
+specified directly as for @code{vwprintf}.
+@end deftypefun
+
 @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{}}@acunsafe{@acsmem{}}}
 This is the equivalent of @code{snprintf} with the variable argument list
 specified directly as for @code{vprintf}.
 @end deftypefun
@@ -1753,6 +2740,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{}}@acunsafe{@acsmem{}}}
 The @code{vasprintf} function is the equivalent of @code{asprintf} with the
 variable argument list specified directly as for @code{vprintf}.
 @end deftypefun
@@ -1760,6 +2748,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{}@mtsafe{@mtsrace{:obstack} @mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{}}@acunsafe{@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
@@ -1805,7 +2797,7 @@ For example, take this declaration of @code{eprintf}:
 
 @smallexample
 void eprintf (const char *template, ...)
-        __attribute__ ((format (printf, 1, 2)));
+       __attribute__ ((format (printf, 1, 2)));
 @end smallexample
 
 @noindent
@@ -1832,20 +2824,21 @@ 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
 this array describes one argument.  This information is encoded using
 the various @samp{PA_} macros, listed below.
 
-The @var{n} argument specifies the number of elements in the array
-@var{argtypes}.  This is the most elements that
+The argument @var{n} specifies the number of elements in the array
+@var{argtypes}.  This is the maximum number of elements that
 @code{parse_printf_format} will try to write.
 
 @code{parse_printf_format} returns the total number of arguments required
 by @var{template}.  If this number is greater than @var{n}, then the
 information returned describes only the first @var{n} arguments.  If you
-want information about more than that many arguments, allocate a bigger
+want information about additional arguments, allocate a bigger
 array and call @code{parse_printf_format} again.
 @end deftypefun
 
@@ -1992,30 +2985,30 @@ validate_args (char *format, int nargs, OBJECT *args)
       int wanted;
 
       if (argtypes[i] & PA_FLAG_PTR)
-        wanted = STRUCTURE;
+       wanted = STRUCTURE;
       else
-        switch (argtypes[i] & ~PA_FLAG_MASK)
-          @{
-          case PA_INT:
-          case PA_FLOAT:
-          case PA_DOUBLE:
-            wanted = NUMBER;
-            break;
-          case PA_CHAR:
-            wanted = CHAR;
-            break;
-          case PA_STRING:
-            wanted = STRING;
-            break;
-          case PA_POINTER:
-            wanted = STRUCTURE;
-            break;
-          @}
+       switch (argtypes[i] & ~PA_FLAG_MASK)
+         @{
+         case PA_INT:
+         case PA_FLOAT:
+         case PA_DOUBLE:
+           wanted = NUMBER;
+           break;
+         case PA_CHAR:
+           wanted = CHAR;
+           break;
+         case PA_STRING:
+           wanted = STRING;
+           break;
+         case PA_POINTER:
+           wanted = STRUCTURE;
+           break;
+         @}
       if (TYPE (args[i]) != wanted)
-        @{
-          error ("type mismatch for arg number %d", i);
-          return 0;
-        @}
+       @{
+         error ("type mismatch for arg number %d", i);
+         return 0;
+       @}
     @}
   return 1;
 @}
@@ -2027,7 +3020,7 @@ validate_args (char *format, int nargs, OBJECT *args)
 @cindex defining new @code{printf} conversions
 @cindex extending @code{printf}
 
-The GNU C library lets you define your own custom conversion specifiers
+@Theglibc{} lets you define your own custom conversion specifiers
 for @code{printf} template strings, to teach @code{printf} clever ways
 to print the important data structures of your program.
 
@@ -2046,15 +3039,15 @@ The facilities of this section are declared in the header file
 
 @menu
 * Registering New Conversions::         Using @code{register_printf_function}
-                                         to register a new output conversion.
+                                        to register a new output conversion.
 * Conversion Specifier Options::        The handler must be able to get
-                                         the options specified in the
-                                         template when it is called.
+                                        the options specified in the
+                                        template when it is called.
 * Defining the Output Handler::         Defining the handler and arginfo
-                                         functions that are passed as arguments
-                                         to @code{register_printf_function}.
+                                        functions that are passed as arguments
+                                        to @code{register_printf_function}.
 * Printf Extension Example::            How to define a @code{printf}
-                                         handler function.
+                                        handler function.
 * Predefined Printf Handlers::          Predefined @code{printf} handlers.
 @end menu
 
@@ -2072,12 +3065,20 @@ 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{:printfext}}@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{'z'}, it defines the conversion @samp{%z}.
+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
 characters like @samp{#} and type modifiers like @samp{l} can never be
 used as conversions; calling @code{register_printf_function} for those
-characters has no effect.
+characters has no effect.  It is advisable not to use lowercase letters,
+since the ISO C standard warns that additional lowercase letters may be
+standardized in future editions of the standard.
 
 The @var{handler-function} is the function called by @code{printf} and
 friends when this conversion appears in a template string.
@@ -2098,9 +3099,9 @@ about this.
 @c but if you are never going to call @code{parse_printf_format}, you do
 @c not need to define an arginfo function.
 
-@strong{Attention:} In the GNU C library version before 2.0 the
+@strong{Attention:} In @theglibc{} versions before 2.0 the
 @var{arginfo-function} function did not need to be installed unless
-the user uses the @code{parse_printf_format} function.  This changed.
+the user used the @code{parse_printf_format} function.  This has changed.
 Now a call to any of the @code{printf} functions will call this
 function when this format specifier appears in the format string.
 
@@ -2164,6 +3165,9 @@ type modifier was specified.  For integer conversions, this indicates
 @code{long long int}, as opposed to @code{long double} for floating
 point conversions.
 
+@item unsigned int is_char
+This is a boolean that is true if the @samp{hh} type modifier was specified.
+
 @item unsigned int is_short
 This is a boolean that is true if the @samp{h} type modifier was specified.
 
@@ -2191,6 +3195,9 @@ be used freely by the user-defined handlers but when called from
 the @code{printf} function this variable always contains the value
 @code{0}.
 
+@item unsigned int wide
+This flag is set if the stream is wide oriented.
+
 @item wchar_t pad
 This is the character to use for padding the output to the minimum field
 width.  The value is @code{'0'} if the @samp{0} flag was specified, and
@@ -2205,7 +3212,7 @@ width.  The value is @code{'0'} if the @samp{0} flag was specified, and
 Now let's look at how to define the handler and arginfo functions
 which are passed as arguments to @code{register_printf_function}.
 
-@strong{Compatibility Note:} The interface change in the GNU libc
+@strong{Compatibility Note:} The interface changed in @theglibc{}
 version 2.0.  Previously the third argument was of type
 @code{va_list *}.
 
@@ -2213,7 +3220,7 @@ You should define your handler functions with a prototype like:
 
 @smallexample
 int @var{function} (FILE *stream, const struct printf_info *info,
-                    const void *const *args)
+                   const void *const *args)
 @end smallexample
 
 The @var{stream} argument passed to the handler function is the stream to
@@ -2239,7 +3246,7 @@ a description of this data structure.
 @c arguments that your handler processes.  @xref{Variadic Functions}.)
 
 The @var{args} is a vector of pointers to the arguments data.
-The number of arguments were determined by calling the argument
+The number of arguments was determined by calling the argument
 information function provided by the user.
 
 Your handler function should return a value just like @code{printf}
@@ -2261,7 +3268,7 @@ You have to define these functions with a prototype like:
 
 @smallexample
 int @var{function} (const struct printf_info *info,
-                    size_t n, int *argtypes)
+                   size_t n, int *argtypes)
 @end smallexample
 
 The return value from the function should be the number of arguments the
@@ -2303,17 +3310,23 @@ The output produced by this program looks like:
 @node Predefined Printf Handlers
 @subsection Predefined @code{printf} Handlers
 
-The GNU libc also contains a concrete and useful application of the
+@Theglibc{} also contains a concrete and useful application of the
 @code{printf} handler extension.  There are two functions available
 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{}@mtsafe{@mtsrace{:fp} @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:
-powers of 1024 or powers to 1000.  Which one is used depends on the
+powers of 1024 or powers of 1000.  Which one is used depends on the
 format character specified while registered this handler.  If the
 character is of lower case, 1024 is used.  For upper case characters,
 1000 is used.
@@ -2322,7 +3335,7 @@ The postfix tag corresponds to bytes, kilobytes, megabytes, gigabytes,
 etc.  The full table is:
 
 @ifinfo
-@multitable @hsep @vsep {' '} {2^10 (1024)} {zetta} {Upper} {10^24 (1000)}
+@multitable {' '} {2^10 (1024)} {zetta} {Upper} {10^24 (1000)}
 @item low @tab Multiplier  @tab From  @tab Upper @tab Multiplier
 @item ' ' @tab 1           @tab       @tab ' '   @tab 1
 @item k   @tab 2^10 (1024) @tab kilo  @tab K     @tab 10^3 (1000)
@@ -2363,11 +3376,12 @@ format character as if it were @code{%.3fk} and will yield @code{1.000k}.
 @end deftypefun
 
 Due to the requirements of @code{register_printf_function} we must also
-provide the function which return information about the arguments.
+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.
@@ -2388,14 +3402,14 @@ register_printf_function ('b', printf_size, printf_size_info);
 @end smallexample
 
 @noindent
-we could also print using power of 1024.  Please note that all what is
-different in these both lines in the format specifier.  The
-@code{printf_size} function knows about the difference of low and upper
+we could also print using a power of 1024.  Please note that all that is
+different in these two lines is the format specifier.  The
+@code{printf_size} function knows about the difference between lower and upper
 case format specifiers.
 
 The use of @code{'B'} and @code{'b'} is no coincidence.  Rather it is
 the preferred way to use this functionality since it is available on
-some other systems also available using the format specifiers.
+some other systems which also use format specifiers.
 
 @node Formatted Input
 @section Formatted Input
@@ -2478,8 +3492,8 @@ from a matching error.
 If you are trying to read input that doesn't match a single, fixed
 pattern, you may be better off using a tool such as Flex to generate a
 lexical scanner, or Bison to generate a parser, rather than using
-@code{scanf}.  For more information about these tools, see @ref{, , ,
-flex.info, Flex: The Lexical Scanner Generator}, and @ref{, , ,
+@code{scanf}.  For more information about these tools, see @ref{Top, , ,
+flex.info, Flex: The Lexical Scanner Generator}, and @ref{Top, , ,
 bison.info, The Bison Reference Manual}.
 
 @node Input Conversion Syntax
@@ -2595,18 +3609,51 @@ Matches an optionally signed floating-point number.  @xref{Numeric Input
 Conversions}.
 
 @item @samp{%s}
+
 Matches a string containing only non-whitespace characters.
-@xref{String Input Conversions}.
+@xref{String Input Conversions}.  The presence of the @samp{l} modifier
+determines whether the output is stored as a wide character string or a
+multibyte string.  If @samp{%s} is used in a wide character function the
+string is converted as with multiple calls to @code{wcrtomb} into a
+multibyte string.  This means that the buffer must provide room for
+@code{MB_CUR_MAX} bytes for each wide character read.  In case
+@samp{%ls} is used in a multibyte function the result is converted into
+wide characters as with multiple calls of @code{mbrtowc} before being
+stored in the user provided buffer.
+
+@item @samp{%S}
+This is an alias for @samp{%ls} which is supported for compatibility
+with the Unix standard.
 
 @item @samp{%[}
 Matches a string of characters that belong to a specified set.
-@xref{String Input Conversions}.
+@xref{String Input Conversions}.  The presence of the @samp{l} modifier
+determines whether the output is stored as a wide character string or a
+multibyte string.  If @samp{%[} is used in a wide character function the
+string is converted as with multiple calls to @code{wcrtomb} into a
+multibyte string.  This means that the buffer must provide room for
+@code{MB_CUR_MAX} bytes for each wide character read.  In case
+@samp{%l[} is used in a multibyte function the result is converted into
+wide characters as with multiple calls of @code{mbrtowc} before being
+stored in the user provided buffer.
 
 @item @samp{%c}
 Matches a string of one or more characters; the number of characters
 read is controlled by the maximum field width given for the conversion.
 @xref{String Input Conversions}.
 
+If the @samp{%c} is used in a wide stream function the read value is
+converted from a wide character to the corresponding multibyte character
+before storing it.  Note that this conversion can produce more than one
+byte of output and therefore the provided buffer be large enough for up
+to @code{MB_CUR_MAX} bytes for each character.  If @samp{%lc} is used in
+a multibyte function the input is treated as a multibyte sequence (and
+not bytes) and the result is converted as with calls to @code{mbrtowc}.
+
+@item @samp{%C}
+This is an alias for @samp{%lc} which is supported for compatibility
+with the Unix standard.
+
 @item @samp{%p}
 Matches a pointer value in the same implementation-defined format used
 by the @samp{%p} output conversion for @code{printf}.  @xref{Other Input
@@ -2670,7 +3717,7 @@ specify other sizes of integer:
 Specifies that the argument is a @code{signed char *} or @code{unsigned
 char *}.
 
-This modifier was introduced in @w{ISO C 9x}.
+This modifier was introduced in @w{ISO C99}.
 
 @item h
 Specifies that the argument is a @code{short int *} or @code{unsigned
@@ -2679,12 +3726,17 @@ short int *}.
 @item j
 Specifies that the argument is a @code{intmax_t *} or @code{uintmax_t *}.
 
-This modifier was introduced in @w{ISO C 9x}.
+This modifier was introduced in @w{ISO C99}.
 
 @item l
 Specifies that the argument is a @code{long int *} or @code{unsigned
 long int *}.  Two @samp{l} characters is like the @samp{L} modifier, below.
 
+If used with @samp{%c} or @samp{%s} the corresponding parameter is
+considered as a pointer to a wide character or wide character string
+respectively.  This use of @samp{l} was introduced in @w{Amendment 1} to
+@w{ISO C90}.
+
 @need 100
 @item ll
 @itemx L
@@ -2700,12 +3752,12 @@ from 4.4 BSD; a @w{@code{long long int}} is sometimes called a ``quad''
 @item t
 Specifies that the argument is a @code{ptrdiff_t *}.
 
-This modifier was introduced in @w{ISO C 9x}.
+This modifier was introduced in @w{ISO C99}.
 
 @item z
 Specifies that the argument is a @code{size_t *}.
 
-This modifier was introduced in @w{ISO C 9x}.
+This modifier was introduced in @w{ISO C99}.
 @end table
 
 All of the @samp{%e}, @samp{%f}, @samp{%g}, @samp{%E}, and @samp{%G}
@@ -2744,15 +3796,17 @@ Otherwise the longest prefix with a correct form is processed.
 @subsection String Input Conversions
 
 This section describes the @code{scanf} input conversions for reading
-string and character values: @samp{%s}, @samp{%[}, and @samp{%c}.
+string and character values: @samp{%s}, @samp{%S}, @samp{%[}, @samp{%c},
+and @samp{%C}.
 
 You have two options for how to receive the input from these
 conversions:
 
 @itemize @bullet
 @item
-Provide a buffer to store it in.  This is the default.  You
-should provide an argument of type @code{char *}.
+Provide a buffer to store it in.  This is the default.  You should
+provide an argument of type @code{char *} or @code{wchar_t *} (the
+latter of the @samp{l} modifier is present).
 
 @strong{Warning:} To make a robust program, you must make sure that the
 input (plus its terminating null) cannot possibly exceed the size of the
@@ -2769,7 +3823,7 @@ in.  @xref{Dynamic String Input}.
 @end itemize
 
 The @samp{%c} conversion is the simplest: it matches a fixed number of
-characters, always.  The maximum field with says how many characters to
+characters, always.  The maximum field width says how many characters to
 read; if you don't specify the maximum, the default is 1.  This
 conversion doesn't append a null character to the end of the text it
 reads.  It also does not skip over initial whitespace characters.  It
@@ -2777,6 +3831,13 @@ reads precisely the next @var{n} characters, and fails if it cannot get
 that many.  Since there is always a maximum field width with @samp{%c}
 (whether specified, or 1 by default), you can always prevent overflow by
 making the buffer long enough.
+@comment Is character == byte here???  --drepper
+
+If the format is @samp{%lc} or @samp{%C} the function stores wide
+characters which are converted using the conversion determined at the
+time the stream was opened from the external byte stream.  The number of
+bytes read from the medium is limited by @code{MB_CUR_LEN * @var{n}} but
+at most @var{n} wide character get stored in the output string.
 
 The @samp{%s} conversion matches a string of non-whitespace characters.
 It skips and discards initial whitespace, but stops when it encounters
@@ -2799,10 +3860,18 @@ then the number of characters read is limited only by where the next
 whitespace character appears.  This almost certainly means that invalid
 input can make your program crash---which is a bug.
 
+The @samp{%ls} and @samp{%S} format are handled just like @samp{%s}
+except that the external byte sequence is converted using the conversion
+associated with the stream to wide characters with their own encoding.
+A width or precision specified with the format do not directly determine
+how many bytes are read from the stream since they measure wide
+characters.  But an upper limit can be computed by multiplying the value
+of the width or precision by @code{MB_CUR_MAX}.
+
 To read in characters that belong to an arbitrary set of your choice,
 use the @samp{%[} conversion.  You specify the set between the @samp{[}
 character and a following @samp{]} character, using the same syntax used
-in regular expressions.  As special cases:
+in regular expressions for explicit sets of characters.  As special cases:
 
 @itemize @bullet
 @item
@@ -2822,6 +3891,10 @@ the characters listed.
 The @samp{%[} conversion does not skip over initial whitespace
 characters.
 
+Note that the @dfn{character class} syntax available in character sets
+that appear inside regular expressions (such as @samp{[:alpha:]}) is
+@emph{not} available in the @samp{%[} conversion.
+
 Here are some examples of @samp{%[} conversions and what they mean:
 
 @table @samp
@@ -2842,6 +3915,10 @@ initial whitespace.
 Matches up to 25 lowercase characters.
 @end table
 
+As for @samp{%c} and @samp{%s} the @samp{%[} format is also modified to
+produce wide characters if the @samp{l} modifier is present.  All what
+is said about @samp{%ls} above is true for @samp{%l[}.
+
 One more reminder: the @samp{%s} and @samp{%[} conversions are
 @strong{dangerous} if you don't specify a maximum width or use the
 @samp{a} flag, because input too long would overflow whatever buffer you
@@ -2872,7 +3949,7 @@ conversion specification to read a ``variable assignment'' of the form
   char *variable, *value;
 
   if (2 > scanf ("%a[a-zA-Z0-9] = %a[^\n]\n",
-                 &variable, &value))
+                &variable, &value))
     @{
       invalid_input_error ();
       return 0;
@@ -2888,7 +3965,7 @@ conversion specification to read a ``variable assignment'' of the form
 This section describes the miscellaneous input conversions.
 
 The @samp{%p} conversion is used to read a pointer value.  It recognizes
-the same syntax as is used by the @samp{%p} output conversion for
+the same syntax used by the @samp{%p} output conversion for
 @code{printf} (@pxref{Other Output Conversions}); that is, a hexadecimal
 number just as the @samp{%x} conversion accepts.  The corresponding
 argument should be of type @code{void **}; that is, the address of a
@@ -2925,35 +4002,75 @@ 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
 resulting values.
 
 The return value is normally the number of successful assignments.  If
-an end-of-file condition is detected before any matches are performed
-(including matches against whitespace and literal characters in the
-template), then @code{EOF} is returned.
+an end-of-file condition is detected before any matches are performed,
+including matches against whitespace and literal characters in the
+template, then @code{EOF} is returned.
+@end deftypefun
+
+@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
+resulting values.
+
+The return value is normally the number of successful assignments.  If
+an end-of-file condition is detected before any matches are performed,
+including matches against whitespace and literal characters in the
+template, then @code{WEOF} is returned.
 @end deftypefun
 
 @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
 
+@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
+
 @comment stdio.h
 @comment ISO
 @deftypefun int sscanf (const char *@var{s}, const char *@var{template}, @dots{})
+@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@ascuheap{}}@acunsafe{@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.
 
 The behavior of this function is undefined if copying takes place
 between objects that overlap---for example, if @var{s} is also given
-as an argument to receive a string read under control of the @samp{%s}
-conversion.
+as an argument to receive a string read under control of the @samp{%s},
+@samp{%S}, or @samp{%[} conversion.
+@end deftypefun
+
+@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{}}@acunsafe{@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.
+
+The behavior of this function is undefined if copying takes place
+between objects that overlap---for example, if @var{ws} is also given as
+an argument to receive a string read under control of the @samp{%s},
+@samp{%S}, or @samp{%[} conversion.
 @end deftypefun
 
 @node Variable Arguments Input
@@ -2966,37 +4083,65 @@ These functions are analogous to the @code{vprintf} series of output
 functions.  @xref{Variable Arguments Output}, for important
 information on how to use them.
 
-@strong{Portability Note:} The functions listed in this section are GNU
-extensions.
+@strong{Portability Note:} The functions listed in this section were
+introduced in @w{ISO C99} and were before available as GNU extensions.
 
 @comment stdio.h
-@comment GNU
+@comment ISO
 @deftypefun int vscanf (const char *@var{template}, va_list @var{ap})
-This function is similar to @code{scanf} except that, instead of taking
+@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}).
+@end deftypefun
+
+@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}).
 @end deftypefun
 
 @comment stdio.h
-@comment GNU
+@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
 
+@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
+
 @comment stdio.h
-@comment GNU
+@comment ISO
 @deftypefun int vsscanf (const char *@var{s}, const char *@var{template}, va_list @var{ap})
+@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{}}}
 This is the equivalent of @code{sscanf} with the variable argument list
 specified directly as for @code{vscanf}.
 @end deftypefun
 
+@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{}}@acunsafe{@acsmem{}}}
+This is the equivalent of @code{swscanf} with the variable argument list
+specified directly as for @code{vwscanf}.
+@end deftypefun
+
 In GNU C, there is a special construct you can use to let the compiler
 know that a function uses a @code{scanf}-style format string.  Then it
 can check the number and types of arguments in each call to the
 function, and warn you when they do not match the format string.
-@xref{Function Attributes, , Declaring Attributes of Functions,
-gcc.info, Using GNU CC}, for details.
+For details, see @ref{Function Attributes, , Declaring Attributes of Functions,
+gcc.info, Using GNU CC}.
 
 @node EOF and Errors
 @section End-Of-File and Errors
@@ -3011,41 +4156,73 @@ check indicators that are part of the internal state of the stream
 object, indicators set if the appropriate condition was detected by a
 previous I/O operation on that stream.
 
-These symbols are declared in the header file @file{stdio.h}.
-@pindex stdio.h
-
 @comment stdio.h
 @comment ISO
 @deftypevr Macro int EOF
-This macro is an integer value that is returned by a number of functions
-to indicate an end-of-file condition, or some other error situation.
-With the GNU library, @code{EOF} is @code{-1}.  In other libraries, its
-value may be some other negative number.
+This macro is an integer value that is returned by a number of narrow
+stream functions to indicate an end-of-file condition, or some other
+error situation.  With @theglibc{}, @code{EOF} is @code{-1}.  In
+other libraries, its value may be some other negative number.
+
+This symbol is declared in @file{stdio.h}.
 @end deftypevr
 
-@comment stdio.h
+@comment wchar.h
 @comment ISO
-@deftypefun void clearerr (FILE *@var{stream})
-This function clears the end-of-file and error indicators for the
-stream @var{stream}.
+@deftypevr Macro int WEOF
+This macro is an integer value that is returned by a number of wide
+stream functions to indicate an end-of-file condition, or some other
+error situation.  With @theglibc{}, @code{WEOF} is @code{-1}.  In
+other libraries, its value may be some other negative number.
 
-The file positioning functions (@pxref{File Positioning}) also clear the
-end-of-file indicator for the stream.
-@end deftypefun
+This symbol is declared in @file{wchar.h}.
+@end deftypevr
 
 @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.
+
+This symbol is declared in @file{stdio.h}.
+@end deftypefun
+
+@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.
+
+This function is a GNU extension.
+
+This symbol is declared in @file{stdio.h}.
 @end deftypefun
 
 @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.
+
+This symbol is declared in @file{stdio.h}.
+@end deftypefun
+
+@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.
+
+This function is a GNU extension.
+
+This symbol is declared in @file{stdio.h}.
 @end deftypefun
 
 In addition to setting the error indicator associated with the stream,
@@ -3058,10 +4235,60 @@ conditions defined for @code{write} are meaningful for these functions.
 For more information about the descriptor-level I/O functions, see
 @ref{Low-Level I/O}.
 
+@node Error Recovery
+@section Recovering from errors
+
+You may explicitly clear the error and EOF flags with the @code{clearerr}
+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}.
+
+The file positioning functions (@pxref{File Positioning}) also clear the
+end-of-file indicator for the stream.
+@end deftypefun
+
+@comment stdio.h
+@comment GNU
+@deftypefun void clearerr_unlocked (FILE *@var{stream})
+@safety{@prelim{}@mtsafe{@mtsrace{:stream}}@assafe{}@acsafe{}}
+The @code{clearerr_unlocked} function is equivalent to the @code{clearerr}
+function except that it does not implicitly lock the stream.
+
+This function is a GNU extension.
+@end deftypefun
+
+Note that it is @emph{not} correct to just clear the error flag and retry
+a failed stream operation.  After a failed write, any number of
+characters since the last buffer flush may have been committed to the
+file, while some buffered data may have been discarded.  Merely retrying
+can thus cause lost or repeated data.
+
+A failed read may leave the file pointer in an inappropriate position for
+a second try.  In both cases, you should seek to a known position before
+retrying.
+
+Most errors that can happen are not recoverable --- a second try will
+always fail again in the same way.  So usually it is best to give up and
+report the error to the user, rather than install complicated recovery
+logic.
+
+One important exception is @code{EINTR} (@pxref{Interrupted Primitives}).
+Many stream I/O implementations will treat it as an ordinary error, which
+can be quite inconvenient.  You can avoid this hassle by installing all
+signals with the @code{SA_RESTART} flag.
+
+For similar reasons, setting nonblocking I/O on a stream's file
+descriptor is not usually advisable.
+
 @node Binary Streams
 @section Text and Binary Streams
 
-The GNU system and other POSIX-compatible operating systems organize all
+@gnusystems{} and other POSIX-compatible operating systems organize all
 files as uniform sequences of characters.  However, some other systems
 make a distinction between files containing text and files containing
 binary data, and the input and output facilities of @w{ISO C} provide for
@@ -3110,7 +4337,7 @@ systems, text and binary streams use different file formats, and the
 only way to read or write ``an ordinary file of text'' that can work
 with other text-oriented programs is through a text stream.
 
-In the GNU library, and on all POSIX systems, there is no difference
+In @theglibc{}, and on all POSIX systems, there is no difference
 between text streams and binary streams.  When you open a stream, you
 get the same kind of stream regardless of whether you ask for binary.
 This stream can handle any file content, and has none of the
@@ -3124,7 +4351,7 @@ restrictions that text streams sometimes have.
 
 The @dfn{file position} of a stream describes where in the file the
 stream is currently reading or writing.  I/O on the stream advances the
-file position through the file.  In the GNU system, the file position is
+file position through the file.  On @gnusystems{}, the file position is
 represented as an integer, which counts the number of bytes from the
 beginning of the file.  @xref{File Position}.
 
@@ -3142,6 +4369,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}.
 
@@ -3154,18 +4382,16 @@ 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})
-The @code{ftello} function is similar to @code{ftell} only it corrects a
-problem which the POSIX type system.  In this type system all file
-positions are described using values of type @code{off_t} which is not
-necessarily of the same size as @code{long int}.  Therefore using
-@code{ftell} can lead to problems if the implementation is written on
-top of a POSIX compliant lowlevel I/O implementation.
-
-Therefore it is a good idea to prefer @code{ftello} whenever it is
-available since its functionality is (if different at all) closer the
-underlying definition.
-
-If this function fails it return @code{(off_t) -1}.  This can happen due
+@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
+which uses a long int.  The two are not necessarily the same size.
+Therefore, using ftell can lead to problems if the implementation is
+written on top of a POSIX compliant low-level I/O implementation, and using
+@code{ftello} is preferable whenever it is available.
+
+If this function fails it returns @code{(off_t) -1}.  This can happen due
 to missing support for file positioning or internal errors.  Otherwise
 the return value is the current file position.
 
@@ -3173,13 +4399,14 @@ The function is an extension defined in the Unix Single Specification
 version 2.
 
 When the sources are compiled with @code{_FILE_OFFSET_BITS == 64} on a
-32 bits system this function is in fact @code{ftello64}.  I.e., the
+32 bit system this function is in fact @code{ftello64}.  I.e., the
 LFS interface transparently replaces the old interface.
 @end deftypefun
 
 @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},
@@ -3195,6 +4422,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
@@ -3214,6 +4442,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.
@@ -3230,13 +4459,14 @@ The function is an extension defined in the Unix Single Specification
 version 2.
 
 When the sources are compiled with @code{_FILE_OFFSET_BITS == 64} on a
-32 bits system this function is in fact @code{fseeko64}.  I.e., the
+32 bit system this function is in fact @code{fseeko64}.  I.e., the
 LFS interface transparently replaces the old interface.
 @end deftypefun
 
 @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
@@ -3285,6 +4515,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
@@ -3320,7 +4551,7 @@ An alias for @code{SEEK_END}.
 @node Portable Positioning
 @section Portable File-Position Functions
 
-On the GNU system, the file position is truly a character count.  You
+On @gnusystems{}, the file position is truly a character count.  You
 can specify any character count value as an argument to @code{fseek} or
 @code{fseeko} and get reliable results for any random access file.
 However, some @w{ISO C} systems do not represent file positions in this
@@ -3345,9 +4576,9 @@ the same file position.
 
 @item
 In a call to @code{fseek} or @code{fseeko} on a text stream, either the
-@var{offset} must either be zero; or @var{whence} must be
-@code{SEEK_SET} and the @var{offset} must be the result of an earlier
-call to @code{ftell} on the same stream.
+@var{offset} must be zero, or @var{whence} must be @code{SEEK_SET} and
+the @var{offset} must be the result of an earlier call to @code{ftell}
+on the same stream.
 
 @item
 The value of the file position indicator of a text stream is undefined
@@ -3380,13 +4611,14 @@ This is the type of an object that can encode information about the
 file position of a stream, for use by the functions @code{fgetpos} and
 @code{fsetpos}.
 
-In the GNU system, @code{fpos_t} is equivalent to @code{off_t} or
-@code{long int}.  In other systems, it might have a different internal
+In @theglibc{}, @code{fpos_t} is an opaque data structure that
+contains internal data to represent file offset and conversion state
+information.  In other systems, it might have a different internal
 representation.
 
-When compiling with @code{_FILE_OFFSET_BITS == 64} on a 32 bits machine
-this type is in fact equivalent to @code{off64_t} since the LFS
-interface transparently replaced the old interface.
+When compiling with @code{_FILE_OFFSET_BITS == 64} on a 32 bit machine
+this type is in fact equivalent to @code{fpos64_t} since the LFS
+interface transparently replaces the old interface.
 @end deftp
 
 @comment stdio.h
@@ -3396,14 +4628,16 @@ This is the type of an object that can encode information about the
 file position of a stream, for use by the functions @code{fgetpos64} and
 @code{fsetpos64}.
 
-In the GNU system, @code{fpos64_t} is equivalent to @code{off64_t} or
-@code{long long int}.  In other systems, it might have a different internal
+In @theglibc{}, @code{fpos64_t} is an opaque data structure that
+contains internal data to represent file offset and conversion state
+information.  In other systems, it might have a different internal
 representation.
 @end deftp
 
 @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
@@ -3411,13 +4645,14 @@ it returns a nonzero value and stores an implementation-defined positive
 value in @code{errno}.
 
 When the sources are compiled with @code{_FILE_OFFSET_BITS == 64} on a
-32 bits system the function is in fact @code{fgetpos64}.  I.e., the LFS
-interface transparently replaced the old interface.
+32 bit system the function is in fact @code{fgetpos64}.  I.e., the LFS
+interface transparently replaces the old interface.
 @end deftypefun
 
 @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.
@@ -3430,6 +4665,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}
@@ -3439,13 +4675,14 @@ of zero.  Otherwise, @code{fsetpos} returns a nonzero value and stores
 an implementation-defined positive value in @code{errno}.
 
 When the sources are compiled with @code{_FILE_OFFSET_BITS == 64} on a
-32 bits system the function is in fact @code{fsetpos64}.  I.e., the LFS
-interface transparently replaced the old interface.
+32 bit system the function is in fact @code{fsetpos64}.  I.e., the LFS
+interface transparently replaces the old interface.
 @end deftypefun
 
 @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.
@@ -3469,7 +4706,7 @@ If you are writing programs that do interactive input and output using
 streams, you need to understand how buffering works when you design the
 user interface to your program.  Otherwise, you might find that output
 (such as progress or prompt messages) doesn't appear when you intended
-it to, or other unexpected behavior.
+it to, or displays some other unexpected behavior.
 
 This section deals only with controlling when characters are transmitted
 between the stream and the file or device, and @emph{not} with how
@@ -3557,6 +4794,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
@@ -3566,12 +4804,57 @@ This function returns @code{EOF} if a write error occurs, or zero
 otherwise.
 @end deftypefun
 
+@comment stdio.h
+@comment POSIX
+@deftypefun int fflush_unlocked (FILE *@var{stream})
+@safety{@prelim{}@mtsafe{@mtsrace{: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
+
+The @code{fflush} function can be used to flush all streams currently
+opened.  While this is useful in some situations it does often more than
+necessary since it might be done in situations when terminal input is
+required and the program wants to be sure that all output is visible on
+the terminal.  But this means that only line buffered streams have to be
+flushed.  Solaris introduced a function especially for this.  It was
+always available in @theglibc{} in some form but never officially
+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.
+
+This function is declared in the @file{stdio_ext.h} header.
+@end deftypefun
+
 @strong{Compatibility Note:} Some brain-damaged operating systems have
 been known to be so thoroughly fixated on line-oriented input and output
 that flushing a line buffered stream causes a newline to be written!
 Fortunately, this ``feature'' seems to be becoming less common.  You do
-not need to worry about this in the GNU system.
+not need to worry about this with @theglibc{}.
 
+In some situations it might be useful to not flush the output pending
+for a stream but instead simply forget it.  If transmission is costly
+and the output is not needed anymore this is valid reasoning.  In this
+situation a non-standard function introduced in Solaris and available in
+@theglibc{} can be used.
+
+@comment stdio_ext.h
+@comment GNU
+@deftypefun void __fpurge (FILE *@var{stream})
+@safety{@prelim{}@mtsafe{@mtsrace{:stream}}@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
+buffered output is not written to the device (or whatever other
+underlying storage) and the buffer the cleared.
+
+This function is declared in @file{stdio_ext.h}.
+@end deftypefun
 
 @node Controlling Buffering
 @subsection Controlling Which Kind of Buffering
@@ -3588,6 +4871,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
@@ -3665,6 +4949,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}
@@ -3678,6 +4963,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}.
@@ -3689,6 +4975,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.
 
@@ -3696,10 +4983,51 @@ This function is provided for compatibility with old BSD code.  Use
 @code{setvbuf} instead.
 @end deftypefun
 
+It is possible to query whether a given stream is line buffered or not
+using a non-standard function introduced in Solaris and available in
+@theglibc{}.
+
+@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.
+
+This function is declared in the @file{stdio_ext.h} header.
+@end deftypefun
+
+Two more extensions allow to determine the size of the buffer and how
+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{}@mtsafe{@mtsrace{:stream}}@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.
+
+This function is declared in the @file{stdio_ext.h} header.
+@end deftypefun
+
+@comment stdio_ext.h
+@comment GNU
+@deftypefun size_t __fpending (FILE *@var{stream})
+@safety{@prelim{}@mtsafe{@mtsrace{:stream}}@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
+function should not be used on buffers in read mode or opened read-only.
+
+This function is declared in the @file{stdio_ext.h} header.
+@end deftypefun
+
 @node Other Kinds of Streams
 @section Other Kinds of Streams
 
-The GNU library provides ways for you to define additional kinds of
+@Theglibc{} provides ways for you to define additional kinds of
 streams that do not necessarily correspond to an open file.
 
 One such type of stream takes input from or writes output to a string.
@@ -3717,10 +5045,9 @@ provide equivalent functionality.
 
 @menu
 * String Streams::              Streams that get data from or put data in
-                                 a string or memory buffer.
-* Obstack Streams::            Streams that store data in an obstack.
+                                a string or memory buffer.
 * Custom Streams::              Defining your own streams with an arbitrary
-                                 input data source and/or output data sink.
+                                input data source and/or output data sink.
 @end menu
 
 @node String Streams
@@ -3736,17 +5063,21 @@ 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{}}@acunsafe{@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.
 
 If you specify a null pointer as the @var{buf} argument, @code{fmemopen}
-dynamically allocates (as with @code{malloc}; @pxref{Unconstrained
-Allocation}) an array @var{size} bytes long.  This is really only useful
+dynamically allocates an array @var{size} bytes long (as with @code{malloc};
+@pxref{Unconstrained Allocation}).  This is really only useful
 if you are going to write things to the buffer and then read them back
 in again, because you have no way of actually getting a pointer to the
 buffer (for this, try @code{open_memstream}, below).  The buffer is
-freed when the stream is open.
+freed when the stream is closed.
 
 The argument @var{opentype} is the same as in @code{fopen}
 (@pxref{Opening Streams}).  If the @var{opentype} specifies
@@ -3788,9 +5119,11 @@ Got r
 @comment stdio.h
 @comment GNU
 @deftypefun {FILE *} open_memstream (char **@var{ptr}, size_t *@var{sizeloc})
+@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{}}}
 This function opens a stream for writing to a buffer.  The buffer is
-allocated dynamically (as with @code{malloc}; @pxref{Unconstrained
-Allocation}) and grown as necessary.
+allocated dynamically and grown as necessary, using @code{malloc}.
+After you've closed the stream, this buffer is your responsibility to
+clean up using @code{free} or @code{realloc}.  @xref{Unconstrained Allocation}.
 
 When the stream is closed with @code{fclose} or flushed with
 @code{fflush}, the locations @var{ptr} and @var{sizeloc} are updated to
@@ -3821,64 +5154,6 @@ buf = `hello', size = 5
 buf = `hello, world', size = 12
 @end smallexample
 
-@c @group  Invalid outside @example.
-@node Obstack Streams
-@subsection Obstack Streams
-
-You can open an output stream that puts it data in an obstack.
-@xref{Obstacks}.
-
-@comment stdio.h
-@comment GNU
-@deftypefun {FILE *} open_obstack_stream (struct obstack *@var{obstack})
-This function opens a stream for writing data into the obstack @var{obstack}.
-This starts an object in the obstack and makes it grow as data is
-written (@pxref{Growing Objects}).
-@c @end group  Doubly invalid because not nested right.
-
-Calling @code{fflush} on this stream updates the current size of the
-object to match the amount of data that has been written.  After a call
-to @code{fflush}, you can examine the object temporarily.
-
-You can move the file position of an obstack stream with @code{fseek} or
-@code{fseeko} (@pxref{File Positioning}).  Moving the file position past
-the end of the data written fills the intervening space with zeros.
-
-To make the object permanent, update the obstack with @code{fflush}, and
-then use @code{obstack_finish} to finalize the object and get its address.
-The following write to the stream starts a new object in the obstack,
-and later writes add to that object until you do another @code{fflush}
-and @code{obstack_finish}.
-
-But how do you find out how long the object is?  You can get the length
-in bytes by calling @code{obstack_object_size} (@pxref{Status of an
-Obstack}), or you can null-terminate the object like this:
-
-@smallexample
-obstack_1grow (@var{obstack}, 0);
-@end smallexample
-
-Whichever one you do, you must do it @emph{before} calling
-@code{obstack_finish}.  (You can do both if you wish.)
-@end deftypefun
-
-Here is a sample function that uses @code{open_obstack_stream}:
-
-@smallexample
-char *
-make_message_string (const char *a, int b)
-@{
-  FILE *stream = open_obstack_stream (&message_obstack);
-  output_task (stream);
-  fprintf (stream, ": ");
-  fprintf (stream, a, b);
-  fprintf (stream, "\n");
-  fclose (stream);
-  obstack_1grow (&message_obstack, 0);
-  return obstack_finish (&message_obstack);
-@}
-@end smallexample
-
 @node Custom Streams
 @subsection Programming Your Own Custom Streams
 @cindex custom streams
@@ -3886,15 +5161,16 @@ make_message_string (const char *a, int b)
 
 This section describes how you can make a stream that gets input from an
 arbitrary data source or writes output to an arbitrary data sink
-programmed by you.  We call these @dfn{custom streams}.
+programmed by you.  We call these @dfn{custom streams}.  The functions
+and types described here are all GNU extensions.
 
 @c !!! this does not talk at all about the higher-level hooks
 
 @menu
 * Streams and Cookies::         The @dfn{cookie} records where to fetch or
-                                 store data that is read or written.
+                                store data that is read or written.
 * Hook Functions::              How you should define the four @dfn{hook
-                                 functions} that a custom stream needs.
+                                functions} that a custom stream needs.
 @end menu
 
 @node Streams and Cookies
@@ -3959,6 +5235,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};
@@ -3979,7 +5256,7 @@ that a custom stream needs.
 You should define the function to read data from the cookie as:
 
 @smallexample
-ssize_t @var{reader} (void *@var{cookie}, void *@var{buffer}, size_t @var{size})
+ssize_t @var{reader} (void *@var{cookie}, char *@var{buffer}, size_t @var{size})
 @end smallexample
 
 This is very similar to the @code{read} function; see @ref{I/O
@@ -3991,26 +5268,24 @@ an error.
 You should define the function to write data to the cookie as:
 
 @smallexample
-ssize_t @var{writer} (void *@var{cookie}, const void *@var{buffer}, size_t @var{size})
+ssize_t @var{writer} (void *@var{cookie}, const char *@var{buffer}, size_t @var{size})
 @end smallexample
 
 This is very similar to the @code{write} function; see @ref{I/O
 Primitives}.  Your function should transfer up to @var{size} bytes from
 the buffer, and return the number of bytes written.  You can return a
-value of @code{-1} to indicate an error.
+value of @code{0} to indicate an error.  You must not return any
+negative value.
 
 You should define the function to perform seek operations on the cookie
 as:
 
 @smallexample
-int @var{seeker} (void *@var{cookie}, fpos_t *@var{position}, int @var{whence})
+int @var{seeker} (void *@var{cookie}, off64_t *@var{position}, int @var{whence})
 @end smallexample
 
 For this function, the @var{position} and @var{whence} arguments are
-interpreted as for @code{fgetpos}; see @ref{Portable Positioning}.  In
-the GNU library, @code{fpos_t} is equivalent to @code{off_t} or
-@code{long int}, and simply represents the number of bytes from the
-beginning of the file.
+interpreted as for @code{fgetpos}; see @ref{Portable Positioning}.
 
 After doing the seek operation, your function should store the resulting
 file position relative to the beginning of the file in @var{position}.
@@ -4142,11 +5417,12 @@ 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
 colon separated parts where the first part has not more than 10 and the
-second part not more the 14 characters.  The @var{text} parameter
+second part not more than 14 characters.  The @var{text} parameter
 describes the condition of the error, the @var{action} parameter possible
 steps to recover from the error and the @var{tag} parameter is a
 reference to the online documentation where more information can be
@@ -4174,7 +5450,7 @@ Ignore @var{tag} parameter.
 
 There is another way certain fields can be omitted from the output to
 standard error.  This is described below in the description of
-environment variables influencing the behaviour.
+environment variables influencing the behavior.
 
 The @var{severity} parameter can have one of the values in the following
 table:
@@ -4212,7 +5488,7 @@ inserted if necessary, i.e., if the corresponding parameter is not
 ignored.
 
 This function is specified in the X/Open Portability Guide.  It is also
-available on all system derived from System V.
+available on all systems derived from System V.
 
 The function returns the value @code{MM_OK} if no error occurred.  If
 only the printing to standard error failed, it returns @code{MM_NOMSG}.
@@ -4222,16 +5498,16 @@ all outputs fail this last value is also returned if a parameter value
 is incorrect.
 @end deftypefun
 
-There are two environment variables which influence the behaviour of
+There are two environment variables which influence the behavior of
 @code{fmtmsg}.  The first is @code{MSGVERB}.  It is used to control the
 output actually happening on standard error (@emph{not} the console
-output).  Each of the five fields can explicitely be enabled.  To do
+output).  Each of the five fields can explicitly be enabled.  To do
 this the user has to put the @code{MSGVERB} variable with a format like
 the following in the environment before calling the @code{fmtmsg} function
 the first time:
 
 @smallexample
-MSGVERB=@var{keyword}[:@var{keyword}[:...]]
+MSGVERB=@var{keyword}[:@var{keyword}[:@dots{}]]
 @end smallexample
 
 Valid @var{keyword}s are @code{label}, @code{severity}, @code{text},
@@ -4239,9 +5515,9 @@ Valid @var{keyword}s are @code{label}, @code{severity}, @code{text},
 or is the empty string, a not supported keyword is given or the value is
 somehow else invalid, no part of the message is masked out.
 
-The second environment variable which influences the behaviour of
+The second environment variable which influences the behavior of
 @code{fmtmsg} is @code{SEV_LEVEL}.  This variable and the change in the
-behaviour of @code{fmtmsg} is not specified in the X/Open Portability
+behavior of @code{fmtmsg} is not specified in the X/Open Portability
 Guide.  It is available in System V systems, though.  It can be used to
 introduce new severity levels.  By default, only the five severity levels
 described above are available.  Any other numeric value would make
@@ -4250,7 +5526,7 @@ described above are available.  Any other numeric value would make
 If the user puts @code{SEV_LEVEL} with a format like
 
 @smallexample
-SEV_LEVEL=[@var{description}[:@var{description}[:...]]]
+SEV_LEVEL=[@var{description}[:@var{description}[:@dots{}]]]
 @end smallexample
 
 @noindent
@@ -4275,17 +5551,18 @@ not print the numeric value but instead the string representation).
 @subsection Adding Severity Classes
 @cindex severity class
 
-There is another possibility to introduce severity classes beside using
+There is another possibility to introduce severity classes besides using
 the environment variable @code{SEV_LEVEL}.  This simplifies the task of
 introducing new classes in a running program.  One could use the
 @code{setenv} or @code{putenv} function to set the environment variable,
 but this is toilsome.
 
 @deftypefun int addseverity (int @var{severity}, const char *@var{string})
-This function allows to introduce new severity classes which can be
+@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
-for the parameter with the same name of @code{fmtmsg} and @var{string}
+for the parameter with the same name of @code{fmtmsg}, and @var{string}
 is the string printed in the actual messages instead of the numeric
 value.
 
@@ -4316,14 +5593,14 @@ functions described in this section.
 @include fmtmsgexpl.c.texi
 @end smallexample
 
-The second call to @code{fmtmsg} illustrates a use of this function how
-it usually happens on System V systems which heavily use this function.
-It might be worth a thought to follow the scheme used in System V
-systems so we give a short explanation here.  The value of the
-@var{label} field (@code{UX:cat}) says that the error occured in the
+The second call to @code{fmtmsg} illustrates a use of this function as
+it usually occurs on System V systems, which heavily use this function.
+It seems worthwhile to give a short explanation here of how this system
+works on System V.  The value of the
+@var{label} field (@code{UX:cat}) says that the error occurred in the
 Unix program @code{cat}.  The explanation of the error follows and the
 value for the @var{action} parameter is @code{"refer to manual"}.  One
-could me more specific here, if needed.  The @var{tag} field contains,
+could be more specific here, if necessary.  The @var{tag} field contains,
 as proposed above, the value of the string given for the @var{label}
 parameter, and additionally a unique ID (@code{001} in this case).  For
 a GNU environment this string could contain a reference to the
@@ -4346,8 +5623,8 @@ form.  The string must contain two fields, separated by a colon
 (@pxref{Printing Formatted Messages}).  The third @code{fmtmsg} call
 produced no output since the class with the numeric value @code{6} is
 not defined.  Although a class with numeric value @code{5} is also not
-defined by default, the call the @code{addseverity} introduces it and
-the second call to @code{fmtmsg} produces the above outout.
+defined by default, the call to @code{addseverity} introduces it and
+the second call to @code{fmtmsg} produces the above output.
 
 When we change the environment of the program to contain
 @code{SEV_LEVEL=XXX,6,NOTE} when running it we get a different result:
@@ -4359,11 +5636,11 @@ label:foo: NOTE: text
 TO FIX: action tag
 @end smallexample
 
-Now the third call the @code{fmtmsg} produced some output and we see how
+Now the third call to @code{fmtmsg} produced some output and we see how
 the string @code{NOTE} from the environment variable appears in the
 message.
 
-Now we can reduce the output by specifying in which fields we are
+Now we can reduce the output by specifying which fields we are
 interested in.  If we additionally set the environment variable
 @code{MSGVERB} to the value @code{severity:label:action} we get the
 following output:
@@ -4379,5 +5656,5 @@ TO FIX: action
 I.e., the output produced by the @var{text} and the @var{tag} parameters
 to @code{fmtmsg} vanished.  Please also note that now there is no colon
 after the @code{NOTE} and @code{NOTE2} strings in the output.  This is
-not necessary since there is no more output on this line since the text
+not necessary since there is no more output on this line because the text
 is missing.