diff options
author | Vsevolod Stakhov <vsevolod@rspamd.com> | 2022-04-02 12:50:59 +0100 |
---|---|---|
committer | Vsevolod Stakhov <vsevolod@rspamd.com> | 2022-04-02 12:50:59 +0100 |
commit | 600452bacff96da2470dd70917c38e5b4de95d1c (patch) | |
tree | 487d0187d060a59edc732d9d7e5d968c07e75d1a | |
parent | d3441f144fb89511832c63b17b30161404529b6e (diff) | |
download | rspamd-600452bacff96da2470dd70917c38e5b4de95d1c.tar.gz rspamd-600452bacff96da2470dd70917c38e5b4de95d1c.zip |
[Minor] Add a simple utility to deal with locked files
-rw-r--r-- | src/libutil/cxx/locked_file.cxx | 36 | ||||
-rw-r--r-- | src/libutil/cxx/locked_file.hxx | 35 |
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 |