Mercurial > hg > svcore
diff system/System.cpp @ 1165:d57f9344db19
Check for plugin loadability before trying to load in the main process (POSIX only so far)
author | Chris Cannam |
---|---|
date | Mon, 11 Jan 2016 14:18:56 +0000 |
parents | b14064bd1f97 |
children | afed8be79032 |
line wrap: on
line diff
--- a/system/System.cpp Fri Jan 08 15:39:12 2016 +0000 +++ b/system/System.cpp Mon Jan 11 14:18:56 2016 +0000 @@ -325,3 +325,64 @@ double princarg(double a) { return mod(a + M_PI, -2 * M_PI) + M_PI; } float princargf(float a) { return float(princarg(a)); } +#ifndef _WIN32 + +#include <unistd.h> +#include <sys/wait.h> + +PluginLoadStatus +TestPluginLoadability(QString soname, QString descriptorFn) +{ + //!!! This is POSIX only, no equivalent on Windows, where we'll + //!!! have to do something completely different + + pid_t pid = fork(); + + if (pid < 0) { + return UnknownPluginLoadStatus; // fork failed + } + + if (pid == 0) { // the child process + + void *handle = DLOPEN(soname, RTLD_NOW | RTLD_LOCAL); + if (!handle) { + cerr << "isPluginLibraryLoadable: Failed to open plugin library \"" + << soname << "\": " << dlerror() << "\n"; + cerr << "exiting with status 1" << endl; + exit(1); + } + + void *fn = DLSYM(handle, descriptorFn.toLocal8Bit().data()); + if (!fn) { + cerr << "isPluginLibraryLoadable: Failed to find plugin descriptor function \"" << descriptorFn << "\" in library \"" << soname << "\": " << dlerror() << "\n"; + exit(2); + } + + exit(0); + + } else { // the parent process + + int status = 0; + + do { + waitpid(pid, &status, 0); + } while (WIFSTOPPED(status)); + + if (WIFEXITED(status)) { + switch (WEXITSTATUS(status)) { + case 0: return PluginLoadOK; // success + case 1: return PluginLoadFailedToLoadLibrary; + case 2: return PluginLoadFailedToFindDescriptor; + default: return PluginLoadFailedElsewhere; + } + } + + if (WIFSIGNALED(status)) { + return PluginLoadFailedElsewhere; + } + + return UnknownPluginLoadStatus; + } +} + +#endif