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

📄 ramfs.c

📁 eCos操作系统源码
💻 C
📖 第 1 页 / 共 5 页
字号:
}// -------------------------------------------------------------------------// ramfs_rename()// Rename a file/dir.static int ramfs_rename   ( cyg_mtab_entry *mte, cyg_dir dir1, const char *name1,                             cyg_dir dir2, const char *name2 ){    ramfs_dirsearch ds1, ds2;    int err;    init_dirsearch( &ds1, (ramfs_node *)dir1, name1 );        err = ramfs_find( &ds1 );    if( err != ENOERR ) return err;    init_dirsearch( &ds2, (ramfs_node *)dir2, name2 );        err = ramfs_find( &ds2 );    // Allow through renames to non-existent objects.    if( ds2.last && err == ENOENT )        ds2.node = NULL, err = ENOERR;        if( err != ENOERR ) return err;    // Null rename, just return    if( ds1.node == ds2.node )        return ENOERR;    // First deal with any entry that is at the destination    if( ds2.node )    {        // Check that we are renaming like-for-like        if( !S_ISDIR(ds1.node->mode) && S_ISDIR(ds2.node->mode) )            return EISDIR;        if( S_ISDIR(ds1.node->mode) && !S_ISDIR(ds2.node->mode) )            return ENOTDIR;        // Now delete the destination directory entry                err = del_direntry( ds2.dir, ds2.name, ds2.namelen );                if( err != ENOERR ) return err;    }    // Now we know that there is no clashing node at the destination,    // make a new direntry at the destination and delete the old entry    // at the source.    err = add_direntry( ds2.dir, ds2.name, ds2.namelen, ds1.node );    if( err == ENOERR )        err = del_direntry( ds1.dir, ds1.name, ds1.namelen );    // Update directory times    if( err == ENOERR )        ds1.dir->ctime =        ds1.dir->mtime =        ds2.dir->ctime =        ds2.dir->mtime = cyg_timestamp();                return err;}// -------------------------------------------------------------------------// ramfs_link()// Make a new directory entry for a file.static int ramfs_link     ( cyg_mtab_entry *mte, cyg_dir dir1, const char *name1,                             cyg_dir dir2, const char *name2, int type ){    ramfs_dirsearch ds1, ds2;    int err;    // Only do hard links for now in this filesystem    if( type != CYG_FSLINK_HARD )        return EINVAL;        init_dirsearch( &ds1, (ramfs_node *)dir1, name1 );        err = ramfs_find( &ds1 );    if( err != ENOERR ) return err;    init_dirsearch( &ds2, (ramfs_node *)dir2, name2 );        err = ramfs_find( &ds2 );    // Don't allow links to existing objects    if( err == ENOERR ) return EEXIST;        // Allow through links to non-existing terminal objects    if( ds2.last && err == ENOENT )        ds2.node = NULL, err = ENOERR;    if( err != ENOERR ) return err;        // Now we know that there is no existing node at the destination,    // make a new direntry at the destination.    err = add_direntry( ds2.dir, ds2.name, ds2.namelen, ds1.node );    if( err == ENOERR )        ds1.node->ctime =        ds2.dir->ctime =        ds2.dir->mtime = cyg_timestamp();                return err;}// -------------------------------------------------------------------------// ramfs_opendir()// Open a directory for reading.static int ramfs_opendir  ( cyg_mtab_entry *mte, cyg_dir dir, const char *name,                             cyg_file *file ){    ramfs_dirsearch ds;    int err;    init_dirsearch( &ds, (ramfs_node *)dir, name );        err = ramfs_find( &ds );    if( err != ENOERR ) return err;    // check it is really a directory.    if( !S_ISDIR(ds.node->mode) ) return ENOTDIR;    ds.node->refcnt++;       // Count successful open        // 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         = &ramfs_dirops;    file->f_offset      = 0;    file->f_data        = (CYG_ADDRWORD)ds.node;    file->f_xops        = 0;            return ENOERR;}// -------------------------------------------------------------------------// ramfs_chdir()// Change directory support.static int ramfs_chdir    ( cyg_mtab_entry *mte, cyg_dir dir, const char *name,                             cyg_dir *dir_out ){    if( dir_out != NULL )    {        // This is a request to get a new directory pointer in        // *dir_out.        ramfs_dirsearch ds;        int err;            init_dirsearch( &ds, (ramfs_node *)dir, name );            err = ramfs_find( &ds );        if( err != ENOERR ) return err;        // check it is a directory        if( !S_ISDIR(ds.node->mode) )            return ENOTDIR;                // Increment ref count to keep this directory in existent        // while it is the current cdir.        ds.node->refcnt++;        // Pass it out        *dir_out = (cyg_dir)ds.node;    }    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.        ramfs_node *node = (ramfs_node *)dir;        // Just decrement directory reference count.        dec_refcnt( node );    }            return ENOERR;}// -------------------------------------------------------------------------// ramfs_stat()// Get struct stat info for named object.static int ramfs_stat     ( cyg_mtab_entry *mte, cyg_dir dir, const char *name,                             struct stat *buf){    ramfs_dirsearch ds;    int err;    init_dirsearch( &ds, (ramfs_node *)dir, name );        err = ramfs_find( &ds );    if( err != ENOERR ) return err;    // Fill in the status    buf->st_mode        = ds.node->mode;    buf->st_ino         = (ino_t)ds.node;    buf->st_dev         = 0;    buf->st_nlink       = ds.node->nlink;    buf->st_uid         = 0;    buf->st_gid         = 0;    buf->st_size        = ds.node->size;    buf->st_atime       = ds.node->atime;    buf->st_mtime       = ds.node->mtime;    buf->st_ctime       = ds.node->ctime;        return err;}// -------------------------------------------------------------------------// ramfs_getinfo()// Getinfo. Currently only support pathconf().static int ramfs_getinfo  ( cyg_mtab_entry *mte, cyg_dir dir, const char *name,                             int key, void *buf, int len ){    ramfs_dirsearch ds;    int err;    init_dirsearch( &ds, (ramfs_node *)dir, name );        err = ramfs_find( &ds );    if( err != ENOERR ) return err;    switch( key )    {    case FS_INFO_CONF:        err = ramfs_pathconf( ds.node, (struct cyg_pathconf_info *)buf );        break;            default:        err = EINVAL;    }    return err;}// -------------------------------------------------------------------------// ramfs_setinfo()// Setinfo. Nothing to support here at present.static int ramfs_setinfo  ( cyg_mtab_entry *mte, cyg_dir dir, const char *name,                             int key, void *buf, int len ){    // No setinfo keys supported at present        return EINVAL;}//==========================================================================// File operations// -------------------------------------------------------------------------// ramfs_fo_read()// Read data from the file.static int ramfs_fo_read      (struct CYG_FILE_TAG *fp, struct CYG_UIO_TAG *uio){    ramfs_node *node = (ramfs_node *)fp->f_data;    int i;    off_t pos = fp->f_offset;    ssize_t resid = uio->uio_resid;    // Loop over the io vectors until there are none left    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;        // Loop over each vector filling it with data from the file.        while( len > 0 && pos < node->size )        {            cyg_uint8 *fbuf;            size_t bsize;            off_t l = len;            int err;            // Get a pointer to the data at offset _pos_.            err = findbuffer_node( node, pos, &fbuf, &bsize, false );            if( err != ENOERR )                return err;            // adjust size to end of file if necessary            if( l > node->size-pos )                l = node->size-pos;                        // adjust size to the amount of contiguous data we can see            // at present.            if( l > bsize )                l = bsize;            // copy data out            memcpy( buf, fbuf, l );            // Update working vars            len -= l;            buf += l;            pos += l;            resid -= l;        }    }    // We successfully read some data, update the node's access time    // and update the file offset and transfer residue.        node->atime = cyg_timestamp();    uio->uio_resid = resid;    fp->f_offset = pos;        return ENOERR;}// -------------------------------------------------------------------------// ramfs_fo_write()// Write data to file.static int ramfs_fo_write     (struct CYG_FILE_TAG *fp, struct CYG_UIO_TAG *uio){    ramfs_node *node = (ramfs_node *)fp->f_data;    off_t pos = fp->f_offset;    ssize_t resid = uio->uio_resid;        int err = ENOERR;    int i;    // If the APPEND mode bit was supplied, force all writes to    // the end of the file.    if( fp->f_flag & CYG_FAPPEND )        pos = fp->f_offset = node->size;        // Check that pos is within current file size, or at the very end.    if( pos < 0 || pos > node->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;        // loop over the vector writing it to the file until it has        // all been done.        while( len > 0 )        {            cyg_uint8 *fbuf;            size_t bsize;            off_t l = len;                        err = findbuffer_node( node, pos, &fbuf, &bsize, true );            // Stop writing if there is no more space in the file and            // indicate end of data.            if( err == ENOSPC )                break;                        if( err != ENOERR )                return err;                        // adjust size to this block            if( l > bsize )                l = bsize;            // copy data in            memcpy( fbuf, buf, l );            // Update working vars            len -= l;            buf += l;            pos += l;            resid -= l;        }    }    // We wrote some data successfully, update the modified and access    // times of the node, increase its size appropriately, and update    // the file offset and transfer residue.    node->mtime =    node->ctime = cyg_timestamp();    if( pos > node->size )        node->size = pos;        uio->uio_resid = resid;    fp->f_offset = pos;        return err;}// -------------------------------------------------------------------------// ramfs_fo_lseek()// Seek to a new file position.static int ramfs_fo_lseek     (struct CYG_FILE_TAG *fp, off_t *apos, int whence ){    ramfs_node *node = (ramfs_node *)fp->f_data;    off_t pos = *apos;    switch( whence )    {    case SEEK_SET:        // Pos is already where we want to be.        break;    case SEEK_CUR:        // Add pos to current offset.        pos += fp->f_offset;        break;    case SEEK_END:        // Add pos to file size.        pos

⌨️ 快捷键说明

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