Skip to content

Commit 037679f

Browse files
committed
perform TTY and pipe check once
checking for interactive input e.g. from TTY or pipe is best done right after opening a file, this checks the file type to set the input to non-blocking for TTY, pipes, and sockets, then registering the non-blocking input-following handler later; this change also prevents unnecessary repeated checks when reading zip/tar archived files
1 parent f54f2e1 commit 037679f

1 file changed

Lines changed: 24 additions & 20 deletions

File tree

src/ugrep.cpp

Lines changed: 24 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3446,6 +3446,9 @@ struct Grep {
34463446
return false;
34473447
}
34483448

3449+
// "interactive" means possibly slow input from a TTY or pipe
3450+
interactive = false;
3451+
34493452
// --filter: fork process to filter file, when applicable
34503453
if (!filter(file_in, pathname))
34513454
return false;
@@ -3458,6 +3461,7 @@ struct Grep {
34583461
{
34593462
int fd = fileno(file_in);
34603463
struct stat buf;
3464+
34613465
if (fstat(fd, &buf) == 0 && S_ISREG(buf.st_mode))
34623466
fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) | O_NONBLOCK);
34633467
}
@@ -3510,6 +3514,22 @@ struct Grep {
35103514
input = reflex::Input(file_in, flag_encoding_type);
35113515
#endif
35123516

3517+
#ifndef OS_WIN
3518+
if (!flag_decompress && !flag_quiet && !flag_files_with_matches && !flag_count)
3519+
{
3520+
int fd = fileno(file_in);
3521+
struct stat buf;
3522+
3523+
// if input is a character device (e.g. TTY) or a pipe, then make it non-blocking and register a stdin handler to continue reading and flush results to output, don't check for invalid Unicode input
3524+
if (fstat(fd, &buf) == 0 && (S_ISCHR(buf.st_mode) || S_ISFIFO(buf.st_mode) || S_ISSOCK(buf.st_mode)))
3525+
interactive = (fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) | O_NONBLOCK) != -1);
3526+
}
3527+
#else
3528+
// for Windows we don't check for invalid Unicode input, no stdin handler
3529+
if (input == stdin && !flag_quiet && !flag_files_with_matches && !flag_count)
3530+
interactive = true;
3531+
#endif
3532+
35133533
return true;
35143534
}
35153535

@@ -3903,9 +3923,6 @@ struct Grep {
39033923
matches = 0;
39043924
stop = false;
39053925

3906-
// "interactive" and possibly slow input from a standard input device or pipe
3907-
bool interactive = false;
3908-
39093926
const char *base;
39103927
size_t size;
39113928

@@ -3930,23 +3947,9 @@ struct Grep {
39303947
#endif
39313948

39323949
#ifndef OS_WIN
3933-
if (!flag_decompress && !flag_quiet && !flag_files_with_matches && !flag_count)
3934-
{
3935-
int fd = fileno(file_in);
3936-
struct stat buf;
3937-
3938-
// if input is a character device (e.g. TTY) or a pipe, then make it non-blocking and register a stdin handler to continue reading and flush results to output, don't check for invalid Unicode input
3939-
if (fstat(fd, &buf) == 0 && (S_ISCHR(buf.st_mode) || S_ISFIFO(buf.st_mode) || S_ISSOCK(buf.st_mode)))
3940-
{
3941-
interactive = (fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) | O_NONBLOCK) != -1);
3942-
if (interactive)
3943-
matcher->in.set_handler(&stdin_handler);
3944-
}
3945-
}
3946-
#else
3947-
// for Windows we don't check for invalid Unicode input, no stdin handler
3948-
if (input == stdin && !flag_quiet && !flag_files_with_matches && !flag_count)
3949-
interactive = true;
3950+
// set interactive search handler e.g. for slow stdin input
3951+
if (interactive)
3952+
matcher->in.set_handler(&stdin_handler);
39503953
#endif
39513954
}
39523955

@@ -4070,6 +4073,7 @@ struct Grep {
40704073
MMap mmap; // mmap state
40714074
reflex::Input input; // input to the matcher
40724075
FILE *file_in; // the current input file
4076+
bool interactive; // the file being searched is a TTY or pipe
40734077
bool binfile; // the file being searched is a binary file
40744078
size_t lineno; // the line number of the last match
40754079
bool heading; // heading on/off, initially set to --with-filename

0 commit comments

Comments
 (0)