aboutsummaryrefslogtreecommitdiff
path: root/libbb/read_key.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--libbb/read_key.c25
1 files changed, 15 insertions, 10 deletions
diff --git a/libbb/read_key.c b/libbb/read_key.c
index cf8ed411e..3df9769f7 100644
--- a/libbb/read_key.c
+++ b/libbb/read_key.c
@@ -11,7 +11,7 @@
11 11
12int64_t FAST_FUNC read_key(int fd, char *buffer, int timeout) 12int64_t FAST_FUNC read_key(int fd, char *buffer, int timeout)
13{ 13{
14 struct pollfd pfd; 14 struct pollfd pfd[1];
15 const char *seq; 15 const char *seq;
16 int n; 16 int n;
17 17
@@ -112,8 +112,8 @@ int64_t FAST_FUNC read_key(int fd, char *buffer, int timeout)
112 0 112 0
113 }; 113 };
114 114
115 pfd.fd = fd; 115 pfd->fd = fd;
116 pfd.events = POLLIN; 116 pfd->events = POLLIN;
117 117
118 buffer++; /* saved chars counter is in buffer[-1] now */ 118 buffer++; /* saved chars counter is in buffer[-1] now */
119 119
@@ -121,12 +121,16 @@ int64_t FAST_FUNC read_key(int fd, char *buffer, int timeout)
121 errno = 0; 121 errno = 0;
122 n = (unsigned char)buffer[-1]; 122 n = (unsigned char)buffer[-1];
123 if (n == 0) { 123 if (n == 0) {
124 /* If no data, wait for input. 124 /* No data. Wait for input. */
125 * If requested, wait TIMEOUT ms. TIMEOUT = -1 is useful 125
126 * if fd can be in non-blocking mode. 126 /* timeout == -2 means "do not poll". Else: */
127 */
128 if (timeout >= -1) { 127 if (timeout >= -1) {
129 n = poll(&pfd, 1, timeout); 128 /* We must poll even if timeout == -1:
129 * we want to be interrupted if signal arrives,
130 * regardless of SA_RESTART-ness of that signal!
131 */
132 /* test bb_got_signal, then poll(), atomically wrt signals */
133 n = check_got_signal_and_poll(pfd, timeout);
130 if (n < 0 && errno == EINTR) 134 if (n < 0 && errno == EINTR)
131 return n; 135 return n;
132 if (n == 0) { 136 if (n == 0) {
@@ -135,6 +139,7 @@ int64_t FAST_FUNC read_key(int fd, char *buffer, int timeout)
135 return -1; 139 return -1;
136 } 140 }
137 } 141 }
142
138 /* It is tempting to read more than one byte here, 143 /* It is tempting to read more than one byte here,
139 * but it breaks pasting. Example: at shell prompt, 144 * but it breaks pasting. Example: at shell prompt,
140 * user presses "c","a","t" and then pastes "\nline\n". 145 * user presses "c","a","t" and then pastes "\nline\n".
@@ -173,7 +178,7 @@ int64_t FAST_FUNC read_key(int fd, char *buffer, int timeout)
173 * so if we block for long it's not really an escape sequence. 178 * so if we block for long it's not really an escape sequence.
174 * Timeout is needed to reconnect escape sequences 179 * Timeout is needed to reconnect escape sequences
175 * split up by transmission over a serial console. */ 180 * split up by transmission over a serial console. */
176 if (safe_poll(&pfd, 1, 50) == 0) { 181 if (safe_poll(pfd, 1, 50) == 0) {
177 /* No more data! 182 /* No more data!
178 * Array is sorted from shortest to longest, 183 * Array is sorted from shortest to longest,
179 * we can't match anything later in array - 184 * we can't match anything later in array -
@@ -222,7 +227,7 @@ int64_t FAST_FUNC read_key(int fd, char *buffer, int timeout)
222 * n = bytes read. Try to read more until we time out. 227 * n = bytes read. Try to read more until we time out.
223 */ 228 */
224 while (n < KEYCODE_BUFFER_SIZE-1) { /* 1 for count byte at buffer[-1] */ 229 while (n < KEYCODE_BUFFER_SIZE-1) { /* 1 for count byte at buffer[-1] */
225 if (safe_poll(&pfd, 1, 50) == 0) { 230 if (safe_poll(pfd, 1, 50) == 0) {
226 /* No more data! */ 231 /* No more data! */
227 break; 232 break;
228 } 233 }