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 startTagsGroup() const;
44 void startExtraGroup() const;
45 void startGPUGroup() const;
46 void startKCrashGroup() const;
47 void add(const char *key, const char *value, BoolValue boolValue) override;
48 void close() override;
49
50 // open or not, all functions are generally save to call without checking this
51 [[nodiscard]] bool isWritable() const;
52
53private:
54 void startGroup(const char *group) const;
55 bool writable = false;
56 int fd = -1;
57
58 Q_DISABLE_COPY_MOVE(MetadataINIWriter)
59};
60#endif
61
62// Compile the crash metadata. These are the primary ARGV metadata, but additional
63// metadata writers may be added behind it to (e.g.) write the data to a file as well.
64// man 7 signal-safety
65class Metadata : public MetadataWriter
66{
67public:
68 explicit Metadata(const char *cmd);
69 ~Metadata() override = default;
70
71 // Add an additional writer that should receive write calls as well. Do not call this after having called add.
72 void setAdditionalWriter(MetadataWriter *writer);
73
74 void add(const char *key, const char *value);
75 void addBool(const char *key);
76
77 // Also closes the backing writer.
78 void close() override;
79
80 // WARNING: DO NOT FORGET TO BUMP AND SHRINK THE CAPACITY
81 // - boolean values increase the argv by 1 slot
82 // - non-boolean values increase the argv by 2 slots
83 // - this should always be the maximum of potentially used slots
84 // - if you re-count slots, don't forget that the 'cmd' and terminal NULL take a slot each
85 std::array<const char *, 38> argv{};
86 std::size_t argc = 0;
87
88private:
89 void add(const char *key, const char *value, BoolValue boolValue) override;
90
91 // Obviously if we should ever need more writers, refactor to std::initializer_list or something similar.
92 MetadataWriter *m_writer = nullptr;
93
94 Q_DISABLE_COPY_MOVE(Metadata)
95};
96
97} // namespace KCrash
98
99#endif // KCRASH_METADATA_H
100

source code of kcrash/src/metadata_p.h