diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 17:39:29 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 17:39:29 +0000 |
commit | 8ffec2a3aba6f114784e11f89ef1d57a096ae540 (patch) | |
tree | ccebcbad06203e8241a8e7249f8e6c478a3682ea /lib/vfprintf.c | |
parent | Initial commit. (diff) | |
download | coreutils-8ffec2a3aba6f114784e11f89ef1d57a096ae540.tar.xz coreutils-8ffec2a3aba6f114784e11f89ef1d57a096ae540.zip |
Adding upstream version 8.32.upstream/8.32upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'lib/vfprintf.c')
-rw-r--r-- | lib/vfprintf.c | 74 |
1 files changed, 74 insertions, 0 deletions
diff --git a/lib/vfprintf.c b/lib/vfprintf.c new file mode 100644 index 0000000..ff7338e --- /dev/null +++ b/lib/vfprintf.c @@ -0,0 +1,74 @@ +/* Formatted output to a stream. + Copyright (C) 2004, 2006-2020 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <https://www.gnu.org/licenses/>. */ + +#if 1 +# include <config.h> +#endif + +/* Specification. */ +#include <stdio.h> + +#include <errno.h> +#include <limits.h> +#include <stdarg.h> +#include <stdlib.h> + +#include "fseterr.h" +#include "vasnprintf.h" + +/* Print formatted output to the stream FP. + Return string length of formatted string. On error, return a negative + value. */ +int +vfprintf (FILE *fp, const char *format, va_list args) +{ + char buf[2000]; + char *output; + size_t len; + size_t lenbuf = sizeof (buf); + + output = vasnprintf (buf, &lenbuf, format, args); + len = lenbuf; + + if (!output) + { + fseterr (fp); + return -1; + } + + if (fwrite (output, 1, len, fp) < len) + { + if (output != buf) + { + int saved_errno = errno; + free (output); + errno = saved_errno; + } + return -1; + } + + if (output != buf) + free (output); + + if (len > INT_MAX) + { + errno = EOVERFLOW; + fseterr (fp); + return -1; + } + + return len; +} |