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

📄 testfs.c

📁 eCos操作系统源码
💻 C
📖 第 1 页 / 共 3 页
字号:
    if( !testfs_initialized )    {        int i;        for( i = 0; i < TESTFS_NFILE; i++ )        {            node[i].next = free_node;            node[i].refcnt = -1;            free_node = &node[i];        }        for( i = 0; i < TESTFS_NBLOCK; i++ )        {            block[i].u.next = free_block;            block[i].pos = -1;            free_block = &block[i];        }        testfs_initialized = true;    }    // Allocate a node to be the root of this filesystem and    // initialize it.    root = free_node;        if( root == NULL ) return ENOSPC;    free_node = root->next;    root->next                  = root;  // form circular list    root->parent                = root;  // I'm my own parent!    root->refcnt                = 1;     // don't want to ever lose root    strcpy( root->name, "root");    root->status.st_mode        = __stat_mode_DIR;    root->status.st_ino         = root-&node[0];    root->status.st_dev         = 0;    root->status.st_nlink       = 1;    root->status.st_uid         = 0;    root->status.st_gid         = 0;    root->status.st_size        = 0;    root->status.st_atime       = testfs_time();    root->status.st_mtime       = testfs_time();    root->status.st_ctime       = testfs_time();    for( i = 0; i < TESTFS_FILEBLOCKS; i++ )        root->u.dir.nodes[i]    = NULL;        mte->root = (cyg_dir)root;        return 0;}// -------------------------------------------------------------------------static int testfs_umount    ( cyg_mtab_entry *mte ){    testfs_node *root = (testfs_node *)mte->root;    // Non-empty filesystem, do not unmount    if( root->refcnt != 1 )        return EBUSY;    // Otherwise just return it to the free pool    root->next = free_node;    root->refcnt = -1;    free_node = root;    // Clear root pointer    mte->root = CYG_DIR_NULL;        // That's all folks.        return ENOERR;}// -------------------------------------------------------------------------static int testfs_open     ( cyg_mtab_entry *mte, cyg_dir dir, const char *path,                          int mode,  cyg_file *file ){    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( lastp && err == ENOENT && (mode & O_CREAT) )    {        int i;        // No node there, if the O_CREAT bit is set then we must        // create a new one. The parent and name results will have been filled        // in, so we know where to put it.        // first check that there is space for it        for( i = 0; i < TESTFS_FILEBLOCKS; i++ )            if( parent->u.dir.nodes[i] == NULL )                break;        if( i == TESTFS_FILEBLOCKS ) return ENOSPC;                // Allocate a new node        nd = free_node;        if( nd == NULL ) return ENOSPC;        free_node = nd->next;        // Add to directory list        parent->u.dir.nodes[i] = nd;        parent->refcnt++;                // Fill in details        nd->parent              = parent;        nd->refcnt              = 1;    // 1 for directory reference        strcpy( nd->name, name);        nd->status.st_mode      = __stat_mode_REG;        nd->status.st_ino       = nd-&node[0];        nd->status.st_dev       = 0;        nd->status.st_nlink     = 1;        nd->status.st_uid       = 0;        nd->status.st_gid       = 0;        nd->status.st_size      = 0;        nd->status.st_atime     = testfs_time();        nd->status.st_mtime     = testfs_time();        nd->status.st_ctime     = testfs_time();        for( i = 0; i < TESTFS_FILEBLOCKS; i++ )            nd->u.file.data[i]  = NULL;        err = ENOERR;    }    if( err == ENOERR && (mode & O_TRUNC ) )    {        // Clean out any blocks in the file...        int i;                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;                nd->u.file.data[i] = NULL;            }        }        nd->status.st_size = 0;    }        if( err != ENOERR ) return err;    if( S_ISDIR(nd->status.st_mode) ) return EISDIR;    nd->refcnt++;       // Count successful open as a ref        // Initialize the file object        file->f_flag        |= mode & CYG_FILE_MODE_MASK;    file->f_type        = CYG_FILE_TYPE_FILE;    file->f_ops         = &testfs_fileops;    file->f_offset      = 0;    file->f_data        = (CYG_ADDRWORD)nd;    file->f_xops        = 0;        return ENOERR;}// -------------------------------------------------------------------------static int testfs_unlink   ( cyg_mtab_entry *mte, cyg_dir dir, const char *path ){    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;    // Cannot unlink directories, use rmdir() instead    if( S_ISDIR(nd->status.st_mode) )        return EPERM;    err = testfs_delnode( nd );        return err;}// -------------------------------------------------------------------------static int testfs_mkdir    ( cyg_mtab_entry *mte, cyg_dir dir, const char *path ){        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( lastp && err == ENOENT )    {        int i;        // No node there, create a new one. The parent and name        // results will have been filled in, so we know where to put        // it.        // first check that there is space for it        for( i = 0; i < TESTFS_FILEBLOCKS; i++ )            if( parent->u.dir.nodes[i] == NULL )                break;        if( i == TESTFS_FILEBLOCKS ) return ENOSPC;                // Allocate a new node        nd = free_node;        if( nd == NULL ) return ENOSPC;        free_node = nd->next;        // Add to directory list        parent->u.dir.nodes[i] = nd;        parent->refcnt++;         // Fill in details        nd->parent              = parent;        nd->refcnt              = 1;    // 1 for directory reference        strcpy( nd->name, name);        nd->status.st_mode      = __stat_mode_DIR;        nd->status.st_ino       = nd-&node[0];        nd->status.st_dev       = 0;        nd->status.st_nlink     = 1;        nd->status.st_uid       = 0;        nd->status.st_gid       = 0;        nd->status.st_size      = 0;        nd->status.st_atime     = testfs_time();        nd->status.st_mtime     = testfs_time();        nd->status.st_ctime     = testfs_time();        for( i = 0; i < TESTFS_FILEBLOCKS; i++ )            nd->u.dir.nodes[i]  = NULL;                err = ENOERR;    }    return err;}// -------------------------------------------------------------------------static int testfs_rmdir    ( cyg_mtab_entry *mte, cyg_dir dir, const char *path ){    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;    // Check that it is a directory    if( !S_ISDIR(nd->status.st_mode) )        return EPERM;    err = testfs_delnode( nd );    return err;}// -------------------------------------------------------------------------static int testfs_rename   ( cyg_mtab_entry *mte, cyg_dir dir1, const char *path1,                          cyg_dir dir2, const char *path2 ){    testfs_node *nd1, *parent1;    testfs_node *nd2, *parent2;    int err;    char name1[TESTFS_NAMESIZE];    char name2[TESTFS_NAMESIZE];    cyg_bool lastp;    int i,j;        err = testfs_find( (testfs_node *)dir1, path1, &nd1, &parent1, name1, &lastp );    if( err != ENOERR ) return err;    err = testfs_find( (testfs_node *)dir2, path2, &nd2, &parent2, name2, &lastp );    // Allow through renames to non-existent objects.    if( lastp && err == ENOENT )        err = ENOERR;        if( err != ENOERR ) return err;    // Null rename, just return    if( nd1 == nd2 )        return ENOERR;        // First deal with any node that is at the destination    if( nd2 )    {        // Check that we are renaming like-for-like        if( !S_ISDIR(nd1->status.st_mode) && S_ISDIR(nd2->status.st_mode) )            return EISDIR;        if( S_ISDIR(nd1->status.st_mode) && !S_ISDIR(nd2->status.st_mode) )            return ENOTDIR;        // Now delete the destination node.        err = testfs_delnode( nd2 );        if( err != ENOERR ) return err;    }    // Now we know that there is no clashing node at the destination.    // Move the node over and change its name.    // first check that there is space for it    for( i = 0; i < TESTFS_FILEBLOCKS; i++ )        if( parent2->u.dir.nodes[i] == NULL )            break;    if( i == TESTFS_FILEBLOCKS ) return ENOSPC;    // Now remove node from old parent.    for( j = 0; j < TESTFS_FILEBLOCKS; j++ )        if( parent1->u.dir.nodes[j] == nd1 )        {            parent1->u.dir.nodes[j] = NULL;            break;        }    parent1->refcnt--;    // Add to directory list    parent2->u.dir.nodes[i] = nd1;    parent2->refcnt++;    nd1->parent = parent2;        // And give it a new name.    strcpy( nd1->name, name2 );        return err;}// -------------------------------------------------------------------------static int testfs_link   ( cyg_mtab_entry *mte, cyg_dir dir1, const char *path1,                          cyg_dir dir2, const char *path2, int type ){    // The data structures of this file system do not support the    // creation of links.        return ENOSYS;}// -------------------------------------------------------------------------static int testfs_opendir  ( cyg_mtab_entry *mte, cyg_dir dir, const char *path,                          cyg_file *file ){    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;    if( !S_ISDIR(nd->status.st_mode) )        return ENOTDIR;    nd->refcnt++;       // Count successful open as a ref        // Initialize the file object        file->f_type        = CYG_FILE_TYPE_FILE;    file->f_ops         = &testfs_dirops;    file->f_offset      = 0;    file->f_data        = (CYG_ADDRWORD)nd;    file->f_xops        = 0;        return ENOERR;}// -------------------------------------------------------------------------static int testfs_chdir    ( cyg_mtab_entry *mte, cyg_dir dir, const char *path,                             cyg_dir *dir_out ){    if( dir_out != NULL )    {        // This is a request to get a new directory pointer in        // *dir_out.        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;        if( !S_ISDIR(nd->status.st_mode) )            return ENOTDIR;                // Increment ref count to keep this directory in existent        // while it is the current cdir.

⌨️ 快捷键说明

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