aboutsummaryrefslogtreecommitdiff
path: root/libbb/read_key.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--libbb/read_key.c30
1 files changed, 20 insertions, 10 deletions
diff --git a/libbb/read_key.c b/libbb/read_key.c
index cf8ed411e..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
@@ -112,8 +112,13 @@ 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#if ENABLE_PLATFORM_MINGW32
116 pfd.events = POLLIN; 116 if (!(terminal_mode(FALSE) & VT_INPUT))
117 return windows_read_key(fd, buffer, timeout);
118#endif
119
120 pfd->fd = fd;
121 pfd->events = POLLIN;
117 122
118 buffer++; /* saved chars counter is in buffer[-1] now */ 123 buffer++; /* saved chars counter is in buffer[-1] now */
119 124
@@ -121,12 +126,16 @@ int64_t FAST_FUNC read_key(int fd, char *buffer, int timeout)
121 errno = 0; 126 errno = 0;
122 n = (unsigned char)buffer[-1]; 127 n = (unsigned char)buffer[-1];
123 if (n == 0) { 128 if (n == 0) {
124 /* If no data, wait for input. 129 /* No data. Wait for input. */
125 * If requested, wait TIMEOUT ms. TIMEOUT = -1 is useful 130
126 * if fd can be in non-blocking mode. 131 /* timeout == -2 means "do not poll". Else: */
127 */
128 if (timeout >= -1) { 132 if (timeout >= -1) {
129 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);
130 if (n < 0 && errno == EINTR) 139 if (n < 0 && errno == EINTR)
131 return n; 140 return n;
132 if (n == 0) { 141 if (n == 0) {
@@ -135,6 +144,7 @@ int64_t FAST_FUNC read_key(int fd, char *buffer, int timeout)
135 return -1; 144 return -1;
136 } 145 }
137 } 146 }
147
138 /* It is tempting to read more than one byte here, 148 /* It is tempting to read more than one byte here,
139 * but it breaks pasting. Example: at shell prompt, 149 * but it breaks pasting. Example: at shell prompt,
140 * user presses "c","a","t" and then pastes "\nline\n". 150 * user presses "c","a","t" and then pastes "\nline\n".
@@ -173,7 +183,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. 183 * so if we block for long it's not really an escape sequence.
174 * Timeout is needed to reconnect escape sequences 184 * Timeout is needed to reconnect escape sequences
175 * split up by transmission over a serial console. */ 185 * split up by transmission over a serial console. */
176 if (safe_poll(&pfd, 1, 50) == 0) { 186 if (safe_poll(pfd, 1, 50) == 0) {
177 /* No more data! 187 /* No more data!
178 * Array is sorted from shortest to longest, 188 * Array is sorted from shortest to longest,
179 * we can't match anything later in array - 189 * we can't match anything later in array -
@@ -222,7 +232,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. 232 * n = bytes read. Try to read more until we time out.
223 */ 233 */
224 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] */
225 if (safe_poll(&pfd, 1, 50) == 0) { 235 if (safe_poll(pfd, 1, 50) == 0) {
226 /* No more data! */ 236 /* No more data! */
227 break; 237 break;
228 } 238 }