From 1946fed7b717e3d06b2246e72d15366cb2c443a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlo=20Marcelo=20Arenas=20Bel=C3=B3n?= Date: Tue, 2 Nov 2021 00:23:03 -0700 Subject: [PATCH] pcre2grep: avoid portability minefield with buffered fseek(stdin) To allow pcre2grep to do an early exit in a resumable way, -m uses fseek on stdin, which is sadly not supported in several platforms. Most of the conflicting issues come from the fact that managing the position while buffering is not trivial, and is therefore an optional feature[1] of POSIX.1-2017 Workaround this by removing the buffer to stdin, if the -m option is being used. There is likely not a significant performance benefit even for the platforms that support it, but it could be conditionally added in that case, later. Fixes: #10 [1] https://pubs.opengroup.org/onlinepubs/9699919799/functions/fseek.html --- src/pcre2grep.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/pcre2grep.c b/src/pcre2grep.c index aa84ea7ce..f182a1f08 100644 --- a/src/pcre2grep.c +++ b/src/pcre2grep.c @@ -3266,6 +3266,7 @@ FILE *zos_test_file; if (strcmp(pathname, "-") == 0) { + if (count_limit >= 0) setbuf(stdin, NULL); return pcre2grep(stdin, FR_PLAIN, stdin_name, (filenames > FN_DEFAULT || (filenames == FN_DEFAULT && !only_one_at_top))? stdin_name : NULL); @@ -4473,6 +4474,11 @@ no file arguments, search stdin, and then exit. */ if (file_lists == NULL && i >= argc) { + /* Using a buffered stdin, that then is seek is not portable, + so attempt to remove the buffer, to workaround reported issues + affecting several BSD and AIX */ + if (count_limit >= 0) + setbuf(stdin, NULL); rc = pcre2grep(stdin, FR_PLAIN, stdin_name, (filenames > FN_DEFAULT)? stdin_name : NULL); goto EXIT;