From: Vsevolod Stakhov Date: Sat, 2 Apr 2022 11:50:59 +0000 (+0100) Subject: [Minor] Add a simple utility to deal with locked files X-Git-Tag: 3.3~293^2~50 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=600452bacff96da2470dd70917c38e5b4de95d1c;p=thirdparty%2Frspamd.git [Minor] Add a simple utility to deal with locked files --- diff --git a/src/libutil/cxx/locked_file.cxx b/src/libutil/cxx/locked_file.cxx new file mode 100644 index 0000000000..8bbb51bf30 --- /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 +#include "libutil/util.h" +#include "libutil/unix-std.h" + +auto raii_locked_file::open(const char *fname, int flags) -> tl::expected +{ + 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 0000000000..63239fcd93 --- /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 + +/** + * 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; +private: + int fd; + explicit raii_locked_file(int _fd) : fd(_fd) {} +}; + +#endif //RSPAMD_LOCKED_FILE_HXX