mirror of
https://github.com/genodelabs/genode.git
synced 2025-02-01 16:58:29 +00:00
parent
ddf3716cff
commit
bae4ce5360
@ -24,7 +24,10 @@ class Vfs::Single_file_system : public File_system
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
enum Node_type { NODE_TYPE_FILE, NODE_TYPE_CHAR_DEVICE, NODE_TYPE_BLOCK_DEVICE };
|
enum Node_type {
|
||||||
|
NODE_TYPE_FILE, NODE_TYPE_SYMLINK,
|
||||||
|
NODE_TYPE_CHAR_DEVICE, NODE_TYPE_BLOCK_DEVICE
|
||||||
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
@ -33,6 +36,8 @@ class Vfs::Single_file_system : public File_system
|
|||||||
enum { FILENAME_MAX_LEN = 64 };
|
enum { FILENAME_MAX_LEN = 64 };
|
||||||
char _filename[FILENAME_MAX_LEN];
|
char _filename[FILENAME_MAX_LEN];
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
bool _root(const char *path)
|
bool _root(const char *path)
|
||||||
{
|
{
|
||||||
return (strcmp(path, "") == 0) || (strcmp(path, "/") == 0);
|
return (strcmp(path, "") == 0) || (strcmp(path, "/") == 0);
|
||||||
@ -79,6 +84,7 @@ class Vfs::Single_file_system : public File_system
|
|||||||
} else if (_single_file(path)) {
|
} else if (_single_file(path)) {
|
||||||
switch (_node_type) {
|
switch (_node_type) {
|
||||||
case NODE_TYPE_FILE: out.mode = STAT_MODE_FILE; break;
|
case NODE_TYPE_FILE: out.mode = STAT_MODE_FILE; break;
|
||||||
|
case NODE_TYPE_SYMLINK: out.mode = STAT_MODE_SYMLINK; break;
|
||||||
case NODE_TYPE_CHAR_DEVICE: out.mode = STAT_MODE_CHARDEV; break;
|
case NODE_TYPE_CHAR_DEVICE: out.mode = STAT_MODE_CHARDEV; break;
|
||||||
case NODE_TYPE_BLOCK_DEVICE: out.mode = STAT_MODE_BLOCKDEV; break;
|
case NODE_TYPE_BLOCK_DEVICE: out.mode = STAT_MODE_BLOCKDEV; break;
|
||||||
}
|
}
|
||||||
@ -98,6 +104,7 @@ class Vfs::Single_file_system : public File_system
|
|||||||
out.fileno = (Genode::addr_t)this;
|
out.fileno = (Genode::addr_t)this;
|
||||||
switch (_node_type) {
|
switch (_node_type) {
|
||||||
case NODE_TYPE_FILE: out.type = DIRENT_TYPE_FILE; break;
|
case NODE_TYPE_FILE: out.type = DIRENT_TYPE_FILE; break;
|
||||||
|
case NODE_TYPE_SYMLINK: out.type = DIRENT_TYPE_SYMLINK; break;
|
||||||
case NODE_TYPE_CHAR_DEVICE: out.type = DIRENT_TYPE_CHARDEV; break;
|
case NODE_TYPE_CHAR_DEVICE: out.type = DIRENT_TYPE_CHARDEV; break;
|
||||||
case NODE_TYPE_BLOCK_DEVICE: out.type = DIRENT_TYPE_BLOCKDEV; break;
|
case NODE_TYPE_BLOCK_DEVICE: out.type = DIRENT_TYPE_BLOCKDEV; break;
|
||||||
}
|
}
|
||||||
|
@ -15,42 +15,29 @@
|
|||||||
#ifndef _INCLUDE__VFS__SYMLINK_FILE_SYSTEM_H_
|
#ifndef _INCLUDE__VFS__SYMLINK_FILE_SYSTEM_H_
|
||||||
#define _INCLUDE__VFS__SYMLINK_FILE_SYSTEM_H_
|
#define _INCLUDE__VFS__SYMLINK_FILE_SYSTEM_H_
|
||||||
|
|
||||||
#include <vfs/file_system.h>
|
#include <vfs/single_file_system.h>
|
||||||
|
|
||||||
namespace Vfs { class Symlink_file_system; }
|
namespace Vfs { class Symlink_file_system; }
|
||||||
|
|
||||||
|
|
||||||
class Vfs::Symlink_file_system : public File_system
|
class Vfs::Symlink_file_system : public Single_file_system
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
|
||||||
enum { FILENAME_MAX_LEN = 64 };
|
enum { FILENAME_MAX_LEN = 64 };
|
||||||
|
typedef Genode::String<MAX_PATH_LEN> Target;
|
||||||
|
|
||||||
char _target[MAX_PATH_LEN];
|
Target const _target;
|
||||||
char _filename[FILENAME_MAX_LEN];
|
|
||||||
|
|
||||||
bool _root(const char *path)
|
|
||||||
{
|
|
||||||
return (strcmp(path, "") == 0) || (strcmp(path, "/") == 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool _single_file(const char *path)
|
|
||||||
{
|
|
||||||
return (strlen(path) == (strlen(_filename) + 1)) &&
|
|
||||||
(strcmp(&path[1], _filename) == 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Symlink_file_system(Genode::Env&,
|
Symlink_file_system(Genode::Env&,
|
||||||
Genode::Allocator&,
|
Genode::Allocator&,
|
||||||
Genode::Xml_node config)
|
Genode::Xml_node config)
|
||||||
{
|
:
|
||||||
try {
|
Single_file_system(NODE_TYPE_SYMLINK, "symlink", config),
|
||||||
config.attribute("name").value(_filename, sizeof(_filename));
|
_target(config.attribute_value("target", Target()))
|
||||||
config.attribute("target").value(_target, sizeof(_target));
|
{ }
|
||||||
} catch (...) { }
|
|
||||||
}
|
|
||||||
|
|
||||||
static char const *name() { return "symlink"; }
|
static char const *name() { return "symlink"; }
|
||||||
|
|
||||||
@ -64,114 +51,38 @@ class Vfs::Symlink_file_system : public File_system
|
|||||||
|
|
||||||
Readlink_result readlink(char const *path,
|
Readlink_result readlink(char const *path,
|
||||||
char *buf,
|
char *buf,
|
||||||
file_size buf_size,
|
file_size buf_len,
|
||||||
file_size &out_len) override
|
file_size &out_len) override
|
||||||
{
|
{
|
||||||
if (!_single_file(path))
|
if (!_single_file(path))
|
||||||
return READLINK_ERR_NO_ENTRY;
|
return READLINK_ERR_NO_ENTRY;
|
||||||
out_len = min(buf_size, file_size(sizeof(_target)));
|
out_len = min(buf_len, (file_size)_target.length()-1);
|
||||||
strncpy(buf, _target, out_len);
|
memcpy(buf, _target.string(), out_len);
|
||||||
|
if (out_len < buf_len)
|
||||||
|
buf[out_len] = '\0';
|
||||||
return READLINK_OK;
|
return READLINK_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
Stat_result stat(char const *path, Stat &out) override
|
|
||||||
{
|
|
||||||
out = Stat();
|
|
||||||
out.device = (Genode::addr_t)this;
|
|
||||||
|
|
||||||
if (_root(path)) {
|
|
||||||
out.mode = STAT_MODE_DIRECTORY;
|
|
||||||
|
|
||||||
} else if (_single_file(path)) {
|
|
||||||
out.mode = STAT_MODE_SYMLINK;
|
|
||||||
out.inode = 1;
|
|
||||||
} else {
|
|
||||||
return STAT_ERR_NO_ENTRY;
|
|
||||||
}
|
|
||||||
return STAT_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
file_size num_dirent(char const *path) override
|
|
||||||
{
|
|
||||||
if (_root(path))
|
|
||||||
return 1;
|
|
||||||
else
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool directory(char const *path) override
|
|
||||||
{
|
|
||||||
if (_root(path))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
char const *leaf_path(char const *path) override
|
|
||||||
{
|
|
||||||
return _single_file(path) ? path : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
Dirent_result dirent(char const *path, file_offset index, Dirent &out) override
|
|
||||||
{
|
|
||||||
if (!_root(path))
|
|
||||||
return DIRENT_ERR_INVALID_PATH;
|
|
||||||
|
|
||||||
if (index == 0) {
|
|
||||||
out.fileno = (Genode::addr_t)this;
|
|
||||||
out.type = DIRENT_TYPE_SYMLINK;
|
|
||||||
strncpy(out.name, _filename, sizeof(out.name));
|
|
||||||
} else {
|
|
||||||
out.type = DIRENT_TYPE_END;
|
|
||||||
}
|
|
||||||
return DIRENT_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
Dataspace_capability dataspace(char const *path) override {
|
|
||||||
return Dataspace_capability(); }
|
|
||||||
|
|
||||||
void release(char const *path, Dataspace_capability ds_cap) override { }
|
|
||||||
|
|
||||||
Open_result open(char const *, unsigned, Vfs_handle **out_handle,
|
Open_result open(char const *, unsigned, Vfs_handle **out_handle,
|
||||||
Allocator&) override {
|
Allocator&) override {
|
||||||
return OPEN_ERR_UNACCESSIBLE; }
|
return OPEN_ERR_UNACCESSIBLE; }
|
||||||
|
|
||||||
void close(Vfs_handle *) override { }
|
void close(Vfs_handle *) override { }
|
||||||
|
|
||||||
Unlink_result unlink(char const *) override {
|
|
||||||
return UNLINK_ERR_NO_PERM; }
|
|
||||||
|
|
||||||
Rename_result rename(char const *from, char const *to) override
|
|
||||||
{
|
|
||||||
if (_single_file(from) || _single_file(to))
|
|
||||||
return RENAME_ERR_NO_PERM;
|
|
||||||
return RENAME_ERR_NO_ENTRY;
|
|
||||||
}
|
|
||||||
|
|
||||||
Mkdir_result mkdir(char const *, unsigned) override {
|
|
||||||
return MKDIR_ERR_NO_PERM; }
|
|
||||||
|
|
||||||
|
|
||||||
/********************************
|
/********************************
|
||||||
** File I/O service interface **
|
** File I/O service interface **
|
||||||
********************************/
|
********************************/
|
||||||
|
|
||||||
Write_result write(Vfs_handle *handle, char const *, file_size,
|
Write_result write(Vfs_handle *handle, char const *, file_size,
|
||||||
file_size &) override
|
file_size &) override {
|
||||||
{
|
return WRITE_ERR_INVALID; }
|
||||||
return WRITE_ERR_INVALID;
|
|
||||||
}
|
|
||||||
|
|
||||||
Read_result read(Vfs_handle *, char *, file_size, file_size &) override
|
Read_result read(Vfs_handle *, char *, file_size, file_size &) override {
|
||||||
{
|
return READ_ERR_INVALID; }
|
||||||
return READ_ERR_INVALID;
|
|
||||||
}
|
|
||||||
|
|
||||||
Ftruncate_result ftruncate(Vfs_handle *, file_size) override
|
|
||||||
{
|
|
||||||
return FTRUNCATE_ERR_NO_PERM;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
Ftruncate_result ftruncate(Vfs_handle *, file_size) override {
|
||||||
|
return FTRUNCATE_ERR_NO_PERM; }
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* _INCLUDE__VFS__SYMLINK_FILE_SYSTEM_H_ */
|
#endif /* _INCLUDE__VFS__SYMLINK_FILE_SYSTEM_H_ */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user