genode/repos/os/include/vfs/directory_service.h

241 lines
4.9 KiB
C++

/*
* \brief Directory-service interface
* \author Norman Feske
* \date 2011-02-17
*/
/*
* Copyright (C) 2011-2017 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3.
*/
#ifndef _INCLUDE__VFS__DIRECTORY_SERVICE_H_
#define _INCLUDE__VFS__DIRECTORY_SERVICE_H_
#include <vfs/types.h>
namespace Vfs {
class Vfs_handle;
class Vfs_watch_handle;
struct Directory_service;
using Genode::Allocator;
}
struct Vfs::Directory_service : Interface
{
virtual Dataspace_capability dataspace(char const *path) = 0;
virtual void release(char const *path, Dataspace_capability) = 0;
enum General_error { ERR_FD_INVALID, NUM_GENERAL_ERRORS };
/**********
** Open **
**********/
/**
* Flags of 'mode' argument of open syscall
*/
enum {
OPEN_MODE_RDONLY = 0,
OPEN_MODE_WRONLY = 1,
OPEN_MODE_RDWR = 2,
OPEN_MODE_ACCMODE = 3,
OPEN_MODE_CREATE = 0x0800, /* libc O_EXCL */
};
enum Open_result
{
OPEN_ERR_UNACCESSIBLE,
OPEN_ERR_NO_PERM,
OPEN_ERR_EXISTS,
OPEN_ERR_NAME_TOO_LONG,
OPEN_ERR_NO_SPACE,
OPEN_ERR_OUT_OF_RAM,
OPEN_ERR_OUT_OF_CAPS,
OPEN_OK
};
virtual Open_result open(char const *path,
unsigned mode,
Vfs_handle **handle,
Allocator &alloc) = 0;
enum Opendir_result
{
OPENDIR_ERR_LOOKUP_FAILED,
OPENDIR_ERR_NAME_TOO_LONG,
OPENDIR_ERR_NODE_ALREADY_EXISTS,
OPENDIR_ERR_NO_SPACE,
OPENDIR_ERR_OUT_OF_RAM,
OPENDIR_ERR_OUT_OF_CAPS,
OPENDIR_ERR_PERMISSION_DENIED,
OPENDIR_OK
};
virtual Opendir_result opendir(char const * /* path */, bool /* create */,
Vfs_handle **, Allocator &)
{
return OPENDIR_ERR_LOOKUP_FAILED;
}
enum Openlink_result
{
OPENLINK_ERR_LOOKUP_FAILED,
OPENLINK_ERR_NAME_TOO_LONG,
OPENLINK_ERR_NODE_ALREADY_EXISTS,
OPENLINK_ERR_NO_SPACE,
OPENLINK_ERR_OUT_OF_RAM,
OPENLINK_ERR_OUT_OF_CAPS,
OPENLINK_ERR_PERMISSION_DENIED,
OPENLINK_OK
};
virtual Openlink_result openlink(char const * /* path */, bool /* create */,
Vfs_handle **, Allocator &)
{
return OPENLINK_ERR_PERMISSION_DENIED;
}
/**
* Close handle resources and deallocate handle
*
* Note: it might be necessary to call 'sync()' before 'close()'
* to ensure that previously written data has been completely
* processed.
*/
virtual void close(Vfs_handle *handle) = 0;
enum Watch_result
{
WATCH_ERR_UNACCESSIBLE,
WATCH_ERR_STATIC,
WATCH_ERR_OUT_OF_RAM,
WATCH_ERR_OUT_OF_CAPS,
WATCH_OK
};
/**
* Watch a file-system node for changes.
*/
virtual Watch_result watch(char const *path,
Vfs_watch_handle**,
Allocator&)
{
/* default implementation for static file-systems */
return (leaf_path(path)) ? WATCH_ERR_STATIC : WATCH_ERR_UNACCESSIBLE;
}
virtual void close(Vfs_watch_handle *)
{
Genode::error("watch handle closed at invalid file-system");
throw ~0;
};
/**********
** Stat **
**********/
struct Stat
{
file_size size;
Node_type type;
Node_rwx rwx;
unsigned long inode;
unsigned long device;
Timestamp modification_time;
};
enum Stat_result { STAT_ERR_NO_ENTRY = NUM_GENERAL_ERRORS,
STAT_ERR_NO_PERM, STAT_OK };
/*
* Note: it might be necessary to call 'sync()' before 'stat()'
* to get the correct file size.
*/
virtual Stat_result stat(char const *path, Stat &) = 0;
/************
** Dirent **
************/
enum class Dirent_type
{
END,
DIRECTORY,
SYMLINK,
CONTINUOUS_FILE,
TRANSACTIONAL_FILE,
};
struct Dirent
{
struct Name
{
enum { MAX_LEN = 128 };
char buf[MAX_LEN] { };
Name() { };
Name(char const *name) { copy_cstring(buf, name, sizeof(buf)); }
};
unsigned long fileno;
Dirent_type type;
Node_rwx rwx;
Name name;
/**
* Sanitize dirent members
*
* This method must be called after receiving a 'Dirent' as
* a plain data copy.
*/
void sanitize()
{
/* enforce null termination */
name.buf[Name::MAX_LEN - 1] = 0;
}
};
/************
** Unlink **
************/
enum Unlink_result { UNLINK_ERR_NO_ENTRY, UNLINK_ERR_NO_PERM,
UNLINK_ERR_NOT_EMPTY, UNLINK_OK };
virtual Unlink_result unlink(char const *path) = 0;
/************
** Rename **
************/
enum Rename_result { RENAME_ERR_NO_ENTRY, RENAME_ERR_CROSS_FS,
RENAME_ERR_NO_PERM, RENAME_OK };
virtual Rename_result rename(char const *from, char const *to) = 0;
/**
* Return number of directory entries located at given path
*/
virtual file_size num_dirent(char const *path) = 0;
virtual bool directory(char const *path) = 0;
/**
* Return leaf path or nullptr if the path does not exist
*/
virtual char const *leaf_path(char const *path) = 0;
};
#endif /* _INCLUDE__VFS__DIRECTORY_SERVICE_H_ */