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