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

📄 rsioctl.c

📁 ATMEL单片机可用的文件系统源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
      PfAssert(Ram->files_tbl != table);

      /*---------------------------------------------------------------*/
      /* Remove and free table. Update counters, and then return.      */
      /*---------------------------------------------------------------*/
      if (table->prev_tbl)
        table->prev_tbl->next_tbl = table->next_tbl;
      if (table->next_tbl)
        table->next_tbl->prev_tbl = table->prev_tbl;
      table->next_tbl = table->prev_tbl = NULL;
      free(table);
      Ram->total_free -= FNUM_ENT;
      return;
    }

    /*-----------------------------------------------------------------*/
    /* Look for the next non-empty entry in the table to be moved.     */
    /*-----------------------------------------------------------------*/
    for (i = 0; i < FNUM_ENT; ++i)
    {
      if (table->tbl[i].type != FEMPTY)
      {
        /*-------------------------------------------------------------*/
        /* Find a place for the non-empty entry to be moved to.        */
        /*-------------------------------------------------------------*/
        entry = find_new_place(table);

        /*-------------------------------------------------------------*/
        /* If no more free entries, stop the garbage collection.       */
        /*-------------------------------------------------------------*/
        if (entry == NULL)
          return;

        /*-------------------------------------------------------------*/
        /* Move entry and update all pointers to it.                   */
        /*-------------------------------------------------------------*/
        entry->type = table->tbl[i].type;
        entry->entry = table->tbl[i].entry;
        table->tbl[i].type = FEMPTY;
        ++table->free;
        update_entries(&table->tbl[i], entry);
      }
    }
  }
}

/***********************************************************************/
/*   close_dir: Close a directory                                      */
/*                                                                     */
/*      Inputs: entry  = pointer to dir entry in files table           */
/*              stream = pointer to dir control block                  */
/*                                                                     */
/***********************************************************************/
static void close_dir(RFSEnt *entry, const FILE *stream)
{
  RDIR_T *dir_ptr = &entry->entry.dir;
  int i;

  /*-------------------------------------------------------------------*/
  /* If no more open links, reset.                                     */
  /*-------------------------------------------------------------------*/
  if (--dir_ptr->comm->open_links == 0)
  {
    dir_ptr->dir = NULL;
    return;
  }

  /*-------------------------------------------------------------------*/
  /* If the dir entry is set to stream on which close was performed,   */
  /* find another stream opened on the file to replace it.             */
  /*-------------------------------------------------------------------*/
  if (dir_ptr->dir == stream)
  {
    for (i = 0; i < DIROPEN_MAX; ++i)
      if (Files[i].handle == dir_ptr && stream != &Files[i])
      {
        PfAssert(Files[i].ioctl == RamIoctl &&
                 Files[i].flags & FCB_DIR);
        dir_ptr->dir = &Files[i];
      }
  }
}

/***********************************************************************/
/*  close_file: Close a file                                           */
/*                                                                     */
/*      Inputs: entry  = pointer to file entry in files table          */
/*              stream = pointer to file control block                 */
/*                                                                     */
/*     Returns: NULL on success, (void *)-1 on error                   */
/*                                                                     */
/***********************************************************************/
static void *close_file(RFSEnt *entry, FILE *stream)
{
  RFIL_T *link_ptr = &entry->entry.file;
  int     i;

  /*-------------------------------------------------------------------*/
  /* Free the file control block associated with this file.            */
  /*-------------------------------------------------------------------*/
  stream->read = NULL;
  stream->write = NULL;
  stream->curr_ptr.sector = (ui16)-1;
  stream->curr_ptr.offset = stream->curr_ptr.sect_off = 0;

  /*-------------------------------------------------------------------*/
  /* If it is the last link open, reset the file mode and check for    */
  /* removal as well.                                                  */
  /*-------------------------------------------------------------------*/
  if (--link_ptr->comm->open_links == 0)
  {
    /*-----------------------------------------------------------------*/
    /* Clear the open_mode and the stream associated with file.        */
    /*-----------------------------------------------------------------*/
    link_ptr->comm->open_mode = 0;
    link_ptr->file = NULL;

    /*-----------------------------------------------------------------*/
    /* If it's a temporary file, remove it without any checking.       */
    /*-----------------------------------------------------------------*/
    if (link_ptr->comm->temp)
    {
      if (remove_file(entry->entry.file.parent_dir,
                      entry->entry.file.name))
        return (void *)-1;
    }

    /*-----------------------------------------------------------------*/
    /* If the number of links to this file is 0 need to remove the     */
    /* contents of the file as well.                                   */
    /*-----------------------------------------------------------------*/
    else if (link_ptr->comm->links == 0)
    {
      /*---------------------------------------------------------------*/
      /* Truncate file size to zero.                                   */
      /*---------------------------------------------------------------*/
      ram_trunc_zero(link_ptr);

      /*---------------------------------------------------------------*/
      /* Remove file from the files table and adjust free entries.     */
      /*---------------------------------------------------------------*/
      link_ptr->comm->addr->type = FEMPTY;
      ++Ram->total_free;
      incTblEntries(link_ptr->comm->addr);
    }

    /*-----------------------------------------------------------------*/
    /* If the file entry was previously removed, clear it.             */
    /*-----------------------------------------------------------------*/
    if (link_ptr->next == (RFSEnt *)REMOVED_LINK &&
        link_ptr->prev == (RFSEnt *)REMOVED_LINK)
    {

      /*---------------------------------------------------------------*/
      /* Clear struct fields.                                          */
      /*---------------------------------------------------------------*/
      link_ptr->comm = NULL;
      link_ptr->next = link_ptr->prev = NULL;
      link_ptr->file = NULL;
      entry->type = FEMPTY;

      /*---------------------------------------------------------------*/
      /* Increment number of free entries.                             */
      /*---------------------------------------------------------------*/
      ++Ram->total_free;
      incTblEntries(entry);

      /*---------------------------------------------------------------*/
      /* Do garbage collection if necessary.                           */
      /*---------------------------------------------------------------*/
      if (Ram->total_free >= (FNUM_ENT * 5 / 3))
        garbageCollect();
    }
  }

  /*-------------------------------------------------------------------*/
  /* Else, if we are closing a stream opened in write mode, clear the  */
  /* write option from the mode.                                       */
  /*-------------------------------------------------------------------*/
  else if ((link_ptr->file == stream) &&
           (link_ptr->comm->open_mode & (F_APPEND | F_WRITE)))
    link_ptr->comm->open_mode &= ~(F_APPEND | F_WRITE);

  /*-------------------------------------------------------------------*/
  /* If the file entry is set to stream on which close was performed,  */
  /* find another stream opened on the file to replace it.             */
  /*-------------------------------------------------------------------*/
  if (link_ptr->file == stream)
  {
    for (i = 0; i < FOPEN_MAX; ++i)
      if (Files[i].handle == link_ptr && stream != &Files[i])
      {
        PfAssert(Files[i].ioctl == RamIoctl &&
                 Files[i].flags & FCB_FILE);
        link_ptr->file = &Files[i];
      }
  }

  return NULL;
}

/***********************************************************************/
/*  statistics: Auxiliary function for FSTAT and STAT to fill out the  */
/*              struct stat contents                                   */
/*                                                                     */
/*      Inputs: buf = stat structure to be filled                      */
/*              entry = pointer to the entry for the stat              */
/*                                                                     */
/***********************************************************************/
static void statistics(struct stat *buf, RFSEnt *entry)
{
  RFIL_T *link_ptr = &entry->entry.file;

  /*-------------------------------------------------------------------*/
  /* Look at the mode for the file/dir. Start with the permissions.    */
  /*-------------------------------------------------------------------*/
  buf->st_mode = link_ptr->comm->mode;

  /*-------------------------------------------------------------------*/
  /* Set the bit corresponding to file/dir according to the entry.     */
  /*-------------------------------------------------------------------*/
  if (entry->type == FDIREN)
    buf->st_mode |= S_DIR;

  /*-------------------------------------------------------------------*/
  /* st_dev is always 0.                                               */
  /*-------------------------------------------------------------------*/
  buf->st_dev = 0;

  /*-------------------------------------------------------------------*/
  /* Get the uid and gid (0 if permissions not used).                  */
  /*-------------------------------------------------------------------*/
  buf->st_uid = link_ptr->comm->user_id;
  buf->st_gid = link_ptr->comm->group_id;

  /*-------------------------------------------------------------------*/
  /* Look at the serial number for the file/dir.                       */
  /*-------------------------------------------------------------------*/
  buf->st_ino = (ino_t)link_ptr->comm->fileno;

  /*-------------------------------------------------------------------*/
  /* Look at the number of links for the file/dir.                     */
  /*-------------------------------------------------------------------*/
  buf->st_nlink = (nlink_t)link_ptr->comm->links;

  /*-------------------------------------------------------------------*/
  /* Look at the size for the file. For a dir the size is 0.           */
  /*-------------------------------------------------------------------*/
  if (entry->type == FFILEN)
    buf->st_size = link_ptr->comm->size;
  else
    buf->st_size = 0;

  /*-------------------------------------------------------------------*/
  /* Look at the access and modified times.                            */
  /*-------------------------------------------------------------------*/
  buf->st_atime = link_ptr->comm->ac_time;
  buf->st_mtime = link_ptr->comm->mod_time;
}

/***********************************************************************/
/*  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;
  RFSEnts *curr_tbl;

  /*-------------------------------------------------------------------*/
  /* Go through all mounted volumes.                                   */
  /*-------------------------------------------------------------------*/
  for (i = 0; i < NUM_RFS_VOLS; ++i)
  {
    /*-----------------------------------------------------------------*/
    /* If this volume is mounted, check all its entries for name dup.  */
    /*-----------------------------------------------------------------*/
    if (MountedList.head == &RamGlobals[i].sys ||
        RamGlobals[i].sys.prev || RamGlobals[i].sys.next)
    {
      /*---------------------------------------------------------------*/
      /* Go through each table in volume.                              */
      /*---------------------------------------------------------------*/

⌨️ 快捷键说明

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