aboutsummaryrefslogtreecommitdiff
path: root/libbb/read_key.c
diff options
context:
space:
mode:
Diffstat (limited to 'libbb/read_key.c')
-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 54886cc9c..2414105ee 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
@@ -117,8 +117,8 @@ int64_t FAST_FUNC read_key(int fd, char *buffer, int timeout)
117 return windows_read_key(fd, buffer, timeout); 117 return windows_read_key(fd, buffer, timeout);
118#endif 118#endif
119 119
120 pfd.fd = fd; 120 pfd->fd = fd;
121 pfd.events = POLLIN; 121 pfd->events = POLLIN;
122 122
123 buffer++; /* saved chars counter is in buffer[-1] now */ 123 buffer++; /* saved chars counter is in buffer[-1] now */
124 124
@@ -126,12 +126,16 @@ int64_t FAST_FUNC read_key(int fd, char *buffer, int timeout)
126 errno = 0; 126 errno = 0;
127 n = (unsigned char)buffer[-1]; 127 n = (unsigned char)buffer[-1];
128 if (n == 0) { 128 if (n == 0) {
129 /* If no data, wait for input. 129 /* No data. Wait for input. */
130 * If requested, wait TIMEOUT ms. TIMEOUT = -1 is useful 130
131 * if fd can be in non-blocking mode. 131 /* timeout == -2 means "do not poll". Else: */
132 */
133 if (timeout >= -1) { 132 if (timeout >= -1) {
134 n = poll(&pfd, 1, timeout); 133 /* We must poll even if timeout == -1:
134 * we want to be interrupted if signal arrives,
135 * regardless of SA_RESTART-ness of that signal!
136 */
137 /* test bb_got_signal, then poll(), atomically wrt signals */
138 n = check_got_signal_and_poll(pfd, timeout);
135 if (n < 0 && errno == EINTR) 139 if (n < 0 && errno == EINTR)
136 return n; 140 return n;
137 if (n == 0) { 141 if (n == 0) {
@@ -140,6 +144,7 @@ int64_t FAST_FUNC read_key(int fd, char *buffer, int timeout)
140 return -1; 144 return -1;
141 } 145 }
142 } 146 }
147
143 /* It is tempting to read more than one byte here, 148 /* It is tempting to read more than one byte here,
144 * but it breaks pasting. Example: at shell prompt, 149 * but it breaks pasting. Example: at shell prompt,
145 * user presses "c","a","t" and then pastes "\nline\n". 150 * user presses "c","a","t" and then pastes "\nline\n".
@@ -178,7 +183,7 @@ int64_t FAST_FUNC read_key(int fd, char *buffer, int timeout)
178 * so if we block for long it's not really an escape sequence. 183 * so if we block for long it's not really an escape sequence.
179 * Timeout is needed to reconnect escape sequences 184 * Timeout is needed to reconnect escape sequences
180 * split up by transmission over a serial console. */ 185 * split up by transmission over a serial console. */
181 if (safe_poll(&pfd, 1, 50) == 0) { 186 if (safe_poll(pfd, 1, 50) == 0) {
182 /* No more data! 187 /* No more data!
183 * Array is sorted from shortest to longest, 188 * Array is sorted from shortest to longest,
184 * we can't match anything later in array - 189 * we can't match anything later in array -
@@ -227,7 +232,7 @@ int64_t FAST_FUNC read_key(int fd, char *buffer, int timeout)
227 * n = bytes read. Try to read more until we time out. 232 * n = bytes read. Try to read more until we time out.
228 */ 233 */
229 while (n < KEYCODE_BUFFER_SIZE-1) { /* 1 for count byte at buffer[-1] */ 234 while (n < KEYCODE_BUFFER_SIZE-1) { /* 1 for count byte at buffer[-1] */
230 if (safe_poll(&pfd, 1, 50) == 0) { 235 if (safe_poll(pfd, 1, 50) == 0) {
231 /* No more data! */ 236 /* No more data! */
232 break; 237 break;
233 } 238 }