aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@rspamd.com>2022-04-02 12:50:59 +0100
committerVsevolod Stakhov <vsevolod@rspamd.com>2022-04-02 12:50:59 +0100
commit600452bacff96da2470dd70917c38e5b4de95d1c (patch)
tree487d0187d060a59edc732d9d7e5d968c07e75d1a
parentd3441f144fb89511832c63b17b30161404529b6e (diff)
downloadrspamd-600452bacff96da2470dd70917c38e5b4de95d1c.tar.gz
rspamd-600452bacff96da2470dd70917c38e5b4de95d1c.zip
[Minor] Add a simple utility to deal with locked files
-rw-r--r--src/libutil/cxx/locked_file.cxx36
-rw-r--r--src/libutil/cxx/locked_file.hxx35
2 files changed, 71 insertions, 0 deletions
diff --git a/src/libutil/cxx/locked_file.cxx b/src/libutil/cxx/locked_file.cxx
new file mode 100644
index 000000000..8bbb51bf3
--- /dev/null
+++ b/src/libutil/cxx/locked_file.cxx
@@ -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
index 000000000..63239fcd9
--- /dev/null
+++ b/src/libutil/cxx/locked_file.hxx
@@ -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