Better string escaping, but it's still not good enough to support paths
with spaces.
This commit is contained in:
parent
3e394b95e4
commit
6a3c94a9d0
|
@ -2,34 +2,79 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "system.h"
|
#include "system.h"
|
||||||
|
|
||||||
|
#if defined WIN32
|
||||||
|
#define ESCAPECHAR '^'
|
||||||
|
|
||||||
|
static int needs_escaping(char c)
|
||||||
|
{
|
||||||
|
switch (c)
|
||||||
|
{
|
||||||
|
case ' ':
|
||||||
|
case '"':
|
||||||
|
case '\'':
|
||||||
|
case '(':
|
||||||
|
case ')':
|
||||||
|
case '^':
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
#define ESCAPECHAR '\\'
|
||||||
|
|
||||||
|
static int needs_escaping(char c)
|
||||||
|
{
|
||||||
|
switch (c)
|
||||||
|
{
|
||||||
|
case ' ':
|
||||||
|
case '"':
|
||||||
|
case '\'':
|
||||||
|
case '\\':
|
||||||
|
case '(':
|
||||||
|
case ')':
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static char* append_escaped(char* buffer, const char* word)
|
||||||
|
{
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
char c = *word++;
|
||||||
|
if (!c)
|
||||||
|
break;
|
||||||
|
if (needs_escaping(c))
|
||||||
|
*buffer++ = ESCAPECHAR;
|
||||||
|
*buffer++ = c;
|
||||||
|
}
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
int sys_system(const char* prog, const char* const* arglist)
|
int sys_system(const char* prog, const char* const* arglist)
|
||||||
{
|
{
|
||||||
/* Calculate the maximum length of the command line. */
|
/* Calculate the maximum length of the command line. */
|
||||||
|
|
||||||
int len = strlen(prog);
|
int len = strlen(prog) * 2 + 1;
|
||||||
for (const char* const* arg = arglist+1; *arg; arg++)
|
for (const char* const* arg = arglist+1; *arg; arg++)
|
||||||
len += strlen(*arg) * 2 + 1;
|
len += strlen(*arg) * 2 + 1;
|
||||||
|
|
||||||
/* Now actually build the command line. */
|
/* Now actually build the command line. */
|
||||||
|
|
||||||
char* cmdline = malloc(len + 1);
|
char* cmdline = malloc(len + 1);
|
||||||
strcpy(cmdline, prog);
|
char* p = append_escaped(cmdline, prog);
|
||||||
char* p = cmdline + strlen(prog);
|
|
||||||
|
|
||||||
for (const char* const* arg = arglist+1; *arg; arg++)
|
for (const char* const* arg = arglist+1; *arg; arg++)
|
||||||
{
|
{
|
||||||
const char* word = *arg;
|
const char* word = *arg;
|
||||||
*p++ = ' ';
|
*p++ = ' ';
|
||||||
|
|
||||||
for (;;)
|
p = append_escaped(p, word);
|
||||||
{
|
|
||||||
char c = *word++;
|
|
||||||
if (!c)
|
|
||||||
break;
|
|
||||||
if ((c == ' ') || (c == '\"') || (c == '\''))
|
|
||||||
*p++ = '\\';
|
|
||||||
*p++ = c;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
*p = 0;
|
*p = 0;
|
||||||
|
|
Loading…
Reference in a new issue