8fc5647638a4536f3da36253c2d32fd67f98c708
[platform/upstream/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           /* 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
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   discard_unwind_frame ("read_builtin");
605
606   retval = eof ? EXECUTION_FAILURE : EXECUTION_SUCCESS;
607
608 assign_vars:
609
610   interrupt_immediately--;
611   terminate_immediately--;
612
613 #if defined (ARRAY_VARS)
614   /* If -a was given, take the string read, break it into a list of words,
615      an assign them to `arrayname' in turn. */
616   if (arrayname)
617     {
618       if (legal_identifier (arrayname) == 0)
619         {
620           sh_invalidid (arrayname);
621           xfree (input_string);
622           return (EXECUTION_FAILURE);
623         }
624
625       var = find_or_make_array_variable (arrayname, 1);
626       if (var == 0)
627         {
628           xfree (input_string);
629           return EXECUTION_FAILURE;     /* readonly or noassign */
630         }
631       array_flush (array_cell (var));
632
633       alist = list_string (input_string, ifs_chars, 0);
634       if (alist)
635         {
636           if (saw_escape)
637             dequote_list (alist);
638           else
639             word_list_remove_quoted_nulls (alist);
640           assign_array_var_from_word_list (var, alist, 0);
641           dispose_words (alist);
642         }
643       xfree (input_string);
644       return (retval);
645     }
646 #endif /* ARRAY_VARS */ 
647
648   /* If there are no variables, save the text of the line read to the
649      variable $REPLY.  ksh93 strips leading and trailing IFS whitespace,
650      so that `read x ; echo "$x"' and `read ; echo "$REPLY"' behave the
651      same way, but I believe that the difference in behaviors is useful
652      enough to not do it.  Without the bash behavior, there is no way
653      to read a line completely without interpretation or modification
654      unless you mess with $IFS (e.g., setting it to the empty string).
655      If you disagree, change the occurrences of `#if 0' to `#if 1' below. */
656   if (list == 0)
657     {
658 #if 0
659       orig_input_string = input_string;
660       for (t = input_string; ifs_chars && *ifs_chars && spctabnl(*t) && isifs(*t); t++)
661         ;
662       input_string = t;
663       input_string = strip_trailing_ifs_whitespace (input_string, ifs_chars, saw_escape);
664 #endif
665
666       if (saw_escape)
667         {
668           t = dequote_string (input_string);
669           var = bind_variable ("REPLY", t, 0);
670           free (t);
671         }
672       else
673         var = bind_variable ("REPLY", input_string, 0);
674       VUNSETATTR (var, att_invisible);
675
676       free (input_string);
677       return (retval);
678     }
679
680   /* This code implements the Posix.2 spec for splitting the words
681      read and assigning them to variables. */
682   orig_input_string = input_string;
683
684   /* Remove IFS white space at the beginning of the input string.  If
685      $IFS is null, no field splitting is performed. */
686   for (t = input_string; ifs_chars && *ifs_chars && spctabnl(*t) && isifs(*t); t++)
687     ;
688   input_string = t;
689   for (; list->next; list = list->next)
690     {
691       varname = list->word->word;
692 #if defined (ARRAY_VARS)
693       if (legal_identifier (varname) == 0 && valid_array_reference (varname) == 0)
694 #else
695       if (legal_identifier (varname) == 0)
696 #endif
697         {
698           sh_invalidid (varname);
699           xfree (orig_input_string);
700           return (EXECUTION_FAILURE);
701         }
702
703       /* If there are more variables than words read from the input,
704          the remaining variables are set to the empty string. */
705       if (*input_string)
706         {
707           /* This call updates INPUT_STRING. */
708           t = get_word_from_string (&input_string, ifs_chars, &e);
709           if (t)
710             *e = '\0';
711           /* Don't bother to remove the CTLESC unless we added one
712              somewhere while reading the string. */
713           if (t && saw_escape)
714             {
715               t1 = dequote_string (t);
716               var = bind_read_variable (varname, t1);
717               xfree (t1);
718             }
719           else
720             var = bind_read_variable (varname, t);
721         }
722       else
723         {
724           t = (char *)0;
725           var = bind_read_variable (varname, "");
726         }
727
728       FREE (t);
729       if (var == 0)
730         {
731           xfree (orig_input_string);
732           return (EXECUTION_FAILURE);
733         }
734
735       stupidly_hack_special_variables (varname);
736       VUNSETATTR (var, att_invisible);
737     }
738
739   /* Now assign the rest of the line to the last variable argument. */
740 #if defined (ARRAY_VARS)
741   if (legal_identifier (list->word->word) == 0 && valid_array_reference (list->word->word) == 0)
742 #else
743   if (legal_identifier (list->word->word) == 0)
744 #endif
745     {
746       sh_invalidid (list->word->word);
747       xfree (orig_input_string);
748       return (EXECUTION_FAILURE);
749     }
750
751 #if 0
752   /* This has to be done this way rather than using string_list
753      and list_string because Posix.2 says that the last variable gets the
754      remaining words and their intervening separators. */
755   input_string = strip_trailing_ifs_whitespace (input_string, ifs_chars, saw_escape);
756 #else
757   /* Check whether or not the number of fields is exactly the same as the
758      number of variables. */
759   tofree = NULL;
760   if (*input_string)
761     {
762       t1 = input_string;
763       t = get_word_from_string (&input_string, ifs_chars, &e);
764       if (*input_string == 0)
765         tofree = input_string = t;
766       else
767         {
768           input_string = strip_trailing_ifs_whitespace (t1, ifs_chars, saw_escape);
769           tofree = t;
770         }
771     }
772 #endif
773
774   if (saw_escape)
775     {
776       t = dequote_string (input_string);
777       var = bind_read_variable (list->word->word, t);
778       xfree (t);
779     }
780   else
781     var = bind_read_variable (list->word->word, input_string);
782   stupidly_hack_special_variables (list->word->word);
783   FREE (tofree);
784
785   if (var)
786     VUNSETATTR (var, att_invisible);
787   xfree (orig_input_string);
788
789   return (retval);
790 }
791
792 static SHELL_VAR *
793 bind_read_variable (name, value)
794      char *name, *value;
795 {
796 #if defined (ARRAY_VARS)
797   if (valid_array_reference (name) == 0)
798     return (bind_variable (name, value, 0));
799   else
800     return (assign_array_element (name, value, 0));
801 #else /* !ARRAY_VARS */
802   return bind_variable (name, value, 0);
803 #endif /* !ARRAY_VARS */
804 }
805
806 #if defined (HANDLE_MULTIBYTE)
807 static int
808 read_mbchar (fd, string, ind, ch, unbuffered)
809      int fd;
810      char *string;
811      int ind, ch, unbuffered;
812 {
813   char mbchar[MB_LEN_MAX + 1];
814   int i, n, r;
815   char c;
816   size_t ret;
817   mbstate_t ps, ps_back;
818   wchar_t wc;
819
820   memset (&ps, '\0', sizeof (mbstate_t));
821   memset (&ps_back, '\0', sizeof (mbstate_t));
822   
823   mbchar[0] = ch;
824   i = 1;
825   for (n = 0; n <= MB_LEN_MAX; n++)
826     {
827       ps_back = ps;
828       ret = mbrtowc (&wc, mbchar, i, &ps);
829       if (ret == (size_t)-2)
830         {
831           ps = ps_back;
832           if (unbuffered)
833             r = zread (fd, &c, 1);
834           else
835             r = zreadc (fd, &c);
836           if (r < 0)
837             goto mbchar_return;
838           mbchar[i++] = c;      
839           continue;
840         }
841       else if (ret == (size_t)-1 || ret == (size_t)0 || ret > (size_t)0)
842         break;
843     }
844
845 mbchar_return:
846   if (i > 1)    /* read a multibyte char */
847     /* mbchar[0] is already string[ind-1] */
848     for (r = 1; r < i; r++)
849       string[ind+r-1] = mbchar[r];
850   return i - 1;
851 }
852 #endif
853
854
855 static void
856 ttyrestore (ttp)
857      struct ttsave *ttp;
858 {
859   ttsetattr (ttp->fd, ttp->attrs);
860 }
861
862 #if defined (READLINE)
863 static rl_completion_func_t *old_attempted_completion_function = 0;
864 static rl_hook_func_t *old_startup_hook;
865 static char *deftext;
866
867 static void
868 reset_attempted_completion_function (cp)
869      char *cp;
870 {
871   if (rl_attempted_completion_function == 0 && old_attempted_completion_function)
872     rl_attempted_completion_function = old_attempted_completion_function;
873 }
874
875 static int
876 set_itext ()
877 {
878   int r1, r2;
879
880   r1 = r2 = 0;
881   if (old_startup_hook)
882     r1 = (*old_startup_hook) ();
883   if (deftext)
884     {
885       r2 = rl_insert_text (deftext);
886       deftext = (char *)NULL;
887       rl_startup_hook = old_startup_hook;
888       old_startup_hook = (rl_hook_func_t *)NULL;
889     }
890   return (r1 || r2);
891 }
892
893 static char *
894 edit_line (p, itext)
895      char *p;
896      char *itext;
897 {
898   char *ret;
899   int len;
900
901   if (bash_readline_initialized == 0)
902     initialize_readline ();
903
904   old_attempted_completion_function = rl_attempted_completion_function;
905   rl_attempted_completion_function = (rl_completion_func_t *)NULL;
906   if (itext)
907     {
908       old_startup_hook = rl_startup_hook;
909       rl_startup_hook = set_itext;
910       deftext = itext;
911     }
912   ret = readline (p);
913   rl_attempted_completion_function = old_attempted_completion_function;
914   old_attempted_completion_function = (rl_completion_func_t *)NULL;
915
916   if (ret == 0)
917     return ret;
918   len = strlen (ret);
919   ret = (char *)xrealloc (ret, len + 2);
920   ret[len++] = delim;
921   ret[len] = '\0';
922   return ret;
923 }
924
925 static int old_delim_ctype;
926 static rl_command_func_t *old_delim_func;
927 static int old_newline_ctype;
928 static rl_command_func_t *old_newline_func;
929
930 static unsigned char delim_char;
931
932 static void
933 set_eol_delim (c)
934      int c;
935 {
936   Keymap cmap;
937
938   if (bash_readline_initialized == 0)
939     initialize_readline ();
940   cmap = rl_get_keymap ();
941
942   /* Change newline to self-insert */
943   old_newline_ctype = cmap[RETURN].type;
944   old_newline_func =  cmap[RETURN].function;
945   cmap[RETURN].type = ISFUNC;
946   cmap[RETURN].function = rl_insert;
947
948   /* Bind the delimiter character to accept-line. */
949   old_delim_ctype = cmap[c].type;
950   old_delim_func = cmap[c].function;
951   cmap[c].type = ISFUNC;
952   cmap[c].function = rl_newline;
953
954   delim_char = c;
955 }
956
957 static void
958 reset_eol_delim (cp)
959      char *cp;
960 {
961   Keymap cmap;
962
963   cmap = rl_get_keymap ();
964
965   cmap[RETURN].type = old_newline_ctype;
966   cmap[RETURN].function = old_newline_func;
967
968   cmap[delim_char].type = old_delim_ctype;
969   cmap[delim_char].function = old_delim_func;
970 }
971 #endif