Implemented symlinks
This commit is contained in:
parent
f41939f443
commit
446c07deff
@ -16,7 +16,8 @@ public:
|
||||
|
||||
enum class EntryType {
|
||||
DIR = 0,
|
||||
FILE = 1
|
||||
FILE = 1,
|
||||
SYMLINK = 2
|
||||
};
|
||||
|
||||
struct Entry {
|
||||
@ -27,6 +28,7 @@ public:
|
||||
|
||||
virtual std::unique_ptr<OpenFile> createAndOpenFile(const std::string &name, mode_t mode, uid_t uid, gid_t gid) = 0;
|
||||
virtual void createDir(const std::string &name, mode_t mode, uid_t uid, gid_t gid) = 0;
|
||||
virtual void createSymlink(const std::string &name, const boost::filesystem::path &target) = 0;
|
||||
|
||||
//TODO Allow alternative implementation returning only children names without more information
|
||||
//virtual std::unique_ptr<std::vector<std::string>> children() const = 0;
|
||||
|
21
fs_interface/Symlink.h
Normal file
21
fs_interface/Symlink.h
Normal file
@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
#ifndef FSPP_SYMLINK_H_
|
||||
#define FSPP_SYMLINK_H_
|
||||
|
||||
#include "Node.h"
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
namespace fspp {
|
||||
class Device;
|
||||
|
||||
class Symlink: public virtual Node {
|
||||
public:
|
||||
virtual ~Symlink() {}
|
||||
|
||||
virtual boost::filesystem::path target() = 0;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
@ -37,6 +37,8 @@ public:
|
||||
virtual void statfs(const boost::filesystem::path &path, struct statvfs *fsstat) = 0;
|
||||
//TODO We shouldn't use Dir::Entry here, that's in another layer
|
||||
virtual std::unique_ptr<std::vector<Dir::Entry>> readDir(const boost::filesystem::path &path) = 0;
|
||||
virtual void createSymlink(const boost::filesystem::path &to, const boost::filesystem::path &from) = 0;
|
||||
virtual void readSymlink(const boost::filesystem::path &path, char *buf, size_t size) = 0;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -45,8 +45,8 @@ int fusepp_rmdir(const char *path) {
|
||||
return FUSE_OBJ->rmdir(bf::path(path));
|
||||
}
|
||||
|
||||
int fusepp_symlink(const char *from, const char *to) {
|
||||
return FUSE_OBJ->symlink(bf::path(from), bf::path(to));
|
||||
int fusepp_symlink(const char *to, const char *from) {
|
||||
return FUSE_OBJ->symlink(bf::path(to), bf::path(from));
|
||||
}
|
||||
|
||||
int fusepp_rename(const char *from, const char *to) {
|
||||
@ -248,13 +248,14 @@ int Fuse::fgetattr(const bf::path &path, struct stat *stbuf, fuse_file_info *fil
|
||||
}
|
||||
}
|
||||
|
||||
//TODO
|
||||
int Fuse::readlink(const bf::path &path, char *buf, size_t size) {
|
||||
UNUSED(path);
|
||||
UNUSED(buf);
|
||||
UNUSED(size);
|
||||
printf("Called non-implemented readlink(%s, _, %zu)\n", path.c_str(), size);
|
||||
return ENOSYS;
|
||||
//printf("readlink(%s, _, %zu)\n", path.c_str(), size);
|
||||
try {
|
||||
_fs->readSymlink(path, buf, size);
|
||||
return 0;
|
||||
} catch (fspp::fuse::FuseErrnoException &e) {
|
||||
return -e.getErrno();
|
||||
}
|
||||
}
|
||||
|
||||
int Fuse::mknod(const bf::path &path, mode_t mode, dev_t rdev) {
|
||||
@ -295,14 +296,14 @@ int Fuse::rmdir(const bf::path &path) {
|
||||
}
|
||||
}
|
||||
|
||||
//TODO
|
||||
int Fuse::symlink(const bf::path &from, const bf::path &to) {
|
||||
printf("NOT IMPLEMENTED: symlink(%s, %s)\n", from.c_str(), to.c_str());
|
||||
//auto real_from = _impl->RootDir() / from;
|
||||
//auto real_to = _impl->RootDir() / to;
|
||||
//int retstat = ::symlink(real_from.c_str(), real_to.c_str());
|
||||
//return errcode_map(retstat);
|
||||
return ENOSYS;
|
||||
//printf("symlink(%s, %s)\n", from.c_str(), to.c_str());
|
||||
try {
|
||||
_fs->createSymlink(from, to);
|
||||
return 0;
|
||||
} catch(fspp::fuse::FuseErrnoException &e) {
|
||||
return -e.getErrno();
|
||||
}
|
||||
}
|
||||
|
||||
int Fuse::rename(const bf::path &from, const bf::path &to) {
|
||||
@ -477,8 +478,13 @@ int Fuse::readdir(const bf::path &path, void *buf, fuse_fill_dir_t filler, off_t
|
||||
//It does getattr() calls on all entries nevertheless.
|
||||
if (entry.type == Dir::EntryType::DIR) {
|
||||
stbuf.st_mode = S_IFDIR;
|
||||
} else {
|
||||
} else if (entry.type == Dir::EntryType::FILE) {
|
||||
stbuf.st_mode = S_IFREG;
|
||||
} else if (entry.type == Dir::EntryType::SYMLINK) {
|
||||
printf("readdir:symlink\n");
|
||||
stbuf.st_mode = S_IFLNK;
|
||||
} else {
|
||||
assert(false);
|
||||
}
|
||||
if (filler(buf, entry.name.c_str(), &stbuf, 0) != 0) {
|
||||
return -ENOMEM;
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include <fcntl.h>
|
||||
#include "../fs_interface/Device.h"
|
||||
#include "../fs_interface/Dir.h"
|
||||
#include "../fs_interface/Symlink.h"
|
||||
|
||||
#include "../fuse/FuseErrnoException.h"
|
||||
#include "../fs_interface/File.h"
|
||||
@ -46,6 +47,15 @@ unique_ptr<Dir> FilesystemImpl::LoadDir(const bf::path &path) {
|
||||
return dir;
|
||||
}
|
||||
|
||||
unique_ptr<Symlink> FilesystemImpl::LoadSymlink(const bf::path &path) {
|
||||
auto node = _device->Load(path);
|
||||
auto dir = dynamic_pointer_move<Symlink>(node);
|
||||
if (!dir) {
|
||||
throw fuse::FuseErrnoException(ENOTDIR);
|
||||
}
|
||||
return dir;
|
||||
}
|
||||
|
||||
int FilesystemImpl::openFile(const bf::path &path, int flags) {
|
||||
auto file = LoadFile(path);
|
||||
return openFile(*file, flags);
|
||||
@ -148,3 +158,14 @@ void FilesystemImpl::utimens(const bf::path &path, const timespec times[2]) {
|
||||
void FilesystemImpl::statfs(const bf::path &path, struct statvfs *fsstat) {
|
||||
_device->statfs(path, fsstat);
|
||||
}
|
||||
|
||||
void FilesystemImpl::createSymlink(const bf::path &to, const bf::path &from) {
|
||||
auto parent = LoadDir(from.parent_path());
|
||||
parent->createSymlink(from.filename().native(), to);
|
||||
}
|
||||
|
||||
void FilesystemImpl::readSymlink(const bf::path &path, char *buf, size_t size) {
|
||||
string target = LoadSymlink(path)->target().native();
|
||||
std::memcpy(buf, target.c_str(), std::min(target.size()+1, size));
|
||||
buf[size-1] = '\0';
|
||||
}
|
||||
|
@ -10,6 +10,7 @@
|
||||
namespace fspp {
|
||||
class Node;
|
||||
class File;
|
||||
class Symlink;
|
||||
class OpenFile;
|
||||
|
||||
class FilesystemImpl: public fuse::Filesystem {
|
||||
@ -39,10 +40,13 @@ public:
|
||||
std::unique_ptr<std::vector<Dir::Entry>> readDir(const boost::filesystem::path &path) override;
|
||||
void utimens(const boost::filesystem::path &path, const timespec times[2]) override;
|
||||
void statfs(const boost::filesystem::path &path, struct statvfs *fsstat) override;
|
||||
void createSymlink(const boost::filesystem::path &to, const boost::filesystem::path &from) override;
|
||||
void readSymlink(const boost::filesystem::path &path, char *buf, size_t size) override;
|
||||
|
||||
private:
|
||||
std::unique_ptr<File> LoadFile(const boost::filesystem::path &path);
|
||||
std::unique_ptr<Dir> LoadDir(const boost::filesystem::path &path);
|
||||
std::unique_ptr<Symlink> LoadSymlink(const boost::filesystem::path &path);
|
||||
int openFile(const File &file, int flags);
|
||||
|
||||
Device *_device;
|
||||
|
Loading…
x
Reference in New Issue
Block a user