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