1This file is read.def, from which is created read.c. 2It implements the builtin "read" in Bash. 3 4Copyright (C) 1987-2009 Free Software Foundation, Inc. 5 6This file is part of GNU Bash, the Bourne Again SHell. 7 8Bash is free software: you can redistribute it and/or modify 9it under the terms of the GNU General Public License as published by 10the Free Software Foundation, either version 3 of the License, or 11(at your option) any later version. 12 13Bash is distributed in the hope that it will be useful, 14but WITHOUT ANY WARRANTY; without even the implied warranty of 15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16GNU General Public License for more details. 17 18You should have received a copy of the GNU General Public License 19along with Bash. If not, see <http://www.gnu.org/licenses/>. 20 21$PRODUCES read.c 22 23$BUILTIN read 24$FUNCTION read_builtin 25$SHORT_DOC read [-ers] [-a array] [-d delim] [-i text] [-n nchars] [-p prompt] [-t timeout] [-u fd] [name ...] 26Read a line from the standard input and split it into fields. 27 28Reads a single line from the standard input, or from file descriptor FD 29if the -u option is supplied. The line is split into fields as with word 30splitting, and the first word is assigned to the first NAME, the second 31word to the second NAME, and so on, with any leftover words assigned to 32the last NAME. Only the characters found in $IFS are recognized as word 33delimiters. 34 35If no NAMEs are supplied, the line read is stored in the REPLY variable. 36 37Options: 38 -a array assign the words read to sequential indices of the array 39 variable ARRAY, starting at zero 40 -d delim continue until the first character of DELIM is read, rather 41 than newline 42 -e use Readline to obtain the line in an interactive shell 43 -i text Use TEXT as the initial text for Readline 44 -n nchars return after reading NCHARS characters rather than waiting 45 for a newline 46 -p prompt output the string PROMPT without a trailing newline before 47 attempting to read 48 -r do not allow backslashes to escape any characters 49 -s do not echo input coming from a terminal 50 -t timeout time out and return failure if a complete line of input is 51 not read withint TIMEOUT seconds. The value of the TMOUT 52 variable is the default timeout. TIMEOUT may be a 53 fractional number. If TIMEOUT is 0, read returns success only 54 if input is available on the specified file descriptor. The 55 exit status is greater than 128 if the timeout is exceeded 56 -u fd read from file descriptor FD instead of the standard input 57 58Exit Status: 59The return code is zero, unless end-of-file is encountered, read times out, 60or an invalid file descriptor is supplied as the argument to -u. 61$END 62 63#include <config.h> 64 65#include "bashtypes.h" 66#include "posixstat.h" 67 68#include <stdio.h> 69 70#include "bashansi.h" 71 72#if defined (HAVE_UNISTD_H) 73# include <unistd.h> 74#endif 75 76#include <signal.h> 77#include <errno.h> 78 79#ifdef __CYGWIN__ 80# include <fcntl.h> 81# include <io.h> 82#endif 83 84#include "../bashintl.h" 85 86#include "../shell.h" 87#include "common.h" 88#include "bashgetopt.h" 89 90#include <shtty.h> 91 92#if defined (READLINE) 93#include "../bashline.h" 94#include <readline/readline.h> 95#endif 96 97#if defined (BUFFERED_INPUT) 98# include "input.h" 99#endif 100 101#if !defined(errno) 102extern int errno; 103#endif 104 105struct ttsave 106{ 107 int fd; 108 TTYSTRUCT *attrs; 109}; 110 111#if defined (READLINE) 112static void reset_attempted_completion_function __P((char *)); 113static int set_itext __P((void)); 114static char *edit_line __P((char *, char *)); 115static void set_eol_delim __P((int)); 116static void reset_eol_delim __P((char *)); 117#endif 118static SHELL_VAR *bind_read_variable __P((char *, char *)); 119#if defined (HANDLE_MULTIBYTE) 120static int read_mbchar __P((int, char *, int, int, int)); 121#endif 122static void ttyrestore __P((struct ttsave *)); 123 124static sighandler sigalrm __P((int)); 125static void reset_alarm __P((void)); 126 127static procenv_t alrmbuf; 128static SigHandler *old_alrm; 129static unsigned char delim; 130 131static sighandler 132sigalrm (s) 133 int s; 134{ 135 longjmp (alrmbuf, 1); 136} 137 138static void 139reset_alarm () 140{ 141 set_signal_handler (SIGALRM, old_alrm); 142 falarm (0, 0); 143} 144 145/* Read the value of the shell variables whose names follow. 146 The reading is done from the current input stream, whatever 147 that may be. Successive words of the input line are assigned 148 to the variables mentioned in LIST. The last variable in LIST 149 gets the remainder of the words on the line. If no variables 150 are mentioned in LIST, then the default variable is $REPLY. */ 151int 152read_builtin (list) 153 WORD_LIST *list; 154{ 155 register char *varname; 156 int size, i, nr, pass_next, saw_escape, eof, opt, retval, code, print_ps2; 157 int input_is_tty, input_is_pipe, unbuffered_read, skip_ctlesc, skip_ctlnul; 158 int raw, edit, nchars, silent, have_timeout, fd; 159 unsigned int tmsec, tmusec; 160 long ival, uval; 161 intmax_t intval; 162 char c; 163 char *input_string, *orig_input_string, *ifs_chars, *prompt, *arrayname; 164 char *e, *t, *t1, *ps2, *tofree; 165 struct stat tsb; 166 SHELL_VAR *var; 167 TTYSTRUCT ttattrs, ttset; 168 struct ttsave termsave; 169#if defined (ARRAY_VARS) 170 WORD_LIST *alist; 171#endif 172#if defined (READLINE) 173 char *rlbuf, *itext; 174 int rlind; 175#endif 176 177 USE_VAR(size); 178 USE_VAR(i); 179 USE_VAR(pass_next); 180 USE_VAR(print_ps2); 181 USE_VAR(saw_escape); 182 USE_VAR(input_is_pipe); 183/* USE_VAR(raw); */ 184 USE_VAR(edit); 185 USE_VAR(tmsec); 186 USE_VAR(tmusec); 187 USE_VAR(nchars); 188 USE_VAR(silent); 189 USE_VAR(ifs_chars); 190 USE_VAR(prompt); 191 USE_VAR(arrayname); 192#if defined (READLINE) 193 USE_VAR(rlbuf); 194 USE_VAR(rlind); 195 USE_VAR(itext); 196#endif 197 USE_VAR(list); 198 USE_VAR(ps2); 199 200 i = 0; /* Index into the string that we are reading. */ 201 raw = edit = 0; /* Not reading raw input by default. */ 202 silent = 0; 203 arrayname = prompt = (char *)NULL; 204 fd = 0; /* file descriptor to read from */ 205 206#if defined (READLINE) 207 rlbuf = itext = (char *)0; 208 rlind = 0; 209#endif 210 211 tmsec = tmusec = 0; /* no timeout */ 212 nr = nchars = input_is_tty = input_is_pipe = unbuffered_read = have_timeout = 0; 213 delim = '\n'; /* read until newline */ 214 215 reset_internal_getopt (); 216 while ((opt = internal_getopt (list, "ersa:d:i:n:p:t:u:")) != -1) 217 { 218 switch (opt) 219 { 220 case 'r': 221 raw = 1; 222 break; 223 case 'p': 224 prompt = list_optarg; 225 break; 226 case 's': 227 silent = 1; 228 break; 229 case 'e': 230#if defined (READLINE) 231 edit = 1; 232#endif 233 break; 234 case 'i': 235#if defined (READLINE) 236 itext = list_optarg; 237#endif 238 break; 239#if defined (ARRAY_VARS) 240 case 'a': 241 arrayname = list_optarg; 242 break; 243#endif 244 case 't': 245 code = uconvert (list_optarg, &ival, &uval); 246 if (code == 0 || ival < 0 || uval < 0) 247 { 248 builtin_error (_("%s: invalid timeout specification"), list_optarg); 249 return (EXECUTION_FAILURE); 250 } 251 else 252 { 253 have_timeout = 1; 254 tmsec = ival; 255 tmusec = uval; 256 } 257 break; 258 case 'n': 259 code = legal_number (list_optarg, &intval); 260 if (code == 0 || intval < 0 || intval != (int)intval) 261 { 262 sh_invalidnum (list_optarg); 263 return (EXECUTION_FAILURE); 264 } 265 else 266 nchars = intval; 267 break; 268 case 'u': 269 code = legal_number (list_optarg, &intval); 270 if (code == 0 || intval < 0 || intval != (int)intval) 271 { 272 builtin_error (_("%s: invalid file descriptor specification"), list_optarg); 273 return (EXECUTION_FAILURE); 274 } 275 else 276 fd = intval; 277 if (sh_validfd (fd) == 0) 278 { 279 builtin_error (_("%d: invalid file descriptor: %s"), fd, strerror (errno)); 280 return (EXECUTION_FAILURE); 281 } 282 break; 283 case 'd': 284 delim = *list_optarg; 285 break; 286 default: 287 builtin_usage (); 288 return (EX_USAGE); 289 } 290 } 291 list = loptend; 292 293 /* `read -t 0 var' tests whether input is available with select/FIONREAD, 294 and fails if those are unavailable */ 295 if (have_timeout && tmsec == 0 && tmusec == 0) 296#if 0 297 return (EXECUTION_FAILURE); 298#else 299 return (input_avail (fd) ? EXECUTION_SUCCESS : EXECUTION_FAILURE); 300#endif 301 302 /* IF IFS is unset, we use the default of " \t\n". */ 303 ifs_chars = getifs (); 304 if (ifs_chars == 0) /* XXX - shouldn't happen */ 305 ifs_chars = ""; 306 for (skip_ctlesc = skip_ctlnul = 0, e = ifs_chars; *e; e++) 307 skip_ctlesc |= *e == CTLESC, skip_ctlnul |= *e == CTLNUL; 308 309 input_string = (char *)xmalloc (size = 112); /* XXX was 128 */ 310 input_string[0] = '\0'; 311 312 /* $TMOUT, if set, is the default timeout for read. */ 313 if (have_timeout == 0 && (e = get_string_value ("TMOUT"))) 314 { 315 code = uconvert (e, &ival, &uval); 316 if (code == 0 || ival < 0 || uval < 0) 317 tmsec = tmusec = 0; 318 else 319 { 320 tmsec = ival; 321 tmusec = uval; 322 } 323 } 324 325 begin_unwind_frame ("read_builtin"); 326 327#if defined (BUFFERED_INPUT) 328 if (interactive == 0 && default_buffered_input >= 0 && fd_is_bash_input (fd)) 329 sync_buffered_stream (default_buffered_input); 330#endif 331 332 input_is_tty = isatty (fd); 333 if (input_is_tty == 0) 334#ifndef __CYGWIN__ 335 input_is_pipe = (lseek (fd, 0L, SEEK_CUR) < 0) && (errno == ESPIPE); 336#else 337 input_is_pipe = 1; 338#endif 339 340 /* If the -p, -e or -s flags were given, but input is not coming from the 341 terminal, turn them off. */ 342 if ((prompt || edit || silent) && input_is_tty == 0) 343 { 344 prompt = (char *)NULL; 345#if defined (READLINE) 346 itext = (char *)NULL; 347#endif 348 edit = silent = 0; 349 } 350 351#if defined (READLINE) 352 if (edit) 353 add_unwind_protect (xfree, rlbuf); 354#endif 355 356 pass_next = 0; /* Non-zero signifies last char was backslash. */ 357 saw_escape = 0; /* Non-zero signifies that we saw an escape char */ 358 359 if (tmsec > 0 || tmusec > 0) 360 { 361 /* Turn off the timeout if stdin is a regular file (e.g. from 362 input redirection). */ 363 if ((fstat (fd, &tsb) < 0) || S_ISREG (tsb.st_mode)) 364 tmsec = tmusec = 0; 365 } 366 367 if (tmsec > 0 || tmusec > 0) 368 { 369 code = setjmp (alrmbuf); 370 if (code) 371 { 372 /* Tricky. The top of the unwind-protect stack is the free of 373 input_string. We want to run all the rest and use input_string, 374 so we have to remove it from the stack. */ 375 remove_unwind_protect (); 376 run_unwind_frame ("read_builtin"); 377 input_string[i] = '\0'; /* make sure it's terminated */ 378 retval = 128+SIGALRM; 379 goto assign_vars; 380 } 381 old_alrm = set_signal_handler (SIGALRM, sigalrm); 382 add_unwind_protect (reset_alarm, (char *)NULL); 383#if defined (READLINE) 384 if (edit) 385 add_unwind_protect (reset_attempted_completion_function, (char *)NULL); 386#endif 387 falarm (tmsec, tmusec); 388 } 389 390 /* If we've been asked to read only NCHARS chars, or we're using some 391 character other than newline to terminate the line, do the right 392 thing to readline or the tty. */ 393 if (nchars > 0 || delim != '\n') 394 { 395#if defined (READLINE) 396 if (edit) 397 { 398 if (nchars > 0) 399 { 400 unwind_protect_int (rl_num_chars_to_read); 401 rl_num_chars_to_read = nchars; 402 } 403 if (delim != '\n') 404 { 405 set_eol_delim (delim); 406 add_unwind_protect (reset_eol_delim, (char *)NULL); 407 } 408 } 409 else 410#endif 411 if (input_is_tty) 412 { 413 /* ttsave() */ 414 termsave.fd = fd; 415 ttgetattr (fd, &ttattrs); 416 termsave.attrs = &ttattrs; 417 418 ttset = ttattrs; 419 i = silent ? ttfd_cbreak (fd, &ttset) : ttfd_onechar (fd, &ttset); 420 if (i < 0) 421 sh_ttyerror (1); 422 add_unwind_protect ((Function *)ttyrestore, (char *)&termsave); 423 } 424 } 425 else if (silent) /* turn off echo but leave term in canonical mode */ 426 { 427 /* ttsave (); */ 428 termsave.fd = fd; 429 ttgetattr (fd, &ttattrs); 430 termsave.attrs = &ttattrs; 431 432 ttset = ttattrs; 433 i = ttfd_noecho (fd, &ttset); /* ttnoecho (); */ 434 if (i < 0) 435 sh_ttyerror (1); 436 437 add_unwind_protect ((Function *)ttyrestore, (char *)&termsave); 438 } 439 440 /* This *must* be the top unwind-protect on the stack, so the manipulation 441 of the unwind-protect stack after the realloc() works right. */ 442 add_unwind_protect (xfree, input_string); 443 interrupt_immediately++; 444 terminate_immediately++; 445 446 unbuffered_read = (nchars > 0) || (delim != '\n') || input_is_pipe; 447 448 if (prompt && edit == 0) 449 { 450 fprintf (stderr, "%s", prompt); 451 fflush (stderr); 452 } 453 454#if defined (__CYGWIN__) && defined (O_TEXT) 455 setmode (0, O_TEXT); 456#endif 457 458 ps2 = 0; 459 for (print_ps2 = eof = retval = 0;;) 460 { 461#if defined (READLINE) 462 if (edit) 463 { 464 if (rlbuf && rlbuf[rlind] == '\0') 465 { 466 xfree (rlbuf); 467 rlbuf = (char *)0; 468 } 469 if (rlbuf == 0) 470 { 471 rlbuf = edit_line (prompt ? prompt : "", itext); 472 rlind = 0; 473 } 474 if (rlbuf == 0) 475 { 476 eof = 1; 477 break; 478 } 479 c = rlbuf[rlind++]; 480 } 481 else 482 { 483#endif 484 485 if (print_ps2) 486 { 487 if (ps2 == 0) 488 ps2 = get_string_value ("PS2"); 489 fprintf (stderr, "%s", ps2 ? ps2 : ""); 490 fflush (stderr); 491 print_ps2 = 0; 492 } 493 494 if (unbuffered_read) 495 retval = zread (fd, &c, 1); 496 else 497 retval = zreadc (fd, &c); 498 499 if (retval <= 0) 500 { 501 eof = 1; 502 break; 503 } 504 505#if defined (READLINE) 506 } 507#endif 508 509 if (i + 4 >= size) /* XXX was i + 2; use i + 4 for multibyte/read_mbchar */ 510 { 511 input_string = (char *)xrealloc (input_string, size += 128); 512 remove_unwind_protect (); 513 add_unwind_protect (xfree, input_string); 514 } 515 516 /* If the next character is to be accepted verbatim, a backslash 517 newline pair still disappears from the input. */ 518 if (pass_next) 519 { 520 pass_next = 0; 521 if (c == '\n') 522 { 523 i--; /* back up over the CTLESC */ 524 if (interactive && input_is_tty && raw == 0) 525 print_ps2 = 1; 526 } 527 else 528 goto add_char; 529 continue; 530 } 531 532 /* This may cause problems if IFS contains CTLESC */ 533 if (c == '\\' && raw == 0) 534 { 535 pass_next++; 536 if (skip_ctlesc == 0) 537 { 538 saw_escape++; 539 input_string[i++] = CTLESC; 540 } 541 continue; 542 } 543 544 if ((unsigned char)c == delim) 545 break; 546 547 if ((skip_ctlesc == 0 && c == CTLESC) || (skip_ctlnul == 0 && c == CTLNUL)) 548 { 549 saw_escape++; 550 input_string[i++] = CTLESC; 551 } 552 553add_char: 554 input_string[i++] = c; 555 556#if defined (HANDLE_MULTIBYTE) 557 if (nchars > 0 && MB_CUR_MAX > 1) 558 { 559 input_string[i] = '\0'; /* for simplicity and debugging */ 560 i += read_mbchar (fd, input_string, i, c, unbuffered_read); 561 } 562#endif 563 564 nr++; 565 566 if (nchars > 0 && nr >= nchars) 567 break; 568 } 569 input_string[i] = '\0'; 570 571#if 1 572 if (retval < 0) 573 { 574 builtin_error (_("read error: %d: %s"), fd, strerror (errno)); 575 run_unwind_frame ("read_builtin"); 576 return (EXECUTION_FAILURE); 577 } 578#endif 579 580 if (tmsec > 0 || tmusec > 0) 581 reset_alarm (); 582 583 if (nchars > 0 || delim != '\n') 584 { 585#if defined (READLINE) 586 if (edit) 587 { 588 if (nchars > 0) 589 rl_num_chars_to_read = 0; 590 if (delim != '\n') 591 reset_eol_delim ((char *)NULL); 592 } 593 else 594#endif 595 if (input_is_tty) 596 ttyrestore (&termsave); 597 } 598 else if (silent) 599 ttyrestore (&termsave); 600 601 if (unbuffered_read == 0) 602 zsyncfd (fd); 603 604 interrupt_immediately--; 605 terminate_immediately--; 606 discard_unwind_frame ("read_builtin"); 607 608 retval = eof ? EXECUTION_FAILURE : EXECUTION_SUCCESS; 609 610assign_vars: 611 612#if defined (ARRAY_VARS) 613 /* If -a was given, take the string read, break it into a list of words, 614 an assign them to `arrayname' in turn. */ 615 if (arrayname) 616 { 617 if (legal_identifier (arrayname) == 0) 618 { 619 sh_invalidid (arrayname); 620 xfree (input_string); 621 return (EXECUTION_FAILURE); 622 } 623 624 var = find_or_make_array_variable (arrayname, 1); 625 if (var == 0) 626 { 627 xfree (input_string); 628 return EXECUTION_FAILURE; /* readonly or noassign */ 629 } 630 array_flush (array_cell (var)); 631 632 alist = list_string (input_string, ifs_chars, 0); 633 if (alist) 634 { 635 if (saw_escape) 636 dequote_list (alist); 637 else 638 word_list_remove_quoted_nulls (alist); 639 assign_array_var_from_word_list (var, alist, 0); 640 dispose_words (alist); 641 } 642 xfree (input_string); 643 return (retval); 644 } 645#endif /* ARRAY_VARS */ 646 647 /* If there are no variables, save the text of the line read to the 648 variable $REPLY. ksh93 strips leading and trailing IFS whitespace, 649 so that `read x ; echo "$x"' and `read ; echo "$REPLY"' behave the 650 same way, but I believe that the difference in behaviors is useful 651 enough to not do it. Without the bash behavior, there is no way 652 to read a line completely without interpretation or modification 653 unless you mess with $IFS (e.g., setting it to the empty string). 654 If you disagree, change the occurrences of `#if 0' to `#if 1' below. */ 655 if (list == 0) 656 { 657#if 0 658 orig_input_string = input_string; 659 for (t = input_string; ifs_chars && *ifs_chars && spctabnl(*t) && isifs(*t); t++) 660 ; 661 input_string = t; 662 input_string = strip_trailing_ifs_whitespace (input_string, ifs_chars, saw_escape); 663#endif 664 665 if (saw_escape) 666 { 667 t = dequote_string (input_string); 668 var = bind_variable ("REPLY", t, 0); 669 free (t); 670 } 671 else 672 var = bind_variable ("REPLY", input_string, 0); 673 VUNSETATTR (var, att_invisible); 674 675 free (input_string); 676 return (retval); 677 } 678 679 /* This code implements the Posix.2 spec for splitting the words 680 read and assigning them to variables. */ 681 orig_input_string = input_string; 682 683 /* Remove IFS white space at the beginning of the input string. If 684 $IFS is null, no field splitting is performed. */ 685 for (t = input_string; ifs_chars && *ifs_chars && spctabnl(*t) && isifs(*t); t++) 686 ; 687 input_string = t; 688 for (; list->next; list = list->next) 689 { 690 varname = list->word->word; 691#if defined (ARRAY_VARS) 692 if (legal_identifier (varname) == 0 && valid_array_reference (varname) == 0) 693#else 694 if (legal_identifier (varname) == 0) 695#endif 696 { 697 sh_invalidid (varname); 698 xfree (orig_input_string); 699 return (EXECUTION_FAILURE); 700 } 701 702 /* If there are more variables than words read from the input, 703 the remaining variables are set to the empty string. */ 704 if (*input_string) 705 { 706 /* This call updates INPUT_STRING. */ 707 t = get_word_from_string (&input_string, ifs_chars, &e); 708 if (t) 709 *e = '\0'; 710 /* Don't bother to remove the CTLESC unless we added one 711 somewhere while reading the string. */ 712 if (t && saw_escape) 713 { 714 t1 = dequote_string (t); 715 var = bind_read_variable (varname, t1); 716 xfree (t1); 717 } 718 else 719 var = bind_read_variable (varname, t); 720 } 721 else 722 { 723 t = (char *)0; 724 var = bind_read_variable (varname, ""); 725 } 726 727 FREE (t); 728 if (var == 0) 729 { 730 xfree (orig_input_string); 731 return (EXECUTION_FAILURE); 732 } 733 734 stupidly_hack_special_variables (varname); 735 VUNSETATTR (var, att_invisible); 736 } 737 738 /* Now assign the rest of the line to the last variable argument. */ 739#if defined (ARRAY_VARS) 740 if (legal_identifier (list->word->word) == 0 && valid_array_reference (list->word->word) == 0) 741#else 742 if (legal_identifier (list->word->word) == 0) 743#endif 744 { 745 sh_invalidid (list->word->word); 746 xfree (orig_input_string); 747 return (EXECUTION_FAILURE); 748 } 749 750#if 0 751 /* This has to be done this way rather than using string_list 752 and list_string because Posix.2 says that the last variable gets the 753 remaining words and their intervening separators. */ 754 input_string = strip_trailing_ifs_whitespace (input_string, ifs_chars, saw_escape); 755#else 756 /* Check whether or not the number of fields is exactly the same as the 757 number of variables. */ 758 tofree = NULL; 759 if (*input_string) 760 { 761 t1 = input_string; 762 t = get_word_from_string (&input_string, ifs_chars, &e); 763 if (*input_string == 0) 764 tofree = input_string = t; 765 else 766 { 767 input_string = strip_trailing_ifs_whitespace (t1, ifs_chars, saw_escape); 768 tofree = t; 769 } 770 } 771#endif 772 773 if (saw_escape) 774 { 775 t = dequote_string (input_string); 776 var = bind_read_variable (list->word->word, t); 777 xfree (t); 778 } 779 else 780 var = bind_read_variable (list->word->word, input_string); 781 stupidly_hack_special_variables (list->word->word); 782 FREE (tofree); 783 784 if (var) 785 VUNSETATTR (var, att_invisible); 786 xfree (orig_input_string); 787 788 return (retval); 789} 790 791static SHELL_VAR * 792bind_read_variable (name, value) 793 char *name, *value; 794{ 795#if defined (ARRAY_VARS) 796 if (valid_array_reference (name) == 0) 797 return (bind_variable (name, value, 0)); 798 else 799 return (assign_array_element (name, value, 0)); 800#else /* !ARRAY_VARS */ 801 return bind_variable (name, value, 0); 802#endif /* !ARRAY_VARS */ 803} 804 805#if defined (HANDLE_MULTIBYTE) 806static int 807read_mbchar (fd, string, ind, ch, unbuffered) 808 int fd; 809 char *string; 810 int ind, ch, unbuffered; 811{ 812 char mbchar[MB_LEN_MAX + 1]; 813 int i, n, r; 814 char c; 815 size_t ret; 816 mbstate_t ps, ps_back; 817 wchar_t wc; 818 819 memset (&ps, '\0', sizeof (mbstate_t)); 820 memset (&ps_back, '\0', sizeof (mbstate_t)); 821 822 mbchar[0] = ch; 823 i = 1; 824 for (n = 0; n <= MB_LEN_MAX; n++) 825 { 826 ps_back = ps; 827 ret = mbrtowc (&wc, mbchar, i, &ps); 828 if (ret == (size_t)-2) 829 { 830 ps = ps_back; 831 if (unbuffered) 832 r = zread (fd, &c, 1); 833 else 834 r = zreadc (fd, &c); 835 if (r < 0) 836 goto mbchar_return; 837 mbchar[i++] = c; 838 continue; 839 } 840 else if (ret == (size_t)-1 || ret == (size_t)0 || ret > (size_t)0) 841 break; 842 } 843 844mbchar_return: 845 if (i > 1) /* read a multibyte char */ 846 /* mbchar[0] is already string[ind-1] */ 847 for (r = 1; r < i; r++) 848 string[ind+r-1] = mbchar[r]; 849 return i - 1; 850} 851#endif 852 853 854static void 855ttyrestore (ttp) 856 struct ttsave *ttp; 857{ 858 ttsetattr (ttp->fd, ttp->attrs); 859} 860 861#if defined (READLINE) 862static rl_completion_func_t *old_attempted_completion_function = 0; 863static rl_hook_func_t *old_startup_hook; 864static char *deftext; 865 866static void 867reset_attempted_completion_function (cp) 868 char *cp; 869{ 870 if (rl_attempted_completion_function == 0 && old_attempted_completion_function) 871 rl_attempted_completion_function = old_attempted_completion_function; 872} 873 874static int 875set_itext () 876{ 877 int r1, r2; 878 879 r1 = r2 = 0; 880 if (old_startup_hook) 881 r1 = (*old_startup_hook) (); 882 if (deftext) 883 { 884 r2 = rl_insert_text (deftext); 885 deftext = (char *)NULL; 886 rl_startup_hook = old_startup_hook; 887 old_startup_hook = (rl_hook_func_t *)NULL; 888 } 889 return (r1 || r2); 890} 891 892static char * 893edit_line (p, itext) 894 char *p; 895 char *itext; 896{ 897 char *ret; 898 int len; 899 900 if (bash_readline_initialized == 0) 901 initialize_readline (); 902 903 old_attempted_completion_function = rl_attempted_completion_function; 904 rl_attempted_completion_function = (rl_completion_func_t *)NULL; 905 if (itext) 906 { 907 old_startup_hook = rl_startup_hook; 908 rl_startup_hook = set_itext; 909 deftext = itext; 910 } 911 ret = readline (p); 912 rl_attempted_completion_function = old_attempted_completion_function; 913 old_attempted_completion_function = (rl_completion_func_t *)NULL; 914 915 if (ret == 0) 916 return ret; 917 len = strlen (ret); 918 ret = (char *)xrealloc (ret, len + 2); 919 ret[len++] = delim; 920 ret[len] = '\0'; 921 return ret; 922} 923 924static int old_delim_ctype; 925static rl_command_func_t *old_delim_func; 926static int old_newline_ctype; 927static rl_command_func_t *old_newline_func; 928 929static unsigned char delim_char; 930 931static void 932set_eol_delim (c) 933 int c; 934{ 935 Keymap cmap; 936 937 if (bash_readline_initialized == 0) 938 initialize_readline (); 939 cmap = rl_get_keymap (); 940 941 /* Change newline to self-insert */ 942 old_newline_ctype = cmap[RETURN].type; 943 old_newline_func = cmap[RETURN].function; 944 cmap[RETURN].type = ISFUNC; 945 cmap[RETURN].function = rl_insert; 946 947 /* Bind the delimiter character to accept-line. */ 948 old_delim_ctype = cmap[c].type; 949 old_delim_func = cmap[c].function; 950 cmap[c].type = ISFUNC; 951 cmap[c].function = rl_newline; 952 953 delim_char = c; 954} 955 956static void 957reset_eol_delim (cp) 958 char *cp; 959{ 960 Keymap cmap; 961 962 cmap = rl_get_keymap (); 963 964 cmap[RETURN].type = old_newline_ctype; 965 cmap[RETURN].function = old_newline_func; 966 967 cmap[delim_char].type = old_delim_ctype; 968 cmap[delim_char].function = old_delim_func; 969} 970#endif 971