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

📄 testfs.c

📁 eCos操作系统源码
💻 C
📖 第 1 页 / 共 3 页
字号:
        nd->refcnt++;        // Pass it out        *dir_out = (cyg_dir)nd;    }    else    {        // If no output dir is required, this means that the mte and        // dir arguments are the current cdir setting and we should        // forget this fact.        testfs_node *nd = (testfs_node *)dir;        // Just decrement reference count.        nd->refcnt--;    }            return ENOERR;}// -------------------------------------------------------------------------static int testfs_stat     ( cyg_mtab_entry *mte, cyg_dir dir, const char *path,                          struct stat *buf){    testfs_node *nd, *parent;    int err;    char name[TESTFS_NAMESIZE];    cyg_bool lastp;        err = testfs_find( (testfs_node *)dir, path, &nd, &parent, name, &lastp );    if( err != ENOERR ) return err;    *buf = nd->status;        return err;}// -------------------------------------------------------------------------static int testfs_getinfo  ( cyg_mtab_entry *mte, cyg_dir dir, const char *path,                          int key, void *buf, int len ){    return ENOSYS;}// -------------------------------------------------------------------------static int testfs_setinfo  ( cyg_mtab_entry *mte, cyg_dir dir, const char *path,                          int key, void *buf, int len ){    return ENOSYS;}//==========================================================================// File operations// -------------------------------------------------------------------------static int testfs_fo_read      (struct CYG_FILE_TAG *fp, struct CYG_UIO_TAG *uio){    testfs_node *nd = (testfs_node *)fp->f_data;    int i;    off_t pos = fp->f_offset;    for( i = 0; i < uio->uio_iovcnt; i++ )    {        cyg_iovec *iov = &uio->uio_iov[i];        char *buf = (char *)iov->iov_base;        off_t len = iov->iov_len;        while( len > 0 && pos < nd->status.st_size )        {            testfs_block *b = nd->u.file.data[pos/TESTFS_BLOCKSIZE];            off_t l = len;            off_t bpos = pos%TESTFS_BLOCKSIZE;                        // If there is no block in that pos, we have reached            // the end of the file.            if( b == NULL ) return ENOERR;            // adjust size to this block            if( l > (b->size-bpos) )                l = (b->size-bpos);            // copy data out            memcpy( buf, &b->data[bpos], l );            uio->uio_resid -= l;            len -= l;            buf += l;            pos += l;            // keep offset up to date incase of errors            fp->f_offset = pos;        }    }        return ENOERR;}// -------------------------------------------------------------------------static int testfs_fo_write     (struct CYG_FILE_TAG *fp, struct CYG_UIO_TAG *uio){    testfs_node *nd = (testfs_node *)fp->f_data;    int i;    off_t pos = fp->f_offset;        // Check we are not at end of allowed max file size    if( pos >= TESTFS_FILESIZE_MAX )        return EFBIG;    // Check that pos is within current file size, or at the very end.    if( pos < 0 || pos > nd->status.st_size )        return EINVAL;    // Now loop over the iovecs until they are all done, or    // we get an error.    for( i = 0; i < uio->uio_iovcnt; i++ )    {        cyg_iovec *iov = &uio->uio_iov[i];        char *buf = (char *)iov->iov_base;        off_t len = iov->iov_len;        while( len > 0 )        {            testfs_block *b = nd->u.file.data[pos/TESTFS_BLOCKSIZE];            off_t l = len;            off_t bpos = pos%TESTFS_BLOCKSIZE;                        // If there is no block in that pos, allocate one            // and initialize it            if( b == NULL )            {                b = free_block;                if( b == NULL ) return ENOSPC;                free_block = b->u.next;                nd->u.file.data[pos/TESTFS_BLOCKSIZE] = b;                b->u.file = nd;                b->pos = pos;                b->size = 0;            }            // adjust size to this block            if( l > (TESTFS_BLOCKSIZE-bpos) )                l = (TESTFS_BLOCKSIZE-bpos);            // copy data in            memcpy( &b->data[bpos], buf, l );            // adjust buffer info            if( b->size < bpos+l )                b->size = bpos+l;                        uio->uio_resid -= l;            len -= l;            buf += l;            pos += l;            // keep node size and file offset up to date            //in case of an error.            if( pos > nd->status.st_size )                nd->status.st_size = pos;            fp->f_offset = pos;            if( pos >= TESTFS_FILESIZE_MAX )                return EFBIG;        }    }        return ENOERR;}// -------------------------------------------------------------------------static int testfs_fo_lseek     (struct CYG_FILE_TAG *fp, off_t *apos, int whence ){    testfs_node *nd = (testfs_node *)fp->f_data;    off_t pos = *apos;    switch( whence )    {    case SEEK_SET:        // we are already where we want to be.        break;    case SEEK_CUR:        pos += fp->f_offset;        break;    case SEEK_END:        pos += nd->status.st_size;        break;    default:        return EINVAL;    }        // Check that pos is within current file size, or at the very end.    if( pos < 0 || pos > nd->status.st_size )        return EINVAL;    // All OK, set fp offset.    *apos = fp->f_offset = pos;        return ENOERR;}// -------------------------------------------------------------------------static int testfs_fo_ioctl     (struct CYG_FILE_TAG *fp, CYG_ADDRWORD com,                             CYG_ADDRWORD data){    return ENOSYS;}// -------------------------------------------------------------------------static int testfs_fo_fsync     (struct CYG_FILE_TAG *fp, int mode ){    // Nothing to do    return ENOERR;}// -------------------------------------------------------------------------static int testfs_fo_close     (struct CYG_FILE_TAG *fp){    testfs_node *nd = (testfs_node *)fp->f_data;    nd->refcnt--;       // remove open count    fp->f_data = 0;     // clear data pointer        return ENOERR;}// -------------------------------------------------------------------------static int testfs_fo_fstat     (struct CYG_FILE_TAG *fp, struct stat *buf ){    testfs_node *nd = (testfs_node *)fp->f_data;    *buf = nd->status;            return ENOERR;}// -------------------------------------------------------------------------static int testfs_fo_getinfo   (struct CYG_FILE_TAG *fp, int key, void *buf, int len ){    return ENOERR;}// -------------------------------------------------------------------------static int testfs_fo_setinfo   (struct CYG_FILE_TAG *fp, int key, void *buf, int len ){    return ENOERR;}//==========================================================================// Directory operationsstatic int testfs_fo_dirread      (struct CYG_FILE_TAG *fp, struct CYG_UIO_TAG *uio){    testfs_node *nd = (testfs_node *)fp->f_data;    off_t pos = fp->f_offset;    cyg_iovec *iov = &uio->uio_iov[0];    char *buf = (char *)iov->iov_base;    off_t len = iov->iov_len;    // End of directory    if( pos >= TESTFS_FILEBLOCKS )        return ENOERR;    if( len < sizeof(struct dirent) )        return EINVAL;        for( ; pos < TESTFS_FILEBLOCKS; pos++ )        if( nd->u.dir.nodes[pos] != NULL )        {            struct dirent *ent = (struct dirent *)buf;            strcpy( ent->d_name, nd->u.dir.nodes[pos]->name );            uio->uio_resid -= sizeof(struct dirent);            break;        }    fp->f_offset = pos+1;        return ENOERR;}// -------------------------------------------------------------------------static int testfs_fo_dirlseek     (struct CYG_FILE_TAG *fp, off_t *pos, int whence ){    if( whence != SEEK_SET || *pos != 0)        return EINVAL;    *pos = fp->f_offset = 0;        return ENOERR;}//==========================================================================// Filesystem dump// Dumps out the node and block arrays in a readable format, and does// a little consistency checking as it goes.void testfs_dump(void){    int errors = 0;    int i;    char *indent = "\n                      |";    diag_printf("Nodes:\n");    for( i = 0; i < TESTFS_NFILE; i++ )    {        testfs_node *nd = &node[i];        diag_printf("%3d : ",i);        if( nd->refcnt < 0 )            diag_printf("<free>");        else if( !S_ISDIR(nd->status.st_mode) )        {            // Regular file            int j;            diag_printf("f %8s %4d |",nd->name,nd->status.st_size);            for( j = 0; j < TESTFS_FILEBLOCKS; j++ )            {                testfs_block *b = nd->u.file.data[j];                if( b != NULL )                {                    if( j > 0 && (j%4) == 0 )                        diag_printf(indent);                    diag_printf(" %3d[%3d,%3d]",b-block,b->pos,b->size);                    if( b->u.file != nd )                    {                        errors++;                        diag_printf("!");                    }                }            }        }        else        {            // Directory            int j;            int rc = 1;            diag_printf("d %8s      |",nd->name);            for( j = 0; j < TESTFS_FILEBLOCKS; j++ )            {                testfs_node *n = nd->u.dir.nodes[j];                if( n != NULL )                {                    if( j > 0 && (j%4) == 0 )                        diag_printf(indent);                    diag_printf(" %3d[%7s]",n-node,n->name);                    rc++;                }            }            if( nd->refcnt != rc )            {                diag_printf("%s refcount is %d should be %d",indent,nd->refcnt,rc);                if( nd->refcnt == rc+1 )                    diag_printf(" (but may be current dir)");            }        }        diag_printf("\n");    }    diag_printf("Blocks:\n");    for( i = 0; i < TESTFS_NBLOCK; i++ )    {        testfs_block *b = &block[i];        diag_printf("%3d :",i);        if( b->pos == -1 )            diag_printf(" <free>");        else        {            int j;            testfs_node *nd = b->u.file;            diag_printf(" %3d %3d %d[%7s]",b->pos,b->size,nd-node,nd->name);            for( j = 0; j < TESTFS_FILEBLOCKS; j++ )            {                if( nd->u.file.data[j] == b )                    break;            }            if( j == TESTFS_FILEBLOCKS )            {                errors++;                diag_printf(" block not in file!");            }        }        diag_printf("\n");    }    if( errors != 0 )        diag_printf("%d errors detected\n",errors);}// -------------------------------------------------------------------------// EOF testfs.c

⌨️ 快捷键说明

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