summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/fud_c_file.hpp44
-rw-r--r--include/fud_permissions.hpp191
2 files changed, 234 insertions, 1 deletions
diff --git a/include/fud_c_file.hpp b/include/fud_c_file.hpp
index 45a8b54..f451292 100644
--- a/include/fud_c_file.hpp
+++ b/include/fud_c_file.hpp
@@ -21,9 +21,13 @@
#include "fud_result.hpp"
#include "fud_status.hpp"
#include "fud_string.hpp"
+#include "fud_permissions.hpp"
#include <cstdint>
#include <cstdio>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <unistd.h>
namespace fud {
@@ -109,6 +113,27 @@ class CFile {
return self.m_file != nullptr ? FudStatus::Success : FudStatus::Failure;
}
+ FudStatus create(Permissions permissions)
+ {
+ auto& self = static_cast<Derived&>(*this);
+ if (self.m_modeFlags == CFileMode::ReadOnly || self.m_modeFlags == CFileMode::ReadWrite) {
+ return FudStatus::OperationInvalid;
+ }
+
+ if (!self.m_filename.valid()) {
+ return FudStatus::ObjectInvalid;
+ }
+
+ auto fdResult = ::open(self.m_filename.c_str(), O_CREAT, permissions.mode());
+ if (fdResult == -1) {
+ return FudStatus::Failure;
+ }
+ ::close(fdResult);
+
+ self.m_file = fopen(self.m_filename.c_str(), self.m_mode.c_str());
+ return self.m_file != nullptr ? FudStatus::Success : FudStatus::Failure;
+ }
+
void close()
{
auto& self = static_cast<Derived&>(*this);
@@ -130,6 +155,22 @@ class CFile {
return self.m_file;
}
+ FudStatus setPermissions(Permissions permissions) {
+ auto& self = static_cast<Derived&>(*this);
+ if (!self.isOpen()) {
+ return FudStatus::OperationInvalid;
+ }
+ auto descriptor = fileno(self.file());
+ if (descriptor == -1) {
+ return FudStatus::ObjectInvalid;
+ }
+ auto result = fchmod(descriptor, permissions());
+ if (result != 0) {
+ return FudStatus::Failure;
+ }
+ return FudStatus::Success;
+ }
+
[[nodiscard]] Result<size_t, FudStatus> size() const
{
const auto& self = static_cast<const Derived&>(*this);
@@ -311,7 +352,8 @@ class CFile {
auto& self = static_cast<Derived&>(*this);
return self.write(static_cast<const void*>(&source), sourceSize, length, offset);
}
-private:
+
+ private:
FudStatus reset() const
{
const auto& self = static_cast<const Derived&>(*this);
diff --git a/include/fud_permissions.hpp b/include/fud_permissions.hpp
new file mode 100644
index 0000000..66eec0c
--- /dev/null
+++ b/include/fud_permissions.hpp
@@ -0,0 +1,191 @@
+/*
+ * libfud
+ * Copyright 2024 Dominick Allen
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef FUD_PERMISSIONS_HPP
+#define FUD_PERMISSIONS_HPP
+
+#include <climits>
+#include <cstdint>
+#include <sys/stat.h>
+#include <type_traits>
+
+namespace fud {
+
+static_assert(CHAR_BIT == 8, "Assume that uint8_t has 8 bits");
+static_assert(sizeof(uint8_t) == 1, "Assume that uint8_t is 1 byte");
+
+enum class PermissionType : uint8_t
+{
+ None = 0x00,
+ Exec = 0x01,
+ Write = 0x02,
+ Read = 0x04
+};
+
+struct PermissionField {
+ explicit constexpr PermissionField(PermissionType permissionType) :
+ m_permissions{static_cast<uint8_t>(permissionType)}
+ {
+ }
+
+ constexpr PermissionField(PermissionType lhs, PermissionType rhs)
+ {
+ m_permissions = static_cast<uint8_t>(lhs) | static_cast<uint8_t>(rhs);
+ }
+
+ constexpr PermissionField(PermissionType lhs, PermissionField rhs)
+ {
+ m_permissions = static_cast<uint8_t>(lhs) | rhs.m_permissions;
+ }
+
+ constexpr PermissionField(PermissionField lhs, PermissionType rhs)
+ {
+ m_permissions = lhs.m_permissions | static_cast<uint8_t>(rhs);
+ }
+
+ constexpr PermissionField(PermissionField lhs, PermissionField rhs)
+ {
+ m_permissions = lhs.m_permissions | rhs.m_permissions;
+ }
+
+ constexpr uint16_t operator()()
+ {
+ return m_permissions;
+ }
+
+ uint8_t m_permissions{};
+};
+
+enum class PermissionSpecialType : uint8_t
+{
+ None = 0x00,
+ Sticky = 0x01,
+ SetGroupId = 0x02,
+ SetUserId = 0x04
+};
+
+struct PermissionSpecial {
+ explicit constexpr PermissionSpecial(PermissionSpecialType permissionType) :
+ m_permissions{static_cast<uint8_t>(permissionType)}
+ {
+ }
+
+ constexpr PermissionSpecial(PermissionSpecialType lhs, PermissionSpecialType rhs)
+ {
+ m_permissions = static_cast<uint8_t>(lhs) | static_cast<uint8_t>(rhs);
+ }
+
+ constexpr PermissionSpecial(PermissionSpecialType lhs, PermissionSpecial rhs)
+ {
+ m_permissions = static_cast<uint8_t>(lhs) | rhs.m_permissions;
+ }
+
+ constexpr PermissionSpecial(PermissionSpecial lhs, PermissionSpecialType rhs)
+ {
+ m_permissions = lhs.m_permissions | static_cast<uint8_t>(rhs);
+ }
+
+ constexpr PermissionSpecial(PermissionSpecial lhs, PermissionSpecial rhs)
+ {
+ m_permissions = lhs.m_permissions | rhs.m_permissions;
+ }
+
+ constexpr uint16_t operator()()
+ {
+ return m_permissions;
+ }
+
+ uint8_t m_permissions{0};
+};
+
+class Permissions {
+ public:
+ static constexpr uint8_t GroupShift = 3;
+ static constexpr uint8_t UserShift = GroupShift + 3;
+ static constexpr uint8_t SpecialShift = UserShift + 3;
+
+ constexpr Permissions(PermissionField user, PermissionField group, PermissionField others)
+ {
+ m_permissions = user() << UserShift | group() << GroupShift | others();
+ }
+
+ template <typename U, typename G, typename O>
+ constexpr Permissions(U user, G group, O others)
+ {
+ m_permissions = PermissionField{user}() << UserShift | PermissionField{group}() << GroupShift |
+ PermissionField{others}();
+ }
+
+ constexpr Permissions(
+ PermissionField user,
+ PermissionField group,
+ PermissionField others,
+ PermissionSpecial special)
+ {
+ m_permissions = special() << SpecialShift | user() << UserShift | group() << GroupShift | others();
+ }
+
+ template <typename U, typename G, typename O, typename S>
+ constexpr Permissions(
+ PermissionField user,
+ PermissionField group,
+ PermissionField others,
+ PermissionSpecial special)
+ {
+ m_permissions = special() << SpecialShift | PermissionField{user}() << UserShift |
+ PermissionField{group}() << GroupShift | PermissionField{others}();
+ }
+
+ constexpr int32_t operator()()
+ {
+ return m_permissions;
+ }
+
+ constexpr mode_t mode()
+ {
+ return static_cast<mode_t>(m_permissions);
+ }
+
+ private:
+ int32_t m_permissions{0};
+};
+
+constexpr PermissionField operator|(PermissionType lhs, PermissionType rhs)
+{
+ return PermissionField{lhs, rhs};
+}
+
+constexpr PermissionField operator|(PermissionType lhs, PermissionField rhs)
+{
+ return PermissionField{lhs, rhs};
+}
+
+constexpr PermissionField operator|(PermissionField lhs, PermissionType rhs)
+{
+ return PermissionField{lhs, rhs};
+}
+
+constexpr PermissionField operator|(PermissionField lhs, PermissionField rhs)
+{
+ return PermissionField{lhs, rhs};
+}
+
+constexpr PermissionField PermReadWrite = PermissionType::Read | PermissionType::Write;
+
+} // namespace fud
+
+#endif