Skip to content

Commit

Permalink
more: make sure we have data on stderr
Browse files Browse the repository at this point in the history
more(1) uses more_poll() to monitor data on stdin, stderr, and
signals. It is used before read_command(), but this function only
reads from stderr. Therefore, if any other non-stderr event occurs,
this function will wait on read(). In this case, more(1) will not
react to signals anymore. We need to ensure that more(1) only waits in
more_poll().

Try

 for x in {1..1000}; do echo "line $x"; done | more

to reproduce.

Reported-by: Radka Skvarilova <rskvaril@redhat.com>
Signed-off-by: Karel Zak <kzak@redhat.com>
  • Loading branch information
karelzak committed Aug 22, 2024
1 parent 96ac92a commit 640b948
Showing 1 changed file with 13 additions and 5 deletions.
18 changes: 13 additions & 5 deletions text-utils/more.c
Original file line number Diff line number Diff line change
Expand Up @@ -1350,7 +1350,7 @@ static void read_line(struct more_control *ctl)
}

/* returns: 0 timeout or nothing; <0 error, >0 success */
static int more_poll(struct more_control *ctl, int timeout)
static int more_poll(struct more_control *ctl, int timeout, int *stderr_active)
{
enum {
POLLFD_SIGNAL = 0,
Expand All @@ -1364,6 +1364,9 @@ static int more_poll(struct more_control *ctl, int timeout)
};
int has_data = 0;

if (stderr_active)
*stderr_active = 0;

while (!has_data) {
int rc;

Expand Down Expand Up @@ -1430,8 +1433,11 @@ static int more_poll(struct more_control *ctl, int timeout)
}

/* event on stderr (we reads user commands from stderr!) */
if (pfd[POLLFD_STDERR].revents)
if (pfd[POLLFD_STDERR].revents) {
has_data++;
if (stderr_active)
*stderr_active = 1;
}
}

return has_data;
Expand Down Expand Up @@ -1502,7 +1508,7 @@ static void search(struct more_control *ctl, char buf[], int n)
}
break;
}
more_poll(ctl, 0);
more_poll(ctl, 0, NULL);
}
/* Move ctrl+c signal handling back to more_key_command(). */
signal(SIGINT, SIG_DFL);
Expand Down Expand Up @@ -1656,7 +1662,7 @@ static int skip_forwards(struct more_control *ctl, int nlines, cc_t comchar)
static int more_key_command(struct more_control *ctl, char *filename)
{
int retval = 0;
int done = 0, search_again = 0;
int done = 0, search_again = 0, stderr_active = 0;
char cmdbuf[INIT_BUF];
struct number_command cmd;

Expand All @@ -1666,7 +1672,9 @@ static int more_key_command(struct more_control *ctl, char *filename)
ctl->report_errors = 0;
ctl->search_called = 0;
for (;;) {
if (more_poll(ctl, -1) <= 0)
if (more_poll(ctl, -1, &stderr_active) <= 0)
continue;
if (stderr_active == 0)
continue;
cmd = read_command(ctl);
if (cmd.key == more_kc_unknown_command)
Expand Down

0 comments on commit 640b948

Please sign in to comment.