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

📄 romfs.c

📁 eCos操作系统源码
💻 C
📖 第 1 页 / 共 3 页
字号:
    return ENOERR;}//==========================================================================// Directory operations// -------------------------------------------------------------------------// find_direntry()// Find a directory entry for the name and return a pointer to the first// entry fragment.static romfs_dirent *find_direntry( romfs_disk *disk, romfs_node *dir, const char *name, int namelen ){    off_t pos = 0;    int err;    // Loop over all the entries until a match is found or we run out    // of data.    while( pos < dir->size )    {        romfs_dirent *d;        cyg_uint8 *buf;        size_t size;        	err = findbuffer_node( disk, dir, pos, &buf, &size );	if( err != ENOERR || size == 0)	    return NULL;	d = (romfs_dirent *)buf;	// Is this the directory entry we're looking for?	if ( match( d->name, name, namelen ) )	    return d;	// Otherwise move on to next entry in chain        pos = d->next;    }    return NULL;}//==========================================================================// Directory search// -------------------------------------------------------------------------// init_dirsearch()// Initialize a dirsearch object to start a searchstatic void init_dirsearch( romfs_dirsearch *ds,                            romfs_disk *disk,			    romfs_node *dir,                            const char *name){    ds->disk     = disk;    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( romfs_dirsearch *ds ){    romfs_node *dir = ds->dir;    const char *name = ds->path;    const char *n = name;    int namelen = 0;    romfs_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( ds->disk, dir, name, namelen );    if( d == NULL )        return ENOENT;    // pass back the node we have found    ds->node = &ds->disk->node[d->node];    return ENOERR;}// -------------------------------------------------------------------------// romfs_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 romfs_find( romfs_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 romfs_pathconf( romfs_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// -------------------------------------------------------------------------// romfs_mount()// Process a mount request. This mainly finds root for the// filesystem.static int romfs_mount    ( cyg_fstab_entry *fste, cyg_mtab_entry *mte ){    romfs_disk *disk=NULL;        if ( !mte->data ) {	// If the image address was not in the MTE data word,	if ( mte->devname && mte->devname[0] ) {	    // And there's something in the 'hardware device' field,	    // then read the address from there.	    sscanf( mte->devname, "%p", (char**)&disk );	}    } else {        disk = (romfs_disk *)mte->data;    }    if ( !disk ) {	// If still no address, try the FSTAB entry data word	disk = (romfs_disk *)fste->data;    }    if ( !disk ) {	// If still no address, give up...	return ENOENT;    }        // Check the ROMFS magic number to ensure that there's really an fs.    if ( disk->magic == ROMFS_CIGAM ) {	// The disk image has the wrong byte sex!!!	return EIO;    } else if ( disk->magic != ROMFS_MAGIC || disk->nodecount == 0 ) {	// No image found	return ENOENT;    }    mte->root = (cyg_dir)&disk->node[0];        mte->data = (CYG_ADDRWORD)disk;    return ENOERR;}// -------------------------------------------------------------------------// romfs_umount()// Unmount the filesystem. This will currently always succeed.static int romfs_umount   ( cyg_mtab_entry *mte ){    // Clear root pointer    mte->root = CYG_DIR_NULL;        // That's all folks.            return ENOERR;}// -------------------------------------------------------------------------// romfs_open()// Open a file for readingstatic int romfs_open     ( cyg_mtab_entry *mte, cyg_dir dir, const char *name,                             int mode,  cyg_file *file ){    romfs_dirsearch ds;    romfs_node *node = NULL;    int err;    init_dirsearch( &ds, (romfs_disk *)mte->data, (romfs_node *)dir, name );        err = romfs_find( &ds );    if( err == ENOENT )    {	return ENOENT;    }    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 fail the open        err = EPERM;    }    if( err != ENOERR ) return err;    // Check that we actually have a file here    if( S_ISDIR(node->mode) ) return EISDIR;    // Initialize the file object        file->f_flag        |= mode & CYG_FILE_MODE_MASK;    file->f_type        = CYG_FILE_TYPE_FILE;    file->f_ops         = &romfs_fileops;    file->f_offset      = 0;    file->f_data        = (CYG_ADDRWORD)node;    file->f_xops        = 0;    return ENOERR;}// -------------------------------------------------------------------------// romfs_opendir()// Open a directory for reading.static int romfs_opendir  ( cyg_mtab_entry *mte, cyg_dir dir, const char *name,                             cyg_file *file ){    romfs_dirsearch ds;    int err;    init_dirsearch( &ds, (romfs_disk *)mte->data, (romfs_node *)dir, name );        err = romfs_find( &ds );    if( err != ENOERR ) return err;    // check it is really a directory.    if( !S_ISDIR(ds.node->mode) ) return ENOTDIR;    // Initialize the file object, setting the f_ops field to a    // special set of file ops.        file->f_type        = CYG_FILE_TYPE_FILE;    file->f_ops         = &romfs_dirops;    file->f_offset      = 0;    file->f_data        = (CYG_ADDRWORD)ds.node;    file->f_xops        = 0;            return ENOERR;}// -------------------------------------------------------------------------// romfs_chdir()// Change directory support.

⌨️ 快捷键说明

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