On Thu, Jul 10, 2025 at 12:05 PM Nicolas Werner
<nicolas.wer...@hotmail.de> wrote:
>
> Users might be using a space in their build directory path. To allow
> specifying such a root for the module mapper started by GCC, we need the
> command to allow quotes. Previously quoting a path passed to the module
> mapper was not possible, so replace the custom argv parsing with
> wordexp(), which supports standard shell quoting rules.
>
> This also should fix PR110153, although my intention was really to fix
> passing parameters to the "--root" parameter.
>
> I'm somewhat unsure about using wordexp. This function seems to be
> referenced by libsanitizer already, but maybe "core" GCC can not depend
> on the function? Do I need to add any system checks? I think it is
> widely supported, but I am not that familiar with requirements regarding
> standard library functions.

wordexp is part of POSIX only. So I would avoid it.
gnulib says it is missing one some important hosts still:
https://www.gnu.org/software/gnulib/manual/html_node/wordexp.html

So I suspect we should avoid it. Maybe have a version included in libliberty?
Maybe there is some C++ std::string functions you could use instead?

Thanks,
Andrew

>
> PR c++/110153
>
> Signed-off-by: Nicolas Werner <nicolas.wer...@hotmail.de>
> ---
>  gcc/cp/mapper-client.cc | 36 +++++++++++++-----------------------
>  1 file changed, 13 insertions(+), 23 deletions(-)
>
> diff --git a/gcc/cp/mapper-client.cc b/gcc/cp/mapper-client.cc
> index 9477feeee31..bf91b825bc0 100644
> --- a/gcc/cp/mapper-client.cc
> +++ b/gcc/cp/mapper-client.cc
> @@ -28,6 +28,7 @@ along with GCC; see the file COPYING3.  If not see
>  #define INCLUDE_VECTOR
>  #define INCLUDE_MAP
>  #include "system.h"
> +#include <wordexp.h>
>
>  #include "line-map.h"
>  #include "rich-location.h"
> @@ -59,29 +60,17 @@ spawn_mapper_program (char const **errmsg, std::string
> &name,
>    char *str = new char[name.size ()];
>    memcpy (str, name.c_str () + 1, name.size ());
>
> -  for (auto ptr = str; ; ++ptr)
> -    {
> -      while (*ptr == ' ')
> -       ptr++;
> -      if (!*ptr)
> -       break;
> -
> -      if (!arg_no)
> -       {
> -         /* @name means look in the compiler's install dir.  */
> -         if (ptr[0] == '@')
> -           ptr++;
> -         else
> -           full_program_name = nullptr;
> -       }
> -
> -      argv[arg_no++] = ptr;
> -      while (*ptr && *ptr != ' ')
> -       ptr++;
> -      if (!*ptr)
> -       break;
> -      *ptr = 0;
> -    }
> +  wordexp_t words = {};
> +  wordexp (str, &words, WRDE_UNDEF|WRDE_NOCMD);
> +  for (size_t i = 0; i < words.we_wordc && i < name.size () / 2 + 1; i++)
> +  {
> +    argv[i] = words.we_wordv[i];
> +    arg_no++;
> +  }
> +  if (arg_no && argv[0][0] == '@')
> +    argv[0] = argv[0] + 1;
> +  else
> +    full_program_name = nullptr;
>    argv[arg_no] = nullptr;
>
>    auto *pex = pex_init (PEX_USE_PIPES, progname, NULL);
> @@ -110,6 +99,7 @@ spawn_mapper_program (char const **errmsg, std::string
> &name,
>      }
>    delete[] str;
>    delete[] argv;
> +  wordfree (&words);
>
>    int fd_from = -1, fd_to = -1;
>    if (!*errmsg)
> --
> 2.49.0
>
>
>
>

Reply via email to