1/*
2 SPDX-License-Identifier: LGPL-2.0-or-later
3 SPDX-FileCopyrightText: 2021 Harald Sitter <sitter@kde.org>
4*/
5
6#ifndef KCRASH_METADATA_H
7#define KCRASH_METADATA_H
8
9#include <QtGlobal>
10
11#include <array>
12
13class QByteArray;
14
15namespace KCrash
16{
17// A metadata writer interface.
18class MetadataWriter
19{
20public:
21 enum BoolValue { No = false, Yes = true };
22
23 virtual void add(const char *key, const char *value, BoolValue boolValue) = 0;
24 virtual void close() = 0;
25
26protected:
27 MetadataWriter() = default;
28 virtual ~MetadataWriter() = default;
29
30private:
31 Q_DISABLE_COPY_MOVE(MetadataWriter)
32};
33
34#ifdef Q_OS_LINUX
35// This writes the metadata file. Only really useful on Linux for now as this needs
36// cleanup by a helper daemon later. Also, this is only ever useful when coredump is in use.
37class MetadataINIWriter : public MetadataWriter
38{
39public:
40 explicit MetadataINIWriter(const QByteArray &path);
41 ~MetadataINIWriter() override = default;
42
43 void add(const char *key, const char *value, BoolValue boolValue) override;
44 void close() override;
45
46 // open or not, all functions are generally save to call without checking this
47 [[nodiscard]] bool isWritable() const;
48
49private:
50 bool writable = false;
51 int fd = -1;
52
53 Q_DISABLE_COPY_MOVE(MetadataINIWriter)
54};
55#endif
56
57// Compile the crash metadata. These are the primary ARGV metadata, but additional
58// metadata writers may be added behind it to (e.g.) write the data to a file as well.
59// man 7 signal-safety
60class Metadata : public MetadataWriter
61{
62public:
63 explicit Metadata(const char *cmd);
64 ~Metadata() override = default;
65
66 // Add an additional writer that should receive write calls as well. Do not call this after having called add.
67 void setAdditionalWriter(MetadataWriter *writer);
68
69 void add(const char *key, const char *value);
70 void addBool(const char *key);
71
72 // Also closes the backing writer.
73 void close() override;
74
75 // WARNING: DO NOT FORGET TO BUMP AND SHRINK THE CAPACITY
76 // - boolean values increase the argv by 1 slot
77 // - non-boolean values increase the argv by 2 slots
78 // - this should always be the maximum of potentially used slots
79 // - if you re-count slots, don't forget that the 'cmd' and terminal NULL take a slot each
80 std::array<const char *, 34> argv{};
81 std::size_t argc = 0;
82
83private:
84 void add(const char *key, const char *value, BoolValue boolValue) override;
85
86 // Obviously if we should ever need more writers, refactor to std::initializer_list or something similar.
87 MetadataWriter *m_writer = nullptr;
88
89 Q_DISABLE_COPY_MOVE(Metadata)
90};
91
92} // namespace KCrash
93
94#endif // KCRASH_METADATA_H
95

source code of kcrash/src/metadata_p.h