comparison 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
comparison
equal deleted inserted replaced
1164:0f90a357cb2a 1165:d57f9344db19
323 float modf(float x, float y) { return x - (y * floorf(x / y)); } 323 float modf(float x, float y) { return x - (y * floorf(x / y)); }
324 324
325 double princarg(double a) { return mod(a + M_PI, -2 * M_PI) + M_PI; } 325 double princarg(double a) { return mod(a + M_PI, -2 * M_PI) + M_PI; }
326 float princargf(float a) { return float(princarg(a)); } 326 float princargf(float a) { return float(princarg(a)); }
327 327
328 #ifndef _WIN32
329
330 #include <unistd.h>
331 #include <sys/wait.h>
332
333 PluginLoadStatus
334 TestPluginLoadability(QString soname, QString descriptorFn)
335 {
336 //!!! This is POSIX only, no equivalent on Windows, where we'll
337 //!!! have to do something completely different
338
339 pid_t pid = fork();
340
341 if (pid < 0) {
342 return UnknownPluginLoadStatus; // fork failed
343 }
344
345 if (pid == 0) { // the child process
346
347 void *handle = DLOPEN(soname, RTLD_NOW | RTLD_LOCAL);
348 if (!handle) {
349 cerr << "isPluginLibraryLoadable: Failed to open plugin library \""
350 << soname << "\": " << dlerror() << "\n";
351 cerr << "exiting with status 1" << endl;
352 exit(1);
353 }
354
355 void *fn = DLSYM(handle, descriptorFn.toLocal8Bit().data());
356 if (!fn) {
357 cerr << "isPluginLibraryLoadable: Failed to find plugin descriptor function \"" << descriptorFn << "\" in library \"" << soname << "\": " << dlerror() << "\n";
358 exit(2);
359 }
360
361 exit(0);
362
363 } else { // the parent process
364
365 int status = 0;
366
367 do {
368 waitpid(pid, &status, 0);
369 } while (WIFSTOPPED(status));
370
371 if (WIFEXITED(status)) {
372 switch (WEXITSTATUS(status)) {
373 case 0: return PluginLoadOK; // success
374 case 1: return PluginLoadFailedToLoadLibrary;
375 case 2: return PluginLoadFailedToFindDescriptor;
376 default: return PluginLoadFailedElsewhere;
377 }
378 }
379
380 if (WIFSIGNALED(status)) {
381 return PluginLoadFailedElsewhere;
382 }
383
384 return UnknownPluginLoadStatus;
385 }
386 }
387
388 #endif