📄 romfs.c
字号:
static int romfs_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. 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 a directory if( !S_ISDIR(ds.node->mode) ) return ENOTDIR; // Pass it out *dir_out = (cyg_dir)ds.node; } // 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. Do nothing in ROMFS. return ENOERR;}// -------------------------------------------------------------------------// romfs_stat()// Get struct stat info for named object.static int romfs_stat ( cyg_mtab_entry *mte, cyg_dir dir, const char *name, struct stat *buf){ romfs_dirsearch ds; int err; romfs_disk *disk = (romfs_disk *)mte->data; init_dirsearch( &ds, disk, (romfs_node *)dir, name ); err = romfs_find( &ds ); if( err != ENOERR ) return err; // Fill in the status buf->st_mode = ds.node->mode; buf->st_ino = (ino_t)(ds.node - &disk->node[0]); buf->st_dev = (dev_t)disk->dev_id; buf->st_nlink = ds.node->nlink; buf->st_uid = ds.node->uid; buf->st_gid = ds.node->gid; buf->st_size = ds.node->size; buf->st_atime = ds.node->ctime; buf->st_mtime = ds.node->ctime; buf->st_ctime = ds.node->ctime; return err;}// -------------------------------------------------------------------------// romfs_getinfo()// Getinfo. Currently only support pathconf().static int romfs_getinfo ( cyg_mtab_entry *mte, cyg_dir dir, const char *name, int key, void *buf, int len ){ 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; switch( key ) { case FS_INFO_CONF: err = romfs_pathconf( ds.node, (struct cyg_pathconf_info *)buf ); break; default: err = EINVAL; } return err;}// -------------------------------------------------------------------------// romfs_setinfo()// Setinfo. Nothing to support here at present.static int romfs_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// -------------------------------------------------------------------------// romfs_fo_read()// Read data from the file.static int romfs_fo_read (struct CYG_FILE_TAG *fp, struct CYG_UIO_TAG *uio){ romfs_node *node = (romfs_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( (romfs_disk *)fp->f_mte->data, node, pos, &fbuf, &bsize ); 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 file offset and transfer residue. uio->uio_resid = resid; fp->f_offset = pos; return ENOERR;}// -------------------------------------------------------------------------// romfs_fo_lseek()// Seek to a new file position.static int romfs_fo_lseek (struct CYG_FILE_TAG *fp, off_t *apos, int whence ){ romfs_node *node = (romfs_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 += node->size; break; default: return EINVAL; } // Check that pos is still within current file size, or at the // very end. if( pos < 0 || pos > node->size ) return EINVAL; // All OK, set fp offset and return new position. *apos = fp->f_offset = pos; return ENOERR;}// -------------------------------------------------------------------------// romfs_fo_ioctl()// Handle ioctls. Currently none are defined.static int romfs_fo_ioctl (struct CYG_FILE_TAG *fp, CYG_ADDRWORD com, CYG_ADDRWORD data){ // No Ioctls currenly defined. return EINVAL;}// -------------------------------------------------------------------------// romfs_fo_fsync().// Force the file out to data storage.static int romfs_fo_fsync (struct CYG_FILE_TAG *fp, int mode ){ // Data is always permanently where it belongs, nothing to do // here. return ENOERR;}// -------------------------------------------------------------------------// romfs_fo_close()// Close a file. We just clear out the data pointer.static int romfs_fo_close (struct CYG_FILE_TAG *fp){ fp->f_data = 0; // zero data pointer return ENOERR;}// -------------------------------------------------------------------------//romfs_fo_fstat()// Get file status.static int romfs_fo_fstat (struct CYG_FILE_TAG *fp, struct stat *buf ){ romfs_node *node = (romfs_node *)fp->f_data; romfs_disk *disk = (romfs_disk*)(fp->f_mte->data); // Fill in the status buf->st_mode = node->mode; buf->st_ino = (ino_t)(node - &disk->node[0]); buf->st_dev = disk->dev_id; buf->st_nlink = node->nlink; buf->st_uid = node->uid; buf->st_gid = node->gid; buf->st_size = node->size; buf->st_atime = node->ctime; buf->st_mtime = node->ctime; buf->st_ctime = node->ctime; return ENOERR;}// -------------------------------------------------------------------------// romfs_fo_getinfo()// Get info. Currently only supports fpathconf().static int romfs_fo_getinfo (struct CYG_FILE_TAG *fp, int key, void *buf, int len ){ romfs_node *node = (romfs_node *)fp->f_data; int err; switch( key ) { case FS_INFO_CONF: err = romfs_pathconf( node, (struct cyg_pathconf_info *)buf ); break; default: err = EINVAL; } return err;}// -------------------------------------------------------------------------// romfs_fo_setinfo()// Set info. Nothing supported here.static int romfs_fo_setinfo (struct CYG_FILE_TAG *fp, int key, void *buf, int len ){ // No setinfo key supported at present return ENOERR;}//==========================================================================// Directory operations// -------------------------------------------------------------------------// romfs_fo_dirread()// Read a single directory entry from a file.static int romfs_fo_dirread (struct CYG_FILE_TAG *fp, struct CYG_UIO_TAG *uio){ romfs_node *dir = (romfs_node *)fp->f_data; off_t pos = fp->f_offset; int err = ENOERR; struct dirent *ent = (struct dirent *)uio->uio_iov[0].iov_base; char *nbuf = ent->d_name; int nlen = sizeof(ent->d_name)-1; off_t len = uio->uio_iov[0].iov_len; romfs_dirent *d = NULL; cyg_uint8 *buf; size_t size; int i; if( len < sizeof(struct dirent) ) return EINVAL; // Get the next entry err = findbuffer_node( (romfs_disk *)fp->f_mte->data, dir, pos, &buf, &size ); if( err != ENOERR || size == 0 || pos >= dir->size ) return err; d = (romfs_dirent *)buf; for ( i = 0 ; i < nlen && d->name[i] ; i++, nbuf++ ) *nbuf = d->name[i]; // A successful read. Terminate the entry name with a NUL, set the // residue and set the file offset to restart at the next // directory entry. *nbuf = '\0'; uio->uio_resid -= sizeof(struct dirent); fp->f_offset = d->next; return ENOERR;}// -------------------------------------------------------------------------// romfs_fo_dirlseek()// Seek directory to start.static int romfs_fo_dirlseek (struct CYG_FILE_TAG *fp, off_t *pos, int whence ){ // Only allow SEEK_SET to zero if( whence != SEEK_SET || *pos != 0) return EINVAL; *pos = fp->f_offset = 0; return ENOERR;}// -------------------------------------------------------------------------// EOF romfs.c
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -