diff options
author | Ian Moffett <ian@osmora.org> | 2024-03-07 17:28:00 -0500 |
---|---|---|
committer | Ian Moffett <ian@osmora.org> | 2024-03-07 17:28:32 -0500 |
commit | bd5969fc876a10b18613302db7087ef3c40f18e1 (patch) | |
tree | 7c2b8619afe902abf99570df2873fbdf40a4d1a1 /lib/mlibc/options/ansi/include/mlibc/file-io.hpp | |
parent | a95b38b1b92b172e6cc4e8e56a88a30cc65907b0 (diff) |
lib: Add mlibc
Signed-off-by: Ian Moffett <ian@osmora.org>
Diffstat (limited to 'lib/mlibc/options/ansi/include/mlibc/file-io.hpp')
-rw-r--r-- | lib/mlibc/options/ansi/include/mlibc/file-io.hpp | 111 |
1 files changed, 111 insertions, 0 deletions
diff --git a/lib/mlibc/options/ansi/include/mlibc/file-io.hpp b/lib/mlibc/options/ansi/include/mlibc/file-io.hpp new file mode 100644 index 0000000..1155a2b --- /dev/null +++ b/lib/mlibc/options/ansi/include/mlibc/file-io.hpp @@ -0,0 +1,111 @@ +#ifndef MLIBC_FILE_IO_HPP +#define MLIBC_FILE_IO_HPP + +#include <stdio.h> + +#include <mlibc/lock.hpp> +#include <mlibc/allocator.hpp> +#include <frg/list.hpp> + +namespace mlibc { + +enum class stream_type { + unknown, + file_like, + pipe_like +}; + +enum class buffer_mode { + unknown, + no_buffer, + line_buffer, + full_buffer +}; + +struct abstract_file : __mlibc_file_base { +public: + abstract_file(void (*do_dispose)(abstract_file *) = nullptr); + + abstract_file(const abstract_file &) = delete; + + abstract_file &operator= (const abstract_file &) = delete; + + virtual ~abstract_file(); + + void dispose(); + + virtual int close() = 0; + virtual int reopen(const char *path, const char *mode) = 0; + + int read(char *buffer, size_t max_size, size_t *actual_size); + int write(const char *buffer, size_t max_size, size_t *actual_size); + int unget(char c); + + int update_bufmode(buffer_mode mode); + + void purge(); + int flush(); + + int tell(off_t *current_offset); + int seek(off_t offset, int whence); + +protected: + virtual int determine_type(stream_type *type) = 0; + virtual int determine_bufmode(buffer_mode *mode) = 0; + virtual int io_read(char *buffer, size_t max_size, size_t *actual_size) = 0; + virtual int io_write(const char *buffer, size_t max_size, size_t *actual_size) = 0; + virtual int io_seek(off_t offset, int whence, off_t *new_offset) = 0; + + int _reset(); +private: + int _init_type(); + int _init_bufmode(); + + int _write_back(); + int _save_pos(); + + void _ensure_allocation(); + + stream_type _type; + buffer_mode _bufmode; + void (*_do_dispose)(abstract_file *); + +public: + // lock for file operations + RecursiveFutexLock _lock; + // All files are stored in a global linked list, so that they can be flushed at exit(). + frg::default_list_hook<abstract_file> _list_hook; +}; + +struct fd_file : abstract_file { + fd_file(int fd, void (*do_dispose)(abstract_file *) = nullptr, bool force_unbuffered = false); + + int fd(); + + int close() override; + int reopen(const char *path, const char *mode) override; + + static int parse_modestring(const char *mode); + +protected: + int determine_type(stream_type *type) override; + int determine_bufmode(buffer_mode *mode) override; + + int io_read(char *buffer, size_t max_size, size_t *actual_size) override; + int io_write(const char *buffer, size_t max_size, size_t *actual_size) override; + int io_seek(off_t offset, int whence, off_t *new_offset) override; + +private: + // Underlying file descriptor. + int _fd; + bool _force_unbuffered; +}; + +template <typename T> +void file_dispose_cb(abstract_file *base) { + frg::destruct(getAllocator(), static_cast<T *>(base)); +} + +} // namespace mlibc + +#endif // MLIBC_FILE_IO_HPP |