Maat C++ Documentation
filesystem.hpp
1 #ifndef MAAT_FS_HPP
2 #define MAAT_FS_HPP
3 
4 #include <memory>
5 #include "memory.hpp"
6 #include "env/os.hpp"
7 #include "snapshot.hpp"
8 
9 namespace maat
10 {
11 namespace env
12 {
13 
17 class PhysicalFile;
18 typedef std::shared_ptr<PhysicalFile> physical_file_t;
19 
21 typedef int filehandle_t;
22 
25 {
26 friend class FileSystem;
27 public:
28  struct State
29  {
30  addr_t read_ptr;
32  };
33 protected:
34  filehandle_t _handle;
35  int flags; // TODO ?
36  physical_file_t physical_file;
37  addr_t _alloc_addr; // Address where the EnvFile's fileno has been allocated in memory ??? TODO
38  State state;
39 public:
40  bool deleted;
41 public:
43  FileAccessor(physical_file_t physical_file, filehandle_t handle);
45  unsigned int write_buffer(const std::vector<Expr>& buffer);
47  unsigned int write_buffer(uint8_t* buffer, int len);
49  unsigned int read_buffer(std::vector<Expr>& buffer, unsigned int nb_elems, unsigned int elem_size);
50 public:
51  filehandle_t handle() const;
52 };
53 
54 
56 enum class FileSystemAction
57 {
58  CREATE_FILE,
59  DELETE_FILE,
60  CREATE_DIR,
61  DELETE_DIR
62 };
63 
64 // Env Snapshot
65 class Snapshot
66 {
67 public:
68  std::list<std::pair<std::shared_ptr<PhysicalFile>, SavedMemState>> saved_file_contents;
69  // <path, action>
70  std::list<std::pair<std::string, FileSystemAction>> fs_actions;
71  std::list<env::FileAccessor> file_accessors;
72 public:
73  Snapshot() = default;
74  Snapshot(const Snapshot& other) = delete;
75  Snapshot& operator=(const Snapshot& other) = delete;
76 public:
77  void add_saved_file_content(std::shared_ptr<PhysicalFile> file, SavedMemState&& content);
78  void add_filesystem_action(std::string path, FileSystemAction action);
79 };
80 
81 
82 
83 typedef unsigned node_status_t;
84 namespace node
85 {
86  static constexpr node_status_t none = 0;
87 
88  static constexpr node_status_t exists = 1 << 0;
89  static constexpr node_status_t is_file = 1 << 1;
90  static constexpr node_status_t is_symlink = 1 << 2;
91  static constexpr node_status_t is_dir = 1 << 3;
92 
93  bool check_is_file(node_status_t s);
94  bool check_is_symlink(node_status_t s);
95  bool check_is_dir(node_status_t s);
96 }
97 
99 typedef std::vector<std::string> fspath_t;
100 
102 class PhysicalFile: public std::enable_shared_from_this<PhysicalFile>
103 {
104 friend class FileSystem;
105 public:
107  enum class Type
108  {
109  REGULAR,
110  IOSTREAM,
111  SYMLINK
112  };
113 
114 protected:
115  std::shared_ptr<MemSegment> data;
116  int flags;
117  bool deleted;
119  std::string _symlink;
120  Type type;
121 private:
122  addr_t istream_read_offset;
123 private:
124  SnapshotManager<env::Snapshot>* snapshots;
125 public:
128  std::optional<std::reference_wrapper<std::ostream>> flush_stream;
129 public:
133  unsigned int write_buffer(const std::vector<Expr>& buffer, addr_t& offset);
135  unsigned int write_buffer(uint8_t* buffer, addr_t& offset, int len);
137  unsigned int read_buffer(std::vector<Expr>& buffer, addr_t& offset, unsigned int nb_elems, unsigned int elem_size);
139  unsigned int size();
141  unsigned int copy_real_file(const std::string& filename);
142 public:
144  node_status_t status();
145 public:
147  void set_deleted(bool deleted);
149  bool is_deleted();
151  bool is_symlink();
153  const std::string& symlink();
154 
155 private:
156  // Used by streams
157  void _adjust_read_offset(addr_t& offset);
158  void _adjust_write_offset(addr_t& offset);
159 
160 private:
161  // Snapshoting
162  void record_write(addr_t offset, int nb_bytes);
163 
164 protected:
165  void _set_symlink(const std::string& target);
166 };
167 
168 
169 
170 class Directory;
171 typedef std::shared_ptr<Directory> directory_t;
172 
174 {
175 friend class FileSystem;
176 protected:
177  bool deleted;
178 private:
179  std::map<std::string, physical_file_t> files;
180  std::map<std::string, directory_t> subdirs;
181  std::map<std::string, fspath_t> symlinks;
182 private:
183  SnapshotManager<env::Snapshot>* snapshots;
184 private:
185  // Return True if 'name' is an existing file or subdir or symlink
186  bool _contains_name(const std::string& name);
187 public:
189  bool create_file(fspath_t path, bool create_path = false); // TODO snapshot manager ?
192  physical_file_t get_file(fspath_t path);
194  bool delete_file(fspath_t path, bool weak=true);
196  bool create_dir(fspath_t path);
198  directory_t get_dir(fspath_t path);
200  bool delete_dir(fspath_t path, bool weak=true);
202  node_status_t get_node_status(fspath_t path);
204  void delete_self(bool recursive=true, bool weak=true); // TODO Snapshot, FileSystem, not used anymore?
205 public:
207  void print(std::ostream& os, const std::string& indent) const;
208 };
209 
210 
211 
213 {
214 friend class EnvEmulator;
215 friend class LinuxEmulator;
216 
217 private:
218  filehandle_t _handle_cnt;
219  std::string path_separator;
220  std::string rootdir_prefix;
221  char orphan_file_wildcard;
222  Directory root;
223  Directory orphan_files; // Stdin, stdout, stderr, network streams, ...
224  // TODO: returning references to FAs in this list is
225  // probably not safe if the list is modified before they
226  // are used....
227  std::list<FileAccessor> fa_list;
228  std::vector<filehandle_t> reserved_handles;
229 private:
231 public:
233  FileSystem(OS system);
234 
235 public:
236  // Physical files
237  // get_fa_by_* functions don't check whether the path is marked as 'deleted' !
238 
242  physical_file_t get_file(const std::string& path, bool follow_symlink=true);
245  physical_file_t get_file_by_handle(filehandle_t handle);
250  bool create_file(const std::string& path, bool create_path=false);
258  bool delete_file(const std::string& path, bool weak=true);
260  bool file_exists(const std::string& path);
261 
262  // Symlinks
267  bool create_symlink(const std::string& link, const std::string& pointed_file, bool create_path=false);
268 
269  // Handles (FILE*)
272  filehandle_t new_fa(const std::string& path);
281  void delete_fa(filehandle_t handle, bool weak=true);
282 
283  // Dir
285  bool create_dir(const std::string& path);
287  directory_t get_dir(const std::string& path);
294  bool delete_dir(const std::string& path, bool weak=true);
295 
296  // Utils
297  std::string path_from_fspath(const fspath_t& path);
298  fspath_t fspath_from_path(const std::string& path);
299  fspath_t fspath_from_path_relative_to(std::string rel_path, fspath_t path_base);
300  std::string path_from_relative_path(std::string rel_path, std::string path_base);
301  std::string pointed_path_from_symlink(std::string symlink_file);
302  bool is_relative_path(const std::string& path);
303 
304  node_status_t get_node_status(const std::string& path);
305 
306 public:
308  std::string get_stdin_for_pid(int pid);
310  std::string get_stdout_for_pid(int pid);
312  std::string get_stderr_for_pid(int pid);
313 
314 public:
315  friend std::ostream& operator<<(std::ostream& os, const FileSystem& fs);
316 
317 private:
319  filehandle_t get_free_handle();
321  void _new_fa(const std::string& path, filehandle_t handle);
322 
323 public:
324  using snapshot_t = int;
326  snapshot_t take_snapshot();
328  void restore_snapshot(snapshot_t snapshot, bool remove=false);
330  void restore_last_snapshot(bool remove=false);
331 };
332 
333 
334  // Doxygen group env
336 
337 } // namespace env
338 } // namespace maat
339 
340 #endif
maat::env::FileAccessor::read_buffer
unsigned int read_buffer(std::vector< Expr > &buffer, unsigned int nb_elems, unsigned int elem_size)
Read abstract buffer from the file. Return the number of bytes read.
maat::env::PhysicalFile::write_buffer
unsigned int write_buffer(uint8_t *buffer, addr_t &offset, int len)
Write concrete buffer to the file. Return the number of bytes written.
maat::env::PhysicalFile
Definition: filesystem.hpp:103
maat::env::EnvEmulator
Main class emulating a process environment.
Definition: env.hpp:31
maat::env::Snapshot
Definition: filesystem.hpp:66
maat::env::FileSystemAction
FileSystemAction
Actions modifying the filesystem layout.
Definition: filesystem.hpp:57
maat::env::PhysicalFile::is_deleted
bool is_deleted()
Return 'True' if the file has been deleted by the emulated program.
maat::env::Directory::Directory
Directory(SnapshotManager< env::Snapshot > *snapshots)
maat::env::Directory::get_dir
directory_t get_dir(fspath_t path)
Get directory object. Throws exception if the directory doesn't exist.
maat::addr_t
uint64_t addr_t
Concrete memory address.
Definition: types.hpp:21
maat::env::FileAccessor::FileAccessor
FileAccessor(physical_file_t physical_file, filehandle_t handle)
If file accessor was deleted by the emulated program.
maat::env::Directory::print
void print(std::ostream &os, const std::string &indent) const
Print directory to output stream.
maat::env::FileAccessor::write_buffer
unsigned int write_buffer(uint8_t *buffer, int len)
Write concrete buffer to the file. Return the number of bytes written.
maat::SavedMemState
Struct used by snapshots to record previous contents of an overwritten memory area.
Definition: snapshot.hpp:25
maat::env::PhysicalFile::Type::REGULAR
@ REGULAR
Regular file supporting arbitrary read write.
maat::env::FileSystem::create_dir
bool create_dir(const std::string &path)
Create a directory in the filesystem. Returns 'true' on success, 'false' on failure.
maat::env::FileSystem::get_dir
directory_t get_dir(const std::string &path)
Get directory by absolute path. This function doesn't check wheter the dir was deleted or not!
maat::env::filehandle_t
int filehandle_t
Opaque handle to a file (equivalent of file descriptors on Linux)
Definition: filesystem.hpp:21
maat::env::Directory
Definition: filesystem.hpp:174
maat::env::FileSystem::get_stdout_for_pid
std::string get_stdout_for_pid(int pid)
Return the stdout file for process with PID 'pid'.
maat::env::PhysicalFile::flush_stream
std::optional< std::reference_wrapper< std::ostream > > flush_stream
If this field is set, flush every write to the file in the stream as well. This is mostly used for st...
Definition: filesystem.hpp:128
maat::env::FileSystem::file_exists
bool file_exists(const std::string &path)
Check if a file exists in the filesystem.
maat::env::LinuxEmulator
Specialisation of 'EnvEmulator' for the Linux operating system.
Definition: env.hpp:68
maat::env::FileAccessor::write_buffer
unsigned int write_buffer(const std::vector< Expr > &buffer)
Write abstract buffer to the file. Return the number of bytes written.
maat::SnapshotManager
Wrapper class to manage a list of snapshots.
Definition: snapshot.hpp:81
maat::env::Directory::delete_file
bool delete_file(fspath_t path, bool weak=true)
Delete physical file.
maat::env::Directory::get_file
physical_file_t get_file(fspath_t path)
Get physical file object. Throws exception if the file doesn't exist.
maat::env::FileAccessor
Definition: filesystem.hpp:25
maat::env::OS
OS
Emulated operating system.
Definition: os.hpp:12
maat::env::PhysicalFile::PhysicalFile
PhysicalFile(SnapshotManager< env::Snapshot > *snapshots, Type type=Type::REGULAR)
Create a new physical file.
maat::env::FileSystem::delete_file
bool delete_file(const std::string &path, bool weak=true)
Delete a file Returns 'true' on success and 'false' on failure.
maat::env::PhysicalFile::read_buffer
unsigned int read_buffer(std::vector< Expr > &buffer, addr_t &offset, unsigned int nb_elems, unsigned int elem_size)
Read abstract buffer from file. Return the number of elements read.
maat::env::PhysicalFile::Type
Type
Types of files.
Definition: filesystem.hpp:108
maat::env::FileSystem::delete_fa
void delete_fa(filehandle_t handle, bool weak=true)
Delete a file accessor.
maat::env::FileSystem::get_stdin_for_pid
std::string get_stdin_for_pid(int pid)
Return the stdin file for process with PID 'pid'.
maat::env::PhysicalFile::copy_real_file
unsigned int copy_real_file(const std::string &filename)
Fill the emulated file with concrete content from a real file. Return the size of 'filename'.
maat::env::fspath_t
std::vector< std::string > fspath_t
Absolute path to a file or directory node in the virtual file system.
Definition: filesystem.hpp:99
maat::operator<<
std::ostream & operator<<(std::ostream &os, const Constraint &constr)
Print a constraint to an out stream.
maat::env::PhysicalFile::size
unsigned int size()
Return the total size of the physical file content in bytes.
maat::env::FileSystemAction::CREATE_FILE
@ CREATE_FILE
Creating a new physical file.
maat::env::PhysicalFile::status
node_status_t status()
Return the file status.
maat::env::FileSystem::get_file_by_handle
physical_file_t get_file_by_handle(filehandle_t handle)
Convenience function to get a physical file by handle.
maat
Main namespace for Maat's API.
Definition: arch.hpp:11
maat::env::FileSystem::get_stderr_for_pid
std::string get_stderr_for_pid(int pid)
Return the stderr file for process with PID 'pid'.
maat::env::FileSystem::get_file
physical_file_t get_file(const std::string &path, bool follow_symlink=true)
Get a file in the file system.
maat::env::Directory::delete_self
void delete_self(bool recursive=true, bool weak=true)
Delete the directory.
maat::env::FileSystem::get_fa_by_handle
FileAccessor & get_fa_by_handle(filehandle_t handle)
Get a file accessor by handle.
maat::env::PhysicalFile::is_symlink
bool is_symlink()
Return 'True' if the file is a symbolic link.
maat::env::FileSystem::FileSystem
FileSystem(OS system)
Create a new filesystem for OS 'system'.
maat::env::PhysicalFile::write_buffer
unsigned int write_buffer(const std::vector< Expr > &buffer, addr_t &offset)
Write abstract buffer to the file. Return the number of bytes written.
maat::env::FileSystem::take_snapshot
snapshot_t take_snapshot()
Take a snapshot of the filesystem.
maat::env::Directory::get_node_status
node_status_t get_node_status(fspath_t path)
Get status of node.
maat::env::PhysicalFile::_size
addr_t _size
Size in bytes.
Definition: filesystem.hpp:118
maat::env::PhysicalFile::_symlink
std::string _symlink
Path if this file is a symlink.
Definition: filesystem.hpp:119
maat::env::Directory::create_dir
bool create_dir(fspath_t path)
Create new sub-directory.
maat::env::FileSystem
Definition: filesystem.hpp:213
maat::env::Directory::create_file
bool create_file(fspath_t path, bool create_path=false)
Create new file.
maat::env::PhysicalFile::symlink
const std::string & symlink()
If symlink, returns the file it points to.
maat::env::PhysicalFile::set_deleted
void set_deleted(bool deleted)
Set the deleted status of the file.
maat::env::Directory::delete_dir
bool delete_dir(fspath_t path, bool weak=true)
Delete sub directory.
maat::env::FileSystem::create_symlink
bool create_symlink(const std::string &link, const std::string &pointed_file, bool create_path=false)
Create a symbolic link.
maat::env::PhysicalFile::Type::IOSTREAM
@ IOSTREAM
Stream (reads consume data from the beginning, writes append data at the end)
maat::env::FileAccessor::State
Definition: filesystem.hpp:29
maat::env::FileSystem::restore_snapshot
void restore_snapshot(snapshot_t snapshot, bool remove=false)
Restore a snapshot of the filesystem.
maat::env::PhysicalFile::Type::SYMLINK
@ SYMLINK
Symbolic link to another file.
maat::env::FileSystem::new_fa
filehandle_t new_fa(const std::string &path)
Create a new file accessor.
maat::env::FileAccessor::State::write_ptr
addr_t write_ptr
Current read offset in file.
Definition: filesystem.hpp:31
maat::env::FileSystem::restore_last_snapshot
void restore_last_snapshot(bool remove=false)
Restore latests snapshot.
maat::env::FileSystem::delete_dir
bool delete_dir(const std::string &path, bool weak=true)
Delete a directory.
maat::env::FileSystem::create_file
bool create_file(const std::string &path, bool create_path=false)
Create a file specified by its absolute path. Returns 'true' on success and 'false' on failure.
maat::env::PhysicalFile::deleted
bool deleted
'True' if the file was deleted by the emulated program
Definition: filesystem.hpp:117