[git commit] less: move "retry-on-EAGAIN" logic closer to read ops

Denys Vlasenko vda.linux at googlemail.com
Mon Sep 22 19:14:02 UTC 2014


commit: http://git.busybox.net/busybox/commit/?id=d6e7672545c717497490c0b0f54f64594f374f9d
branch: http://git.busybox.net/busybox/commit/?id=refs/heads/master

This makes "G" (goto end of input) command work as well as
/search_for_nonexistent_string: both will read to EOF now
even from somewhat slow input (such as kernel's "git log").

function                                             old     new   delta
ndelay_on                                             35      43      +8
ndelay_off                                            35      43      +8
read_lines                                           695     691      -4
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 2/1 up/down: 16/-4)              Total: 12 bytes

Signed-off-by: Denys Vlasenko <vda.linux at googlemail.com>
---
 include/libbb.h  |    4 ++--
 libbb/xfuncs.c   |   10 ++++++----
 miscutils/less.c |   47 +++++++++++++++++++++--------------------------
 3 files changed, 29 insertions(+), 32 deletions(-)

diff --git a/include/libbb.h b/include/libbb.h
index ff223dd..d57f00e 100644
--- a/include/libbb.h
+++ b/include/libbb.h
@@ -390,8 +390,8 @@ const char *bb_basename(const char *name) FAST_FUNC;
 char *last_char_is(const char *s, int c) FAST_FUNC;
 const char* endofname(const char *name) FAST_FUNC;
 
-void ndelay_on(int fd) FAST_FUNC;
-void ndelay_off(int fd) FAST_FUNC;
+int ndelay_on(int fd) FAST_FUNC;
+int ndelay_off(int fd) FAST_FUNC;
 void close_on_exec_on(int fd) FAST_FUNC;
 void xdup2(int, int) FAST_FUNC;
 void xmove_fd(int, int) FAST_FUNC;
diff --git a/libbb/xfuncs.c b/libbb/xfuncs.c
index 23f2751..f25ce94 100644
--- a/libbb/xfuncs.c
+++ b/libbb/xfuncs.c
@@ -25,20 +25,22 @@
 #include "libbb.h"
 
 /* Turn on nonblocking I/O on a fd */
-void FAST_FUNC ndelay_on(int fd)
+int FAST_FUNC ndelay_on(int fd)
 {
 	int flags = fcntl(fd, F_GETFL);
 	if (flags & O_NONBLOCK)
-		return;
+		return flags;
 	fcntl(fd, F_SETFL, flags | O_NONBLOCK);
+	return flags;
 }
 
-void FAST_FUNC ndelay_off(int fd)
+int FAST_FUNC ndelay_off(int fd)
 {
 	int flags = fcntl(fd, F_GETFL);
 	if (!(flags & O_NONBLOCK))
-		return;
+		return flags;
 	fcntl(fd, F_SETFL, flags & ~O_NONBLOCK);
+	return flags;
 }
 
 void FAST_FUNC close_on_exec_on(int fd)
diff --git a/miscutils/less.c b/miscutils/less.c
index 719af5a..3016c5b 100644
--- a/miscutils/less.c
+++ b/miscutils/less.c
@@ -414,10 +414,10 @@ static void read_lines(void)
 	char *current_line, *p;
 	int w = width;
 	char last_terminated = terminated;
+	time_t last_time = 0;
+	int retry_EAGAIN = 2;
 #if ENABLE_FEATURE_LESS_REGEXP
 	unsigned old_max_fline = max_fline;
-	time_t last_time = 0;
-	int had_progress = 2;
 #endif
 
 	/* (careful: max_fline can be -1) */
@@ -427,8 +427,6 @@ static void read_lines(void)
 	if (option_mask32 & FLAG_N)
 		w -= 8;
 
- IF_FEATURE_LESS_REGEXP(again0:)
-
 	p = current_line = ((char*)xmalloc(w + 4)) + 4;
 	max_fline += last_terminated;
 	if (!last_terminated) {
@@ -448,15 +446,29 @@ static void read_lines(void)
 			char c;
 			/* if no unprocessed chars left, eat more */
 			if (readpos >= readeof) {
-				errno = 0;
-				ndelay_on(0);
-				eof_error = safe_read(STDIN_FILENO, readbuf, sizeof(readbuf));
-				ndelay_off(0);
+				int flags = ndelay_on(0);
+
+				while (1) {
+					time_t t;
+
+					errno = 0;
+					eof_error = safe_read(STDIN_FILENO, readbuf, sizeof(readbuf));
+					if (errno != EAGAIN)
+						break;
+					t = time(NULL);
+					if (t != last_time) {
+						last_time = t;
+						if (--retry_EAGAIN < 0)
+							break;
+					}
+					sched_yield();
+				}
+				fcntl(0, F_SETFL, flags); /* ndelay_off(0) */
 				readpos = 0;
 				readeof = eof_error;
 				if (eof_error <= 0)
 					goto reached_eof;
-				IF_FEATURE_LESS_REGEXP(had_progress = 1;)
+				retry_EAGAIN = 1;
 			}
 			c = readbuf[readpos];
 			/* backspace? [needed for manpages] */
@@ -534,24 +546,7 @@ static void read_lines(void)
 #endif
 		}
 		if (eof_error <= 0) {
-#if !ENABLE_FEATURE_LESS_REGEXP
 			break;
-#else
-			if (wanted_match < num_matches) {
-				break;
-			} /* else: goto_match() called us */
-			if (errno == EAGAIN) {
-				time_t t = time(NULL);
-				if (t != last_time) {
-					last_time = t;
-					if (--had_progress < 0)
-						break;
-				}
-				sched_yield();
-				goto again0;
-			}
-			break;
-#endif
 		}
 		max_fline++;
 		current_line = ((char*)xmalloc(w + 4)) + 4;


More information about the busybox-cvs mailing list