aboutsummaryrefslogtreecommitdiff
path: root/shell/shell_common.c
diff options
context:
space:
mode:
Diffstat (limited to 'shell/shell_common.c')
-rw-r--r--shell/shell_common.c84
1 files changed, 83 insertions, 1 deletions
diff --git a/shell/shell_common.c b/shell/shell_common.c
index 754fef34b..657f0df8f 100644
--- a/shell/shell_common.c
+++ b/shell/shell_common.c
@@ -62,7 +62,9 @@ shell_builtin_read(struct builtin_read_params *params)
62 char **pp; 62 char **pp;
63 char *buffer; 63 char *buffer;
64 char delim; 64 char delim;
65#if !ENABLE_PLATFORM_MINGW32
65 struct termios tty, old_tty; 66 struct termios tty, old_tty;
67#endif
66 const char *retval; 68 const char *retval;
67 int bufpos; /* need to be able to hold -1 */ 69 int bufpos; /* need to be able to hold -1 */
68 int startword; 70 int startword;
@@ -158,6 +160,7 @@ shell_builtin_read(struct builtin_read_params *params)
158 ifs = defifs; 160 ifs = defifs;
159 161
160 read_flags = params->read_flags; 162 read_flags = params->read_flags;
163#if !ENABLE_PLATFORM_MINGW32
161 if (nchars || (read_flags & BUILTIN_READ_SILENT)) { 164 if (nchars || (read_flags & BUILTIN_READ_SILENT)) {
162 tcgetattr(fd, &tty); 165 tcgetattr(fd, &tty);
163 old_tty = tty; 166 old_tty = tty;
@@ -180,6 +183,7 @@ shell_builtin_read(struct builtin_read_params *params)
180 * Ignoring, it's harmless. */ 183 * Ignoring, it's harmless. */
181 tcsetattr(fd, TCSANOW, &tty); 184 tcsetattr(fd, TCSANOW, &tty);
182 } 185 }
186#endif
183 187
184 retval = (const char *)(uintptr_t)0; 188 retval = (const char *)(uintptr_t)0;
185 startword = 1; 189 startword = 1;
@@ -196,6 +200,7 @@ shell_builtin_read(struct builtin_read_params *params)
196 if ((bufpos & 0xff) == 0) 200 if ((bufpos & 0xff) == 0)
197 buffer = xrealloc(buffer, bufpos + 0x101); 201 buffer = xrealloc(buffer, bufpos + 0x101);
198 202
203 IF_PLATFORM_MINGW32(loop:)
199 timeout = -1; 204 timeout = -1;
200 if (params->opt_t) { 205 if (params->opt_t) {
201 timeout = end_ms - (unsigned)monotonic_ms(); 206 timeout = end_ms - (unsigned)monotonic_ms();
@@ -216,6 +221,13 @@ shell_builtin_read(struct builtin_read_params *params)
216 errno = 0; 221 errno = 0;
217 pfd->events = POLLIN; 222 pfd->events = POLLIN;
218 223
224#if ENABLE_PLATFORM_MINGW32
225 /* Don't poll if timeout is -1, it hurts performance. The
226 * caution above about interrupts isn't relevant on Windows
227 * where Ctrl-C causes an event, not a signal.
228 */
229 if (timeout >= 0)
230#endif
219 /* test bb_got_signal, then poll(), atomically wrt signals */ 231 /* test bb_got_signal, then poll(), atomically wrt signals */
220 if (check_got_signal_and_poll(pfd, timeout) <= 0) { 232 if (check_got_signal_and_poll(pfd, timeout) <= 0) {
221 /* timed out, or some error */ 233 /* timed out, or some error */
@@ -227,6 +239,41 @@ shell_builtin_read(struct builtin_read_params *params)
227 retval = (const char *)(uintptr_t)1; 239 retval = (const char *)(uintptr_t)1;
228 goto ret; 240 goto ret;
229 } 241 }
242#if ENABLE_PLATFORM_MINGW32
243 if (isatty(fd)) {
244 int64_t key;
245
246 key = windows_read_key(fd, NULL, timeout);
247 if (key == 0x03) {
248 /* ^C pressed */
249 retval = (const char *)(uintptr_t)3;
250 goto ret;
251 }
252 else if (key == -1) {
253 /* timeout */
254 retval = (const char *)(uintptr_t)2;
255 break;
256 } else if (key == 0x1a && bufpos == 0) {
257 /* ^Z at start of buffer */
258 retval = (const char *)(uintptr_t)1;
259 break;
260 } else if (key == '\b') {
261 if (bufpos > 0) {
262 --bufpos;
263 ++nchars;
264 if (!(read_flags & BUILTIN_READ_SILENT)) {
265 console_write("\b \b", 3);
266 }
267 }
268 goto loop;
269 }
270 buffer[bufpos] = key == '\r' ? '\n' : key;
271 if (!(read_flags & BUILTIN_READ_SILENT)) {
272 /* echo input if not in silent mode */
273 console_write(buffer + bufpos, 1);
274 }
275 } else
276#endif
230 if (read(fd, &buffer[bufpos], 1) != 1) { 277 if (read(fd, &buffer[bufpos], 1) != 1) {
231 err = errno; 278 err = errno;
232 retval = (const char *)(uintptr_t)1; 279 retval = (const char *)(uintptr_t)1;
@@ -234,11 +281,37 @@ shell_builtin_read(struct builtin_read_params *params)
234 } 281 }
235 282
236 c = buffer[bufpos]; 283 c = buffer[bufpos];
284#if ENABLE_PLATFORM_MINGW32
285 if (c == '\n') {
286 if (backslash == 2 || (bufpos > 0 && buffer[bufpos - 1] == '\r')) {
287 /* We saw either:
288 * - BS CR LF: remove CR, fall through to ignore escaped LF
289 * and exit BS context.
290 * - CR LF not in BS context: replace CR with LF */
291 buffer[--bufpos] = c;
292 nchars += 1 + (backslash == 2);
293 }
294 } else if (backslash == 2) {
295 /* We saw BS CR ??, keep escaped CR, exit BS context,
296 * process ?? */
297 backslash = 0;
298 }
299#endif
237 if (!(read_flags & BUILTIN_READ_RAW)) { 300 if (!(read_flags & BUILTIN_READ_RAW)) {
238 if (backslash) { 301 if (backslash) {
302#if ENABLE_PLATFORM_MINGW32
303 if (c == '\r') {
304 /* We have BS CR, keep CR for now, might see LF next */
305 backslash = 2;
306 goto put;
307 }
308#endif
239 backslash = 0; 309 backslash = 0;
240 if (c != '\n') 310 if (c != '\n')
241 goto put; 311 goto put;
312#if ENABLE_PLATFORM_MINGW32
313 ++nchars;
314#endif
242 continue; 315 continue;
243 } 316 }
244 if (c == '\\') { 317 if (c == '\\') {
@@ -279,7 +352,7 @@ shell_builtin_read(struct builtin_read_params *params)
279 } 352 }
280 put: 353 put:
281 bufpos++; 354 bufpos++;
282 } while (--nchars); 355 } while (IF_PLATFORM_MINGW32(backslash ||) --nchars);
283 356
284 if (argv[0]) { 357 if (argv[0]) {
285 /* Remove trailing space $IFS chars */ 358 /* Remove trailing space $IFS chars */
@@ -334,8 +407,10 @@ shell_builtin_read(struct builtin_read_params *params)
334 407
335 ret: 408 ret:
336 free(buffer); 409 free(buffer);
410#if !ENABLE_PLATFORM_MINGW32
337 if (read_flags & BUILTIN_READ_SILENT) 411 if (read_flags & BUILTIN_READ_SILENT)
338 tcsetattr(fd, TCSANOW, &old_tty); 412 tcsetattr(fd, TCSANOW, &old_tty);
413#endif
339 414
340 errno = err; 415 errno = err;
341 return retval; 416 return retval;
@@ -344,6 +419,7 @@ shell_builtin_read(struct builtin_read_params *params)
344 419
345/* ulimit builtin */ 420/* ulimit builtin */
346 421
422#if !ENABLE_PLATFORM_MINGW32
347struct limits { 423struct limits {
348 uint8_t cmd; /* RLIMIT_xxx fit into it */ 424 uint8_t cmd; /* RLIMIT_xxx fit into it */
349 uint8_t factor_shift; /* shift by to get rlim_{cur,max} values */ 425 uint8_t factor_shift; /* shift by to get rlim_{cur,max} values */
@@ -712,3 +788,9 @@ shell_builtin_ulimit(char **argv)
712 788
713 return EXIT_SUCCESS; 789 return EXIT_SUCCESS;
714} 790}
791#else
792int FAST_FUNC shell_builtin_ulimit(char **argv UNUSED_PARAM)
793{
794 return 1;
795}
796#endif