1#include <stdlib.h>
2#include <string.h>
3#include <dlfcn.h>
4#include <assert.h>
5
6int main(int argc, char* argv[])
7{
8#if defined(__FreeBSD__)
9    // workaround for Bugzilla 14824
10    void *druntime = dlopen(argv[1], RTLD_LAZY); // load druntime
11    assert(druntime);
12#endif
13
14    const size_t pathlen = strrchr(argv[0], '/') - argv[0] + 1;
15    char *name = malloc(pathlen + sizeof("plugin1.so"));
16    memcpy(name, argv[0], pathlen);
17    memcpy(name+pathlen, "plugin1.so", sizeof("plugin1.so"));
18
19    void* plugin1 = dlopen(name, RTLD_LAZY);
20    name[pathlen + sizeof("plugin1.so") - 5] = '2';
21    void* plugin2 = dlopen(name, RTLD_LAZY);
22
23    int (*plugin1_init)() = dlsym(plugin1, "plugin_init");
24    int (*plugin1_term)() = dlsym(plugin1, "plugin_term");
25    int (*runTests1)() = dlsym(plugin1, "runTests");
26    int (*plugin2_init)() = dlsym(plugin2, "plugin_init");
27    int (*plugin2_term)() = dlsym(plugin2, "plugin_term");
28    int (*runTests2)() = dlsym(plugin2, "runTests");
29    assert(plugin1_init());
30    assert(runTests1());
31    assert(plugin2_init());
32    assert(runTests2());
33
34    assert(plugin1_term());
35    assert(dlclose(plugin1) == 0);
36    assert(runTests2());
37
38    name[pathlen + sizeof("plugin1.so") - 5] = '1';
39    plugin1 = dlopen(name, RTLD_LAZY);
40    plugin1_init = dlsym(plugin1, "plugin_init");
41    plugin1_term = dlsym(plugin1, "plugin_term");
42    runTests1 = dlsym(plugin1, "runTests");
43    assert(plugin1_init());
44    assert(runTests1());
45    assert(runTests2());
46
47    assert(plugin2_term());
48    assert(dlclose(plugin2) == 0);
49    assert(runTests1());
50
51    assert(plugin1_term());
52    assert(dlclose(plugin1) == 0);
53
54    free(name);
55
56#if defined(__FreeBSD__)
57    dlclose(druntime);
58#endif
59    return EXIT_SUCCESS;
60}
61