Better string escaping, but it's still not good enough to support paths

with spaces.
This commit is contained in:
David Given 2022-07-20 00:24:20 +02:00
parent 3e394b95e4
commit 6a3c94a9d0

View file

@ -2,34 +2,79 @@
#include <string.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)
{
/* 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++)
len += strlen(*arg) * 2 + 1;
/* Now actually build the command line. */
char* cmdline = malloc(len + 1);
strcpy(cmdline, prog);
char* p = cmdline + strlen(prog);
char* p = append_escaped(cmdline, prog);
for (const char* const* arg = arglist+1; *arg; arg++)
{
const char* word = *arg;
*p++ = ' ';
for (;;)
{
char c = *word++;
if (!c)
break;
if ((c == ' ') || (c == '\"') || (c == '\''))
*p++ = '\\';
*p++ = c;
}
p = append_escaped(p, word);
}
*p = 0;