1 /* $NetBSD: read.c,v 1.85 2016/02/24 17:20:01 christos Exp $ */ 2 3 /*- 4 * Copyright (c) 1992, 1993 5 * The Regents of the University of California. All rights reserved. 6 * 7 * This code is derived from software contributed to Berkeley by 8 * Christos Zoulas of Cornell University. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. Neither the name of the University nor the names of its contributors 19 * may be used to endorse or promote products derived from this software 20 * without specific prior written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 * SUCH DAMAGE. 33 */ 34 35 #include "config.h" 36 #if !defined(lint) && !defined(SCCSID) 37 #if 0 38 static char sccsid[] = "@(#)read.c 8.1 (Berkeley) 6/4/93"; 39 #else 40 __RCSID("$NetBSD: read.c,v 1.85 2016/02/24 17:20:01 christos Exp $"); 41 #endif 42 #endif /* not lint && not SCCSID */ 43 #include <sys/cdefs.h> 44 __FBSDID("$FreeBSD$"); 45 46 /* 47 * read.c: Clean this junk up! This is horrible code. 48 * Terminal read functions 49 */ 50 #include <ctype.h> 51 #include <errno.h> 52 #include <fcntl.h> 53 #include <limits.h> 54 #include <stdlib.h> 55 #include <string.h> 56 #include <unistd.h> 57 58 #include "el.h" 59 60 #define OKCMD -1 /* must be -1! */ 61 62 private int read__fixio(int, int); 63 private int read_preread(EditLine *); 64 private int read_char(EditLine *, wchar_t *); 65 private int read_getcmd(EditLine *, el_action_t *, Char *); 66 private void read_pop(c_macro_t *); 67 68 /* read_init(): 69 * Initialize the read stuff 70 */ 71 protected int 72 read_init(EditLine *el) 73 { 74 /* builtin read_char */ 75 el->el_read.read_char = read_char; 76 return 0; 77 } 78 79 80 /* el_read_setfn(): 81 * Set the read char function to the one provided. 82 * If it is set to EL_BUILTIN_GETCFN, then reset to the builtin one. 83 */ 84 protected int 85 el_read_setfn(EditLine *el, el_rfunc_t rc) 86 { 87 el->el_read.read_char = (rc == EL_BUILTIN_GETCFN) ? read_char : rc; 88 return 0; 89 } 90 91 92 /* el_read_getfn(): 93 * return the current read char function, or EL_BUILTIN_GETCFN 94 * if it is the default one 95 */ 96 protected el_rfunc_t 97 el_read_getfn(EditLine *el) 98 { 99 return el->el_read.read_char == read_char ? 100 EL_BUILTIN_GETCFN : el->el_read.read_char; 101 } 102 103 104 #ifndef MIN 105 #define MIN(A,B) ((A) < (B) ? (A) : (B)) 106 #endif 107 108 #ifdef DEBUG_EDIT 109 private void 110 read_debug(EditLine *el) 111 { 112 113 if (el->el_line.cursor > el->el_line.lastchar) 114 (void) fprintf(el->el_errfile, "cursor > lastchar\r\n"); 115 if (el->el_line.cursor < el->el_line.buffer) 116 (void) fprintf(el->el_errfile, "cursor < buffer\r\n"); 117 if (el->el_line.cursor > el->el_line.limit) 118 (void) fprintf(el->el_errfile, "cursor > limit\r\n"); 119 if (el->el_line.lastchar > el->el_line.limit) 120 (void) fprintf(el->el_errfile, "lastchar > limit\r\n"); 121 if (el->el_line.limit != &el->el_line.buffer[EL_BUFSIZ - 2]) 122 (void) fprintf(el->el_errfile, "limit != &buffer[EL_BUFSIZ-2]\r\n"); 123 } 124 #endif /* DEBUG_EDIT */ 125 126 127 /* read__fixio(): 128 * Try to recover from a read error 129 */ 130 /* ARGSUSED */ 131 private int 132 read__fixio(int fd __attribute__((__unused__)), int e) 133 { 134 135 switch (e) { 136 case -1: /* Make sure that the code is reachable */ 137 138 #ifdef EWOULDBLOCK 139 case EWOULDBLOCK: 140 #ifndef TRY_AGAIN 141 #define TRY_AGAIN 142 #endif 143 #endif /* EWOULDBLOCK */ 144 145 #if defined(POSIX) && defined(EAGAIN) 146 #if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN 147 case EAGAIN: 148 #ifndef TRY_AGAIN 149 #define TRY_AGAIN 150 #endif 151 #endif /* EWOULDBLOCK && EWOULDBLOCK != EAGAIN */ 152 #endif /* POSIX && EAGAIN */ 153 154 e = 0; 155 #ifdef TRY_AGAIN 156 #if defined(F_SETFL) && defined(O_NDELAY) 157 if ((e = fcntl(fd, F_GETFL, 0)) == -1) 158 return -1; 159 160 if (fcntl(fd, F_SETFL, e & ~O_NDELAY) == -1) 161 return -1; 162 else 163 e = 1; 164 #endif /* F_SETFL && O_NDELAY */ 165 166 #ifdef FIONBIO 167 { 168 int zero = 0; 169 170 if (ioctl(fd, FIONBIO, &zero) == -1) 171 return -1; 172 else 173 e = 1; 174 } 175 #endif /* FIONBIO */ 176 177 #endif /* TRY_AGAIN */ 178 return e ? 0 : -1; 179 180 case EINTR: 181 return 0; 182 183 default: 184 return -1; 185 } 186 } 187 188 189 /* read_preread(): 190 * Try to read the stuff in the input queue; 191 */ 192 private int 193 read_preread(EditLine *el) 194 { 195 int chrs = 0; 196 197 if (el->el_tty.t_mode == ED_IO) 198 return 0; 199 200 #ifndef WIDECHAR 201 /* FIONREAD attempts to buffer up multiple bytes, and to make that work 202 * properly with partial wide/UTF-8 characters would need some careful work. */ 203 #ifdef FIONREAD 204 (void) ioctl(el->el_infd, FIONREAD, &chrs); 205 if (chrs > 0) { 206 char buf[EL_BUFSIZ]; 207 208 chrs = read(el->el_infd, buf, 209 (size_t) MIN(chrs, EL_BUFSIZ - 1)); 210 if (chrs > 0) { 211 buf[chrs] = '\0'; 212 el_push(el, buf); 213 } 214 } 215 #endif /* FIONREAD */ 216 #endif 217 return chrs > 0; 218 } 219 220 221 /* el_push(): 222 * Push a macro 223 */ 224 public void 225 FUN(el,push)(EditLine *el, const Char *str) 226 { 227 c_macro_t *ma = &el->el_chared.c_macro; 228 229 if (str != NULL && ma->level + 1 < EL_MAXMACRO) { 230 ma->level++; 231 if ((ma->macro[ma->level] = Strdup(str)) != NULL) 232 return; 233 ma->level--; 234 } 235 terminal_beep(el); 236 terminal__flush(el); 237 } 238 239 240 /* read_getcmd(): 241 * Get next command from the input stream, return OKCMD on success. 242 * Character values > 255 are not looked up in the map, but inserted. 243 */ 244 private int 245 read_getcmd(EditLine *el, el_action_t *cmdnum, Char *ch) 246 { 247 static const Char meta = (Char)0x80; 248 el_action_t cmd; 249 wchar_t wc; 250 int num; 251 252 el->el_errno = 0; 253 do { 254 if ((num = el_wgetc(el, &wc)) != 1) {/* if EOF or error */ 255 el->el_errno = num == 0 ? 0 : errno; 256 return 0; /* not OKCMD */ 257 } 258 *ch = (Char)wc; 259 260 #ifdef KANJI 261 if ((*ch & meta)) { 262 el->el_state.metanext = 0; 263 cmd = CcViMap[' ']; 264 break; 265 } else 266 #endif /* KANJI */ 267 268 if (el->el_state.metanext) { 269 el->el_state.metanext = 0; 270 *ch |= meta; 271 } 272 #ifdef WIDECHAR 273 if (*ch >= N_KEYS) 274 cmd = ED_INSERT; 275 else 276 #endif 277 cmd = el->el_map.current[(unsigned char) *ch]; 278 if (cmd == ED_SEQUENCE_LEAD_IN) { 279 keymacro_value_t val; 280 switch (keymacro_get(el, ch, &val)) { 281 case XK_CMD: 282 cmd = val.cmd; 283 break; 284 case XK_STR: 285 FUN(el,push)(el, val.str); 286 break; 287 #ifdef notyet 288 case XK_EXE: 289 /* XXX: In the future to run a user function */ 290 RunCommand(val.str); 291 break; 292 #endif 293 default: 294 EL_ABORT((el->el_errfile, "Bad XK_ type \n")); 295 break; 296 } 297 } 298 if (el->el_map.alt == NULL) 299 el->el_map.current = el->el_map.key; 300 } while (cmd == ED_SEQUENCE_LEAD_IN); 301 *cmdnum = cmd; 302 return OKCMD; 303 } 304 305 /* read_char(): 306 * Read a character from the tty. 307 */ 308 private int 309 read_char(EditLine *el, wchar_t *cp) 310 { 311 ssize_t num_read; 312 int tried = 0; 313 char cbuf[MB_LEN_MAX]; 314 size_t cbp = 0; 315 int save_errno = errno; 316 317 again: 318 el->el_signal->sig_no = 0; 319 while ((num_read = read(el->el_infd, cbuf + cbp, (size_t)1)) == -1) { 320 int e = errno; 321 switch (el->el_signal->sig_no) { 322 case SIGCONT: 323 FUN(el,set)(el, EL_REFRESH); 324 /*FALLTHROUGH*/ 325 case SIGWINCH: 326 sig_set(el); 327 goto again; 328 default: 329 break; 330 } 331 if (!tried && read__fixio(el->el_infd, e) == 0) { 332 errno = save_errno; 333 tried = 1; 334 } else { 335 errno = e; 336 *cp = L'\0'; 337 return -1; 338 } 339 } 340 341 /* Test for EOF */ 342 if (num_read == 0) { 343 *cp = L'\0'; 344 return 0; 345 } 346 347 for (;;) { 348 349 ++cbp; 350 switch (ct_mbrtowc(cp, cbuf, cbp)) { 351 case (size_t)-1: 352 if (cbp > 1) { 353 /* 354 * Invalid sequence, discard all bytes 355 * except the last one. 356 */ 357 cbuf[0] = cbuf[cbp - 1]; 358 cbp = 0; 359 break; 360 } else { 361 /* Invalid byte, discard it. */ 362 cbp = 0; 363 goto again; 364 } 365 case (size_t)-2: 366 /* 367 * We don't support other multibyte charsets. 368 * The second condition shouldn't happen 369 * and is here merely for additional safety. 370 */ 371 if ((el->el_flags & CHARSET_IS_UTF8) == 0 || 372 cbp >= MB_LEN_MAX) { 373 errno = EILSEQ; 374 *cp = L'\0'; 375 return -1; 376 } 377 /* Incomplete sequence, read another byte. */ 378 goto again; 379 default: 380 /* Valid character, process it. */ 381 return 1; 382 } 383 } 384 } 385 386 /* read_pop(): 387 * Pop a macro from the stack 388 */ 389 private void 390 read_pop(c_macro_t *ma) 391 { 392 int i; 393 394 el_free(ma->macro[0]); 395 for (i = 0; i < ma->level; i++) 396 ma->macro[i] = ma->macro[i + 1]; 397 ma->level--; 398 ma->offset = 0; 399 } 400 401 /* el_wgetc(): 402 * Read a wide character 403 */ 404 public int 405 el_wgetc(EditLine *el, wchar_t *cp) 406 { 407 int num_read; 408 c_macro_t *ma = &el->el_chared.c_macro; 409 410 terminal__flush(el); 411 for (;;) { 412 if (ma->level < 0) { 413 if (!read_preread(el)) 414 break; 415 } 416 417 if (ma->level < 0) 418 break; 419 420 if (ma->macro[0][ma->offset] == '\0') { 421 read_pop(ma); 422 continue; 423 } 424 425 *cp = ma->macro[0][ma->offset++]; 426 427 if (ma->macro[0][ma->offset] == '\0') { 428 /* Needed for QuoteMode On */ 429 read_pop(ma); 430 } 431 432 return 1; 433 } 434 435 #ifdef DEBUG_READ 436 (void) fprintf(el->el_errfile, "Turning raw mode on\n"); 437 #endif /* DEBUG_READ */ 438 if (tty_rawmode(el) < 0)/* make sure the tty is set up correctly */ 439 return 0; 440 441 #ifdef DEBUG_READ 442 (void) fprintf(el->el_errfile, "Reading a character\n"); 443 #endif /* DEBUG_READ */ 444 num_read = (*el->el_read.read_char)(el, cp); 445 if (num_read < 0) 446 el->el_errno = errno; 447 #ifdef DEBUG_READ 448 (void) fprintf(el->el_errfile, "Got it %lc\n", *cp); 449 #endif /* DEBUG_READ */ 450 return num_read; 451 } 452 453 protected void 454 read_prepare(EditLine *el) 455 { 456 if (el->el_flags & HANDLE_SIGNALS) 457 sig_set(el); 458 if (el->el_flags & NO_TTY) 459 return; 460 if ((el->el_flags & (UNBUFFERED|EDIT_DISABLED)) == UNBUFFERED) 461 tty_rawmode(el); 462 463 /* This is relatively cheap, and things go terribly wrong if 464 we have the wrong size. */ 465 el_resize(el); 466 re_clear_display(el); /* reset the display stuff */ 467 ch_reset(el, 0); 468 re_refresh(el); /* print the prompt */ 469 470 if (el->el_flags & UNBUFFERED) 471 terminal__flush(el); 472 } 473 474 protected void 475 read_finish(EditLine *el) 476 { 477 if ((el->el_flags & UNBUFFERED) == 0) 478 (void) tty_cookedmode(el); 479 if (el->el_flags & HANDLE_SIGNALS) 480 sig_clr(el); 481 } 482 483 public const Char * 484 FUN(el,gets)(EditLine *el, int *nread) 485 { 486 int retval; 487 el_action_t cmdnum = 0; 488 int num; /* how many chars we have read at NL */ 489 wchar_t wc; 490 Char ch, *cp; 491 int crlf = 0; 492 int nrb; 493 #ifdef FIONREAD 494 c_macro_t *ma = &el->el_chared.c_macro; 495 #endif /* FIONREAD */ 496 497 if (nread == NULL) 498 nread = &nrb; 499 *nread = 0; 500 501 if (el->el_flags & NO_TTY) { 502 size_t idx; 503 504 cp = el->el_line.buffer; 505 while ((num = (*el->el_read.read_char)(el, &wc)) == 1) { 506 *cp = (Char)wc; 507 /* make sure there is space for next character */ 508 if (cp + 1 >= el->el_line.limit) { 509 idx = (size_t)(cp - el->el_line.buffer); 510 if (!ch_enlargebufs(el, (size_t)2)) 511 break; 512 cp = &el->el_line.buffer[idx]; 513 } 514 cp++; 515 if (el->el_flags & UNBUFFERED) 516 break; 517 if (cp[-1] == '\r' || cp[-1] == '\n') 518 break; 519 } 520 if (num == -1) { 521 if (errno == EINTR) 522 cp = el->el_line.buffer; 523 el->el_errno = errno; 524 } 525 526 goto noedit; 527 } 528 529 530 #ifdef FIONREAD 531 if (el->el_tty.t_mode == EX_IO && ma->level < 0) { 532 long chrs = 0; 533 534 (void) ioctl(el->el_infd, FIONREAD, &chrs); 535 if (chrs == 0) { 536 if (tty_rawmode(el) < 0) { 537 errno = 0; 538 *nread = 0; 539 return NULL; 540 } 541 } 542 } 543 #endif /* FIONREAD */ 544 545 if ((el->el_flags & UNBUFFERED) == 0) 546 read_prepare(el); 547 548 if (el->el_flags & EDIT_DISABLED) { 549 size_t idx; 550 551 if ((el->el_flags & UNBUFFERED) == 0) 552 cp = el->el_line.buffer; 553 else 554 cp = el->el_line.lastchar; 555 556 terminal__flush(el); 557 558 while ((num = (*el->el_read.read_char)(el, &wc)) == 1) { 559 *cp = (Char)wc; 560 /* make sure there is space next character */ 561 if (cp + 1 >= el->el_line.limit) { 562 idx = (size_t)(cp - el->el_line.buffer); 563 if (!ch_enlargebufs(el, (size_t)2)) 564 break; 565 cp = &el->el_line.buffer[idx]; 566 } 567 cp++; 568 crlf = cp[-1] == '\r' || cp[-1] == '\n'; 569 if (el->el_flags & UNBUFFERED) 570 break; 571 if (crlf) 572 break; 573 } 574 575 if (num == -1) { 576 if (errno == EINTR) 577 cp = el->el_line.buffer; 578 el->el_errno = errno; 579 } 580 581 goto noedit; 582 } 583 584 for (num = OKCMD; num == OKCMD;) { /* while still editing this 585 * line */ 586 #ifdef DEBUG_EDIT 587 read_debug(el); 588 #endif /* DEBUG_EDIT */ 589 /* if EOF or error */ 590 if ((num = read_getcmd(el, &cmdnum, &ch)) != OKCMD) { 591 num = -1; 592 #ifdef DEBUG_READ 593 (void) fprintf(el->el_errfile, 594 "Returning from el_gets %d\n", num); 595 #endif /* DEBUG_READ */ 596 break; 597 } 598 if (el->el_errno == EINTR) { 599 el->el_line.buffer[0] = '\0'; 600 el->el_line.lastchar = 601 el->el_line.cursor = el->el_line.buffer; 602 break; 603 } 604 if ((size_t)cmdnum >= el->el_map.nfunc) { /* BUG CHECK command */ 605 #ifdef DEBUG_EDIT 606 (void) fprintf(el->el_errfile, 607 "ERROR: illegal command from key 0%o\r\n", ch); 608 #endif /* DEBUG_EDIT */ 609 continue; /* try again */ 610 } 611 /* now do the real command */ 612 #ifdef DEBUG_READ 613 { 614 el_bindings_t *b; 615 for (b = el->el_map.help; b->name; b++) 616 if (b->func == cmdnum) 617 break; 618 if (b->name) 619 (void) fprintf(el->el_errfile, 620 "Executing %s\n", b->name); 621 else 622 (void) fprintf(el->el_errfile, 623 "Error command = %d\n", cmdnum); 624 } 625 #endif /* DEBUG_READ */ 626 /* vi redo needs these way down the levels... */ 627 el->el_state.thiscmd = cmdnum; 628 el->el_state.thisch = ch; 629 if (el->el_map.type == MAP_VI && 630 el->el_map.current == el->el_map.key && 631 el->el_chared.c_redo.pos < el->el_chared.c_redo.lim) { 632 if (cmdnum == VI_DELETE_PREV_CHAR && 633 el->el_chared.c_redo.pos != el->el_chared.c_redo.buf 634 && Isprint(el->el_chared.c_redo.pos[-1])) 635 el->el_chared.c_redo.pos--; 636 else 637 *el->el_chared.c_redo.pos++ = ch; 638 } 639 retval = (*el->el_map.func[cmdnum]) (el, ch); 640 #ifdef DEBUG_READ 641 (void) fprintf(el->el_errfile, 642 "Returned state %d\n", retval ); 643 #endif /* DEBUG_READ */ 644 645 /* save the last command here */ 646 el->el_state.lastcmd = cmdnum; 647 648 /* use any return value */ 649 switch (retval) { 650 case CC_CURSOR: 651 re_refresh_cursor(el); 652 break; 653 654 case CC_REDISPLAY: 655 re_clear_lines(el); 656 re_clear_display(el); 657 /* FALLTHROUGH */ 658 659 case CC_REFRESH: 660 re_refresh(el); 661 break; 662 663 case CC_REFRESH_BEEP: 664 re_refresh(el); 665 terminal_beep(el); 666 break; 667 668 case CC_NORM: /* normal char */ 669 break; 670 671 case CC_ARGHACK: /* Suggested by Rich Salz */ 672 /* <[email protected]> */ 673 continue; /* keep going... */ 674 675 case CC_EOF: /* end of file typed */ 676 if ((el->el_flags & UNBUFFERED) == 0) 677 num = 0; 678 else if (num == -1) { 679 *el->el_line.lastchar++ = CONTROL('d'); 680 el->el_line.cursor = el->el_line.lastchar; 681 num = 1; 682 } 683 break; 684 685 case CC_NEWLINE: /* normal end of line */ 686 num = (int)(el->el_line.lastchar - el->el_line.buffer); 687 break; 688 689 case CC_FATAL: /* fatal error, reset to known state */ 690 #ifdef DEBUG_READ 691 (void) fprintf(el->el_errfile, 692 "*** editor fatal ERROR ***\r\n\n"); 693 #endif /* DEBUG_READ */ 694 /* put (real) cursor in a known place */ 695 re_clear_display(el); /* reset the display stuff */ 696 ch_reset(el, 1); /* reset the input pointers */ 697 re_refresh(el); /* print the prompt again */ 698 break; 699 700 case CC_ERROR: 701 default: /* functions we don't know about */ 702 #ifdef DEBUG_READ 703 (void) fprintf(el->el_errfile, 704 "*** editor ERROR ***\r\n\n"); 705 #endif /* DEBUG_READ */ 706 terminal_beep(el); 707 terminal__flush(el); 708 break; 709 } 710 el->el_state.argument = 1; 711 el->el_state.doingarg = 0; 712 el->el_chared.c_vcmd.action = NOP; 713 if (el->el_flags & UNBUFFERED) 714 break; 715 } 716 717 terminal__flush(el); /* flush any buffered output */ 718 /* make sure the tty is set up correctly */ 719 if ((el->el_flags & UNBUFFERED) == 0) { 720 read_finish(el); 721 *nread = num != -1 ? num : 0; 722 } else { 723 *nread = (int)(el->el_line.lastchar - el->el_line.buffer); 724 } 725 goto done; 726 noedit: 727 el->el_line.cursor = el->el_line.lastchar = cp; 728 *cp = '\0'; 729 *nread = (int)(el->el_line.cursor - el->el_line.buffer); 730 done: 731 if (*nread == 0) { 732 if (num == -1) { 733 *nread = -1; 734 errno = el->el_errno; 735 } 736 return NULL; 737 } else 738 return el->el_line.buffer; 739 } 740