vfs: default constructor for Dirent and Stat

Fixes #1743
This commit is contained in:
Christian Helmuth 2016-06-22 15:38:42 +02:00
parent 0a01edded2
commit d8c34237bf
9 changed files with 64 additions and 24 deletions

View File

@ -86,12 +86,12 @@ struct Vfs::Directory_service
struct Stat struct Stat
{ {
file_size size; file_size size = 0;
unsigned mode; unsigned mode = 0;
unsigned uid; unsigned uid = 0;
unsigned gid; unsigned gid = 0;
unsigned long inode; unsigned long inode = 0;
unsigned long device; unsigned long device = 0;
}; };
enum Stat_result { STAT_ERR_NO_ENTRY = NUM_GENERAL_ERRORS, enum Stat_result { STAT_ERR_NO_ENTRY = NUM_GENERAL_ERRORS,
@ -120,9 +120,9 @@ struct Vfs::Directory_service
struct Dirent struct Dirent
{ {
unsigned long fileno; unsigned long fileno = 0;
Dirent_type type; Dirent_type type = DIRENT_TYPE_END;
char name[DIRENT_MAX_NAME_LEN]; char name[DIRENT_MAX_NAME_LEN] = { 0 };
}; };
virtual Dirent_result dirent(char const *path, file_offset index, Dirent &) = 0; virtual Dirent_result dirent(char const *path, file_offset index, Dirent &) = 0;

View File

@ -255,7 +255,7 @@ class Vfs::Fs_file_system : public File_system
catch (::File_system::Lookup_failed) { return STAT_ERR_NO_ENTRY; } catch (::File_system::Lookup_failed) { return STAT_ERR_NO_ENTRY; }
catch (::File_system::Out_of_metadata) { return STAT_ERR_NO_PERM; } catch (::File_system::Out_of_metadata) { return STAT_ERR_NO_PERM; }
memset(&out, 0, sizeof(out)); out = Stat();
out.size = status.size; out.size = status.size;
out.mode = STAT_MODE_FILE | 0777; out.mode = STAT_MODE_FILE | 0777;

View File

@ -70,7 +70,7 @@ class Vfs::Single_file_system : public File_system
Stat_result stat(char const *path, Stat &out) override Stat_result stat(char const *path, Stat &out) override
{ {
out = { 0, 0, 0, 0, 0, 0 }; out = Stat();
out.device = (Genode::addr_t)this; out.device = (Genode::addr_t)this;
if (_root(path)) { if (_root(path)) {

View File

@ -75,7 +75,7 @@ class Vfs::Symlink_file_system : public File_system
Stat_result stat(char const *path, Stat &out) override Stat_result stat(char const *path, Stat &out) override
{ {
out = { 0, 0, 0, 0, 0, 0 }; out = Stat();
out.device = (Genode::addr_t)this; out.device = (Genode::addr_t)this;
if (_root(path)) { if (_root(path)) {

View File

@ -425,6 +425,8 @@ class Vfs::Tar_file_system : public File_system
if (verbose) if (verbose)
PDBG("path = %s", path); PDBG("path = %s", path);
out = Stat();
Node const *node = dereference(path); Node const *node = dereference(path);
if (!node) if (!node)
return STAT_ERR_NO_ENTRY; return STAT_ERR_NO_ENTRY;
@ -433,7 +435,6 @@ class Vfs::Tar_file_system : public File_system
if (verbose) if (verbose)
PDBG("found a virtual directoty node"); PDBG("found a virtual directoty node");
memset(&out, 0, sizeof(out));
out.mode = STAT_MODE_DIRECTORY; out.mode = STAT_MODE_DIRECTORY;
return STAT_OK; return STAT_OK;
} }
@ -452,7 +453,6 @@ class Vfs::Tar_file_system : public File_system
PDBG("unhandled record type %d", record->type()); PDBG("unhandled record type %d", record->type());
} }
memset(&out, 0, sizeof(out));
out.mode = mode; out.mode = mode;
out.size = record->size(); out.size = record->size();
out.uid = record->uid(); out.uid = record->uid();

View File

@ -452,10 +452,8 @@ class Vfs_server::Session_component :
Node &node = _lookup(node_handle); Node &node = _lookup(node_handle);
if (_vfs.stat(node.path(), vfs_stat) != Directory_service::STAT_OK) { if (_vfs.stat(node.path(), vfs_stat) != Directory_service::STAT_OK)
memset(&fs_stat, 0x00, sizeof(fs_stat));
return fs_stat; return fs_stat;
}
fs_stat.inode = vfs_stat.inode; fs_stat.inode = vfs_stat.inode;

View File

@ -262,7 +262,6 @@ struct Vfs_server::Directory : Node
size_t remains = len; size_t remains = len;
while (remains >= blocksize) { while (remains >= blocksize) {
memset(&vfs_dirent, 0x00, sizeof(vfs_dirent));
if (vfs.dirent(path(), index++, vfs_dirent) if (vfs.dirent(path(), index++, vfs_dirent)
!= Vfs::Directory_service::DIRENT_OK) != Vfs::Directory_service::DIRENT_OK)
return len - remains; return len - remains;

View File

@ -82,7 +82,30 @@ namespace Noux {
STAT_MODE_BLOCKDEV = 0060000, STAT_MODE_BLOCKDEV = 0060000,
}; };
typedef Vfs::Directory_service::Stat Stat; /*
* Must be POD (in contrast to the VFS type) because it's used in a union
*/
struct Stat
{
Vfs::file_size size;
unsigned mode;
unsigned uid;
unsigned gid;
unsigned long inode;
unsigned long device;
Stat & operator= (Vfs::Directory_service::Stat const &stat)
{
size = stat.size;
mode = stat.mode;
uid = stat.uid;
gid = stat.gid;
inode = stat.inode;
device = stat.device;
return *this;
}
};
/** /**
* Argument structure used for ioctl syscall * Argument structure used for ioctl syscall
@ -107,7 +130,25 @@ namespace Noux {
enum { DIRENT_MAX_NAME_LEN = Vfs::Directory_service::DIRENT_MAX_NAME_LEN }; enum { DIRENT_MAX_NAME_LEN = Vfs::Directory_service::DIRENT_MAX_NAME_LEN };
typedef Vfs::Directory_service::Dirent_type Dirent_type; typedef Vfs::Directory_service::Dirent_type Dirent_type;
typedef Vfs::Directory_service::Dirent Dirent;
/*
* Must be POD (in contrast to the VFS type) because it's used in a union
*/
struct Dirent
{
unsigned long fileno;
Dirent_type type;
char name[DIRENT_MAX_NAME_LEN];
Dirent & operator= (Vfs::Directory_service::Dirent const &dirent)
{
fileno = dirent.fileno;
type = dirent.type;
memcpy(name, dirent.name, DIRENT_MAX_NAME_LEN);
return *this;
}
};
enum Fcntl_cmd { enum Fcntl_cmd {
FCNTL_CMD_GET_FILE_STATUS_FLAGS, FCNTL_CMD_GET_FILE_STATUS_FLAGS,

View File

@ -85,8 +85,9 @@ namespace Noux {
* 'sysio.stat_in' is not used in '_fh->ds().stat()', * 'sysio.stat_in' is not used in '_fh->ds().stat()',
* so no 'sysio' member translation is needed here * so no 'sysio' member translation is needed here
*/ */
sysio->error.stat = _fh->ds().stat(_leaf_path.base(), Vfs::Directory_service::Stat stat;
sysio->fstat_out.st); sysio->error.stat = _fh->ds().stat(_leaf_path.base(), stat);
sysio->fstat_out.st = stat;
return (sysio->error.stat == Vfs::Directory_service::STAT_OK); return (sysio->error.stat == Vfs::Directory_service::STAT_OK);
@ -149,9 +150,10 @@ namespace Noux {
* Align index range to zero when calling the directory service. * Align index range to zero when calling the directory service.
*/ */
if (!_fh->ds().dirent(_path.base(), index - 2, Vfs::Directory_service::Dirent dirent;
sysio->dirent_out.entry)) if (!_fh->ds().dirent(_path.base(), index - 2, dirent))
return false; return false;
sysio->dirent_out.entry = dirent;
_fh->advance_seek(sizeof(Sysio::Dirent)); _fh->advance_seek(sizeof(Sysio::Dirent));
return true; return true;