]> git.ipfire.org Git - thirdparty/bash.git/blob - builtins/read.def
Imported from ../bash-4.0.tar.gz.
[thirdparty/bash.git] / builtins / read.def
1 This file is read.def, from which is created read.c.
2 It implements the builtin "read" in Bash.
3
4 Copyright (C) 1987-2009 Free Software Foundation, Inc.
5
6 This file is part of GNU Bash, the Bourne Again SHell.
7
8 Bash is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
12
13 Bash is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along 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 ...]
26 Read a line from the standard input and split it into fields.
27
28 Reads a single line from the standard input, or from file descriptor FD
29 if the -u option is supplied. The line is split into fields as with word
30 splitting, and the first word is assigned to the first NAME, the second
31 word to the second NAME, and so on, with any leftover words assigned to
32 the last NAME. Only the characters found in $IFS are recognized as word
33 delimiters.
34
35 If no NAMEs are supplied, the line read is stored in the REPLY variable.
36
37 Options:
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
58 Exit Status:
59 The return code is zero, unless end-of-file is encountered, read times out,
60 or 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)
102 extern int errno;
103 #endif
104
105 struct ttsave
106 {
107 int fd;
108 TTYSTRUCT *attrs;
109 };
110
111 #if defined (READLINE)
112 static void reset_attempted_completion_function __P((char *));
113 static int set_itext __P((void));
114 static char *edit_line __P((char *, char *));
115 static void set_eol_delim __P((int));
116 static void reset_eol_delim __P((char *));
117 #endif
118 static SHELL_VAR *bind_read_variable __P((char *, char *));
119 #if defined (HANDLE_MULTIBYTE)
120 static int read_mbchar __P((int, char *, int, int, int));
121 #endif
122 static void ttyrestore __P((struct ttsave *));
123
124 static sighandler sigalrm __P((int));
125 static void reset_alarm __P((void));
126
127 static procenv_t alrmbuf;
128 static SigHandler *old_alrm;
129 static unsigned char delim;
130
131 static sighandler
132 sigalrm (s)
133 int s;
134 {
135 longjmp (alrmbuf, 1);
136 }
137
138 static void
139 reset_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. */
151 int
152 read_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 #if 0
373 run_unwind_frame ("read_builtin");
374 return (EXECUTION_FAILURE);
375 #else
376 input_string[i] = '\0'; /* make sure it's terminated */
377 retval = 128+SIGALRM;;
378 goto assign_vars;
379 #endif
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
553 add_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
610 assign_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 input_string = strip_trailing_ifs_whitespace (t1, ifs_chars, saw_escape);
767 }
768 #endif
769
770 if (saw_escape)
771 {
772 t = dequote_string (input_string);
773 var = bind_read_variable (list->word->word, t);
774 xfree (t);
775 }
776 else
777 var = bind_read_variable (list->word->word, input_string);
778 stupidly_hack_special_variables (list->word->word);
779 FREE (tofree);
780
781 if (var)
782 VUNSETATTR (var, att_invisible);
783 xfree (orig_input_string);
784
785 return (retval);
786 }
787
788 static SHELL_VAR *
789 bind_read_variable (name, value)
790 char *name, *value;
791 {
792 #if defined (ARRAY_VARS)
793 if (valid_array_reference (name) == 0)
794 return (bind_variable (name, value, 0));
795 else
796 return (assign_array_element (name, value, 0));
797 #else /* !ARRAY_VARS */
798 return bind_variable (name, value, 0);
799 #endif /* !ARRAY_VARS */
800 }
801
802 #if defined (HANDLE_MULTIBYTE)
803 static int
804 read_mbchar (fd, string, ind, ch, unbuffered)
805 int fd;
806 char *string;
807 int ind, ch, unbuffered;
808 {
809 char mbchar[MB_LEN_MAX + 1];
810 int i, n, r;
811 char c;
812 size_t ret;
813 mbstate_t ps, ps_back;
814 wchar_t wc;
815
816 memset (&ps, '\0', sizeof (mbstate_t));
817 memset (&ps_back, '\0', sizeof (mbstate_t));
818
819 mbchar[0] = ch;
820 i = 1;
821 for (n = 0; n <= MB_LEN_MAX; n++)
822 {
823 ps_back = ps;
824 ret = mbrtowc (&wc, mbchar, i, &ps);
825 if (ret == (size_t)-2)
826 {
827 ps = ps_back;
828 if (unbuffered)
829 r = zread (fd, &c, 1);
830 else
831 r = zreadc (fd, &c);
832 if (r < 0)
833 goto mbchar_return;
834 mbchar[i++] = c;
835 continue;
836 }
837 else if (ret == (size_t)-1 || ret == (size_t)0 || ret > (size_t)0)
838 break;
839 }
840
841 mbchar_return:
842 if (i > 1) /* read a multibyte char */
843 /* mbchar[0] is already string[ind-1] */
844 for (r = 1; r < i; r++)
845 string[ind+r-1] = mbchar[r];
846 return i - 1;
847 }
848 #endif
849
850
851 static void
852 ttyrestore (ttp)
853 struct ttsave *ttp;
854 {
855 ttsetattr (ttp->fd, ttp->attrs);
856 }
857
858 #if defined (READLINE)
859 static rl_completion_func_t *old_attempted_completion_function = 0;
860 static rl_hook_func_t *old_startup_hook;
861 static char *deftext;
862
863 static void
864 reset_attempted_completion_function (cp)
865 char *cp;
866 {
867 if (rl_attempted_completion_function == 0 && old_attempted_completion_function)
868 rl_attempted_completion_function = old_attempted_completion_function;
869 }
870
871 static int
872 set_itext ()
873 {
874 int r1, r2;
875
876 r1 = r2 = 0;
877 if (old_startup_hook)
878 r1 = (*old_startup_hook) ();
879 if (deftext)
880 {
881 r2 = rl_insert_text (deftext);
882 deftext = (char *)NULL;
883 rl_startup_hook = old_startup_hook;
884 old_startup_hook = (rl_hook_func_t *)NULL;
885 }
886 return (r1 || r2);
887 }
888
889 static char *
890 edit_line (p, itext)
891 char *p;
892 char *itext;
893 {
894 char *ret;
895 int len;
896
897 if (bash_readline_initialized == 0)
898 initialize_readline ();
899
900 old_attempted_completion_function = rl_attempted_completion_function;
901 rl_attempted_completion_function = (rl_completion_func_t *)NULL;
902 if (itext)
903 {
904 old_startup_hook = rl_startup_hook;
905 rl_startup_hook = set_itext;
906 deftext = itext;
907 }
908 ret = readline (p);
909 rl_attempted_completion_function = old_attempted_completion_function;
910 old_attempted_completion_function = (rl_completion_func_t *)NULL;
911
912 if (ret == 0)
913 return ret;
914 len = strlen (ret);
915 ret = (char *)xrealloc (ret, len + 2);
916 ret[len++] = delim;
917 ret[len] = '\0';
918 return ret;
919 }
920
921 static int old_delim_ctype;
922 static rl_command_func_t *old_delim_func;
923 static int old_newline_ctype;
924 static rl_command_func_t *old_newline_func;
925
926 static unsigned char delim_char;
927
928 static void
929 set_eol_delim (c)
930 int c;
931 {
932 Keymap cmap;
933
934 if (bash_readline_initialized == 0)
935 initialize_readline ();
936 cmap = rl_get_keymap ();
937
938 /* Change newline to self-insert */
939 old_newline_ctype = cmap[RETURN].type;
940 old_newline_func = cmap[RETURN].function;
941 cmap[RETURN].type = ISFUNC;
942 cmap[RETURN].function = rl_insert;
943
944 /* Bind the delimiter character to accept-line. */
945 old_delim_ctype = cmap[c].type;
946 old_delim_func = cmap[c].function;
947 cmap[c].type = ISFUNC;
948 cmap[c].function = rl_newline;
949
950 delim_char = c;
951 }
952
953 static void
954 reset_eol_delim (cp)
955 char *cp;
956 {
957 Keymap cmap;
958
959 cmap = rl_get_keymap ();
960
961 cmap[RETURN].type = old_newline_ctype;
962 cmap[RETURN].function = old_newline_func;
963
964 cmap[delim_char].type = old_delim_ctype;
965 cmap[delim_char].function = old_delim_func;
966 }
967 #endif