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

📄 fsioctl.c

📁 ATMEL单片机可用的文件系统源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
  buf->st_atime = (time_t)link_ptr->comm->ac_time;
  buf->st_mtime = (time_t)link_ptr->comm->mod_time;
}

/***********************************************************************/
/* seek_within_file: Help function for FSEEK (steps through file)      */
/*                                                                     */
/*      Inputs: stream = pointer to file control block                 */
/*              offset = new seek location                             */
/*              curr_pos = current position within file                */
/*                                                                     */
/*     Returns: NULL on success, (void*)-1 on error                    */
/*                                                                     */
/***********************************************************************/
static void *seek_within_file(FILE *stream, i32 offset, i32 curr_pos)
{
  i32 old_pos;
  fpos_t beg_ptr;
  void *vp;

  /*-------------------------------------------------------------------*/
  /* If stream has a cached entry, free it.                            */
  /*-------------------------------------------------------------------*/
  if (stream->cached && FreeSector(&stream->cached, &Flash->cache))
    return (void *)-1;

  /*-------------------------------------------------------------------*/
  /* Get valid position from old_ptr or set it to the end of the file. */
  /*-------------------------------------------------------------------*/
  if (stream->old_ptr.sector != (ui16)-1)
    old_pos = (i32)(stream->old_ptr.sect_off * Flash->sect_sz +
                    stream->old_ptr.offset);
  else
    old_pos = (i32)((FFSEnt *)stream->handle)->entry.file.comm->size;

  /*-------------------------------------------------------------------*/
  /* Choose among curr_pos, old_pos, or beginning of file, whichever   */
  /* is closer to where we want to get. The only time when beginning   */
  /* of file is better than the other two is when both curr and old    */
  /* position are beyond where we want to seek.                        */
  /*-------------------------------------------------------------------*/
  if (curr_pos > offset && old_pos > offset)
  {
    beg_ptr.sector =
                  ((FFSEnt *)stream->handle)->entry.file.comm->frst_sect;
    beg_ptr.offset = 0;
    beg_ptr.sect_off = 0;
    return seek_up(offset, stream, beg_ptr);
  }

  /*-------------------------------------------------------------------*/
  /* Else choose between old_pos and curr_pos and seek from there up   */
  /* to the right spot.                                                */
  /*-------------------------------------------------------------------*/
  else
  {
    /*-----------------------------------------------------------------*/
    /* If old_pos is past location, use curr_pos.                      */
    /*-----------------------------------------------------------------*/
    if (old_pos > offset)
    {
      /*---------------------------------------------------------------*/
      /* Adjust offset by subtracting curr_pos from it.                */
      /*---------------------------------------------------------------*/
      offset -= curr_pos;
      beg_ptr = stream->curr_ptr;
      vp = seek_up(offset, stream, stream->curr_ptr);
      stream->old_ptr = beg_ptr;
      return vp;
    }

    /*-----------------------------------------------------------------*/
    /* Else if curr_pos is past location, use old_pos.                 */
    /*-----------------------------------------------------------------*/
    else if (curr_pos > offset)
    {
      /*---------------------------------------------------------------*/
      /* Adjust offset by subtracting old_pos from it.                 */
      /*---------------------------------------------------------------*/
      offset -= old_pos;
      return seek_up(offset, stream, stream->old_ptr);
    }

    /*-----------------------------------------------------------------*/
    /* Else choose the one that's closest.                             */
    /*-----------------------------------------------------------------*/
    else
    {
      /*---------------------------------------------------------------*/
      /* Use whichever is bigger between curr_pos and old_pos.         */
      /*---------------------------------------------------------------*/
      if (old_pos > curr_pos)
      {
        /*-------------------------------------------------------------*/
        /* Adjust offset by subtracting old position from it.          */
        /*-------------------------------------------------------------*/
        offset -= old_pos;
        return seek_up(offset, stream, stream->old_ptr);
      }
      else
      {
        /*-------------------------------------------------------------*/
        /* Adjust offset by subtracting curr position from it.         */
        /*-------------------------------------------------------------*/
        offset -= curr_pos;
        beg_ptr = stream->curr_ptr;
        vp = seek_up(offset, stream, stream->curr_ptr);
        stream->old_ptr = beg_ptr;
        return vp;
      }
    }
  }
}

/***********************************************************************/
/* seek_past_end: Adjust file position past EOF                        */
/*                                                                     */
/*      Inputs: offset = length of fseek in bytes                      */
/*              stream = pointer to file control block (FILE)          */
/*                                                                     */
/*     Returns: NULL on success, (void *)-1 on error                   */
/*                                                                     */
/***********************************************************************/
static void *seek_past_end(i32 offset, FILE *stream)
{
  FFIL_T *link_ptr = &((FFSEnt *)stream->handle)->entry.file;
  FCOM_T *file = link_ptr->comm;

  /*-------------------------------------------------------------------*/
  /* Files created by creatn() cannot seek past end.                   */
  /*-------------------------------------------------------------------*/
  if (offset && (link_ptr->comm->mode & S_CREATN))
  {
    set_errno(EINVAL);
    return (void *)-1;
  }

  /*-------------------------------------------------------------------*/
  /* If stream has a cached entry, free it.                            */
  /*-------------------------------------------------------------------*/
  if (stream->cached && FreeSector(&stream->cached, &Flash->cache))
    return (void *)-1;

  /*-------------------------------------------------------------------*/
  /* If offset is zero, set current pointer to EOF.                    */
  /*-------------------------------------------------------------------*/
  if (offset == 0)
    FlashPoint2End(&stream->curr_ptr, file);

  /*-------------------------------------------------------------------*/
  /* Else set current pointer past the EOF.                            */
  /*-------------------------------------------------------------------*/
  else
  {
    /*-----------------------------------------------------------------*/
    /* Current sector will be invalid since we're past EOF.            */
    /*-----------------------------------------------------------------*/
    stream->curr_ptr.sector = FDRTY_SECT;

    /*-----------------------------------------------------------------*/
    /* Position is given by sect_off and offset.                       */
    /*-----------------------------------------------------------------*/
    stream->curr_ptr.sect_off = (file->size + offset) / Flash->sect_sz;
    stream->curr_ptr.offset = (ui16)((file->size + offset) %
                                     Flash->sect_sz);
  }

  return NULL;
}

/***********************************************************************/
/*     seek_up: Helper function for FSEEK                              */
/*                                                                     */
/*      Inputs: offset = length of fseek in bytes                      */
/*              stream = pointer to file control block (FILE)          */
/*              start_pos = start position (beginning, curr, or old)   */
/*                                                                     */
/*     Returns: NULL on success, (void *)-1 on error                   */
/*                                                                     */
/***********************************************************************/
static void *seek_up(i32 offset, FILE *stream, fpos_t start_pos)
{
  FCOM_T *file = ((FFSEnt *)stream->handle)->entry.file.comm;
  ui32 num_sects, i;

  /*-------------------------------------------------------------------*/
  /* If seek goes past start sector, subtract starting position from   */
  /* offset.                                                           */
  /*-------------------------------------------------------------------*/
  if (offset > (Flash->sect_sz - start_pos.offset))
    offset -= (Flash->sect_sz - start_pos.offset);

  /*-------------------------------------------------------------------*/
  /* Else adjust offset and return.                                    */
  /*-------------------------------------------------------------------*/
  else
  {
    start_pos.offset += (ui16)offset;
    stream->curr_ptr = start_pos;
    return NULL;
  }

  /*-------------------------------------------------------------------*/
  /* Move to the next sector in file.                                  */
  /*-------------------------------------------------------------------*/
  ++start_pos.sect_off;
  start_pos.sector = Flash->sect_tbl[start_pos.sector].next;

  /*-------------------------------------------------------------------*/
  /* Figure out how many sectors we have to go up.                     */
  /*-------------------------------------------------------------------*/
  num_sects = (ui32)offset / Flash->sect_sz;
  start_pos.offset = (ui16)((ui32)offset % Flash->sect_sz);

  /*-------------------------------------------------------------------*/
  /* Step through to the desired num_sects.                            */
  /*-------------------------------------------------------------------*/
  for (i = 0; i < num_sects; ++i)
    start_pos.sector = Flash->sect_tbl[start_pos.sector].next;
  start_pos.sect_off += num_sects;

  /*-------------------------------------------------------------------*/
  /* If this was the last sector, we're at the end of the file, but    */
  /* not past it.                                                      */
  /*-------------------------------------------------------------------*/
  if (start_pos.sector == FLAST_SECT)
    FlashPoint2End(&start_pos, file);

  /*-------------------------------------------------------------------*/
  /* Update curr_ptr and return success.                               */
  /*-------------------------------------------------------------------*/
  stream->curr_ptr = start_pos;
  return NULL;
}

/***********************************************************************/
/*  check_name: Search through all entries for name                    */
/*                                                                     */
/*       Input: name = filename to look for                            */
/*                                                                     */
/*     Returns: 0 if the name was not found, 1 if it was               */
/*                                                                     */
/***********************************************************************/
static int check_name(const char *name)
{
  int i, j;
  FFSEnts *curr_tbl;

  /*-------------------------------------------------------------------*/
  /* Go through all mounted volumes.                                   */
  /*-------------------------------------------------------------------*/
  for (i = 0; i < NUM_FFS_VOLS; ++i)
  {
    /*-----------------------------------------------------------------*/
    /* If this volume is mounted, check all its entries for name dup.  */
    /*-----------------------------------------------------------------*/
    if (MountedList.head == &FlashGlobals[i].sys ||
        FlashGlobals[i].sys.prev || FlashGlobals[i].sys.next)
    {
      /*---------------------------------------------------------------*/
      /* Acquire exclusive access to the flash file system.            */
      /*---------------------------------------------------------------*/
      semPend(FlashSem, WAIT_FOREVER);

      /*---------------------------------------------------------------*/
      /* Go through each table in volume.                              */
      /*---------------------------------------------------------------*/
      for (curr_tbl = FlashGlobals[i].files_tbl; curr_tbl;
           curr_tbl = curr_tbl->next_tbl)
      {
        /*-------------------------------------------------------------*/
        /* Go through all entries in table.                            */
        /*-------------------------------------------------------------*/
        for (j = 0; j < FNUM_ENT; ++j)
        {
          /*-----------------------------------------------------------*/
          /* If entry is a file and names match, stop.                 */
          /*-----------------------------------------------

⌨️ 快捷键说明

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