Пример #1
0
int exec(FAR const char *filename, FAR char * const *argv,
         FAR const struct symtab_s *exports, int nexports)
{
#if defined(CONFIG_SCHED_ONEXIT) && defined(CONFIG_SCHED_HAVE_PARENT)
  FAR struct binary_s *bin;
  int pid;
  int errcode;
  int ret;

  /* Allocate the load information */

  bin = (FAR struct binary_s *)kmm_zalloc(sizeof(struct binary_s));
  if (!bin)
    {
      berr("ERROR: Failed to allocate binary_s\n");
      errcode = ENOMEM;
      goto errout;
    }

  /* Initialize the binary structure */

  bin->filename = filename;
  bin->exports  = exports;
  bin->nexports = nexports;

  /* Copy the argv[] list */

  ret = binfmt_copyargv(bin, argv);
  if (ret < 0)
    {
      errcode = -ret;
      berr("ERROR: Failed to copy argv[]: %d\n", errcode);
      goto errout_with_bin;
    }

  /* Load the module into memory */

  ret = load_module(bin);
  if (ret < 0)
    {
      errcode = get_errno();
      berr("ERROR: Failed to load program '%s': %d\n", filename, errcode);
      goto errout_with_argv;
    }

  /* Disable pre-emption so that the executed module does
   * not return until we get a chance to connect the on_exit
   * handler.
   */

  sched_lock();

  /* Then start the module */

  pid = exec_module(bin);
  if (pid < 0)
    {
      errcode = get_errno();
      berr("ERROR: Failed to execute program '%s': %d\n", filename, errcode);
      goto errout_with_lock;
    }

  /* Set up to unload the module (and free the binary_s structure)
   * when the task exists.
   */

  ret = schedule_unload(pid, bin);
  if (ret < 0)
    {
      errcode = get_errno();
      berr("ERROR: Failed to schedule unload '%s': %d\n", filename, errcode);
    }

  sched_unlock();
  return pid;

errout_with_lock:
  sched_unlock();
  unload_module(bin);
errout_with_argv:
  binfmt_freeargv(bin);
errout_with_bin:
  kmm_free(bin);
errout:
  set_errno(errcode);
  return ERROR;

#else
  struct binary_s bin;
  int errcode;
  int ret;

  /* Load the module into memory */

  memset(&bin, 0, sizeof(struct binary_s));
  bin.filename = filename;
  bin.exports  = exports;
  bin.nexports = nexports;

  ret = load_module(&bin);
  if (ret < 0)
    {
      errcode = get_errno();
      berr("ERROR: Failed to load program '%s': %d\n", filename, errcode);
      goto errout;
    }

  /* Then start the module */

  ret = exec_module(&bin);
  if (ret < 0)
    {
      errcode = get_errno();
      berr("ERROR: Failed to execute program '%s': %d\n", filename, errcode);
      goto errout_with_module;
    }

  /* TODO:  How does the module get unloaded in this case? */

  return ret;

errout_with_module:
  unload_module(&bin);
errout:
  set_errno(errcode);
  return ERROR;
#endif
}
Пример #2
0
int exec(FAR const char *filename, FAR char * const *argv,
         FAR const struct symtab_s *exports, int nexports)
{
#if defined(CONFIG_SCHED_ONEXIT) && defined(CONFIG_SCHED_HAVE_PARENT)
  FAR struct binary_s *bin;
  int pid;
  int ret;

  /* Allocate the load information */

  bin = (FAR struct binary_s *)kzalloc(sizeof(struct binary_s));
  if (!bin)
    {
      set_errno(ENOMEM);
      return ERROR;
    }

  /* Load the module into memory */

  bin->filename = filename;
  bin->argv     = argv;
  bin->exports  = exports;
  bin->nexports = nexports;

  ret = load_module(bin);
  if (ret < 0)
    {
      bdbg("ERROR: Failed to load program '%s'\n", filename);
      kfree(bin);
      return ERROR;
    }

  /* Disable pre-emption so that the executed module does
   * not return until we get a chance to connect the on_exit
   * handler.
   */

  sched_lock();

  /* Then start the module */

  pid = exec_module(bin);
  if (pid < 0)
    {
      bdbg("ERROR: Failed to execute program '%s'\n", filename);
      sched_unlock();
      unload_module(bin);
      kfree(bin);
      return ERROR;
    }

  /* Set up to unload the module (and free the binary_s structure)
   * when the task exists.
   */

  ret = schedule_unload(pid, bin);
  if (ret < 0)
    {
      bdbg("ERROR: Failed to schedul unload '%s'\n", filename);
    }

  sched_unlock();
  return pid;
#else
  struct binary_s bin;
  int ret;

  /* Load the module into memory */

  memset(&bin, 0, sizeof(struct binary_s));
  bin.filename = filename;
  bin.exports  = exports;
  bin.nexports = nexports;

  ret = load_module(&bin);
  if (ret < 0)
    {
      bdbg("ERROR: Failed to load program '%s'\n", filename);
      return ERROR;
    }

  /* Then start the module */

  ret = exec_module(&bin);
  if (ret < 0)
    {
      bdbg("ERROR: Failed to execute program '%s'\n", filename);
      unload_module(&bin);
      return ERROR;
    }

  /* TODO:  How does the module get unloaded in this case? */

  return ret;
#endif
}