From: Bruno Haible Date: Sun, 30 Jun 2024 15:09:24 +0000 (+0200) Subject: vdzprintf: New module. X-Git-Url: https://gitweb.git.savannah.gnu.org/gitweb/?a=commitdiff_plain;h=95d9b651676b861d47736fcab2f1277bdc89712b;p=gnulib.git vdzprintf: New module. * lib/stdio.in.h (vdzprintf): New declaration. * lib/vdzprintf.c: New file, based on lib/vdprintf.c. * m4/stdio_h.m4 (gl_STDIO_H_REQUIRE_DEFAULTS): Initialize GNULIB_VDZPRINTF. * modules/stdio (Makefile.am): Substitute GNULIB_VDZPRINTF. * modules/vdzprintf: New file. --- diff --git a/ChangeLog b/ChangeLog index cf44fca935..c75cbe10f1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2024-06-30 Bruno Haible + + vdzprintf: New module. + * lib/stdio.in.h (vdzprintf): New declaration. + * lib/vdzprintf.c: New file, based on lib/vdprintf.c. + * m4/stdio_h.m4 (gl_STDIO_H_REQUIRE_DEFAULTS): Initialize + GNULIB_VDZPRINTF. + * modules/stdio (Makefile.am): Substitute GNULIB_VDZPRINTF. + * modules/vdzprintf: New file. + 2024-06-30 Bruno Haible *printf-tests: Correct test file descriptions. diff --git a/lib/stdio.in.h b/lib/stdio.in.h index bcae688b78..52dc8f30ba 100644 --- a/lib/stdio.in.h +++ b/lib/stdio.in.h @@ -1703,6 +1703,22 @@ _GL_CXXALIAS_SYS (vasprintf, int, _GL_CXXALIASWARN (vasprintf); #endif +#if @GNULIB_VDZPRINTF@ +/* Prints formatted output to file descriptor FD. + Returns the number of bytes written to the file descriptor. Upon + failure, returns -1 with errno set. + Failure code EOVERFLOW can only occur when a width > INT_MAX is used. + Therefore, if the format string is valid and does not use %ls/%lc + directives nor widths, the only possible failure codes are ENOMEM + and the possible failure codes from write(), excluding EINTR. */ +_GL_FUNCDECL_SYS (vdzprintf, off64_t, + (int fd, const char *restrict format, va_list args) + _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (2, 0) + _GL_ARG_NONNULL ((2))); +_GL_CXXALIAS_SYS (vdzprintf, off64_t, + (int fd, const char *restrict format, va_list args)); +#endif + #if @GNULIB_VDPRINTF@ # if @REPLACE_VDPRINTF@ # if !(defined __cplusplus && defined GNULIB_NAMESPACE) diff --git a/lib/vdzprintf.c b/lib/vdzprintf.c new file mode 100644 index 0000000000..64c3ab1331 --- /dev/null +++ b/lib/vdzprintf.c @@ -0,0 +1,69 @@ +/* Formatted output to a file descriptor. + Copyright (C) 2009-2024 Free Software Foundation, Inc. + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation, either version 3 of the + License, or (at your option) any later version. + + This file 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +/* Specification. */ +#include + +#include +#include +#include + +#include "full-write.h" +#include "intprops.h" +#include "vasnprintf.h" + +off64_t +vdzprintf (int fd, 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) + return -1; + + if (len > TYPE_MAXIMUM (off64_t)) + { + /* We could write the (huge) output, but then could not return len, as it + would be negative. Since we want to use the error code ENOMEM, it is + better to treat this case as if vasnprintf had already encountered an + out-of-memory situation. */ + if (output != buf) + free (output); + errno = ENOMEM; + return -1; + } + + if (full_write (fd, output, len) < len) + { + if (output != buf) + free (output); + return -1; + } + + if (output != buf) + free (output); + + return len; +} diff --git a/m4/stdio_h.m4 b/m4/stdio_h.m4 index f3edc43ccd..8073f6fa5b 100644 --- a/m4/stdio_h.m4 +++ b/m4/stdio_h.m4 @@ -1,5 +1,5 @@ # stdio_h.m4 -# serial 69 +# serial 70 dnl Copyright (C) 2007-2024 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -173,25 +173,26 @@ AC_DEFUN([gl_STDIO_H_REQUIRE_DEFAULTS], gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_RENAMEAT]) gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_SCANF]) gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_SNPRINTF]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_SNZPRINTF]) gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_SPRINTF_POSIX]) gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STDIO_H_NONBLOCKING]) gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STDIO_H_SIGPIPE]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_SZPRINTF]) gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_TMPFILE]) gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_VASPRINTF]) gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_VASZPRINTF]) gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_VFSCANF]) gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_VSCANF]) gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_VDPRINTF]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_VDZPRINTF]) gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_VFPRINTF]) gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_VFPRINTF_POSIX]) gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_VPRINTF]) gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_VPRINTF_POSIX]) gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_VSNPRINTF]) - gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_VSPRINTF_POSIX]) gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_VSNZPRINTF]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_VSPRINTF_POSIX]) gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_VSZPRINTF]) - gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_SNZPRINTF]) - gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_SZPRINTF]) dnl Support Microsoft deprecated alias function names by default. gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_FCLOSEALL], [1]) gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_FDOPEN], [1]) diff --git a/modules/stdio b/modules/stdio index 319309828f..dcc2bfbbf2 100644 --- a/modules/stdio +++ b/modules/stdio @@ -108,13 +108,16 @@ stdio.h: stdio.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) -e 's/@''GNULIB_RENAMEAT''@/$(GNULIB_RENAMEAT)/g' \ -e 's/@''GNULIB_SCANF''@/$(GNULIB_SCANF)/g' \ -e 's/@''GNULIB_SNPRINTF''@/$(GNULIB_SNPRINTF)/g' \ + -e 's/@''GNULIB_SNZPRINTF''@/$(GNULIB_SNZPRINTF)/g' \ -e 's/@''GNULIB_SPRINTF_POSIX''@/$(GNULIB_SPRINTF_POSIX)/g' \ -e 's/@''GNULIB_STDIO_H_NONBLOCKING''@/$(GNULIB_STDIO_H_NONBLOCKING)/g' \ -e 's/@''GNULIB_STDIO_H_SIGPIPE''@/$(GNULIB_STDIO_H_SIGPIPE)/g' \ + -e 's/@''GNULIB_SZPRINTF''@/$(GNULIB_SZPRINTF)/g' \ -e 's/@''GNULIB_TMPFILE''@/$(GNULIB_TMPFILE)/g' \ -e 's/@''GNULIB_VASPRINTF''@/$(GNULIB_VASPRINTF)/g' \ -e 's/@''GNULIB_VASZPRINTF''@/$(GNULIB_VASZPRINTF)/g' \ -e 's/@''GNULIB_VDPRINTF''@/$(GNULIB_VDPRINTF)/g' \ + -e 's/@''GNULIB_VDZPRINTF''@/$(GNULIB_VDZPRINTF)/g' \ -e 's/@''GNULIB_VFPRINTF''@/$(GNULIB_VFPRINTF)/g' \ -e 's/@''GNULIB_VFPRINTF_POSIX''@/$(GNULIB_VFPRINTF_POSIX)/g' \ -e 's/@''GNULIB_VFSCANF''@/$(GNULIB_VFSCANF)/g' \ @@ -122,11 +125,9 @@ stdio.h: stdio.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) -e 's/@''GNULIB_VPRINTF''@/$(GNULIB_VPRINTF)/g' \ -e 's/@''GNULIB_VPRINTF_POSIX''@/$(GNULIB_VPRINTF_POSIX)/g' \ -e 's/@''GNULIB_VSNPRINTF''@/$(GNULIB_VSNPRINTF)/g' \ - -e 's/@''GNULIB_VSPRINTF_POSIX''@/$(GNULIB_VSPRINTF_POSIX)/g' \ -e 's/@''GNULIB_VSNZPRINTF''@/$(GNULIB_VSNZPRINTF)/g' \ + -e 's/@''GNULIB_VSPRINTF_POSIX''@/$(GNULIB_VSPRINTF_POSIX)/g' \ -e 's/@''GNULIB_VSZPRINTF''@/$(GNULIB_VSZPRINTF)/g' \ - -e 's/@''GNULIB_SNZPRINTF''@/$(GNULIB_SNZPRINTF)/g' \ - -e 's/@''GNULIB_SZPRINTF''@/$(GNULIB_SZPRINTF)/g' \ -e 's/@''GNULIB_MDA_FCLOSEALL''@/$(GNULIB_MDA_FCLOSEALL)/g' \ -e 's/@''GNULIB_MDA_FDOPEN''@/$(GNULIB_MDA_FDOPEN)/g' \ -e 's/@''GNULIB_MDA_FILENO''@/$(GNULIB_MDA_FILENO)/g' \ diff --git a/modules/vdzprintf b/modules/vdzprintf new file mode 100644 index 0000000000..496763c82b --- /dev/null +++ b/modules/vdzprintf @@ -0,0 +1,29 @@ +Description: +vdzprintf() function: print formatted output (without INT_MAX limitation) +to a file descriptor + +Files: +lib/vdzprintf.c + +Depends-on: +stdio +vasnprintf +intprops +free-posix +full-write +errno + +configure.ac: +gl_STDIO_MODULE_INDICATOR([vdzprintf]) + +Makefile.am: +lib_SOURCES += vdzprintf.c + +Include: + + +License: +LGPL + +Maintainer: +all