mirror of
https://https.git.savannah.gnu.org/git/bash.git
synced 2026-07-11 22:20:49 +02:00
fixes for HAVE_SELECT/HAVE_PSELECT; change some warning messages for nameref loops; run unwind-protects if max function nesting level is exceeded
This commit is contained in:
@@ -4530,3 +4530,52 @@ lib/readline/rldefs.h
|
||||
include/posixselect.h
|
||||
- include "posixtime.h" instead of <sys/time.h> so the right guards
|
||||
are present
|
||||
|
||||
builtins/read.def
|
||||
- read_builtin_timeout: make sure we don't try to call shtimer_select
|
||||
if HAVE_SELECT isn't define; it won't be compiled in
|
||||
|
||||
include/stdc.h
|
||||
- restrict: make sure we have a definition if __STDC__ is not defined
|
||||
|
||||
include/posixtime.h,lib/sh/gettimeofday.c
|
||||
- gettimeofday: make sure the function signature matches POSIX by
|
||||
adding `restrict'
|
||||
|
||||
11/25
|
||||
-----
|
||||
include/posixselect.h
|
||||
- don't try to define HAVE_SELECT at all if _WIN32 is defined
|
||||
|
||||
lib/readline/kill.c
|
||||
- define WIN32_LEAN_AND_MEAN for the windows-specific paste function
|
||||
|
||||
lib/readline/rlprivate.h
|
||||
- _rl_timeout_select: only include declaration if HAVE_SELECT or
|
||||
HAVE_PSELECT are defined
|
||||
|
||||
11/28
|
||||
-----
|
||||
lib/readline/input.c
|
||||
- rl_gather_tyi: call rl_input_available_hook after FIONREAD test,
|
||||
let the application hook into whether or not there are characters
|
||||
to read
|
||||
|
||||
execute_cmd.c
|
||||
- execute_function: if the maximum function nesting level is exceeded,
|
||||
run the unwind-protects before jumping back to top level. Report
|
||||
from felix <felix@f-hauri.ch>
|
||||
|
||||
variables.c
|
||||
- find_variable_nameref_for_create,find_variable_nameref_for_assignment:
|
||||
handle find_variable_nameref returning &nameref_maxloop_value, return
|
||||
NULL and print a warning message in that case
|
||||
- find_variable_nameref: return &namref_maxloop_value instead of NULL
|
||||
if the number of resolution cycles exceeds NAMEREF_MAX; change
|
||||
callers to print a new error message in this case; no other change
|
||||
in behavior. From a 4/2020 suggestion from Andrej Podzimek
|
||||
<andrej@podzimek.org>
|
||||
- find_variable_nameref_context, find_nameref_at_context,
|
||||
find_variable_last_nameref_context: make sure to return
|
||||
&nameref_maxloop_value consistently and handle getting it as a
|
||||
return value from other functions
|
||||
|
||||
@@ -189,8 +189,12 @@ read_builtin_timeout (fd)
|
||||
(read_timeout->tmout.tv_sec == 0 && read_timeout->tmout.tv_usec == 0))
|
||||
return 0;
|
||||
|
||||
#if defined (HAVE_SELECT)
|
||||
return ((read_timeout->flags & SHTIMER_ALARM) ? shtimer_alrm (read_timeout)
|
||||
: shtimer_select (read_timeout));
|
||||
#else
|
||||
return (shtimer_alrm (read_timeout));
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Read the value of the shell variables whose names follow.
|
||||
|
||||
@@ -489,8 +489,6 @@
|
||||
|
||||
#undef HAVE_DECL_STRTOLD
|
||||
|
||||
#undef HAVE_DECL_GETTIMEOFDAY
|
||||
|
||||
#undef PRI_MACROS_BROKEN
|
||||
|
||||
#undef STRTOLD_BROKEN
|
||||
|
||||
@@ -875,7 +875,6 @@ AC_CHECK_DECLS([sbrk])
|
||||
AC_CHECK_DECLS([setregid])
|
||||
AC_CHECK_DECLS([strcpy])
|
||||
AC_CHECK_DECLS([strsignal])
|
||||
AC_CHECK_DECLS([gettimeofday])
|
||||
|
||||
AC_CHECK_FUNCS(setresuid setresgid)
|
||||
|
||||
|
||||
@@ -5077,6 +5077,7 @@ execute_function (var, words, flags, fds_to_close, async, subshell)
|
||||
if (funcnest_max > 0 && funcnest >= funcnest_max)
|
||||
{
|
||||
internal_error (_("%s: maximum function nesting level exceeded (%d)"), var->name, funcnest);
|
||||
run_unwind_protects (); /* XXX */
|
||||
funcnest = 0; /* XXX - should we reset it somewhere else? */
|
||||
jump_to_top_level (DISCARD);
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
#ifndef _POSIXSELECT_H_
|
||||
#define _POSIXSELECT_H_
|
||||
|
||||
#if defined (FD_SET) && !defined (HAVE_SELECT)
|
||||
#if defined (FD_SET) && !defined (HAVE_SELECT) && !defined (_WIN32)
|
||||
# define HAVE_SELECT 1
|
||||
#endif
|
||||
|
||||
|
||||
+1
-1
@@ -49,7 +49,7 @@ struct timeval
|
||||
#endif
|
||||
|
||||
#if !HAVE_GETTIMEOFDAY
|
||||
extern int gettimeofday PARAMS((struct timeval *, void *));
|
||||
extern int gettimeofday PARAMS((struct timeval * restrict, void * restrict));
|
||||
#endif
|
||||
|
||||
/* These exist on BSD systems, at least. */
|
||||
|
||||
@@ -52,6 +52,9 @@
|
||||
# if !defined (volatile)
|
||||
# define volatile __volatile
|
||||
# endif
|
||||
# if !defined (restrict)
|
||||
# define restrict __restrict
|
||||
# endif
|
||||
#else /* !__GNUC__ */
|
||||
# if !defined (inline)
|
||||
# define inline
|
||||
@@ -62,6 +65,9 @@
|
||||
# if !defined (volatile)
|
||||
# define volatile
|
||||
# endif
|
||||
# if !defined (restrict)
|
||||
# define restrict
|
||||
# endif
|
||||
#endif /* !__GNUC__ */
|
||||
|
||||
#endif /* !__STDC__ */
|
||||
|
||||
@@ -284,6 +284,13 @@ rl_gather_tyi (void)
|
||||
chars_avail = 0;
|
||||
#endif
|
||||
|
||||
if (result == -1 && rl_input_available_hook)
|
||||
{
|
||||
result = (*rl_input_available_hook) ();
|
||||
if (result == 0)
|
||||
result = -1;
|
||||
}
|
||||
|
||||
#if defined (O_NDELAY)
|
||||
if (result == -1)
|
||||
{
|
||||
|
||||
@@ -865,6 +865,8 @@ _rl_bracketed_read_mbstring (char *mb, int mlen)
|
||||
|
||||
/* A special paste command for Windows users. */
|
||||
#if defined (_WIN32)
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
int
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "rlstdc.h"
|
||||
#include "posixselect.h"
|
||||
|
||||
#if defined (HAVE_STRING_H)
|
||||
|
||||
@@ -596,8 +596,7 @@ readline_internal_charloop (void)
|
||||
if (RL_ISSTATE (RL_STATE_TIMEOUT))
|
||||
{
|
||||
RL_SETSTATE (RL_STATE_DONE);
|
||||
rl_done = 1;
|
||||
return 1;
|
||||
return (rl_done = 1);
|
||||
}
|
||||
|
||||
/* If we get here, we're not being called from something dispatched
|
||||
|
||||
@@ -303,7 +303,7 @@ extern int _rl_pushed_input_available (void);
|
||||
|
||||
extern int _rl_timeout_init (void);
|
||||
extern int _rl_timeout_handle_sigalrm (void);
|
||||
#if defined (_POSIXSELECT_H_) && !defined (__MINGW32__)
|
||||
#if defined (_POSIXSELECT_H_) && !defined (__MINGW32__) && (defined (HAVE_SELECT) || defined (HAVE_PSELECT))
|
||||
/* use as a sentinel for fd_set, struct timeval, and sigset_t definitions */
|
||||
extern int _rl_timeout_select (int, fd_set *, fd_set *, fd_set *, const struct timeval *, const sigset_t *);
|
||||
#endif
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
|
||||
/* A version of gettimeofday that just sets tv_sec from time(3) */
|
||||
int
|
||||
gettimeofday (struct timeval *tv, void *tz)
|
||||
gettimeofday (struct timeval *restrict tv, void *restrict tz)
|
||||
{
|
||||
tv->tv_sec = (time_t) time ((time_t *)0);
|
||||
tv->tv_usec = 0;
|
||||
|
||||
+6
-6
@@ -123,17 +123,17 @@ bar
|
||||
unset
|
||||
./nameref8.sub: line 16: typeset: warning: v: circular name reference
|
||||
./nameref8.sub: line 16: warning: v: circular name reference
|
||||
./nameref8.sub: line 18: warning: v: circular name reference
|
||||
./nameref8.sub: line 18: warning: v: maximum nameref depth (8) exceeded
|
||||
inside
|
||||
inside: two
|
||||
outside:
|
||||
./nameref8.sub: line 42: typeset: warning: x: circular name reference
|
||||
./nameref8.sub: line 42: warning: x: circular name reference
|
||||
./nameref8.sub: line 44: warning: x: circular name reference
|
||||
./nameref8.sub: line 44: warning: x: maximum nameref depth (8) exceeded
|
||||
foo
|
||||
./nameref8.sub: line 51: typeset: warning: v: circular name reference
|
||||
./nameref8.sub: line 51: warning: v: circular name reference
|
||||
./nameref8.sub: line 51: warning: v: circular name reference
|
||||
./nameref8.sub: line 51: warning: v: maximum nameref depth (8) exceeded
|
||||
local
|
||||
./nameref8.sub: line 60: typeset: v: nameref variable self references not allowed
|
||||
./nameref8.sub: line 67: warning: x: circular name reference
|
||||
@@ -302,7 +302,7 @@ declare -n ref="var"
|
||||
declare -a a=([0]="0")
|
||||
./nameref15.sub: line 14: local: warning: a: circular name reference
|
||||
./nameref15.sub: line 14: warning: a: circular name reference
|
||||
./nameref15.sub: line 14: warning: a: circular name reference
|
||||
./nameref15.sub: line 14: warning: a: maximum nameref depth (8) exceeded
|
||||
declare -a a=([0]="X")
|
||||
declare -a b=([0]="X")
|
||||
./nameref15.sub: line 14: local: warning: a: circular name reference
|
||||
@@ -311,14 +311,14 @@ declare -a b=([0]="X")
|
||||
declare -a b=([0]="0")
|
||||
./nameref15.sub: line 32: typeset: warning: ref: circular name reference
|
||||
./nameref15.sub: line 32: warning: ref: circular name reference
|
||||
./nameref15.sub: line 33: warning: ref: circular name reference
|
||||
./nameref15.sub: line 33: warning: ref: maximum nameref depth (8) exceeded
|
||||
./nameref15.sub: line 34: warning: ref: circular name reference
|
||||
inside X
|
||||
outside X
|
||||
before: 7
|
||||
./nameref15.sub: line 45: typeset: warning: xxx: circular name reference
|
||||
./nameref15.sub: line 45: warning: xxx: circular name reference
|
||||
./nameref15.sub: line 46: warning: xxx: circular name reference
|
||||
./nameref15.sub: line 46: warning: xxx: maximum nameref depth (8) exceeded
|
||||
declare -n xxx="xxx"
|
||||
./nameref15.sub: line 48: warning: xxx: circular name reference
|
||||
xxx_func: inside: xxx = foo
|
||||
|
||||
+83
-11
@@ -2086,7 +2086,7 @@ find_variable_nameref (v)
|
||||
{
|
||||
level++;
|
||||
if (level > NAMEREF_MAX)
|
||||
return ((SHELL_VAR *)0); /* error message here? */
|
||||
return (&nameref_maxloop_value);
|
||||
newname = nameref_cell (v);
|
||||
if (newname == 0 || *newname == '\0')
|
||||
return ((SHELL_VAR *)0);
|
||||
@@ -2266,6 +2266,11 @@ find_variable_nameref_for_create (name, flags)
|
||||
/* See if we have a nameref pointing to a variable that hasn't been
|
||||
created yet. */
|
||||
var = find_variable_last_nameref (name, 1);
|
||||
if (var == &nameref_maxloop_value)
|
||||
{
|
||||
internal_warning (_("%s: maximum nameref depth (%d) exceeded"), name, NAMEREF_MAX);
|
||||
return ((SHELL_VAR *)INVALID_NAMEREF_VALUE);
|
||||
}
|
||||
if ((flags&1) && var && nameref_p (var) && invisible_p (var))
|
||||
{
|
||||
internal_warning (_("%s: removing nameref attribute"), name);
|
||||
@@ -2292,6 +2297,11 @@ find_variable_nameref_for_assignment (name, flags)
|
||||
/* See if we have a nameref pointing to a variable that hasn't been
|
||||
created yet. */
|
||||
var = find_variable_last_nameref (name, 1);
|
||||
if (var == &nameref_maxloop_value)
|
||||
{
|
||||
internal_warning (_("%s: maximum nameref depth (%d) exceeded"), name, NAMEREF_MAX);
|
||||
return ((SHELL_VAR *)INVALID_NAMEREF_VALUE);
|
||||
}
|
||||
if (var && nameref_p (var) && invisible_p (var)) /* XXX - flags */
|
||||
{
|
||||
internal_warning (_("%s: removing nameref attribute"), name);
|
||||
@@ -2347,7 +2357,14 @@ find_variable_tempenv (name)
|
||||
|
||||
var = find_variable_internal (name, FV_FORCETEMPENV);
|
||||
if (var && nameref_p (var))
|
||||
var = find_variable_nameref (var);
|
||||
{
|
||||
var = find_variable_nameref (var);
|
||||
if (var == &nameref_maxloop_value)
|
||||
{
|
||||
internal_warning (_("%s: maximum nameref depth (%d) exceeded"), name, NAMEREF_MAX);
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
return (var);
|
||||
}
|
||||
|
||||
@@ -2360,7 +2377,14 @@ find_variable_notempenv (name)
|
||||
|
||||
var = find_variable_internal (name, 0);
|
||||
if (var && nameref_p (var))
|
||||
var = find_variable_nameref (var);
|
||||
{
|
||||
var = find_variable_nameref (var);
|
||||
if (var == &nameref_maxloop_value)
|
||||
{
|
||||
internal_warning (_("%s: maximum nameref depth (%d) exceeded"), name, NAMEREF_MAX);
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
return (var);
|
||||
}
|
||||
|
||||
@@ -2372,7 +2396,14 @@ find_global_variable (name)
|
||||
|
||||
var = var_lookup (name, global_variables);
|
||||
if (var && nameref_p (var))
|
||||
var = find_variable_nameref (var); /* XXX - find_global_variable_noref? */
|
||||
{
|
||||
var = find_variable_nameref (var); /* XXX - find_global_variable_noref? */
|
||||
if (var == &nameref_maxloop_value)
|
||||
{
|
||||
internal_warning (_("%s: maximum nameref depth (%d) exceeded"), name, NAMEREF_MAX);
|
||||
return ((SHELL_VAR *)NULL);
|
||||
}
|
||||
}
|
||||
|
||||
if (var == 0)
|
||||
return ((SHELL_VAR *)NULL);
|
||||
@@ -2402,7 +2433,14 @@ find_shell_variable (name)
|
||||
|
||||
var = var_lookup (name, shell_variables);
|
||||
if (var && nameref_p (var))
|
||||
var = find_variable_nameref (var);
|
||||
{
|
||||
var = find_variable_nameref (var);
|
||||
if (var == &nameref_maxloop_value)
|
||||
{
|
||||
internal_warning (_("%s: maximum nameref depth (%d) exceeded"), name, NAMEREF_MAX);
|
||||
return ((SHELL_VAR *)NULL);
|
||||
}
|
||||
}
|
||||
|
||||
if (var == 0)
|
||||
return ((SHELL_VAR *)NULL);
|
||||
@@ -2424,7 +2462,15 @@ find_variable (name)
|
||||
flags |= FV_FORCETEMPENV;
|
||||
v = find_variable_internal (name, flags);
|
||||
if (v && nameref_p (v))
|
||||
v = find_variable_nameref (v);
|
||||
{
|
||||
v = find_variable_nameref (v);
|
||||
if (v == &nameref_maxloop_value)
|
||||
{
|
||||
internal_warning (_("%s: maximum nameref depth (%d) exceeded"), name, NAMEREF_MAX);
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
@@ -2444,7 +2490,15 @@ find_variable_no_invisible (name)
|
||||
flags |= FV_FORCETEMPENV;
|
||||
v = find_variable_internal (name, flags);
|
||||
if (v && nameref_p (v))
|
||||
v = find_variable_nameref (v);
|
||||
{
|
||||
v = find_variable_nameref (v);
|
||||
if (v == &nameref_maxloop_value)
|
||||
{
|
||||
internal_warning (_("%s: maximum nameref depth (%d) exceeded"), name, NAMEREF_MAX);
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
@@ -2463,7 +2517,15 @@ find_variable_for_assignment (name)
|
||||
flags |= FV_FORCETEMPENV;
|
||||
v = find_variable_internal (name, flags);
|
||||
if (v && nameref_p (v))
|
||||
v = find_variable_nameref (v);
|
||||
{
|
||||
v = find_variable_nameref (v);
|
||||
if (v == &nameref_maxloop_value)
|
||||
{
|
||||
internal_warning (_("%s: maximum nameref depth (%d) exceeded"), name, NAMEREF_MAX);
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
@@ -3288,7 +3350,7 @@ bind_variable (name, value, flags)
|
||||
if (nv == 0)
|
||||
{
|
||||
nv = find_variable_last_nameref_context (v, vc, &nvc);
|
||||
if (nv && nameref_p (nv))
|
||||
if (nv && nv != &nameref_maxloop_value && nameref_p (nv))
|
||||
{
|
||||
/* If this nameref variable doesn't have a value yet,
|
||||
set the value. Otherwise, assign using the value as
|
||||
@@ -3304,7 +3366,7 @@ bind_variable (name, value, flags)
|
||||
}
|
||||
else if (nv == &nameref_maxloop_value)
|
||||
{
|
||||
internal_warning (_("%s: circular name reference"), v->name);
|
||||
internal_warning (_("%s: maximum nameref depth (%d) exceeded"), v->name, NAMEREF_MAX);
|
||||
return (bind_global_variable (v->name, value, flags));
|
||||
}
|
||||
else
|
||||
@@ -3312,7 +3374,7 @@ bind_variable (name, value, flags)
|
||||
}
|
||||
else if (nv == &nameref_maxloop_value)
|
||||
{
|
||||
internal_warning (_("%s: circular name reference"), v->name);
|
||||
internal_warning (_("%s: maximum nameref depth (%d) exceeded"), v->name, NAMEREF_MAX);
|
||||
return (bind_global_variable (v->name, value, flags));
|
||||
}
|
||||
else
|
||||
@@ -3811,6 +3873,11 @@ unbind_variable (name)
|
||||
|
||||
v = var_lookup (name, shell_variables);
|
||||
nv = (v && nameref_p (v)) ? find_variable_nameref (v) : (SHELL_VAR *)NULL;
|
||||
if (nv == &nameref_maxloop_value)
|
||||
{
|
||||
internal_warning (_("%s: maximum nameref depth (%d) exceeded"), name, NAMEREF_MAX);
|
||||
nv = 0;
|
||||
}
|
||||
|
||||
r = nv ? makunbound (nv->name, shell_variables) : makunbound (name, shell_variables);
|
||||
return r;
|
||||
@@ -3853,6 +3920,11 @@ unbind_global_variable (name)
|
||||
/* This starts at the current scope, just like find_global_variable; should we
|
||||
use find_global_variable_nameref here? */
|
||||
nv = (v && nameref_p (v)) ? find_variable_nameref (v) : (SHELL_VAR *)NULL;
|
||||
if (nv == &nameref_maxloop_value)
|
||||
{
|
||||
internal_warning (_("%s: maximum nameref depth (%d) exceeded"), name, NAMEREF_MAX);
|
||||
nv = 0;
|
||||
}
|
||||
|
||||
r = nv ? makunbound (nv->name, shell_variables) : makunbound (name, global_variables);
|
||||
return r;
|
||||
|
||||
Reference in New Issue
Block a user