more is an ancient paging program dating back to the earliest unix operating system.
Lately, it was consuming 100% cpu while waiting for user input.
How can that be?
With more < long.txt, top reports:
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
4705 user 20 0 230564 2636 2372 R 99.7 0.0 10:20.66 more
strace reports more repeated calling the poll function:
poll([{fd=3, events=POLLIN|POLLERR|POLLHUP}, {fd=0, events=POLLIN|POLLERR|POLLHUP}, {fd=2, events=POLLIN|POLLERR|POLLHUP}], 3, -1) = 1 ([{fd=0, revents=POLLIN}])
more is reading long.txt on fd 0, or stdin:
poll returns immediately, because there is always something to read from long.txt, so this is the cause of the 100% cpu spin, a bugsignalfd, to monitor things like terminal window size changesA comparison of more on Fedora 39 strace shows:
poll([{fd=3, events=POLLIN|POLLERR|POLLHUP}, {fd=0, events=POLLIN}], 2, -1) = 1 ([{fd=0, revents=POLLIN}])
read(2
Again, poll returns immediately, because there is always something to read from long.txt:
more goes on to read from fd 2, and goes to sleep waiting for user inputread(2) saves more from spinning on Fedora 39, this means it is not paying attention to signals on fd 3What accounts for these bugs in such an ancient program?
more.c and use the poll system call resulted in signals being ignored while waiting
for the user to pagepoll results in 100% cpu utilization