1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
|
#include <dlfcn.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/wait.h>
#define VERSION_LEN 10
#define FORMAT EPREFIX PLUGIN_DIR "/kpython%spluginfactory.so"
static void *handle;
static void *(*wrapped_qt_plugin_instance)();
static void get_python_version(char* out) {
int pipefd[2];
pipe(pipefd);
pid_t cpid = fork();
if (cpid > 0) {
close(pipefd[1]);
read(pipefd[0], out, VERSION_LEN);
close(pipefd[0]);
waitpid(cpid, NULL, 0);
} else if (cpid < 0) {
/* fork failed, guess 2.7 */
strcpy(out, "2.7\n");
close(pipefd[0]);
close(pipefd[1]);
} else {
close(pipefd[0]);
close(1);
dup2(pipefd[1], 1);
close(pipefd[1]);
close(0);
char *args[] = { "eselect", "python", "show", "--ABI", "--python2", 0 };
execv(EPREFIX "/usr/bin/eselect", args);
/* exec failed, guess 2.7 */
write(1, "2.7\n", 4);
exit(0);
}
}
__attribute__((constructor))
static void init() {
char buf[VERSION_LEN + 1];
memset(buf, 0, VERSION_LEN + 1);
get_python_version(buf);
char *s = buf;
while(*s != '\0') {
if(*s == '\n') {
*s = '\0';
break;
}
++s;
}
int length = strlen(FORMAT) + strlen(buf) + 1;
char *name = malloc(length + 1);
snprintf(name, length, FORMAT, buf);
handle = dlopen(name, RTLD_NOW);
free(name);
wrapped_qt_plugin_instance = dlsym(handle, "qt_plugin_instance");
}
__attribute__((destructor))
static void fini() {
dlclose(handle);
}
void *qt_plugin_instance() {
return wrapped_qt_plugin_instance();
}
|