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

📄 vfsfiles.c

📁 在ARM7和UC/OSII的平台上实现了GPS自动报站的功能,涉及GPS模块LEA_4S的驱动,位置速寻算法,语音芯片ISD4004的录放音驱动,LED页面管理等等.从启动代码到操作系统的移植以及到业
💻 C
📖 第 1 页 / 共 4 页
字号:
/*
 * FILENAME: vfsfiles.c
 *
 * Copyright 1997- 2000 By InterNiche Technologies Inc. All rights reserved
 *
 *
 * MODULE: VFS
 *
 * ROUTINES: vfopen(), set_vfopen_error(), get_vfopen_error(), 
 * ROUTINES: vf_alloc_and_link_vop(), *vf_alloc_buffer(), vf_free_buffer(), 
 * ROUTINES: vfopen_locked(), vfclose_locked(), vunlink_flag_open_files(), 
 * ROUTINES: vfread(), vfwrite_locked(), vfseek(), vftell(), vgetc_locked(), 
 * ROUTINES: vfslookup_locked(), (), vfslookup(), strippath(), 
 * ROUTINES: isvfile_locked(), (), isvfile(), vferror(), vclearerr(), 
 *
 * PORTABLE: yes
 */

/* Additional Copyrights: */

/* vfsfiles.c 
 * Portions Copyright 1996 by NetPort Software. All rights reserved. 
 * InterNIche virtual file system. This implements the vfopen(), 
 * vfread(), etc, calls the Embedded WEB servers and similar devices 
 * to do file IO. These calls lookup names, descriptors, etc, to see 
 * if the file is a "virtual" file in RAM/ROM/FLASH, or if it should 
 * fall through to the local disk system (if any) 
 * 7/24/96 - Created by John Bartas 
 * 12/10/98 - Added RWVFS hooks for writable file support -JB- 
 * 12/26/98 - Separated from WebPort sources. 
 */

#include "ipport.h"

#ifdef VFS_FILES

#include "vfsport.h"    /* per-port include */

#include "vfsfiles.h"   /* overlay vfs stuff on system file IO */

#include "profiler.h"   /* InterNiche profile utility */
 
/* if this sort of thing is needed, it should probably be in ipport.h */
#ifdef NOTDEF
#ifdef HT_LOCALFS
#include <fcntl.h>   /* Standard lib stuff for file IO */
#include <io.h>
#endif   /* HT_LOCALFS */
#endif   /* NOTDEF */

#ifdef WEBPORT
#include "httpd.h"   /* local NetPort HTML includes */
#include "cgi.h"
#endif   /* WEBPORT */

#ifdef HTML_COMPRESSION
#include "htcmptab.h"   /* tag table, for compression */
#endif   /* HTML_COMPRESSION */

/* path to file system root. This must use UNIX slashes, and should not
be NULL. A single slash is OK. */
#ifdef HT_LOCALFS
/* if there's a local FS (e.g. a disk), force vfs created files to 
 * live in a special directory. This can be changed at startup 
 * time.
 */
char     vfs_root_path[HTPATHMAX]   =  { "/vfs/" };
#else /* the vfs is the whole file system */
char     vfs_root_path[HTPATHMAX]   =  { "/" };
#endif   /* HT_LOCALFS */

#ifdef VFS_STRIPPATH
/* preserve compatibility with old-style webport path */
char *   http_root_path =  &vfs_root_path[0];
#endif   /* VFS_STRIPPATH */

#ifdef HT_EXTDEV
/* list of alternate file IO routine sets */
struct vfroutines *  vfsystems   =  NULL;
#endif   /* HT_EXTDEV */


#ifdef HT_RWVFS

/* this counts the number of bytes that have been allocated for 
 * buffers for the read/write file system so that the above maximum 
 * can be enforced
 */
unsigned long vfs_total_rw_space;

/* this counts the number of dynamically allocated files in the file
   system so that the above maximum can be enforced */
unsigned long vfs_total_dyna_files;

/* this flag gets set during successful unlink operations so that 
 * vfs_sync() knows to sync the file system even though none of the 
 * files in it show that they are stale
 */
int      vfs_dir_stale;

#endif   /* HT_RWVFS */


/* this counts the number of open files in the file system so that
   the above maximum can be enforced */
unsigned long vfs_open_files;

#ifdef VFS_STRIPPATH
char * strippath(char * name);
#endif   /* VFS_STRIPPATH */

VFILE * vfiles = NULL;  /* list of open files */

/* list of files */
struct vfs_file * vfsfiles =  NULL;

#ifdef VFS_UNIT_TEST

/* this flag determines whether the VFS logs the file names that are
   passed to it */
int      vfs_log_file_name =  0;

#endif   /* VFS_UNIT_TEST */

/* vfopen_error is used as a place to store errors that occur in vfopen() */
/* the porting engineer might want to replace this with a macro that
   defines vfopen to be errno, depending on his target system */
int      vfopen_error   =  0;



/* FUNCTION: set_vfopen_error()
 * 
 * this function sets the vfopen() error indication. it is called from
 * vfopen() when errors occur
 *
 * PARAM1: int error
 *
 * RETURNS: 
 */

void set_vfopen_error(int error)
{
   vfopen_error = error;
}



/* FUNCTION: get_vfopen_error()
 * 
 * this function returns the last error that occurred in a call to 
 * vfopen(). the porting engineer might want to define errno to be 
 * equal to this function, depending on his target system 
 *
 * PARAM1: 
 *
 * RETURNS: 
 */

int get_vfopen_error()
{
   return vfopen_error;
}



/* FUNCTION: vf_alloc_and_link_vop()
 * 
 * this function allocates a VFILE structure and links it to the
 * beginning of the linked list of open files
 *
 * PARAM1: 
 *
 * RETURNS: 
 */

VFILE * vf_alloc_and_link_vop()
{
   struct vfs_open * vop;

   /* enforce maximum number of simultaneously open files */
   if (vfs_open_files >= VFS_MAX_OPEN_FILES)
   {
#ifdef VFS_VERBOSE
      dprintf("vfs_open_files too big (%ld) in vf_alloc_and_link_vop()\n",
       vfs_open_files);
#endif   /* VFS_VERBOSE */
      return NULL;
   }

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

   /* if the allocation succeeded */
   if (vop)
   {
      /* add to the beginning of the list of open files */
      vop->next = vfiles;
      vfiles = vop;
      /* increment the count of open files */
      vfs_open_files++;
   }
#ifdef VFS_VERBOSE
   else
      dprintf("VFS_VFS_OPEN_ALLOC() failed in vf_alloc_and_link_vop()\n");
#endif   /* VFS_VERBOSE */

   return vop;
}

#ifdef HT_RWVFS



/* FUNCTION: *vf_alloc_buffer()
 * 
 * PARAM1: unsigned long size
 *
 * RETURNS: 
 */

unsigned char * vf_alloc_buffer(unsigned long size)
{
   unsigned char *buffer;
#ifdef MUTE_WARNS
   unsigned int long_size,int_size;
#endif   /* MUTE_WARNS */

   /* make sure the requested allocation does not exceed the total
      memory space reserved for file buffers */
   if ((vfs_total_rw_space + size) > VFS_MAX_TOTAL_RW_SPACE)
      return NULL;

   /* the file sizes in the vfs_file structures are all unsigned 
    * longs, but npalloc() only can allocate sizes expressed in 
    * unsigned ints, so if your longs are bigger than your ints, you 
    * can't allocate memory 
    * any bigger than what will fit in an unsigned int 
    */
#ifdef MUTE_WARNS
   /* the idiotic hoops you got to jump through to suppress compiler
      warnings */
   long_size   =  sizeof(unsigned   long);
   int_size = sizeof(unsigned int);
   if (long_size > int_size)
#else
   if (sizeof(unsigned long) > sizeof (unsigned int))
#endif   /* MUTE_WARNS */
   {
      unsigned long mem_mask;

      /* what this does is create a mem_mask containing 0xffff0000 on 
       * most systems where this "if" expression will evaluate to 
       * true (2 byte ints, 4 byte longs). if any of those upper bits 
       * are on in your requested size, you otta luck.
       */
#ifdef MUTE_WARNS
      switch (int_size)
#else
      switch (sizeof(unsigned int))
#endif   /* MUTE_WARNS */
      {
      case 2 :
         mem_mask = 0xffff0000;
         break;
         default :
            dtrap("vfsfiles 0\n");    /* you have a weird compiler */
         return NULL;
      }

      if (size & mem_mask)
         return NULL;
   }

   /* try to allocate a buffer of the requested size */
   buffer = (unsigned char *) npalloc((unsigned int) size);

   /* if the allocation succeeded */
   if (buffer)
   {
      /* add size to the count of total buffer space allocated */
      vfs_total_rw_space += size;
   }

   return buffer;
}



/* FUNCTION: vf_free_buffer()
 * 
 * PARAM1: unsigned char *buffer
 * PARAM2: unsigned long size
 *
 * RETURNS: 
 */

void vf_free_buffer(unsigned char * buffer, unsigned long size)
{
   /* free the buffer */
   if (buffer)
      npfree(buffer);

   /* and subtract its size from the total buffer space count */
   vfs_total_rw_space -= size;
}

#endif   /* HT_RWVFS */



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

VFILE *
vfopen_locked(char * name, char * mode)
{
   struct vfs_file * vfp;
   struct vfs_open * vop;

   /* clear any previous vfopen() error */
   set_vfopen_error(0);

   /* the old code used to do special handling of '?' in files for 
    * the benefit of the web server. the web server should be doing 
    * this now. this is here to make sure that its doing it 
    */
   if (strchr(name,'?'))
   {
      dtrap("vfsfiles 1\n");
      return NULL;
   }

   /* determine if the file exists */
   /* if the directory exists, vfp will point to its directory entry
      structure else vfp will be NULL */
   vfp = vfslookup_locked(name);

   /* if the file exists */
   if (vfp)
   {

#ifdef HT_RWVFS

      /* if mode begins with 'w' we will truncate to end of file */
      /* make sure the file is writable before proceeding */
      if ((*mode == 'w') && !(vfp->flags & VF_WRITE))
      {
         set_vfopen_error(ENP_FILEIO);
#ifdef VFS_VERBOSE
         dprintf("mode w with no VF_WRITE\n");
#endif   /* VFS_VERBOSE */
         return NULL;
      }

#endif   /* HT_RWVFS */

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

      /* check for failure */
      if (!vop)
      {
         set_vfopen_error(ENP_NOMEM);
#ifdef VFS_VERBOSE
         dprintf("vf_alloc_and_link_vop() failed 1\n");
#endif   /* VFS_VERBOSE */
         return NULL;
      }

      /* link to the file's directory entry structure */
      vop->file = vfp;

      /* by default start at the beginning of the file */
      /* note that vfp->data could be NULL at this point since empty
         files might have no data buffer allocated to them */
      vop->cmploc = vfp->data;   /* start at beginning of file */

#ifdef HT_RWVFS

      /* if mode begins with 'a', seek to end of file */
      if (*mode == 'a')
      {
         if (vfp->data)
         {
            vop->cmploc = vfp->data + vfp->comp_size;
         }
      }

      /* if mode begins with 'w', truncate to end of file */
      if (*mode == 'w')
      {
         /* set the size of the file before compression to 0 */
         vfp->real_size = 0;
         /* set the size of the compressed data to 0 */
         vfp->comp_size = 0;
         /* note we leave the pointer to the file buffer and its length
            alone since first writes will go to it */
         /* flag that the file has been modified */
         vfp->flags |= VF_STALE;

         /* turn off the compression flag */
         vfp->flags &= ~VF_HTMLCOMPRESSED;
      }

#endif   /* HT_RWVFS */

      return vop;
   }

#ifdef HT_EXTDEV

   /* if the mode implies that the file should be created if it
      does not exist */
   if (*mode != 'r')
   {
      /* see if one of the other systems wants to create this file */
      /* if none of the below devices can open the file, continue on */
      struct vfroutines *  vfs;

      for (vfs = vfsystems; vfs; vfs = vfs->next)
      {
         if ((vop = vfs->r_fopen(name, mode)) != NULL)
         {
            return vop;
         }
      }
   }

#endif   /* HT_EXTDEV */

#ifdef HT_LOCALFS
   /* compare the passed name to a vfs_root_path. if the name does 
    * not begin with it, pass it to the native file 
    * system fopen()
    */
   if (strncmp(name, vfs_root_path, strlen(vfs_root_path)))
   {
      return (VFILE *) fopen(name, mode);
   }
#endif   /* HT_LOCALFS */

#ifdef HT_RWVFS

   /* if the mode implies that the file should be created if it
      does not exist */
   if (*mode != 'r')
   {
      /* enforce maximum number of files */
      if (vfs_total_dyna_files >= VFS_MAX_DYNA_FILES)
      {
         set_vfopen_error(ENP_NOMEM);
#ifdef VFS_VERBOSE
         dprintf("vf_total_dyna_files too big in vfopen_locked()\n");
#endif   /* VFS_VERBOSE */
         return NULL;
      }

      /* make sure the file name is not too long for the VFS */
      if (strlen(name) > FILENAMEMAX)
      {
         set_vfopen_error(ENP_PARAM);

⌨️ 快捷键说明

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