Mercurial > hg > vamp-plugin-load-checker
diff src/helper.cpp @ 8:25e00373f597
Much renaming to ease inclusion into another project
author | Chris Cannam |
---|---|
date | Thu, 14 Apr 2016 16:52:19 +0100 |
parents | helper.cpp@61dbb18f2369 |
children | c7baebf68fac |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/helper.cpp Thu Apr 14 16:52:19 2016 +0100 @@ -0,0 +1,130 @@ +/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ + +/** + * Plugin Load Checker Helper + * + * This program accepts the name of a descriptor symbol as its only + * command-line argument. It then reads a list of plugin library paths + * from stdin, one per line. For each path read, it attempts to load + * that library and retrieve the named descriptor symbol, printing a + * line to stdout reporting whether this was successful or not and + * then flushing stdout. The output line format is described + * below. The program exits with code 0 if all libraries were loaded + * successfully and non-zero otherwise. + * + * Note that library paths must be ready to pass to dlopen() or + * equivalent; this usually means they should be absolute paths. + * + * Output line for successful load of library libname.so: + * SUCCESS|/path/to/libname.so| + * + * Output line for failed load of library libname.so: + * FAILURE|/path/to/libname.so|Reason for failure if available + * + * Sometimes plugins will crash completely on load, bringing down this + * program with them. If the program exits before all listed plugins + * have been checked, this means that the plugin following the last + * reported one has crashed. Typically the caller may want to run it + * again, omitting that plugin. + */ + +/* + Copyright (c) 2016 Queen Mary, University of London + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, copy, + modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + Except as contained in this notice, the names of the Centre for + Digital Music and Queen Mary, University of London shall not be + used in advertising or otherwise to promote the sale, use or other + dealings in this Software without prior written authorization. +*/ + +#ifdef _WIN32 +#include <windows.h> +#include <process.h> +#define DLOPEN(a,b) LoadLibrary((a).toStdWString().c_str()) +#define DLSYM(a,b) GetProcAddress((HINSTANCE)(a),(b)) +#define DLCLOSE(a) (!FreeLibrary((HINSTANCE)(a))) +#define DLERROR() "" +#else +#include <dlfcn.h> +#define DLOPEN(a,b) dlopen((a).c_str(),(b)) +#define DLSYM(a,b) dlsym((a),(b).c_str()) +#define DLCLOSE(a) dlclose((a)) +#define DLERROR() dlerror() +#endif + +#include <string> +#include <iostream> + +#include <unistd.h> + +using namespace std; + +string error() +{ + string e = dlerror(); + if (e == "") return "(unknown error)"; + else return e; +} + +string check(string soname, string descriptor) +{ + void *handle = DLOPEN(soname, RTLD_NOW | RTLD_LOCAL); + if (!handle) { + return "Unable to open plugin library: " + error(); + } + + void *fn = DLSYM(handle, descriptor); + if (!fn) { + return "Failed to find plugin descriptor " + descriptor + + " in library: " + error(); + } + + return ""; +} + +int main(int argc, char **argv) +{ + bool allGood = true; + string soname; + + if (argc != 2) { + cerr << "\nUsage:\n " << argv[0] << " descriptorname\n" + "\nwhere descriptorname is the name of a plugin descriptor symbol to be sought\n" + "in each library (e.g. vampGetPluginDescriptor for Vamp plugins). The list of\n" + "candidate plugin library filenames is read from stdin.\n" << endl; + return 2; + } + + string descriptor = argv[1]; + + while (getline(cin, soname)) { + string report = check(soname, descriptor); + if (report != "") { + cout << "FAILURE|" << soname << "|" << report << endl; + allGood = false; + } else { + cout << "SUCCESS|" << soname << "|" << endl; + } + } + + return allGood ? 0 : 1; +}