aboutsummaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
author_ov4 <ov4@ov4.org>2026-10-12 11:09:51 +0800
committer_ov4 <ov4@ov4.org>2026-10-12 11:09:51 +0800
commit77cd5981b398075ff866aab9d4145fc28542d773 (patch)
tree4b5db756a299d0c0b1e930dab1db4614eeebb6b3 /include
parent273858455fce9b7667f423d28830b5e08d0d7548 (diff)
add unix file class
Diffstat (limited to 'include')
-rw-r--r--include/error.h6
-rw-r--r--include/util/file.h104
2 files changed, 110 insertions, 0 deletions
diff --git a/include/error.h b/include/error.h
index d058ec4..50ca23e 100644
--- a/include/error.h
+++ b/include/error.h
@@ -20,6 +20,12 @@ enum class error_code
// eval
EVAL_FAIL_TO_CREATE_PIPE,
+ // file
+ FILE_MODE_NOT_SET,
+ FILE_FAIL_TO_OPEN,
+ FILE_OFLAG_ERROR,
+ FILE_POINTER_FAIL_TO_OPEN,
+
};
class T_error : public std::runtime_error {
diff --git a/include/util/file.h b/include/util/file.h
new file mode 100644
index 0000000..bbc6539
--- /dev/null
+++ b/include/util/file.h
@@ -0,0 +1,104 @@
+#pragma once
+
+#include <unistd.h>
+#include <fcntl.h>
+#include <string>
+#include <cstdio>
+
+#include "error.h"
+
+namespace ov4
+{
+
+class T_unix_file_d;
+class T_unix_file_p;
+
+
+class T_unix_file_d
+{
+public:
+ int fd = -1;
+
+ virtual int close()
+ {
+ if (fd == -1) return -1;
+ int ret = ::close(fd);
+ fd = -1;
+ return ret;
+ }
+
+ T_unix_file_d(const std::string &path, int oflag, int mode = -1)
+ {
+ if (oflag & O_CREAT)
+ {
+ if (mode == -1) throw T_error{error_code::FILE_MODE_NOT_SET, "Mode should be set for O_CREAT"};
+ fd = open(path.c_str(), oflag, mode);
+ if (fd == -1)
+ throw T_error(error_code::FILE_FAIL_TO_OPEN, "Fail to open file");
+ return;
+ }
+ fd = open(path.c_str(), oflag);
+ if (fd == -1)
+ throw T_error(error_code::FILE_FAIL_TO_OPEN, "Fail to open file");
+ }
+
+ ~T_unix_file_d()
+ {
+ this->close();
+ }
+
+ T_unix_file_d(const T_unix_file_d &) = delete;
+ T_unix_file_d &operator=(const T_unix_file_d &) = delete;
+};
+
+class T_unix_file_p : public T_unix_file_d
+{
+public:
+ FILE* fp = nullptr;
+
+ int close() override
+ {
+ if (fp == nullptr) return -1;
+ int ret = fclose(fp);
+ fp = nullptr;
+ fd = -1;
+ return ret;
+ }
+
+ T_unix_file_p(const std::string &path, int oflag, int mode = -1)
+ : T_unix_file_d(path, oflag, mode)
+ {
+ const char *fp_mode;
+ switch (oflag & O_ACCMODE)
+ {
+ case O_RDONLY:
+ fp_mode = "r";
+ break;
+
+ case O_WRONLY:
+ fp_mode = "w";
+ break;
+
+ case O_RDWR:
+ fp_mode = "r+";
+ break;
+
+ default:
+ throw T_error{error_code::FILE_OFLAG_ERROR, "oflag error"};
+ }
+ fp = fdopen(fd, fp_mode);
+
+ if (fp == nullptr)
+ throw T_error{error_code::FILE_POINTER_FAIL_TO_OPEN, "Fail to open file pointer"};
+ }
+
+ ~T_unix_file_p()
+ {
+ this->close();
+ }
+
+ T_unix_file_p(const T_unix_file_p &) = delete;
+ T_unix_file_p &operator=(const T_unix_file_p &) = delete;
+};
+
+} \ No newline at end of file