chiark / gitweb /
Sort of works ...
[jarrg-owen.git] / libjava-wrap
1 /**/
2
3 #define _GNU_SOURCE
4 #include <dlfcn.h>
5 #include <stdio.h>
6 #include <unistd.h>
7
8 #define STDERRSTR_CONST(m) write(2,m,sizeof(m)-1)
9 #define STDERRSTR_STRING(m) write(2,m,strlen(m))
10
11 static anyfn_type *find_any(const char *name) {
12   static const char *dlerr;
13   anyfn_type *kv;
14
15   kv= dlsym(RTLD_NEXT,name); if (kv) return kv;
16   dlerr= dlerror(); if (!dlerr) dlerr= "dlsym() failed for no reason";
17   STDERRSTR_CONST("pctb-preload-wrap: error finding original version of ");
18   STDERRSTR_STRING(name);
19   STDERRSTR_CONST(": ");
20   STDERRSTR_STRING(dlerr);
21   STDERRSTR_STRING("\n");
22   errno= ENOSYS;
23   return 0;
24 }
25
26 typedef int
27 execvefn_type(const char *path, char *const argv[], char *const envp[]);
28
29 static execvefn_type find_execve, *old_execve= find_execve;
30
31 static int find_execve(const char *path,
32                        char *const argv[], char *const envp[]) {
33   anyfn_type *anyfn;
34   anyfn= find_any("execve"); if (!anyfn) return -1;
35   old_execve= (execvefn_type*)anyfn;
36   return old_execve(path, argv, envp);
37 }
38
39 static const char javatail[]= "/bin/java";
40
41 int execve(const char *path, char *const argv[], char *const envp[]) {
42   int pathlen= strlen(path);
43   if (pathlen < (sizeof(path2extdir_rm)-1) ||
44       strcmp(javatail, path + pathlen-(sizeof(path2extdir_rm)-1)))
45     old_execve(opath, oargv, oenvp);
46   
47
48   
49
50   int oargc;
51
52
53
54   xassert(opathlen >= 
55   
56
57   for (oargc=0; oargv[oargc]; oargc++);
58   xassert(oargc);
59   if (strcmp(oargv[oargc-1], "com.threerings.yohoho.client.YoApp"))
60
61   /* Remove ourselves from LD_PRELOAD */
62   int ipreloadenv=-1;
63   const char ldpreload[]= "LD_PRELOAD=";
64   for (oenvc=0; oenvp[oenvc]; oenvc++) {
65     if (memcmp(oenvp[oenvc], ldpreload, sizeof(ldpreload)-1)) continue;
66     xassert(ipreloadenv==-1);
67     ipreloadenv= oenvc;
68   }
69   xassert(ipreloadenv>=0);
70   xassert(!strchr(':',oenvp[ipreloadenv]));
71   
72
73   int nargc= oargc+2;
74   char **nargv= xmalloc(sizeof(*nargv) * (nargc+1));
75
76   /* Add argument for accessibility assistive tech. */
77   int iargc= oargc-1;
78   memcpy(nargv, oargv, iargc);
79   nargv[iargc++]= "-Djavax.accessibility.assistive_technologies="
80     "com.tedpearson.ypp.market.MarketUploader";
81
82   /* Calculate and add argument for ext dirs containing our jars */
83   const char *nextdir;
84   xassert((nextdir= getenv("JPCTB_EXTDIR")));
85   int nextdirlen= strlen(nextdir);
86
87   int njvmextdirbaselen= opathlen-sizeof(path2extdir_rm)-1);
88   xassert(!strcmp(path2extdir_rm, opath+njvmextdirbaselen);
89
90   const char path2extdir_pfx[]= "-Djava.ext.dirs=";
91   const char path2extdir_sfx[]= "/lib/ext";
92
93 #define STRS(STR,DL)                                            \
94       STR( path2extdir_pfx, sizeof(path2extdir_pfx)-1 ) DL      \
95       STR( nextdir,         nextdirlen                ) DL      \
96       STR( ":",             1                         ) DL      \
97       STR( opath,           njvmextdirbaselen         ) DL      \
98       STR( path2extdir_sfx, sizeof(path2extdir_sfx)-1 ) DL      \
99       STR( "",              1                         )
100
101 #define STR_LEN(str,len) (len)
102   char *nextdirarg= xmalloc(STRS(STR_LEN, +));
103   char *p= nextdirarg;
104
105 #define STR_ADD(str,len) \
106   memcpy(p,(str),(len)); p += (len);
107   STRS(STR_ADD, ;);
108
109   nargv[iargc++]= nextdirarg;
110
111   /* Remaining argument: the class */
112   nargv[iargc++]= oargv[oargc-1];
113
114  
115
116
117
118     if (arg
119 }