]> git.ipfire.org Git - thirdparty/bash.git/blame - builtins/read.def
Imported from ../bash-2.05.tar.gz.
[thirdparty/bash.git] / builtins / read.def
CommitLineData
726f6388
JA
1This file is read.def, from which is created read.c.
2It implements the builtin "read" in Bash.
3
4Copyright (C) 1987, 1989, 1991 Free Software Foundation, Inc.
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
bb70624e 10Software Foundation; either version 2, or (at your option) any later
726f6388
JA
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
bb70624e 20Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA.
726f6388
JA
21
22$PRODUCES read.c
23
24$BUILTIN read
25$FUNCTION read_builtin
bb70624e 26$SHORT_DOC read [-ers] [-t timeout] [-p prompt] [-a array] [-n nchars] [-d delim] [name ...]
726f6388 27One line is read from the standard input, and the first word is
ccc6cda3
JA
28assigned to the first NAME, the second word to the second NAME, and so
29on, with leftover words assigned to the last NAME. Only the characters
bb70624e
JA
30found in $IFS are recognized as word delimiters. If no NAMEs are supplied,
31the line read is stored in the REPLY variable. If the -r option is given,
32this signifies `raw' input, and backslash escaping is disabled. The
33-d option causes read to continue until the first character of DELIM is
34read, rather than newline. If the `-p' option is supplied, the string
35PROMPT is output without a trailing newline before attempting to read.
36If -a is supplied, the words read are assigned to sequential indices of
37ARRAY, starting at zero. If -e is supplied and the shell is interactive,
38readline is used to obtain the line. If -n is supplied with a non-zero
39NCHARS argument, read returns after NCHARS characters have been read.
40The -s option causes input coming from a terminal to not be echoed.
41
42The -t option causes read to time out and return failure if a complete line
43of input is not read within TIMEOUT seconds. The return code is zero,
44unless end-of-file is encountered or read times out.
726f6388
JA
45$END
46
ccc6cda3
JA
47#include <config.h>
48
bb70624e
JA
49#include "bashtypes.h"
50#include "posixstat.h"
51
726f6388 52#include <stdio.h>
ccc6cda3
JA
53
54#if defined (HAVE_UNISTD_H)
55# include <unistd.h>
56#endif
57
bb70624e 58#include <signal.h>
e8ce775d
JA
59#include <errno.h>
60
28ef6c31
JA
61#ifdef __CYGWIN__
62# include <fcntl.h>
63# include <io.h>
64#endif
65
726f6388
JA
66#include "../shell.h"
67#include "common.h"
ccc6cda3 68#include "bashgetopt.h"
726f6388 69
bb70624e
JA
70#include <shtty.h>
71
ccc6cda3
JA
72#if defined (READLINE)
73#include "../bashline.h"
74#include <readline/readline.h>
75#endif
726f6388 76
e8ce775d
JA
77#if !defined(errno)
78extern int errno;
79#endif
80
ccc6cda3 81#define issep(c) (strchr (ifs_chars, (c)))
726f6388
JA
82
83extern int interrupt_immediately;
84
ccc6cda3
JA
85#if defined (READLINE)
86static char *edit_line ();
bb70624e
JA
87static void set_eol_delim ();
88static void reset_eol_delim ();
ccc6cda3
JA
89#endif
90static SHELL_VAR *bind_read_variable ();
91
bb70624e
JA
92static procenv_t alrmbuf;
93static SigHandler *old_alrm;
94static int delim;
95
96static sighandler
97sigalrm (s)
98 int s;
99{
100 longjmp (alrmbuf, 1);
101}
102
103static void
104reset_alarm ()
105{
106 set_signal_handler (SIGALRM, old_alrm);
107 alarm (0);
108}
109
726f6388
JA
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
ccc6cda3
JA
115 are mentioned in LIST, then the default variable is $REPLY. */
116int
726f6388
JA
117read_builtin (list)
118 WORD_LIST *list;
119{
120 register char *varname;
bb70624e
JA
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;
ccc6cda3
JA
125 char c;
126 char *input_string, *orig_input_string, *ifs_chars, *prompt, *arrayname;
127 char *e, *t, *t1;
bb70624e 128 struct stat tsb;
726f6388 129 SHELL_VAR *var;
ccc6cda3
JA
130#if defined (ARRAY_VARS)
131 WORD_LIST *alist;
132#endif
133#if defined (READLINE)
134 char *rlbuf;
135 int rlind;
136#endif
726f6388
JA
137
138 i = 0; /* Index into the string that we are reading. */
ccc6cda3 139 raw = edit = 0; /* Not reading raw input by default. */
bb70624e 140 silent = 0;
ccc6cda3
JA
141 arrayname = prompt = (char *)NULL;
142
143#if defined (READLINE)
144 rlbuf = (char *)0;
145 rlind = 0;
146#endif
726f6388 147
bb70624e
JA
148 tmout = -1; /* no timeout */
149 nchars = input_is_tty = input_is_pipe = unbuffered_read = 0;
150 delim = '\n'; /* read until newline */
151
ccc6cda3 152 reset_internal_getopt ();
bb70624e 153 while ((opt = internal_getopt (list, "erp:a:d:t:n:s")) != -1)
726f6388 154 {
ccc6cda3 155 switch (opt)
28ef6c31
JA
156 {
157 case 'r':
ccc6cda3 158 raw = 1;
726f6388 159 break;
ccc6cda3
JA
160 case 'p':
161 prompt = list_optarg;
162 break;
bb70624e
JA
163 case 's':
164 silent = 1;
165 break;
ccc6cda3
JA
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
bb70624e
JA
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;
ccc6cda3
JA
199 default:
200 builtin_usage ();
726f6388
JA
201 return (EX_USAGE);
202 }
726f6388 203 }
ccc6cda3 204 list = loptend;
726f6388 205
bb70624e
JA
206 /* `read -t 0 var' returns failure immediately. */
207 if (tmout == 0)
208 return (EXECUTION_FAILURE);
209
ccc6cda3 210 /* IF IFS is unset, we use the default of " \t\n". */
726f6388
JA
211 var = find_variable ("IFS");
212 ifs_chars = var ? value_cell (var) : " \t\n";
ccc6cda3
JA
213 if (ifs_chars == 0) /* XXX */
214 ifs_chars = ""; /* XXX */
726f6388 215
ccc6cda3 216 input_string = xmalloc (size = 128);
726f6388
JA
217
218 begin_unwind_frame ("read_builtin");
ccc6cda3
JA
219#if defined (READLINE)
220 add_unwind_protect (xfree, rlbuf);
221#endif
726f6388 222
bb70624e
JA
223 input_is_tty = isatty (0);
224 if (input_is_tty == 0)
28ef6c31 225#ifndef __CYGWIN__
bb70624e
JA
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
ccc6cda3 232 terminal, turn them off. */
bb70624e 233 if ((prompt || edit || silent) && input_is_tty == 0)
ccc6cda3
JA
234 {
235 prompt = (char *)NULL;
bb70624e 236 edit = silent = 0;
ccc6cda3
JA
237 }
238
239 if (prompt && edit == 0)
240 {
241 fprintf (stderr, "%s", prompt);
242 fflush (stderr);
243 }
244
726f6388
JA
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
bb70624e
JA
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))
28ef6c31 253 tmout = -1;
bb70624e
JA
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)
28ef6c31 291 {
bb70624e
JA
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
28ef6c31
JA
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
bb70624e
JA
312 unbuffered_read = (nchars > 0) || (delim != '\n') || input_is_pipe;
313
28ef6c31
JA
314#if defined (__CYGWIN__) && defined (O_TEXT)
315 setmode (0, O_TEXT);
316#endif
317
ccc6cda3 318 for (eof = 0;;)
726f6388 319 {
ccc6cda3
JA
320#if defined (READLINE)
321 if (edit)
322 {
323 if (rlbuf && rlbuf[rlind] == '\0')
324 {
d166f048 325 xfree (rlbuf);
ccc6cda3
JA
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
b72432fd 341 {
e8ce775d
JA
342#endif
343
bb70624e
JA
344 if (unbuffered_read)
345 retval = zread (0, &c, 1);
346 else
347 retval = zreadc (0, &c);
348
e8ce775d 349 if (retval <= 0)
ccc6cda3
JA
350 {
351 eof = 1;
352 break;
353 }
354
b72432fd
JA
355#if defined (READLINE)
356 }
357#endif
358
726f6388 359 if (i + 2 >= size)
28ef6c31
JA
360 {
361 input_string = xrealloc (input_string, size += 128);
362 remove_unwind_protect ();
363 add_unwind_protect (xfree, input_string);
364 }
726f6388
JA
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
ccc6cda3 378 if (c == '\\' && raw == 0)
726f6388
JA
379 {
380 pass_next++;
381 saw_escape++;
382 input_string[i++] = CTLESC;
383 continue;
384 }
385
bb70624e 386 if (c == delim)
726f6388
JA
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;
bb70624e
JA
396
397 if (nchars > 0 && i >= nchars)
398 break;
726f6388
JA
399 }
400 input_string[i] = '\0';
401
bb70624e
JA
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
726f6388
JA
426 interrupt_immediately--;
427 discard_unwind_frame ("read_builtin");
428
ccc6cda3 429 retval = eof ? EXECUTION_FAILURE : EXECUTION_SUCCESS;
726f6388 430
ccc6cda3
JA
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)
726f6388 435 {
ccc6cda3
JA
436 var = find_variable (arrayname);
437 if (var == 0)
28ef6c31 438 var = make_new_array_variable (arrayname);
ccc6cda3 439 else if (array_p (var) == 0)
28ef6c31 440 var = convert_var_to_array (var);
ccc6cda3
JA
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 }
d166f048 450 xfree (input_string);
ccc6cda3 451 return (retval);
726f6388 452 }
ccc6cda3 453#endif /* ARRAY_VARS */
726f6388 454
d166f048
JA
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
28ef6c31
JA
460 to read a line completely without interpretation or modification
461 unless you mess with $IFS (e.g., setting it to the empty string).
d166f048
JA
462 If you disagree, change the occurrences of `#if 0' to `#if 1' below. */
463 if (list == 0)
726f6388 464 {
d166f048
JA
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
726f6388
JA
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);
bb70624e 481 VUNSETATTR (var, att_invisible);
28ef6c31 482
726f6388 483 free (input_string);
ccc6cda3 484 return (retval);
726f6388 485 }
ccc6cda3
JA
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)
726f6388 498 {
ccc6cda3
JA
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
726f6388 505 {
ccc6cda3
JA
506 builtin_error ("`%s': not a valid identifier", varname);
507 free (orig_input_string);
508 return (EXECUTION_FAILURE);
509 }
726f6388 510
ccc6cda3
JA
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)
726f6388 522 {
ccc6cda3
JA
523 t1 = dequote_string (t);
524 var = bind_read_variable (varname, t1);
525 free (t1);
726f6388
JA
526 }
527 else
ccc6cda3
JA
528 var = bind_read_variable (varname, t);
529 }
530 else
531 {
532 t = (char *)0;
533 var = bind_read_variable (varname, "");
726f6388
JA
534 }
535
ccc6cda3
JA
536 FREE (t);
537 if (var == 0)
726f6388 538 {
726f6388
JA
539 free (orig_input_string);
540 return (EXECUTION_FAILURE);
541 }
542
ccc6cda3 543 stupidly_hack_special_variables (varname);
bb70624e 544 VUNSETATTR (var, att_invisible);
ccc6cda3
JA
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);
726f6388 555 free (orig_input_string);
ccc6cda3 556 return (EXECUTION_FAILURE);
726f6388
JA
557 }
558
ccc6cda3
JA
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)
bb70624e 574 VUNSETATTR (var, att_invisible);
ccc6cda3
JA
575 free (orig_input_string);
576
726f6388
JA
577 return (retval);
578}
579
ccc6cda3
JA
580static SHELL_VAR *
581bind_read_variable (name, value)
582 char *name, *value;
583{
584#if defined (ARRAY_VARS)
585 if (valid_array_reference (name) == 0)
586 {
cce855bc 587#if 0
ccc6cda3 588 if (legal_identifier (name) == 0)
28ef6c31 589 {
ccc6cda3
JA
590 builtin_error ("`%s': not a valid identifier", name);
591 return ((SHELL_VAR *)NULL);
28ef6c31 592 }
cce855bc 593#endif
ccc6cda3
JA
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)
604static char *
605edit_line (p)
606 char *p;
726f6388 607{
ccc6cda3
JA
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);
bb70624e 618 ret[len++] = delim;
ccc6cda3
JA
619 ret[len] = '\0';
620 return ret;
726f6388 621}
bb70624e
JA
622
623static int old_delim_ctype;
624static Function *old_delim_func;
625static int old_newline_ctype;
626static Function *old_newline_func;
627
628static int delim_char;
629
630static void
631set_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
655static void
656reset_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}
ccc6cda3 669#endif