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