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

📄 rsioctl.c

📁 ATMEL单片机可用的文件系统源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
      for (curr_tbl = RamGlobals[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.                 */
          /*-----------------------------------------------------------*/
          if (curr_tbl->tbl[i].type == FFILEN &&
              !strncmp(curr_tbl->tbl[i].entry.dir.name, name,
                       FILENAME_MAX))
            return 1;
        }
      }
    }
  }
  return 0;
}

/***********************************************************************/
/*  find_entry: Find an empty entry in the file tables                 */
/*                                                                     */
/*      Output: *indexp = index of empty entry in table                */
/*                                                                     */
/*     Returns: NULL if no empty entry, or ptr to table with entry     */
/*                                                                     */
/***********************************************************************/
static RFSEnts *find_entry(ui32 *indexp)
{
  int t;
  RFSEnts *curr_table, *prev_table;

  /*-------------------------------------------------------------------*/
  /* Look through all the tables for an empty entry.                   */
  /*-------------------------------------------------------------------*/
  curr_table = Ram->files_tbl;
  do
  {
    /*-----------------------------------------------------------------*/
    /* Search current table for an empty entry.                        */
    /*-----------------------------------------------------------------*/
    for (t = 0; t < FNUM_ENT; ++t)
    {
      /*---------------------------------------------------------------*/
      /* If an empty entry is found, take it and remember its value.   */
      /*---------------------------------------------------------------*/
      if (curr_table->tbl[t].type == FEMPTY)
      {
        curr_table->tbl[t].type = (ui8)EOF;
        --curr_table->free;
        --Ram->total_free;
        *indexp = t;
        return curr_table;
      }
    }

    /*-----------------------------------------------------------------*/
    /* Go to the next table.                                           */
    /*-----------------------------------------------------------------*/
    prev_table = curr_table;
    curr_table = curr_table->next_tbl;
  } while (curr_table);

  /*-------------------------------------------------------------------*/
  /* No empty entry was found, assign a new table.                     */
  /*-------------------------------------------------------------------*/
  curr_table = GetRamTable();

  /*-------------------------------------------------------------------*/
  /* If no space available to assign new table, return error.          */
  /*-------------------------------------------------------------------*/
  if (curr_table == NULL)
  {
    /*-----------------------------------------------------------------*/
    /* Set errno to no memory available.                               */
    /*-----------------------------------------------------------------*/
    set_errno(ENOMEM);
    return NULL;
  }

  /*-------------------------------------------------------------------*/
  /* Update the linked list of entry tables with the new table.        */
  /*-------------------------------------------------------------------*/
  prev_table->next_tbl = curr_table;
  curr_table->prev_tbl = prev_table;
  Ram->total_free += (FNUM_ENT - 1);

  /*-------------------------------------------------------------------*/
  /* Mark not empty, output entry index, and return table pointer.     */
  /*-------------------------------------------------------------------*/
  curr_table->tbl[0].type = (ui8)EOF;
  *indexp = 0;
  return curr_table;
}

/***********************************************************************/
/*    get_path: Get name of current working directory                  */
/*                                                                     */
/*      Inputs: buf = pointer to buffer or NULL                        */
/*              max = size of buffer, if provided                      */
/*              curr_dir = current working directory handle            */
/*                                                                     */
/***********************************************************************/
static char *get_path(char *buf, size_t max, RFSEnt *curr_dir)
{
  size_t size;
  int depth, i;
  char *rval;
  RDIR_T *dir = &curr_dir->entry.dir;

  /*-------------------------------------------------------------------*/
  /* Count directories between CWD and root, and determine path size.  */
  /*-------------------------------------------------------------------*/
  size = strlen(dir->name) + 2;
  for (depth = 0; dir->parent_dir; ++depth)
  {
    dir = &dir->parent_dir->entry.dir;
    size += strlen(dir->name) + 1;
  }

  /*-------------------------------------------------------------------*/
  /* If a buffer has been provided, ensure it is big enough.           */
  /*-------------------------------------------------------------------*/
  if (buf)
  {
    if ((int)max < 0 || max < size + 1)
    {
      set_errno(ERANGE);
      return NULL;
    }
  }

  /*-------------------------------------------------------------------*/
  /* Else allocate a buffer.                                           */
  /*-------------------------------------------------------------------*/
  else
  {
    buf = malloc(size + 1);
    if (buf == NULL)
      return NULL;
  }

  /*-------------------------------------------------------------------*/
  /* Build path name of current working directory.                     */
  /*-------------------------------------------------------------------*/
  for (rval = buf; depth >= 0; --depth)
  {
    /*-----------------------------------------------------------------*/
    /* Set the dir pointer to the current directory.                   */
    /*-----------------------------------------------------------------*/
    dir = &curr_dir->entry.dir;

    /*-----------------------------------------------------------------*/
    /* Walk up to the "depth" level directory.                         */
    /*-----------------------------------------------------------------*/
    for (i = 0; i < depth; ++i)
      dir = &dir->parent_dir->entry.dir;

    /*-----------------------------------------------------------------*/
    /* Copy '/' and then the directory name to the buffer.             */
    /*-----------------------------------------------------------------*/
    *buf++ = '/';
    strcpy(buf, dir->name);
    buf += strlen(dir->name);
  }

  /*-------------------------------------------------------------------*/
  /* Add a last '/' and end the buffer with '\0' before returning.     */
  /*-------------------------------------------------------------------*/
  *buf++ = '/';
  *buf = '\0';
  return rval;
}

/***********************************************************************/
/*   set_fmode: Set access mode for a file in the RamFileTbl           */
/*                                                                     */
/*      Inputs: stream = pointer to file control block                 */
/*              mode = string describing the access mode               */
/*                                                                     */
/*     Returns: 0 on success, -1 on failure                            */
/*                                                                     */
/***********************************************************************/
static int set_fmode(FILE *stream, const char *mode)
{
  RFIL_T *entry = &(((RFSEnt *)stream->handle)->entry.file);

  /*-------------------------------------------------------------------*/
  /* For read only, set curr_ptr to the beginning of the file.         */
  /*-------------------------------------------------------------------*/
  if (!strcmp(mode, "r") || !strcmp(mode, "rb"))
  {
    entry->comm->open_mode |= F_READ;
    stream->curr_ptr.sector = (ui32)entry->comm->frst_sect;
    stream->curr_ptr.offset = 0;
    stream->curr_ptr.sect_off = 0;
  }

  /*-------------------------------------------------------------------*/
  /* For write only mode, truncate file.                               */
  /*-------------------------------------------------------------------*/
  else if (!strcmp(mode, "w") || !strcmp(mode, "wb"))
  {
    entry->comm->open_mode |= F_WRITE;
    ram_trunc_zero(entry);
    stream->curr_ptr.sector = (ui32)NULL;
    stream->curr_ptr.offset = 0;
    stream->curr_ptr.sect_off = 0;
  }

  /*-------------------------------------------------------------------*/
  /* For append mode, set curr_ptr to the end of the file.             */
  /*-------------------------------------------------------------------*/
  else if (!strcmp(mode, "a") || !strcmp(mode, "ab"))
  {
    RamPoint2End(&stream->curr_ptr, entry->comm);
    entry->comm->open_mode |= F_APPEND;
  }

  /*-------------------------------------------------------------------*/
  /* For read/write, set curr_ptr to the end of the file.              */
  /*-------------------------------------------------------------------*/
  else if (!strcmp(mode, "r+") || !strcmp(mode, "rb+") ||
           !strcmp(mode, "r+b"))
  {
    stream->curr_ptr.sector = (ui32)entry->comm->frst_sect;
    stream->curr_ptr.offset = 0;
    stream->curr_ptr.sect_off = 0;
    entry->comm->open_mode |= (F_READ | F_WRITE);
  }

  /*-------------------------------------------------------------------*/
  /* For write/read, truncate file.                                    */
  /*-------------------------------------------------------------------*/
  else if (!strcmp(mode, "w+") || !strcmp(mode, "wb+") ||
           !strcmp(mode, "w+b"))
  {
    entry->comm->open_mode |= (F_READ | F_WRITE);
    ram_trunc_zero(entry);
    stream->curr_ptr.sector = (ui32)NULL;
    stream->curr_ptr.offset = 0;
    stream->curr_ptr.sect_off = 0;
  }

  /*-------------------------------------------------------------------*/
  /* For append/read, set curr_ptr to the end of the file.             */
  /*-------------------------------------------------------------------*/
  else if (!strcmp(mode, "a+") || !strcmp(mode, "ab+") ||
           !strcmp(mode, "a+b"))
  {
    RamPoint2End(&stream->curr_ptr, entry->comm);
    entry->comm->open_mode |= (F_READ | F_APPEND);
  }

  /*-------------------------------------------------------------------*/
  /* If mode is invalid, return error.                                 */
  /*-------------------------------------------------------------------*/
  else
  {
    set_errno(EINVAL);
    return -1;
  }

  /*-------------------------------------------------------------------*/
  /* Set old_ptr to the same value as curr_ptr when opening a file.    */
  /*-------------------------------------------------------------------*/
  stream->old_ptr = stream->curr_ptr;
  return 0;
}

/***********************************************************************/
/*     acquire: Acquire the RAM file system lock                       */
/*                                                                     */
/*      Inputs: handle = pointer to file control block                 */
/*              code   = if more than 1 sem, select which one          */
/*                                                                     */
/***********************************************************************/
static void acquire(const FILE *file, int code)
{
  semPend(R

⌨️ 快捷键说明

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