1
0
mirror of https://github.com/postgres/postgres.git synced 2025-09-02 04:21:28 +03:00

Introduce PG_MODULE_MAGIC_EXT macro.

This macro allows dynamically loaded shared libraries (modules) to
provide a wired-in module name and version, and possibly other
compile-time-constant fields in future.  This information can be
retrieved with the new pg_get_loaded_modules() function.

This feature is expected to be particularly useful for modules
that do not have any exposed SQL functionality and thus are
not associated with a SQL-level extension object.  But even for
modules that do belong to extensions, being able to verify the
actual code version can be useful.

Author: Andrei Lepikhov <lepihov@gmail.com>
Reviewed-by: Yurii Rashkovskii <yrashk@omnigres.com>
Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>
Discussion: https://postgr.es/m/dd4d1b59-d0fe-49d5-b28f-1e463b68fa32@gmail.com
This commit is contained in:
Tom Lane
2025-03-26 10:59:42 -04:00
parent e92c0632c1
commit 9324c8c580
10 changed files with 248 additions and 28 deletions

View File

@@ -2811,6 +2811,59 @@ pg_extension_config_dump(PG_FUNCTION_ARGS)
PG_RETURN_VOID();
}
/*
* pg_get_loaded_modules
*
* SQL-callable function to get per-loaded-module information. Modules
* (shared libraries) aren't necessarily one-to-one with extensions, but
* they're sufficiently closely related to make this file a good home.
*/
Datum
pg_get_loaded_modules(PG_FUNCTION_ARGS)
{
ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;
DynamicFileList *file_scanner;
/* Build tuplestore to hold the result rows */
InitMaterializedSRF(fcinfo, 0);
for (file_scanner = get_first_loaded_module(); file_scanner != NULL;
file_scanner = get_next_loaded_module(file_scanner))
{
const char *library_path,
*module_name,
*module_version;
const char *sep;
Datum values[3] = {0};
bool nulls[3] = {0};
get_loaded_module_details(file_scanner,
&library_path,
&module_name,
&module_version);
if (module_name == NULL)
nulls[0] = true;
else
values[0] = CStringGetTextDatum(module_name);
if (module_version == NULL)
nulls[1] = true;
else
values[1] = CStringGetTextDatum(module_version);
/* For security reasons, we don't show the directory path */
sep = last_dir_separator(library_path);
if (sep)
library_path = sep + 1;
values[2] = CStringGetTextDatum(library_path);
tuplestore_putvalues(rsinfo->setResult, rsinfo->setDesc,
values, nulls);
}
return (Datum) 0;
}
/*
* extension_config_remove
*