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

📄 vfsfiles.c

📁 在ARM7和UC/OSII的平台上实现了GPS自动报站的功能,涉及GPS模块LEA_4S的驱动,位置速寻算法,语音芯片ISD4004的录放音驱动,LED页面管理等等.从启动代码到操作系统的移植以及到业
💻 C
📖 第 1 页 / 共 4 页
字号:
#ifdef VFS_VERBOSE
         dprintf("file name too long in vfopen_locked()\n");
#endif   /* VFS_VERBOSE */
         return NULL;
      }

      /* allocate a vfs_file structure to hold the new file entry in */
      vfp = VFS_VFS_FILE_ALLOC();

      /* check for memory allocation failure */
      if (!vfp)
      {
         set_vfopen_error(ENP_NOMEM);
#ifdef VFS_VERBOSE
         dprintf("VFS_VFS_FILE_ALLOC() failed in vfopen_locked()\n");
#endif   /* VFS_VERBOSE */
         return NULL;
      }

      /* allocate a VFILE structure to represent the open file */
      vop = vf_alloc_and_link_vop();

      /* check for memory allocation failure */
      if (!vop)
      {
         VFS_VFS_FILE_FREE(vfp); /* free the allocated vfs_file entry */
         set_vfopen_error(ENP_NOMEM);
#ifdef VFS_VERBOSE
         dprintf("vf_alloc_and_link_vop() failed 2\n");
#endif   /* VFS_VERBOSE */
         return NULL;
      }

      /* add the vfs_file structure to the head of the list */

      vfp->next = vfsfiles;
      vfsfiles = vfp;

      /* increment count of total files */
      vfs_total_dyna_files++;

      /* remove leading directory separator before storing name */
      if (*name == '/' || *name == '\\')
         name++;

      /* store the converted name in the directory entry structure */
      strcpy(vfp->name,name);

      /* set the flags */
      vfp->flags = VF_DYNAMICINFO   /* the directory entry was allocated */
      | VF_WRITE        /* the file is writable */
      | VF_NONVOLATILE  /* the file is non-volatile */
      | VF_STALE;       /* the file is stale */

      /* the rest of the vfs_file structure fields remain with the 
       * zeroes that npalloc() is guaranteed to init its data with. 
       * note that this means the data pointer contains a null 
       * because we don't allocate any buffer to hold the data 
       * in until the first write 
       */
      /* link to the file's directory entry structure */
      vop->file = vfp;

      /* the cmploc and tag fields of the vop retain their NULLs from 
       * npalloc(). cmploc contains NULL because there is no data 
       * buffer to point to yet. tag contains NULL because no 
       * decompression operation has started yet
       */
      return vop;
   }

#endif   /* HT_RWVFS */

#ifdef HT_LOCALFS

   /* pass the open to the local file system */
   return (VFILE *) fopen(name,mode);

#else

   set_vfopen_error(ENP_NOFILE);
#ifdef VFS_VERBOSE
   dprintf("fell thru to end of vfopen_locked()\n");
#endif   /* VFS_VERBOSE */
   return NULL;

#endif   /* HT_LOCALFS */
}



/* FUNCTION: vfopen()
 * 
 * PARAM1: char * name
 * PARAM2: char * mode
 *
 * RETURNS: 
 */

VFILE *
vfopen(char * name, char * mode)
{
   VFILE *vfd;

#ifdef VFS_UNIT_TEST
   if (vfs_log_file_name)
      dprintf("vfopen() passed >%s<,%s\n",name,mode);
#endif   /* VFS_UNIT_TEST */

   /* lock the VFS */
   vfs_lock();

   vfd = vfopen_locked(name,mode);

   vfs_unlock();

   return vfd;
}



/* FUNCTION: vfclose_locked()
 * 
 * PARAM1: VFILE * vfd
 *
 * RETURNS: 
 */

void 
vfclose_locked(VFILE * vfd)
{
   VFILE * vtmp;
   VFILE * vlast;

   vlast = NULL;

   /* see if vfd is in our list of open virtual files. We
      can't use isvfile() since we need a pointer to last. */
   vtmp = vfiles;
   while (vtmp)
   {
      /* if this is the one we are looking for, exist search loop */
      if (vfd == vtmp)
         break;

      /* bump the next and previous pointers along to try the next one */
      vlast = vtmp;
      vtmp = vtmp->next;
   }

   /* if the passed in handle was not in the list we maintain */
   if (vfd != vtmp)
   {

#ifdef HT_LOCALFS
      /* default to call on local system */
      fclose((FILE*)vfd);
#endif   /* HT_LOCALFS */
      return;
   }

   /* the passed in handle is in the list we maintain */

   /* this not really a forever loop. it exists so we can break easily
      and deal with all the ifdefs */
   while (1)
   {
      struct vfs_file * vfp   =  vfd->file;
#ifdef HT_RWVFS
      unsigned char *new_buffer;

      /* vfd->file will be null if somebody unlinked the file after 
       * this handle was created to point to it. if the file itself 
       * is gone there is nothing left to do, so break to list 
       * deletion code at bottom of loop
       */
      if (vfp == NULL)
         break;
#endif   /* HT_RWVFS */

#ifdef HT_EXTDEV
      /* if the file was created by an external file system */
      if (vfp->method)
      {
         /* call that file system's fclose() */
         struct vfroutines *  vfs   =  (struct  vfroutines*)(vfp->method);

         vfs->r_fclose(vfd);
         break;   /* break to list deletion code after end of phoney loop */
      }
#endif   /* HT_EXTDEV */

#ifdef HT_RWVFS

      /* if the buffer containing the data was allocated dynamically, 
       * and there are VFS_CLOSE_FRAG_FLOOR bytes of unused data 
       * between the end of the file and the end of the buffer 
       */
      if ((vfp->flags & VF_DYNAMICDATA) &&
          ((vfp->buf_size - vfp->comp_size) > VFS_CLOSE_FRAG_FLOOR) &&
          vfp->data) /* this last test is a sanity check */
      {
         /* try to reclaim the unused data */

         /* allocate a new buffer just big enough for the data */
         new_buffer = vf_alloc_buffer(vfp->comp_size);

         /* if the allocation worked */
         if (new_buffer)
         {
            /* copy the old buffer to the new one */
            MEMCPY(new_buffer,vfp->data,(unsigned int) (vfp->comp_size));
            /* free the old buffer */
            vf_free_buffer(vfp->data,vfp->buf_size);
            /* update the buffer pointer and size to reflect the
               just big enough buffer */
            vfp->data = new_buffer;
            vfp->buf_size = vfp->comp_size;
         }
      }

#ifdef VFS_AUTO_SYNC
      /* if the file's flags indicate that the file is non-volatile
         and that it has been changed */
      if ((vfp->flags & (VF_NONVOLATILE | VF_STALE)) ==
          (VF_NONVOLATILE | VF_STALE))
      {
         /* store the non-volatile files to whatever backing store 
          * the system provides. note that it is up to the vfs_sync() 
          * function to clear the VF_STALE bits in whatever files it 
          * successfully stores. this way if a given attempt fails, 
          * the unsuccessfully saved files get another chance on the 
          * next call to vfs_sync(). note also that the sync function 
          * is passed the pointer to the vfs_file so that if all it 
          * does is sync the single file, then only that 
          * file's VF_STALE flag can be cleared. 
          */
         vfs_sync(vfp);
      }
#endif   /* VFS_AUTO_SYNC */

#endif   /* HT_RWVFS */

      /* break to list deletion code below */
      break;

   }

   if (vlast)  /* unlink from list of open files */
      vlast->next = vtmp->next;
   else
      vfiles = vtmp->next;

   /* free structure addressed by open handle */
   VFS_VFS_OPEN_FREE(vtmp);
   /* decrement the number of open files */
   vfs_open_files--;
   return;
}



/* FUNCTION: vfclose()
 * 
 * PARAM1: VFILE *vfd
 *
 * RETURNS: 
 */

void vfclose(VFILE * vfd)
{
   vfs_lock();

   vfclose_locked(vfd);

   vfs_unlock();
}

#ifdef HT_RWVFS



/* FUNCTION: vunlink_flag_open_files()
 * 
 * fix up references to deleted file in list of currently 
 * open VFILEs 
 *
 * PARAM1: struct vfs_file *vfp
 *
 * RETURNS: 
 */

void vunlink_flag_open_files(struct vfs_file * vfp)
{
   VFILE * vtmp;

   /* for all open files */
   for (vtmp = vfiles; vtmp; vtmp = vtmp->next)
   {
      /* if the open file handle is referencing the file we are
         deleting, set that reference to NULL */
      if (vtmp->file == vfp)
         vtmp->file = NULL;
   }
}

#endif   /* HT_RWVFS */



/* FUNCTION: vunlink()
 * 
 * PARAM1: char *name
 *
 * RETURNS: 
 */

int
vunlink(char * name)
{
   struct vfs_file * vfp;
   int   rc =  0;
#ifdef VFS_AUTO_SYNC
   int   do_sync  =  0;
#endif
#ifdef   HT_RWVFS
   struct vfs_file * vtmp;
   struct vfs_file * vflast;
   struct vfs_file * vfnext;
#endif

#ifdef VFS_UNIT_TEST
   if (vfs_log_file_name)
      dprintf("vunlink() passed >%s<\n",name);
#endif   /* VFS_UNIT_TEST */

   /* lock the VFS */
   vfs_lock();

   /* see if the converted name is one of the one's in our list */
   /* if it isn't */
   if ((vfp = vfslookup_locked(name)) == NULL)
   {
      vfs_unlock();

#ifdef HT_LOCALFS
      /* default to call on local system */
      return remove(name);
#else
      /* no local file system, so return error condition */
      return -1;
#endif   /* HT_LOCALFS */
   }

#ifdef   HT_RWVFS
   /* save the next link pointer since in one path through the code, 
    * the vfs_file structure gets freed before its unlinked from the 
    * list
    */
   vfnext = vfp->next;

   /* search list of files to determine predecessor in list */
   vflast = NULL;
   for (vtmp = vfsfiles; vtmp != NULL; vtmp = vtmp->next)
   {
      if (vtmp == vfp)
         break;
      vflast = vtmp;
   }

   /* this shouldn't happen since vfslookup_locked() already searched
      the list, but just in case */
   if (vtmp == NULL)
   {
      dtrap("vfsfiles 2\n");
      vfs_unlock();
      return -1;
   }

   /* this is not really a forever loop. it exists so we can break easily
      and deal with all the ifdefs */
   while (1)
   {

#ifdef HT_EXTDEV
      /* if the file was created by an external file system */
      if (vfp->method)
      {
         /* call that file system's unlink() */
         struct vfroutines *  vfs   =  (struct  vfroutines*)   (vfp->method);

         rc = vfs->r_unlink(name);
         break;   /* break to list deletion code after end of phoney loop */
      }
#endif   /* HT_EXTDEV */

      /* if the file is not write enabled, return error condition */
      if (!(vfp->flags & VF_WRITE))
      {
         vfs_unlock();
         return -1;
      }

      /* if the data buffer containing the file's data was dynamically
         allocated and is not null */
      if ((vfp->flags & VF_DYNAMICDATA) && (vfp->data))
      {
         /* free the buffer */
         vf_free_buffer(vfp->data,vfp->buf_size);
      }

      /* if the vfs_file structure itself was allocated dynamically */
      if (vfp->flags & VF_DYNAMICINFO)
      {
         /* decrement count of total files */
         vfs_total_dyna_files--;

         /* free the vfs_file structure */
         VFS_VFS_FILE_FREE(vfp);
      }

      /* since we modified the list we maintain, do a sync, but after
         the vfs_file has been deleted from the list */
#ifdef VFS_AUTO_SYNC
      do_sync = 1;
#endif
      /* we were successful at our unlink */
      rc = 0;

      break;
   }

   /* delete the vfs_file structure from the list headed by vfsfiles */
   if (vflast)
      vflast->next = vfnext;
   else
      vfsfiles = vfnext;

   /* fix up references to deleted file in list of currently open VFILEs */
   vunlink_flag_open_files(vfp);

   /* flag that the directory is stale so vfs_sync() knows it has to do
      something */
   vfs_dir_stale = TRUE;

#ifdef VFS_AUTO_SYNC
   /* if we need to sync the backing store, call the function to do it */
   if (do_sync)
   {
      /* a NULL passed to vfs_sync() means that only the directory
         structure itself was changed */
      vfs_sync(NULL);
   }
#endif   /* VFS_AUTO_SYNC */

#else    /* HT_RWVFS */

   /* unlinks not allowed on read-only VFS */
   rc = -1;

#endif   /* HT_RWVFS */
   vfs_unlock();
   return rc;
}



⌨️ 快捷键说明

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