builtins now return success if supplied --help; use groff to build HTML man pages; reset mbstate if $'...' strings read an invalid multibyte sequence; read -t 0 now looks at other options (-n/-N/-d) and sets the terminal state appropriately

This commit is contained in:
Chet Ramey
2025-10-01 10:44:10 -04:00
parent cf8a2518c8
commit fbd078be0a
35 changed files with 1666 additions and 1479 deletions
+4 -3
View File
@@ -1,7 +1,7 @@
This file is builtin.def, from which is created builtin.c.
It implements the builtin "builtin" in Bash.
Copyright (C) 1987-2017,2022 Free Software Foundation, Inc.
Copyright (C) 1987-2017,2022-2025 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -54,9 +54,10 @@ builtin_builtin (WORD_LIST *list)
{
sh_builtin_func_t *function;
register char *command;
int r;
if (no_options (list))
return (EX_USAGE);
if (r = no_options (list))
return (r == EX_HELPOPT ? EXECUTION_SUCCESS : EX_USAGE);
list = loptend; /* skip over possible `--' */
if (list == 0)
+1 -1
View File
@@ -164,7 +164,7 @@ no_options (WORD_LIST *list)
if (opt == GETOPT_HELP)
{
builtin_help ();
return (2);
return (EX_HELPOPT);
}
builtin_usage ();
return (1);
+2 -2
View File
@@ -31,14 +31,14 @@ do { \
if ((l) && (l)->word && ISHELP((l)->word->word)) \
{ \
builtin_help (); \
return (EX_USAGE); \
return (EXECUTION_SUCCESS); \
} \
} while (0)
#define CASE_HELPOPT \
case GETOPT_HELP: \
builtin_help (); \
return (EX_USAGE)
return (EXECUTION_SUCCESS)
/* Flag values for parse_and_execute () and parse_string () */
#define SEVAL_NONINT 0x001
+5 -3
View File
@@ -1,7 +1,7 @@
This file is eval.def, from which is created eval.c.
It implements the builtin "eval" in Bash.
Copyright (C) 1987-2016,2022 Free Software Foundation, Inc.
Copyright (C) 1987-2016,2022-2025 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -48,8 +48,10 @@ $END
int
eval_builtin (WORD_LIST *list)
{
if (no_options (list))
return (EX_USAGE);
int r;
if (r = no_options (list))
return (r == EX_HELPOPT ? EXECUTION_SUCCESS : EX_USAGE);
list = loptend; /* skip over possible `--' */
return (list ? evalstring (string_list (list), "eval", SEVAL_NOHIST|SEVAL_NOOPTIMIZE) : EXECUTION_SUCCESS);
+3 -3
View File
@@ -1,7 +1,7 @@
This file is getopts.def, from which is created getopts.c.
It implements the builtin "getopts" in Bash.
Copyright (C) 1987-2024 Free Software Foundation, Inc.
Copyright (C) 1987-2025 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -315,8 +315,8 @@ getopts_builtin (WORD_LIST *list)
char **av;
int ac, ret;
if (no_options (list))
return (EX_USAGE);
if (ret = no_options (list))
return (ret == EX_HELPOPT ? EXECUTION_SUCCESS : EX_USAGE);
list = loptend; /* skip over possible `--' */
if (list == 0)
+31 -2
View File
@@ -216,6 +216,28 @@ uw_reset_rl_instream (void *fp)
}
#endif
/* Check whether there is input on FD after setting the terminal settings to
what they would be if the read was actually performed. */
static int
check_read_input (int fd, int change_term)
{
TTYSTRUCT ttattrs, ttset;
int r;
if (change_term)
{
ttgetattr (fd, &ttattrs);
ttset = ttattrs;
r = ttfd_onechar (fd, &ttset);
if (r < 0)
sh_ttyerror (1);
}
r = input_avail (fd);
if (change_term)
ttsetattr (fd, &ttattrs);
return r;
}
/* Read the value of the shell variables whose names follow.
The reading is done from the current input stream, whatever
that may be. Successive words of the input line are assigned
@@ -300,7 +322,8 @@ read_builtin (WORD_LIST *list)
mb_cur_max = MB_CUR_MAX;
tmsec = tmusec = 0; /* no timeout */
nr = nchars = input_is_tty = input_is_pipe = unbuffered_read = have_timeout = 0;
nr = nchars = input_is_pipe = unbuffered_read = have_timeout = 0;
input_is_tty = -1; /* not checked yet */
delim = '\n'; /* read until newline */
ignore_delim = nflag = 0;
@@ -395,7 +418,12 @@ read_builtin (WORD_LIST *list)
/* `read -t 0 var' tests whether input is available with select/FIONREAD,
and fails if those are unavailable */
if (have_timeout && tmsec == 0 && tmusec == 0)
return (input_avail (fd) ? EXECUTION_SUCCESS : EXECUTION_FAILURE);
{
int ct; /* change terminal settings */
ct = (nflag || delim) && isatty (fd);
return (check_read_input (fd, ct) ? EXECUTION_SUCCESS : EXECUTION_FAILURE);
}
/* Convenience: check early whether or not the first of possibly several
variable names is a valid identifier, and bail early if so. */
@@ -477,6 +505,7 @@ read_builtin (WORD_LIST *list)
#else
input_is_tty = 1;
#endif
if (input_is_tty == 0)
#ifndef __CYGWIN__
input_is_pipe = fd_ispipe (fd);
+4 -1
View File
@@ -30,6 +30,9 @@ the evaluation of EXPR. Expressions may be unary or binary. Unary
expressions are often used to examine the status of a file. There
are string operators and numeric comparison operators as well.
Unless specified otherwise, primaries that operate on files operate
on the target of a symbolic link rather than the link itself.
The behavior of test depends on the number of arguments. Read the
bash manual page for the complete specification.
@@ -62,7 +65,7 @@ File operators:
FILE1 -ot FILE2 True if file1 is older than file2.
FILE1 -ef FILE2 True if file1 is a hard link to file2.
FILE1 -ef FILE2 True if file1 and file2 refer to the same file.
String operators:
+8 -7
View File
@@ -1,7 +1,7 @@
This file is times.def, from which is created times.c.
It implements the builtin "times" in Bash.
Copyright (C) 1987-2009,2022 Free Software Foundation, Inc.
Copyright (C) 1987-2009,2022-2025 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -64,13 +64,14 @@ $END
int
times_builtin (WORD_LIST *list)
{
int r;
#if defined (HAVE_GETRUSAGE) && defined (HAVE_TIMEVAL) && defined (RUSAGE_SELF)
struct rusage self, kids;
USE_VAR(list);
if (no_options (list))
return (EX_USAGE);
if (r = no_options (list))
return (r == EX_HELPOPT ? EXECUTION_SUCCESS : EX_USAGE);
getrusage (RUSAGE_SELF, &self);
getrusage (RUSAGE_CHILDREN, &kids); /* terminated child processes */
@@ -92,8 +93,8 @@ times_builtin (WORD_LIST *list)
USE_VAR(list);
if (no_options (list))
return (EX_USAGE);
if (r = no_options (list))
return (r == EX_HELPOPT ? EXECUTION_SUCCESS : EX_USAGE);
times (&t);
@@ -110,8 +111,8 @@ times_builtin (WORD_LIST *list)
USE_VAR(list);
if (no_options (list))
return (EX_USAGE);
if (r = no_options (list))
return (r == EX_HELPOPT ? EXECUTION_SUCCESS : EX_USAGE);
printf ("0.00 0.00\n0.00 0.00\n");
# endif /* HAVE_TIMES */