bug-bash
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH 3/4] Port unwind protection to C23


From: Martin D Kealey
Subject: Re: [PATCH 3/4] Port unwind protection to C23
Date: Mon, 27 Mar 2023 14:17:32 +1000

While C has never guaranteed that pointers all have the same size &
alignment, POSIX does provide this guarantee, although indirectly (it has
to be true for dlsym() to work, for example).

Bash seems to need an environment that's "kinda POSIX" (at least emulating
the POSIX process & signal models), but does it currently run on any
platform not POSIX enough to require a non-Harvard (unified code & data)
linear address space?

Everything, even exotic microcontrollers, are heading towards unified
linear addressing, because it's less complex and therefore cheaper than the
alternatives, so I don't see any likelihood of this *becoming* a problem
for Bash in the future. (For other projects, sure, but not for Bash.)

All that said, I'm all for tidying up the code so that it can compile
cleanly and run reliably.

-Martin

On Mon, 27 Mar 2023 at 09:50, Paul Eggert <eggert@cs.ucla.edu> wrote:

> Do not assume that all pointers have the same representation at
> the machine level and that address space is linear, as the C
> standard does not guarantee this and it is not true on a few
> unusual platforms.  Fixing this also uncovered a bug on
> conventional 64-bit platforms, where the call 'add_unwind_protect
> (pop_scope, should_keep ? "1" : 0)' eventually casts a nonnull
> pointer to to an int that is tested against zero to see whether
> the pointer was null; this does not work if pointers are 64 bits,
> ints are 32 bits, and half the nonnull pointer happens to be all
> bits zero.
>
> Strictly speaking, the old code wasn't portable even to C89 on
> hypothetical platforms.  However, C23 makes this more urgent since
> it removes support for K&R-style function declarations.
>
> Use the generic function type void (*) (void *) for all unwind
> cleanups.  When an existing cleanup doesn't already have that
> type, change the type if the function is used only as a cleanup,
> and add a shim function otherwise.  If the shim is used in more
> than one compilation unit, put the shim function next to the
> cleanup as an extern function; otherwise, put the shim in the
> compilation unit as a static function.
>
> Although this does not finish the job of porting to C23,
> one step at a time.
>
> * builtins/mkbuiltins.c, general.h, readline/rltypedefs.h
> (_FUNCTION_DEF, Function, VFunction, CPFunction, CPPFunction):
> Remove; no longer used, as they are no longer needed.
> Their meaning changes in C23 anyway.
> * configure.ac (AC_TYPE_INTPTR_T): Use this.
> * execute_cmd.c (execute_command_internal):
> Remove a 'volatile' that didn't type check and appears to
> be a typo anyway.  Perhaps 'void *volatile' was meant, but
> in that case the 'volatile' appears to be unnecessary anyway.
> * general.h (STREQ, STREQN): Now inline functions instead of
> macros; needed for unwind_prot.c now that it passes void *
> to STREQ.
> * unwind_prot.c (UNWIND_ELT): Use a prototype for head.cleanup.
> arg.v is now void *, not char *; this simplifies use.
> (without_interrupts): Remove, as this vestigial function just
> got in the way of type checking.
> ---
>  builtins/command.def      |   2 +-
>  builtins/evalfile.c       |   4 +-
>  builtins/evalstring.c     |  35 +++++++++---
>  builtins/fc.def           |  10 +++-
>  builtins/jobs.def         |   2 +-
>  builtins/mkbuiltins.c     |   1 -
>  builtins/read.def         |  35 +++++++++---
>  builtins/source.def       |   6 +-
>  configure.ac              |   1 +
>  dispose_cmd.c             |  10 ++++
>  dispose_cmd.h             |   2 +
>  execute_cmd.c             | 117 +++++++++++++++++++++++++++-----------
>  execute_cmd.h             |   3 +
>  general.h                 |  22 ++++---
>  lib/readline/rltypedefs.h |  21 -------
>  pcomplete.c               |  26 ++++++---
>  print_cmd.c               |   4 +-
>  subst.c                   |   2 +-
>  trap.c                    |  10 ++--
>  trap.h                    |   8 +--
>  unwind_prot.c             |  82 +++++++++++---------------
>  unwind_prot.h             |   2 +-
>  variables.c               |  11 +++-
>  variables.h               |   5 +-
>  24 files changed, 254 insertions(+), 167 deletions(-)
>
> diff --git a/builtins/command.def b/builtins/command.def
> index e695fdd1..a376131e 100644
> --- a/builtins/command.def
> +++ b/builtins/command.def
> @@ -131,7 +131,7 @@ command_builtin (WORD_LIST *list)
>    command->flags |= COMMAND_BUILTIN_FLAGS;
>    command->value.Simple->flags |= COMMAND_BUILTIN_FLAGS;
>
> -  add_unwind_protect ((char *)dispose_command, command);
> +  add_unwind_protect (unwind_dispose_command, command);
>    result = execute_command (command);
>
>    run_unwind_frame ("command_builtin");
> diff --git a/builtins/evalfile.c b/builtins/evalfile.c
> index 9b6f4215..46788398 100644
> --- a/builtins/evalfile.c
> +++ b/builtins/evalfile.c
> @@ -247,7 +247,7 @@ file_error_and_exit:
>    fa->funcname_a = funcname_a;
>    fa->funcname_v = funcname_v;
>    if (flags & FEVAL_UNWINDPROT)
> -    add_unwind_protect (restore_funcarray_state, fa);
> +    add_unwind_protect (unwind_restore_funcarray_state, fa);
>
>  #  if defined (DEBUGGER)
>    /* Have to figure out a better way to do this when `source' is supplied
> @@ -260,7 +260,7 @@ file_error_and_exit:
>        tt[0] = '1'; tt[1] = '\0';
>        array_push (bash_argc_a, tt);
>        if (flags & FEVAL_UNWINDPROT)
> -       add_unwind_protect (pop_args, 0);
> +       add_unwind_protect (unwind_pop_args, 0);
>      }
>  #  endif
>  #endif
> diff --git a/builtins/evalstring.c b/builtins/evalstring.c
> index 243becbc..b52a1a26 100644
> --- a/builtins/evalstring.c
> +++ b/builtins/evalstring.c
> @@ -70,14 +70,14 @@ static int cat_file (REDIRECT *);
>
>  #if defined (HISTORY)
>  static void
> -set_history_remembering (void)
> +set_history_remembering (void *ignored)
>  {
>    remember_on_history = enable_history_list;
>  }
>  #endif
>
>  static void
> -restore_lastcom (char *x)
> +restore_lastcom (void *x)
>  {
>    FREE (the_printed_command_except_trap);
>    the_printed_command_except_trap = x;
> @@ -204,6 +204,26 @@ parse_and_execute_cleanup (int old_running_trap)
>      parse_and_execute_level = 0;                       /* XXX */
>  }
>
> +#if defined (HISTORY)
> +static void
> +unwind_set_current_prompt_level (void *x)
> +{
> +  set_current_prompt_level ((intptr_t) x);
> +}
> +#endif
> +
> +static void
> +unwind_pop_stream (void *ignored)
> +{
> +  pop_stream ();
> +}
> +
> +static void
> +unwind_parser_restore_alias (void *ignored)
> +{
> +  parser_restore_alias ();
> +}
> +
>  static void
>  parse_prologue (char *string, int flags, char *tag)
>  {
> @@ -238,7 +258,8 @@ parse_prologue (char *string, int flags, char *tag)
>    if (interactive_shell)
>      {
>        x = get_current_prompt_level ();
> -      add_unwind_protect (set_current_prompt_level, x);
> +      add_unwind_protect (unwind_set_current_prompt_level,
> +                         (void *) (intptr_t) x);
>      }
>
>    if (the_printed_command_except_trap)
> @@ -247,9 +268,9 @@ parse_prologue (char *string, int flags, char *tag)
>        add_unwind_protect (restore_lastcom, lastcom);
>      }
>
> -  add_unwind_protect (pop_stream, (char *)NULL);
> +  add_unwind_protect (unwind_pop_stream, NULL);
>    if (parser_expanding_alias ())
> -    add_unwind_protect (parser_restore_alias, (char *)NULL);
> +    add_unwind_protect (unwind_parser_restore_alias, NULL);
>
>    if (orig_string && ((flags & SEVAL_NOFREE) == 0))
>      add_unwind_protect (xfree, orig_string);
> @@ -455,8 +476,8 @@ parse_and_execute (char *string, const char
> *from_file, int flags)
>
>               bitmap = new_fd_bitmap (FD_BITMAP_SIZE);
>               begin_unwind_frame ("pe_dispose");
> -             add_unwind_protect (dispose_fd_bitmap, bitmap);
> -             add_unwind_protect (dispose_command, command);    /* XXX */
> +             add_unwind_protect (unwind_dispose_fd_bitmap, bitmap);
> +             add_unwind_protect (unwind_dispose_command, command); /* XXX
> */
>
>               global_command = (COMMAND *)NULL;
>
> diff --git a/builtins/fc.def b/builtins/fc.def
> index 06f0f610..94a5ded6 100644
> --- a/builtins/fc.def
> +++ b/builtins/fc.def
> @@ -167,7 +167,7 @@ static void fc_addhist (char *);
>  #endif
>
>  static void
> -set_verbose_flag (void)
> +set_verbose_flag (void *ignored)
>  {
>    echo_input_at_read = verbose_flag;
>  }
> @@ -180,6 +180,12 @@ set_verbose_flag (void)
>  #  define POSIX_FC_EDIT_COMMAND "${FCEDIT:-${EDITOR:-ed}}"
>  #endif
>
> +static void
> +unwind_unlink (void *filename)
> +{
> +  unlink ((const char *) filename);
> +}
> +
>  int
>  fc_builtin (WORD_LIST *list)
>  {
> @@ -525,7 +531,7 @@ fc_builtin (WORD_LIST *list)
>       will be echoed as they are read by the parser. */
>    begin_unwind_frame ("fc builtin");
>    add_unwind_protect (xfree, fn);
> -  add_unwind_protect (unlink, fn);
> +  add_unwind_protect (unwind_unlink, fn);
>    add_unwind_protect (set_verbose_flag, (char *)NULL);
>    unwind_protect_int (suppress_debug_trap_verbose);
>    echo_input_at_read = 1;
> diff --git a/builtins/jobs.def b/builtins/jobs.def
> index 316f34bd..fdaa0b8b 100644
> --- a/builtins/jobs.def
> +++ b/builtins/jobs.def
> @@ -206,7 +206,7 @@ execute_list_with_replacements (WORD_LIST *list)
>    command->flags |= CMD_INHIBIT_EXPANSION;
>    command->value.Simple->flags |= CMD_INHIBIT_EXPANSION;
>
> -  add_unwind_protect (dispose_command, command);
> +  add_unwind_protect (unwind_dispose_command, command);
>    result = execute_command (command);
>    dispose_command (command);
>
> diff --git a/builtins/mkbuiltins.c b/builtins/mkbuiltins.c
> index 78c7a999..acc55356 100644
> --- a/builtins/mkbuiltins.c
> +++ b/builtins/mkbuiltins.c
> @@ -452,7 +452,6 @@ array_free (ARRAY *array)
>  /* **************************************************************** */
>
>  /* The definition of a function. */
> -typedef int Function ();
>  typedef int mk_handler_func_t (char *, DEF_FILE *, char *);
>
>  /* Structure handles processor directives. */
> diff --git a/builtins/read.def b/builtins/read.def
> index e0f73749..9b19ff95 100644
> --- a/builtins/read.def
> +++ b/builtins/read.def
> @@ -119,11 +119,11 @@ struct ttsave
>  };
>
>  #if defined (READLINE)
> -static void reset_attempted_completion_function (char *);
> +static void reset_attempted_completion_function (void *);
>  static int set_itext (void);
>  static char *edit_line (char *, char *);
>  static void set_eol_delim (int);
> -static void reset_eol_delim (char *);
> +static void reset_eol_delim (void *);
>  static void set_readline_timeout (sh_timer *t, time_t, long);
>  #endif
>  static SHELL_VAR *bind_read_variable (char *, char *, int);
> @@ -131,6 +131,7 @@ static SHELL_VAR *bind_read_variable (char *, char *,
> int);
>  static int read_mbchar (int, char *, int, int, int);
>  #endif
>  static void ttyrestore (struct ttsave *);
> +static void unwind_ttyrestore (void *);
>
>  static sighandler sigalrm (int);
>  static void reset_timeout (void);
> @@ -168,6 +169,11 @@ reset_timeout (void)
>  #endif
>    read_timeout = 0;
>  }
> +static void
> +unwind_reset_timeout (void *ignored)
> +{
> +  reset_timeout ();
> +}
>
>  void
>  check_read_timeout (void)
> @@ -192,6 +198,14 @@ read_builtin_timeout (int fd)
>  #endif
>  }
>
> +#if defined (READLINE)
> +static void
> +unwind_bashline_reset_event_hook (void *ignored)
> +{
> +  bashline_reset_event_hook ();
> +}
> +#endif
> +
>  /* 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
> @@ -509,12 +523,12 @@ read_builtin (WORD_LIST *list)
>         }
>        if (interactive_shell == 0)
>         initialize_terminating_signals ();
> -      add_unwind_protect (reset_timeout, (char *)NULL);
> +      add_unwind_protect (unwind_reset_timeout, NULL);
>  #if defined (READLINE)
>        if (edit)
>         {
>           add_unwind_protect (reset_attempted_completion_function, (char
> *)NULL);
> -         add_unwind_protect (bashline_reset_event_hook, (char *)NULL);
> +         add_unwind_protect (unwind_bashline_reset_event_hook, NULL);
>           set_readline_timeout (read_timeout, tmsec, tmusec);
>         }
>        else
> @@ -555,7 +569,7 @@ read_builtin (WORD_LIST *list)
>           if (i < 0)
>             sh_ttyerror (1);
>           tty_modified = 1;
> -         add_unwind_protect ((Function *)ttyrestore, (char *)&termsave);
> +         add_unwind_protect (unwind_ttyrestore, &termsave);
>           if (interactive_shell == 0)
>             initialize_terminating_signals ();
>         }
> @@ -573,7 +587,7 @@ read_builtin (WORD_LIST *list)
>         sh_ttyerror (1);
>
>        tty_modified = 1;
> -      add_unwind_protect ((Function *)ttyrestore, (char *)&termsave);
> +      add_unwind_protect (unwind_ttyrestore, &termsave);
>        if (interactive_shell == 0)
>         initialize_terminating_signals ();
>      }
> @@ -1113,6 +1127,11 @@ ttyrestore (struct ttsave *ttp)
>    ttsetattr (ttp->fd, &(ttp->attrs));
>    tty_modified = 0;
>  }
> +static void
> +unwind_ttyrestore (void *ttp)
> +{
> +  ttyrestore (ttp);
> +}
>
>  void
>  read_tty_cleanup (void)
> @@ -1133,7 +1152,7 @@ static rl_hook_func_t *old_startup_hook;
>  static char *deftext;
>
>  static void
> -reset_attempted_completion_function (char *cp)
> +reset_attempted_completion_function (void *ignored)
>  {
>    if (rl_attempted_completion_function == 0 &&
> old_attempted_completion_function)
>      rl_attempted_completion_function = old_attempted_completion_function;
> @@ -1241,7 +1260,7 @@ set_eol_delim (int c)
>  }
>
>  static void
> -reset_eol_delim (char *cp)
> +reset_eol_delim (void *ignored)
>  {
>    Keymap cmap;
>
> diff --git a/builtins/source.def b/builtins/source.def
> index c15dbc51..999557ca 100644
> --- a/builtins/source.def
> +++ b/builtins/source.def
> @@ -80,7 +80,7 @@ $END
>  extern int errno;
>  #endif /* !errno */
>
> -static void maybe_pop_dollar_vars (void);
> +static void maybe_pop_dollar_vars (void *);
>
>  /* If non-zero, `.' uses $PATH to look up the script to be sourced. */
>  int source_uses_path = 1;
> @@ -96,7 +96,7 @@ int source_searches_cwd = 1;
>     not executing a shell function, we leave the new values alone and free
>     the saved values. */
>  static void
> -maybe_pop_dollar_vars (void)
> +maybe_pop_dollar_vars (void *ignored)
>  {
>    if (variable_context == 0 && (dollar_vars_changed () & ARGS_SETBLTIN))
>      dispose_saved_dollar_vars ();
> @@ -170,7 +170,7 @@ source_builtin (WORD_LIST *list)
>    if (list->next)
>      {
>        push_dollar_vars ();
> -      add_unwind_protect ((Function *)maybe_pop_dollar_vars, (char
> *)NULL);
> +      add_unwind_protect (maybe_pop_dollar_vars, NULL);
>        if (debugging_mode || shell_compatibility_level <= 44)
>         init_bash_argv ();      /* Initialize BASH_ARGV and BASH_ARGC */
>        remember_args (list->next, 1);
> diff --git a/configure.ac b/configure.ac
> index 343320ec..0533ae4b 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -964,6 +964,7 @@ AC_TYPE_MODE_T
>  AC_TYPE_UID_T
>  AC_TYPE_PID_T
>  AC_TYPE_SIZE_T
> +AC_TYPE_INTPTR_T
>  AC_TYPE_UINTPTR_T
>
>  AC_CHECK_TYPE(ssize_t, int)
> diff --git a/dispose_cmd.c b/dispose_cmd.c
> index a79201ab..227bb300 100644
> --- a/dispose_cmd.c
> +++ b/dispose_cmd.c
> @@ -203,6 +203,11 @@ dispose_command (COMMAND *command)
>      }
>    free (command);
>  }
> +void
> +unwind_dispose_command (void *command)
> +{
> +  dispose_command (command);
> +}
>
>  #if defined (COND_COMMAND)
>  /* How to free a node in a conditional command. */
> @@ -271,6 +276,11 @@ dispose_words (WORD_LIST *list)
>  #endif
>      }
>  }
> +void
> +unwind_dispose_words (void *list)
> +{
> +  dispose_words (list);
> +}
>
>  #ifdef INCLUDE_UNUSED
>  /* How to dispose of an array of pointers to char.  This is identical to
> diff --git a/dispose_cmd.h b/dispose_cmd.h
> index 0e6eabc9..2c0cdf88 100644
> --- a/dispose_cmd.h
> +++ b/dispose_cmd.h
> @@ -24,9 +24,11 @@
>  #include "stdc.h"
>
>  extern void dispose_command (COMMAND *);
> +extern void unwind_dispose_command (void *);
>  extern void dispose_word_desc (WORD_DESC *);
>  extern void dispose_word (WORD_DESC *);
>  extern void dispose_words (WORD_LIST *);
> +extern void unwind_dispose_words (void *);
>  extern void dispose_word_array (char **);
>  extern void dispose_redirects (REDIRECT *);
>
> diff --git a/execute_cmd.c b/execute_cmd.c
> index 6546ea8c..6236146d 100644
> --- a/execute_cmd.c
> +++ b/execute_cmd.c
> @@ -123,7 +123,7 @@ static int shell_control_structure (enum command_type);
>  static void cleanup_redirects (REDIRECT *);
>
>  #if defined (JOB_CONTROL)
> -static int restore_signal_mask (sigset_t *);
> +static void restore_signal_mask (void *);
>  #endif
>
>  static int builtin_status (int);
> @@ -343,6 +343,11 @@ dispose_fd_bitmap (struct fd_bitmap *fdbp)
>    FREE (fdbp->bitmap);
>    free (fdbp);
>  }
> +void
> +unwind_dispose_fd_bitmap (void *fdbp)
> +{
> +  dispose_fd_bitmap (fdbp);
> +}
>
>  void
>  close_fd_bitmap (struct fd_bitmap *fdbp)
> @@ -359,6 +364,17 @@ close_fd_bitmap (struct fd_bitmap *fdbp)
>           }
>      }
>  }
> +static void
> +unwind_close_fd_bitmap (void *fdbp)
> +{
> +  close_fd_bitmap (fdbp);
> +}
> +
> +void
> +unwind_close (void *fd)
> +{
> +  close ((intptr_t) fd);
> +}
>
>  /* Return the line number of the currently executing command. */
>  int
> @@ -403,7 +419,7 @@ execute_command (COMMAND *command)
>    current_fds_to_close = (struct fd_bitmap *)NULL;
>    bitmap = new_fd_bitmap (FD_BITMAP_DEFAULT_SIZE);
>    begin_unwind_frame ("execute-command");
> -  add_unwind_protect (dispose_fd_bitmap, (char *)bitmap);
> +  add_unwind_protect (unwind_dispose_fd_bitmap, bitmap);
>
>    /* Just do the command, but not asynchronously. */
>    result = execute_command_internal (command, 0, NO_PIPE, NO_PIPE,
> bitmap);
> @@ -462,6 +478,16 @@ cleanup_redirects (REDIRECT *list)
>    do_redirections (list, RX_ACTIVE);
>    dispose_redirects (list);
>  }
> +static void
> +unwind_cleanup_redirects (void *list)
> +{
> +  cleanup_redirects (list);
> +}
> +static void
> +unwind_dispose_redirects (void *list)
> +{
> +  dispose_redirects (list);
> +}
>
>  void
>  undo_partial_redirects (void)
> @@ -505,10 +531,10 @@ dispose_partial_redirects (void)
>  #if defined (JOB_CONTROL)
>  /* A function to restore the signal mask to its proper value when the
> shell
>     is interrupted or errors occur while creating a pipeline. */
> -static int
> -restore_signal_mask (sigset_t *set)
> +static void
> +restore_signal_mask (void *set)
>  {
> -  return (sigprocmask (SIG_SETMASK, set, (sigset_t *)NULL));
> +  sigprocmask (SIG_SETMASK, set, NULL);
>  }
>  #endif /* JOB_CONTROL */
>
> @@ -570,7 +596,7 @@ execute_command_internal (COMMAND *command, int
> asynchronous, int pipe_in, int p
>    volatile int save_line_number;
>  #if defined (PROCESS_SUBSTITUTION)
>    volatile int ofifo, nfifo, osize, saved_fifo;
> -  volatile void *ofifo_list;
> +  void *ofifo_list;
>  #endif
>
>    if (breaking || continuing)
> @@ -791,7 +817,7 @@ execute_command_internal (COMMAND *command, int
> asynchronous, int pipe_in, int p
>  #if defined (PROCESS_SUBSTITUTION)
>        if (saved_fifo)
>         {
> -         free ((void *)ofifo_list);
> +         free (ofifo_list);
>            discard_unwind_frame ("internal_fifos");
>         }
>  #endif
> @@ -826,10 +852,10 @@ execute_command_internal (COMMAND *command, int
> asynchronous, int pipe_in, int p
>      begin_unwind_frame ("loop_redirections");
>
>    if (my_undo_list)
> -    add_unwind_protect ((Function *)cleanup_redirects, my_undo_list);
> +    add_unwind_protect (unwind_cleanup_redirects, my_undo_list);
>
>    if (exec_undo_list)
> -    add_unwind_protect ((Function *)dispose_redirects, exec_undo_list);
> +    add_unwind_protect (unwind_dispose_redirects, exec_undo_list);
>
>    QUIT;
>
> @@ -1103,8 +1129,8 @@ execute_command_internal (COMMAND *command, int
> asynchronous, int pipe_in, int p
>      {
>        nfifo = num_fifos ();
>        if (nfifo > ofifo)
> -       close_new_fifos ((void *)ofifo_list, osize);
> -      free ((void *)ofifo_list);
> +       close_new_fifos (ofifo_list, osize);
> +      free (ofifo_list);
>        discard_unwind_frame ("internal_fifos");
>      }
>  #endif
> @@ -2437,12 +2463,27 @@ restore_stdin (int s)
>        close (s);
>      }
>  }
> +static void
> +unwind_restore_stdin (void *s)
> +{
> +  restore_stdin ((intptr_t) s);
> +}
> +static void
> +unwind_set_error_trap (void *command)
> +{
> +  set_error_trap (command);
> +}
> +static void
> +unwind_merge_temporary_env (void *ignored)
> +{
> +  merge_temporary_env ();
> +}
>
>  /* Catch-all cleanup function for lastpipe code for unwind-protects */
>  static void
> -lastpipe_cleanup (int s)
> +lastpipe_cleanup (void *s)
>  {
> -  set_jobs_list_frozen (s);
> +  set_jobs_list_frozen ((intptr_t) s);
>  }
>
>  static int
> @@ -2516,12 +2557,12 @@ execute_pipeline (COMMAND *command, int
> asynchronous, int pipe_in, int pipe_out,
>          unwind-protects are run, and the storage used for the
>          bitmaps freed up. */
>        begin_unwind_frame ("pipe-file-descriptors");
> -      add_unwind_protect (dispose_fd_bitmap, fd_bitmap);
> -      add_unwind_protect (close_fd_bitmap, fd_bitmap);
> +      add_unwind_protect (unwind_dispose_fd_bitmap, fd_bitmap);
> +      add_unwind_protect (unwind_close_fd_bitmap, fd_bitmap);
>        if (prev >= 0)
> -       add_unwind_protect (close, prev);
> +       add_unwind_protect (unwind_close, (void *) (intptr_t) prev);
>        dummyfd = fildes[1];
> -      add_unwind_protect (close, dummyfd);
> +      add_unwind_protect (unwind_close, (void *) (intptr_t) dummyfd);
>
>  #if defined (JOB_CONTROL)
>        add_unwind_protect (restore_signal_mask, &oset);
> @@ -2568,11 +2609,13 @@ execute_pipeline (COMMAND *command, int
> asynchronous, int pipe_in, int pipe_out,
>         {
>           do_piping (prev, pipe_out);
>           prev = NO_PIPE;
> -         add_unwind_protect (restore_stdin, lstdin);
> +         add_unwind_protect (unwind_restore_stdin,
> +                             (void *) (intptr_t) lstdin);
>           lastpipe_flag = 1;
>           old_frozen = freeze_jobs_list ();
>           lastpipe_jid = stop_pipeline (0, (COMMAND *)NULL);    /* XXX */
> -         add_unwind_protect (lastpipe_cleanup, old_frozen);
> +         add_unwind_protect (lastpipe_cleanup,
> +                             (void *) (intptr_t) old_frozen);
>  #if defined (JOB_CONTROL)
>           UNBLOCK_CHILD (oset);         /* XXX */
>  #endif
> @@ -2581,7 +2624,7 @@ execute_pipeline (COMMAND *command, int
> asynchronous, int pipe_in, int pipe_out,
>         cmd->flags |= CMD_LASTPIPE;
>      }
>    if (prev >= 0)
> -    add_unwind_protect (close, prev);
> +    add_unwind_protect (unwind_close, (void *) (intptr_t) prev);
>
>    exec_result = execute_command_internal (cmd, asynchronous, prev,
> pipe_out, fds_to_close);
>
> @@ -2841,14 +2884,14 @@ execute_for_command (FOR_COM *for_command)
>    list = releaser = expand_words_no_vars (for_command->map_list);
>
>    begin_unwind_frame ("for");
> -  add_unwind_protect (dispose_words, releaser);
> +  add_unwind_protect (unwind_dispose_words, releaser);
>
>  #if 0
>    if (lexical_scoping)
>      {
>        old_value = copy_variable (find_variable (identifier));
>        if (old_value)
> -       add_unwind_protect (dispose_variable, old_value);
> +       add_unwind_protect (unwind_dispose_variable, old_value);
>      }
>  #endif
>
> @@ -3375,7 +3418,7 @@ execute_select_command (SELECT_COM *select_command)
>      }
>
>    begin_unwind_frame ("select");
> -  add_unwind_protect (dispose_words, releaser);
> +  add_unwind_protect (unwind_dispose_words, releaser);
>
>    if (select_command->flags & CMD_IGNORE_RETURN)
>      select_command->action->flags |= CMD_IGNORE_RETURN;
> @@ -4539,7 +4582,7 @@ itrace("execute_simple_command: posix mode tempenv
> assignment error");
>        builtin = 0;
>      }
>
> -  add_unwind_protect (dispose_words, words);
> +  add_unwind_protect (unwind_dispose_words, words);
>    QUIT;
>
>    /* Bind the last word in this command to "$_" after execution. */
> @@ -4798,7 +4841,7 @@ execute_builtin (sh_builtin_func_t *builtin,
> WORD_LIST *words, int flags, int su
>         {
>           error_trap = savestring (error_trap);
>           add_unwind_protect (xfree, error_trap);
> -         add_unwind_protect (set_error_trap, error_trap);
> +         add_unwind_protect (unwind_set_error_trap, error_trap);
>           restore_default_signal (ERROR_TRAP);
>         }
>        exit_immediately_on_error = 0;
> @@ -4838,7 +4881,7 @@ execute_builtin (sh_builtin_func_t *builtin,
> WORD_LIST *words, int flags, int su
>           if (flags & CMD_COMMAND_BUILTIN)
>             should_keep = 0;
>           if (subshell == 0)
> -           add_unwind_protect (pop_scope, should_keep ? "1" : 0);
> +           add_unwind_protect (pop_scope, (void *) (intptr_t)
> should_keep);
>            temporary_env = (HASH_TABLE *)NULL;
>         }
>      }
> @@ -4877,7 +4920,7 @@ execute_builtin (sh_builtin_func_t *builtin,
> WORD_LIST *words, int flags, int su
>    if (posixly_correct && subshell == 0 && builtin == return_builtin &&
> (flags & CMD_COMMAND_BUILTIN) == 0 && temporary_env)
>      {
>        begin_unwind_frame ("return_temp_env");
> -      add_unwind_protect (merge_temporary_env, (char *)NULL);
> +      add_unwind_protect (unwind_merge_temporary_env, NULL);
>      }
>
>    executing_builtin++;
> @@ -4908,8 +4951,9 @@ execute_builtin (sh_builtin_func_t *builtin,
> WORD_LIST *words, int flags, int su
>  }
>
>  static void
> -maybe_restore_getopt_state (sh_getopt_state_t *gs)
> +maybe_restore_getopt_state (void *arg)
>  {
> +  sh_getopt_state_t *gs = arg;
>    /* If we have a local copy of OPTIND and it's at the right (current)
>       context, then we restore getopt's internal state.  If not, we just
>       let it go.  We know there is a local OPTIND if gs->gs_flags & 1.
> @@ -4936,6 +4980,11 @@ restore_funcarray_state (struct func_array_state
> *fa)
>
>    free (fa);
>  }
> +void
> +unwind_restore_funcarray_state (void *fa)
> +{
> +  return restore_funcarray_state (fa);
> +}
>  #endif
>
>  static int
> @@ -4996,13 +5045,13 @@ execute_function (SHELL_VAR *var, WORD_LIST
> *words, int flags, struct fd_bitmap
>          local variables may cause the restore of a local declaration of
>          OPTIND to force a getopts state reset. */
>        add_unwind_protect (maybe_restore_getopt_state, gs);
> -      add_unwind_protect (pop_context, (char *)NULL);
> +      add_unwind_protect (pop_context, NULL);
>        unwind_protect_int (line_number);
>        unwind_protect_int (line_number_for_err_trap);
>        unwind_protect_int (function_line_number);
>        unwind_protect_int (return_catch_flag);
>        unwind_protect_jmp_buf (return_catch);
> -      add_unwind_protect (dispose_command, (char *)tc);
> +      add_unwind_protect (unwind_dispose_command, tc);
>        unwind_protect_pointer (this_shell_function);
>        unwind_protect_int (funcnest);
>        unwind_protect_int (loop_level);
> @@ -5085,7 +5134,7 @@ execute_function (SHELL_VAR *var, WORD_LIST *words,
> int flags, struct fd_bitmap
>    fa->funcname_a = (ARRAY *)funcname_a;
>    fa->funcname_v = funcname_v;
>    if (subshell == 0)
> -    add_unwind_protect (restore_funcarray_state, fa);
> +    add_unwind_protect (unwind_restore_funcarray_state, fa);
>  #endif
>
>    /* The temporary environment for a function is supposed to apply to
> @@ -5103,7 +5152,7 @@ execute_function (SHELL_VAR *var, WORD_LIST *words,
> int flags, struct fd_bitmap
>      {
>        push_args (words->next);
>        if (subshell == 0)
> -       add_unwind_protect (pop_args, 0);
> +       add_unwind_protect (unwind_pop_args, NULL);
>      }
>
>    /* Number of the line on which the function body starts. */
> @@ -5202,7 +5251,7 @@ execute_shell_function (SHELL_VAR *var, WORD_LIST
> *words)
>
>    bitmap = new_fd_bitmap (FD_BITMAP_DEFAULT_SIZE);
>    begin_unwind_frame ("execute-shell-function");
> -  add_unwind_protect (dispose_fd_bitmap, (char *)bitmap);
> +  add_unwind_protect (unwind_dispose_fd_bitmap, bitmap);
>
>    ret = execute_function (var, words, 0, bitmap, 0, 0);
>
> @@ -5383,7 +5432,7 @@ execute_builtin_or_function (WORD_LIST *words,
>    if (saved_undo_list)
>      {
>        begin_unwind_frame ("saved-redirects");
> -      add_unwind_protect (cleanup_redirects, (char *)saved_undo_list);
> +      add_unwind_protect (unwind_cleanup_redirects, saved_undo_list);
>      }
>
>    redirection_undo_list = (REDIRECT *)NULL;
> diff --git a/execute_cmd.h b/execute_cmd.h
> index d9c3e7b1..ec86dee7 100644
> --- a/execute_cmd.h
> +++ b/execute_cmd.h
> @@ -71,7 +71,9 @@ extern SHELL_VAR *this_shell_function;
>
>  extern struct fd_bitmap *new_fd_bitmap (int);
>  extern void dispose_fd_bitmap (struct fd_bitmap *);
> +extern void unwind_dispose_fd_bitmap (void *);
>  extern void close_fd_bitmap (struct fd_bitmap *);
> +extern void unwind_close (void *);
>  extern int executing_line_number (void);
>  extern int execute_command (COMMAND *);
>  extern int execute_command_internal (COMMAND *, int, int, int, struct
> fd_bitmap *);
> @@ -118,6 +120,7 @@ extern void close_all_files (void);
>
>  #if defined (ARRAY_VARS)
>  extern void restore_funcarray_state (struct func_array_state *);
> +extern void unwind_restore_funcarray_state (void *);
>  #endif
>
>  extern void bind_lastarg (char *);
> diff --git a/general.h b/general.h
> index eb296f56..2b81f683 100644
> --- a/general.h
> +++ b/general.h
> @@ -159,9 +159,16 @@ typedef struct {
>  #endif /* !__GNUC__ */
>
>  /* String comparisons that possibly save a function call each. */
> -#define STREQ(a, b) ((a)[0] == (b)[0] && strcmp(a, b) == 0)
> -#define STREQN(a, b, n) ((n == 0) ? (1) \
> -                                 : ((a)[0] == (b)[0] && strncmp(a, b, n)
> == 0))
> +static inline int
> +STREQ (const char *a, const char *b)
> +{
> +  return a[0] == b[0] && strcmp (a, b) == 0;
> +}
> +static inline int
> +STREQN (const char *a, const char *b, size_t n)
> +{
> +  return !n || (a[0] == b[0] && strncmp (a, b, n) == 0);
> +}
>
>  /* More convenience definitions that possibly save system or libc calls.
> */
>  #define STRLEN(s) (((s) && (s)[0]) ? ((s)[1] ? ((s)[2] ? strlen(s) : 2) :
> 1) : 0)
> @@ -186,15 +193,6 @@ typedef struct {
>        } \
>    } while (0)
>
> -/* Function pointers can be declared as (Function *)foo. */
> -#if !defined (_FUNCTION_DEF)
> -#  define _FUNCTION_DEF
> -typedef int Function ();
> -typedef void VFunction ();
> -typedef char *CPFunction ();           /* no longer used */
> -typedef char **CPPFunction ();         /* no longer used */
> -#endif /* _FUNCTION_DEF */
> -
>  #ifndef SH_FUNCTION_TYPEDEF
>  #  define SH_FUNCTION_TYPEDEF
>
> diff --git a/lib/readline/rltypedefs.h b/lib/readline/rltypedefs.h
> index 16365492..b6ebcec2 100644
> --- a/lib/readline/rltypedefs.h
> +++ b/lib/readline/rltypedefs.h
> @@ -26,27 +26,6 @@
>  extern "C" {
>  #endif
>
> -/* Old-style, attempt to mark as deprecated in some way people will
> notice. */
> -
> -#if !defined (_FUNCTION_DEF)
> -#  define _FUNCTION_DEF
> -
> -#if defined(__GNUC__) || defined(__clang__)
> -typedef int Function () __attribute__((deprecated));
> -typedef void VFunction () __attribute__((deprecated));
> -typedef char *CPFunction () __attribute__((deprecated));
> -typedef char **CPPFunction () __attribute__((deprecated));
> -#else
> -typedef int Function ();
> -typedef void VFunction ();
> -typedef char *CPFunction ();
> -typedef char **CPPFunction ();
> -#endif
> -
> -#endif /* _FUNCTION_DEF */
> -
> -/* New style. */
> -
>  #if !defined (_RL_FUNCTION_TYPEDEF)
>  #  define _RL_FUNCTION_TYPEDEF
>
> diff --git a/pcomplete.c b/pcomplete.c
> index e79b8a71..22e079f9 100644
> --- a/pcomplete.c
> +++ b/pcomplete.c
> @@ -134,7 +134,7 @@ static char *pcomp_filename_completion_function (const
> char *, int);
>  static SHELL_VAR *bind_comp_words (WORD_LIST *);
>  #endif
>  static void bind_compfunc_variables (char *, int, WORD_LIST *, int, int);
> -static void unbind_compfunc_variables (int);
> +static void unbind_compfunc_variables (void *);
>  static WORD_LIST *build_arg_list (const char *, const char *, const char
> *, WORD_LIST *, int);
>  static WORD_LIST *command_line_to_word_list (char *, int, int, int *, int
> *);
>
> @@ -981,7 +981,7 @@ bind_compfunc_variables (char *line, int ind,
> WORD_LIST *lwords, int cw, int exp
>  }
>
>  static void
> -unbind_compfunc_variables (int exported)
> +unbind_compfunc_variables (void *exported)
>  {
>    unbind_variable_noref ("COMP_LINE");
>    unbind_variable_noref ("COMP_POINT");
> @@ -1034,6 +1034,18 @@ build_arg_list (const char *cmd, const char *cname,
> const char *text, WORD_LIST
>    return ret;
>  }
>
> +static void
> +unwind_restore_parser_state (void *ps)
> +{
> +  restore_parser_state (ps);
> +}
> +
> +static void
> +unwind_rl_set_signals (void *ignored)
> +{
> +  rl_set_signals ();
> +}
> +
>  /* Build a command string with
>         $0 == cs->funcname      (function to execute for completion list)
>         $1 == command name      (command being completed)
> @@ -1090,12 +1102,12 @@ gen_shell_function_matches (COMPSPEC *cs, const
> char *cmd, const char *text,
>    pps = &ps;
>    save_parser_state (pps);
>    begin_unwind_frame ("gen-shell-function-matches");
> -  add_unwind_protect (restore_parser_state, (char *)pps);
> -  add_unwind_protect (dispose_words, (char *)cmdlist);
> -  add_unwind_protect (unbind_compfunc_variables, (char *)0);
> +  add_unwind_protect (unwind_restore_parser_state, pps);
> +  add_unwind_protect (unwind_dispose_words, cmdlist);
> +  add_unwind_protect (unbind_compfunc_variables, NULL);
>    if (local_compgen == 0)
>      {
> -      add_unwind_protect (rl_set_signals, (char *)NULL);
> +      add_unwind_protect (unwind_rl_set_signals, NULL);
>        rl_clear_signals ();
>      }
>
> @@ -1205,7 +1217,7 @@ gen_command_matches (COMPSPEC *cs, const char *cmd,
> const char *text,
>    /* Now clean up and destroy everything. */
>    dispose_words (cmdlist);
>    free (cscmd);
> -  unbind_compfunc_variables (1);
> +  unbind_compfunc_variables ("");
>
>    if (csbuf == 0 || *csbuf == '\0')
>      {
> diff --git a/print_cmd.c b/print_cmd.c
> index 2410b8a2..365692e5 100644
> --- a/print_cmd.c
> +++ b/print_cmd.c
> @@ -57,7 +57,7 @@ typedef void PFUNC (const char *, ...);
>  static void cprintf (const char *, ...)  __attribute__((__format__
> (printf, 1, 2)));
>  static void xprintf (const char *, ...)  __attribute__((__format__
> (printf, 1, 2)));
>
> -static void reset_locals (void);
> +static void reset_locals (void *);
>  static void newline (char *);
>  static void indent (int);
>  static void semicolon (void);
> @@ -1241,7 +1241,7 @@ print_redirection (REDIRECT *redirect)
>  }
>
>  static void
> -reset_locals (void)
> +reset_locals (void *unused)
>  {
>    inside_function_def = 0;
>    indentation = 0;
> diff --git a/subst.c b/subst.c
> index f45e29b8..3e5966c7 100644
> --- a/subst.c
> +++ b/subst.c
> @@ -6960,7 +6960,7 @@ command_substitute (char *string, int quoted, int
> flags)
>
>        begin_unwind_frame ("read-comsub");
>        dummyfd = fildes[0];
> -      add_unwind_protect (close, dummyfd);
> +      add_unwind_protect (unwind_close, (void *) (intptr_t) dummyfd);
>
>        /* Block SIGINT while we're reading from the pipe. If the child
>          process gets a SIGINT, it will either handle it or die, and the
> diff --git a/trap.c b/trap.c
> index 07e7ddec..0bfa338c 100644
> --- a/trap.c
> +++ b/trap.c
> @@ -652,10 +652,10 @@ set_sigchld_trap (const char *command_string)
>     reset the disposition to the default and not have the original signal
>     accidentally restored, undoing the user's command. */
>  void
> -maybe_set_sigchld_trap (const char *command_string)
> +maybe_set_sigchld_trap (void *command_string)
>  {
>    if ((sigmodes[SIGCHLD] & SIG_TRAPPED) == 0 && trap_list[SIGCHLD] ==
> (char *)IMPOSSIBLE_TRAP_HANDLER)
> -    set_signal (SIGCHLD, command_string);
> +    set_signal (SIGCHLD, (const char *) command_string);
>  }
>
>  /* Temporarily set the SIGCHLD trap string to IMPOSSIBLE_TRAP_HANDLER.
> Used
> @@ -705,7 +705,7 @@ set_debug_trap (const char *command)
>     SIG_TRAPPED will be set and we don't bother restoring the original
> trap string.
>     This is used by both functions and the source builtin. */
>  void
> -maybe_set_debug_trap (const char *command)
> +maybe_set_debug_trap (void *command)
>  {
>    trap_if_untrapped (DEBUG_TRAP, command);
>  }
> @@ -717,7 +717,7 @@ set_error_trap (const char *command)
>  }
>
>  void
> -maybe_set_error_trap (const char *command)
> +maybe_set_error_trap (void *command)
>  {
>    trap_if_untrapped (ERROR_TRAP, command);
>  }
> @@ -729,7 +729,7 @@ set_return_trap (const char *command)
>  }
>
>  void
> -maybe_set_return_trap (const char *command)
> +maybe_set_return_trap (void *command)
>  {
>    trap_if_untrapped (RETURN_TRAP, command);
>  }
> diff --git a/trap.h b/trap.h
> index e031e5fe..048f65ca 100644
> --- a/trap.h
> +++ b/trap.h
> @@ -73,7 +73,7 @@ extern void initialize_traps (void);
>  extern void run_pending_traps (void);
>
>  extern void queue_sigchld_trap (int);
> -extern void maybe_set_sigchld_trap (const char *);
> +extern void maybe_set_sigchld_trap (void *);
>  extern void set_impossible_sigchld_trap (void);
>  extern void set_sigchld_trap (const char *);
>
> @@ -81,9 +81,9 @@ extern void set_debug_trap (const char *);
>  extern void set_error_trap (const char *);
>  extern void set_return_trap (const char *);
>
> -extern void maybe_set_debug_trap (const char *);
> -extern void maybe_set_error_trap (const char *);
> -extern void maybe_set_return_trap (const char *);
> +extern void maybe_set_debug_trap (void *);
> +extern void maybe_set_error_trap (void *);
> +extern void maybe_set_return_trap (void *);
>
>  extern void set_sigint_trap (const char *);
>  extern void set_signal (int, const char *);
> diff --git a/unwind_prot.c b/unwind_prot.c
> index c471b98a..3b5ce215 100644
> --- a/unwind_prot.c
> +++ b/unwind_prot.c
> @@ -65,11 +65,11 @@ typedef struct {
>  typedef union uwp {
>    struct uwp_head {
>      union uwp *next;
> -    Function *cleanup;
> +    void (*cleanup) (void *);
>    } head;
>    struct {
>      struct uwp_head uwp_head;
> -    char *v;
> +    void *v;
>    } arg;
>    struct {
>      struct uwp_head uwp_head;
> @@ -77,15 +77,14 @@ typedef union uwp {
>    } sv;
>  } UNWIND_ELT;
>
> -static void without_interrupts (VFunction *, char *, char *);
> -static void unwind_frame_discard_internal (char *, char *);
> -static void unwind_frame_run_internal (char *, char *);
> -static void add_unwind_protect_internal (Function *, char *);
> -static void remove_unwind_protect_internal (char *, char *);
> -static void run_unwind_protects_internal (char *, char *);
> -static void clear_unwind_protects_internal (char *, char *);
> -static inline void restore_variable (SAVED_VAR *);
> -static void unwind_protect_mem_internal (char *, char *);
> +static void unwind_frame_discard_internal (char *);
> +static void unwind_frame_run_internal (char *);
> +static void add_unwind_protect_internal (void (*) (void *), void *);
> +static void remove_unwind_protect_internal ();
> +static void run_unwind_protects_internal ();
> +static void clear_unwind_protects_internal (int);
> +static inline void restore_variable (void *);
> +static void unwind_protect_mem_internal (char *, int);
>
>  static UNWIND_ELT *unwind_protect_list = (UNWIND_ELT *)NULL;
>
> @@ -108,19 +107,11 @@ uwp_init (void)
>    ocache_create (uwcache, UNWIND_ELT, UWCACHESIZE);
>  }
>
> -/* Run a function without interrupts.  This relies on the fact that the
> -   FUNCTION cannot call QUIT (). */
> -static void
> -without_interrupts (VFunction *function, char *arg1, char *arg2)
> -{
> -  (*function)(arg1, arg2);
> -}
> -
>  /* Start the beginning of a region. */
>  void
>  begin_unwind_frame (char *tag)
>  {
> -  add_unwind_protect ((Function *)NULL, tag);
> +  add_unwind_protect (NULL, tag);
>  }
>
>  /* Discard the unwind protects back to TAG. */
> @@ -128,7 +119,7 @@ void
>  discard_unwind_frame (char *tag)
>  {
>    if (unwind_protect_list)
> -    without_interrupts (unwind_frame_discard_internal, tag, (char *)NULL);
> +    unwind_frame_discard_internal (tag);
>  }
>
>  /* Run the unwind protects back to TAG. */
> @@ -136,14 +127,14 @@ void
>  run_unwind_frame (char *tag)
>  {
>    if (unwind_protect_list)
> -    without_interrupts (unwind_frame_run_internal, tag, (char *)NULL);
> +    unwind_frame_run_internal (tag);
>  }
>
>  /* Add the function CLEANUP with ARG to the list of unwindable things. */
>  void
> -add_unwind_protect (Function *cleanup, char *arg)
> +add_unwind_protect (void (*cleanup) (void *), void *arg)
>  {
> -  without_interrupts (add_unwind_protect_internal, (char *)cleanup, arg);
> +  add_unwind_protect_internal (cleanup, arg);
>  }
>
>  /* Remove the top unwind protect from the list. */
> @@ -151,8 +142,7 @@ void
>  remove_unwind_protect (void)
>  {
>    if (unwind_protect_list)
> -    without_interrupts
> -      (remove_unwind_protect_internal, (char *)NULL, (char *)NULL);
> +    remove_unwind_protect_internal ();
>  }
>
>  /* Run the list of cleanup functions in unwind_protect_list. */
> @@ -160,22 +150,15 @@ void
>  run_unwind_protects (void)
>  {
>    if (unwind_protect_list)
> -    without_interrupts
> -      (run_unwind_protects_internal, (char *)NULL, (char *)NULL);
> +    run_unwind_protects_internal ();
>  }
>
>  /* Erase the unwind-protect list.  If flags is 1, free the elements. */
>  void
>  clear_unwind_protect_list (int flags)
>  {
> -  char *flag;
> -
>    if (unwind_protect_list)
> -    {
> -      flag = flags ? "" : (char *)NULL;
> -      without_interrupts
> -        (clear_unwind_protects_internal, flag, (char *)NULL);
> -    }
> +    clear_unwind_protects_internal (flags);
>  }
>
>  int
> @@ -206,7 +189,7 @@ unwind_protect_tag_on_stack (const char *tag)
>  /* **************************************************************** */
>
>  static void
> -add_unwind_protect_internal (Function *cleanup, char *arg)
> +add_unwind_protect_internal (void (*cleanup) (void *), void *arg)
>  {
>    UNWIND_ELT *elt;
>
> @@ -218,7 +201,7 @@ add_unwind_protect_internal (Function *cleanup, char
> *arg)
>  }
>
>  static void
> -remove_unwind_protect_internal (char *ignore1, char *ignore2)
> +remove_unwind_protect_internal ()
>  {
>    UNWIND_ELT *elt;
>
> @@ -231,24 +214,24 @@ remove_unwind_protect_internal (char *ignore1, char
> *ignore2)
>  }
>
>  static void
> -run_unwind_protects_internal (char *ignore1, char *ignore2)
> +run_unwind_protects_internal ()
>  {
> -  unwind_frame_run_internal ((char *) NULL, (char *) NULL);
> +  unwind_frame_run_internal (NULL);
>  }
>
>  static void
> -clear_unwind_protects_internal (char *flag, char *ignore)
> +clear_unwind_protects_internal (int flag)
>  {
>    if (flag)
>      {
>        while (unwind_protect_list)
> -       remove_unwind_protect_internal ((char *)NULL, (char *)NULL);
> +       remove_unwind_protect_internal ();
>      }
>    unwind_protect_list = (UNWIND_ELT *)NULL;
>  }
>
>  static void
> -unwind_frame_discard_internal (char *tag, char *ignore)
> +unwind_frame_discard_internal (char *tag)
>  {
>    UNWIND_ELT *elt;
>    int found;
> @@ -275,13 +258,14 @@ unwind_frame_discard_internal (char *tag, char
> *ignore)
>     sv->desired_setting is a block of memory SIZE bytes long holding the
>     value itself.  This block of memory is copied back into the variable.
> */
>  static inline void
> -restore_variable (SAVED_VAR *sv)
> +restore_variable (void *arg)
>  {
> +  SAVED_VAR *sv = arg;
>    FASTCOPY (sv->desired_setting, sv->variable, sv->size);
>  }
>
>  static void
> -unwind_frame_run_internal (char *tag, char *ignore)
> +unwind_frame_run_internal (char *tag)
>  {
>    UNWIND_ELT *elt;
>    int found;
> @@ -303,7 +287,7 @@ unwind_frame_run_internal (char *tag, char *ignore)
>         }
>        else
>         {
> -         if (elt->head.cleanup == (Function *) restore_variable)
> +         if (elt->head.cleanup == restore_variable)
>             restore_variable (&elt->sv.v);
>           else
>             (*(elt->head.cleanup)) (elt->arg.v);
> @@ -316,19 +300,17 @@ unwind_frame_run_internal (char *tag, char *ignore)
>  }
>
>  static void
> -unwind_protect_mem_internal (char *var, char *psize)
> +unwind_protect_mem_internal (char *var, int size)
>  {
> -  int size;
>    size_t allocated;
>    UNWIND_ELT *elt;
>
> -  size = *(int *) psize;
>    allocated = size + offsetof (UNWIND_ELT, sv.v.desired_setting[0]);
>    if (allocated < sizeof (UNWIND_ELT))
>      allocated = sizeof (UNWIND_ELT);
>    elt = (UNWIND_ELT *)xmalloc (allocated);
>    elt->head.next = unwind_protect_list;
> -  elt->head.cleanup = (Function *) restore_variable;
> +  elt->head.cleanup = restore_variable;
>    elt->sv.v.variable = var;
>    elt->sv.v.size = size;
>    FASTCOPY (var, elt->sv.v.desired_setting, size);
> @@ -341,7 +323,7 @@ unwind_protect_mem_internal (char *var, char *psize)
>  void
>  unwind_protect_mem (char *var, int size)
>  {
> -  without_interrupts (unwind_protect_mem_internal, var, (char *) &size);
> +  unwind_protect_mem_internal (var, size);
>  }
>
>  #if defined (DEBUG)
> diff --git a/unwind_prot.h b/unwind_prot.h
> index 7493c22e..730512b8 100644
> --- a/unwind_prot.h
> +++ b/unwind_prot.h
> @@ -27,7 +27,7 @@ extern void uwp_init (void);
>  extern void begin_unwind_frame (char *);
>  extern void discard_unwind_frame (char *);
>  extern void run_unwind_frame (char *);
> -extern void add_unwind_protect (); /* Not portable to arbitrary C99
> hosts.  */
> +extern void add_unwind_protect (void (*) (void *), void *);
>  extern void remove_unwind_protect (void);
>  extern void run_unwind_protects (void);
>  extern void clear_unwind_protect_list (int);
> diff --git a/variables.c b/variables.c
> index 1d67cc8c..5e17a976 100644
> --- a/variables.c
> +++ b/variables.c
> @@ -5330,7 +5330,7 @@ push_exported_var (PTR_T data)
>     variables in its temporary environment. In the first case, we call
>     push_builtin_var, which does the right thing. */
>  void
> -pop_scope (int is_special)
> +pop_scope (void *is_special)
>  {
>    VAR_CONTEXT *vcxt, *ret;
>    int is_bltinenv;
> @@ -5354,7 +5354,7 @@ pop_scope (int is_special)
>    FREE (vcxt->name);
>    if (vcxt->table)
>      {
> -      if (is_special)
> +      if ((intptr_t) is_special)
>         hash_flush (vcxt->table, push_builtin_var);
>        else
>         hash_flush (vcxt->table, push_exported_var);
> @@ -5453,7 +5453,7 @@ push_context (char *name, int is_subshell,
> HASH_TABLE *tempvars)
>  /* Only called when subshell == 0, so we don't need to check, and can
>     unconditionally pop the dollar vars off the stack. */
>  void
> -pop_context (void)
> +pop_context (void *ignored)
>  {
>    pop_dollar_vars ();
>    variable_context--;
> @@ -5591,6 +5591,11 @@ pop_args (void)
>    array_dispose_element (ce);
>  #endif /* ARRAY_VARS && DEBUGGER */
>  }
> +void
> +unwind_pop_args (void *unused)
> +{
> +  pop_args ();
> +}
>
>  /*************************************************
>   *                                              *
> diff --git a/variables.h b/variables.h
> index 1616d455..fb603966 100644
> --- a/variables.h
> +++ b/variables.h
> @@ -345,12 +345,12 @@ extern void dispose_var_context (VAR_CONTEXT *);
>  extern VAR_CONTEXT *push_var_context (char *, int, HASH_TABLE *);
>  extern void pop_var_context (void);
>  extern VAR_CONTEXT *push_scope (int, HASH_TABLE *);
> -extern void pop_scope (int);
> +extern void pop_scope (void *);
>
>  extern void clear_dollar_vars (void);
>
>  extern void push_context (char *, int, HASH_TABLE *);
> -extern void pop_context (void);
> +extern void pop_context (void *);
>  extern void push_dollar_vars (void);
>  extern void pop_dollar_vars (void);
>  extern void dispose_saved_dollar_vars (void);
> @@ -359,6 +359,7 @@ extern void init_bash_argv (void);
>  extern void save_bash_argv (void);
>  extern void push_args (WORD_LIST *);
>  extern void pop_args (void);
> +extern void unwind_pop_args (void *);
>
>  extern void adjust_shell_level (int);
>  extern void non_unsettable (char *);
> --
> 2.39.2
>
>
>
>
>


reply via email to

[Prev in Thread] Current Thread [Next in Thread]