2026-01-22 Collin Funk <collin.funk1@gmail.com>
+ getdelim, getline: Don't replace these functions on glibc.
+ This largely reverts my 2025-10-10 commits since POSIX has relaxed the
+ requirements to make glibc's behavior compliant. See:
+ <https://www.austingroupbugs.net/bug_view_page.php?bug_id=1953>.
+ * doc/posix-functions/getdelim.texi: Move the text about glibc 2.42
+ to under "Portability problems not fixed by Gnulib".
+ * doc/posix-functions/getline.texi: Likewise.
+ * m4/getdelim.m4 (gl_FUNC_GETDELIM): Remove the test on an empty file.
+ * m4/getline.m4 (gl_FUNC_GETLINE): Likewise.
+ * tests/test-getdelim.c (main): Remove the test case.
+ * tests/test-getline.c (main): Likewise.
+
doc: document a portability issue with macOS getrusage.
* doc/posix-functions/getrusage.texi: Document that the 'ru_maxrss'
field of 'struct rusage' is measured in bytes on macOS.
This function crashes when passed a pointer to a NULL buffer together with a
pointer to a non-zero buffer size on some platforms:
FreeBSD 8.0.
-@item
-This function does not NUL terminate the buffer when the first
-character read is EOF on some platforms:
-@c https://sourceware.org/PR28038
-glibc 2.42.
@end itemize
Portability problems not fixed by Gnulib:
@item
This function has quadratic running time for long lines on some platforms:
uClibc 0.9.31.
+@item
+This function does not NUL terminate the buffer when the first
+character read is EOF on some platforms:
+@c https://sourceware.org/PR28038
+glibc 2.42.
@end itemize
This function crashes when passed a pointer to a NULL buffer together with a
pointer to a non-zero buffer size on some platforms:
FreeBSD 8.0.
-@item
-This function does not NUL terminate the buffer when the first
-character read is EOF on some platforms:
-@c https://sourceware.org/PR28038
-glibc 2.42.
@end itemize
Portability problems not fixed by Gnulib:
@item
This function has quadratic running time for long lines on some platforms:
uClibc 0.9.31.
+@item
+This function does not NUL terminate the buffer when the first
+character read is EOF on some platforms:
+@c https://sourceware.org/PR28038
+glibc 2.42.
@end itemize
# getdelim.m4
-# serial 21
+# serial 22
dnl Copyright (C) 2005-2007, 2009-2026 Free Software Foundation, Inc.
dnl
gl_cv_func_working_getdelim=no ;;
*)
echo fooNbarN | tr -d '\012' | tr N '\012' > conftest.data
- touch conftest.empty
AC_RUN_IFELSE([AC_LANG_SOURCE([[
# include <stdio.h>
# include <stdlib.h>
free (line);
}
fclose (in);
- {
- /* Test that reading EOF as the first character sets the first byte
- in the buffer to NUL. This fails on glibc 2.42 and earlier. */
- in = fopen ("./conftest.empty", "r");
- if (!in)
- return 1;
- char *line = malloc (1);
- line[0] = 'A';
- size_t siz = 1;
- if (getdelim (&line, &siz, '\n', in) != -1 || line[0] != '\0')
- result |= 8;
- free (line);
- }
- fclose (in);
return result;
}
]])],
[gl_cv_func_working_getdelim=yes],
[gl_cv_func_working_getdelim=no],
- [case "$host_os" in
- # Guess yes on musl.
- *-musl* | midipix*) gl_cv_func_working_getdelim="guessing yes" ;;
- # Guess no on glibc.
- *-gnu* | gnu*) gl_cv_func_working_getdelim="guessing no" ;;
- *) gl_cv_func_working_getdelim="$gl_cross_guess_normal" ;;
- esac
+ [dnl We're cross compiling.
+ dnl Guess it works on glibc2 systems and musl systems.
+ AC_EGREP_CPP([Lucky GNU user],
+ [
+#include <features.h>
+#ifdef __GNU_LIBRARY__
+ #if (__GLIBC__ >= 2) && !defined __UCLIBC__
+ Lucky GNU user
+ #endif
+#endif
+ ],
+ [gl_cv_func_working_getdelim="guessing yes"],
+ [case "$host_os" in
+ *-musl* | midipix*) gl_cv_func_working_getdelim="guessing yes" ;;
+ *) gl_cv_func_working_getdelim="$gl_cross_guess_normal" ;;
+ esac
+ ])
])
;;
esac
- rm -f conftest.data conftest.empty
+ rm -f conftest.data
])
case "$gl_cv_func_working_getdelim" in
*yes) ;;
# getline.m4
-# serial 35
+# serial 36
dnl Copyright (C) 1998-2003, 2005-2007, 2009-2026 Free Software Foundation,
dnl Inc.
AC_CACHE_CHECK([for working getline function],
[am_cv_func_working_getline],
[echo fooNbarN | tr -d '\012' | tr N '\012' > conftest.data
- touch conftest.empty
AC_RUN_IFELSE([AC_LANG_SOURCE([[
# include <stdio.h>
# include <stdlib.h>
free (line);
}
fclose (in);
- {
- /* Test that reading EOF as the first character sets the first byte
- in the buffer to NUL. This fails on glibc 2.42 and earlier. */
- in = fopen ("./conftest.empty", "r");
- if (!in)
- return 1;
- char *line = malloc (1);
- line[0] = 'A';
- size_t siz = 1;
- if (getline (&line, &siz, in) != -1 || line[0] != '\0')
- result |= 8;
- free (line);
- }
- fclose (in);
return result;
}
]])],
[am_cv_func_working_getline=yes],
[am_cv_func_working_getline=no],
- [case "$host_os" in
- # Guess yes on musl.
- *-musl* | midipix*) am_cv_func_working_getline="guessing yes" ;;
- # Guess no on glibc.
- *-gnu* | gnu*) am_cv_func_working_getline="guessing no" ;;
- *) am_cv_func_working_getline="$gl_cross_guess_normal" ;;
- esac
+ [dnl We're cross compiling.
+ dnl Guess it works on glibc2 systems and musl systems.
+ AC_EGREP_CPP([Lucky GNU user],
+ [
+#include <features.h>
+#ifdef __GNU_LIBRARY__
+ #if (__GLIBC__ >= 2) && !defined __UCLIBC__
+ Lucky GNU user
+ #endif
+#endif
+ ],
+ [am_cv_func_working_getline="guessing yes"],
+ [case "$host_os" in
+ *-musl* | midipix*) am_cv_func_working_getline="guessing yes" ;;
+ *) am_cv_func_working_getline="$gl_cross_guess_normal" ;;
+ esac
+ ])
])
- rm -f conftest.data conftest.empty
+ rm -f conftest.data
])
else
am_cv_func_working_getline=no
ASSERT (memcmp (line, "d\0f", 4) == 0);
ASSERT (3 < len);
- /* Test that reading an EOF will terminate the buffer with a NUL
- character. */
result = getdelim (&line, &len, 'n', f);
- ASSERT (0 < len);
- ASSERT (line[0] == '\0');
ASSERT (result == -1);
free (line);
ASSERT (memcmp (line, "d\0f", 4) == 0);
ASSERT (3 < len);
- /* Test that reading an EOF will terminate the buffer with a NUL
- character. */
result = getline (&line, &len, f);
- ASSERT (0 < len);
- ASSERT (line[0] == '\0');
ASSERT (result == -1);
free (line);