]> git.ipfire.org Git - thirdparty/rspamd.git/commitdiff
[Minor] Add a simple utility to deal with locked files
authorVsevolod Stakhov <vsevolod@rspamd.com>
Sat, 2 Apr 2022 11:50:59 +0000 (12:50 +0100)
committerVsevolod Stakhov <vsevolod@rspamd.com>
Sat, 2 Apr 2022 11:50:59 +0000 (12:50 +0100)
src/libutil/cxx/locked_file.cxx [new file with mode: 0644]
src/libutil/cxx/locked_file.hxx [new file with mode: 0644]

diff --git a/src/libutil/cxx/locked_file.cxx b/src/libutil/cxx/locked_file.cxx
new file mode 100644 (file)
index 0000000..8bbb51b
--- /dev/null
@@ -0,0 +1,36 @@
+//
+// Created by Vsevolod Stakhov on 02/04/2022.
+//
+
+#include "locked_file.hxx"
+#include <fmt/core.h>
+#include "libutil/util.h"
+#include "libutil/unix-std.h"
+
+auto raii_locked_file::open(const char *fname, int flags) -> tl::expected<raii_locked_file, std::string>
+{
+       int oflags = flags;
+#ifdef O_CLOEXEC
+       oflags |= O_CLOEXEC;
+#endif
+       auto fd = ::open(fname, oflags);
+
+       if (fd == -1) {
+               return tl::make_unexpected(fmt::format("cannot open file {}: {}", fname, ::strerror(errno)));
+       }
+
+       if (!rspamd_file_lock(fd, FALSE)) {
+               close(fd);
+               return tl::make_unexpected(fmt::format("cannot lock file {}: {}", fname, ::strerror(errno)));
+       }
+
+       return raii_locked_file{fd};
+}
+
+raii_locked_file::~raii_locked_file()
+{
+       if (fd != -1) {
+               (void) rspamd_file_unlock(fd, FALSE);
+               close(fd);
+       }
+}
diff --git a/src/libutil/cxx/locked_file.hxx b/src/libutil/cxx/locked_file.hxx
new file mode 100644 (file)
index 0000000..63239fc
--- /dev/null
@@ -0,0 +1,35 @@
+/*-
+ * Copyright 2022 Vsevolod Stakhov
+ *
+ * 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 RSPAMD_LOCKED_FILE_HXX
+#define RSPAMD_LOCKED_FILE_HXX
+#pragma once
+
+#include "contrib/expected/expected.hpp"
+#include <string>
+
+/**
+ * A simple RAII object to contain a file descriptor with an flock wrap
+ * A file is unlocked and closed when not needed
+ */
+struct raii_locked_file final {
+       ~raii_locked_file();
+       static auto open(const char *fname, int flags) -> tl::expected<raii_locked_file, std::string>;
+private:
+       int fd;
+       explicit raii_locked_file(int _fd) : fd(_fd) {}
+};
+
+#endif //RSPAMD_LOCKED_FILE_HXX