@@ -16,6 +16,9 @@ Major new features:
-z pack-relative-relocs option, which is supported for some targets
in recent binutils versions. Lazy binding doesn't apply to DT_RELR.
+* The fgetln line reading function has been added, based on the BSD
+ function of the same name.
+
Deprecated and removed features, and other changes affecting compatibility:
* Support for prelink will be removed in the next release; this includes
@@ -92,10 +92,10 @@ struct _IO_FILE_complete
struct _IO_wide_data *_wide_data;
struct _IO_FILE *_freeres_list;
void *_freeres_buf;
- size_t __pad5;
+ char *_fgetln_buf;
int _mode;
/* Make sure we don't get into trouble again. */
- char _unused2[15 * sizeof (int) - 4 * sizeof (void *) - sizeof (size_t)];
+ char _unused2[15 * sizeof (int) - 4 * sizeof (void *) - sizeof (char *)];
};
/* These macros are used by bits/stdio.h and internal headers. */
@@ -585,6 +585,7 @@ _IO_no_init (FILE *fp, int flags, int orientation,
stream. */
fp->_wide_data = (struct _IO_wide_data *) -1L;
fp->_freeres_list = NULL;
+ fp->_fgetln_buf = NULL;
}
int
@@ -71,6 +71,7 @@ _IO_new_fclose (FILE *fp)
if (_IO_have_backup (fp))
_IO_free_backup_area (fp);
}
+ free (fp->_fgetln_buf);
_IO_deallocate_file (fp);
return status;
}
@@ -645,6 +645,15 @@ extern __ssize_t getdelim (char **__restrict __lineptr,
extern __ssize_t getline (char **__restrict __lineptr,
size_t *__restrict __n,
FILE *__restrict __stream) __wur;
+#endif /* __USE_XOPEN2K8 || __GLIBC_USE (LIB_EXT2) */
+
+#ifdef __USE_MISC
+/* Reads the next line from STREAM and returns a pointer to the start of
+ an array containing it. The array is not null-terminated. The
+ length of the array, including the line terminator if present in
+ the input, is written to *LENGTH. Returns NULL on EOF and failure.
+ Subsequent operations on STREAM invalidate the returned pointer. */
+extern char *fgetln (FILE *__stream, size_t *__length) __wur;
#endif
@@ -1365,6 +1365,38 @@ function except that it does not implicitly lock the stream.
This function is a GNU extension.
@end deftypefun
+@deftypefun {char *} fgetln (FILE *@var{stream}, size_t *@var{length})
+@standards{BSD, unistd.h}
+@safety{@mtsafe{@mtsrace{:stream}}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{}}}
+The @code{fgetln} function reads a line from @var{stream}, writes the
+length of the line to @code{@var{length}}, and returns a pointer to the
+start of a character array containing the line contents. The length
+includes the line terminator if present in the stream. (The last line
+of a file may lack a line terminator.)
+
+If the function encounters the end of stream before reading any
+characters or an error, a null pointer is returned, and zero is written
+to @code{*@var{length}}. You can use @code{feof} and @code{ferror} to
+disambiguate the two cases.
+
+The returned pointer does not point to a string: the array is not
+null-terminated. The pointer and the array are invalidated by a
+subsequent operation on @var{stream}. The @code{fgetln} function does
+not perform locking. If the caller needs locking, it has to call
+@code{flockfile} explicitly. @xref{Streams and Threads}.
+
+The @code{fgetln} function is a BSD extension. The comparable
+@code{getline} function is slightly less efficient on buffered streams,
+but it can be easier to use because the allocated string is
+null-terminated and not invalidated by unrelated operations on
+@var{stream}. BSD specifies that the first @code{*@var{length}} bytes
+of the character array are writable. In @theglibc{} implementation,
+this is not necessarily the case for some stream types, such as
+read-only memory-mapped files created by the @code{fopen} function with
+an @code{"rm"} mode argument.
+@xref{Opening Streams}.
+@end deftypefun
+
@deftypefn {Deprecated function} {char *} gets (char *@var{s})
@standards{ISO, stdio.h}
@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@aculock{} @acucorrupt{}}}
@@ -31,6 +31,7 @@ routines := \
ctermid \
cuserid \
dprintf \
+ fgetln \
flockfile \
fprintf \
fscanf \
@@ -161,6 +162,7 @@ tests := \
tst-cookie \
tst-fdopen \
tst-ferror \
+ tst-fgetln \
tst-fgets \
tst-fileno \
tst-fmemopen \
@@ -63,6 +63,9 @@ libc {
GLIBC_2.29 {
# SHLIB_COMPAT(GLIBC_2_0, GLIBC_2_29) used in iovfscanf.c etc.
}
+ GLIBC_2.36 {
+ fgetln;
+ }
GLIBC_PRIVATE {
# global variables
_itoa_lower_digits;
new file mode 100644
@@ -0,0 +1,82 @@
+/* Zero-copy line reading function.
+ Copyright (C) 2022 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 "libioP.h"
+#include <errno.h>
+#include <shlib-compat.h>
+#include <stddef.h>
+#include <string.h>
+
+char *
+__fgetln (FILE *fp, size_t *length)
+{
+#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)
+ /* There is no fgetln support for old streams. */
+ if (_IO_vtable_offset (fp) != 0)
+ {
+ *length = 0;
+ __set_errno (EOPNOTSUPP);
+ return NULL;
+ }
+#endif
+
+ /* Discard the old buffer. This optimizes for a buffered stream,
+ with multiple lines in each buffer. */
+ if (fp->_fgetln_buf != NULL)
+ {
+ free (fp->_fgetln_buf);
+ fp->_fgetln_buf = NULL;
+ }
+
+ /* Fast path if there is a read buffer. */
+ if (fp->_IO_read_ptr < fp->_IO_read_end)
+ {
+ char *nl = memchr (fp->_IO_read_ptr, '\n',
+ fp->_IO_read_end - fp->_IO_read_ptr);
+ if (nl != NULL)
+ {
+ /* The line terminator was found. Consume the line and
+ return it. */
+ char *result = fp->_IO_read_ptr;
+ ++nl;
+ fp->_IO_read_ptr = nl;
+ *length = nl - result;
+ return result;
+ }
+ /* Fall through to the slow path. */
+ }
+
+ /* In the slow path, just use getdelim. __uflow would perhaps
+ re-fill the buffer without an allocation, but it also consumes a
+ character, and that would have to be somehow merged with the rest
+ of the line (if it is not possible to unread it in the same
+ buffer). */
+ size_t allocated = 0;
+ ssize_t ret = __getdelim (&fp->_fgetln_buf, &allocated, '\n', fp);
+ if (ret <= 0)
+ {
+ free (fp->_fgetln_buf);
+ fp->_fgetln_buf = NULL;
+ ret = 0;
+ }
+ *length = ret;
+ return fp->_fgetln_buf;
+}
+
+
+weak_alias (__fgetln, fgetln)
new file mode 100644
@@ -0,0 +1,179 @@
+/* Test the fgetln function.
+ Copyright (C) 2022 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 <array_length.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdio.h>
+#include <support/check.h>
+
+struct expected_line
+{
+ const char *contents;
+ size_t length;
+};
+
+static void
+check_lines (FILE *fp, const struct expected_line *expected)
+{
+ for (size_t i = 0; expected[i].contents != NULL; ++i)
+ {
+ size_t line_length;
+ char *line = fgetln (fp, &line_length);
+ if (line == NULL)
+ FAIL_EXIT1 ("failure to read line %zu (feof=%d ferror=%d)",
+ i, feof (fp), ferror (fp));
+ TEST_COMPARE_BLOB (expected[i].contents, expected[i].length,
+ line, line_length);
+ }
+
+ size_t line_length;
+ TEST_VERIFY (fgetln (fp, &line_length) == NULL);
+ TEST_VERIFY (feof (fp));
+ TEST_VERIFY (!ferror (fp));
+}
+
+static void
+check_popen (const char *command,
+ const struct expected_line *expected)
+{
+ char file_buffer[8];
+
+ for (int do_file_redirect = 0; do_file_redirect < 2; ++do_file_redirect)
+ for (int buffering = 0; buffering < 4; ++buffering)
+ {
+ FILE *fp = popen (command, "r");
+ if (fp == NULL)
+ FAIL_EXIT1 ("popen: %m");
+
+ if (do_file_redirect)
+ {
+ /* Copy the data to a temporary file, and use that stream
+ instead. */
+ FILE *tmpfp = tmpfile ();
+ if (tmpfp == NULL)
+ FAIL_EXIT1 ("tmpfile: %m");
+ while (true)
+ {
+ int ch = fgetc (fp);
+ if (ch == EOF)
+ {
+ TEST_VERIFY (!ferror (fp));
+ break;
+ }
+ fputc (ch, tmpfp);
+ TEST_VERIFY (!ferror (fp));
+ }
+
+ TEST_COMPARE (fflush (tmpfp), 0);
+ rewind (tmpfp);
+ TEST_COMPARE (pclose (fp), 0);
+ fp = tmpfp;
+ }
+
+ switch (buffering)
+ {
+ case 0:
+ /* Use default. */
+ break;
+ case 1:
+ /* Unbuffered. */
+ TEST_COMPARE (setvbuf (fp, NULL, _IONBF, 0), 0);
+ break;
+
+ case 2:
+ /* Small buffer. */
+ TEST_COMPARE (setvbuf (fp, file_buffer, _IOFBF,
+ sizeof (file_buffer) / 2),
+ 0);
+ break;
+ case 3:
+ /* Slightly larger buffer. */
+ TEST_COMPARE (setvbuf (fp, file_buffer, _IOFBF,
+ sizeof (file_buffer)),
+ 0);
+ break;
+ }
+
+ check_lines (fp, expected);
+
+ if (do_file_redirect)
+ TEST_COMPARE (fclose (fp), 0);
+ else
+ TEST_COMPARE (pclose (fp), 0);
+ }
+}
+
+static int
+do_test (void)
+{
+ check_popen ("exit 0", (const struct expected_line[]) { { } });
+ check_popen ("echo", (const struct expected_line[])
+ {
+ { "\n", 1 },
+ { }
+ });
+ check_popen ("echo Abc; echo Defg", (const struct expected_line[])
+ {
+ { "Abc\n", 4 },
+ { "Defg\n", 5 },
+ { }
+ });
+ check_popen ("printf 'aBc\ndEfg'", (const struct expected_line[])
+ {
+ { "aBc\n", 4 },
+ { "dEfg", 4 },
+ { }
+ });
+ check_popen ("printf 'abC123\ndeFg'", (const struct expected_line[])
+ {
+ { "abC123\n", 7 },
+ { "deFg", 4 },
+ { }
+ });
+ check_popen ("printf 'AbC123\nDeFg4\n56\n'", (const struct expected_line[])
+ {
+ { "AbC123\n", 7 },
+ { "DeFg4\n", 6 },
+ { "56\n", 3 },
+ { }
+ });
+ check_popen ("printf 'AbC123.\nDeFg4.\n56.\n78.\n'",
+ (const struct expected_line[])
+ {
+ { "AbC123.\n", 8 },
+ { "DeFg4.\n", 7 },
+ { "56.\n", 4 },
+ { "78.\n", 4 },
+ { }
+ });
+ check_popen ("printf 'ABC123.\nDEF\\000g4.\n56.\n78.\n'",
+ (const struct expected_line[])
+ {
+ { "ABC123.\n", 8 },
+ { "DEF\000g4.\n", 8 },
+ { "56.\n", 4 },
+ { "78.\n", 4 },
+ { }
+ });
+
+ return 0;
+}
+
+#include <support/test-driver.c>
@@ -2289,6 +2289,7 @@ GLIBC_2.35 __memcmpeq F
GLIBC_2.35 _dl_find_object F
GLIBC_2.35 close_range F
GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 fgetln F
GLIBC_2.4 __confstr_chk F
GLIBC_2.4 __fgets_chk F
GLIBC_2.4 __fgets_unlocked_chk F
@@ -2616,3 +2616,4 @@ GLIBC_2.35 __memcmpeq F
GLIBC_2.35 _dl_find_object F
GLIBC_2.35 epoll_pwait2 F
GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 fgetln F
@@ -2713,6 +2713,7 @@ GLIBC_2.35 __memcmpeq F
GLIBC_2.35 _dl_find_object F
GLIBC_2.35 epoll_pwait2 F
GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 fgetln F
GLIBC_2.4 _IO_fprintf F
GLIBC_2.4 _IO_printf F
GLIBC_2.4 _IO_sprintf F
@@ -2377,3 +2377,4 @@ GLIBC_2.35 __memcmpeq F
GLIBC_2.35 _dl_find_object F
GLIBC_2.35 epoll_pwait2 F
GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 fgetln F
@@ -496,6 +496,7 @@ GLIBC_2.35 __memcmpeq F
GLIBC_2.35 _dl_find_object F
GLIBC_2.35 epoll_pwait2 F
GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 fgetln F
GLIBC_2.4 _Exit F
GLIBC_2.4 _IO_2_1_stderr_ D 0xa0
GLIBC_2.4 _IO_2_1_stdin_ D 0xa0
@@ -493,6 +493,7 @@ GLIBC_2.35 __memcmpeq F
GLIBC_2.35 _dl_find_object F
GLIBC_2.35 epoll_pwait2 F
GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 fgetln F
GLIBC_2.4 _Exit F
GLIBC_2.4 _IO_2_1_stderr_ D 0xa0
GLIBC_2.4 _IO_2_1_stdin_ D 0xa0
@@ -2652,3 +2652,4 @@ GLIBC_2.35 __memcmpeq F
GLIBC_2.35 _dl_find_object F
GLIBC_2.35 epoll_pwait2 F
GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 fgetln F
@@ -2601,6 +2601,7 @@ GLIBC_2.35 __memcmpeq F
GLIBC_2.35 _dl_find_object F
GLIBC_2.35 epoll_pwait2 F
GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 fgetln F
GLIBC_2.4 __confstr_chk F
GLIBC_2.4 __fgets_chk F
GLIBC_2.4 __fgets_unlocked_chk F
@@ -2785,6 +2785,7 @@ GLIBC_2.35 __memcmpeq F
GLIBC_2.35 _dl_find_object F
GLIBC_2.35 epoll_pwait2 F
GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 fgetln F
GLIBC_2.4 __confstr_chk F
GLIBC_2.4 __fgets_chk F
GLIBC_2.4 __fgets_unlocked_chk F
@@ -2551,6 +2551,7 @@ GLIBC_2.35 __memcmpeq F
GLIBC_2.35 _dl_find_object F
GLIBC_2.35 epoll_pwait2 F
GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 fgetln F
GLIBC_2.4 __confstr_chk F
GLIBC_2.4 __fgets_chk F
GLIBC_2.4 __fgets_unlocked_chk F
@@ -497,6 +497,7 @@ GLIBC_2.35 __memcmpeq F
GLIBC_2.35 _dl_find_object F
GLIBC_2.35 epoll_pwait2 F
GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 fgetln F
GLIBC_2.4 _Exit F
GLIBC_2.4 _IO_2_1_stderr_ D 0x98
GLIBC_2.4 _IO_2_1_stdin_ D 0x98
@@ -2728,6 +2728,7 @@ GLIBC_2.35 __memcmpeq F
GLIBC_2.35 _dl_find_object F
GLIBC_2.35 epoll_pwait2 F
GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 fgetln F
GLIBC_2.4 __confstr_chk F
GLIBC_2.4 __fgets_chk F
GLIBC_2.4 __fgets_unlocked_chk F
@@ -2701,3 +2701,4 @@ GLIBC_2.35 __memcmpeq F
GLIBC_2.35 _dl_find_object F
GLIBC_2.35 epoll_pwait2 F
GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 fgetln F
@@ -2698,3 +2698,4 @@ GLIBC_2.35 __memcmpeq F
GLIBC_2.35 _dl_find_object F
GLIBC_2.35 epoll_pwait2 F
GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 fgetln F
@@ -2693,6 +2693,7 @@ GLIBC_2.35 __memcmpeq F
GLIBC_2.35 _dl_find_object F
GLIBC_2.35 epoll_pwait2 F
GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 fgetln F
GLIBC_2.4 __confstr_chk F
GLIBC_2.4 __fgets_chk F
GLIBC_2.4 __fgets_unlocked_chk F
@@ -2691,6 +2691,7 @@ GLIBC_2.35 __memcmpeq F
GLIBC_2.35 _dl_find_object F
GLIBC_2.35 epoll_pwait2 F
GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 fgetln F
GLIBC_2.4 __confstr_chk F
GLIBC_2.4 __fgets_chk F
GLIBC_2.4 __fgets_unlocked_chk F
@@ -2699,6 +2699,7 @@ GLIBC_2.35 __memcmpeq F
GLIBC_2.35 _dl_find_object F
GLIBC_2.35 epoll_pwait2 F
GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 fgetln F
GLIBC_2.4 __confstr_chk F
GLIBC_2.4 __fgets_chk F
GLIBC_2.4 __fgets_unlocked_chk F
@@ -2602,6 +2602,7 @@ GLIBC_2.35 __memcmpeq F
GLIBC_2.35 _dl_find_object F
GLIBC_2.35 epoll_pwait2 F
GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 fgetln F
GLIBC_2.4 __confstr_chk F
GLIBC_2.4 __fgets_chk F
GLIBC_2.4 __fgets_unlocked_chk F
@@ -2740,3 +2740,4 @@ GLIBC_2.35 __memcmpeq F
GLIBC_2.35 _dl_find_object F
GLIBC_2.35 epoll_pwait2 F
GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 fgetln F
@@ -2123,3 +2123,4 @@ GLIBC_2.35 wprintf F
GLIBC_2.35 write F
GLIBC_2.35 writev F
GLIBC_2.35 wscanf F
+GLIBC_2.36 fgetln F
@@ -2755,6 +2755,7 @@ GLIBC_2.35 __memcmpeq F
GLIBC_2.35 _dl_find_object F
GLIBC_2.35 epoll_pwait2 F
GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 fgetln F
GLIBC_2.4 _IO_fprintf F
GLIBC_2.4 _IO_printf F
GLIBC_2.4 _IO_sprintf F
@@ -2788,6 +2788,7 @@ GLIBC_2.35 __memcmpeq F
GLIBC_2.35 _dl_find_object F
GLIBC_2.35 epoll_pwait2 F
GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 fgetln F
GLIBC_2.4 _IO_fprintf F
GLIBC_2.4 _IO_printf F
GLIBC_2.4 _IO_sprintf F
@@ -2510,6 +2510,7 @@ GLIBC_2.35 __memcmpeq F
GLIBC_2.35 _dl_find_object F
GLIBC_2.35 epoll_pwait2 F
GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 fgetln F
GLIBC_2.4 _IO_fprintf F
GLIBC_2.4 _IO_printf F
GLIBC_2.4 _IO_sprintf F
@@ -2812,3 +2812,4 @@ GLIBC_2.35 __memcmpeq F
GLIBC_2.35 _dl_find_object F
GLIBC_2.35 epoll_pwait2 F
GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 fgetln F
@@ -2379,3 +2379,4 @@ GLIBC_2.35 __memcmpeq F
GLIBC_2.35 _dl_find_object F
GLIBC_2.35 epoll_pwait2 F
GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 fgetln F
@@ -2579,3 +2579,4 @@ GLIBC_2.35 __memcmpeq F
GLIBC_2.35 _dl_find_object F
GLIBC_2.35 epoll_pwait2 F
GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 fgetln F
@@ -2753,6 +2753,7 @@ GLIBC_2.35 __memcmpeq F
GLIBC_2.35 _dl_find_object F
GLIBC_2.35 epoll_pwait2 F
GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 fgetln F
GLIBC_2.4 _IO_fprintf F
GLIBC_2.4 _IO_printf F
GLIBC_2.4 _IO_sprintf F
@@ -2547,6 +2547,7 @@ GLIBC_2.35 __memcmpeq F
GLIBC_2.35 _dl_find_object F
GLIBC_2.35 epoll_pwait2 F
GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 fgetln F
GLIBC_2.4 _IO_fprintf F
GLIBC_2.4 _IO_printf F
GLIBC_2.4 _IO_sprintf F
@@ -2608,6 +2608,7 @@ GLIBC_2.35 __memcmpeq F
GLIBC_2.35 _dl_find_object F
GLIBC_2.35 epoll_pwait2 F
GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 fgetln F
GLIBC_2.4 __confstr_chk F
GLIBC_2.4 __fgets_chk F
GLIBC_2.4 __fgets_unlocked_chk F
@@ -2605,6 +2605,7 @@ GLIBC_2.35 __memcmpeq F
GLIBC_2.35 _dl_find_object F
GLIBC_2.35 epoll_pwait2 F
GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 fgetln F
GLIBC_2.4 __confstr_chk F
GLIBC_2.4 __fgets_chk F
GLIBC_2.4 __fgets_unlocked_chk F
@@ -2748,6 +2748,7 @@ GLIBC_2.35 __memcmpeq F
GLIBC_2.35 _dl_find_object F
GLIBC_2.35 epoll_pwait2 F
GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 fgetln F
GLIBC_2.4 _IO_fprintf F
GLIBC_2.4 _IO_printf F
GLIBC_2.4 _IO_sprintf F
@@ -2574,6 +2574,7 @@ GLIBC_2.35 __memcmpeq F
GLIBC_2.35 _dl_find_object F
GLIBC_2.35 epoll_pwait2 F
GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 fgetln F
GLIBC_2.4 __confstr_chk F
GLIBC_2.4 __fgets_chk F
GLIBC_2.4 __fgets_unlocked_chk F
@@ -2525,6 +2525,7 @@ GLIBC_2.35 __memcmpeq F
GLIBC_2.35 _dl_find_object F
GLIBC_2.35 epoll_pwait2 F
GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 fgetln F
GLIBC_2.4 __confstr_chk F
GLIBC_2.4 __fgets_chk F
GLIBC_2.4 __fgets_unlocked_chk F
@@ -2631,3 +2631,4 @@ GLIBC_2.35 __memcmpeq F
GLIBC_2.35 _dl_find_object F
GLIBC_2.35 epoll_pwait2 F
GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
+GLIBC_2.36 fgetln F