⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sysioctl.c

📁 ATMEL单片机可用的文件系统源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
  /*-------------------------------------------------------------------*/
  pivot = *head;
  *head = (*head)->entry.dir.next;
  (*head)->entry.dir.prev = NULL;
  pivot->entry.dir.next = NULL;

  /*-------------------------------------------------------------------*/
  /* Fill in DirEntry for the pivot.                                   */
  /*-------------------------------------------------------------------*/
  fill_dir_entry(&pivot->entry.dir, e1);

  /*-------------------------------------------------------------------*/
  /* Now walk the rest of the list and place each entry into one of the*/
  /* two categories (<=, >) based on the comparison function.          */
  /*-------------------------------------------------------------------*/
  while ((curr_ent = *head) != NULL)
  {
    /*-----------------------------------------------------------------*/
    /* Advance head to next entry in list.                             */
    /*-----------------------------------------------------------------*/
    *head = (*head)->entry.dir.next;
    curr_ent->entry.dir.next = NULL;

    /*-----------------------------------------------------------------*/
    /* Fill in DirEntry for current entry.                             */
    /*-----------------------------------------------------------------*/
    fill_dir_entry(&curr_ent->entry.dir, e2);

    /*-----------------------------------------------------------------*/
    /* If entry >= pivot, place it in the 'less' list.                 */
    /*-----------------------------------------------------------------*/
    if (cmp(e1, e2) >= 0)
    {
      if (less_tail == NULL)
      {
        less_head = less_tail = curr_ent;
        curr_ent->entry.dir.prev = NULL;
      }
      else
      {
        less_tail->entry.dir.next = curr_ent;
        curr_ent->entry.dir.prev = less_tail;
        less_tail = curr_ent;
      }
    }

    /*-----------------------------------------------------------------*/
    /* If entry after pivot, place it in the 'greater' list.           */
    /*-----------------------------------------------------------------*/
    else
    {
      if (greater_tail == NULL)
      {
        greater_head = greater_tail = curr_ent;
        curr_ent->entry.dir.prev = NULL;
      }
      else
      {
        greater_tail->entry.dir.next = curr_ent;
        curr_ent->entry.dir.prev = greater_tail;
        greater_tail = curr_ent;
      }
    }
  }

  /*-------------------------------------------------------------------*/
  /* Sort both lists if non-empty.                                     */
  /*-------------------------------------------------------------------*/
  if (less_head)
    QuickSort(&less_head, &less_tail, e1, e2, cmp);
  if (greater_head)
    QuickSort(&greater_head, &greater_tail, e1, e2, cmp);

  /*-------------------------------------------------------------------*/
  /* Create sorted list: less->pivot->greater.                         */
  /*-------------------------------------------------------------------*/
  if (less_tail)
  {
    *head = less_head;
    less_tail->entry.dir.next = pivot;
  }
  else
    *head = pivot;
  pivot->entry.dir.prev = less_tail;
  if (greater_head)
  {
    *tail = greater_tail;
    greater_head->entry.dir.prev = pivot;
  }
  else
    *tail = pivot;
  pivot->entry.dir.next = greater_head;
}

/***********************************************************************/
/*     InitFFS: Initialize the flash                                   */
/*                                                                     */
/*     Returns: 0 on success, -1 on failure                            */
/*                                                                     */
/***********************************************************************/
int InitFFS(void)
{
  /*-------------------------------------------------------------------*/
  /* Set the file system semaphore and global variables.               */
  /*-------------------------------------------------------------------*/
  FileSysSem = semCreate("FSYS_SEM", 1, OS_FIFO);
  if (FileSysSem == NULL)
    return -1;
  FsInitFCB(&Files[ROOT_DIR_INDEX], FCB_DIR);
  Files[ROOT_DIR_INDEX].ioctl = root_ioctl;

  /*-------------------------------------------------------------------*/
  /* Initialize all modules in the list.                               */
  /*-------------------------------------------------------------------*/
  return sw_mod_loop(kInitMod);
}

/***********************************************************************/
/*      IsLast: Given a string, look to see if it is last entry in the */
/*              path for a filename or a directory                     */
/*                                                                     */
/*      Inputs: name = string to check                                 */
/*              incr = pointer to num of chars to increment            */
/*                                                                     */
/*     Returns: length of entry if not last, 0 if it is                */
/*                                                                     */
/***********************************************************************/
ui32 IsLast(const char *name, ui32 *incr)
{
  ui32 i, inc = 0;

  for (;; ++name, ++inc)
  {
    /*-----------------------------------------------------------------*/
    /* If a '/' is encountered, it's not the last entry in the path.   */
    /*-----------------------------------------------------------------*/
    if (*name == '/')
    {
      /*---------------------------------------------------------------*/
      /* If there's nothing pointing past the '/' however, it is the   */
      /* last entry in the path.                                       */
      /*---------------------------------------------------------------*/
      for (i = inc;; ++i)
      {
        ++name;
        *incr = i + 1;
        if (*name == '\0')
          return 0;
        else if (*name != '/')
          return inc;
      }
    }

    /*-----------------------------------------------------------------*/
    /* If we've reached the end of the string, it is last entry.       */
    /*-----------------------------------------------------------------*/
    if (*name == '\0')
    {
      *incr = inc;
      return 0;
    }
  }
}

/***********************************************************************/
/* FSearchFSUID: Search for a filename(or full path) based on FSUID    */
/*                                                                     */
/*      Inputs: fsuid = FSUID number to look for                       */
/*              buf = buffer to place filename(path) in if non NULL    */
/*              size = size of buf when non NULL                       */
/*              lookup = flag to indicate filename or full path        */
/*                                                                     */
/*     Returns: filename(path), NULL on error                          */
/*                                                                     */
/***********************************************************************/
char *FSearchFSUID(ui32 fsuid, char *buf, size_t size, int lookup)
{
  ui32 vid, fid;
  FileSys *fsys;
  char *r_value = NULL;

  /*-------------------------------------------------------------------*/
  /* Get the volume id and file id from the FSUID.                     */
  /*-------------------------------------------------------------------*/
  vid = get_vid(fsuid);
  fid = get_fid(fsuid);

  /*-------------------------------------------------------------------*/
  /* Scan all the mounted volumes for the entry with FSUID.            */
  /*-------------------------------------------------------------------*/
  for (fsys = MountedList.head; fsys && r_value == NULL;
       fsys = fsys->next)
  {
    r_value = fsys->ioctl(NULL, GET_NAME, fsys->volume, buf, size,
                          lookup, vid, fid);
    if (r_value == (char *)-1)
      return NULL;
  }

  return r_value;
}

/***********************************************************************/
/*     FSearch: Search a path to determine if it is valid              */
/*                                                                     */
/*      Inputs: handle = handle to either dir or file ctrl block       */
/*              path = pointer to the path                             */
/*              dir_lookup = flag to indicate up to what level lookup  */
/*                           is performed (actual or parent directory) */
/*                                                                     */
/*     Returns: Pointer to directory that holds entity for which       */
/*              search was performed, or NULL if no directory exists   */
/*                                                                     */
/***********************************************************************/
void *FSearch(void *handle, const char **path, int dir_lookup)
{
  FILE *file = handle;
  void *r_value = (void *)-1;
  ui32 len, incr, dummy;
  FsVolume *volume;

  /*-------------------------------------------------------------------*/
  /* Set FSPath to point to *path.                                     */
  /*-------------------------------------------------------------------*/
  FSPath = *path;

  /*-------------------------------------------------------------------*/
  /* Keep looping until entry found or error.                          */
  /*-------------------------------------------------------------------*/
  do
  {
    /*-----------------------------------------------------------------*/
    /* Obtain current directory info. If never set before, set it to   */
    /* root.                                                           */
    /*-----------------------------------------------------------------*/
    FsReadCWD((void *)&volume, &dummy);

    /*-----------------------------------------------------------------*/
    /* If it's an absolute path, or current ioctl is root one, figure  */
    /* out to which file system to direct the search.                  */
    /*-----------------------------------------------------------------*/
    if (*FSPath == '/' || volume == NULL || r_value == NULL)
    {
      /*---------------------------------------------------------------*/
      /* Strip off the leading '/' in the path if there are any.       */
      /*---------------------------------------------------------------*/
      while (*FSPath == '/')
        ++FSPath;

      /*---------------------------------------------------------------*/
      /* Skip multiple "./" strings. Skip ending ".".                  */
      /*---------------------------------------------------------------*/
      while (!strncmp(FSPath, "./", 2))
        FSPath += 2;
      if (!strcmp(FSPath, "."))
        ++FSPath;

      /*---------------------------------------------------------------*/
      /* If pathname is empty, we're in the root directory, stop.      */
      /*---------------------------------------------------------------*/
      if (*FSPath == '\0')
      {
        file->ioctl = Files[ROOT_DIR_INDEX].ioctl;
        file->acquire = file->release = do_nothing;
        r_value = &Files[ROOT_DIR_INDEX];
      }

      /*---------------------------------------------------------------*/
      /* Else pathname is valid, check if any file systems are mounted.*/
      /*---------------------------------------------------------------*/
      else if (MountedList.head)
      {
        FileSys *fsys;

        /*-------------------------------------------------------------*/
        /* Check if we're looking at last name in path.                */
        /*-------------------------------------------------------------*/
        len = IsLast(FSPath, &incr);
        if (len == 0)
        {
          /*-----------------------------------------------------------*/
          /* If it's directory, strip off trailing '/' if it exists.   */
          /*-----------------------------------------------------------*/
          if (dir_lookup == ACTUAL_DIR || dir_lookup == DIR_FILE)
          {
            if ((FSPath)[incr - 1] == '/')
            {
              len = incr - 1;
              while (FSPath[len - 1] == '/')
                --len;
            }
            else
              len = incr;

            /*---------------------------------------------------------*/
            /* If path too long, return error if no truncation, else   */
            /* truncate.                                               */
            /*---------------------------------------------------------*/
            if (len > PATH_MAX)
            {
#if _PATH_NO_TRUNC
              set_errno(ENAMETOOLONG);
              return NULL;
#else
              len = PATH_MAX;
#endif
            }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -