]> git.ipfire.org Git - thirdparty/bash.git/blob - builtins/read.def
Imported from ../bash-2.04.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, 1989, 1991 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 it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 2, or (at your option) any later
11 version.
12
13 Bash is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 for more details.
17
18 You should have received a copy of the GNU General Public License along
19 with Bash; see the file COPYING. If not, write to the Free Software
20 Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA.
21
22 $PRODUCES read.c
23
24 $BUILTIN read
25 $FUNCTION read_builtin
26 $SHORT_DOC read [-ers] [-t timeout] [-p prompt] [-a array] [-n nchars] [-d delim] [name ...]
27 One line is read from the standard input, and the first word is
28 assigned to the first NAME, the second word to the second NAME, and so
29 on, with leftover words assigned to the last NAME. Only the characters
30 found in $IFS are recognized as word delimiters. If no NAMEs are supplied,
31 the line read is stored in the REPLY variable. If the -r option is given,
32 this signifies `raw' input, and backslash escaping is disabled. The
33 -d option causes read to continue until the first character of DELIM is
34 read, rather than newline. If the `-p' option is supplied, the string
35 PROMPT is output without a trailing newline before attempting to read.
36 If -a is supplied, the words read are assigned to sequential indices of
37 ARRAY, starting at zero. If -e is supplied and the shell is interactive,
38 readline is used to obtain the line. If -n is supplied with a non-zero
39 NCHARS argument, read returns after NCHARS characters have been read.
40 The -s option causes input coming from a terminal to not be echoed.
41
42 The -t option causes read to time out and return failure if a complete line
43 of input is not read within TIMEOUT seconds. The return code is zero,
44 unless end-of-file is encountered or read times out.
45 $END
46
47 #include <config.h>
48
49 #include "bashtypes.h"
50 #include "posixstat.h"
51
52 #include <stdio.h>
53
54 #if defined (HAVE_UNISTD_H)
55 # include <unistd.h>
56 #endif
57
58 #include <signal.h>
59 #include <errno.h>
60
61 #include "../shell.h"
62 #include "common.h"
63 #include "bashgetopt.h"
64
65 #include <shtty.h>
66
67 #if defined (READLINE)
68 #include "../bashline.h"
69 #include <readline/readline.h>
70 #endif
71
72 #if !defined(errno)
73 extern int errno;
74 #endif
75
76 #define issep(c) (strchr (ifs_chars, (c)))
77
78 extern int interrupt_immediately;
79
80 #if defined (READLINE)
81 static char *edit_line ();
82 static void set_eol_delim ();
83 static void reset_eol_delim ();
84 #endif
85 static SHELL_VAR *bind_read_variable ();
86
87 static procenv_t alrmbuf;
88 static SigHandler *old_alrm;
89 static int delim;
90
91 static sighandler
92 sigalrm (s)
93 int s;
94 {
95 longjmp (alrmbuf, 1);
96 }
97
98 static void
99 reset_alarm ()
100 {
101 set_signal_handler (SIGALRM, old_alrm);
102 alarm (0);
103 }
104
105 /* Read the value of the shell variables whose names follow.
106 The reading is done from the current input stream, whatever
107 that may be. Successive words of the input line are assigned
108 to the variables mentioned in LIST. The last variable in LIST
109 gets the remainder of the words on the line. If no variables
110 are mentioned in LIST, then the default variable is $REPLY. */
111 int
112 read_builtin (list)
113 WORD_LIST *list;
114 {
115 register char *varname;
116 int size, i, pass_next, saw_escape, eof, opt, retval, code;
117 int input_is_tty, input_is_pipe, unbuffered_read;
118 int raw, edit, tmout, nchars, silent;
119 long timeoutval, ncharsval;
120 char c;
121 char *input_string, *orig_input_string, *ifs_chars, *prompt, *arrayname;
122 char *e, *t, *t1;
123 struct stat tsb;
124 SHELL_VAR *var;
125 #if defined (ARRAY_VARS)
126 WORD_LIST *alist;
127 #endif
128 #if defined (READLINE)
129 char *rlbuf;
130 int rlind;
131 #endif
132
133 i = 0; /* Index into the string that we are reading. */
134 raw = edit = 0; /* Not reading raw input by default. */
135 silent = 0;
136 arrayname = prompt = (char *)NULL;
137
138 #if defined (READLINE)
139 rlbuf = (char *)0;
140 rlind = 0;
141 #endif
142
143 tmout = -1; /* no timeout */
144 nchars = input_is_tty = input_is_pipe = unbuffered_read = 0;
145 delim = '\n'; /* read until newline */
146
147 reset_internal_getopt ();
148 while ((opt = internal_getopt (list, "erp:a:d:t:n:s")) != -1)
149 {
150 switch (opt)
151 {
152 case 'r':
153 raw = 1;
154 break;
155 case 'p':
156 prompt = list_optarg;
157 break;
158 case 's':
159 silent = 1;
160 break;
161 case 'e':
162 #if defined (READLINE)
163 edit = 1;
164 #endif
165 break;
166 #if defined (ARRAY_VARS)
167 case 'a':
168 arrayname = list_optarg;
169 break;
170 #endif
171 case 't':
172 code = legal_number (list_optarg, &timeoutval);
173 if (code == 0 || timeoutval < 0)
174 {
175 builtin_error ("%s: invalid timeout specification", list_optarg);
176 return (EXECUTION_FAILURE);
177 }
178 else
179 tmout = timeoutval;
180 break;
181 case 'n':
182 code = legal_number (list_optarg, &ncharsval);
183 if (code == 0 || ncharsval < 0)
184 {
185 builtin_error ("%s: invalid number specification", list_optarg);
186 return (EXECUTION_FAILURE);
187 }
188 else
189 nchars = ncharsval;
190 break;
191 case 'd':
192 delim = *list_optarg;
193 break;
194 default:
195 builtin_usage ();
196 return (EX_USAGE);
197 }
198 }
199 list = loptend;
200
201 /* `read -t 0 var' returns failure immediately. */
202 if (tmout == 0)
203 return (EXECUTION_FAILURE);
204
205 /* IF IFS is unset, we use the default of " \t\n". */
206 var = find_variable ("IFS");
207 ifs_chars = var ? value_cell (var) : " \t\n";
208 if (ifs_chars == 0) /* XXX */
209 ifs_chars = ""; /* XXX */
210
211 input_string = xmalloc (size = 128);
212
213 begin_unwind_frame ("read_builtin");
214 add_unwind_protect (xfree, input_string);
215 #if defined (READLINE)
216 add_unwind_protect (xfree, rlbuf);
217 #endif
218 interrupt_immediately++;
219
220 input_is_tty = isatty (0);
221 if (input_is_tty == 0)
222 #ifndef __CYGWIN32__
223 input_is_pipe = (lseek (0, 0L, SEEK_CUR) < 0) && (errno == ESPIPE);
224 #else
225 input_is_pipe = 1;
226 #endif
227
228 /* If the -p, -e or -s flags were given, but input is not coming from the
229 terminal, turn them off. */
230 if ((prompt || edit || silent) && input_is_tty == 0)
231 {
232 prompt = (char *)NULL;
233 edit = silent = 0;
234 }
235
236 if (prompt && edit == 0)
237 {
238 fprintf (stderr, "%s", prompt);
239 fflush (stderr);
240 }
241
242 pass_next = 0; /* Non-zero signifies last char was backslash. */
243 saw_escape = 0; /* Non-zero signifies that we saw an escape char */
244
245 if (tmout > 0)
246 {
247 /* Turn off the timeout if stdin is a regular file (e.g. from
248 input redirection). */
249 if ((fstat (0, &tsb) < 0) || S_ISREG (tsb.st_mode))
250 tmout = -1;
251 }
252
253 if (tmout > 0)
254 {
255 code = setjmp (alrmbuf);
256 if (code)
257 {
258 run_unwind_frame ("read_builtin");
259 return (EXECUTION_FAILURE);
260 }
261 old_alrm = set_signal_handler (SIGALRM, sigalrm);
262 add_unwind_protect (reset_alarm, (char *)NULL);
263 alarm (tmout);
264 }
265
266 /* If we've been asked to read only NCHARS chars, or we're using some
267 character other than newline to terminate the line, do the right
268 thing to readline or the tty. */
269 if (nchars > 0 || delim != '\n')
270 {
271 #if defined (READLINE)
272 if (edit)
273 {
274 if (nchars > 0)
275 {
276 unwind_protect_int (rl_num_chars_to_read);
277 rl_num_chars_to_read = nchars;
278 }
279 if (delim != '\n')
280 {
281 set_eol_delim (delim);
282 add_unwind_protect (reset_eol_delim, (char *)NULL);
283 }
284 }
285 else
286 #endif
287 if (input_is_tty)
288 {
289 ttsave ();
290 if (silent)
291 ttcbreak ();
292 else
293 ttonechar ();
294 add_unwind_protect ((Function *)ttrestore, (char *)NULL);
295 }
296 }
297 else if (silent) /* turn off echo but leave term in canonical mode */
298 {
299 ttsave ();
300 ttnoecho ();
301 add_unwind_protect ((Function *)ttrestore, (char *)NULL);
302 }
303
304 unbuffered_read = (nchars > 0) || (delim != '\n') || input_is_pipe;
305
306 for (eof = 0;;)
307 {
308 #if defined (READLINE)
309 if (edit)
310 {
311 if (rlbuf && rlbuf[rlind] == '\0')
312 {
313 xfree (rlbuf);
314 rlbuf = (char *)0;
315 }
316 if (rlbuf == 0)
317 {
318 rlbuf = edit_line (prompt ? prompt : "");
319 rlind = 0;
320 }
321 if (rlbuf == 0)
322 {
323 eof = 1;
324 break;
325 }
326 c = rlbuf[rlind++];
327 }
328 else
329 {
330 #endif
331
332 if (unbuffered_read)
333 retval = zread (0, &c, 1);
334 else
335 retval = zreadc (0, &c);
336
337 if (retval <= 0)
338 {
339 eof = 1;
340 break;
341 }
342
343 #if defined (READLINE)
344 }
345 #endif
346
347 if (i + 2 >= size)
348 input_string = xrealloc (input_string, size += 128);
349
350 /* If the next character is to be accepted verbatim, a backslash
351 newline pair still disappears from the input. */
352 if (pass_next)
353 {
354 if (c == '\n')
355 i--; /* back up over the CTLESC */
356 else
357 input_string[i++] = c;
358 pass_next = 0;
359 continue;
360 }
361
362 if (c == '\\' && raw == 0)
363 {
364 pass_next++;
365 saw_escape++;
366 input_string[i++] = CTLESC;
367 continue;
368 }
369
370 if (c == delim)
371 break;
372
373 if (c == CTLESC || c == CTLNUL)
374 {
375 saw_escape++;
376 input_string[i++] = CTLESC;
377 }
378
379 input_string[i++] = c;
380
381 if (nchars > 0 && i >= nchars)
382 break;
383 }
384 input_string[i] = '\0';
385
386 if (tmout > 0)
387 reset_alarm ();
388
389 if (nchars > 0 || delim != '\n')
390 {
391 #if defined (READLINE)
392 if (edit)
393 {
394 if (nchars > 0)
395 rl_num_chars_to_read = 0;
396 if (delim != '\n')
397 reset_eol_delim ();
398 }
399 else
400 #endif
401 if (input_is_tty)
402 ttrestore ();
403 }
404 else if (silent)
405 ttrestore ();
406
407 if (unbuffered_read == 0)
408 zsyncfd (0);
409
410 interrupt_immediately--;
411 discard_unwind_frame ("read_builtin");
412
413 retval = eof ? EXECUTION_FAILURE : EXECUTION_SUCCESS;
414
415 #if defined (ARRAY_VARS)
416 /* If -a was given, take the string read, break it into a list of words,
417 an assign them to `arrayname' in turn. */
418 if (arrayname)
419 {
420 var = find_variable (arrayname);
421 if (var == 0)
422 var = make_new_array_variable (arrayname);
423 else if (array_p (var) == 0)
424 var = convert_var_to_array (var);
425
426 empty_array (array_cell (var));
427
428 alist = list_string (input_string, ifs_chars, 0);
429 if (alist)
430 {
431 assign_array_var_from_word_list (var, alist);
432 dispose_words (alist);
433 }
434 xfree (input_string);
435 return (retval);
436 }
437 #endif /* ARRAY_VARS */
438
439 /* If there are no variables, save the text of the line read to the
440 variable $REPLY. ksh93 strips leading and trailing IFS whitespace,
441 so that `read x ; echo "$x"' and `read ; echo "$REPLY"' behave the
442 same way, but I believe that the difference in behaviors is useful
443 enough to not do it. Without the bash behavior, there is no way
444 to read a line completely without interpretation or modification.
445 If you disagree, change the occurrences of `#if 0' to `#if 1' below. */
446 if (list == 0)
447 {
448 #if 0
449 orig_input_string = input_string;
450 for (t = input_string; ifs_chars && *ifs_chars && spctabnl(*t) && issep(*t); t++)
451 ;
452 input_string = t;
453 input_string = strip_trailing_ifs_whitespace (input_string, ifs_chars, saw_escape);
454 #endif
455
456 if (saw_escape)
457 {
458 t = dequote_string (input_string);
459 var = bind_variable ("REPLY", t);
460 free (t);
461 }
462 else
463 var = bind_variable ("REPLY", input_string);
464 VUNSETATTR (var, att_invisible);
465 #if 0
466 free (orig_input_string);
467 #else
468 free (input_string);
469 #endif
470 return (retval);
471 }
472
473 /* This code implements the Posix.2 spec for splitting the words
474 read and assigning them to variables. */
475 orig_input_string = input_string;
476
477 /* Remove IFS white space at the beginning of the input string. If
478 $IFS is null, no field splitting is performed. */
479 for (t = input_string; ifs_chars && *ifs_chars && spctabnl(*t) && issep(*t); t++)
480 ;
481 input_string = t;
482
483 for (; list->next; list = list->next)
484 {
485 varname = list->word->word;
486 #if defined (ARRAY_VARS)
487 if (legal_identifier (varname) == 0 && valid_array_reference (varname) == 0)
488 #else
489 if (legal_identifier (varname) == 0)
490 #endif
491 {
492 builtin_error ("`%s': not a valid identifier", varname);
493 free (orig_input_string);
494 return (EXECUTION_FAILURE);
495 }
496
497 /* If there are more variables than words read from the input,
498 the remaining variables are set to the empty string. */
499 if (*input_string)
500 {
501 /* This call updates INPUT_STRING. */
502 t = get_word_from_string (&input_string, ifs_chars, &e);
503 if (t)
504 *e = '\0';
505 /* Don't bother to remove the CTLESC unless we added one
506 somewhere while reading the string. */
507 if (t && saw_escape)
508 {
509 t1 = dequote_string (t);
510 var = bind_read_variable (varname, t1);
511 free (t1);
512 }
513 else
514 var = bind_read_variable (varname, t);
515 }
516 else
517 {
518 t = (char *)0;
519 var = bind_read_variable (varname, "");
520 }
521
522 FREE (t);
523 if (var == 0)
524 {
525 free (orig_input_string);
526 return (EXECUTION_FAILURE);
527 }
528
529 stupidly_hack_special_variables (varname);
530 VUNSETATTR (var, att_invisible);
531 }
532
533 /* Now assign the rest of the line to the last variable argument. */
534 #if defined (ARRAY_VARS)
535 if (legal_identifier (list->word->word) == 0 && valid_array_reference (list->word->word) == 0)
536 #else
537 if (legal_identifier (list->word->word) == 0)
538 #endif
539 {
540 builtin_error ("`%s': not a valid identifier", list->word->word);
541 free (orig_input_string);
542 return (EXECUTION_FAILURE);
543 }
544
545 /* This has to be done this way rather than using string_list
546 and list_string because Posix.2 says that the last variable gets the
547 remaining words and their intervening separators. */
548 input_string = strip_trailing_ifs_whitespace (input_string, ifs_chars, saw_escape);
549
550 if (saw_escape)
551 {
552 t = dequote_string (input_string);
553 var = bind_read_variable (list->word->word, t);
554 free (t);
555 }
556 else
557 var = bind_read_variable (list->word->word, input_string);
558 stupidly_hack_special_variables (list->word->word);
559 if (var)
560 VUNSETATTR (var, att_invisible);
561 free (orig_input_string);
562
563 return (retval);
564 }
565
566 static SHELL_VAR *
567 bind_read_variable (name, value)
568 char *name, *value;
569 {
570 #if defined (ARRAY_VARS)
571 if (valid_array_reference (name) == 0)
572 {
573 #if 0
574 if (legal_identifier (name) == 0)
575 {
576 builtin_error ("`%s': not a valid identifier", name);
577 return ((SHELL_VAR *)NULL);
578 }
579 #endif
580 return (bind_variable (name, value));
581 }
582 else
583 return (do_array_element_assignment (name, value));
584 #else
585 return bind_variable (name, value);
586 #endif
587 }
588
589 #if defined (READLINE)
590 static char *
591 edit_line (p)
592 char *p;
593 {
594 char *ret;
595 int len;
596
597 if (!bash_readline_initialized)
598 initialize_readline ();
599 ret = readline (p);
600 if (ret == 0)
601 return ret;
602 len = strlen (ret);
603 ret = xrealloc (ret, len + 2);
604 ret[len++] = delim;
605 ret[len] = '\0';
606 return ret;
607 }
608
609 static int old_delim_ctype;
610 static Function *old_delim_func;
611 static int old_newline_ctype;
612 static Function *old_newline_func;
613
614 static int delim_char;
615
616 static void
617 set_eol_delim (c)
618 int c;
619 {
620 Keymap cmap;
621
622 if (bash_readline_initialized == 0)
623 initialize_readline ();
624 cmap = rl_get_keymap ();
625
626 /* Change newline to self-insert */
627 old_newline_ctype = cmap[RETURN].type;
628 old_newline_func = cmap[RETURN].function;
629 cmap[RETURN].type = ISFUNC;
630 cmap[RETURN].function = rl_insert;
631
632 /* Bind the delimiter character to accept-line. */
633 old_delim_ctype = cmap[c].type;
634 old_delim_func = cmap[c].function;
635 cmap[c].type = ISFUNC;
636 cmap[c].function = rl_newline;
637
638 delim_char = c;
639 }
640
641 static void
642 reset_eol_delim (c)
643 int c;
644 {
645 Keymap cmap;
646
647 cmap = rl_get_keymap ();
648
649 cmap[RETURN].type = old_newline_ctype;
650 cmap[RETURN].function = old_newline_func;
651
652 cmap[delim_char].type = old_delim_ctype;
653 cmap[delim_char].function = old_delim_func;
654 }
655 #endif