File indexing completed on 2024-12-01 11:06:25

0001 /*
0002     SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
0003     SPDX-FileCopyrightText: 2019-2021 Harald Sitter <sitter@kde.org>
0004 */
0005 
0006 #pragma once
0007 
0008 #include <memory>
0009 #include <systemd/sd-journal.h>
0010 
0011 namespace std
0012 {
0013 template<>
0014 struct default_delete<sd_journal> {
0015     void operator()(sd_journal *ptr) const
0016     {
0017         sd_journal_close(ptr);
0018     }
0019 };
0020 } // namespace std
0021 
0022 template<typename T, typename Deleter>
0023 struct Expected {
0024     const int ret; // return value of call
0025     const int error; // errno immediately after the call
0026     std::unique_ptr<T, Deleter> value; // the newly owned object (may be null)
0027 };
0028 
0029 // Wrapper around C double pointer API of which we must take ownership.
0030 // errno may or may not be
0031 template<typename T, typename Func, typename... Args>
0032 Expected<T, std::default_delete<T>> owning_ptr_call(Func func, Args &&...args)
0033 {
0034     T *raw = nullptr;
0035     const int ret = func(&raw, std::forward<Args>(args)...);
0036     return {ret, errno, std::unique_ptr<T>(raw)};
0037 }
0038 
0039 // Same as owning_ptr_call but for (sd_journal *, foo **, ...) API
0040 template<typename T, typename Deleter, typename Func, typename... Args>
0041 Expected<T, Deleter> contextual_owning_ptr_call(Func func, sd_journal *context, Deleter deleter = std::default_delete<T>{}, Args &&...args)
0042 {
0043     T *raw = nullptr;
0044     const int ret = func(context, &raw, std::forward<Args>(args)...);
0045     return {ret, errno, std::unique_ptr<T, Deleter>(raw, deleter)};
0046 }