From owner-freebsd-doc Thu Dec 21 15:30: 9 2000 From owner-freebsd-doc@FreeBSD.ORG Thu Dec 21 15:30:02 2000 Return-Path: Delivered-To: freebsd-doc@freebsd.org Received: from freefall.freebsd.org (freefall.FreeBSD.org [216.136.204.21]) by hub.freebsd.org (Postfix) with ESMTP id 8779A37B400 for ; Thu, 21 Dec 2000 15:30:02 -0800 (PST) Received: (from gnats@localhost) by freefall.freebsd.org (8.11.1/8.11.1) id eBLNU2442437; Thu, 21 Dec 2000 15:30:02 -0800 (PST) (envelope-from gnats) Date: Thu, 21 Dec 2000 15:30:02 -0800 (PST) Message-Id: <200012212330.eBLNU2442437@freefall.freebsd.org> To: freebsd-doc@freebsd.org Cc: From: Ben Smithurst Subject: Re: docs/23717: printf(3) is unclear about asprintf(3) return value Reply-To: Ben Smithurst Sender: gnats@FreeBSD.org Sender: owner-freebsd-doc@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.org The following reply was made to PR docs/23717; it has been noted by GNATS. From: Ben Smithurst To: Poul-Henning Kamp Cc: FreeBSD-gnats-submit@freebsd.org Subject: Re: docs/23717: printf(3) is unclear about asprintf(3) return value Date: Thu, 21 Dec 2000 22:46:53 +0000 Poul-Henning Kamp wrote: > printf(3) says: > > [...] > int > asprintf(char **ret, const char *format, ...) > [...] > Asprintf() and vasprintf() return a pointer to a buffer [...] > > It seems to me that asprintf() returns an int... How about this. ... -return a pointer to a buffer sufficiently large to hold the -string in the -.Fa ret -argument; +set +.Fa *ret +to be a pointer to a buffer sufficiently large to hold the formatted string. The full diff with a few other changes is here... Index: printf.3 =================================================================== RCS file: /usr/cvs/src/lib/libc/stdio/printf.3,v retrieving revision 1.19 diff -u -r1.19 printf.3 --- printf.3 2000/11/10 17:44:59 1.19 +++ printf.3 2000/12/21 22:44:37 @@ -82,7 +82,7 @@ family of functions produces output according to a .Fa format as described below. -.Fn Printf +.Fn printf and .Fn vprintf write output to @@ -114,19 +114,12 @@ .Xr stdarg 3 ) are converted for output. .Pp -These functions return -the number of characters printed -(not including the trailing -.Ql \e0 -used to end output to strings). -.Pp -.Fn Asprintf +.Fn asprintf and .Fn vasprintf -return a pointer to a buffer sufficiently large to hold the -string in the -.Fa ret -argument; +set +.Fa *ret +to be a pointer to a buffer sufficiently large to hold the formatted string. This pointer should be passed to .Xr free 3 to release the allocated storage when it is no longer needed. @@ -135,10 +128,10 @@ and .Fn vasprintf will return -1 and set -.Fa ret +.Fa *ret to be a NULL pointer. .Pp -.Fn Snprintf +.Fn snprintf and .Fn vsnprintf will write at most @@ -153,7 +146,7 @@ argument, the string was too short and some of the printed characters were discarded. .Pp -.Fn Sprintf +.Fn sprintf and .Fn vsprintf effectively assume an infinite @@ -557,6 +550,27 @@ a field; if the result of a conversion is wider than the field width, the field is expanded to contain the conversion result. .Pp +.Sh RETURN VALUE +These functions return +the number of characters formatted +(not including the trailing +.Ql \e0 +used to end output to strings). +If a system error is encountered +(for example, +if memory allocations fails for +.Fn asprintf +or if a write failure occurs on an output stream), +-1 will be returned. +Note that +.Fn snprintf +and +.Fn vsnprintf +return the number of characters which should have been written to the +specified buffer, +which may be more than the number of characters actually written if the +specified buffer was too small. +.Pp .Sh EXAMPLES To print a date and time in the form `Sunday, July 3, 10:02', where @@ -585,14 +599,22 @@ #include 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); + if (vsnprintf(p, 128, fmt, ap) >= 128) { + /* + * The buffer wasn't big enough; handle this case as + * appropriate. Here, missing characters is assumed to be a + * fatal error so the string is free'd and NULL is returned. + */ + free(p); + p = NULL; + } + va_end(ap); + return (p); } .Ed .Sh SEE ALSO -- Ben Smithurst / ben@FreeBSD.org / PGP: 0x99392F7D To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-doc" in the body of the message