From d8c34237bf49a57cf01df792655c2ab50d8ba1c5 Mon Sep 17 00:00:00 2001 From: Christian Helmuth Date: Wed, 22 Jun 2016 15:38:42 +0200 Subject: [PATCH] vfs: default constructor for Dirent and Stat Fixes #1743 --- repos/os/include/vfs/directory_service.h | 18 ++++----- repos/os/include/vfs/fs_file_system.h | 2 +- repos/os/include/vfs/single_file_system.h | 2 +- repos/os/include/vfs/symlink_file_system.h | 2 +- repos/os/include/vfs/tar_file_system.h | 4 +- repos/os/src/server/vfs/main.cc | 4 +- repos/os/src/server/vfs/node.h | 1 - repos/ports/include/noux_session/sysio.h | 45 +++++++++++++++++++++- repos/ports/src/noux/vfs_io_channel.h | 10 +++-- 9 files changed, 64 insertions(+), 24 deletions(-) diff --git a/repos/os/include/vfs/directory_service.h b/repos/os/include/vfs/directory_service.h index 2745f4a4e1..252f3e3083 100644 --- a/repos/os/include/vfs/directory_service.h +++ b/repos/os/include/vfs/directory_service.h @@ -86,12 +86,12 @@ struct Vfs::Directory_service struct Stat { - file_size size; - unsigned mode; - unsigned uid; - unsigned gid; - unsigned long inode; - unsigned long device; + file_size size = 0; + unsigned mode = 0; + unsigned uid = 0; + unsigned gid = 0; + unsigned long inode = 0; + unsigned long device = 0; }; enum Stat_result { STAT_ERR_NO_ENTRY = NUM_GENERAL_ERRORS, @@ -120,9 +120,9 @@ struct Vfs::Directory_service struct Dirent { - unsigned long fileno; - Dirent_type type; - char name[DIRENT_MAX_NAME_LEN]; + unsigned long fileno = 0; + Dirent_type type = DIRENT_TYPE_END; + char name[DIRENT_MAX_NAME_LEN] = { 0 }; }; virtual Dirent_result dirent(char const *path, file_offset index, Dirent &) = 0; diff --git a/repos/os/include/vfs/fs_file_system.h b/repos/os/include/vfs/fs_file_system.h index 0989d71369..7addbe72f3 100644 --- a/repos/os/include/vfs/fs_file_system.h +++ b/repos/os/include/vfs/fs_file_system.h @@ -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::Out_of_metadata) { return STAT_ERR_NO_PERM; } - memset(&out, 0, sizeof(out)); + out = Stat(); out.size = status.size; out.mode = STAT_MODE_FILE | 0777; diff --git a/repos/os/include/vfs/single_file_system.h b/repos/os/include/vfs/single_file_system.h index 773f54cb79..a4ec1ac007 100644 --- a/repos/os/include/vfs/single_file_system.h +++ b/repos/os/include/vfs/single_file_system.h @@ -70,7 +70,7 @@ class Vfs::Single_file_system : public File_system Stat_result stat(char const *path, Stat &out) override { - out = { 0, 0, 0, 0, 0, 0 }; + out = Stat(); out.device = (Genode::addr_t)this; if (_root(path)) { diff --git a/repos/os/include/vfs/symlink_file_system.h b/repos/os/include/vfs/symlink_file_system.h index 6414b24439..e8409f6483 100644 --- a/repos/os/include/vfs/symlink_file_system.h +++ b/repos/os/include/vfs/symlink_file_system.h @@ -75,7 +75,7 @@ class Vfs::Symlink_file_system : public File_system Stat_result stat(char const *path, Stat &out) override { - out = { 0, 0, 0, 0, 0, 0 }; + out = Stat(); out.device = (Genode::addr_t)this; if (_root(path)) { diff --git a/repos/os/include/vfs/tar_file_system.h b/repos/os/include/vfs/tar_file_system.h index 1341ee62a7..ef551946f1 100644 --- a/repos/os/include/vfs/tar_file_system.h +++ b/repos/os/include/vfs/tar_file_system.h @@ -425,6 +425,8 @@ class Vfs::Tar_file_system : public File_system if (verbose) PDBG("path = %s", path); + out = Stat(); + Node const *node = dereference(path); if (!node) return STAT_ERR_NO_ENTRY; @@ -433,7 +435,6 @@ class Vfs::Tar_file_system : public File_system if (verbose) PDBG("found a virtual directoty node"); - memset(&out, 0, sizeof(out)); out.mode = STAT_MODE_DIRECTORY; return STAT_OK; } @@ -452,7 +453,6 @@ class Vfs::Tar_file_system : public File_system PDBG("unhandled record type %d", record->type()); } - memset(&out, 0, sizeof(out)); out.mode = mode; out.size = record->size(); out.uid = record->uid(); diff --git a/repos/os/src/server/vfs/main.cc b/repos/os/src/server/vfs/main.cc index 4c1cd40b10..9d8ca2c75e 100644 --- a/repos/os/src/server/vfs/main.cc +++ b/repos/os/src/server/vfs/main.cc @@ -452,10 +452,8 @@ class Vfs_server::Session_component : Node &node = _lookup(node_handle); - if (_vfs.stat(node.path(), vfs_stat) != Directory_service::STAT_OK) { - memset(&fs_stat, 0x00, sizeof(fs_stat)); + if (_vfs.stat(node.path(), vfs_stat) != Directory_service::STAT_OK) return fs_stat; - } fs_stat.inode = vfs_stat.inode; diff --git a/repos/os/src/server/vfs/node.h b/repos/os/src/server/vfs/node.h index f2fc12e7d9..b017edb69f 100644 --- a/repos/os/src/server/vfs/node.h +++ b/repos/os/src/server/vfs/node.h @@ -262,7 +262,6 @@ struct Vfs_server::Directory : Node size_t remains = len; while (remains >= blocksize) { - memset(&vfs_dirent, 0x00, sizeof(vfs_dirent)); if (vfs.dirent(path(), index++, vfs_dirent) != Vfs::Directory_service::DIRENT_OK) return len - remains; diff --git a/repos/ports/include/noux_session/sysio.h b/repos/ports/include/noux_session/sysio.h index f63c734092..adac263cf3 100644 --- a/repos/ports/include/noux_session/sysio.h +++ b/repos/ports/include/noux_session/sysio.h @@ -82,7 +82,30 @@ namespace Noux { 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 @@ -107,7 +130,25 @@ namespace Noux { 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 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 { FCNTL_CMD_GET_FILE_STATUS_FLAGS, diff --git a/repos/ports/src/noux/vfs_io_channel.h b/repos/ports/src/noux/vfs_io_channel.h index a96adb113d..2c21e2420e 100644 --- a/repos/ports/src/noux/vfs_io_channel.h +++ b/repos/ports/src/noux/vfs_io_channel.h @@ -85,8 +85,9 @@ namespace Noux { * 'sysio.stat_in' is not used in '_fh->ds().stat()', * so no 'sysio' member translation is needed here */ - sysio->error.stat = _fh->ds().stat(_leaf_path.base(), - sysio->fstat_out.st); + Vfs::Directory_service::Stat stat; + sysio->error.stat = _fh->ds().stat(_leaf_path.base(), stat); + sysio->fstat_out.st = stat; 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. */ - if (!_fh->ds().dirent(_path.base(), index - 2, - sysio->dirent_out.entry)) + Vfs::Directory_service::Dirent dirent; + if (!_fh->ds().dirent(_path.base(), index - 2, dirent)) return false; + sysio->dirent_out.entry = dirent; _fh->advance_seek(sizeof(Sysio::Dirent)); return true;