File indexing completed on 2024-04-28 15:20:27

0001 /*
0002     SPDX-License-Identifier: LGPL-2.0-or-later
0003     SPDX-FileCopyrightText: 2021 Harald Sitter <sitter@kde.org>
0004 */
0005 
0006 #ifndef KCRASH_METADATA_H
0007 #define KCRASH_METADATA_H
0008 
0009 #include <QtGlobal>
0010 
0011 #include <array>
0012 
0013 class QByteArray;
0014 
0015 namespace KCrash
0016 {
0017 // A metadata writer interface.
0018 class MetadataWriter
0019 {
0020 public:
0021     enum BoolValue { No = false, Yes = true };
0022 
0023     virtual void add(const char *key, const char *value, BoolValue boolValue) = 0;
0024     virtual void close() = 0;
0025 
0026 protected:
0027     MetadataWriter() = default;
0028     virtual ~MetadataWriter() = default;
0029 
0030 private:
0031     Q_DISABLE_COPY_MOVE(MetadataWriter)
0032 };
0033 
0034 #ifdef Q_OS_LINUX
0035 // This writes the metadata file. Only really useful on Linux for now as this needs
0036 // cleanup by a helper daemon later. Also, this is only ever useful when coredump is in use.
0037 class MetadataINIWriter : public MetadataWriter
0038 {
0039 public:
0040     explicit MetadataINIWriter(const QByteArray &path);
0041     ~MetadataINIWriter() override = default;
0042 
0043     void add(const char *key, const char *value, BoolValue boolValue) override;
0044     void close() override;
0045 
0046     // open or not, all functions are generally save to call without checking this
0047     [[nodiscard]] bool isWritable() const;
0048 
0049 private:
0050     bool writable = false;
0051     int fd = -1;
0052     std::array<char, 1024> iniLine{}; // arbitrary max size
0053 
0054     Q_DISABLE_COPY_MOVE(MetadataINIWriter)
0055 };
0056 #endif
0057 
0058 // Compile the crash metadata. These are the primary ARGV metadata, but additional
0059 // metadata writers may be added behind it to (e.g.) write the data to a file as well.
0060 //   man 7 signal-safety
0061 class Metadata : public MetadataWriter
0062 {
0063 public:
0064     explicit Metadata(const char *cmd);
0065     ~Metadata() override = default;
0066 
0067     // Add an additional writer that should receive write calls as well. Do not call this after having called add.
0068     void setAdditionalWriter(MetadataWriter *writer);
0069 
0070     void add(const char *key, const char *value);
0071     void addBool(const char *key);
0072 
0073     // Also closes the backing writer.
0074     void close() override;
0075 
0076     std::array<const char *, 31> argv{};
0077     std::size_t argc = 0;
0078 
0079 private:
0080     void add(const char *key, const char *value, BoolValue boolValue) override;
0081 
0082     // Obviously if we should ever need more writers, refactor to std::initializer_list or something similar.
0083     MetadataWriter *m_writer = nullptr;
0084 
0085     Q_DISABLE_COPY_MOVE(Metadata)
0086 };
0087 
0088 } // namespace KCrash
0089 
0090 #endif // KCRASH_METADATA_H