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 > > > >