コード例 #1
0
struct fs_dirent *vc_hostfs_readdir_r(void *dhandle, struct fs_dirent *result)
{
   struct fs_dir *fsdir = (struct fs_dir *)dhandle;

   DEBUG_MINOR( "vc_hostfs_readdir_r(%p)", fsdir );

   if (fsdir && result)
   {
      struct dirent *dent;

      while ((dent = readdir(fsdir->dhandle)) != NULL)
      {
         struct stat statbuf;
         int ret;

         /* Append the filename, and stat the resulting path */
         fsdir->pathbuf[fsdir->pathlen] = '/';
         strcpy(fsdir->pathbuf + fsdir->pathlen + 1, dent->d_name);
         ret = stat(fsdir->pathbuf, &statbuf);
         fsdir->pathbuf[fsdir->pathlen] = '\0';

         if (ret == 0)
         {
            strncpy(result->d_name, dent->d_name, sizeof(result->d_name) - 1);
            result->d_name[sizeof(result->d_name) - 1] = '\0';
            result->d_size = (statbuf.st_size <= 0xffffffff) ? (unsigned int)statbuf.st_size : 0xffffffff;
            result->d_attrib = ATTR_NORMAL;
            if ((statbuf.st_mode & S_IWUSR) == 0)
               result->d_attrib |= ATTR_RDONLY;
            if (statbuf.st_mode & S_IFDIR)
               result->d_attrib |= ATTR_DIRENT;
            result->d_creatime = statbuf.st_ctime;
            result->d_modtime = statbuf.st_mtime;
            DEBUG_MINOR( "vc_hostfs_readdir_r() = '%s', %x, %x", result->d_name, result->d_size, result->d_attrib );
            break;
         }
      }

      if (!dent)
      {
         DEBUG_MINOR( "vc_hostfs_readdir_r() = NULL" );
         rewinddir(fsdir->dhandle);
         result = NULL;
      }
   }
   else
   {
      result = NULL;
   }

   return result;
}
コード例 #2
0
int vc_hostfs_get_attr(const char *path, fattributes_t *attr)
{
    struct stat sb;

    DEBUG_MINOR("vc_hostfs_get_attr: '%s'", path );


    *attr = 0;

    if ( stat( path, &sb ) == 0 )
    {
        if ( S_ISDIR( sb.st_mode ))
        {
            *attr |= ATTR_DIRENT;
        }

        if (( sb.st_mode & S_IWUSR  ) == 0 )
        {
            *attr |= ATTR_RDONLY;
        }

        return 0;
    }
    return -1;
}
コード例 #3
0
/******************************************************************************
NAME
   vc_hostfs_freespace

SYNOPSIS
   int vc_hostfs_freespace(const char *path)

FUNCTION
   Returns the amount of free space on the physical file system that contains
   path.

RETURNS
   Successful completion: free space
   Otherwise: -1
******************************************************************************/
int64_t vc_hostfs_freespace64(const char *inPath)
{
   char *path = strdup( inPath );
   int64_t ret;
   STRUCT_STATFS fsStat;

   // Replace all '\' with '/'
   backslash_to_slash( path );

   ret = (int64_t) STATFS( path, &fsStat );

   if (ret == 0)
   {
      ret = fsStat.f_bsize * fsStat.f_bavail;
   }
   else
   {
      ret = -1;
   }

   DEBUG_MINOR( "vc_hostfs_freespace64 for '%s' returning %" PRId64 "", path, ret );

   free( path );
   return ret;
}
コード例 #4
0
void vc_hostfs_init(void)
{
   // This hostfs module is not thread safe - it allocaes a block
   // of memory and uses it without any kind of locking. 
   //
   // It offers no advantage of stdio, and so most clients should
   // not use it. Arguably FILESYS should use it in order to get
   // the FIFO support.

   const char *thread_name = vcos_thread_get_name(vcos_thread_current());
   if (strcmp(thread_name, "FILESYS") != 0 && strcmp(thread_name, "HFilesys") != 0)
   {
      fprintf(stderr,"%s: vc_hostfs is deprecated. Please use stdio\n",
              vcos_thread_get_name(vcos_thread_current()));
   }

   vcos_log_register("hostfs", &hostfs_log_cat);
   DEBUG_MINOR("init");
   // Allocate memory for the file info table
   p_file_info_table = (file_info_t *)calloc( FILE_INFO_TABLE_CHUNK_LEN, sizeof( file_info_t ) );
   assert( p_file_info_table != NULL );
   if (p_file_info_table)
   {
      file_info_table_len = FILE_INFO_TABLE_CHUNK_LEN;
   }
}
コード例 #5
0
int64_t vc_hostfs_lseek64(int fildes, int64_t offset, int whence)
{
   DEBUG_MINOR("vc_hostfs_lseek(%d,%" PRId64 ",%d)", fildes, offset, whence);
   if (fildes >= file_info_table_len)
   {
      // File descriptor not in table, so this is an error
      DEBUG_MAJOR("vc_hostfs_lseek: invalid fildes %d", fildes);
      return -1;
   }
   else
   {
      // There is entry in the file info table for this file descriptor, so go
      // ahead and handle the seek
      int64_t read_offset = p_file_info_table[fildes].read_offset;

      if (p_file_info_table[fildes].is_fifo)
      {
         // The Videocore is attempting to seek on a FIFO.  FIFOs don't support seeking
         // but, for the benefit of certain Videocore "streaming" file handlers, we
         // will fake limited FIFO seek functionality by computing where a seek
         // would take us to
         if (whence == SEEK_SET)
         {
            read_offset = offset;
         }
         else if (whence == SEEK_CUR)
         {
            read_offset += offset;
         }
         else
         {
            // seeking to the end of FIFO makes no sense, so this is an error
            DEBUG_MAJOR("vc_hostfs_lseek(%d,%lld,%d): SEEK_END not supported on FIFO", fildes, (long long)offset, whence);
            return -1;
         }
      }
      else
      {
         // File is not a FIFO, so do the seek
         read_offset = lseek64(fildes, offset, whence);
      }
      p_file_info_table[fildes].read_offset = read_offset;
      DEBUG_MINOR("vc_hostfs_lseek returning %" PRId64 ")", read_offset);
      return read_offset;
   }
}
コード例 #6
0
int vc_hostfs_mkdir(const char *path)
{
    DEBUG_MINOR( "vc_hostfs_mkdir: '%s'",  path );
    if ( mkdir( path, 0777 ) == 0 )
    {
        return 0;
    }
    return -1;
}
コード例 #7
0
void *vc_hostfs_opendir(const char *dirname)
{
   struct fs_dir *fsdir = NULL;

   DEBUG_MINOR( "vc_hostfs_opendir: '%s'", dirname );

   if (dirname && dirname[0])
   {
      fsdir = (struct fs_dir *)malloc(sizeof(struct fs_dir));

      if (fsdir)
      {
         DIR *dhandle;
         int len = strlen(dirname);

         memcpy(fsdir->pathbuf, dirname, len);

         backslash_to_slash(fsdir->pathbuf);

         /* Remove any trailing slashes */
         while (fsdir->pathbuf[len - 1] == '/')
            len--;

         fsdir->pathbuf[len] = '\0';

         dhandle = opendir(fsdir->pathbuf);
         DEBUG_MINOR( "opendir: '%s' = %p", fsdir->pathbuf, dhandle );

         if (dhandle)
         {
            fsdir->pathlen = len;
            fsdir->dhandle = dhandle;
         }
         else
         {
            free(fsdir);
            fsdir = NULL;
         }
      }
   }

   return fsdir;
}
コード例 #8
0
int vc_hostfs_remove(const char *path)
{
    char *pathbuf = strdup(path);
    int ret = -1;

    DEBUG_MINOR( "vc_hostfs_remove: '%s'", path );

    if (pathbuf)
    {
       backslash_to_slash(pathbuf);

       if ( unlink( pathbuf ) == 0 )
          ret = 0;
    }
    return ret;
}
コード例 #9
0
int vc_hostfs_closedir(void *dhandle)
{
   struct fs_dir *fsdir = (struct fs_dir *)dhandle;
   int ret = -1;

   DEBUG_MINOR( "vc_hostfs_closedir(%p)", dhandle );

   if (dhandle && fsdir->dhandle)
   {
      (void)closedir(fsdir->dhandle);
      fsdir->dhandle = NULL;
      free(fsdir);
      ret = 0;
   }

   return ret;
}
コード例 #10
0
int vc_hostfs_read(int fildes, void *buf, unsigned int nbyte)
{
   if (fildes >= file_info_table_len)
   {
      // File descriptor not in table, so this is an error
      DEBUG_MAJOR("vc_hostfs_read(%d,%p,%u): invalid fildes", fildes, buf, nbyte);
      return -1;
   }
   else
   {
      // There is entry in the file info table for this file descriptor, so go
      // ahead and handle the read
      int ret = (int) read(fildes, buf, nbyte);
      DEBUG_MINOR("vc_hostfs_read(%d,%p,%u) = %d", fildes, buf, nbyte, ret);
      if (ret > 0)
      {
         p_file_info_table[fildes].read_offset += (long) ret;
      }
      return ret;
   }
}
コード例 #11
0
int vc_hostfs_format(const char *path)
{
   DEBUG_MINOR("vc_hostfs_format: '%s' not implemented", path);
   return -1;
}
コード例 #12
0
int vc_hostfs_write(int fildes, const void *buf, unsigned int nbyte)
{
   int ret = (int) write(fildes, buf, nbyte);
   DEBUG_MINOR("vc_hostfs_write(%d,%p,%u) = %d", fildes, buf, nbyte, ret);
   return ret;
}
コード例 #13
0
int vc_hostfs_open(const char *inPath, int vc_oflag)
{
   char *path = strdup( inPath );
   //char *s;
   int flags = 0, ret=errno;
   struct stat fileStat;

   // Replace all '\' with '/'
   backslash_to_slash( path );

#if 0
   s = path + strlen( path );
   if (( s - path ) >= 4 )
   {
      if ( strcasecmp( &s[ -4 ], ".vll" ) == 0 )
      {
         // The Videocore is asking for a .vll file. Since it isn't consistent with
         // the case, we convert .vll files to all lowercase.
          "vc_hostfs_open: '%s'", path ;

         s--;	 // backup to the last character (*s is on the '\0')
         while (( s >= path ) && ( *s != '/' ))
         {
            *s = tolower( *s );
            s--;
         }
      }
   }
#endif
   DEBUG_MINOR("vc_hostfs_open: '%s'", path);

   flags = O_RDONLY;
   if (vc_oflag & VC_O_WRONLY)  flags =  O_WRONLY;
   if (vc_oflag & VC_O_RDWR)    flags =  O_RDWR;
   if (vc_oflag & VC_O_APPEND)  flags |= O_APPEND;
   if (vc_oflag & VC_O_CREAT)   flags |= O_CREAT;
   if (vc_oflag & VC_O_TRUNC)   flags |= O_TRUNC;
   if (vc_oflag & VC_O_EXCL)    flags |= O_EXCL;

   //while (*path == '\\') path++; // do not want initial '\'
   if (flags & O_CREAT)
      ret = open(path, flags, S_IRUSR | S_IWUSR );
   else
      ret = open(path, flags );

   if (ret < 0 )
   {
      DEBUG_MINOR("vc_hostfs_open(%s,%d) = %d", path, vc_oflag, ret);
   }
   else
   {
      DEBUG_MINOR("vc_hostfs_open(%s,%d) = %d", path, vc_oflag, ret);
   }

   // If the file was successfully open then initialize its entry in
   // the file info table.  If necessary, we expand the size of the table
   if (ret >= 0)
   {
      // File was successfully opened
      if (ret >= file_info_table_len)
      {
         file_info_t *p_new_file_info_table = p_file_info_table;
         int new_file_info_table_len = file_info_table_len;

         // try and allocate a bigger buffer for the file info table
         new_file_info_table_len += FILE_INFO_TABLE_CHUNK_LEN;
         p_new_file_info_table = calloc( (size_t)new_file_info_table_len, sizeof( file_info_t ) );
         if (p_new_file_info_table == NULL)
         {
            // calloc failed
            DEBUG_MAJOR("vc_hostfs_open: file_info_table calloc failed");
            assert( 0 );
         }
         else
         {
            // calloc successful, so copy data from previous buffer to new buffer,
            // free previous buffer and update ptr and len info
            memcpy( p_new_file_info_table, p_file_info_table, sizeof( file_info_t ) * file_info_table_len );
            free( p_file_info_table );
            p_file_info_table = p_new_file_info_table;
            file_info_table_len = new_file_info_table_len;
         }
      }
      assert( ret < file_info_table_len );
      {
         // initialize this file's entry in the file info table
         p_file_info_table[ret].is_fifo = 0;
         p_file_info_table[ret].read_offset = 0;
      }

      // Check whether the file is a FIFO.  A FIFO does not support seeking
      // but we will fake, to the extent supported by the buffered file system
      // on the Videocore, limited FIFO seek functionality.  This is for the benefit
      // of certain Videocore "streaming" file handlers.
      if (fstat( ret, &fileStat ) != 0)
      {
         DEBUG_MINOR("vc_hostfs_open: fstat failed: %s", strerror(errno));
      }
      else if (S_ISFIFO( fileStat.st_mode ))
      {
         // file is a FIFO, so note its fildes for future reference
         p_file_info_table[ret].is_fifo = 1;
         DEBUG_MINOR("vc_hostfs_open: file with fildes %d is a FIFO", ret);
      }
   }

   free( path );

   return ret;
}
コード例 #14
0
int vc_hostfs_close(int fildes)
{
   DEBUG_MINOR("vc_hostfs_close(%d)", fildes);
   return close(fildes);
}