Skip to content

Commit

Permalink
Add dprintf() and vdprintf() from POSIX.1-2008. Like getline(),
Browse files Browse the repository at this point in the history
dprintf() is a simple wrapper around another function, so we may as
well implement it. But also like getline(), we can't prototype it by
default right now because it would break too many ports.
  • Loading branch information
David Schultz authored and David Schultz committed Mar 4, 2009
1 parent 3895337 commit ad760e6
Show file tree
Hide file tree
Showing 7 changed files with 218 additions and 36 deletions.
24 changes: 20 additions & 4 deletions include/stdio.h
Original file line number Diff line number Diff line change
Expand Up @@ -345,12 +345,14 @@ char *tempnam(const char *, const char *);
ssize_t getdelim(char ** __restrict, size_t * __restrict, int,
FILE * __restrict);
int renameat(int, const char *, int, const char *);
int vdprintf(int, const char * __restrict, __va_list);

/*
* Every programmer and his dog wrote functions called getline()
* before POSIX.1-2008 came along and decided to usurp the name, so we
* don't prototype getline() by default unless one of the following is true:
* a) the app has requested it specifically by defining _WITH_GETLINE
* Every programmer and his dog wrote functions called getline() and dprintf()
* before POSIX.1-2008 came along and decided to usurp the names, so we
* don't prototype them by default unless one of the following is true:
* a) the app has requested them specifically by defining _WITH_GETLINE or
* _WITH_DPRINTF, respectively
* b) the app has requested a POSIX.1-2008 environment via _POSIX_C_SOURCE
* c) the app defines a GNUism such as _BSD_SOURCE or _GNU_SOURCE
*/
Expand All @@ -368,6 +370,20 @@ int renameat(int, const char *, int, const char *);
ssize_t getline(char ** __restrict, size_t * __restrict, FILE * __restrict);
#endif

#ifndef _WITH_DPRINTF
#if defined(_BSD_SOURCE) || defined(_GNU_SOURCE)
#define _WITH_DPRINTF
#elif defined(_POSIX_C_SOURCE)
#if _POSIX_C_SOURCE > 200809
#define _WITH_DPRINTF
#endif
#endif
#endif

#ifdef _WITH_DPRINTF
int dprintf(int, const char * __restrict, ...);
#endif

#endif /* __BSD_VISIBLE || __POSIX_VISIBLE >= 200809 */

/*
Expand Down
9 changes: 5 additions & 4 deletions lib/libc/stdio/Makefile.inc
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
# stdio sources
.PATH: ${.CURDIR}/stdio

SRCS+= _flock_stub.c asprintf.c clrerr.c fclose.c fcloseall.c fdopen.c \
SRCS+= _flock_stub.c asprintf.c clrerr.c dprintf.c \
fclose.c fcloseall.c fdopen.c \
feof.c ferror.c fflush.c fgetc.c fgetln.c fgetpos.c fgets.c fgetwc.c \
fgetwln.c fgetws.c \
fileno.c findfp.c flags.c fopen.c fprintf.c fpurge.c fputc.c fputs.c \
Expand All @@ -17,7 +18,7 @@ SRCS+= _flock_stub.c asprintf.c clrerr.c fclose.c fcloseall.c fdopen.c \
refill.c remove.c rewind.c rget.c scanf.c setbuf.c setbuffer.c \
setvbuf.c snprintf.c sprintf.c sscanf.c stdio.c swprintf.c swscanf.c \
tempnam.c tmpfile.c \
tmpnam.c ungetc.c ungetwc.c vasprintf.c vfprintf.c \
tmpnam.c ungetc.c ungetwc.c vasprintf.c vdprintf.c vfprintf.c \
vfscanf.c \
vfwprintf.c vfwscanf.c vprintf.c vscanf.c vsnprintf.c vsprintf.c \
vsscanf.c \
Expand Down Expand Up @@ -57,9 +58,9 @@ MLINKS+=getc.3 fgetc.3 getc.3 getc_unlocked.3 getc.3 getchar.3 \
MLINKS+=getline.3 getdelim.3
MLINKS+=getwc.3 fgetwc.3 getwc.3 getwchar.3
MLINKS+=mktemp.3 mkdtemp.3 mktemp.3 mkstemp.3 mktemp.3 mkstemps.3
MLINKS+=printf.3 asprintf.3 printf.3 fprintf.3 \
MLINKS+=printf.3 asprintf.3 printf.3 dprintf.3 printf.3 fprintf.3 \
printf.3 snprintf.3 printf.3 sprintf.3 \
printf.3 vasprintf.3 \
printf.3 vasprintf.3 printf.3 vdprintf.3 \
printf.3 vfprintf.3 printf.3 vprintf.3 printf.3 vsnprintf.3 \
printf.3 vsprintf.3
MLINKS+=putc.3 fputc.3 putc.3 putc_unlocked.3 putc.3 putchar.3 \
Expand Down
2 changes: 2 additions & 0 deletions lib/libc/stdio/Symbol.map
Original file line number Diff line number Diff line change
Expand Up @@ -111,8 +111,10 @@ FBSD_1.0 {
};

FBSD_1.1 {
dprintf;
getdelim;
getline;
vdprintf;
};

FBSDprivate_1.0 {
Expand Down
46 changes: 46 additions & 0 deletions lib/libc/stdio/dprintf.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*-
* Copyright (c) 2009 David Schultz <[email protected]>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/

#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");

#define _WITH_DPRINTF
#include "namespace.h"
#include <stdarg.h>
#include <stdio.h>
#include "un-namespace.h"

int
dprintf(int fd, const char * __restrict fmt, ...)
{
va_list ap;
int ret;

va_start(ap, fmt);
ret = vdprintf(fd, fmt, ap);
va_end(ap);
return (ret);
}
103 changes: 76 additions & 27 deletions lib/libc/stdio/printf.3
Original file line number Diff line number Diff line change
Expand Up @@ -32,16 +32,17 @@
.\" @(#)printf.3 8.1 (Berkeley) 6/4/93
.\" $FreeBSD$
.\"
.Dd October 16, 2004
.Dd March 3, 2009
.Dt PRINTF 3
.Os
.Sh NAME
.Nm printf , fprintf , sprintf , snprintf , asprintf ,
.Nm vprintf , vfprintf, vsprintf , vsnprintf , vasprintf
.Nm printf , fprintf , sprintf , snprintf , asprintf , dprintf ,
.Nm vprintf , vfprintf, vsprintf , vsnprintf , vasprintf, vdprintf
.Nd formatted output conversion
.Sh LIBRARY
.Lb libc
.Sh SYNOPSIS
.Fd "#define _WITH_DPRINTF"
.In stdio.h
.Ft int
.Fn printf "const char * restrict format" ...
Expand All @@ -53,6 +54,8 @@
.Fn snprintf "char * restrict str" "size_t size" "const char * restrict format" ...
.Ft int
.Fn asprintf "char **ret" "const char *format" ...
.Ft int
.Fn dprintf "int" "const char * restrict format" ...
.In stdarg.h
.Ft int
.Fn vprintf "const char * restrict format" "va_list ap"
Expand All @@ -64,6 +67,8 @@
.Fn vsnprintf "char * restrict str" "size_t size" "const char * restrict format" "va_list ap"
.Ft int
.Fn vasprintf "char **ret" "const char *format" "va_list ap"
.Ft int
.Fn vdprintf "int fd" "const char * restrict format" "va_list ap"
.Sh DESCRIPTION
The
.Fn printf
Expand All @@ -83,6 +88,10 @@ and
.Fn vfprintf
write output to the given output
.Fa stream ;
.Fn dprintf
and
.Fn vdprintf
write output to the given file descriptor;
.Fn sprintf ,
.Fn snprintf ,
.Fn vsprintf ,
Expand Down Expand Up @@ -771,6 +780,57 @@ for later interpolation by
Always use the proper secure idiom:
.Pp
.Dl "snprintf(buffer, sizeof(buffer), \*q%s\*q, string);"
.Sh COMPATIBILITY
Many application writers used the name
.Va dprintf
before the
.Fn dprintf
function was introduced in
.St -p1003.1 ,
so a prototype is not provided by default in order to avoid
compatibility problems.
Applications that wish to use the
.Fn dprintf
function described herein should either request a strict
.St -p1003.1-2008
environment by defining the macro
.Dv _POSIX_C_SOURCE
to the value 200809 or greater, or by defining the macro
.Dv _WITH_DPRINTF ,
prior to the inclusion of
.In stdio.h .
For compatibility with GNU libc, defining either
.Dv _BSD_SOURCE
or
.Dv _GNU_SOURCE
prior to the inclusion of
.In stdio.h
will also make
.Fn dprintf
available.
.Pp
The conversion formats
.Cm \&%D , \&%O ,
and
.Cm %U
are not standard and
are provided only for backward compatibility.
The effect of padding the
.Cm %p
format with zeros (either by the
.Cm 0
flag or by specifying a precision), and the benign effect (i.e., none)
of the
.Cm #
flag on
.Cm %n
and
.Cm %p
conversions, as well as other
nonsensical combinations such as
.Cm %Ld ,
are not standard; such combinations
should be avoided.
.Sh ERRORS
In addition to the errors documented for the
.Xr write 2
Expand Down Expand Up @@ -810,7 +870,13 @@ With the same reservation, the
and
.Fn vsnprintf
functions conform to
.St -isoC-99 .
.St -isoC-99 ,
while
.Fn dprintf
and
.Fn vdprintf
conform to
.St -p1003.1-2008 .
.Sh HISTORY
The functions
.Fn asprintf
Expand All @@ -828,30 +894,13 @@ from
.An Todd C. Miller Aq [email protected]
for
.Ox 2.3 .
.Sh BUGS
The conversion formats
.Cm \&%D , \&%O ,
and
.Cm %U
are not standard and
are provided only for backward compatibility.
The effect of padding the
.Cm %p
format with zeros (either by the
.Cm 0
flag or by specifying a precision), and the benign effect (i.e., none)
of the
.Cm #
flag on
.Cm %n
The
.Fn dprintf
and
.Cm %p
conversions, as well as other
nonsensical combinations such as
.Cm %Ld ,
are not standard; such combinations
should be avoided.
.Pp
.Fn vdprintf
functions were added in
.Fx 8.0 .
.Sh BUGS
The
.Nm
family of functions do not correctly handle multibyte characters in the
Expand Down
4 changes: 3 additions & 1 deletion lib/libc/stdio/stdio.3
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
.\" @(#)stdio.3 8.7 (Berkeley) 4/19/94
.\" $FreeBSD$
.\"
.Dd February 28, 2009
.Dd March 3, 2009
.Dt STDIO 3
.Os
.Sh NAME
Expand Down Expand Up @@ -243,6 +243,7 @@ library conforms to
.It Sy "Function Description"
.It "asprintf formatted output conversion"
.It "clearerr check and reset stream status"
.It "dprintf formatted output conversion"
.It "fclose close a stream"
.It "fdopen stream open functions"
.It "feof check and reset stream status"
Expand Down Expand Up @@ -313,6 +314,7 @@ library conforms to
.It "ungetc un-get character from input stream"
.It "ungetwc un-get wide character from input stream"
.It "vasprintf formatted output conversion"
.It "vdprintf formatted output conversion"
.It "vfprintf formatted output conversion"
.It "vfscanf input format conversion"
.It "vfwprintf formatted wide character output conversion"
Expand Down
66 changes: 66 additions & 0 deletions lib/libc/stdio/vdprintf.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/*-
* Copyright (c) 2009 David Schultz <[email protected]>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/

#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");

#include "namespace.h"
#include <errno.h>
#include <limits.h>
#include <stdarg.h>
#include <stdio.h>
#include "un-namespace.h"

#include "local.h"

int
vdprintf(int fd, const char * __restrict fmt, va_list ap)
{
FILE f;
unsigned char buf[BUFSIZ];
int ret;

if (fd > SHRT_MAX) {
errno = EMFILE;
return (EOF);
}

f._p = buf;
f._w = sizeof(buf);
f._flags = __SWR;
f._file = fd;
f._cookie = &f;
f._write = __swrite;
f._bf._base = buf;
f._bf._size = sizeof(buf);
f._orientation = 0;
bzero(&f._mbstate, sizeof(f._mbstate));

if ((ret = __vfprintf(&f, fmt, ap)) < 0)
return (ret);

return (__fflush(&f) ? EOF : ret);
}

0 comments on commit ad760e6

Please sign in to comment.