aboutsummaryrefslogtreecommitdiff
path: root/stdio-common
diff options
context:
space:
mode:
Diffstat (limited to 'stdio-common')
-rw-r--r--stdio-common/Makefile1
-rw-r--r--stdio-common/printf-parsemb.c1
-rw-r--r--stdio-common/printf_fp.c18
-rw-r--r--stdio-common/stdio_ext.h18
-rw-r--r--stdio-common/tst-fclose-devzero.c50
-rw-r--r--stdio-common/tst-scanf-format-ss.h2
-rw-r--r--stdio-common/vfscanf-internal.c2
7 files changed, 72 insertions, 20 deletions
diff --git a/stdio-common/Makefile b/stdio-common/Makefile
index 3709222..64b3575 100644
--- a/stdio-common/Makefile
+++ b/stdio-common/Makefile
@@ -262,6 +262,7 @@ tests := \
tst-bz11319-fortify2 \
tst-cookie \
tst-dprintf-length \
+ tst-fclose-devzero \
tst-fclose-offset \
tst-fdopen \
tst-fdopen2 \
diff --git a/stdio-common/printf-parsemb.c b/stdio-common/printf-parsemb.c
index aad697a..a7ba52a 100644
--- a/stdio-common/printf-parsemb.c
+++ b/stdio-common/printf-parsemb.c
@@ -17,6 +17,7 @@
<https://www.gnu.org/licenses/>. */
#include <ctype.h>
+#include <errno.h>
#include <limits.h>
#include <stdlib.h>
#include <string.h>
diff --git a/stdio-common/printf_fp.c b/stdio-common/printf_fp.c
index 5b46ddc..0039e1b 100644
--- a/stdio-common/printf_fp.c
+++ b/stdio-common/printf_fp.c
@@ -29,7 +29,6 @@
#include <gmp.h>
#include <ieee754.h>
#include <stdlib/gmp-impl.h>
-#include <stdlib/longlong.h>
#include <stdlib/fpioconst.h>
#include <locale/localeinfo.h>
#include <limits.h>
@@ -40,6 +39,7 @@
#include <stdlib.h>
#include <wchar.h>
#include <stdbool.h>
+#include <stdbit.h>
#include <rounding-mode.h>
#include <printf_buffer.h>
#include <printf_buffer_to_file.h>
@@ -386,7 +386,7 @@ __printf_fp_buffer_1 (struct __printf_buffer *buf, locale_t loc,
{
int cnt;
MPN_ASSIGN (p.scale, p.tmp);
- count_leading_zeros (cnt, p.scale[p.scalesize - 1]);
+ cnt = stdc_leading_zeros (p.scale[p.scalesize - 1]);
scaleexpo = (p.scalesize - 2) * BITS_PER_MP_LIMB - cnt - 1;
exp10 |= 1 << explog;
}
@@ -408,7 +408,7 @@ __printf_fp_buffer_1 (struct __printf_buffer *buf, locale_t loc,
;
/* Determine number of bits the scaling factor is misplaced. */
- count_leading_zeros (cnt_h, p.scale[p.scalesize - 1]);
+ cnt_h = stdc_leading_zeros (p.scale[p.scalesize - 1]);
if (cnt_h == 0)
{
@@ -426,17 +426,17 @@ __printf_fp_buffer_1 (struct __printf_buffer *buf, locale_t loc,
{
if (p.scale[i] != 0)
{
- count_trailing_zeros (cnt_l, p.scale[i]);
+ cnt_l = stdc_trailing_zeros (p.scale[i]);
if (p.frac[i] != 0)
{
int cnt_l2;
- count_trailing_zeros (cnt_l2, p.frac[i]);
+ cnt_l2 = stdc_trailing_zeros (p.frac[i]);
if (cnt_l2 < cnt_l)
cnt_l = cnt_l2;
}
}
else
- count_trailing_zeros (cnt_l, p.frac[i]);
+ cnt_l = stdc_trailing_zeros (p.frac[i]);
/* Now shift the numbers to their optimal position. */
if (i == 0 && BITS_PER_MP_LIMB - cnt_h > cnt_l)
@@ -528,7 +528,7 @@ __printf_fp_buffer_1 (struct __printf_buffer *buf, locale_t loc,
if (cy == 0)
--p.tmpsize;
- count_leading_zeros (cnt_h, p.tmp[p.tmpsize - 1]);
+ cnt_h = stdc_leading_zeros (p.tmp[p.tmpsize - 1]);
incr = (p.tmpsize - p.fracsize) * BITS_PER_MP_LIMB
+ BITS_PER_MP_LIMB - 1 - cnt_h;
@@ -584,7 +584,7 @@ __printf_fp_buffer_1 (struct __printf_buffer *buf, locale_t loc,
}
else
{
- count_trailing_zeros (cnt_l, p.tmp[i]);
+ cnt_l = stdc_trailing_zeros (p.tmp[i]);
/* Now shift the numbers to their optimal position. */
if (i == 0 && BITS_PER_MP_LIMB - 1 - cnt_h > cnt_l)
@@ -630,7 +630,7 @@ __printf_fp_buffer_1 (struct __printf_buffer *buf, locale_t loc,
p.tmpsize = p.fracsize;
assert (cy == 0 || p.tmp[p.tmpsize - 1] < 20);
- count_trailing_zeros (cnt_l, p.tmp[0]);
+ cnt_l = stdc_trailing_zeros (p.tmp[0]);
if (cnt_l < MIN (4, p.exponent))
{
cy = __mpn_lshift (p.frac, p.tmp, p.tmpsize,
diff --git a/stdio-common/stdio_ext.h b/stdio-common/stdio_ext.h
index 3a9a981..397b37f 100644
--- a/stdio-common/stdio_ext.h
+++ b/stdio-common/stdio_ext.h
@@ -43,43 +43,43 @@ __BEGIN_DECLS
/* Return the size of the buffer of FP in bytes currently in use by
the given stream. */
-extern size_t __fbufsize (FILE *__fp) __THROW;
+extern size_t __fbufsize (FILE *__fp) __THROW __nonnull ((1));
/* Return non-zero value iff the stream FP is opened readonly, or if the
last operation on the stream was a read operation. */
-extern int __freading (FILE *__fp) __THROW;
+extern int __freading (FILE *__fp) __THROW __nonnull ((1));
/* Return non-zero value iff the stream FP is opened write-only or
append-only, or if the last operation on the stream was a write
operation. */
-extern int __fwriting (FILE *__fp) __THROW;
+extern int __fwriting (FILE *__fp) __THROW __nonnull ((1));
/* Return non-zero value iff stream FP is not opened write-only or
append-only. */
-extern int __freadable (FILE *__fp) __THROW;
+extern int __freadable (FILE *__fp) __THROW __nonnull ((1));
/* Return non-zero value iff stream FP is not opened read-only. */
-extern int __fwritable (FILE *__fp) __THROW;
+extern int __fwritable (FILE *__fp) __THROW __nonnull ((1));
/* Return non-zero value iff the stream FP is line-buffered. */
-extern int __flbf (FILE *__fp) __THROW;
+extern int __flbf (FILE *__fp) __THROW __nonnull ((1));
/* Discard all pending buffered I/O on the stream FP. */
-extern void __fpurge (FILE *__fp) __THROW;
+extern void __fpurge (FILE *__fp) __THROW __nonnull ((1));
/* Return amount of output in bytes pending on a stream FP. */
-extern size_t __fpending (FILE *__fp) __THROW;
+extern size_t __fpending (FILE *__fp) __THROW __nonnull ((1));
/* Flush all line-buffered files. */
extern void _flushlbf (void);
/* Set locking status of stream FP to TYPE. */
-extern int __fsetlocking (FILE *__fp, int __type) __THROW;
+extern int __fsetlocking (FILE *__fp, int __type) __THROW __nonnull ((1));
__END_DECLS
diff --git a/stdio-common/tst-fclose-devzero.c b/stdio-common/tst-fclose-devzero.c
new file mode 100644
index 0000000..1c7b39a
--- /dev/null
+++ b/stdio-common/tst-fclose-devzero.c
@@ -0,0 +1,50 @@
+/* Test that always-zero lseek does not cause fclose failure after fread.
+ Copyright (C) 2025 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library 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 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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 the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <support/check.h>
+#include <support/xstdio.h>
+
+int
+do_test (void)
+{
+ for (int do_ftello = 0; do_ftello < 2; ++do_ftello)
+ {
+ FILE *fp = xfopen ("/dev/zero", "r");
+ char buf[17];
+ memset (buf, 0xcc, sizeof (buf));
+ xfread (buf, 1, sizeof (buf), fp);
+ static const char zeros[sizeof (buf)] = { 0 };
+ TEST_COMPARE_BLOB (buf, sizeof (buf), zeros, sizeof (zeros));
+ if (do_ftello)
+ {
+ errno = 0;
+ TEST_COMPARE (ftello (fp), -1);
+ TEST_COMPARE (errno, ESPIPE);
+ }
+ /* Do not use xfclose because it flushes first. */
+ TEST_COMPARE (fclose (fp), 0);
+ }
+
+ return 0;
+}
+
+#include <support/test-driver.c>
diff --git a/stdio-common/tst-scanf-format-ss.h b/stdio-common/tst-scanf-format-ss.h
index 2fb1ca2..b35e5bc 100644
--- a/stdio-common/tst-scanf-format-ss.h
+++ b/stdio-common/tst-scanf-format-ss.h
@@ -1,4 +1,4 @@
-/* Test feature wrapper for formatted 'scanf' input.
+/* Test feature wrapper for formatted 'sscanf' input.
Copyright (C) 2025 Free Software Foundation, Inc.
This file is part of the GNU C Library.
diff --git a/stdio-common/vfscanf-internal.c b/stdio-common/vfscanf-internal.c
index b965c7b..86ae501 100644
--- a/stdio-common/vfscanf-internal.c
+++ b/stdio-common/vfscanf-internal.c
@@ -1737,7 +1737,7 @@ __vfscanf_internal (FILE *s, const char *format, va_list argptr,
#endif
}
- if (n < 10)
+ if (n < num_digits_len)
{
/* Found it. */
from_level = level;