mirror of
https://https.git.savannah.gnu.org/git/bash.git
synced 2026-09-01 23:50:44 +02:00
change `read -d' on a tty when the delimiter is not a newline to set the terminal EOL character instead of putting the terminal into character-at-a-time mode; change some calls to atoi to use strol instead
This commit is contained in:
+1
-1
@@ -641,7 +641,7 @@ fc_gethnum (char *command, HIST_ENTRY **hlist, int mode)
|
||||
|
||||
if (s && DIGIT(*s))
|
||||
{
|
||||
n = atoi (s);
|
||||
n = (int)strtol (s, (char **)NULL, 10);
|
||||
n *= sign;
|
||||
|
||||
/* We want to return something that is an offset to HISTORY_BASE. */
|
||||
|
||||
+31
-15
@@ -1,7 +1,7 @@
|
||||
This file is read.def, from which is created read.c.
|
||||
It implements the builtin "read" in Bash.
|
||||
|
||||
Copyright (C) 1987-2025 Free Software Foundation, Inc.
|
||||
Copyright (C) 1987-2026 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
@@ -249,7 +249,7 @@ read_builtin (WORD_LIST *list)
|
||||
{
|
||||
char *varname;
|
||||
int nr, pass_next, saw_escape, eof, opt, retval, code, print_ps2, nflag;
|
||||
size_t size;
|
||||
size_t input_string_size;
|
||||
volatile int i;
|
||||
int input_is_tty, input_is_pipe, unbuffered_read, skip_ctlesc, skip_ctlnul;
|
||||
int edit, use_bash_completion;
|
||||
@@ -279,7 +279,7 @@ read_builtin (WORD_LIST *list)
|
||||
FILE *save_instream;
|
||||
#endif
|
||||
|
||||
USE_VAR(size);
|
||||
USE_VAR(input_string_size);
|
||||
USE_VAR(i);
|
||||
USE_VAR(pass_next);
|
||||
USE_VAR(print_ps2);
|
||||
@@ -421,6 +421,8 @@ read_builtin (WORD_LIST *list)
|
||||
{
|
||||
int ct; /* change terminal settings */
|
||||
|
||||
/* XXX - revisit this now that bash doesn't change terminal settings if
|
||||
the delimiter is not a newline. */
|
||||
ct = (nflag || delim != '\n') && isatty (fd);
|
||||
return (check_read_input (fd, ct) ? EXECUTION_SUCCESS : EXECUTION_FAILURE);
|
||||
}
|
||||
@@ -460,7 +462,7 @@ read_builtin (WORD_LIST *list)
|
||||
for (skip_ctlesc = skip_ctlnul = 0, e = ifs_chars; *e; e++)
|
||||
skip_ctlesc |= *e == CTLESC, skip_ctlnul |= *e == CTLNUL;
|
||||
|
||||
input_string = (char *)xmalloc (size = 112); /* XXX was 128 */
|
||||
input_string = (char *)xmalloc (input_string_size = 496); /* XXX was 128 */
|
||||
input_string[0] = '\0';
|
||||
|
||||
pass_next = 0; /* Non-zero signifies last char was backslash. */
|
||||
@@ -616,13 +618,24 @@ read_builtin (WORD_LIST *list)
|
||||
#endif
|
||||
if (input_is_tty)
|
||||
{
|
||||
int rc;
|
||||
|
||||
/* ttsave() */
|
||||
termsave.fd = fd;
|
||||
ttgetattr (fd, &ttattrs);
|
||||
termsave.attrs = ttattrs;
|
||||
|
||||
ttset = ttattrs;
|
||||
if ((silent ? ttfd_cbreak (fd, &ttset) : ttfd_onechar (fd, &ttset)) < 0)
|
||||
ttset = ttattrs;
|
||||
|
||||
if (nchars > 0)
|
||||
rc = silent ? ttfd_cbreak (fd, &ttset) : ttfd_onechar (fd, &ttset);
|
||||
else /* delim != '\n' */
|
||||
{
|
||||
rc = silent ? tt_setnoecho (&ttset) : 0;
|
||||
if (rc >= 0)
|
||||
rc = ttfd_seteol (fd, &ttset, delim);
|
||||
}
|
||||
if (rc < 0)
|
||||
sh_ttyerror (1);
|
||||
tty_modified = 1;
|
||||
add_unwind_protect (uw_ttyrestore, &termsave);
|
||||
@@ -690,12 +703,11 @@ read_builtin (WORD_LIST *list)
|
||||
/* These only matter if edit == 0 */
|
||||
if ((nchars > 0) && (input_is_tty == 0) && ignore_delim) /* read -N */
|
||||
unbuffered_read = 2;
|
||||
#if 0
|
||||
else if ((nchars > 0) || (delim != '\n') || input_is_pipe)
|
||||
#else
|
||||
else if (((nchars > 0 || delim != '\n') && input_is_tty) || input_is_pipe)
|
||||
else if ((nchars > 0 && input_is_tty) || input_is_pipe) /* read -n */
|
||||
unbuffered_read = 1;
|
||||
#endif
|
||||
else if (delim != '\n' && input_is_tty) /* read -d */
|
||||
unbuffered_read = 3;
|
||||
|
||||
if (prompt && edit == 0)
|
||||
{
|
||||
fprintf (stderr, "%s", prompt);
|
||||
@@ -759,9 +771,11 @@ read_builtin (WORD_LIST *list)
|
||||
if (tmsec > 0 || tmusec > 0)
|
||||
sigprocmask (SIG_SETMASK, &chldset, &prevset);
|
||||
#endif
|
||||
if (unbuffered_read == 2)
|
||||
if (unbuffered_read == 2) /* read -N */
|
||||
retval = posixly_correct ? zreadintr (fd, &c, 1) : zreadn (fd, &c, nchars - nr);
|
||||
else if (unbuffered_read)
|
||||
else if (unbuffered_read == 3) /* read -d on a tty */
|
||||
retval = posixly_correct ? zreadcintr (fd, &c) : zreadc (fd, &c);
|
||||
else if (unbuffered_read) /* read -n or input_is_pipe */
|
||||
retval = posixly_correct ? zreadintr (fd, &c, 1) : zread (fd, &c, 1);
|
||||
else
|
||||
retval = posixly_correct ? zreadcintr (fd, &c) : zreadc (fd, &c);
|
||||
@@ -811,10 +825,10 @@ read_builtin (WORD_LIST *list)
|
||||
check_read_timeout ();
|
||||
|
||||
/* XXX -- use i + mb_cur_max (at least 4) for multibyte/read_mbchar */
|
||||
if (i + (mb_cur_max > 4 ? mb_cur_max : 4) >= size)
|
||||
if (i + (mb_cur_max > 4 ? mb_cur_max : 4) >= input_string_size)
|
||||
{
|
||||
char *x;
|
||||
x = (char *)xrealloc (input_string, size += 128);
|
||||
x = (char *)xrealloc (input_string, input_string_size += 512);
|
||||
|
||||
#if 0
|
||||
/* This is, in theory, undefined behavior, since input_string may
|
||||
@@ -1213,6 +1227,8 @@ read_mbchar (int fd, char *string, int ind, int ch, int delim, int unbuffered)
|
||||
/* We don't want to be interrupted during a multibyte char read */
|
||||
if (unbuffered == 2)
|
||||
r = zreadn (fd, &c, 1);
|
||||
else if (unbuffered == 3)
|
||||
r = zreadc (fd, &c);
|
||||
else if (unbuffered)
|
||||
r = zread (fd, &c, 1);
|
||||
else
|
||||
|
||||
Reference in New Issue
Block a user