genode/repos/os/include/vfs/directory_service.h
2019-11-19 14:17:30 +01:00

234 lines
5.1 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 **
**********/
/**
* These values are the same as in the FreeBSD libc
*/
enum {
STAT_MODE_SYMLINK = 0120000,
STAT_MODE_FILE = 0100000,
STAT_MODE_DIRECTORY = 0040000,
STAT_MODE_CHARDEV = 0020000,
STAT_MODE_BLOCKDEV = 0060000,
};
struct Stat
{
file_size size = 0;
unsigned mode = 0;
unsigned uid = 0;
unsigned gid = 0;
unsigned long inode = 0;
unsigned long device = 0;
Timestamp modification_time { Timestamp::INVALID };
};
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 { DIRENT_MAX_NAME_LEN = 128 };
enum Dirent_type {
DIRENT_TYPE_FILE,
DIRENT_TYPE_DIRECTORY,
DIRENT_TYPE_FIFO,
DIRENT_TYPE_CHARDEV,
DIRENT_TYPE_BLOCKDEV,
DIRENT_TYPE_SYMLINK,
DIRENT_TYPE_END
};
struct Dirent
{
unsigned long fileno = 0;
Dirent_type type = DIRENT_TYPE_END;
char name[DIRENT_MAX_NAME_LEN] = { 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_ */