A module is addressed by name and command string, and nothing else. Typed API access handed a caller a pointer into the callee's function table, which meant compiling against that module's struct layout — a build-time dependency between modules that the design does not permit. Removing it also removes the manifest, the table magic constant, and the table size field, which existed only to describe and validate those tables. Load validation is now three steps: reserved contract symbols resolve, the minimum-version handshake passes, and the version and description probes return well-formed values. The contract is four reserved symbols, and a module's interface is the command vocabulary it documents. Documentation is brought in line, and artifacts are named exactly: libdpm-core.so for the library, <dpm/core.h> for the header, the dpm binary for the command-line tool.
74 lines
2.2 KiB
C++
74 lines
2.2 KiB
C++
/**
|
|
* @file modules.hpp
|
|
* @brief Module handle, cursor, and loader declarations
|
|
*
|
|
* @copyright Copyright (c) 2026 SILO GROUP LLC
|
|
* @author Chris Punches <chris.punches@silogroup.org>
|
|
*
|
|
* Part of the Dark Horse Linux Package Manager (DPM)
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU Affero General Public License as
|
|
* published by the Free Software Foundation, either version 3 of the
|
|
* License, or (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU Affero General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Affero General Public License
|
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
*/
|
|
#pragma once
|
|
|
|
#include <dpm/core.h>
|
|
|
|
#include <memory>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
/** @brief A loaded, fully validated module */
|
|
struct dpm_module {
|
|
std::string name;
|
|
void* handle = nullptr;
|
|
std::string version;
|
|
std::string description;
|
|
std::string core_min;
|
|
int (*execute)(dpm_ctx*, const char*, int, char**) = nullptr;
|
|
};
|
|
|
|
/** @brief Enumeration cursor over validated modules */
|
|
struct dpm_cursor {
|
|
std::vector<dpm_module_info> infos;
|
|
size_t idx = 0;
|
|
};
|
|
|
|
/**
|
|
* @brief Closes a dlopen handle
|
|
*
|
|
* Keeps handle release beside the loader in one translation unit.
|
|
*
|
|
* @param handle The handle to close; NULL is a no-op
|
|
*/
|
|
void dpm_internal_unload(void* handle);
|
|
|
|
namespace dpmcore {
|
|
|
|
/**
|
|
* @brief Runs the full load-time validation sequence against a module
|
|
*
|
|
* Loads the named module's .so from the context's module path and
|
|
* verifies the complete contract.
|
|
*
|
|
* @param ctx The libdpm-core context
|
|
* @param name The module name
|
|
* @param reason Receives the refusal reason on failure
|
|
* @return The validated module (caller owns), or nullptr on failure
|
|
*/
|
|
std::unique_ptr<dpm_module> validate_and_load(dpm_ctx* ctx,
|
|
const std::string& name,
|
|
std::string& reason);
|
|
|
|
} // namespace dpmcore
|