This file is read.def, from which is created read.c.
It implements the builtin "read" in Bash.
-Copyright (C) 1987-2004 Free Software Foundation, Inc.
+Copyright (C) 1987-2005 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
#include <readline/readline.h>
#endif
+#if defined (BUFFERED_INPUT)
+# include "input.h"
+#endif
+
#if !defined(errno)
extern int errno;
#endif
-extern int interrupt_immediately;
-
#if defined (READLINE)
+static void reset_attempted_completion_function __P((char *));
static char *edit_line __P((char *));
static void set_eol_delim __P((int));
static void reset_eol_delim __P((char *));
WORD_LIST *list;
{
register char *varname;
- int size, i, pass_next, saw_escape, eof, opt, retval, code;
- int input_is_tty, input_is_pipe, unbuffered_read;
+ int size, i, nr, pass_next, saw_escape, eof, opt, retval, code, print_ps2;
+ int input_is_tty, input_is_pipe, unbuffered_read, skip_ctlesc, skip_ctlnul;
int raw, edit, nchars, silent, have_timeout, fd;
unsigned int tmout;
intmax_t intval;
char c;
char *input_string, *orig_input_string, *ifs_chars, *prompt, *arrayname;
- char *e, *t, *t1;
+ char *e, *t, *t1, *ps2, *tofree;
struct stat tsb;
SHELL_VAR *var;
#if defined (ARRAY_VARS)
USE_VAR(size);
USE_VAR(i);
USE_VAR(pass_next);
+ USE_VAR(print_ps2);
USE_VAR(saw_escape);
USE_VAR(input_is_pipe);
/* USE_VAR(raw); */
USE_VAR(rlind);
#endif
USE_VAR(list);
+ USE_VAR(ps2);
i = 0; /* Index into the string that we are reading. */
raw = edit = 0; /* Not reading raw input by default. */
#endif
tmout = 0; /* no timeout */
- nchars = input_is_tty = input_is_pipe = unbuffered_read = have_timeout = 0;
+ nr = nchars = input_is_tty = input_is_pipe = unbuffered_read = have_timeout = 0;
delim = '\n'; /* read until newline */
reset_internal_getopt ();
begin_unwind_frame ("read_builtin");
+#if defined (BUFFERED_INPUT)
+ if (interactive == 0 && default_buffered_input >= 0 && fd_is_bash_input (fd))
+ sync_buffered_stream (default_buffered_input);
+#endif
+
input_is_tty = isatty (fd);
if (input_is_tty == 0)
#ifndef __CYGWIN__
- input_is_pipe = (lseek (0, 0L, SEEK_CUR) < 0) && (errno == ESPIPE);
+ input_is_pipe = (lseek (fd, 0L, SEEK_CUR) < 0) && (errno == ESPIPE);
#else
input_is_pipe = 1;
#endif
}
old_alrm = set_signal_handler (SIGALRM, sigalrm);
add_unwind_protect (reset_alarm, (char *)NULL);
+#if defined (READLINE)
+ if (edit)
+ add_unwind_protect (reset_attempted_completion_function, (char *)NULL);
+#endif
alarm (tmout);
}
of the unwind-protect stack after the realloc() works right. */
add_unwind_protect (xfree, input_string);
interrupt_immediately++;
+ terminate_immediately = 1;
unbuffered_read = (nchars > 0) || (delim != '\n') || input_is_pipe;
setmode (0, O_TEXT);
#endif
- for (eof = retval = 0;;)
+ ps2 = 0;
+ for (print_ps2 = eof = retval = 0;;)
{
#if defined (READLINE)
if (edit)
{
#endif
+ if (print_ps2)
+ {
+ if (ps2 == 0)
+ ps2 = get_string_value ("PS2");
+ fprintf (stderr, "%s", ps2 ? ps2 : "");
+ fflush (stderr);
+ print_ps2 = 0;
+ }
+
if (unbuffered_read)
retval = zread (fd, &c, 1);
else
newline pair still disappears from the input. */
if (pass_next)
{
+ pass_next = 0;
if (c == '\n')
- i--; /* back up over the CTLESC */
+ {
+ i--; /* back up over the CTLESC */
+ if (interactive && input_is_tty && raw == 0)
+ print_ps2 = 1;
+ }
else
- input_string[i++] = c;
- pass_next = 0;
+ goto add_char;
continue;
}
input_string[i++] = CTLESC;
}
+add_char:
input_string[i++] = c;
+ nr++;
- if (nchars > 0 && i >= nchars)
+ if (nchars > 0 && nr >= nchars)
break;
}
input_string[i] = '\0';
if (retval < 0)
{
builtin_error (_("read error: %d: %s"), fd, strerror (errno));
+ run_unwind_frame ("read_builtin");
return (EXECUTION_FAILURE);
}
#endif
zsyncfd (fd);
interrupt_immediately--;
+ terminate_immediately = 0;
discard_unwind_frame ("read_builtin");
retval = eof ? EXECUTION_FAILURE : EXECUTION_SUCCESS;
var = find_or_make_array_variable (arrayname, 1);
if (var == 0)
- return EXECUTION_FAILURE; /* readonly or noassign */
+ {
+ xfree (input_string);
+ return EXECUTION_FAILURE; /* readonly or noassign */
+ }
array_flush (array_cell (var));
alist = list_string (input_string, ifs_chars, 0);
if (alist)
{
- word_list_remove_quoted_nulls (alist);
- assign_array_var_from_word_list (var, alist);
+ if (saw_escape)
+ dequote_list (alist);
+ else
+ word_list_remove_quoted_nulls (alist);
+ assign_array_var_from_word_list (var, alist, 0);
dispose_words (alist);
}
xfree (input_string);
if (saw_escape)
{
t = dequote_string (input_string);
- var = bind_variable ("REPLY", t);
+ var = bind_variable ("REPLY", t, 0);
free (t);
}
else
- var = bind_variable ("REPLY", input_string);
+ var = bind_variable ("REPLY", input_string, 0);
VUNSETATTR (var, att_invisible);
free (input_string);
return (EXECUTION_FAILURE);
}
+#if 0
/* This has to be done this way rather than using string_list
and list_string because Posix.2 says that the last variable gets the
remaining words and their intervening separators. */
input_string = strip_trailing_ifs_whitespace (input_string, ifs_chars, saw_escape);
+#else
+ /* Check whether or not the number of fields is exactly the same as the
+ number of variables. */
+ tofree = NULL;
+ if (*input_string)
+ {
+ t1 = input_string;
+ t = get_word_from_string (&input_string, ifs_chars, &e);
+ if (*input_string == 0)
+ tofree = input_string = t;
+ else
+ input_string = strip_trailing_ifs_whitespace (t1, ifs_chars, saw_escape);
+ }
+#endif
if (saw_escape)
{
else
var = bind_read_variable (list->word->word, input_string);
stupidly_hack_special_variables (list->word->word);
+ FREE (tofree);
+
if (var)
VUNSETATTR (var, att_invisible);
xfree (orig_input_string);
{
#if defined (ARRAY_VARS)
if (valid_array_reference (name) == 0)
- return (bind_variable (name, value));
+ return (bind_variable (name, value, 0));
else
- return (assign_array_element (name, value));
+ return (assign_array_element (name, value, 0));
#else /* !ARRAY_VARS */
- return bind_variable (name, value);
+ return bind_variable (name, value, 0);
#endif /* !ARRAY_VARS */
}
#if defined (READLINE)
-static rl_completion_func_t *old_attempted_completion_function;
+static rl_completion_func_t *old_attempted_completion_function = 0;
+
+static void
+reset_attempted_completion_function (cp)
+ char *cp;
+{
+ if (rl_attempted_completion_function == 0 && old_attempted_completion_function)
+ rl_attempted_completion_function = old_attempted_completion_function;
+}
static char *
edit_line (p)
char *ret;
int len;
- if (!bash_readline_initialized)
+ if (bash_readline_initialized == 0)
initialize_readline ();
+
old_attempted_completion_function = rl_attempted_completion_function;
rl_attempted_completion_function = (rl_completion_func_t *)NULL;
ret = readline (p);
rl_attempted_completion_function = old_attempted_completion_function;
+ old_attempted_completion_function = (rl_completion_func_t *)NULL;
+
if (ret == 0)
return ret;
len = strlen (ret);