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

📄 ramfs.c

📁 eCos操作系统源码
💻 C
📖 第 1 页 / 共 5 页
字号:
// -------------------------------------------------------------------------// init_dirsearch()// Initialize a dirsearch object to start a searchstatic void init_dirsearch( ramfs_dirsearch *ds,                            ramfs_node *dir,                            const char *name){    ds->dir      = dir;    ds->path     = name;    ds->node     = dir;    ds->name     = name;    ds->namelen  = 0;    ds->last     = false;    }// -------------------------------------------------------------------------// find_entry()// Search a single directory for the next name in a path and update the// dirsearch object appropriately.static int find_entry( ramfs_dirsearch *ds ){    ramfs_node *dir = ds->dir;    const char *name = ds->path;    const char *n = name;    char namelen = 0;    ramfs_dirent *d;        // check that we really have a directory    if( !S_ISDIR(dir->mode) )        return ENOTDIR;    // Isolate the next element of the path name.     while( *n != '\0' && *n != '/' )        n++, namelen++;    // Check if this is the last path element.    while( *n == '/') n++;    if( *n == '\0' )         ds->last = true;    // update name in dirsearch object    ds->name = name;    ds->namelen = namelen;        // Here we have the name and its length set up.    // Search the directory for a matching entry    d = find_direntry( dir, name, namelen );    if( d == NULL )        return ENOENT;    // pass back the node we have found    ds->node = d->node;    return ENOERR;}// -------------------------------------------------------------------------// ramfs_find()// Main interface to directory search code. This is used in all file// level operations to locate the object named by the pathname.static int ramfs_find( ramfs_dirsearch *d ){    int err;    // Short circuit empty paths    if( *(d->path) == '\0' )        return ENOERR;    // iterate down directory tree until we find the object    // we want.    for(;;)    {        err = find_entry( d );        if( err != ENOERR )            return err;        if( d->last )            return ENOERR;        // Update dirsearch object to search next directory.        d->dir = d->node;        d->path += d->namelen;        while( *(d->path) == '/' ) d->path++; // skip dirname separators    }}//==========================================================================// Pathconf support// This function provides support for pathconf() and fpathconf().static int ramfs_pathconf( ramfs_node *node, struct cyg_pathconf_info *info ){    int err = ENOERR;        switch( info->name )    {    case _PC_LINK_MAX:        info->value = LINK_MAX;        break;            case _PC_MAX_CANON:        info->value = -1;       // not supported        err = EINVAL;        break;            case _PC_MAX_INPUT:        info->value = -1;       // not supported        err = EINVAL;                break;            case _PC_NAME_MAX:        info->value = NAME_MAX;        break;            case _PC_PATH_MAX:        info->value = PATH_MAX;        break;            case _PC_PIPE_BUF:        info->value = -1;       // not supported        err = EINVAL;                break;                    case _PC_ASYNC_IO:        info->value = -1;       // not supported        err = EINVAL;                break;            case _PC_CHOWN_RESTRICTED:        info->value = -1;       // not supported        err = EINVAL;        break;            case _PC_NO_TRUNC:        info->value = 0;        break;            case _PC_PRIO_IO:        info->value = 0;        break;            case _PC_SYNC_IO:        info->value = 0;        break;            case _PC_VDISABLE:        info->value = -1;       // not supported        err = EINVAL;                break;            default:        err = EINVAL;        break;    }    return err;}//==========================================================================// Filesystem operations// -------------------------------------------------------------------------// ramfs_mount()// Process a mount request. This mainly creates a root for the// filesystem.static int ramfs_mount    ( cyg_fstab_entry *fste, cyg_mtab_entry *mte ){    ramfs_node *root;    int err;        // Allocate a node to be the root of this filesystem and initialize it.    root = alloc_node(__stat_mode_DIR);    if( root == NULL )        return ENOSPC;    // Add . and .. entries back to self.            err = add_direntry( root, ".", 1, root );    if( err == ENOERR )        err = add_direntry( root, "..", 2, root );    if( err != ENOERR )    {        free_node( root );        return err;    }        mte->root = (cyg_dir)root;        return ENOERR;}// -------------------------------------------------------------------------// ramfs_umount()// Unmount the filesystem. This will currently only succeed if the// filesystem is empty.static int ramfs_umount   ( cyg_mtab_entry *mte ){    ramfs_node *root = (ramfs_node *)mte->root;    // Check for open/inuse root    if( root->refcnt != 0 )        return EBUSY;    // Check that root directory is clear of extra links.    if( root->nlink != 2 )        return EBUSY;    // Just return it to free pool    free_node( root );    // Clear root pointer    mte->root = CYG_DIR_NULL;        // That's all folks.            return ENOERR;}// -------------------------------------------------------------------------// ramfs_open()// Open a file for reading or writing.static int ramfs_open     ( cyg_mtab_entry *mte, cyg_dir dir, const char *name,                             int mode,  cyg_file *file ){    ramfs_dirsearch ds;    ramfs_node *node = NULL;    int err;    init_dirsearch( &ds, (ramfs_node *)dir, name );        err = ramfs_find( &ds );    if( err == ENOENT )    {        if( ds.last && (mode & O_CREAT) )        {            // No node there, if the O_CREAT bit is set then we must            // create a new one. The dir and name fields of the dirsearch            // object will have been updated so we know where to put it.            node = alloc_node( __stat_mode_REG );            if( node == NULL )                return ENOSPC;            err = add_direntry( ds.dir, ds.name, ds.namelen, node );            if( err != ENOERR )            {                free_node( node );                return err;            }                    err = ENOERR;        }    }    else if( err == ENOERR )    {        // The node exists. If the O_CREAT and O_EXCL bits are set, we        // must fail the open.                if( (mode & (O_CREAT|O_EXCL)) == (O_CREAT|O_EXCL) )            err = EEXIST;        else node = ds.node;    }        if( err == ENOERR && (mode & O_TRUNC ) )    {        // If the O_TRUNC bit is set we must clean out the file data.        err = freebuffer_node( node );        node->size = 0;        // Update file times        node->ctime =        node->mtime = cyg_timestamp();    }    if( err != ENOERR ) return err;    // Check that we actually have a file here    if( S_ISDIR(node->mode) ) return EISDIR;    node->refcnt++;       // Count successful open        // Initialize the file object        file->f_flag        |= mode & CYG_FILE_MODE_MASK;    file->f_type        = CYG_FILE_TYPE_FILE;    file->f_ops         = &ramfs_fileops;    file->f_offset      = (mode&O_APPEND) ? node->size : 0;    file->f_data        = (CYG_ADDRWORD)node;    file->f_xops        = 0;    return ENOERR;}// -------------------------------------------------------------------------// ramfs_unlink()// Remove a file link from its directory.static int ramfs_unlink   ( cyg_mtab_entry *mte, cyg_dir dir, const char *name ){    ramfs_dirsearch ds;    int err;    init_dirsearch( &ds, (ramfs_node *)dir, name );        err = ramfs_find( &ds );    if( err != ENOERR ) return err;    // Cannot unlink directories, use rmdir() instead    if( S_ISDIR(ds.node->mode) )        return EPERM;    // Delete it from its directory    err = del_direntry( ds.dir, ds.name, ds.namelen );        return err;}// -------------------------------------------------------------------------// ramfs_mkdir()// Create a new directory.static int ramfs_mkdir    ( cyg_mtab_entry *mte, cyg_dir dir, const char *name ){    ramfs_dirsearch ds;    ramfs_node *node = NULL;    int err;    init_dirsearch( &ds, (ramfs_node *)dir, name );        err = ramfs_find( &ds );    if( err == ENOENT )    {        if( ds.last )        {            // The entry does not exist, and it is the last element in            // the pathname, so we can create it here.            int doterr, dotdoterr, direrr;                    node = alloc_node( __stat_mode_DIR );            if( node == NULL )                return ENOSPC;            // Add "." and ".." entries.            doterr = add_direntry( node, ".", 1, node );            dotdoterr = add_direntry( node, "..", 2, ds.dir );            // And add to parent directory.            direrr = add_direntry( ds.dir, ds.name, ds.namelen, node );            // check for any errors in that...            if( doterr+dotdoterr+direrr != ENOERR )            {                // For each of the add_direntry() calls that succeeded,                // we must now undo it.                                if( doterr == ENOERR )                    del_direntry( node, ".", 1 );                else err = doterr;                if( dotdoterr == ENOERR )                    del_direntry( node, "..", 2 );                else err = dotdoterr;                if( direrr == ENOERR )                    del_direntry( ds.dir, ds.name, ds.namelen );                else err = direrr;                // Free the data and the node itself.                freebuffer_node( node );                free_node( node );            }            else err = ENOERR;        }        // If this was not the last element, then and intermediate        // directory does not exist.    }    else    {        // If there we no error, something already exists with that        // name, so we cannot create another one.                if( err == ENOERR )            err = EEXIST;    }    return err;}// -------------------------------------------------------------------------// ramfs_rmdir()// Remove a directory.static int ramfs_rmdir    ( cyg_mtab_entry *mte, cyg_dir dir, const char *name ){    ramfs_dirsearch ds;    int err;    init_dirsearch( &ds, (ramfs_node *)dir, name );        err = ramfs_find( &ds );    if( err != ENOERR ) return err;    // Check that this is actually a directory.    if( !S_ISDIR(ds.node->mode) )        return EPERM;    // Delete the entry. This will adjust the link values    // accordingly and if the directory is now unreferenced,    // will cause it to be deleted.        err = del_direntry( ds.dir, ds.name, ds.namelen );        return err;

⌨️ 快捷键说明

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