[GRASS-SVN] r40162 - grass/trunk/lib/gis
svn_grass at osgeo.org
svn_grass at osgeo.org
Tue Dec 29 07:54:29 EST 2009
Author: glynn
Date: 2009-12-29 07:54:28 -0500 (Tue, 29 Dec 2009)
New Revision: 40162
Modified:
grass/trunk/lib/gis/spawn.c
Log:
Various Windows fixes for G_spawn[_ex]
Modified: grass/trunk/lib/gis/spawn.c
===================================================================
--- grass/trunk/lib/gis/spawn.c 2009-12-29 05:05:39 UTC (rev 40161)
+++ grass/trunk/lib/gis/spawn.c 2009-12-29 12:54:28 UTC (rev 40162)
@@ -66,115 +66,8 @@
#ifdef __MINGW32__
-int G_spawn(const char *command, ...)
-{
- va_list va;
- const char *args[MAX_ARGS];
- int num_args = 0;
-
- va_start(va, command);
-
- for (num_args = 0; num_args < MAX_ARGS;) {
- const char *arg = va_arg(va, const char *);
-
- args[num_args++] = arg;
- if (!arg)
- break;
- }
-
- va_end(va);
-
- if (num_args >= MAX_ARGS) {
- G_warning(_("Too many arguments"));
- return -1;
- }
-
- G_debug(3, "spawning '%s' ...", command);
-
- return _spawnvp(_P_WAIT, command, args);
-}
-
#else
-int G_spawn(const char *command, ...)
-{
- va_list va;
- char *args[MAX_ARGS];
- int num_args = 0;
- struct sigaction act, intr, quit;
- sigset_t block, oldmask;
- int status = -1;
- pid_t pid;
-
- va_start(va, command);
-
- for (num_args = 0; num_args < MAX_ARGS;) {
- char *arg = va_arg(va, char *);
-
- args[num_args++] = arg;
- if (!arg)
- break;
- }
-
- va_end(va);
-
- if (num_args >= MAX_ARGS) {
- G_warning(_("Too many arguments"));
- return -1;
- }
-
- sigemptyset(&act.sa_mask);
- act.sa_flags = SA_RESTART;
-
- act.sa_handler = SIG_IGN;
- if (sigaction(SIGINT, &act, &intr) < 0)
- goto error_1;
- if (sigaction(SIGQUIT, &act, &quit) < 0)
- goto error_2;
-
- sigemptyset(&block);
- sigaddset(&block, SIGCHLD);
- if (sigprocmask(SIG_BLOCK, &block, &oldmask) < 0)
- goto error_3;
-
- G_debug(3, "forking '%s' ...", command);
-
- pid = fork();
-
- if (pid < 0) {
- G_warning(_("Unable to create a new process"));
- goto error_4;
- }
-
- if (pid == 0) {
- sigaction(SIGINT, &intr, NULL);
- sigaction(SIGQUIT, &quit, NULL);
-
- execvp(command, args);
- G_warning(_("Unable to execute command"));
- _exit(127);
- }
- else {
- pid_t n;
-
- do
- n = waitpid(pid, &status, 0);
- while (n == (pid_t) - 1 && errno == EINTR);
-
- if (n != pid)
- status = -1;
- }
-
- error_4:
- sigprocmask(SIG_SETMASK, &oldmask, NULL);
- error_3:
- sigaction(SIGQUIT, &quit, NULL);
- error_2:
- sigaction(SIGINT, &intr, NULL);
- error_1:
- return status;
-}
-
#endif /*__MINGW32__*/
struct redirect
@@ -286,66 +179,80 @@
b->str[b->len] = '\0';
}
-static char *make_command_line(const char **argv)
+static void escape_arg(struct buffer *result, const char *arg)
{
- struct buffer result;
struct buffer buf;
- int i;
+ int quote, j;
- init(&result);
init(&buf);
- for (i = 0; argv[i]; i++) {
- const char *arg = argv[i];
- int quote;
- int j;
+ quote = arg[0] == '\0' || strchr(arg, ' ') || strchr(arg, '\t');
- clear(&buf);
+ if (quote)
+ append_char(result, '\"');
- if (result.len > 0)
- append_char(&result, ' ');
+ for (j = 0; arg[j]; j++) {
+ int c = arg[j];
+ int k;
- quote = arg[0] == '\0' || strchr(arg, ' ') || strchr(arg, '\t');
-
- if (quote)
- append_char(&result, '\"');
-
- for (j = 0; arg[j]; j++) {
- int c = arg[j];
- int k;
-
- switch (c) {
- case '\\':
- append_char(&buf, '\\');
- break;
- case '\"':
- for (k = 0; k < buf.len; k++)
- append(&result, "\\\\");
+ switch (c) {
+ case '\\':
+ append_char(&buf, '\\');
+ break;
+ case '\"':
+ for (k = 0; k < buf.len; k++)
+ append(result, "\\\\");
+ clear(&buf);
+ append(result, "\\\"");
+ break;
+ default:
+ if (buf.len > 0) {
+ append(result, buf.str);
clear(&buf);
- append(&result, "\\\"");
- break;
- default:
- if (buf.len > 0) {
- append(&result, buf.str);
- clear(&buf);
- }
- append_char(&result, c);
}
+ append_char(result, c);
}
+ }
- if (buf.len > 0)
- append(&result, buf.str);
+ if (buf.len > 0)
+ append(result, buf.str);
- if (quote) {
- append(&result, buf.str);
- append_char(&result, '\"');
- }
+ if (quote) {
+ append(result, buf.str);
+ append_char(result, '\"');
}
finish(&buf);
+}
+
+static const char *escaped(const char *arg)
+{
+ struct buffer result;
+
+ if (!arg)
+ return NULL;
+
+ init(&result);
+ escape_arg(&result, arg);
return release(&result);
}
+static char *make_command_line(const char **argv)
+{
+ struct buffer result;
+ int i;
+
+ init(&result);
+
+ for (i = 0; argv[i]; i++) {
+ if (result.len > 0)
+ append_char(&result, ' ');
+ escape_arg(&result, argv[i]);
+ }
+
+ return release(&result);
+}
+
static char *make_environment(const char **envp)
{
struct buffer result;
@@ -433,7 +340,7 @@
h1 = (HANDLE) _get_osfhandle(fd);
if (!DuplicateHandle(GetCurrentProcess(), h1,
GetCurrentProcess(), &h2,
- DUPLICATE_SAME_ACCESS, 1, 0))
+ 0, TRUE, DUPLICATE_SAME_ACCESS))
return INVALID_HANDLE_VALUE;
return h2;
@@ -450,6 +357,9 @@
BOOL result;
DWORD exitcode;
+ G_debug(3, "win_spawn: program = %s", program);
+ G_debug(3, "win_spawn: args = %s", args);
+
if (!program) {
G_free(args);
G_free(env);
@@ -481,6 +391,11 @@
G_free(env);
G_free(program);
+ if (!result) {
+ G_warning(_("CreateProcess() failed: error = %d"), GetLastError());
+ return -1;
+ }
+
if (!background) {
WaitForSingleObject(pi.hProcess, INFINITE);
if (!GetExitCodeProcess(pi.hProcess, &exitcode))
@@ -597,6 +512,46 @@
return status;
}
+int G_spawn(const char *command, ...)
+{
+ va_list va;
+ char *program = find_program(command);
+ const char *args[MAX_ARGS];
+ int num_args = 0;
+ int result, i;
+
+ va_start(va, command);
+
+ for (num_args = 0; num_args < MAX_ARGS;) {
+ const char *arg = va_arg(va, const char *);
+
+ args[num_args++] = escaped(arg);
+ if (!arg)
+ break;
+ G_debug(3, "argv[%d]='%s'", num_args-1, args[num_args-1]);
+ }
+
+ va_end(va);
+
+ if (num_args >= MAX_ARGS) {
+ G_warning(_("Too many arguments"));
+ result = -1;
+ }
+ else {
+ G_debug(3, "spawning '%s' ...", program);
+ result = _spawnvp(_P_WAIT, program, args);
+ G_debug(3, "result = %d", result);
+ if (result < 0)
+ G_debug(3, "error: %s", strerror(errno));
+ }
+
+ G_free(program);
+ for (i = 0; i < num_args; i++)
+ G_free((char *) args[i]);
+
+ return result;
+}
+
#else /* __MINGW32__ */
static int undo_signals(const struct signal *signals, int num_signals, int which)
@@ -803,6 +758,85 @@
return status;
}
+int G_spawn(const char *command, ...)
+{
+ va_list va;
+ char *args[MAX_ARGS];
+ int num_args = 0;
+ struct sigaction act, intr, quit;
+ sigset_t block, oldmask;
+ int status = -1;
+ pid_t pid;
+
+ va_start(va, command);
+
+ for (num_args = 0; num_args < MAX_ARGS;) {
+ char *arg = va_arg(va, char *);
+
+ args[num_args++] = arg;
+ if (!arg)
+ break;
+ }
+
+ va_end(va);
+
+ if (num_args >= MAX_ARGS) {
+ G_warning(_("Too many arguments"));
+ return -1;
+ }
+
+ sigemptyset(&act.sa_mask);
+ act.sa_flags = SA_RESTART;
+
+ act.sa_handler = SIG_IGN;
+ if (sigaction(SIGINT, &act, &intr) < 0)
+ goto error_1;
+ if (sigaction(SIGQUIT, &act, &quit) < 0)
+ goto error_2;
+
+ sigemptyset(&block);
+ sigaddset(&block, SIGCHLD);
+ if (sigprocmask(SIG_BLOCK, &block, &oldmask) < 0)
+ goto error_3;
+
+ G_debug(3, "forking '%s' ...", command);
+
+ pid = fork();
+
+ if (pid < 0) {
+ G_warning(_("Unable to create a new process"));
+ goto error_4;
+ }
+
+ if (pid == 0) {
+ sigaction(SIGINT, &intr, NULL);
+ sigaction(SIGQUIT, &quit, NULL);
+
+ execvp(command, args);
+ G_warning(_("Unable to execute command"));
+ _exit(127);
+ }
+ else {
+ pid_t n;
+
+ do
+ n = waitpid(pid, &status, 0);
+ while (n == (pid_t) - 1 && errno == EINTR);
+
+ if (n != pid)
+ status = -1;
+ }
+
+ error_4:
+ sigprocmask(SIG_SETMASK, &oldmask, NULL);
+ error_3:
+ sigaction(SIGQUIT, &quit, NULL);
+ error_2:
+ sigaction(SIGINT, &intr, NULL);
+ error_1:
+ return status;
+}
+
#endif /* __MINGW32__ */
static void begin_spawn(struct spawn *sp)
More information about the grass-commit
mailing list