81 #include <grass/gis.h> 82 #include <grass/spawn.h> 83 #include <grass/glocale.h> 85 #include "parser_local_proto.h" 97 #define MAX_MATCHES 50 104 static void set_flag(
int);
105 static int contains(
const char *,
int);
106 static int valid_option_name(
const char *);
107 static int is_option(
const char *);
108 static int match_option_1(
const char *,
const char *);
109 static int match_option(
const char *,
const char *);
110 static void set_option(
const char *);
111 static void check_opts(
void);
112 static void check_an_opt(
const char *,
int,
const char *,
const char **,
char **);
113 static int check_int(
const char *,
const char **);
114 static int check_double(
const char *,
const char **);
115 static int check_string(
const char *,
const char **,
int *);
116 static void check_required(
void);
117 static void split_opts(
void);
118 static void check_multiple_opts(
void);
119 static int check_overwrite(
void);
120 static void define_keywords(
void);
121 static void split_gisprompt(
const char *,
char *,
char *,
char *);
122 static int module_gui_wx(
void);
123 static void append_error(
const char *);
124 static const char *get_renamed_option(
const char *);
139 st->no_interactive = 1;
162 flag = G_malloc(
sizeof(
struct Flag));
163 st->current_flag->next_flag = flag;
166 flag = &
st->first_flag;
170 G_zero(flag,
sizeof(
struct Flag));
172 st->current_flag = flag;
176 item = G_malloc(
sizeof(
struct Item));
177 st->current_item->next_item = item;
180 item = &
st->first_item;
182 G_zero(item,
sizeof(
struct Item));
187 st->current_item = item;
216 opt = G_malloc(
sizeof(
struct Option));
217 st->current_option->next_opt = opt;
220 opt = &
st->first_option;
223 G_zero(opt,
sizeof(
struct Option));
228 st->current_option = opt;
232 item = G_malloc(
sizeof(
struct Item));
233 st->current_item->next_item = item;
236 item = &
st->first_item;
238 G_zero(item,
sizeof(
struct Item));
242 st->current_item = item;
255 struct GModule *module;
258 module = &
st->module_info;
261 G_zero(module,
sizeof(
struct GModule));
322 char *ptr, *tmp_name, *
err;
325 char force_gui =
FALSE;
330 st->pgm_path = tmp_name;
334 i = strlen(tmp_name);
342 st->pgm_name = tmp_name;
346 opt = &
st->first_option;
347 while (
st->n_opts && opt) {
349 st->has_required = 1;
351 if (!valid_option_name(opt->key))
352 G_warning(_(
"BUG in option name, '%s' is not valid"), opt->key);
357 char **tokens, delm[2];
370 opt->opts = G_calloc(cnt + 1,
sizeof(
const char *));
374 opt->opts[i] =
G_store(tokens[i]);
379 if (opt->descriptions) {
382 opt->descs = G_calloc(cnt + 1,
sizeof(
const char *));
396 while (opt->opts[j]) {
397 if (strcmp(opt->opts[j], tokens[i]) == 0) {
404 G_warning(_(
"BUG in descriptions, option '%s' in <%s> does not exist"),
405 tokens[i], opt->key);
408 opt->descs[j] =
G_store(tokens[i + 1]);
418 if (opt->multiple && opt->answers && opt->answers[0]) {
419 opt->answer = G_malloc(strlen(opt->answers[0]) + 1);
420 strcpy(opt->answer, opt->answers[0]);
421 for (i = 1; opt->answers[i]; i++) {
422 opt->answer = G_realloc(opt->answer,
423 strlen(opt->answer) +
424 strlen(opt->answers[i]) + 2);
425 strcat(opt->answer,
",");
426 strcat(opt->answer, opt->answers[i]);
429 opt->def = opt->answer;
436 && !
st->no_interactive && isatty(0)) {
437 if (module_gui_wx() == 0)
441 if (argc < 2 && st->has_required && isatty(0)) {
445 else if (argc >= 2) {
448 if (strcmp(argv[1],
"help") == 0 ||
449 strcmp(argv[1],
"-help") == 0 || strcmp(argv[1],
"--help") == 0) {
456 if (strcmp(argv[1],
"--help-text") == 0) {
463 if (strcmp(argv[1],
"--interface-description") == 0) {
470 if (strcmp(argv[1],
"--html-description") == 0) {
477 if (strcmp(argv[1],
"--rst-description") == 0) {
484 if (strcmp(argv[1],
"--wps-process-description") == 0) {
491 if (strcmp(argv[1],
"--script") == 0) {
501 if (strcmp(ptr,
"help") == 0 || strcmp(ptr,
"--h") == 0 ||
502 strcmp(ptr,
"-help") == 0 || strcmp(ptr,
"--help") == 0) {
508 if (strcmp(ptr,
"--o") == 0 || strcmp(ptr,
"--overwrite") == 0) {
513 else if (strcmp(ptr,
"--v") == 0 || strcmp(ptr,
"--verbose") == 0) {
520 if (
st->quiet == 1) {
521 G_warning(_(
"Use either --quiet or --verbose flag, not both. Assuming --verbose."));
527 else if (strcmp(ptr,
"--q") == 0 || strcmp(ptr,
"--quiet") == 0) {
534 if (
st->quiet == -1) {
535 G_warning(_(
"Use either --quiet or --verbose flag, not both. Assuming --quiet."));
541 else if (strcmp(ptr,
"--ui") == 0) {
546 else if (*ptr ==
'-') {
552 else if (is_option(ptr)) {
558 else if (need_first_opt &&
st->n_opts) {
560 st->first_option.count++;
566 G_asprintf(&err, _(
"Sorry <%s> is not a valid option"), ptr);
578 if (module_gui_wx() != 0)
579 G_fatal_error(_(
"Your installation doesn't include GUI, exiting."));
584 check_multiple_opts();
591 if (!
st->suppress_required)
596 if (
st->n_errors > 0) {
600 fprintf(stderr,
"\n");
601 for (i = 0; i <
st->n_errors; i++) {
602 fprintf(stderr,
"%s: %s\n", _(
"ERROR"),
st->error[i]);
608 if (check_overwrite())
633 G_debug(3,
"G_recreate_command()");
637 buff = G_calloc(1024,
sizeof(
char));
641 if (len >= nalloced) {
642 nalloced += (1024 > len) ? 1024 : len + 1;
643 buff = G_realloc(buff, nalloced);
650 slen = strlen(
" --overwrite");
651 if (len + slen >= nalloced) {
652 nalloced += (1024 > len) ? 1024 : len + 1;
653 buff = G_realloc(buff, nalloced);
655 strcpy(cur,
" --overwrite");
668 if (len + slen >= nalloced) {
669 nalloced += (1024 > len) ? 1024 : len + 1;
670 buff = G_realloc(buff, nalloced);
678 flag = &
st->first_flag;
680 if (flag->answer == 1) {
686 if (len + slen >= nalloced) {
688 (nalloced + 1024 > len + slen) ? 1024 : slen + 1;
689 buff = G_realloc(buff, nalloced);
696 flag = flag->next_flag;
700 opt = &
st->first_option;
701 while (
st->n_opts && opt) {
702 if (opt->answer && opt->answers && opt->answers[0]) {
703 slen = strlen(opt->key) + strlen(opt->answers[0]) + 4;
704 if (len + slen >= nalloced) {
705 nalloced += (nalloced + 1024 > len + slen) ? 1024 : slen + 1;
706 buff = G_realloc(buff, nalloced);
711 strcpy(cur, opt->key);
712 cur = strchr(cur,
'\0');
715 if (opt->type == TYPE_STRING) {
719 strcpy(cur, opt->answers[0]);
720 cur = strchr(cur,
'\0');
722 for (n = 1; opt->answers[n]; n++) {
723 if (!opt->answers[n])
725 slen = strlen(opt->answers[n]) + 2;
726 if (len + slen >= nalloced) {
728 (nalloced + 1024 > len + slen) ? 1024 : slen + 1;
729 buff = G_realloc(buff, nalloced);
734 strcpy(cur, opt->answers[n]);
735 cur = strchr(cur,
'\0');
738 if (opt->type == TYPE_STRING) {
757 if (
st->n_keys >=
st->n_keys_alloc) {
758 st->n_keys_alloc += 10;
759 st->module_info.keywords = G_realloc(
st->module_info.keywords,
760 st->n_keys_alloc *
sizeof(
char *));
763 st->module_info.keywords[
st->n_keys++] =
G_store(keyword);
774 st->module_info.keywords = (
const char **)tokens;
786 if (
st->module_info.overwrite)
792 opt = &
st->first_option;
794 if (opt->gisprompt) {
795 split_gisprompt(opt->gisprompt, age, element, desc);
796 if (strcmp(age,
"new") == 0)
819 for(i = 0; i <
st->n_keys; i++) {
821 fprintf(fd,
"%s",
st->module_info.keywords[i]);
824 format(fd,
st->module_info.keywords[i]);
826 if (i < st->n_keys - 1)
841 return st->overwrite;
844 void define_keywords(
void)
847 st->n_keys_alloc = 0;
860 int module_gui_wx(
void)
862 char script[GPATH_MAX];
869 sprintf(script,
"%s/gui/wxpython/gui_core/forms.py",
871 if (access(script, F_OK) != -1)
872 G_spawn(getenv(
"GRASS_PYTHON"), getenv(
"GRASS_PYTHON"),
895 flag = &
st->first_flag;
897 if (flag->key == f) {
899 if (flag->suppress_required)
900 st->suppress_required = 1;
903 flag = flag->next_flag;
913 int contains(
const char *s,
int c)
923 int valid_option_name(
const char *
string)
925 int m = strlen(
string);
926 int n = strspn(
string,
"abcdefghijklmnopqrstuvwxyz0123456789_");
934 if (
string[m-1] ==
'_')
940 int is_option(
const char *
string)
942 int n = strspn(
string,
"abcdefghijklmnopqrstuvwxyz0123456789_");
944 return n > 0 &&
string[n] ==
'=' &&
string[0] !=
'_' &&
string[n-1] !=
'_';
947 int match_option_1(
const char *
string,
const char *option)
957 if (*
string == *option && match_option_1(
string + 1, option + 1))
960 if (*option ==
'_' && match_option_1(
string, option + 1))
963 next = strchr(option,
'_');
968 return match_option_1(
string + 1, next + 1);
970 return match_option_1(
string, next + 1);
973 int match_option(
const char *
string,
const char *option)
975 return (*
string == *option)
976 && match_option_1(
string + 1, option + 1);
979 void set_option(
const char *
string)
981 struct Option *at_opt =
NULL;
982 struct Option *opt =
NULL;
991 for (ptr = the_key; *
string !=
'='; ptr++,
string++)
997 key_len = strlen(the_key);
998 for (at_opt = &
st->first_option; at_opt; at_opt = at_opt->next_opt) {
1002 if (strcmp(the_key, at_opt->key) == 0) {
1003 matches[0] = at_opt;
1008 if (strncmp(the_key, at_opt->key, key_len) == 0 ||
1009 match_option(the_key, at_opt->key)) {
1012 matches[found++] = at_opt;
1018 int length = strlen(matches[0]->key);
1021 for (i = 1; i < found; i++) {
1022 int len = strlen(matches[i]->key);
1028 for (i = 0; prefix && i < found; i++)
1029 if (strncmp(matches[i]->key, matches[shortest]->key, length) != 0)
1032 matches[0] = matches[shortest];
1038 for (i = 0; i < found; i++) {
1039 G_asprintf(&err, _(
"Option <%s=> matches"), matches[i]->key);
1051 const char *renamed_key =
NULL;
1053 renamed_key = get_renamed_option(the_key);
1055 for (at_opt = &
st->first_option; at_opt; at_opt = at_opt->next_opt) {
1056 if (strcmp(renamed_key, at_opt->key) == 0) {
1057 G_warning(_(
"Please update the usage of <%s>: " 1058 "option <%s> has been renamed to <%s>"),
1075 if (getenv(
"GRASS_FULL_OPTION_NAMES") && strcmp(the_key, opt->key) != 0)
1076 G_warning(_(
"<%s> is an abbreviation for <%s>"), the_key, opt->key);
1080 if (!opt->multiple) {
1081 G_asprintf(&err, _(
"Option <%s> does not accept multiple answers"), opt->key);
1084 opt->answer = G_realloc(opt->answer,
1085 strlen(opt->answer) + strlen(
string) + 2);
1086 strcat(opt->answer,
",");
1087 strcat(opt->answer,
string);
1090 opt->answer =
G_store(
string);
1093 void check_opts(
void)
1101 opt = &
st->first_option;
1106 if (opt->multiple == 0)
1107 check_an_opt(opt->key, opt->type,
1108 opt->options, opt->opts, &opt->answer);
1110 for (ans = 0; opt->answers[ans] !=
'\0'; ans++)
1111 check_an_opt(opt->key, opt->type,
1112 opt->options, opt->opts, &opt->answers[ans]);
1119 opt->checker(opt->answer);
1121 opt = opt->next_opt;
1125 void check_an_opt(
const char *key,
int type,
const char *options,
1126 const char **opts,
char **answerp)
1128 const char *answer = *answerp;
1138 error = check_int(answer, opts);
1141 error = check_double(answer, opts);
1144 error = check_string(answer, opts, &found);
1152 _(
"Illegal range syntax for parameter <%s>\n" 1153 "\tPresented as: %s"), key, options);
1158 _(
"Value <%s> out of range for parameter <%s>\n" 1159 "\tLegal range: %s"), answer, key, options);
1164 _(
"Missing value for parameter <%s>"),
1170 _(
"Value <%s> ambiguous for parameter <%s>\n" 1171 "\tValid options: %s"), answer, key, options);
1175 *answerp =
G_store(opts[found]);
1181 int check_int(
const char *ans,
const char **opts)
1186 if (strcmp(ans,
"-") == 0)
1189 if (sscanf(ans,
"%d", &d) != 1)
1195 for (i = 0; opts[i]; i++) {
1196 const char *opt = opts[i];
1199 if (contains(opt,
'-')) {
1200 if (sscanf(opt,
"%d-%d", &lo, &hi) == 2) {
1201 if (d >= lo && d <= hi)
1204 else if (sscanf(opt,
"-%d", &hi) == 1) {
1208 else if (sscanf(opt,
"%d-", &lo) == 1) {
1216 if (sscanf(opt,
"%d", &lo) == 1) {
1228 int check_double(
const char *ans,
const char **opts)
1234 if (strcmp(ans,
"-") == 0)
1237 if (sscanf(ans,
"%lf", &d) != 1)
1243 for (i = 0; opts[i]; i++) {
1244 const char *opt = opts[i];
1247 if (contains(opt,
'-')) {
1248 if (sscanf(opt,
"%lf-%lf", &lo, &hi) == 2) {
1249 if (d >= lo && d <= hi)
1252 else if (sscanf(opt,
"-%lf", &hi) == 1) {
1256 else if (sscanf(opt,
"%lf-", &lo) == 1) {
1264 if (sscanf(opt,
"%lf", &lo) == 1) {
1276 int check_string(
const char *ans,
const char **opts,
int *result)
1278 int len = strlen(ans);
1286 for (i = 0; opts[i]; i++) {
1287 if (strcmp(ans, opts[i]) == 0)
1289 if (strncmp(ans, opts[i], len) == 0 || match_option(ans, opts[i])) {
1292 matches[found++] = i;
1298 int length = strlen(opts[matches[0]]);
1301 for (i = 1; i < found; i++) {
1302 int len = strlen(opts[matches[i]]);
1308 for (i = 0; prefix && i < found; i++)
1309 if (strncmp(opts[matches[i]], opts[matches[shortest]], length) != 0)
1312 matches[0] = matches[shortest];
1318 *result = matches[0];
1320 if (found > 0 && getenv(
"GRASS_FULL_OPTION_NAMES") && strcmp(ans, opts[matches[0]]) != 0)
1321 G_warning(_(
"<%s> is an abbreviation for <%s>"), ans, opts[matches[0]]);
1330 void check_required(
void)
1340 opt = &
st->first_option;
1342 if (opt->required && !opt->answer) {
1343 G_asprintf(&err, _(
"Required parameter <%s> not set:\n" 1345 opt->key, (opt->label ? opt->label : opt->description));
1348 opt = opt->next_opt;
1352 void split_opts(
void)
1365 opt = &
st->first_option;
1370 opt->answers = G_malloc(allocated *
sizeof(
char *));
1374 opt->answers[ans_num] =
NULL;
1377 for (len = 0, ptr2 = ptr1; *ptr2 !=
'\0' && *ptr2 !=
',';
1381 opt->answers[ans_num] = G_malloc(len + 1);
1382 memcpy(opt->answers[ans_num], ptr1, len);
1383 opt->answers[ans_num][len] = 0;
1387 if (ans_num >= allocated) {
1389 opt->answers = G_realloc(opt->answers,
1390 allocated *
sizeof(
char *));
1393 opt->answers[ans_num] =
NULL;
1405 opt = opt->next_opt;
1409 void check_multiple_opts(
void)
1421 opt = &
st->first_option;
1424 if (opt->answer && strcmp(opt->answer,
"-") && opt->key_desc) {
1427 for (ptr = opt->key_desc; *ptr !=
'\0'; ptr++)
1431 for (n = 0; opt->answers[n] !=
'\0'; n++) ;
1435 _(
"Option <%s> must be provided in multiples of %d\n" 1436 "\tYou provided %d item(s): %s"),
1437 opt->key, n_commas, n, opt->answer);
1442 opt = opt->next_opt;
1447 int check_overwrite(
void)
1454 const char *overstr;
1457 st->module_info.overwrite = 0;
1465 over = atoi(overstr);
1469 if ((overstr = getenv(
"GRASS_OVERWRITE"))) {
1474 if (
st->overwrite || over) {
1475 st->module_info.overwrite = 1;
1477 putenv(
"GRASS_OVERWRITE=1");
1482 opt = &
st->first_option;
1484 if (opt->answer && opt->gisprompt) {
1485 split_gisprompt(opt->gisprompt, age, element, desc);
1487 if (strcmp(age,
"new") == 0) {
1491 for (i = 0; opt->answers[i]; i++) {
1493 if (strcmp(element,
"file") == 0) {
1494 if (access(opt->answers[i], F_OK) == 0)
1497 else if (strcmp(element,
"mapset") != 0) {
1506 if (!
st->overwrite && !over) {
1509 fprintf(stderr, _(
"ERROR: "));
1511 _(
"option <%s>: <%s> exists. To overwrite, use the --overwrite flag"),
1512 opt->key, opt->answers[i]);
1513 fprintf(stderr,
"\n");
1516 fprintf(stderr,
"GRASS_INFO_ERROR(%d,1): ", getpid());
1518 _(
"option <%s>: <%s> exists. To overwrite, use the --overwrite flag"),
1519 opt->key, opt->answers[i]);
1520 fprintf(stderr,
"\n");
1521 fprintf(stderr,
"GRASS_INFO_END(%d,1)\n",
1531 opt = opt->next_opt;
1537 void split_gisprompt(
const char *gisprompt,
char *age,
char *
element,
1543 for (ptr1 = gisprompt, ptr2 = age; *ptr1 !=
'\0'; ptr1++, ptr2++) {
1550 for (ptr1++, ptr2 = element; *ptr1 !=
'\0'; ptr1++, ptr2++) {
1557 for (ptr1++, ptr2 = desc; *ptr1 !=
'\0'; ptr1++, ptr2++) {
1565 void append_error(
const char *msg)
1567 st->error = G_realloc(
st->error,
sizeof(
char *) * (
st->n_errors + 1));
1571 const char *get_renamed_option(
const char *key)
1573 const char *pgm, *key_new;
1576 if (!
st->renamed_options) {
1578 char path[GPATH_MAX];
1591 pgm_key = (
char *) G_malloc (strlen(pgm) + strlen(key) + 2);
1626 if (option->gisprompt ==
NULL ||
1627 strcmp(option->gisprompt,
"old,separator,separator") != 0)
1628 G_fatal_error(_(
"%s= is not a separator option"), option->key);
1630 if (option->answer ==
NULL)
1631 G_fatal_error(_(
"No separator given for %s="), option->key);
1633 if (strcmp(option->answer,
"pipe") == 0)
1635 else if (strcmp(option->answer,
"comma") == 0)
1637 else if (strcmp(option->answer,
"space") == 0)
1639 else if (strcmp(option->answer,
"tab") == 0 ||
1640 strcmp(option->answer,
"\\t") == 0)
1642 else if (strcmp(option->answer,
"newline") == 0 ||
1643 strcmp(option->answer,
"\\n") == 0)
1646 sep =
G_store(option->answer);
1648 G_debug(2,
"G_option_to_separator(): key = %s -> sep = '%s'",
1689 stdinout = !option->answer || !*(option->answer) ||
1690 strcmp(option->answer,
"-") == 0;
1692 if (option->gisprompt ==
NULL)
1694 else if (option->multiple)
1695 G_fatal_error(_(
"Opening multiple files not supported for %s="),
1697 else if (strcmp(option->gisprompt,
"old,file,file") == 0) {
1700 else if ((fp = fopen(option->answer,
"r")) ==
NULL)
1702 option->key, option->answer);
1703 }
else if (strcmp(option->gisprompt,
"new,file,file") == 0) {
1706 else if ((fp = fopen(option->answer,
"w")) ==
NULL)
1708 option->key, option->answer);
1723 if (fp != stdin && fp != stdout && fp != stderr)
int G__uses_new_gisprompt(void)
int G_info_format(void)
Get current message format.
int G__has_required_rule(void)
Checks if there is any rule RULE_REQUIRED (internal use only).
void G__usage_html(void)
Print module usage description in HTML format.
const char * G_find_key_value(const char *key, const struct Key_Value *kv)
Find given key (case sensitive)
const char * G_mapset(void)
Get current mapset name.
void G__usage_xml(void)
Print module usage description in XML format.
struct GModule * G_define_module(void)
Initializes a new module.
void G_zero(void *buf, int i)
Zero out a buffer, buf, of length i.
const char * G_find_file(const char *element, char *name, const char *mapset)
Searches for a file from the mapset search list or in a specified mapset.
void G__usage_rest(void)
Print module usage description in reStructuredText format.
char * G_store(const char *s)
Copy string to allocated memory.
void G__check_option_rules(void)
Check for option rules (internal use only)
int G_asprintf(char **out, const char *fmt,...)
int G_get_overwrite()
Get overwrite value.
char * G_chop(char *line)
Chop leading and trailing white spaces.
char * G_option_to_separator(const struct Option *option)
Get separator string from the option.
char * G_recreate_command(void)
Creates command to run non-interactive.
struct Flag * G_define_flag(void)
Initializes a Flag struct.
int G_number_of_tokens(char **tokens)
Return number of tokens.
void G_fatal_error(const char *msg,...)
Print a fatal error message to stderr.
int G_snprintf(char *str, size_t size, const char *fmt,...)
snprintf() clone.
void G_close_option_file(FILE *fp)
Close an input/output file returned by G_open_option_file(). If the file pointer is stdin...
SYMBOL * err(FILE *fp, SYMBOL *s, char *msg)
struct Key_Value * G_read_key_value_file(const char *file)
Read key/values pairs from file.
int G_parser(int argc, char **argv)
Parse command line.
struct Option * G_define_option(void)
Initializes an Option struct.
int G_verbose_max(void)
Get max verbosity level.
int G_debug(int level, const char *msg,...)
Print debugging message.
const char * G_getenv_nofatal(const char *name)
Get environment variable.
void G_set_keywords(const char *keywords)
Set keywords from the string.
void G__script(void)
Generate Python script-like output.
char * G_basename(char *filename, const char *desired_ext)
Truncates filename to the base part (before the last '.') if it matches the extension, otherwise leaves it unchanged.
const char * G_program_name(void)
Return module name.
int G_verbose_std(void)
Get standard verbosity level.
void G_free_tokens(char **tokens)
Free memory allocated to tokens.
int G_verbose(void)
Get current verbosity level.
void G_usage(void)
Command line help/usage message.
FILE * G_open_option_file(const struct Option *option)
Get an input/output file pointer from the option. If the file name is omitted or '-', it returns either stdin or stdout based on the gisprompt.
void G_disable_interactive(void)
Disables the ability of the parser to operate interactively.
char ** G_tokenize(const char *buf, const char *delim)
Tokenize string.
int G_verbose_min(void)
Get min verbosity level.
void G__print_keywords(FILE *fd, void(*format)(FILE *, const char *))
Print list of keywords (internal use only)
void G_add_keyword(const char *keyword)
Add keyword to the list.
int G_is_dirsep(char c)
Checks if a specified character is a valid directory separator character on the host system...
void G__wps_print_process_description(void)
Print the WPS 1.0.0 process description XML document to stdout.
void G_free(void *buf)
Free allocated memory.
const char * G_gisbase(void)
Get full path name of the top level module directory.
void G_warning(const char *msg,...)
Print a warning message to stderr.
int G_spawn(const char *command,...)
Spawn new process based on command.