Common macros for loading shared libs

This commit is contained in:
Linus Dierheimer
2021-11-13 14:10:30 +01:00
parent 6cdf32dabc
commit fd447ab439
7 changed files with 268 additions and 361 deletions
+17 -60
View File
@@ -14,7 +14,6 @@ void ffPrintGPU(FFinstance* instance)
#else
#include <dlfcn.h>
#include <pci/pci.h>
static void printGPU(FFinstance* instance, struct pci_access* pacc, struct pci_dev* dev, FFcache* cache, uint8_t counter, char*(*ffpci_lookup_name)(struct pci_access*, char*, int, int, ...))
@@ -59,66 +58,19 @@ static void printGPU(FFinstance* instance, struct pci_access* pacc, struct pci_d
ffStrbufDestroy(&namePretty);
}
void ffPrintGPU(FFinstance* instance)
static const char* printGPUs(FFinstance* instance)
{
if(ffPrintFromCache(instance, FF_GPU_MODULE_NAME, &instance->config.gpuKey, &instance->config.gpuFormat, FF_GPU_NUM_FORMAT_ARGS))
return;
return NULL;
const char* pciLibName = instance->config.libPCI.length == 0 ? "libpci.so" : instance->config.libPCI.chars;
void* pci = dlopen(pciLibName, RTLD_LAZY);
if(pci == NULL)
{
ffPrintError(instance, FF_GPU_MODULE_NAME, 0, &instance->config.gpuKey, &instance->config.gpuFormat, FF_GPU_NUM_FORMAT_ARGS, "dlopen(\"%s\", RTLD_LAZY) == NULL", pciLibName);
return;
}
FF_LIBRARY_LOAD(pci, "libpci.so", instance->config.libPCI, "gpu: dlopen of libpci failed")
struct pci_access*(*ffpci_alloc)() = dlsym(pci, "pci_alloc");
if(ffpci_alloc == NULL)
{
dlclose(pci);
ffPrintError(instance, FF_GPU_MODULE_NAME, 0, &instance->config.gpuKey, &instance->config.gpuFormat, FF_GPU_NUM_FORMAT_ARGS, "dlsym(pci, \"pci_alloc\") == NULL");
return;
}
void(*ffpci_init)(struct pci_access*) = dlsym(pci, "pci_init");
if(ffpci_init == NULL)
{
dlclose(pci);
ffPrintError(instance, FF_GPU_MODULE_NAME, 0, &instance->config.gpuKey, &instance->config.gpuFormat, FF_GPU_NUM_FORMAT_ARGS, "dlsym(pci, \"pci_init\") == NULL");
return;
}
void(*ffpci_scan_bus)(struct pci_access*) = dlsym(pci, "pci_scan_bus");
if(ffpci_scan_bus == NULL)
{
dlclose(pci);
ffPrintError(instance, FF_GPU_MODULE_NAME, 0, &instance->config.gpuKey, &instance->config.gpuFormat, FF_GPU_NUM_FORMAT_ARGS, "dlsym(pci, \"pci_init\") == NULL");
return;
}
int(*ffpci_fill_info)(struct pci_dev*, int) = dlsym(pci, "pci_fill_info");
if(ffpci_fill_info == NULL)
{
dlclose(pci);
ffPrintError(instance, FF_GPU_MODULE_NAME, 0, &instance->config.gpuKey, &instance->config.gpuFormat, FF_GPU_NUM_FORMAT_ARGS, "dlsym(pci, \"pci_fill_info\") == NULL");
return;
}
char*(*ffpci_lookup_name)(struct pci_access*, char*, int, int, ...) = dlsym(pci, "pci_lookup_name");
if(ffpci_lookup_name == NULL)
{
dlclose(pci);
ffPrintError(instance, FF_GPU_MODULE_NAME, 0, &instance->config.gpuKey, &instance->config.gpuFormat, FF_GPU_NUM_FORMAT_ARGS, "dlsym(pci, \"pci_lookup_name\") == NULL");
return;
}
void(*ffpci_cleanup)(struct pci_access*) = dlsym(pci, "pci_cleanup");
if(ffpci_cleanup == NULL)
{
dlclose(pci);
ffPrintError(instance, FF_GPU_MODULE_NAME, 0, &instance->config.gpuKey, &instance->config.gpuFormat, FF_GPU_NUM_FORMAT_ARGS, "dlsym(pci, \"pci_cleanup\") == NULL");
return;
}
FF_LIBRARY_LOAD_SYMBOL(pci, pci_alloc, "gpu: dlsym of pci_alloc failed")
FF_LIBRARY_LOAD_SYMBOL(pci, pci_init, "gpu: dlsym of pci_init failed")
FF_LIBRARY_LOAD_SYMBOL(pci, pci_scan_bus, "gpu: dlsym of pci_scan_bus failed")
FF_LIBRARY_LOAD_SYMBOL(pci, pci_fill_info, "gpu: dlsym of pci_fill_info failed")
FF_LIBRARY_LOAD_SYMBOL(pci, pci_lookup_name, "gpu: dlsym of pci_lookup_name failed")
FF_LIBRARY_LOAD_SYMBOL(pci, pci_cleanup, "gpu: dlsym of pci_cleanup failed")
struct pci_access *pacc = ffpci_alloc();
ffpci_init(pacc);
@@ -146,13 +98,18 @@ void ffPrintGPU(FFinstance* instance)
for(uint32_t i = 0; i < devices.length; i++)
printGPU(instance, pacc, *(struct pci_dev**)ffListGet(&devices, i), &cache, devices.length == 1 ? 0 : i + 1, ffpci_lookup_name);
if(devices.length == 0)
ffPrintError(instance, FF_GPU_MODULE_NAME, 0, &instance->config.gpuKey, &instance->config.gpuFormat, FF_GPU_NUM_FORMAT_ARGS, "No GPU found");
ffCacheClose(&cache);
ffListDestroy(&devices);
ffpci_cleanup(pacc);
dlclose(pci);
return devices.length > 0 ? NULL : "No GPU found";
}
void ffPrintGPU(FFinstance* instance)
{
const char* error = printGPUs(instance);
if(error != NULL)
ffPrintError(instance, FF_GPU_MODULE_NAME, 0, &instance->config.gpuKey, &instance->config.gpuFormat, FF_GPU_NUM_FORMAT_ARGS, error);
}
#endif
+47 -4
View File
@@ -6,6 +6,44 @@
#define FF_PACKAGES_MODULE_NAME "Packages"
#define FF_PACKAGES_NUM_FORMAT_ARGS 8
#ifdef FF_HAVE_RPM
#include <rpm/rpmlib.h>
#include <rpm/rpmts.h>
#include <rpm/rpmdb.h>
#include <rpm/rpmlog.h>
static uint32_t getRpmPackageCount(FFinstance* instance)
{
FF_LIBRARY_LOAD(rpm, "librpm.so", instance->config.librpm, 0);
FF_LIBRARY_LOAD_SYMBOL(rpm, rpmReadConfigFiles, 0)
FF_LIBRARY_LOAD_SYMBOL(rpm, rpmtsCreate, 0)
FF_LIBRARY_LOAD_SYMBOL(rpm, rpmtsInitIterator, 0)
FF_LIBRARY_LOAD_SYMBOL(rpm, rpmdbGetIteratorCount, 0)
FF_LIBRARY_LOAD_SYMBOL(rpm, rpmdbFreeIterator, 0)
FF_LIBRARY_LOAD_SYMBOL(rpm, rpmtsFree, 0)
FF_LIBRARY_LOAD_SYMBOL(rpm, rpmlogSetMask, 0)
// Don't print any error messages
ffrpmlogSetMask(RPMLOG_MASK(RPMLOG_EMERG));
uint32_t count = 0;
rpmts ts = NULL;
rpmdbMatchIterator mi = NULL;
if (ffrpmReadConfigFiles(NULL, NULL)) goto exit;
if (!(ts = ffrpmtsCreate())) goto exit;
if (!(mi = ffrpmtsInitIterator(ts, RPMDBI_LABEL, NULL, 0))) goto exit;
count = ffrpmdbGetIteratorCount(mi);
exit:
if (mi) ffrpmdbFreeIterator(mi);
if (ts) ffrpmtsFree(ts);
dlclose(rpm);
return count;
}
#endif
static uint32_t getNumElements(const char* dirname, unsigned char type)
{
DIR* dirp = opendir(dirname);
@@ -58,11 +96,16 @@ void ffPrintPackages(FFinstance* instance)
uint32_t pacman = getNumElements("/var/lib/pacman/local", DT_DIR);
uint32_t dpkg = getNumStrings("/var/lib/dpkg/status", "Status: ");
#if __ANDROID__
dpkg += getNumStrings("/data/data/com.termux/files/usr/var/lib/dpkg/status", "Status: ");
#endif
#if __ANDROID__
dpkg += getNumStrings("/data/data/com.termux/files/usr/var/lib/dpkg/status", "Status: ");
#endif
#ifdef FF_HAVE_RPM
uint32_t rpm = getRpmPackageCount(instance);
#else
uint32_t rpm = 0;
#endif
uint32_t rpm = ffSettingsGetRpmPackageCount(instance);
uint32_t xbps = getNumElements("/var/db/xbps", DT_REG);
uint32_t flatpak = getNumElements("/var/lib/flatpak/app", DT_DIR);
uint32_t snap = getNumElements("/snap", DT_DIR);
+43 -56
View File
@@ -1,25 +1,12 @@
#include "fastfetch.h"
#include <string.h>
#include <dlfcn.h>
#include <dirent.h>
#include <pthread.h>
#define FF_RESOLUTION_MODULE_NAME "Resolution"
#define FF_RESOLUTION_NUM_FORMAT_ARGS 3
typedef void* DynamicLibrary;
#define FF_LIBRARY_LOAD(libraryNameUser, libraryNameDefault) dlopen(libraryNameUser.length == 0 ? libraryNameDefault : libraryNameUser.chars, RTLD_LAZY); \
if(dlerror() != NULL) \
return false;
#define FF_LIBRARY_LOAD_SYMBOL(library, symbolName) dlsym(library, symbolName); \
if(dlerror() != NULL) { \
dlclose(library); \
return false; \
}
typedef struct ResolutionResult
{
int width;
@@ -157,10 +144,9 @@ static void x11AddScreenAsResult(FFlist* results, Screen* screen, int refreshRat
static bool printResolutionX11Backend(FFinstance* instance)
{
DynamicLibrary x11 = FF_LIBRARY_LOAD(instance->config.libX11, "libX11.so");
Display*(*ffXOpenDisplay)(const char*) = FF_LIBRARY_LOAD_SYMBOL(x11, "XOpenDisplay");
int(*ffXCloseDisplay)(Display*) = FF_LIBRARY_LOAD_SYMBOL(x11, "XCloseDisplay");
FF_LIBRARY_LOAD(x11, "libX11.so", instance->config.libX11, false)
FF_LIBRARY_LOAD_SYMBOL(x11, XOpenDisplay, false)
FF_LIBRARY_LOAD_SYMBOL(x11, XCloseDisplay, false)
Display* display = ffXOpenDisplay(x11);
if(display == NULL)
@@ -188,17 +174,18 @@ static bool printResolutionX11Backend(FFinstance* instance)
typedef struct XrandrData
{
XRRScreenConfiguration*(*ffXRRGetScreenInfo)(Display* display, Window window);
short(*ffXRRConfigCurrentRate)(XRRScreenConfiguration* config);
XRRMonitorInfo*(*ffXRRGetMonitors)(Display* display, Window window, Bool getActive, int* nmonitors);
XRRScreenResources*(*ffXRRGetScreenResources)(Display* display, Window window);
XRROutputInfo*(*ffXRRGetOutputInfo)(Display* display, XRRScreenResources* resources, RROutput output);
XRRCrtcInfo*(*ffXRRGetCrtcInfo)(Display* display, XRRScreenResources* resources, RRCrtc crtc);
void(*ffXRRFreeCrtcInfo)(XRRCrtcInfo* crtcInfo);
void(*ffXRRFreeOutputInfo)(XRROutputInfo* outputInfo);
void(*ffXRRFreeScreenResources)(XRRScreenResources* resources);
void(*ffXRRFreeMonitors)(XRRMonitorInfo* monitors);
void(*ffXRRFreeScreenConfigInfo)(XRRScreenConfiguration* config);
FF_LIBRARY_SYMBOL(XRRGetScreenInfo)
FF_LIBRARY_SYMBOL(XRRConfigCurrentConfiguration)
FF_LIBRARY_SYMBOL(XRRConfigCurrentRate)
FF_LIBRARY_SYMBOL(XRRGetMonitors)
FF_LIBRARY_SYMBOL(XRRGetScreenResources)
FF_LIBRARY_SYMBOL(XRRGetOutputInfo)
FF_LIBRARY_SYMBOL(XRRGetCrtcInfo)
FF_LIBRARY_SYMBOL(XRRFreeCrtcInfo)
FF_LIBRARY_SYMBOL(XRRFreeOutputInfo)
FF_LIBRARY_SYMBOL(XRRFreeScreenResources)
FF_LIBRARY_SYMBOL(XRRFreeMonitors)
FF_LIBRARY_SYMBOL(XRRFreeScreenConfigInfo)
//Init once
Display* display;
@@ -331,24 +318,24 @@ static void xrandrHandleScreen(XrandrData* data, Screen* screen)
static bool printResolutionXrandrBackend(FFinstance* instance)
{
DynamicLibrary xrandr = FF_LIBRARY_LOAD(instance->config.libXrandr, "libXrandr.so");
FF_LIBRARY_LOAD(xrandr, "libXrandr.so", instance->config.libXrandr, false);
Display*(*ffXOpenDisplay)(const char*) = FF_LIBRARY_LOAD_SYMBOL(xrandr, "XOpenDisplay");
int(*ffXCloseDisplay)(Display*) = FF_LIBRARY_LOAD_SYMBOL(xrandr, "XCloseDisplay");
FF_LIBRARY_LOAD_SYMBOL(xrandr, XOpenDisplay, false)
FF_LIBRARY_LOAD_SYMBOL(xrandr, XCloseDisplay, false)
XrandrData data;
data.ffXRRGetScreenInfo = FF_LIBRARY_LOAD_SYMBOL(xrandr, "XRRGetScreenInfo");
data.ffXRRConfigCurrentRate = FF_LIBRARY_LOAD_SYMBOL(xrandr, "XRRConfigCurrentRate");
data.ffXRRGetMonitors = FF_LIBRARY_LOAD_SYMBOL(xrandr, "XRRGetMonitors");
data.ffXRRGetScreenResources = FF_LIBRARY_LOAD_SYMBOL(xrandr, "XRRGetScreenResources");
data.ffXRRGetOutputInfo = FF_LIBRARY_LOAD_SYMBOL(xrandr, "XRRGetOutputInfo");
data.ffXRRGetCrtcInfo = FF_LIBRARY_LOAD_SYMBOL(xrandr, "XRRGetCrtcInfo");
data.ffXRRFreeCrtcInfo = FF_LIBRARY_LOAD_SYMBOL(xrandr, "XRRFreeCrtcInfo");
data.ffXRRFreeOutputInfo = FF_LIBRARY_LOAD_SYMBOL(xrandr, "XRRFreeOutputInfo");
data.ffXRRFreeScreenResources = FF_LIBRARY_LOAD_SYMBOL(xrandr, "XRRFreeScreenResources");
data.ffXRRFreeMonitors = FF_LIBRARY_LOAD_SYMBOL(xrandr, "XRRFreeMonitors");
data.ffXRRFreeScreenConfigInfo = FF_LIBRARY_LOAD_SYMBOL(xrandr, "XRRFreeScreenConfigInfo");
FF_LIBRARY_LOAD_SYMBOL_ADRESS(xrandr, data.ffXRRGetScreenInfo, XRRGetScreenInfo, false)
FF_LIBRARY_LOAD_SYMBOL_ADRESS(xrandr, data.ffXRRConfigCurrentRate, XRRConfigCurrentRate, false);
FF_LIBRARY_LOAD_SYMBOL_ADRESS(xrandr, data.ffXRRGetMonitors, XRRGetMonitors, false);
FF_LIBRARY_LOAD_SYMBOL_ADRESS(xrandr, data.ffXRRGetScreenResources, XRRGetScreenResources, false);
FF_LIBRARY_LOAD_SYMBOL_ADRESS(xrandr, data.ffXRRGetOutputInfo, XRRGetOutputInfo, false);
FF_LIBRARY_LOAD_SYMBOL_ADRESS(xrandr, data.ffXRRGetCrtcInfo, XRRGetCrtcInfo, false);
FF_LIBRARY_LOAD_SYMBOL_ADRESS(xrandr, data.ffXRRFreeCrtcInfo, XRRFreeCrtcInfo, false);
FF_LIBRARY_LOAD_SYMBOL_ADRESS(xrandr, data.ffXRRFreeOutputInfo, XRRFreeOutputInfo, false);
FF_LIBRARY_LOAD_SYMBOL_ADRESS(xrandr, data.ffXRRFreeScreenResources, XRRFreeScreenResources, false);
FF_LIBRARY_LOAD_SYMBOL_ADRESS(xrandr, data.ffXRRFreeMonitors, XRRFreeMonitors, false);
FF_LIBRARY_LOAD_SYMBOL_ADRESS(xrandr, data.ffXRRFreeScreenConfigInfo, XRRFreeScreenConfigInfo, false);
data.display = ffXOpenDisplay(NULL);
if(data.display == NULL)
@@ -376,9 +363,9 @@ typedef struct WaylandData
{
FFinstance* instance;
FFlist results;
struct wl_proxy*(*ffwl_proxy_marshal_constructor_versioned)(struct wl_proxy*, uint32_t, const struct wl_interface*, uint32_t, ...);
int(*ffwl_proxy_add_listener)(struct wl_proxy*, void (**)(void), void *data);
void(*ffwl_proxy_destroy)(struct wl_proxy*);
FF_LIBRARY_SYMBOL(wl_proxy_marshal_constructor_versioned)
FF_LIBRARY_SYMBOL(wl_proxy_add_listener)
FF_LIBRARY_SYMBOL(wl_proxy_destroy)
const struct wl_interface* ffwl_output_interface;
struct wl_output_listener output_listener;
} WaylandData;
@@ -453,21 +440,21 @@ static bool printResolutionWaylandBackend(FFinstance* instance)
if(sessionType != NULL && strcasecmp(sessionType, "wayland") != 0)
return false;
DynamicLibrary wayland = FF_LIBRARY_LOAD(instance->config.libWayland, "libwayland-client.so");
FF_LIBRARY_LOAD(wayland, "libwayland-client.so", instance->config.libWayland, false);
struct wl_display*(*ffwl_display_connect)(const char*) = FF_LIBRARY_LOAD_SYMBOL(wayland, "wl_display_connect");
int(*ffwl_display_dispatch)(struct wl_display*) = FF_LIBRARY_LOAD_SYMBOL(wayland, "wl_display_dispatch");
void(*ffwl_display_roundtrip)(struct wl_display*) = FF_LIBRARY_LOAD_SYMBOL(wayland, "wl_display_roundtrip");
struct wl_proxy*(*ffwl_proxy_marshal_constructor)(struct wl_proxy*, uint32_t, const struct wl_interface*, ...) = FF_LIBRARY_LOAD_SYMBOL(wayland, "wl_proxy_marshal_constructor");
const struct wl_interface* ffwl_registry_interface = FF_LIBRARY_LOAD_SYMBOL(wayland, "wl_registry_interface");
void(*ffwl_display_disconnect)(struct wl_display*) = FF_LIBRARY_LOAD_SYMBOL(wayland, "wl_display_disconnect");
FF_LIBRARY_LOAD_SYMBOL(wayland, wl_display_connect, false)
FF_LIBRARY_LOAD_SYMBOL(wayland, wl_display_dispatch, false)
FF_LIBRARY_LOAD_SYMBOL(wayland, wl_display_roundtrip, false)
FF_LIBRARY_LOAD_SYMBOL(wayland, wl_proxy_marshal_constructor, false)
FF_LIBRARY_LOAD_SYMBOL(wayland, wl_display_disconnect, false)
FF_LIBRARY_LOAD_SYMBOL(wayland, wl_registry_interface, false)
WaylandData data;
data.ffwl_proxy_marshal_constructor_versioned = FF_LIBRARY_LOAD_SYMBOL(wayland, "wl_proxy_marshal_constructor_versioned");
data.ffwl_proxy_add_listener = FF_LIBRARY_LOAD_SYMBOL(wayland, "wl_proxy_add_listener");
data.ffwl_output_interface = FF_LIBRARY_LOAD_SYMBOL(wayland, "wl_output_interface");
data.ffwl_proxy_destroy = FF_LIBRARY_LOAD_SYMBOL(wayland, "wl_proxy_destroy");
FF_LIBRARY_LOAD_SYMBOL_ADRESS(wayland, data.ffwl_proxy_marshal_constructor_versioned, wl_proxy_marshal_constructor_versioned, false)
FF_LIBRARY_LOAD_SYMBOL_ADRESS(wayland, data.ffwl_proxy_add_listener, wl_proxy_add_listener, false)
FF_LIBRARY_LOAD_SYMBOL_ADRESS(wayland, data.ffwl_output_interface, wl_output_interface, false)
FF_LIBRARY_LOAD_SYMBOL_ADRESS(wayland, data.ffwl_proxy_destroy, wl_proxy_destroy, false)
struct wl_display* display = ffwl_display_connect(NULL);
if(display == NULL)