Loading...
--- Libc/Libc-594.9.5/stdio/printf.3
+++ Libc/Libc-262.3.2/stdio/printf.3
@@ -34,97 +34,51 @@
.\" SUCH DAMAGE.
.\"
.\" @(#)printf.3 8.1 (Berkeley) 6/4/93
-.\" $FreeBSD: src/lib/libc/stdio/printf.3,v 1.58 2004/10/16 16:00:01 stefanf Exp $
+.\" $FreeBSD: src/lib/libc/stdio/printf.3,v 1.17.2.10 2001/12/14 18:33:57 ru Exp $
.\"
-.Dd October 16, 2004
+.Dd June 4, 1993
.Dt PRINTF 3
.Os
.Sh NAME
-.Nm asprintf ,
-.Nm fprintf ,
-.Nm printf ,
-.Nm snprintf ,
-.Nm sprintf ,
-.Nm vasprintf ,
-.Nm vfprintf,
-.Nm vprintf ,
-.Nm vsnprintf ,
-.Nm vsprintf
+.Nm printf , fprintf , sprintf , snprintf , asprintf ,
+.Nm vprintf , vfprintf, vsprintf , vsnprintf , vasprintf
.Nd formatted output conversion
.Sh LIBRARY
.Lb libc
.Sh SYNOPSIS
.In stdio.h
.Ft int
-.Fo asprintf
-.Fa "char **ret"
-.Fa "const char *format" ...
-.Fc
-.Ft int
-.Fo fprintf
-.Fa "FILE *restrict stream"
-.Fa "const char *restrict format" ...
-.Fc
-.Ft int
-.Fo printf
-.Fa "const char *restrict format" ...
-.Fc
-.Ft int
-.Fo snprintf
-.Fa "char *restrict s"
-.Fa "size_t n"
-.Fa "const char *restrict format" ...
-.Fc
-.Ft int
-.Fo sprintf
-.Fa "char *restrict s"
-.Fa "const char *restrict format" ...
-.Fc
+.Fn printf "const char *format" ...
+.Ft int
+.Fn fprintf "FILE *stream" "const char *format" ...
+.Ft int
+.Fn sprintf "char *str" "const char *format" ...
+.Ft int
+.Fn snprintf "char *str" "size_t size" "const char *format" ...
+.Ft int
+.Fn asprintf "char **ret" "const char *format" ...
.In stdarg.h
-.In stdio.h
-.Ft int
-.Fo vasprintf
-.Fa "char **ret"
-.Fa "const char *format"
-.Fa "va_list ap"
-.Fc
-.Ft int
-.Fo vfprintf
-.Fa "FILE *restrict stream"
-.Fa "const char *restrict format"
-.Fa "va_list ap"
-.Fc
-.Ft int
-.Fo vprintf
-.Fa "const char *restrict format"
-.Fa "va_list ap"
-.Fc
-.Ft int
-.Fo vsnprintf
-.Fa "char *restrict s"
-.Fa "size_t n"
-.Fa "const char *restrict format"
-.Fa "va_list ap"
-.Fc
-.Ft int
-.Fo vsprintf
-.Fa "char *restrict s"
-.Fa "const char *restrict format"
-.Fa "va_list ap"
-.Fc
+.Ft int
+.Fn vprintf "const char *format" "va_list ap"
+.Ft int
+.Fn vfprintf "FILE *stream" "const char *format" "va_list ap"
+.Ft int
+.Fn vsprintf "char *str" "const char *format" "va_list ap"
+.Ft int
+.Fn vsnprintf "char *str" "size_t size" "const char *format" "va_list ap"
+.Ft int
+.Fn vasprintf "char **ret" "const char *format" "va_list ap"
.Sh DESCRIPTION
The
.Fn printf
family of functions produces output according to a
-.Fa format ,
+.Fa format
as described below.
-The
-.Fn printf
+.Fn Printf
and
.Fn vprintf
-functions
write output to
-.Dv stdout ,
+.Pa stdout ,
the standard output stream;
.Fn fprintf
and
@@ -137,19 +91,13 @@
and
.Fn vsnprintf
write to the character string
-.Fa s ;
+.Fa str ;
and
.Fn asprintf
and
.Fn vasprintf
dynamically allocate a new string with
.Xr malloc 3 .
-.Pp
-Extended locale versions of these functions are documented in
-.Xr printf_l 3 .
-See
-.Xr xlocale 3
-for more information.
.Pp
These functions write the output under the control of a
.Fa format
@@ -161,22 +109,20 @@
These functions return the number of characters printed
(not including the trailing
.Ql \e0
-used to end output to strings) or a negative value if an output error occurs,
+used to end output to strings),
except for
.Fn snprintf
and
.Fn vsnprintf ,
which return the number of characters that would have been printed if the
-.Fa n
+.Fa size
were unlimited
(again, not including the final
.Ql \e0 ) .
.Pp
-The
-.Fn asprintf
+.Fn Asprintf
and
.Fn vasprintf
-functions
set
.Fa *ret
to be a pointer to a buffer sufficiently large to hold the formatted string.
@@ -187,41 +133,32 @@
.Fn asprintf
and
.Fn vasprintf
-will return \-1 and set
+will return -1 and set
.Fa ret
to be a
.Dv NULL
pointer.
.Pp
-The
-.Fn snprintf
+.Fn Snprintf
and
.Fn vsnprintf
-functions
will write at most
-.Fa n Ns \-1
+.Fa size Ns \-1
of the characters printed into the output string
(the
-.Fa n Ns \'th
+.Fa size Ns 'th
character then gets the terminating
.Ql \e0 ) ;
if the return value is greater than or equal to the
-.Fa n
+.Fa size
argument, the string was too short
and some of the printed characters were discarded.
-The output is always null-terminated.
-.Pp
-The
-.Fn sprintf
+.Pp
+.Fn Sprintf
and
.Fn vsprintf
-functions
effectively assume an infinite
-.Fa n .
-.Pp
-For those routines that write to a user-provided character string,
-that string and the format strings should not overlap, as the
-behavior is undefined.
+.Fa size .
.Pp
The format string is composed of zero or more directives:
ordinary
@@ -253,9 +190,12 @@
are accessed the results will be indeterminate.
.It
Zero or more of the following flags:
-.Bl -tag -width ".So \ Sc (space)"
-.It Sq Cm #
-The value should be converted to an
+.Bl -hyphen
+.It
+A
+.Cm #
+character
+specifying that the value should be converted to an
.Dq alternate form .
For
.Cm c , d , i , n , p , s ,
@@ -279,7 +219,7 @@
.Cm X
conversions) prepended to it.
For
-.Cm a , A , e , E , f , F , g ,
+.Cm e , E , f , g ,
and
.Cm G
conversions, the result will always contain a decimal point, even if no
@@ -291,8 +231,11 @@
.Cm G
conversions, trailing zeros are not removed from the result as they
would otherwise be.
-.It So Cm 0 Sc (zero)
-Zero padding.
+.It
+A
+.Cm 0
+(zero)
+character specifying zero padding.
For all conversions except
.Cm n ,
the converted value is padded on the left with zeros rather than blanks.
@@ -303,9 +246,10 @@
the
.Cm 0
flag is ignored.
-.It Sq Cm \-
-A negative field width flag;
-the converted value is to be left adjusted on the field boundary.
+.It
+A negative field width flag
+.Cm \-
+indicates the converted value is to be left adjusted on the field boundary.
Except for
.Cm n
conversions, the converted value is padded on the right with blanks,
@@ -315,45 +259,21 @@
overrides a
.Cm 0
if both are given.
-.It So "\ " Sc (space)
-A blank should be left before a positive number
+.It
+A space, specifying that a blank should be left before a positive number
produced by a signed conversion
-.Cm ( a , A , d , e , E , f , F , g , G ,
+.Cm ( d , e , E , f , g , G ,
or
.Cm i ) .
-.It Sq Cm +
-A sign must always be placed before a
+.It
+A
+.Cm +
+character specifying that a sign always be placed before a
number produced by a signed conversion.
A
.Cm +
overrides a space if both are used.
-.It Sq Cm '
-Decimal conversions
-.Cm ( d , u ,
-or
-.Cm i )
-or the integral portion of a floating point conversion
-.Cm ( f
-or
-.Cm F )
-should be grouped and separated by thousands using
-the non-monetary separator returned by
-.Xr localeconv 3 .
.El
-.It
-An optional separator character (
-.Cm \ , | \; | \ : | _
-) used for separating multiple values when printing an AltiVec or SSE vector,
-or other multi-value unit.
-.Pp
-NOTE: This is an extension to the
-.Fn printf
-specification.
-Behaviour of these values for
-.Fn printf
-is only defined for operating systems conforming to the
-AltiVec Technology Programming Interface Manual.
-(At time of writing this includes only Mac OS X 10.2 and later.)
.It
An optional decimal digit string specifying a minimum field width.
If the converted value has fewer characters than the field width, it will
@@ -371,9 +291,9 @@
and
.Cm X
conversions, the number of digits to appear after the decimal-point for
-.Cm a , A , e , E , f ,
-and
-.Cm F
+.Cm e , E ,
+and
+.Cm f
conversions, the maximum number of significant digits for
.Cm g
and
@@ -383,98 +303,79 @@
.Cm s
conversions.
.It
-An optional length modifier, that specifies the size of the argument.
-The following length modifiers are valid for the
-.Cm d , i , n , o , u , x ,
-or
-.Cm X
-conversion:
-.Bl -column ".Cm q Em (deprecated)" ".Vt signed char" ".Vt unsigned long long" ".Vt long long *"
-.It Sy Modifier Ta Cm d , i Ta Cm o , u , x , X Ta Cm n
-.It Cm hh Ta Vt "signed char" Ta Vt "unsigned char" Ta Vt "signed char *"
-.It Cm h Ta Vt short Ta Vt "unsigned short" Ta Vt "short *"
-.It Cm l No (ell) Ta Vt long Ta Vt "unsigned long" Ta Vt "long *"
-.It Cm ll No (ell ell) Ta Vt "long long" Ta Vt "unsigned long long" Ta Vt "long long *"
-.It Cm j Ta Vt intmax_t Ta Vt uintmax_t Ta Vt "intmax_t *"
-.It Cm t Ta Vt ptrdiff_t Ta (see note) Ta Vt "ptrdiff_t *"
-.It Cm z Ta (see note) Ta Vt size_t Ta (see note)
-.It Cm q Em (deprecated) Ta Vt quad_t Ta Vt u_quad_t Ta Vt "quad_t *"
-.El
-.Pp
-Note:
-the
-.Cm t
-modifier, when applied to a
-.Cm o , u , x ,
-or
-.Cm X
-conversion, indicates that the argument is of an unsigned type
-equivalent in size to a
-.Vt ptrdiff_t .
-The
-.Cm z
-modifier, when applied to a
-.Cm d
-or
-.Cm i
-conversion, indicates that the argument is of a signed type equivalent in
-size to a
-.Vt size_t .
-Similarly, when applied to an
+The optional character
+.Cm h ,
+specifying that a following
+.Cm d , i , o , u , x ,
+or
+.Cm X
+conversion corresponds to a
+.Vt short int
+or
+.Vt unsigned short int
+argument, or that a following
.Cm n
-conversion, it indicates that the argument is a pointer to a signed type
-equivalent in size to a
-.Vt size_t .
-.Pp
-The following length modifier is valid for the
-.Cm a , A , e , E , f , F , g ,
+conversion corresponds to a pointer to a
+.Vt short int
+argument.
+.It
+The optional character
+.Cm l
+(ell) specifying that a following
+.Cm d , i , o , u , x ,
+or
+.Cm X
+conversion applies to a pointer to a
+.Vt long int
+or
+.Vt unsigned long int
+argument, or that a following
+.Cm n
+conversion corresponds to a pointer to a
+.Vt long int
+argument.
+.It
+The optional characters
+.Cm ll
+(ell ell) specifying that a following
+.Cm d , i , o , u , x ,
+or
+.Cm X
+conversion applies to a pointer to a
+.Vt long long int
+or
+.Vt unsigned long long int
+argument, or that a following
+.Cm n
+conversion corresponds to a pointer to a
+.Vt long long int
+argument.
+.It
+The optional character
+.Cm q ,
+specifying that a following
+.Cm d , i , o , u , x ,
+or
+.Cm X
+conversion corresponds to a
+.Vt quad int
+or
+.Vt unsigned quad int
+argument, or that a following
+.Cm n
+conversion corresponds to a pointer to a
+.Vt quad int
+argument.
+.It
+The character
+.Cm L
+specifying that a following
+.Cm e , E , f , g ,
or
.Cm G
-conversion:
-.Bl -column ".Sy Modifier" ".Cm a , A , e , E , f , F , g , G"
-.It Sy Modifier Ta Cm a , A , e , E , f , F , g , G
-.It Cm l No (ell) Ta Vt double
-(ignored, same behavior as without it)
-.It Cm L Ta Vt "long double"
-.El
-.Pp
-The following length modifier is valid for the
-.Cm c
-or
-.Cm s
-conversion:
-.Bl -column ".Sy Modifier" ".Vt wint_t" ".Vt wchar_t *"
-.It Sy Modifier Ta Cm c Ta Cm s
-.It Cm l No (ell) Ta Vt wint_t Ta Vt "wchar_t *"
-.El
-.Pp
-The AltiVec Technology Programming Interface Manual also defines five additional length modifiers
-which can be used (in place of the conventional length modifiers) for the printing of AltiVec or SSE vectors:
-.Bl -tag -compact
-.It Cm v
-Treat the argument as a vector value, unit length will be determined by the conversion
-specifier (default = 16 8-bit units for all integer conversions,
-4 32-bit units for floating point conversions).
-.It Cm vh, hv
-Treat the argument as a vector of 8 16-bit units.
-.It Cm vl, lv
-Treat the argument as a vector of 4 32-bit units.
-.El
-.Pp
-NOTE: The vector length specifiers are extensions to the
-.Fn printf
-specification.
-Behaviour of these values for
-.Fn printf
-is only defined for operating systems conforming to the
-AltiVec Technology Programming Interface Manual.
-(At time of writing this includes only Mac OS X 10.2 and later.)
-.Pp
-As a further extension, for SSE2 64-bit units:
-.Bl -tag -compact
-.It Cm vll, llv
-Treat the argument as a vector of 2 64-bit units.
-.El
+conversion corresponds to a
+.Vt long double
+argument.
.It
A character that specifies the type of conversion to be applied.
.El
@@ -492,12 +393,11 @@
A negative field width is treated as a left adjustment flag followed by a
positive field width; a negative precision is treated as though it were
missing.
-If a single format directive mixes positional
-.Pq Li nn$
+If a single format directive mixes positional (nn$)
and non-positional arguments, the results are undefined.
.Pp
The conversion specifiers and their meanings are:
-.Bl -tag -width ".Cm diouxX"
+.Bl -tag -width "diouxX"
.It Cm diouxX
The
.Vt int
@@ -515,11 +415,11 @@
.Cm X )
notation.
The letters
-.Dq Li abcdef
+.Cm abcdef
are used for
.Cm x
conversions; the letters
-.Dq Li ABCDEF
+.Cm ABCDEF
are used for
.Cm X
conversions.
@@ -528,7 +428,7 @@
the left with zeros.
.It Cm DOU
The
-.Vt "long int"
+.Vt long int
argument is converted to signed decimal, unsigned octal, or unsigned
decimal, as if the format had been
.Cm ld , lo ,
@@ -540,9 +440,7 @@
The
.Vt double
argument is rounded and converted in the style
-.Sm off
-.Oo \- Oc Ar d Li \&. Ar ddd Li e \\*[Pm] Ar dd
-.Sm on
+.Oo \- Oc Ns d Ns Cm \&. Ns ddd Ns Cm e Ns \\*[Pm]dd
where there is one digit before the
decimal-point character
and the number of digits after it is equal to the precision;
@@ -552,38 +450,17 @@
An
.Cm E
conversion uses the letter
-.Ql E
+.Cm E
(rather than
-.Ql e )
+.Cm e )
to introduce the exponent.
The exponent always contains at least two digits; if the value is zero,
the exponent is 00.
-.Pp
-For
-.Cm a , A , e , E , f , F , g ,
-and
-.Cm G
-conversions, positive and negative infinity are represented as
-.Li inf
-and
-.Li -inf
-respectively when using the lowercase conversion character, and
-.Li INF
-and
-.Li -INF
-respectively when using the uppercase conversion character.
-Similarly, NaN is represented as
-.Li nan
-when using the lowercase conversion, and
-.Li NAN
-when using the uppercase conversion.
-.It Cm fF
+.It Cm f
The
.Vt double
argument is rounded and converted to decimal notation in the style
-.Sm off
-.Oo \- Oc Ar ddd Li \&. Ar ddd ,
-.Sm on
+.Oo \- Oc Ns ddd Ns Cm \&. Ns ddd ,
where the number of digits after the decimal-point character
is equal to the precision specification.
If the precision is missing, it is taken as 6; if the precision is
@@ -597,8 +474,6 @@
or
.Cm e
(or
-.Cm F
-or
.Cm E
for
.Cm G
@@ -608,90 +483,19 @@
it is treated as 1.
Style
.Cm e
-is used if the exponent from its conversion is less than \-4 or greater than
+is used if the exponent from its conversion is less than -4 or greater than
or equal to the precision.
Trailing zeros are removed from the fractional part of the result; a
decimal point appears only if it is followed by at least one digit.
-.It Cm aA
-The
-.Vt double
-argument is rounded and converted to hexadecimal notation in the style
-.Sm off
-.Oo \- Oc Li 0x Ar h Li \&. Ar hhhp Oo \\*[Pm] Oc Ar d ,
-.Sm on
-where the number of digits after the hexadecimal-point character
-is equal to the precision specification.
-If the precision is missing, it is taken as enough to represent
-the floating-point number exactly, and no rounding occurs.
-If the precision is zero, no hexadecimal-point character appears.
-The
-.Cm p
-is a literal character
-.Ql p ,
-and the exponent consists of a positive or negative sign
-followed by a decimal number representing an exponent of 2.
-The
-.Cm A
-conversion uses the prefix
-.Dq Li 0X
-(rather than
-.Dq Li 0x ) ,
-the letters
-.Dq Li ABCDEF
-(rather than
-.Dq Li abcdef )
-to represent the hex digits, and the letter
-.Ql P
-(rather than
-.Ql p )
-to separate the mantissa and exponent.
-.Pp
-Note that there may be multiple valid ways to represent floating-point
-numbers in this hexadecimal format.
-For example,
-.Li 0x3.24p+0 , 0x6.48p-1
-and
-.Li 0xc.9p-2
-are all equivalent.
-The format chosen depends on the internal representation of the
-number, but the implementation guarantees that the length of the
-mantissa will be minimized.
-Zeroes are always represented with a mantissa of 0 (preceded by a
-.Ql -
-if appropriate) and an exponent of
-.Li +0 .
-.It Cm C
-Treated as
-.Cm c
-with the
-.Cm l
-(ell) modifier.
.It Cm c
The
.Vt int
argument is converted to an
-.Vt "unsigned char" ,
+.Vt unsigned char ,
and the resulting character is written.
-.Pp
-If the
-.Cm l
-(ell) modifier is used, the
-.Vt wint_t
-argument shall be converted to a
-.Vt wchar_t ,
-and the (potentially multi-byte) sequence representing the
-single wide character is written, including any shift sequences.
-If a shift sequence is used, the shift state is also restored
-to the original state after the character.
-.It Cm S
-Treated as
-.Cm s
-with the
-.Cm l
-(ell) modifier.
.It Cm s
The
-.Vt "char *"
+.Vt char *
argument is expected to be a pointer to an array of character type (pointer
to a string).
Characters from the array are written up to (but not including)
@@ -705,34 +509,9 @@
the size of the array, the array must contain a terminating
.Dv NUL
character.
-.Pp
-If the
-.Cm l
-(ell) modifier is used, the
-.Vt "wchar_t *"
-argument is expected to be a pointer to an array of wide characters
-(pointer to a wide string).
-For each wide character in the string, the (potentially multi-byte)
-sequence representing the
-wide character is written, including any shift sequences.
-If any shift sequence is used, the shift state is also restored
-to the original state after the string.
-Wide characters from the array are written up to (but not including)
-a terminating wide
-.Dv NUL
-character;
-if a precision is specified, no more than the number of bytes specified are
-written (including shift sequences).
-Partial characters are never written.
-If a precision is given, no null character
-need be present; if the precision is not specified, or is greater than
-the number of bytes required to render the multibyte representation of
-the string, the array must contain a terminating wide
-.Dv NUL
-character.
.It Cm p
The
-.Vt "void *"
+.Vt void *
pointer argument is printed in hexadecimal (as if by
.Ql %#x
or
@@ -740,7 +519,7 @@
.It Cm n
The number of characters written so far is stored into the
integer indicated by the
-.Vt "int *"
+.Vt int *
(or variant) pointer argument.
No argument is converted.
.It Cm %
@@ -753,13 +532,8 @@
.Ql %% .
.El
.Pp
-The decimal point
-character is defined in the program's locale (category
-.Dv LC_NUMERIC ) .
-.Pp
In no case does a non-existent or small field width cause truncation of
-a numeric field; if the result of a conversion is wider than the field
-width, the
+a field; if the result of a conversion is wider than the field width, the
field is expanded to contain the conversion result.
.Sh EXAMPLES
To print a date and time in the form
@@ -790,111 +564,21 @@
#include <stdarg.h>
char *newfmt(const char *fmt, ...)
{
- char *p;
- va_list ap;
- if ((p = malloc(128)) == NULL)
- return (NULL);
- va_start(ap, fmt);
- (void) vsnprintf(p, 128, fmt, ap);
- va_end(ap);
- return (p);
+ char *p;
+ va_list ap;
+ if ((p = malloc(128)) == NULL)
+ return (NULL);
+ va_start(ap, fmt);
+ (void) vsnprintf(p, 128, fmt, ap);
+ va_end(ap);
+ return (p);
}
.Ed
-.Sh SECURITY CONSIDERATIONS
-The
-.Fn sprintf
-and
-.Fn vsprintf
-functions are easily misused in a manner which enables malicious users
-to arbitrarily change a running program's functionality through
-a buffer overflow attack.
-Because
-.Fn sprintf
-and
-.Fn vsprintf
-assume an infinitely long string,
-callers must be careful not to overflow the actual space;
-this is often hard to assure.
-For safety, programmers should use the
-.Fn snprintf
-interface instead.
-For example:
-.Bd -literal
-void
-foo(const char *arbitrary_string, const char *and_another)
-{
- char onstack[8];
-
-#ifdef BAD
- /*
- * This first sprintf is bad behavior. Do not use sprintf!
- */
- sprintf(onstack, "%s, %s", arbitrary_string, and_another);
-#else
- /*
- * The following two lines demonstrate better use of
- * snprintf().
- */
- snprintf(onstack, sizeof(onstack), "%s, %s", arbitrary_string,
- and_another);
-#endif
-}
-.Ed
-.Pp
-The
-.Fn printf
-and
-.Fn sprintf
-family of functions are also easily misused in a manner
-allowing malicious users to arbitrarily change a running program's
-functionality by either causing the program
-to print potentially sensitive data
-.Dq "left on the stack" ,
-or causing it to generate a memory fault or bus error
-by dereferencing an invalid pointer.
-.Pp
-.Cm %n
-can be used to write arbitrary data to potentially carefully-selected
-addresses.
-Programmers are therefore strongly advised to never pass untrusted strings
-as the
-.Fa format
-argument, as an attacker can put format specifiers in the string
-to mangle your stack,
-leading to a possible security hole.
-This holds true even if the string was built using a function like
-.Fn snprintf ,
-as the resulting string may still contain user-supplied conversion specifiers
-for later interpolation by
-.Fn printf .
-.Pp
-Always use the proper secure idiom:
-.Pp
-.Dl "snprintf(buffer, sizeof(buffer), \*q%s\*q, string);"
-.Sh ERRORS
-In addition to the errors documented for the
-.Xr write 2
-system call, the
-.Fn printf
-family of functions may fail if:
-.Bl -tag -width Er
-.It Bq Er EILSEQ
-An invalid wide character code was encountered.
-.It Bq Er ENOMEM
-Insufficient storage space is available.
-.El
.Sh SEE ALSO
.Xr printf 1 ,
-.Xr fmtcheck 3 ,
-.Xr printf_l 3 ,
-.Xr scanf 3 ,
-.Xr setlocale 3 ,
-.Xr stdarg 3 ,
-.Xr wprintf 3
+.Xr scanf 3
.Sh STANDARDS
-Subject to the caveats noted in the
-.Sx BUGS
-section below, the
+The
.Fn fprintf ,
.Fn printf ,
.Fn sprintf ,
@@ -904,15 +588,7 @@
.Fn vsprintf
functions
conform to
-.St -ansiC
-and
-.St -isoC-99 .
-With the same reservation, the
-.Fn snprintf
-and
-.Fn vsnprintf
-functions conform to
-.St -isoC-99 .
+.St -isoC .
.Sh HISTORY
The functions
.Fn asprintf
@@ -954,8 +630,14 @@
are not standard; such combinations
should be avoided.
.Pp
-The
-.Nm
-family of functions do not correctly handle multibyte characters in the
-.Fa format
-argument.
+Because
+.Fn sprintf
+and
+.Fn vsprintf
+assume an infinitely long string,
+callers must be careful not to overflow the actual space;
+this is often hard to assure.
+For safety, programmers should use the
+.Fn snprintf
+interface instead.
+Unfortunately, this interface is not portable.