[GRASS-SVN] r40453 - in grass/trunk: include lib/gis
svn_grass at osgeo.org
svn_grass at osgeo.org
Thu Jan 14 19:49:23 EST 2010
Author: glynn
Date: 2010-01-14 19:49:22 -0500 (Thu, 14 Jan 2010)
New Revision: 40453
Modified:
grass/trunk/include/spawn.h
grass/trunk/lib/gis/spawn.c
Log:
G_spawn* updates:
Use shell on Windows
Eliminate spawnv*-based implementations
Implement G_spawn() atop G_spawn_ex()
Add SF_ARGLIST
Modified: grass/trunk/include/spawn.h
===================================================================
--- grass/trunk/include/spawn.h 2010-01-14 22:01:18 UTC (rev 40452)
+++ grass/trunk/include/spawn.h 2010-01-15 00:49:22 UTC (rev 40453)
@@ -23,6 +23,7 @@
#define SF_BACKGROUND ((const char *) 7)
#define SF_DIRECTORY ((const char *) 8)
#define SF_ARGVEC ((const char *) 9)
+#define SF_ARGLIST ((const char *) 10)
enum signal_action
{
@@ -41,7 +42,7 @@
};
extern int G_spawn(const char *command, ...);
+extern int G_vspawn_ex(const char *command, const char **args);
extern int G_spawn_ex(const char *command, ...);
-extern int G_vspawn_ex(const char *command, const char **args);
#endif
Modified: grass/trunk/lib/gis/spawn.c
===================================================================
--- grass/trunk/lib/gis/spawn.c 2010-01-14 22:01:18 UTC (rev 40452)
+++ grass/trunk/lib/gis/spawn.c 2010-01-15 00:49:22 UTC (rev 40453)
@@ -24,17 +24,11 @@
#include <errno.h>
#include <sys/types.h>
-#define USE_CREATE_PROCESS 1
-
#ifndef __MINGW32__
#include <sys/wait.h>
#else
-#ifdef USE_CREATE_PROCESS
#include <windows.h>
-#else
-typedef void *HANDLE;
#endif
-#endif
#include <grass/config.h>
#include <grass/gis.h>
#include <grass/glocale.h>
@@ -64,12 +58,6 @@
* \return process status on success
*/
-#ifdef __MINGW32__
-
-#else
-
-#endif /*__MINGW32__*/
-
struct redirect
{
int dst_fd;
@@ -110,10 +98,11 @@
const char *directory;
};
+static void parse_arglist(struct spawn *sp, va_list va);
+static void parse_argvec(struct spawn *sp, const char **va);
+
#ifdef __MINGW32__
-#ifdef USE_CREATE_PROCESS
-
struct buffer {
char *str;
size_t len;
@@ -225,51 +214,6 @@
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;
- int i;
-
- init(&result);
-
- for (i = 0; envp[i]; i++) {
- const char *env = envp[i];
-
- append(&result, env);
- append_char(&result, '\0');
- }
-
- return release(&result);
-}
-
static char *check_program(const char *pgm, const char *dir, const char *ext)
{
char pathname[GPATH_MAX];
@@ -330,6 +274,46 @@
return result;
}
+static char *make_command_line(int shell, const char *cmd, const char **argv)
+{
+ struct buffer result;
+ int i;
+
+ init(&result);
+
+ if (shell) {
+ const char *comspec = getenv("COMSPEC");
+ append(&result, comspec ? comspec : "cmd.exe");
+ append(&result, " /c ");
+ escape_arg(&result, cmd);
+ }
+
+ for (i = shell ? 1 : 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;
+ int i;
+
+ init(&result);
+
+ for (i = 0; envp[i]; i++) {
+ const char *env = envp[i];
+
+ append(&result, env);
+ append_char(&result, '\0');
+ }
+
+ return release(&result);
+}
+
static HANDLE get_handle(int fd)
{
HANDLE h1, h2;
@@ -347,25 +331,29 @@
}
static int win_spawn(const char *cmd, const char **argv, const char **envp,
- const char *cwd, HANDLE handles[3], int background)
+ const char *cwd, HANDLE handles[3], int background,
+ int shell)
{
- char *args = make_command_line(argv);
+ char *args = make_command_line(shell, cmd, argv);
char *env = make_environment(envp);
- char *program = find_program(cmd);
+ char *program = shell ? NULL : find_program(cmd);
STARTUPINFO si;
PROCESS_INFORMATION pi;
BOOL result;
DWORD exitcode;
- G_debug(3, "win_spawn: program = %s", program);
- G_debug(3, "win_spawn: args = %s", args);
+ if (!shell) {
+ G_debug(3, "win_spawn: program = %s", program);
- if (!program) {
- G_free(args);
- G_free(env);
- return -1;
+ if (!program) {
+ G_free(args);
+ G_free(env);
+ return -1;
+ }
}
+ G_debug(3, "win_spawn: args = %s", args);
+
memset(&si, 0, sizeof(si));
si.cb = sizeof(si);
@@ -442,17 +430,6 @@
}
}
-#else
-
-static void do_redirects(struct redirect *redirects, int num_redirects, HANDLE handles[3])
-{
- if (num_redirects > 0)
- G_fatal_error
- ("G_spawn_ex: redirection not (yet) supported on Windows");
-}
-
-#endif
-
static void add_binding(const char **env, int *pnum, const struct binding *b)
{
char *str = G_malloc(strlen(b->var) + strlen(b->val) + 2);
@@ -500,11 +477,7 @@
do_redirects(sp->redirects, sp->num_redirects, handles);
env = do_bindings(sp->bindings, sp->num_bindings);
-#ifdef USE_CREATE_PROCESS
- status = win_spawn(command, sp->args, env, sp->directory, handles, sp->background);
-#else
- status = spawnvpe(sp->background ? _P_NOWAIT : _P_WAIT, command, sp->args, env);
-#endif
+ status = win_spawn(command, sp->args, env, sp->directory, handles, sp->background, 1);
if (!sp->background && status < 0)
G_warning(_("Unable to execute command"));
@@ -512,46 +485,6 @@
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)
@@ -758,85 +691,6 @@
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)
@@ -914,6 +768,9 @@
else if (arg == SF_ARGVEC) {
parse_argvec(sp, NEXT_ARG(va, const char **));
}
+ else if (arg == SF_ARGLIST) {
+ parse_arglist(sp, NEXT_ARG(va, va_list));
+ }
else
sp->args[sp->num_args++] = arg;
}
@@ -981,6 +838,9 @@
else if (arg == SF_ARGVEC) {
parse_argvec(sp, va_arg(va, const char **));
}
+ else if (arg == SF_ARGLIST) {
+ parse_arglist(sp, va_arg(va, va_list));
+ }
else
sp->args[sp->num_args++] = arg;
}
@@ -1031,3 +891,33 @@
return do_spawn(&sp, command);
}
+/**
+ * \brief Spawn new process based on <b>command</b>.
+ *
+ * \param[in] command
+ * \return -1 on error
+ * \return process status on success
+ */
+
+int G_spawn(const char *command, ...)
+{
+ va_list va;
+ int status = -1;
+
+ va_start(va, command);
+
+ status = G_spawn_ex(
+ command,
+#ifndef __MINGW32__
+ SF_SIGNAL, SST_PRE, SSA_IGNORE, SIGINT,
+ SF_SIGNAL, SST_PRE, SSA_IGNORE, SIGQUIT,
+ SF_SIGNAL, SST_PRE, SSA_BLOCK, SIGCHLD,
+#endif
+ SF_ARGLIST, va,
+ NULL);
+
+ va_end(va);
+
+ return status;
+}
+
More information about the grass-commit
mailing list