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