예제 #1
0
파일: fs_binfs.c 프로젝트: a1ien/nuttx
static int binfs_open(FAR struct file *filep, FAR const char *relpath,
                      int oflags, mode_t mode)
{
  int index;

  finfo("Open '%s'\n", relpath);

  /* BINFS is read-only.  Any attempt to open with any kind of write
   * access is not permitted.
   */

  if ((oflags & O_WRONLY) != 0 || (oflags & O_RDONLY) == 0)
    {
      ferr("ERROR: Only O_RDONLY supported\n");
      return -EACCES;
    }

  /* Check if the an entry exists with this name in the root directory.
   * so the 'relpath' must be the name of the builtin function.
   */

  index = builtin_isavail(relpath);
  if (index < 0)
    {
      ferr("ERROR: Builting %s does not exist\n", relpath);
      return -ENOENT;
    }

  /* Save the index as the open-specific state in filep->f_priv */

  filep->f_priv = (FAR void *)((uintptr_t)index);
  return OK;
}
예제 #2
0
파일: builtin.c 프로젝트: a1ien/nuttx
static int builtin_loadbinary(struct binary_s *binp)
{
  FAR const char *filename;
  FAR const struct builtin_s *b;
  int fd;
  int index;
  int ret;

  binfo("Loading file: %s\n", binp->filename);

  /* Open the binary file for reading (only) */

  fd = open(binp->filename, O_RDONLY);
  if (fd < 0)
    {
      int errval = get_errno();
      berr("ERROR: Failed to open binary %s: %d\n", binp->filename, errval);
      return -errval;
    }

  /* If this file is a BINFS file system, then we can recover the name of
   * the file using the FIOC_FILENAME ioctl() call.
   */

  ret = ioctl(fd, FIOC_FILENAME, (unsigned long)((uintptr_t)&filename));
  if (ret < 0)
    {
      int errval = get_errno();
      berr("ERROR: FIOC_FILENAME ioctl failed: %d\n", errval);
      close(fd);
      return -errval;
    }

  /* Other file systems may also support FIOC_FILENAME, so the real proof
   * is that we can look up the index to this name in g_builtins[].
   */

  index = builtin_isavail(filename);
  if (index < 0)
    {
      int errval = get_errno();
      berr("ERROR: %s is not a builtin application\n", filename);
      close(fd);
      return -errval;

    }

  /* Return the load information.  NOTE: that there is no way to configure
   * the priority.  That is a bug and needs to be fixed.
   */

  b = builtin_for_index(index);
  binp->entrypt   = b->main;
  binp->stacksize = b->stacksize;
  binp->priority  = b->priority;
  close(fd);
  return OK;
}
예제 #3
0
int exec_builtin(FAR const char *appname, FAR char * const *argv,
                 FAR const char *redirfile, int oflags)
{
  FAR const struct builtin_s *builtin;
  posix_spawnattr_t attr;
  posix_spawn_file_actions_t file_actions;
  struct sched_param param;
  pid_t pid;
  int index;
  int ret;

  /* Verify that an application with this name exists */

  index = builtin_isavail(appname);
  if (index < 0)
    {
      ret = ENOENT;
      goto errout_with_errno;
    }

  /* Get information about the builtin */

  builtin = builtin_for_index(index);
  if (builtin == NULL)
    { 
      ret = ENOENT;
      goto errout_with_errno;
    }

  /* Initialize attributes for task_spawn(). */

  ret = posix_spawnattr_init(&attr);
  if (ret != 0)
    {
      goto errout_with_errno;
    }

  ret = posix_spawn_file_actions_init(&file_actions);
  if (ret != 0)
    {
      goto errout_with_attrs;
    }

  /* Set the correct task size and priority */

  param.sched_priority = builtin->priority;
  ret = posix_spawnattr_setschedparam(&attr, &param);
  if (ret != 0)
    {
      goto errout_with_actions;
    }

  ret = task_spawnattr_setstacksize(&attr, builtin->stacksize);
  if (ret != 0)
    {
      goto errout_with_actions;
    }

   /* If robin robin scheduling is enabled, then set the scheduling policy
    * of the new task to SCHED_RR before it has a chance to run.
    */

#if CONFIG_RR_INTERVAL > 0
  ret = posix_spawnattr_setschedpolicy(&attr, SCHED_RR);
  if (ret != 0)
    {
      goto errout_with_actions;
    }

  ret = posix_spawnattr_setflags(&attr,
                                 POSIX_SPAWN_SETSCHEDPARAM |
                                 POSIX_SPAWN_SETSCHEDULER);
  if (ret != 0)
    {
      goto errout_with_actions;
    }
#else
  ret = posix_spawnattr_setflags(&attr, POSIX_SPAWN_SETSCHEDPARAM);
  if (ret != 0)
    {
      goto errout_with_actions;
    }
#endif

  /* Is output being redirected? */

  if (redirfile)
    {
      /* Set up to close open redirfile and set to stdout (1) */

      ret = posix_spawn_file_actions_addopen(&file_actions, 1,
                                             redirfile, O_WRONLY, 0644);
      if (ret != 0)
        {
          sdbg("ERROR: posix_spawn_file_actions_addopen failed: %d\n", ret);
          goto errout_with_actions;
        }
    }

  /* Start the built-in */

  ret = task_spawn(&pid, builtin->name, builtin->main, &file_actions,
                   &attr, (argv) ? &argv[1] : (FAR char * const *)NULL,
                   (FAR char * const *)NULL);
  if (ret != 0)
    {
      sdbg("ERROR: task_spawn failed: %d\n", ret);
      goto errout_with_actions;
    }

  /* Free attibutes and file actions.  Ignoring return values in the case
   * of an error.
   */

  /* Return the task ID of the new task if the task was sucessfully
   * started.  Otherwise, ret will be ERROR (and the errno value will
   * be set appropriately).
   */

  (void)posix_spawn_file_actions_destroy(&file_actions);
  (void)posix_spawnattr_destroy(&attr);
  return pid;

errout_with_actions:
  (void)posix_spawn_file_actions_destroy(&file_actions);

errout_with_attrs:
  (void)posix_spawnattr_destroy(&attr);

errout_with_errno:
  set_errno(ret);
  return ERROR;
}