1 /* Functions to deal with the inferior being executed on GDB or
2    GDBserver.
3 
4    Copyright (C) 2019-2021 Free Software Foundation, Inc.
5 
6    This file is part of GDB.
7 
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 3 of the License, or
11    (at your option) any later version.
12 
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17 
18    You should have received a copy of the GNU General Public License
19    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
20 
21 #include "gdbsupport/common-defs.h"
22 #include "gdbsupport/common-inferior.h"
23 
24 /* See common-inferior.h.  */
25 
26 bool startup_with_shell = true;
27 
28 /* See common-inferior.h.  */
29 
30 std::string
construct_inferior_arguments(gdb::array_view<char * const> argv)31 construct_inferior_arguments (gdb::array_view<char * const> argv)
32 {
33   std::string result;
34 
35   if (startup_with_shell)
36     {
37 #ifdef __MINGW32__
38       /* This holds all the characters considered special to the
39 	 Windows shells.  */
40       static const char special[] = "\"!&*|[]{}<>?`~^=;, \t\n";
41       static const char quote = '"';
42 #else
43       /* This holds all the characters considered special to the
44 	 typical Unix shells.  We include `^' because the SunOS
45 	 /bin/sh treats it as a synonym for `|'.  */
46       static const char special[] = "\"!#$&*()\\|[]{}<>?'`~^; \t\n";
47       static const char quote = '\'';
48 #endif
49       for (int i = 0; i < argv.size (); ++i)
50 	{
51 	  if (i > 0)
52 	    result += ' ';
53 
54 	  /* Need to handle empty arguments specially.  */
55 	  if (argv[i][0] == '\0')
56 	    {
57 	      result += quote;
58 	      result += quote;
59 	    }
60 	  else
61 	    {
62 #ifdef __MINGW32__
63 	      bool quoted = false;
64 
65 	      if (strpbrk (argv[i], special))
66 		{
67 		  quoted = true;
68 		  result += quote;
69 		}
70 #endif
71 	      for (char *cp = argv[i]; *cp; ++cp)
72 		{
73 		  if (*cp == '\n')
74 		    {
75 		      /* A newline cannot be quoted with a backslash (it
76 			 just disappears), only by putting it inside
77 			 quotes.  */
78 		      result += quote;
79 		      result += '\n';
80 		      result += quote;
81 		    }
82 		  else
83 		    {
84 #ifdef __MINGW32__
85 		      if (*cp == quote)
86 #else
87 		      if (strchr (special, *cp) != NULL)
88 #endif
89 			result += '\\';
90 		      result += *cp;
91 		    }
92 		}
93 #ifdef __MINGW32__
94 	      if (quoted)
95 		result += quote;
96 #endif
97 	    }
98 	}
99     }
100   else
101     {
102       /* In this case we can't handle arguments that contain spaces,
103 	 tabs, or newlines -- see breakup_args().  */
104       for (char *arg : argv)
105 	{
106 	  char *cp = strchr (arg, ' ');
107 	  if (cp == NULL)
108 	    cp = strchr (arg, '\t');
109 	  if (cp == NULL)
110 	    cp = strchr (arg, '\n');
111 	  if (cp != NULL)
112 	    error (_("can't handle command-line "
113 		     "argument containing whitespace"));
114 	}
115 
116       for (int i = 0; i < argv.size (); ++i)
117 	{
118 	  if (i > 0)
119 	    result += " ";
120 	  result += argv[i];
121 	}
122     }
123 
124   return result;
125 }
126