📄 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 + -