mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-20 13:46:30 +01:00
SystemExec: copy last argument from command line to argv[]
Make sure to copy any part of the command line after the last delimiter to argv[] when creating a SystemExec with an escaped command line. Conflicts: libs/pbd/system_exec.cc
This commit is contained in:
parent
f28e54aceb
commit
c35659c2ad
1 changed files with 87 additions and 0 deletions
|
|
@ -187,6 +187,93 @@ SystemExec::SystemExec (std::string c, char **a)
|
||||||
make_envp();
|
make_envp();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SystemExec::SystemExec (std::string command, const std::map<char, std::string> subs)
|
||||||
|
{
|
||||||
|
init ();
|
||||||
|
make_argp_escaped(command, subs);
|
||||||
|
cmd = argp[0];
|
||||||
|
// cmd = strdup(argp[0]);
|
||||||
|
make_envp();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
SystemExec::make_argp_escaped(std::string command, const std::map<char, std::string> subs)
|
||||||
|
{
|
||||||
|
|
||||||
|
int inquotes = 0;
|
||||||
|
int n = 0;
|
||||||
|
size_t i = 0;
|
||||||
|
std::string arg = "";
|
||||||
|
|
||||||
|
argp = (char **) malloc(sizeof(char *));
|
||||||
|
|
||||||
|
for (i = 0; i <= command.length(); i++) { // include terminating '\0'
|
||||||
|
char c = command.c_str()[i];
|
||||||
|
if (inquotes) {
|
||||||
|
if (c == '"') {
|
||||||
|
inquotes = 0;
|
||||||
|
} else {
|
||||||
|
// still in quotes - just copy
|
||||||
|
arg += c;
|
||||||
|
}
|
||||||
|
} else switch (c) {
|
||||||
|
case '%' :
|
||||||
|
c = command.c_str()[++i];
|
||||||
|
if (c == '%' || c == '\0') {
|
||||||
|
// "%%", "%" at end-of-string => "%"
|
||||||
|
arg += '%';
|
||||||
|
} else {
|
||||||
|
// search subs for string to substitute for char
|
||||||
|
std::map<char, std::string>::const_iterator s = subs.find(c);
|
||||||
|
if (s != subs.end()) {
|
||||||
|
// found substitution
|
||||||
|
arg += s->second;
|
||||||
|
} else {
|
||||||
|
// not a valid substitution, just copy
|
||||||
|
arg += '%';
|
||||||
|
arg += c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case '\\':
|
||||||
|
c = command.c_str()[++i];
|
||||||
|
switch (c) {
|
||||||
|
case ' ' :
|
||||||
|
case '"' : arg += c; break; // "\\", "\" at end-of-string => "\"
|
||||||
|
case '\0':
|
||||||
|
case '\\': arg += '\\'; break;
|
||||||
|
default : arg += '\\'; arg += c; break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case '"' :
|
||||||
|
inquotes = 1;
|
||||||
|
break;
|
||||||
|
case ' ' :
|
||||||
|
case '\t':
|
||||||
|
case '\0':
|
||||||
|
if (arg.length() > 0) {
|
||||||
|
// if there wasn't already a space or tab, start a new parameter
|
||||||
|
argp = (char **) realloc(argp, (n + 2) * sizeof(char *));
|
||||||
|
argp[n++] = strdup (arg.c_str());
|
||||||
|
arg = "";
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default :
|
||||||
|
arg += c;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
argp[n] = NULL;
|
||||||
|
|
||||||
|
char *p = argp[0];
|
||||||
|
n = 0;
|
||||||
|
do {
|
||||||
|
std::cerr << "argv[" << n << "] == \"" << p << "\"" << std::endl;
|
||||||
|
p = argp[n++];
|
||||||
|
} while (p);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
SystemExec::~SystemExec ()
|
SystemExec::~SystemExec ()
|
||||||
{
|
{
|
||||||
terminate ();
|
terminate ();
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue