示例#1
0
static void * con(void *arg)
{
	struct args *c;

	while(1){
		c = malloc(sizeof(struct args));
		copy_args(arg, c);
		
		/* Try to get exclusive access to count */
		pthread_mutex_lock(c->mutex_count);
		while(*(c->count) >= CONCURRENT_OPS){	
			pthread_cond_wait(c->cv_consumer, c->mutex_count);
		}	
	
		pthread_mutex_unlock(c->mutex_count);
	
		consume(*(c->count), (c->queue) , (c->queue_lock));
	
		pthread_mutex_lock(c->mutex_count);
		*(c->count)  = *(c->count) + 1;
		pthread_cond_signal(c->cv_producer);
		pthread_mutex_unlock(c->mutex_count);
		/* wakeup other threads that may be waiting on the queue */
		free(c);
	}
	return NULL;
}
示例#2
0
static
int
common_prog(int nargs, char **args)
{
	int result;
	char **args_copy;
#if OPT_SYNCHPROBS
	kprintf("Warning: this probably won't work with a "
		"synchronization-problems kernel.\n");
#endif

	/* demke: Make a copy of arguments to pass to new thread,
	 * so that we aren't depending on parent's stack!
	 */
	args_copy = copy_args(nargs, args);
	if (!args_copy) {
		return ENOMEM;
	}

	/* demke: and now call thread_fork with the copy */
	
	result = thread_fork(args_copy[0] /* thread name */,
			cmd_progthread /* thread function */,
			args_copy /* thread arg */, nargs /* thread arg */,
			NULL);
	if (result) {
		kprintf("thread_fork failed: %s\n", strerror(result));
		/* demke: need to free copy of args if fork fails */
		free_args(nargs, args_copy);
		return result;
	}

	return 0;
}
示例#3
0
static void * prod(void *arg)
{
	struct args *p;
	int i;
	int loop;

	for(loop = 0 ; loop < 50 ; loop++){
	p = malloc(sizeof(struct args));
	copy_args(arg, p);

	/* try getting exclusive access to p.count variable */

	pthread_mutex_lock(p->mutex_count);
	while(*(p->count) <= 0){
		pthread_cond_wait(p->cv_producer, p->mutex_count);
	}

	req_no++;
	*(p->count) = *(p->count)- 1; /* One more queue element filled */		
	produce(*(p->count), req_no, (p->queue) , (p->queue_lock));
	
	pthread_cond_signal(p->cv_consumer);
	pthread_mutex_unlock(p->mutex_count);

	free(p);
	}
	return NULL;
}
示例#4
0
文件: args.c 项目: mrdk/mind
void init_args(int argc, char *argv[])
{
    copy_args(argc, argv);

    // Default: start in interactive mode
    args.command = 0;
    args.interactive = TRUE;

    int opt;
    while ((opt = getopt(argc, argv, "he:x:")) != -1) {
	switch (opt) {
	case 'h':
            usage(argv[0]);
	    exit(0);
	case 'e':
	    args.command = (cell)optarg;
	    args.interactive = FALSE;
	    break;
	case 'x':
	    args.command = (cell)optarg;
	    args.interactive = TRUE;
	    break;
	default:
	    exit(-1);
	}
    }

    // The words `argv` and `argc` then contain the remaining
    // arguments, to be processed by the program.
    args.argc = argc - optind;
    args.argv = args.raw_argv + optind;
}
示例#5
0
文件: str.c 项目: itmm/waelzer
char *str_cons(int count, ...) {
	return_unless(count >= 0, empty, "count must not be negative");
	if (!count) { return empty; }

	va_list args1;
	va_list args2;
	va_start(args1, count);
	va_copy(args2, args1);
/*>
The calculation of the length is straight forward. We only have to watch out for `NULL` strings, that will be silently ignored.
<*/
	size_t length = 0;
	for (int i = count; i; --i) {
		const char *current = va_arg(args1, const char *);
		if (current) length += strlen(current);
	}
	va_end(args1);
/*>
The result buffer must be one byte bigger to store the terminating null byte.
<*/
	char *result = malloc(length + 1);
/*>
The `copy_args` function may throw an error. We put it in a different function, so we can free the second argument list, even, if an error is raised.
<*/
	copy_args(result, count, args2);
	va_end(args2);

	return result ? : empty;
}
示例#6
0
void start_core(int argc, char **argv) {

  int orig_argc = argc;
  char **orig_argv = copy_args(argc, argv);

  FLAGS_stderrthreshold = 0;
  FLAGS_logbuflevel = -1;

  google::ParseCommandLineFlags(&argc, &argv, true);

  google::InitGoogleLogging(argv[0]);

  auto conf = create_config();

  ld_environment(orig_argv, conf.rules_directory);

  free_args(orig_argc, orig_argv);

  log_config(conf);

  g_core = make_real_core(conf);

  g_core->start();

  g_core.reset();

  free_thread_ns();
}
示例#7
0
文件: menu.c 项目: Adam-Koza/A3
static
int
common_prog(int nargs, char **args)
{
	int result;
	char **args_copy;
#if OPT_SYNCHPROBS
	kprintf("Warning: this probably won't work with a "
		"synchronization-problems kernel.\n");
#endif

	/*
	 * Implementation of & option for menu when running programs.
	 * By default, menu will wait for user program to end before running.
	 * If on menu command line has a '&' at the end,
	 * it will not wait for the user program to end
	 * before continuing to run.
	 */

	bool toDetach;
	toDetach = false;
	pid_t childpid;
	if (*args[nargs - 1] == '&'){
		nargs--; // So we don't pass on &
		toDetach = true;
	}


	/* demke: Make a copy of arguments to pass to new thread,
	 * so that we aren't depending on parent's stack!
	 */
	args_copy = copy_args(nargs, args);
	if (!args_copy) {
		return ENOMEM;
	}

	/* demke: and now call thread_fork with the copy */
	
	result = thread_fork(args_copy[0] /* thread name */,
			cmd_progthread /* thread function */,
			args_copy /* thread arg */, nargs /* thread arg */,
			&childpid);
	if (result) {
		kprintf("thread_fork failed: %s\n", strerror(result));
		/* demke: need to free copy of args if fork fails */
		free_args(nargs, args_copy);
		return result;
	}

	// If toDetach, then wont wait for program to end before continuing menu.
	if (toDetach) {
		pid_detach(childpid);
	}
	// Wait for program to end before continuing
	// (unless it's detached, in which case join will do nothing.)
	pid_join(childpid, NULL, (int)NULL);

	return 0;
}
示例#8
0
static
int
common_prog(int nargs, char **args)
{
	int result;
	int join_result;
	int *status;
	char **args_copy;
	pid_t *ret;

#if OPT_SYNCHPROBS
	kprintf("Warning: this probably won't work with a "
		"synchronization-problems kernel.\n");
#endif

	/* demke: Make a copy of arguments to pass to new thread,
	 * so that we aren't depending on parent's stack!
	 */
	args_copy = copy_args(nargs, args);
	if (!args_copy) {
		return ENOMEM;
	}

	if(strcmp(args[nargs-2], "&") == 0) {
		ret = NULL; //This will cause thread_fork to detach the child
	}

	/* demke: and now call thread_fork with the copy */
	
	result = thread_fork(args_copy[0] /* thread name */,
			cmd_progthread /* thread function */,
			args_copy /* thread arg */, nargs /* thread arg */,
			ret);

	if (result) {

		kprintf("thread_fork failed: %s\n", strerror(result));
		/* demke: need to free copy of args if fork fails */
		free_args(nargs, args_copy);
		return result;

	} else if (result != 0 && ret != NULL) {

		join_result = pid_join(result, status, 0);

		if (status != 0 || join_result < 0) {
			return join_result;
		}

	}

	return 0;
}
示例#9
0
/*
 * Convert six control points marked as CS_FLEX_CTRL to a flex path.
 */
static void
do_othersubr0 (t1_chardesc *cd)
{
  t1_cpath *flex, *cur, *next;

  if (ps_stack_top < 1) {
    status = CS_PARSE_ERROR;
    return;
  }

  /* Seek first CS_FLEX_CTRL mark */
  for (cur = cd->charpath; cur != NULL && cur->type != CS_FLEX_CTRL; cur = cur->next);
  flex = cur;
  {
    int i;
    cur = cur->next;
    for (i = 1; i < 7; i++) {
      if (cur == NULL || cur->type != CS_FLEX_CTRL ||
          cur->num_args != 2) {
        status = CS_PARSE_ERROR;
        return;
      }
      if (i == 1) {
        flex->args[0] += cur->args[0];
        flex->args[1] += cur->args[1];
      } else {
        copy_args(&(flex->args[2*i-2]), cur->args, 2);
      }
      next = cur->next;
      RELEASE(cur);
      cur = next;
    }
  }
  if (cur != NULL) {
    status = CS_PARSE_ERROR;
    return;
  }
  /*
   * Now 'flex' have all six control points, the first pair is relative
   * from starting point.
   */
  flex->type = cs_flex;
  flex->args[12] = ps_arg_stack[--ps_stack_top]; /* flex depth */
  flex->num_args = 13;
  flex->next   = NULL;
  cd->lastpath = flex;

  phase = T1_CS_PHASE_PATH;
}
示例#10
0
int argify(const char *line, char ***argv_ptr)
{
  int argc;
  char ** argv;

  argc = count_args (line);
  if (argc == 0)
      return -1;
  argv = (char **)malloc (sizeof (char *) * argc);
  if (!argv) return -1;
  if (copy_args (line, argc, argv) < 0) return -1;
  *argv_ptr = argv;
  
  return argc;
}
示例#11
0
static int do_bootm_plan9(int flag, int argc, char * const argv[],
			   bootm_headers_t *images)
{
	void (*entry_point)(void);
	char *s;

	if (flag & BOOTM_STATE_OS_PREP)
		return 0;
	if ((flag != 0) && (flag != BOOTM_STATE_OS_GO))
		return 1;

#if defined(CONFIG_FIT)
	if (!images->legacy_hdr_valid) {
		fit_unsupported_reset("Plan 9");
		return 1;
	}
#endif

	/* See README.plan9 */
	s = getenv("confaddr");
	if (s != NULL) {
		char *confaddr = (char *)simple_strtoul(s, NULL, 16);

		if (argc > 0) {
			copy_args(confaddr, argc, argv, '\n');
		} else {
			s = getenv("bootargs");
			if (s != NULL)
				strcpy(confaddr, s);
		}
	}

	entry_point = (void (*)(void))images->ep;

	printf("## Transferring control to Plan 9 (at address %08lx) ...\n",
		(ulong)entry_point);

	bootstage_mark(BOOTSTAGE_ID_RUN_OS);

	/*
	 * Plan 9 Parameters:
	 *   None
	 */
	(*entry_point)();

	return 1;
}
示例#12
0
static
int
common_prog(int nargs, char **args)
{
	int result;
	char **args_copy;
#if OPT_SYNCHPROBS
	kprintf("Warning: this probably won't work with a "
		"synchronization-problems kernel.\n");
#endif

	/* demke: Make a copy of arguments to pass to new thread,
	 * so that we aren't depending on parent's stack!
	 */
	args_copy = copy_args(nargs, args);
	if (!args_copy) {
		return ENOMEM;
	}

	/* demke: and now call thread_fork with the copy */
	
	result = thread_fork(args_copy[0] /* thread name */,
			cmd_progthread /* thread function */,
			args_copy /* thread arg */, nargs /* thread arg */,
			NULL);
	if (result) {
		kprintf("thread_fork failed: %s\n", strerror(result));
		/* demke: need to free copy of args if fork fails */
		free_args(nargs, args_copy);
		return result;
	}

	/* BEGIN A3 SETUP */
	/* This is not needed if you have a working pid_join -
	 * that should be used instead.
	 */
	/* Wait for progthread to finish and send a V() */
	P(cmd_sem);
	/* END A3 SETUP */

	return 0;
}
示例#13
0
static int do_bootm_netbsd(int flag, int argc, char * const argv[],
			    bootm_headers_t *images)
{
	void (*loader)(bd_t *, image_header_t *, char *, char *);
	image_header_t *os_hdr, *hdr;
	ulong kernel_data, kernel_len;
	char *consdev;
	char *cmdline;

	if (flag != BOOTM_STATE_OS_GO)
		return 0;

#if defined(CONFIG_FIT)
	if (!images->legacy_hdr_valid) {
		fit_unsupported_reset("NetBSD");
		return 1;
	}
#endif
	hdr = images->legacy_hdr_os;

	/*
	 * Booting a (NetBSD) kernel image
	 *
	 * This process is pretty similar to a standalone application:
	 * The (first part of an multi-) image must be a stage-2 loader,
	 * which in turn is responsible for loading & invoking the actual
	 * kernel.  The only differences are the parameters being passed:
	 * besides the board info strucure, the loader expects a command
	 * line, the name of the console device, and (optionally) the
	 * address of the original image header.
	 */
	os_hdr = NULL;
	if (image_check_type(&images->legacy_hdr_os_copy, IH_TYPE_MULTI)) {
		image_multi_getimg(hdr, 1, &kernel_data, &kernel_len);
		if (kernel_len)
			os_hdr = hdr;
	}

	consdev = "";
#if   defined(CONFIG_8xx_CONS_SMC1)
	consdev = "smc1";
#elif defined(CONFIG_8xx_CONS_SMC2)
	consdev = "smc2";
#elif defined(CONFIG_8xx_CONS_SCC2)
	consdev = "scc2";
#elif defined(CONFIG_8xx_CONS_SCC3)
	consdev = "scc3";
#endif

	if (argc > 0) {
		ulong len;
		int   i;

		for (i = 0, len = 0; i < argc; i += 1)
			len += strlen(argv[i]) + 1;
		cmdline = malloc(len);
		copy_args(cmdline, argc, argv, ' ');
	} else if ((cmdline = getenv("bootargs")) == NULL) {
		cmdline = "";
	}

	loader = (void (*)(bd_t *, image_header_t *, char *, char *))images->ep;

	printf("## Transferring control to NetBSD stage-2 loader "
		"(at address %08lx) ...\n",
		(ulong)loader);

	bootstage_mark(BOOTSTAGE_ID_RUN_OS);

	/*
	 * NetBSD Stage-2 Loader Parameters:
	 *   arg[0]: pointer to board info data
	 *   arg[1]: image load address
	 *   arg[2]: char pointer to the console device to use
	 *   arg[3]: char pointer to the boot arguments
	 */
	(*loader)(gd->bd, os_hdr, consdev, cmdline);

	return 1;
}
示例#14
0
int
main(int argc, char **argv)
{
   int i, do_precache = 0, valgrind_mode = 0;
   int valgrind_tool = 0;
   char buf[16384], **args, *p;
   char valgrind_path[PATH_MAX] = "";
   const char *valgrind_log = NULL;

   eina_init();
   prefix_determine(argv[0]);

   env_set("E_START", argv[0]);

   p = getenv("PATH");
   if (p) snprintf(buf, sizeof(buf), "%s:%s", eina_prefix_bin_get(pfx), p);
   else snprintf(buf, sizeof(buf), "%s", eina_prefix_bin_get(pfx));
   env_set("PATH", buf);

   p = getenv("LD_LIBRARY_PATH");
   if (p) snprintf(buf, sizeof(buf), "%s:%s", eina_prefix_lib_get(pfx), p);
   else snprintf(buf, sizeof(buf), "%s", eina_prefix_lib_get(pfx));
   env_set("LD_LIBRARY_PATH", buf);

   for (i = 1; i < argc; i++)
     {
	if (!strcmp(argv[i], "-no-precache")) do_precache = 0;
	else if (!strncmp(argv[i], "-valgrind", sizeof("-valgrind") - 1))
	  {
	     const char *val = argv[i] + sizeof("-valgrind") - 1;

	     if (*val == '\0') valgrind_mode = 1;
	     else if (*val == '-')
	       {
		  val++;
		  if (!strncmp(val, "log-file=", sizeof("log-file=") - 1))
		    {
		       valgrind_log = val + sizeof("log-file=") - 1;
		       if (*valgrind_log == '\0') valgrind_log = NULL;
		    }
	       }
	     else if (*val == '=')
	       {
		  val++;
		  if (!strcmp(val, "all")) valgrind_mode = VALGRIND_MODE_ALL;
		  else valgrind_mode = atoi(val);
	       }
	     else
                printf("Unknown valgrind option: %s\n", argv[i]);
	  }
	else if (!strcmp(argv[i], "-massif")) valgrind_tool = 1;
	else if (!strcmp(argv[i], "-callgrind")) valgrind_tool = 2;
        else if ((!strcmp(argv[i], "-h")) ||
		 (!strcmp(argv[i], "-help")) ||
		 (!strcmp(argv[i], "--help")))
	  {
	     printf
                (
                    "Options:\n"
                    "\t-no-precache\n"
                    "\t\tDisable pre-caching of files\n"
                    "\t-valgrind[=MODE]\n"
                    "\t\tRun enlightenment from inside valgrind, mode is OR of:\n"
                    "\t\t   1 = plain valgrind to catch crashes (default)\n"
                    "\t\t   2 = trace children (thumbnailer, efm slaves, ...)\n"
                    "\t\t   4 = check leak\n"
                    "\t\t   8 = show reachable after processes finish.\n"
                    "\t\t all = all of above\n"
                    "\t-massif\n"
                    "\t\tRun enlightenment from inside massif valgrind tool.\n"
                    "\t-callgrind\n"
                    "\t\tRun enlightenment from inside callgrind valgrind tool.\n"
                    "\t-valgrind-log-file=<FILENAME>\n"
                    "\t\tSave valgrind log to file, see valgrind's --log-file for details.\n"
                    "\n"
                    "Please run:\n"
                    "\tenlightenment %s\n"
                    "for more options.\n",
                    argv[i]);
	     exit(0);
	  }
     }

   if (valgrind_mode || valgrind_tool)
     {
	if (!find_valgrind(valgrind_path, sizeof(valgrind_path)))
	  {
	     printf("E - valgrind required but no binary found! Ignoring request.\n");
	     valgrind_mode = 0;
	  }
     }
   
   printf("E - PID=%i, do_precache=%i, valgrind=%d", getpid(), do_precache, valgrind_mode);
   if (valgrind_mode)
     {
	printf(" valgrind-command='%s'", valgrind_path);
	if (valgrind_log) printf(" valgrind-log-file='%s'", valgrind_log);
     }
   putchar('\n');
   
   if (do_precache)
     {
	void *lib, *func;
        
	/* sanity checks - if precache might fail - check here first */
	lib = dlopen("libeina.so", RTLD_GLOBAL | RTLD_LAZY);
	if (!lib) dlopen("libeina.so.1", RTLD_GLOBAL | RTLD_LAZY);
	if (!lib) goto done;
	func = dlsym(lib, "eina_init");
	if (!func) goto done;

	lib = dlopen("libecore.so", RTLD_GLOBAL | RTLD_LAZY);
	if (!lib) dlopen("libecore.so.1", RTLD_GLOBAL | RTLD_LAZY);
	if (!lib) goto done;
	func = dlsym(lib, "ecore_init");
	if (!func) goto done;

	lib = dlopen("libecore_file.so", RTLD_GLOBAL | RTLD_LAZY);
	if (!lib) dlopen("libecore_file.so.1", RTLD_GLOBAL | RTLD_LAZY);
	if (!lib) goto done;
	func = dlsym(lib, "ecore_file_init");
	if (!func) goto done;

	lib = dlopen("libecore_x.so", RTLD_GLOBAL | RTLD_LAZY);
	if (!lib) dlopen("libecore_x.so.1", RTLD_GLOBAL | RTLD_LAZY);
	if (!lib) goto done;
	func = dlsym(lib, "ecore_x_init");
	if (!func) goto done;

	lib = dlopen("libevas.so", RTLD_GLOBAL | RTLD_LAZY);
	if (!lib) dlopen("libevas.so.1", RTLD_GLOBAL | RTLD_LAZY);
	if (!lib) goto done;
	func = dlsym(lib, "evas_init");
	if (!func) goto done;

	lib = dlopen("libedje.so", RTLD_GLOBAL | RTLD_LAZY);
	if (!lib) dlopen("libedje.so.1", RTLD_GLOBAL | RTLD_LAZY);
	if (!lib) goto done;
	func = dlsym(lib, "edje_init");
	if (!func) goto done;

	lib = dlopen("libeet.so", RTLD_GLOBAL | RTLD_LAZY);
	if (!lib) dlopen("libeet.so.0", RTLD_GLOBAL | RTLD_LAZY);
	if (!lib) goto done;
	func = dlsym(lib, "eet_init");
	if (!func) goto done;

	/* precache SHOULD work */
	snprintf(buf, sizeof(buf), "%s/enlightenment/preload/e_precache.so",
                 eina_prefix_lib_get(pfx));
	env_set("LD_PRELOAD", buf);
	printf("E - PRECACHE GOING NOW...\n");
	fflush(stdout);
	precache();
     }
done:
   
   /* mtrack memory tracker support */
   p = getenv("HOME");
   if (p)
     {
        FILE *f;

        /* if you have ~/.e-mtrack, then the tracker will be enabled
         * using the content of this file as the path to the mtrack.so
         * shared object that is the mtrack preload */
        snprintf(buf, sizeof(buf), "%s/.e-mtrack", p);
        f = fopen(buf, "r");
        if (f)
          {
             if (fgets(buf, sizeof(buf), f))
               {
                  int len = strlen(buf);
                  if ((len > 1) && (buf[len - 1] == '\n'))
                    {
                       buf[len - 1] = 0;
                       len--;
                    }
                  env_set("LD_PRELOAD", buf);
                  env_set("MTRACK", "track");
                  env_set("E_START_MTRACK", "track");
                  snprintf(buf, sizeof(buf), "%s/.e-mtrack.log", p);
                  env_set("MTRACK_TRACE_FILE", buf);
               }
             fclose(f);
          }
     }
   
   /* try dbus-launch */
   snprintf(buf, sizeof(buf), "%s/enlightenment", eina_prefix_bin_get(pfx));

   args = alloca((argc + 2 + VALGRIND_MAX_ARGS) * sizeof(char *));
   if ((!getenv("DBUS_SESSION_BUS_ADDRESS")) &&
       (!getenv("DBUS_LAUNCHD_SESSION_BUS_SOCKET")))
     {
	args[0] = "dbus-launch";
	args[1] = "--exit-with-session";
        
	i = 2 + valgrind_append(args + 2, valgrind_mode, valgrind_tool, valgrind_path, valgrind_log);
	args[i++] = buf;
	copy_args(args + i, argv + 1, argc - 1);
	args[i + argc - 1] = NULL;
	execvp("dbus-launch", args);
     }
   
   /* dbus-launch failed - run e direct */
   i = valgrind_append(args, valgrind_mode, valgrind_tool, valgrind_path, valgrind_log);
   args[i++] = buf;
   copy_args(args + i, argv + 1, argc - 1);
   args[i + argc - 1] = NULL;
   execv(args[0], args);

   printf("FAILED TO RUN:\n");
   printf("  %s\n", buf);
   perror("execv");
   return -1;
}
示例#15
0
/*
 * -- do_config
 *
 * Apply the configuration on the map. It expects each useful line to 
 * start with a known keyword. Note the unconventional return values. 
 * It returns NULL if successful or an error string in case of error.
 *
 */
static char * 
do_config(struct _como * m, int argc, char *argv[])
{
    static char errstr[1024]; 
    static int scope = CTX_GLOBAL;      	/* scope of current keyword */
    static module_t * mdl = NULL;       	/* module currently open */
    static int node_id = 0; 			/* current node */
    static alias_t * alias = NULL;       	/* alias currently open */
    keyword_t *t;

    /*
     * run some checks on the token (i.e., that it exists
     * and that we have all the arguments it needs).
     */
    t = match_token(argv[0], keywords);
    if (t == NULL) {
	sprintf(errstr, "unknown token \"%s\"\n", argv[0]);
        return errstr;
    }

    if (argc < t->nargs) {
	sprintf(errstr, "\"%s\", requires at least %d arguments\n", argv[0],
	      t->nargs);
        return errstr;
    }

    /*
     * Check if the keyword is ok in the current scope.
     */
    if (!(t->scope & scope)) {
	sprintf(errstr, "\"%s\" out of scope\n", argv[0]);
        return errstr;
    }

    /*
     * configuration actions
     */
    switch (t->action) {
    case TOK_DBDIR:
	if (m->cli_args.dbdir_set == 0) {
	    safe_dup(&m->dbdir, argv[1]);
	}
	break;

    case TOK_QUERYPORT:
	if (m->cli_args.query_port_set == 0 || node_id > 0) {
	    m->node[node_id].query_port = atoi(argv[1]);
	}
	break;

    case TOK_DESCRIPTION:
	if (scope == CTX_MODULE) 
	    safe_dup(&mdl->description, argv[1]);
	else 
	    safe_dup(&alias->description, argv[1]);
	break;

    case TOK_END:
	if (scope == CTX_MODULE) { 
	    /*
	     * "end" of a module configuration.  run some checks depending 
	     * on context to make sure that all mandatory fields are there
	     * and set default values
	     */

	    if (check_module(m, mdl)) { 
		remove_module(m, mdl); 
		scope = CTX_GLOBAL;
		break;
	    }

	    if (m->runmode == RUNMODE_INLINE) 
		m->inline_mdl = mdl;

	    logmsg(LOGUI, "... module%s %s [%d][%d] ", 
		   (mdl->running == RUNNING_ON_DEMAND) ? " on-demand" : "",
		   mdl->name, mdl->node, mdl->priority); 
	    logmsg(LOGUI, " filter %s; out %s (%uMB)\n", 
		   mdl->filter_str, mdl->output, mdl->streamsize/(1024*1024));
        } else if (scope == CTX_VIRTUAL) { 
	    /* 
	     * we are done with this virtual node. let's go back to 
	     * the master node (i.e. node_id == 0)
	     */
	    node_id = 0; 
	}
	scope = CTX_GLOBAL; 
	break;
	    
    case TOK_FILTER:
	if (scope == CTX_MODULE) 
            safe_dup(&mdl->filter_str, argv[1]);
        else if (scope == CTX_VIRTUAL) 
	    safe_dup(&m->node[node_id].filter_str, argv[1]);
	break;

    case TOK_HASHSIZE:
        mdl->ex_hashsize = mdl->ca_hashsize = atoi(argv[1]);
        break;

    case TOK_SOURCE:
	if (scope == CTX_MODULE) { 
	    safe_dup(&mdl->source, argv[1]);
	} else { 
	    safe_dup(&m->node[node_id].source, argv[1]);
	} 
	break;

    case TOK_LIBRARYDIR:
	if (m->cli_args.libdir_set == 0) {
	    safe_dup(&m->libdir, argv[1]);
	}
	break;

    case TOK_LOGFLAGS:
	if (m->cli_args.logflags_set == 0) {
	    m->logflags = set_flags(0, argv[1]);
	}
	break;

    case TOK_MEMSIZE:
	/* this keyword can be used in two contexts */
	if (m->cli_args.mem_size_set == 0) {
	    m->mem_size = atoi(argv[1]);
	}
	break;

    case TOK_MODULE:
	if (scope == CTX_GLOBAL) {
	    int node = (m->runmode == RUNMODE_INLINE? -1 : 0);
	    mdl = new_module(m, argv[1], node, -1);
	    scope = CTX_MODULE; 		/* change scope */
	} else { 
	    safe_dup(&alias->module, argv[1]);
	} 
        break;
        
    case TOK_MODULE_MAX:
	m->module_max = atoi(argv[1]);
	m->modules = safe_realloc(m->modules, sizeof(module_t)*m->module_max); 
        break;

    case TOK_OUTPUT:
        safe_dup(&mdl->output, argv[1]);
	break;

    case TOK_SNIFFER:
	add_sniffer(m, argv[1], argv[2], argc > 3 ? argv[3] : NULL);
        break;

    case TOK_STREAMSIZE: 
	mdl->streamsize = parse_size(argv[1]);
	break;

    case TOK_MAXFILESIZE: 
	m->maxfilesize = parse_size(argv[1]); 
	if (m->maxfilesize > 1024*1024*1024) { 
	    m->maxfilesize = DEFAULT_FILESIZE; 
	    sprintf(errstr, "'filesize' should be < 1GB --> set to %dMB\n", 
		    (int)(m->maxfilesize / (1024*1024)));
	    return errstr; 
	} 
	break;

    case TOK_ARGS: 
	/* copy the arguments. one line may have multiple arguments 
 	 * starting from argv[1]. that's why we pass the pointer to 
	 * argv[1] and reduce argc by one. 
	 */
	if (scope == CTX_MODULE) 
	    mdl->args = copy_args(mdl->args, &argv[1], argc - 1); 
	else if (scope == CTX_VIRTUAL) 
	    m->node[node_id].args = copy_args(m->node->args, &argv[1], argc-1); 
        else if (scope == CTX_ALIAS) {
	    alias->args = copy_args(alias->args, &argv[1], argc - 1); 
	    alias->ac += argc - 1; 
	} 
	break;

    case TOK_ARGSFILE: 
	if (scope == CTX_MODULE) {
	    mdl->args = copy_args_from_file(mdl->args, argv[1], NULL); 
	} else if (scope == CTX_VIRTUAL) {
	    m->node[node_id].args = 
		copy_args_from_file(m->node[node_id].args, argv[1], NULL); 
        } else if (scope == CTX_ALIAS) {
	    int count; 
	    alias->args = copy_args_from_file(alias->args, argv[1], &count); 
	    alias->ac += count; 
	} 
	break; 
    
    case TOK_PRIORITY: 
        mdl->priority = atoi(argv[1]);
	break; 

    case TOK_RUNNING: 
        mdl->running = (strcmp(argv[1], "on-demand") == 0) ?
		       RUNNING_ON_DEMAND : RUNNING_NORMAL;
	break; 

    case TOK_NAME: 
        safe_dup(&m->node[node_id].name, argv[1]);
	break; 

    case TOK_LOCATION:
        safe_dup(&m->node[node_id].location, argv[1]);
	break; 

    case TOK_TYPE:
        safe_dup(&m->node[node_id].type, argv[1]);
	break; 

    case TOK_COMMENT: 
        safe_dup(&m->node[node_id].comment, argv[1]);
	break; 

    case TOK_VIRTUAL: 
	m->node = safe_realloc(m->node, (m->node_count + 1) * sizeof(node_t)); 
	node_id = m->node_count; 
	bzero(&m->node[node_id], sizeof(node_t)); 
	safe_dup(&m->node[node_id].name, argv[1]);
	m->node[node_id].location = strdup("Unknown");
	m->node[node_id].type = strdup("Unknown");
	m->node_count++;
	scope = CTX_VIRTUAL; 
	break;

    case TOK_ALIAS: 
	alias = safe_calloc(1, sizeof(alias_t)); 
	safe_dup(&alias->name, argv[1]);
	alias->next = m->aliases;
	m->aliases = alias; 
	scope = CTX_ALIAS; 
	break;

    case TOK_ASNFILE:
	safe_dup(&m->asnfile, argv[1]);
	break;

    case TOK_LIVE_THRESH:
	m->live_thresh = TIME2TS(0, atoi(argv[1]));
	break;

    default:
	sprintf(errstr, "unknown keyword %s\n", argv[0]);
	return errstr; 
    }

    return NULL;
}
示例#16
0
/*
 * -- configure
 *
 * do a first pass of the command line parameters to find all
 * configuration files. the options in those files are processed
 * before any other command line parameter. command line will
 * overwrite any other configuration, as well as the last config
 * file will overwrite previous config files.
 *
 */
void
configure(struct _como * m, int argc, char ** argv)
{
    cli_args_t cli_args;
    int config_file_exists;
    int c, i, j;
    DIR *d;
    
    if (m->cli_args.done_flag == 0) {
	parse_cmdline(&cli_args, argc, argv);

	if (cli_args.logflags != -1) {
	    m->logflags = cli_args.logflags;
	    m->cli_args.logflags_set = 1;
	}
	if (cli_args.dbdir != NULL) {
	    safe_dup(&m->dbdir, cli_args.dbdir);
	    m->cli_args.dbdir_set = 1;
	}
	if (cli_args.libdir != NULL) {
	    safe_dup(&m->libdir, cli_args.libdir);
	    m->cli_args.libdir_set = 1;
	}
	if (cli_args.query_port != -1) {
	    m->node->query_port = cli_args.query_port;
	    m->cli_args.query_port_set = 1;
	}
	if (cli_args.mem_size != 0) {
	    m->mem_size = cli_args.mem_size;
	    m->cli_args.mem_size_set = 1;
	}
	m->exit_when_done = cli_args.exit_when_done;
    }
    
    m->runmode = cli_args.runmode;
    m->inline_fd = (m->runmode == RUNMODE_INLINE) ? 1 /* stdout */ : -1; 
    
    m->debug = cli_args.debug;

    /*
     * build list of config files
     */
    config_file_exists = 0;
    for (c = 0; c < cli_args.cfg_files_count; c++) {
	config_file_exists = 1;
	parse_cfgfile(m, cli_args.cfg_files[c]);
    }
    
    if (!config_file_exists && m->runmode != RUNMODE_INLINE) 
        parse_cfgfile(m, DEFAULT_CFGFILE);	/* add default config file */

    if (m->runmode == RUNMODE_INLINE) {
	char *conf_argv[2];
	
	m->exit_when_done = 1;
	
    	if (cli_args.sniffer != NULL) {
	    add_sniffer(m, cli_args.sniffer, NULL, NULL);
    	}
    	
	/* prepare the arguments for do_config() */
	conf_argv[0] = "module";
	conf_argv[1] = cli_args.module;
	do_config(m, 2, conf_argv);

	if (cli_args.module_args != NULL) {
	    conf_argv[0] = "args";
	    conf_argv[1] = cli_args.module_args;
	    do_config(m, 2, conf_argv);
	}
	
	if (cli_args.filter != NULL) {
	    conf_argv[0] = "filter";
	    conf_argv[1] = cli_args.filter;
	    do_config(m, 2, conf_argv);
	}
	
	conf_argv[0] = "end";
	do_config(m, 1, conf_argv);
    }

    /* 
     * now look into the virtual nodes and replicate
     * all modules that have been found in the config file(s)
     * 
     * these new modules will have the same name but will be 
     * running the additional filter associated with the virtual 
     * node and save data in the virtual node dbdir.  
     * 
     * XXX all virtual nodes will be running on demand and 
     *     the source is defined in the configuration (or assumed to 
     *     be a trace module). later there shouldn't be a need 
     *     for defining the source module anyway...
     *
     */
    for (i = 0, j = m->module_last; i <= j; i++) { 
	module_t * orig; 
	int node_id; 

	orig = &m->modules[i]; 
	for (node_id = 1; node_id < m->node_count; node_id++) { 
	    module_t * mdl; 
	    char * nm; 

	    /* create a new module and copy it from  new module */
	    mdl = copy_module(m, orig, node_id, -1, m->node[node_id].args);
	    mdl->running = RUNNING_ON_DEMAND; 
	    
	    /* append node id to module's output file */
	    asprintf(&nm, "%s-%d", mdl->output, mdl->node); 
	    safe_dup(&mdl->output, nm); 
	    free(nm); 
	    
	    /* add the node filter to the module filter */
	    if (m->node[node_id].filter_str) {
		char * flt;
		if (!strcmp(mdl->filter_str, "all"))
		    asprintf(&flt, "%s", m->node[node_id].filter_str);
		else 
		    asprintf(&flt,"(%s) and (%s)", 
			m->node[node_id].filter_str, mdl->filter_str);
		mdl->filter_str = flt; /* FIXME: possible leak */
	    } 

	    /* add the node arguments to the module arguments */ 
	    if (m->node[node_id].args) { 
		int k; 

	 	for (k = 0; m->node[node_id].args[k]; k++) {
		    /* 
		     * XXX we copy one argument at a time to avoid 
		     *     having to count them first. FIX THIS
		     */ 
		    mdl->args = 
			copy_args(mdl->args, &m->node[node_id].args[k], 1); 
		}
	    } 

            logmsg(LOGUI, "... module%s %s [%d][%d] ",
                   (mdl->running == RUNNING_ON_DEMAND) ? " on-demand" : "",
                   mdl->name, mdl->node, mdl->priority);
            logmsg(LOGUI, " filter %s; out %s (%uMB)\n",
                   mdl->filter_str, mdl->output, mdl->streamsize/(1024*1024));
            if (mdl->description != NULL)
                logmsg(LOGUI, "    -- %s\n", mdl->description);
	}
    }

    /* 
     * open the dbdir for all nodes (virtual ones included) 
     */
    if (m->runmode == RUNMODE_NORMAL) {
	if (m->dbdir == NULL)
	    panicx("missing db-path");
	d = opendir(m->dbdir);
	if (d == NULL) 
	    createdir(m->dbdir); 
	else 
	    closedir(d);
    }

    /*
     * process the AS file
     */

    asn_readfile(m->asnfile);
}
示例#17
0
文件: execv.c 项目: script3r/os161
int	
sys_execv( userptr_t upname, userptr_t uargs ) {
	struct addrspace		*as_new = NULL;
	struct addrspace		*as_old = NULL;
	struct vnode			*vn = NULL;
	vaddr_t				entry_ptr;
	vaddr_t				stack_ptr;
	int				err;
	char				kpname[MAX_PROG_NAME];
	int				nargs;
	int				buflen;

	KASSERT( curthread != NULL );
	KASSERT( curthread->td_proc != NULL );
	
	(void)uargs;
	
	//lock the execv args
	lock_acquire( lk_exec );

	//copy the old addrspace just in case.
	as_old = curthread->t_addrspace;

	//copyin the program name.
	err = copyinstr( upname, kpname, sizeof( kpname ), NULL );
	if( err ) {
		lock_release( lk_exec );
		return err;
	}
	
	//try to open the given executable.
	err = vfs_open( kpname, O_RDONLY, 0, &vn );
	if( err ) {
		lock_release( lk_exec );
		return err;
	}

	//copy the arguments into the kernel buffer.
	err = copy_args( uargs, &nargs, &buflen );
	if( err ) {
		lock_release( lk_exec );
		vfs_close( vn );
		return err;
	}

	//create the new addrspace.
	as_new = as_create();
	if( as_new == NULL ) {
		lock_release( lk_exec );
		vfs_close( vn );
		return ENOMEM;
	}
	
	//activate the new addrspace.
	as_activate( as_new );

	//temporarily switch the addrspaces.
	curthread->t_addrspace = as_new;

	//load the elf executable.
	err = load_elf( vn, &entry_ptr );
	if( err ) {
		curthread->t_addrspace = as_old;
		as_activate( as_old );
	
		as_destroy( as_new );
		vfs_close( vn );
		lock_release( lk_exec );
		return err;
	}

	//create a stack for the new addrspace.
	err = as_define_stack( as_new, &stack_ptr );
	if( err ) {
		curthread->t_addrspace = as_old;
		as_activate( as_old );

		as_destroy( as_new );
		vfs_close( vn );
		lock_release( lk_exec );
		return err;
	}
	
	//adjust the stackptr to reflect the change
	stack_ptr -= buflen;
	err = adjust_kargbuf( nargs, stack_ptr );
	if( err ) {
		curthread->t_addrspace = as_old;
		as_activate( as_old );

		as_destroy( as_new );
		vfs_close( vn );
		lock_release( lk_exec );
		return err;
	}

	//copy the arguments into the new user stack.
	err = copyout( kargbuf, (userptr_t)stack_ptr, buflen );
	if( err ) {
		curthread->t_addrspace = as_old;
		as_activate( as_old );
		as_destroy( as_new );
		vfs_close( vn );
		lock_release( lk_exec );
		return err;
	}

	//reelase lk_exec
	lock_release( lk_exec );

	//no need for it anymore.
	vfs_close( vn );

	//we are good to go.
	as_destroy( as_old );
	
	//off we go to userland.
	enter_new_process( nargs-1, (userptr_t)stack_ptr, stack_ptr, entry_ptr );
	
	panic( "execv: we should not be here." );
	return EINVAL;
}
示例#18
0
/* simulate_set performs the required piping to setup and run a simulation with the given parameters
	parameters:
		parameters: the parameters to pass as a parameter set to the simulation
	returns: the score the simulation received
	notes:
	todo:
*/
void simulate_set (parameters& pr) {
	ostream& v = term->verbose();
	for (int i = 0 ; i < pr.num_sets/NUM_SETS_PER_SIM; i++){
		// Create a pipe
		int sim_in[2];
		int sim_out[2]; 
		v << "  ";
		v << term->blue << "Creating a pipe " << term->reset << ". . . ";
		if (pipe(sim_in) == -1 || pipe(sim_out) == -1) {
			term->failed_pipe_create();
			exit(EXIT_PIPE_CREATE_ERROR);
		}
		v << term->blue << "Done: " << term->reset << "parent_read " << sim_out[0] << " parent_write " << sim_in[1] << " child_write " << sim_out[1] << " child_read "<< sim_in[0] << endl;
		
		int parent_read = sim_out[0];
		int parent_write = sim_in[1];
		int child_write = sim_out[1];
		int child_read = sim_in[0];
		
		cout << ip.sim_args[0] << ip.sim_args[1] << ip.sim_args[2]<< endl;
		// Copy the user-specified simulation arguments and fill the copy with the pipe's file descriptors
		char** sim_args = copy_args(ip.sim_args, ip.num_sim_args);
		cout << "after storing pipe"<< endl;
		store_pipe(sim_args, ip.num_sim_args - 4, child_read);
		store_pipe(sim_args, ip.num_sim_args - 2, child_write);
		
		// Fork the process so the child can run the simulation
		v << "  ";
		v << term->blue << "Forking the process " << term->reset << ". . . ";
		pid_t pid = fork();
		if (pid == -1) {
			term->failed_fork();
			exit(EXIT_FORK_ERROR);
		}
		if (pid == 0) { // The child runs the simulation
			v << "  ";
			v << term->blue << "Checking that the simulation file exists and can be executed " << term->reset << ". . . ";
			if (access(ip.sim_file, X_OK) == -1) {
				term->failed_exec();
				exit(EXIT_EXEC_ERROR);
			}
			term->done(v);
			if (execv(ip.sim_file, sim_args) == -1) {
				term->failed_exec();
				exit(EXIT_EXEC_ERROR);
			}
		}
		else { // The parent pipes in the parameter set to run
			v << term->blue << "Done: " << term->reset << "the child process's PID is " << pid << endl;
			v << "  ";
			v << term->blue << "Writing to the pipe " << term->reset << "(file descriptor " << parent_write << ") . . . ";
			write_pipe(parent_write, pr, i);
			term->done(v);
		}
		
		// Wait for the child to finish simulating
		int status = 0;
		waitpid(pid, &status, WUNTRACED);
		if (WIFEXITED(status) == 0) {
			term->failed_child();
			exit(EXIT_CHILD_ERROR);
		}
		
		
		// Pipe in the simulation's score
		double* score;
		v << "  ";
		v << term->blue << "Reading the pipe " << term->reset << "(file descriptor " << parent_read << ") . . . ";
		read_pipe(parent_read, &score);
		v << term->blue << "Done: " << term->reset << "(raw score " << score << " / " << 1 << ")" << endl;
	
		// CLOSE PIPES
		v << "  ";
		v << term->blue << "Closing the the pipes " << term->reset << "(file descriptor " << parent_read << ", "<< parent_write << ", " << child_read << ", " << child_write<< ") . . . ";
		if (close(parent_read) == -1) {
			term->failed_pipe_read();
			exit(EXIT_PIPE_WRITE_ERROR);
		}
		
		if (close(parent_write) == -1) {
			term->failed_pipe_write();
			exit(EXIT_PIPE_WRITE_ERROR);
		}
	
		if (close(child_read) == -1) {
			term->failed_pipe_write();
			exit(EXIT_PIPE_WRITE_ERROR);
		}
		
		if (close(child_write) == -1) {
			term->failed_pipe_write();
			exit(EXIT_PIPE_WRITE_ERROR);
		}
		term->done(v);
		
		print_good_set(pr, &score, i);
		
		// Free the simulation arguments
		for (int i = 0; sim_args[i] != NULL; i++) {
			mfree(sim_args[i]);
		}
		mfree(sim_args);
	}
}
示例#19
0
/* simulate_set performs the required piping to setup and run a simulation with the given parameters
	parameters:
		parameters: the parameters to pass as a parameter set to the simulation
	returns: the score the simulation received
	notes:
	todo:
*/
double simulate_set (double parameters[]) {
	// Get the MPI rank of the process
	int rank = get_rank();
	ostream& v = term->verbose();

	// Create a pipe
	int sim_in[2];
	int sim_out[2]; 
	
	v << "  ";
	term->rank(rank, v);
	v << term->blue << "Creating a pipe " << term->reset << ". . . ";
	if (pipe(sim_in) == -1 || pipe(sim_out) == -1) {
		term->failed_pipe_create();
		exit(EXIT_PIPE_CREATE_ERROR);
	}
	v << term->blue << "Done: " << term->reset << "parent_read " << sim_out[0] << " parent_write " << sim_in[1] << " child_write " << sim_out[1] << " child_read "<< sim_in[0] << endl;
	
	int parent_read = sim_out[0];
	int parent_write = sim_in[1];
	int child_write = sim_out[1];
	int child_read = sim_in[0];
	// Copy the user-specified simulation arguments and fill the copy with the pipe's file descriptors
	char** sim_args = copy_args(ip.sim_args, ip.num_sim_args);
	store_pipe(sim_args, ip.num_sim_args - 4, child_read);
	store_pipe(sim_args, ip.num_sim_args - 2, child_write);
	
	// Fork the process so the child can run the simulation
	v << "  ";
	term->rank(rank, v);
	v << term->blue << "Forking the process " << term->reset << ". . . ";
	pid_t pid = fork();
	if (pid == -1) {
		term->failed_fork();
		exit(EXIT_FORK_ERROR);
	}
	if (pid == 0) { // The child runs the simulation
		v << "  ";
		term->rank(rank, v);
		v << term->blue << "Checking that the simulation file exists and can be executed " << term->reset << ". . . ";
		if (access(ip.sim_file, X_OK) == -1) {
			term->failed_exec();
			exit(EXIT_EXEC_ERROR);
		}
		term->done(v);
		if (execv(ip.sim_file, sim_args) == -1) {
			term->failed_exec();
			exit(EXIT_EXEC_ERROR);
		}
	} else { // The parent pipes in the parameter set to run
		v << term->blue << "Done: " << term->reset << "the child process's PID is " << pid << endl;
		v << "  ";
		term->rank(rank, v);
		v << term->blue << "Writing to the pipe " << term->reset << "(file descriptor " << parent_write << ") . . . ";
		write_pipe(parent_write, parameters);
		term->done(v);
	}
	
	// Wait for the child to finish simulating
	int status = 0;
	waitpid(pid, &status, WUNTRACED);
	if (WIFEXITED(status) == 0) {
		term->failed_child();
		exit(EXIT_CHILD_ERROR);
	}
	
	
	// Pipe in the simulation's score
	//double max_score;
	double score;
	double cond_score;
	double exp_score;
	v << "  ";
	term->rank(rank, v);
	v << term->blue << "Reading the pipe " << term->reset << "(file descriptor " << parent_read << ") . . . ";
	read_pipe(parent_read, &score, &cond_score, &exp_score);
	v << term->blue << "Done: " << term->reset << "(raw score " << score << ")" << endl;
	
	/////PRINT OUT GOOD SETS
	print_good_set(parameters, score, cond_score, exp_score);
	
	// CLOSE PIPES
	v << "  ";
	term->rank(rank, v);
	v << term->blue << "Closing the the pipes " << term->reset << "(file descriptor " << parent_read << ", "<< parent_write << ", " << child_read << ", " << child_write<< ") . . . ";
	if (close(parent_read) == -1) {
		term->failed_pipe_read();
		exit(EXIT_PIPE_WRITE_ERROR);
	}
	
	if (close(parent_write) == -1) {
		term->failed_pipe_write();
		exit(EXIT_PIPE_WRITE_ERROR);
	}

	if (close(child_read) == -1) {
		term->failed_pipe_write();
		exit(EXIT_PIPE_WRITE_ERROR);
	}
	
	if (close(child_write) == -1) {
		term->failed_pipe_write();
		exit(EXIT_PIPE_WRITE_ERROR);
	}
	term->done(v);
	
	// Free the simulation arguments
	for (int i = 0; sim_args[i] != NULL; i++) {
		mfree(sim_args[i]);
	}
	mfree(sim_args);
	
	
	// libSRES requires scores from 0 to 1 with 0 being a perfect score so convert the simulation's score format into libSRES's
	return score;
}
示例#20
0
/* simulate_set performs the required piping to setup and run a simulation with the given parameters
	parameters:
		parameters: the parameters to pass as a parameter set to the simulation
	returns: the score the simulation received
	notes:
	todo:
*/
double simulate_set (double parameters[]) {
	// Get the MPI rank of the process
	int rank = get_rank();
	ostream& v = term->verbose();
	
	// Create a pipe
	int pipes[2];
	v << "  ";
	term->rank(rank, v);
	v << term->blue << "Creating a pipe " << term->reset << ". . . ";
	if (pipe(pipes) == -1) {
		term->failed_pipe_create();
		exit(EXIT_PIPE_CREATE_ERROR);
	}
	v << term->blue << "Done: " << term->reset << "using file descriptors " << pipes[0] << " and " << pipes[1] << endl;
	
	// Fork the process so the child can run the simulation
	v << "  ";
	term->rank(rank, v);
	v << term->blue << "Forking the process " << term->reset << ". . . ";
	pid_t pid = fork();
	if (pid == -1) {
		term->failed_fork();
		exit(EXIT_FORK_ERROR);
	}
	
	int child_pid;
	if (pid == 0) {
		child_pid = getpid();
	} else {
		child_pid = pid;
		v << term->blue << "Done: " << term->reset << "the child process's PID is " << child_pid << endl;
	}
	int rank_strlen = INT_STRLEN(rank);
	char* grad_fname = (char*)mallocate(sizeof(char) * (strlen("input-.gradients") + rank_strlen + 1));
	sprintf(grad_fname, "input-%d.gradients", rank);
	
	if (pid == 0) {
		char** sim_args = copy_args(ip.sim_args, ip.num_sim_args);
		store_pipe(sim_args, ip.num_sim_args - 6, pipes[0]);
		store_pipe(sim_args, ip.num_sim_args - 4, pipes[1]);
		sim_args[ip.num_sim_args - 2] = grad_fname;
		
		ofstream grad_file;
		v << "  ";
		term->rank(rank, v);
		open_file(&grad_file, grad_fname, false);
		if (ip.base_gradients != NULL) {
			grad_file << ip.base_gradients << "\n";
		}
		int loc_start = parameters[0];
		int loc_end = parameters[1];
		int val = parameters[2];
		gradient_index* gi = ip.gradient_indices;
		while (gi != NULL) {
			grad_file << gi->index << " (" << loc_start << " 100) (" << loc_end << " " << val << ")\n";
			gi = gi->next;
		}
		grad_file.close();
		
		v << "  ";
		term->rank(rank, v);
		v << term->blue << "Checking that the simulation file exists and can be executed " << term->reset << ". . . ";
		if (access(ip.sim_file, X_OK) == -1) {
			term->failed_exec();
			exit(EXIT_EXEC_ERROR);
		}
		term->done(v);
		if (execv(ip.sim_file, sim_args) == -1) {
			term->failed_exec();
			exit(EXIT_EXEC_ERROR);
		}
	} else {
		v << "  ";
		term->rank(rank, v);
		v << term->blue << "Writing to the pipe " << term->reset << "(file descriptor " << pipes[1] << ") . . . ";
		write_pipe(pipes[1], ip.sets, ip.num_sets);
		term->done(v);
	}
	
	// Wait for the child to finish simulating
	int status = 0;
	waitpid(pid, &status, WUNTRACED);
	if (WIFEXITED(status) == 0) {
		term->failed_child();
		exit(EXIT_CHILD_ERROR);
	}
	
	// Close the writing end of the pipe
	if (close(pipes[1]) == -1) {
		term->failed_pipe_write();
		exit(EXIT_PIPE_WRITE_ERROR);
	}
	
	// Pipe in the simulation's score
	int max_score;
	int scores[ip.num_sets];
	memset(scores, 0, sizeof(int) * ip.num_sets);
	v << "  ";
	term->rank(rank, v);
	v << term->blue << "Reading the pipe " << term->reset << "(file descriptor " << pipes[0] << ") . . . ";
	read_pipe(pipes[0], &max_score, scores, ip.num_sets);
	v << term->blue << "Done: " << term->reset << "(raw score of set 0: " << scores[0] << " / " << max_score << ")" << endl;
	
	// Close the reading end of the pipe
	v << "  ";
	term->rank(rank, v);
	v << term->blue << "Closing the reading end of the pipe " << term->reset << "(file descriptor " << pipes[0] << ") . . . ";
	if (close(pipes[0]) == -1) {
		term->failed_pipe_read();
		exit(EXIT_PIPE_WRITE_ERROR);
	}
	term->done(v);
	
	// Remove the gradient file
	v << "  ";
	term->rank(rank, v);
	v << term->blue << "Removing " << term->reset << grad_fname << " . . . ";
	if (remove(grad_fname) != 0) {
		term->failed_file_remove(grad_fname);
		exit(EXIT_FILE_REMOVE_ERROR);
	}
	mfree(grad_fname);
	term->done(v);
	
	// Calculate the average score of all the runs
	int avg_score = 0;
	for (int i = 0; i < ip.num_sets; i++) {
		avg_score += scores[i];
	}
	avg_score /= ip.num_sets;
	
	// libSRES requires scores from 0 to 1 with 0 being a perfect score so convert the simulation's score format into libSRES's
	return 1 - ((double)avg_score / max_score);
}