13 #define STDERRSTR_CONST(m) write(2,m,sizeof(m)-1)
14 #define STDERRSTR_STRING(m) write(2,m,strlen(m))
16 #define QUIS "libjwrap"
18 typedef void anyfn_type(void);
20 static anyfn_type *find_any(const char *name) {
21 static const char *dlerr;
24 kv= dlsym(RTLD_NEXT,name); if (kv) return kv;
25 dlerr= dlerror(); if (!dlerr) dlerr= "dlsym() failed for no reason";
26 STDERRSTR_CONST(QUIS ": error finding original version of ");
27 STDERRSTR_STRING(name);
28 STDERRSTR_CONST(": ");
29 STDERRSTR_STRING(dlerr);
30 STDERRSTR_CONST("\n");
36 #define REIMPLEMENTWRAP(FN, ARGS_DECL, ARGS_USE) \
38 typedef int FN##_type ARGS_DECL; \
40 static FN##_type find_##FN, *old_##FN= find_##FN; \
42 static int find_##FN ARGS_DECL { \
44 anyfn= find_any(# FN); if (!anyfn) return -1; \
45 old_##FN= (FN##_type*)anyfn; \
46 return old_##FN ARGS_USE; \
53 static const char javatail[]= "/bin/java";
55 REIMPLEMENTWRAP(execve,
56 (const char *path, char *const oargv[], char *const envp[]),
57 (path, oargv, envp)) {
59 for (oargc=0; oargv[oargc]; oargc++);
61 if (!strcmp(path,"/dev/jwrap/bypass")) {
62 //STDERRSTR_CONST(QUIS ": bypass\n");
64 char **nargv= malloc(sizeof(*nargv) * nargc); if (!nargv) return -1;
66 memcpy(nargv+1, oargv+2, sizeof(*nargv) * nargc-1);
67 return old_execve(oargv[1], nargv, envp);
70 int pathlen= strlen(path);
72 pathlen < (sizeof(javatail)-1) ||
73 strcmp(javatail, path + pathlen-(sizeof(javatail)-1))) {
74 //STDERRSTR_CONST(QUIS ": non-java\n");
75 return old_execve(path, oargv, envp);
78 //STDERRSTR_CONST(QUIS ": ours\n");
81 if (stat(path,&stab)) return -1;
84 char **nargv= malloc(sizeof(*nargv) * nargc); if (!nargv) return -1;
86 const char *jwrap_script= getenv("JWRAP_SCRIPT");
88 STDERRSTR_CONST(QUIS ": no JWRAP_SCRIPT specified!\n");
93 nargv[0]= (char*)jwrap_script;
94 nargv[1]= (char*)path;
95 memcpy(nargv+2, oargv, sizeof(*nargv) * (oargc+1));
97 old_execve(nargv[0], nargv, envp);
100 const char *errstr= strerror(e);
101 STDERRSTR_CONST(QUIS ": failed to execute ");
102 STDERRSTR_STRING(jwrap_script);
103 STDERRSTR_CONST(": ");
104 STDERRSTR_STRING(errstr);
105 STDERRSTR_CONST("\n");
111 int execv(const char *path, char *const argv[]) {
112 return execve(path, argv, environ);
116 static int execvep(const char *path, char *const argv[], char *const envp[]) {
118 * libc binds strongly to its own execve.
119 * That means we need to reimplement exec*p.
120 * (Also for some mysterious reason there is no standard execvep
121 * and no standard execlep)
123 if (strchr(path,'/')) return execve(path,argv,envp);
125 int pathlen= strlen(path);
129 const char *searchpath= getenv("PATH");
131 const char *colon= strchr(searchpath,':');
132 int entrylen= colon ? colon - searchpath : strlen(searchpath);
137 int trylen= entrylen + 1 + pathlen + 1;
138 if (trylen > buflen) {
144 memcpy(buf, searchpath, entrylen);
146 strcpy(buf+entrylen+1, path);
149 execve(try, argv, envp);
158 static int execl_corev(int e, int p,
159 const char *path, const char *arg0, va_list al) {
165 while ((arg= va_arg(countal, char*)))
169 char **argv= malloc(sizeof(*argv) * (argc+1));
171 argv[argc++]= (char*)arg0;
172 while ((arg= va_arg(al, char*)))
176 char **envp= e ? va_arg(al, char**) : environ;
178 if (p) return execvep(path, argv, envp);
179 else return execve(path, argv, envp);
183 #define REIMPLEMENTLCOREV(FN,E,P) \
184 int FN(const char *path, const char *arg, ...) { \
187 execl_corev(E,P,path,arg,al); \
192 REIMPLEMENTLCOREV( execl, 0,0 )
193 REIMPLEMENTLCOREV( execle, 1,0 )
194 REIMPLEMENTLCOREV( execlp, 0,1 )