source: branches/stable/mindi-busybox/libbb/printf.c @ 821

Last change on this file since 821 was 821, checked in by bruno, 13 years ago

Addition of busybox 1.2.1 as a mindi-busybox new package
This should avoid delivering binary files in mindi not built there (Fedora and Debian are quite serious about that)

File size: 2.5 KB
Line 
1/* vi: set sw=4 ts=4: */
2/*
3 * *printf implementations for busybox
4 *
5 * Copyright (C) 2003  Manuel Novoa III  <mjn3@codepoet.org>
6 *
7 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
8 */
9
10/* Mar 12, 2003     Manuel Novoa III
11 *
12 * While fwrite(), fputc(), fputs(), etc. all set the stream error flag
13 * on failure, the *printf functions are unique in that they can fail
14 * for reasons not related to the actual output itself.  Among the possible
15 * reasons for failure which don't set the streams error indicator,
16 * SUSv3 lists EILSEQ, EINVAL, and ENOMEM.
17 *
18 * In some cases, it would be desirable to have a group of *printf()
19 * functions available that _always_ set the stream error indicator on
20 * failure.  That would allow us to defer error checking until applet
21 * exit.  Unfortunately, there is no standard way of setting a streams
22 * error indicator... even though we can clear it with clearerr().
23 */
24
25/* Mar 22, 2006     Rich Felker III
26 *
27 * Actually there is a portable way to set the error indicator. See below.
28 * It is not thread-safe as written due to a race condition with file
29 * descriptors but since BB is not threaded that does not matter. It can be
30 * made thread-safe at the expense of slightly more code, if this is ever
31 * needed in the future.
32 */
33
34#include <stdio.h>
35#include <stdarg.h>
36#include <unistd.h>
37#include <errno.h>
38#include "libbb.h"
39
40#ifdef L_bb_vfprintf
41int bb_vfprintf(FILE * __restrict stream,
42                       const char * __restrict format,
43                       va_list arg)
44{
45    int rv;
46
47    if ((rv = vfprintf(stream, format, arg)) < 0) {
48        /* The following sequence portably sets the error flag for
49         * stream on any remotely POSIX-compliant implementation. */
50
51        int errno_save = errno;
52        int fd = fileno(stream);
53        int tmp = dup(fd);
54
55        fflush(stream);
56        close(fd);
57        /* Force an attempted write to nonexistant fd => EBADF */
58        fputc(0, stream);
59        fflush(stream);
60        /* Restore the stream's original fd */
61        dup2(tmp, fd);
62        close(tmp);
63        errno = errno_save;
64    }
65
66    return rv;
67}
68#endif
69
70#ifdef L_bb_vprintf
71int bb_vprintf(const char * __restrict format, va_list arg)
72{
73    return bb_vfprintf(stdout, format, arg);
74}
75#endif
76
77#ifdef L_bb_fprintf
78int bb_fprintf(FILE * __restrict stream,
79                      const char * __restrict format, ...)
80{
81    va_list arg;
82    int rv;
83
84    va_start(arg, format);
85    rv = bb_vfprintf(stream, format, arg);
86    va_end(arg);
87
88    return rv;
89}
90#endif
91
92#ifdef L_bb_printf
93int bb_printf(const char * __restrict format, ...)
94{
95    va_list arg;
96    int rv;
97
98    va_start(arg, format);
99    rv = bb_vfprintf(stdout, format, arg);
100    va_end(arg);
101
102    return rv;
103}
104#endif
Note: See TracBrowser for help on using the repository browser.