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/tst-setvbuf2.c39
-rw-r--r--stdio-common/vfscanf-internal.c2
8 files changed, 93 insertions, 38 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/tst-setvbuf2.c b/stdio-common/tst-setvbuf2.c
index 6cc8335..84d8b43 100644
--- a/stdio-common/tst-setvbuf2.c
+++ b/stdio-common/tst-setvbuf2.c
@@ -240,6 +240,21 @@ typedef struct {
/* It's OK if this is static, we only run one at a time. */
ThreadData thread_data;
+static void
+end_thread (pthread_t *ptid)
+{
+ if (*ptid)
+ {
+ pthread_cancel (*ptid);
+ xpthread_join (*ptid);
+ /* The descriptor was passed in, or the helper thread made
+ sufficient progress and opened the file. */
+ if (thread_data.fd >= 0)
+ xclose (thread_data.fd);
+ *ptid = 0;
+ }
+}
+
static void *
writer_thread_proc (void *closure)
{
@@ -306,7 +321,7 @@ static void
start_writer_thread_n (const char *fname)
{
debug;
- thread_data.fd = 0;
+ thread_data.fd = -1;
thread_data.fname = fname;
writer_thread_tid = xpthread_create (NULL, writer_thread_proc,
(void *)&thread_data);
@@ -316,13 +331,7 @@ static void
end_writer_thread (void)
{
debug;
- if (writer_thread_tid)
- {
- pthread_cancel (writer_thread_tid);
- xpthread_join (writer_thread_tid);
- xclose (thread_data.fd);
- writer_thread_tid = 0;
- }
+ end_thread (&writer_thread_tid);
}
static void
@@ -339,7 +348,7 @@ static void
start_reader_thread_n (const char *fname)
{
debug;
- thread_data.fd = 0;
+ thread_data.fd = -1;
thread_data.fname = fname;
reader_thread_tid = xpthread_create (NULL, reader_thread_proc,
(void *)&thread_data);
@@ -349,13 +358,7 @@ static void
end_reader_thread (void)
{
debug;
- if (reader_thread_tid)
- {
- pthread_cancel (reader_thread_tid);
- xpthread_join (reader_thread_tid);
- xclose (thread_data.fd);
- reader_thread_tid = 0;
- }
+ end_thread (&reader_thread_tid);
}
/*------------------------------------------------------------*/
@@ -852,7 +855,7 @@ do_second_part (FILE *fp,
}
- fclose (fp);
+ xfclose (fp);
return rv;
}
@@ -939,7 +942,7 @@ recurse (FILE *fp,
break;
default: /* parent */
- fclose (fp);
+ xfclose (fp);
xwaitpid (pid, &status, 0);
if (WIFEXITED (status)
&& WEXITSTATUS (status) == 0)
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;