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

📄 testfs.c

📁 eCos操作系统源码
💻 C
📖 第 1 页 / 共 3 页
字号:
//==========================================================================////      testfs.c////      Test file system////==========================================================================//####ECOSGPLCOPYRIGHTBEGIN####// -------------------------------------------// This file is part of eCos, the Embedded Configurable Operating System.// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.//// eCos is free software; you can redistribute it and/or modify it under// the terms of the GNU General Public License as published by the Free// Software Foundation; either version 2 or (at your option) any later version.//// eCos is distributed in the hope that it will be useful, but WITHOUT ANY// WARRANTY; without even the implied warranty of MERCHANTABILITY or// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License// for more details.//// You should have received a copy of the GNU General Public License along// with eCos; if not, write to the Free Software Foundation, Inc.,// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.//// As a special exception, if other files instantiate templates or use macros// or inline functions from this file, or you compile this file and link it// with other works to produce a work based on this file, this file does not// by itself cause the resulting work to be covered by the GNU General Public// License. However the source code for this file must still be made available// in accordance with section (3) of the GNU General Public License.//// This exception does not invalidate any other reasons why a work based on// this file might be covered by the GNU General Public License.//// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.// at http://sources.redhat.com/ecos/ecos-license/// -------------------------------------------//####ECOSGPLCOPYRIGHTEND####//==========================================================================//#####DESCRIPTIONBEGIN####//// Author(s):           nickg// Contributors:        nickg// Date:                2000-05-25// Purpose:             Test file system// Description:         This is a very simple implementation of a RAM file system.//                      This implementation is not "industrial strength" or suitable//                      for production use, it is too wasteful of both memory and time.//                      Its primary purpose is to support testing of the fileio//                      infrastructure and API. It can, however, serve as a model//                      and source of code fragments for the implementation//                      of further filesystems.//              ////####DESCRIPTIONEND####////==========================================================================#include <pkgconf/hal.h>#include <pkgconf/kernel.h>#include <pkgconf/io_fileio.h>#include <cyg/kernel/ktypes.h>         // base kernel types#include <cyg/infra/cyg_trac.h>        // tracing macros#include <cyg/infra/cyg_ass.h>         // assertion macros#include <unistd.h>#include <fcntl.h>#include <sys/stat.h>#include <errno.h>#include <dirent.h>#include <cyg/fileio/fileio.h>#include <cyg/kernel/kapi.h>#include <cyg/infra/diag.h>//==========================================================================// Configuration  parameters#define TESTFS_NFILE            10      // Max number of files/directories#define TESTFS_NBLOCK           20      // Number of data blocks available#define TESTFS_BLOCKSIZE        128     // Bytes stored per block#define TESTFS_FILEBLOCKS       8       // Max blocks per file#define TESTFS_NAMESIZE         32      // Length of file names in bytes// Maximum file size is blocksize*blocks#define TESTFS_FILESIZE_MAX     (TESTFS_BLOCKSIZE*TESTFS_FILEBLOCKS)//==========================================================================// Data structuresstruct testfs_node;typedef struct testfs_node testfs_node;struct testfs_block;typedef struct testfs_block testfs_block;struct testfs_node{    testfs_node         *next;          // next node in list    testfs_node         *parent;        // Back pointer to parent    int                 refcnt;         // reference count    char                name[TESTFS_NAMESIZE]; // file name    struct stat         status;         // status data    union    {        struct        {            testfs_block        *data[TESTFS_FILEBLOCKS];  // array of blocks        } file;        struct        {            testfs_node         *nodes[TESTFS_FILEBLOCKS]; // array of nodes        } dir;    } u;};struct testfs_block{    union    {        testfs_block    *next;          // next block in free list        testfs_node     *file;          // back pointer to file    } u;    off_t               pos;            // position in file of first byte    size_t              size;           // number of bytes in buffer    char                data[TESTFS_BLOCKSIZE]; // the data};//==========================================================================// Local data// Array of nodesstatic testfs_node node[TESTFS_NFILE];// node free list.static testfs_node *free_node = NULL;// Array of data blocksstatic testfs_block block[TESTFS_NBLOCK];// block free list.static testfs_block *free_block = NULL;// Init flagcyg_bool testfs_initialized = false;//==========================================================================// Forward definitions// Filesystem operationsstatic int testfs_mount    ( cyg_fstab_entry *fste, cyg_mtab_entry *mte );static int testfs_umount   ( cyg_mtab_entry *mte );static int testfs_open     ( cyg_mtab_entry *mte, cyg_dir dir, const char *name,                             int mode,  cyg_file *fte );static int testfs_unlink   ( cyg_mtab_entry *mte, cyg_dir dir, const char *name );static int testfs_mkdir    ( cyg_mtab_entry *mte, cyg_dir dir, const char *name );static int testfs_rmdir    ( cyg_mtab_entry *mte, cyg_dir dir, const char *name );static int testfs_rename   ( cyg_mtab_entry *mte, cyg_dir dir1, const char *name1,                             cyg_dir dir2, const char *name2 );static int testfs_link     ( cyg_mtab_entry *mte, cyg_dir dir1, const char *name1,                             cyg_dir dir2, const char *name2, int type );static int testfs_opendir  ( cyg_mtab_entry *mte, cyg_dir dir, const char *name,                             cyg_file *fte );static int testfs_chdir    ( cyg_mtab_entry *mte, cyg_dir dir, const char *name,                             cyg_dir *dir_out );static int testfs_stat     ( cyg_mtab_entry *mte, cyg_dir dir, const char *name,                             struct stat *buf);static int testfs_getinfo  ( cyg_mtab_entry *mte, cyg_dir dir, const char *name,                             int key, void *buf, int len );static int testfs_setinfo  ( cyg_mtab_entry *mte, cyg_dir dir, const char *name,                             int key, void *buf, int len );// File operationsstatic int testfs_fo_read      (struct CYG_FILE_TAG *fp, struct CYG_UIO_TAG *uio);static int testfs_fo_write     (struct CYG_FILE_TAG *fp, struct CYG_UIO_TAG *uio);static int testfs_fo_lseek     (struct CYG_FILE_TAG *fp, off_t *pos, int whence );static int testfs_fo_ioctl     (struct CYG_FILE_TAG *fp, CYG_ADDRWORD com,                                CYG_ADDRWORD data);//static int testfs_fo_select    (struct CYG_FILE_TAG *fp, int which, CYG_ADDRWORD info);static int testfs_fo_fsync     (struct CYG_FILE_TAG *fp, int mode );        static int testfs_fo_close     (struct CYG_FILE_TAG *fp);static int testfs_fo_fstat     (struct CYG_FILE_TAG *fp, struct stat *buf );static int testfs_fo_getinfo   (struct CYG_FILE_TAG *fp, int key, void *buf, int len );static int testfs_fo_setinfo   (struct CYG_FILE_TAG *fp, int key, void *buf, int len );// Directory operationsstatic int testfs_fo_dirread      (struct CYG_FILE_TAG *fp, struct CYG_UIO_TAG *uio);static int testfs_fo_dirlseek     (struct CYG_FILE_TAG *fp, off_t *pos, int whence );//==========================================================================// Filesystem table entriesFSTAB_ENTRY( testfs_fste, "testfs", 0,             CYG_SYNCMODE_FILE_FILESYSTEM|CYG_SYNCMODE_IO_FILESYSTEM,             testfs_mount,             testfs_umount,             testfs_open,             testfs_unlink,             testfs_mkdir,             testfs_rmdir,             testfs_rename,             testfs_link,             testfs_opendir,             testfs_chdir,             testfs_stat,             testfs_getinfo,             testfs_setinfo);MTAB_ENTRY( testfs_mte1,                   "/",                   "testfs",                   "",                   0);#if 0MTAB_ENTRY( testfs_mte2,                   "/ram",                   "testfs",                   "",                   0);#endifstatic cyg_fileops testfs_fileops ={    testfs_fo_read,    testfs_fo_write,    testfs_fo_lseek,    testfs_fo_ioctl,    cyg_fileio_seltrue,    testfs_fo_fsync,    testfs_fo_close,    testfs_fo_fstat,    testfs_fo_getinfo,    testfs_fo_setinfo};static cyg_fileops testfs_dirops ={    testfs_fo_dirread,    (cyg_fileop_write *)cyg_fileio_enosys,    testfs_fo_dirlseek,    (cyg_fileop_ioctl *)cyg_fileio_enosys,    cyg_fileio_seltrue,    (cyg_fileop_fsync *)cyg_fileio_enosys,    testfs_fo_close,    (cyg_fileop_fstat *)cyg_fileio_enosys,    (cyg_fileop_getinfo *)cyg_fileio_enosys,    (cyg_fileop_setinfo *)cyg_fileio_enosys};//==========================================================================// Support routines// -------------------------------------------------------------------------// Local strcmp() and strcpy()static int strcmp( const char *s1, const char *s2 ){    while( *s1 == *s2 && *s1 != '\0' && *s2 != '\0' )        s1++, s2++;    return (*s2)-(*s1);}static char *strcpy( char *s1, const char *s2 ){    char *s = s1;    while( (*s1++ = *s2++) != 0);    return s;}// -------------------------------------------------------------------------// Follow a path through the directory structurestatic int testfs_find( testfs_node *dir,       // dir to start search in                        const char *path,       // path to follow                        testfs_node **found,    // return node found                        testfs_node **parent,   // return last dir searched                        char *name,             // name fragment buffer                        cyg_bool *lastp)        // last name in path ?{    testfs_node *nd = dir;    *lastp = false;    *found = NULL;        while( *path != '\0' )    {        const char *p = path;        char *n = name;        testfs_node *nd1;        int i;        // check nd is a directory        if( !S_ISDIR(nd->status.st_mode) ) return ENOTDIR;                // Isolate the next element of the path name.         while( *p != '\0' && *p != '/' && (n-&name[0]) < TESTFS_NAMESIZE)            *n++ = *p++;        if( (n-&name[0]) >= TESTFS_NAMESIZE )            return ENAMETOOLONG;        // Step path on past the separator        // If this is the last name element in the path,        // set *lastp to indicate this.        if( *(path=p) == '/' ) path++;        else *lastp = true;        // teminate name        *n = '\0';        // name now contains the next path element, search the node        // in nd for it.        *parent = nd;        nd1 = NULL;                for( i = 0; i < TESTFS_FILEBLOCKS; i++ )        {            testfs_node *n = nd->u.dir.nodes[i];            if( n == NULL )                continue;            if( strcmp( name, n->name ) == 0 )            {                nd1 = n;                break;            }        }                if( nd1 == NULL ) return ENOENT;        nd = nd1;    }    // Return what we have found    *found = nd;        return ENOERR;}// -------------------------------------------------------------------------// Get current time since epochstatic time_t testfs_time(void){    // FIXME: !!!!Temporary!!!!    return cyg_current_time();}// -------------------------------------------------------------------------static int testfs_delnode( testfs_node *nd ){    testfs_node *parent;    int i;    // Non-unitary ref count means this node is either open        // or is a dir with entries in it.    if( nd->refcnt > 1 )        return EBUSY;    // Remove from parent's node list.        parent = nd->parent;    for( i = 0; i < TESTFS_FILEBLOCKS; i++ )        if( parent->u.dir.nodes[i] == nd )        {            parent->u.dir.nodes[i] = NULL;            break;        }    parent->refcnt--;    if( S_ISREG(nd->status.st_mode) )    {        // for a file, return blocks to free list        for( i = 0; i < TESTFS_FILEBLOCKS; i++ )        {            testfs_block *b = nd->u.file.data[i];            if( b != NULL )            {                b->u.next = free_block;                b->pos = -1;                free_block = b;            }        }    }    // and finally return nd to free node list    nd->next = free_node;    nd->refcnt = -1;    free_node = nd;    return ENOERR;}//==========================================================================// Filesystem operations// -------------------------------------------------------------------------static int testfs_mount    ( cyg_fstab_entry *fste, cyg_mtab_entry *mte ){    testfs_node *root;    int i;    

⌨️ 快捷键说明

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