X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~yarrgweb/git?a=blobdiff_plain;f=libjwrap.c;fp=libjwrap.c;h=0000000000000000000000000000000000000000;hb=f990674d59428070dc501681c7fafd6a2e7e07d7;hp=23ee7d6ec16eddb83f93cee5408c721ae0fd0e10;hpb=801ee8fc524bfda06f4bbfbec51caf228258d3fe;p=jarrg-owen.git diff --git a/libjwrap.c b/libjwrap.c deleted file mode 100644 index 23ee7d6..0000000 --- a/libjwrap.c +++ /dev/null @@ -1,194 +0,0 @@ -/**/ - -#define _GNU_SOURCE -#include -#include -#include -#include -#include -#include -#include -#include - -#define STDERRSTR_CONST(m) write(2,m,sizeof(m)-1) -#define STDERRSTR_STRING(m) write(2,m,strlen(m)) - -#define QUIS "libjwrap" - -typedef void anyfn_type(void); - -static anyfn_type *find_any(const char *name) { - static const char *dlerr; - anyfn_type *kv; - - kv= dlsym(RTLD_NEXT,name); if (kv) return kv; - dlerr= dlerror(); if (!dlerr) dlerr= "dlsym() failed for no reason"; - STDERRSTR_CONST(QUIS ": error finding original version of "); - STDERRSTR_STRING(name); - STDERRSTR_CONST(": "); - STDERRSTR_STRING(dlerr); - STDERRSTR_CONST("\n"); - errno= ENOSYS; - return 0; -} - - -#define REIMPLEMENTWRAP(FN, ARGS_DECL, ARGS_USE) \ - \ - typedef int FN##_type ARGS_DECL; \ - \ - static FN##_type find_##FN, *old_##FN= find_##FN; \ - \ - static int find_##FN ARGS_DECL { \ - anyfn_type *anyfn; \ - anyfn= find_any(# FN); if (!anyfn) return -1; \ - old_##FN= (FN##_type*)anyfn; \ - return old_##FN ARGS_USE; \ - } \ - \ - int FN ARGS_DECL - - - -static const char javatail[]= "/bin/java"; - -REIMPLEMENTWRAP(execve, - (const char *path, char *const oargv[], char *const envp[]), - (path, oargv, envp)) { - int oargc; - for (oargc=0; oargv[oargc]; oargc++); - - if (!strcmp(path,"/dev/jwrap/bypass")) { - //STDERRSTR_CONST(QUIS ": bypass\n"); - int nargc= oargc-1; - char **nargv= malloc(sizeof(*nargv) * nargc); if (!nargv) return -1; - nargv[0]= oargv[0]; - memcpy(nargv+1, oargv+2, sizeof(*nargv) * nargc-1); - return old_execve(oargv[1], nargv, envp); - } - - int pathlen= strlen(path); - if (!oargc || - pathlen < (sizeof(javatail)-1) || - strcmp(javatail, path + pathlen-(sizeof(javatail)-1))) { - //STDERRSTR_CONST(QUIS ": non-java\n"); - return old_execve(path, oargv, envp); - } - - //STDERRSTR_CONST(QUIS ": ours\n"); - - struct stat stab; - if (stat(path,&stab)) return -1; - - int nargc= oargc+2; - char **nargv= malloc(sizeof(*nargv) * nargc); if (!nargv) return -1; - - const char *jwrap_script= getenv("JWRAP_SCRIPT"); - if (!jwrap_script) { - STDERRSTR_CONST(QUIS ": no JWRAP_SCRIPT specified!\n"); - errno= ENOENT; - return -1; - } - - nargv[0]= (char*)jwrap_script; - nargv[1]= (char*)path; - memcpy(nargv+2, oargv, sizeof(*nargv) * (oargc+1)); - - old_execve(nargv[0], nargv, envp); - int e= errno; - - const char *errstr= strerror(e); - STDERRSTR_CONST(QUIS ": failed to execute "); - STDERRSTR_STRING(jwrap_script); - STDERRSTR_CONST(": "); - STDERRSTR_STRING(errstr); - STDERRSTR_CONST("\n"); - - errno= e; - return -1; -} - -int execv(const char *path, char *const argv[]) { - return execve(path, argv, environ); -} - - -static int execvep(const char *path, char *const argv[], char *const envp[]) { - /* How tiresome. - * libc binds strongly to its own execve. - * That means we need to reimplement exec*p. - * (Also for some mysterious reason there is no standard execvep - * and no standard execlep) - */ - if (strchr(path,'/')) return execve(path,argv,envp); - - int pathlen= strlen(path); - int buflen= 0; - char *buf= 0; - - const char *searchpath= getenv("PATH"); - for (;;) { - const char *colon= strchr(searchpath,':'); - int entrylen= colon ? colon - searchpath : strlen(searchpath); - const char *try; - if (entrylen) { - try= path; - } else { - int trylen= entrylen + 1 + pathlen + 1; - if (trylen > buflen) { - free(buf); - buf= malloc(trylen); - if (!buf) return -1; - buflen= trylen; - } - memcpy(buf, searchpath, entrylen); - buf[entrylen]= '/'; - strcpy(buf+entrylen+1, path); - try= buf; - } - execve(try, argv, envp); - if (errno != ENOENT) - return -1; - } - errno= ENOENT; - return -1; -} - - -static int execl_corev(int e, int p, - const char *path, const char *arg0, va_list al) { - char *arg; - va_list countal; - - va_copy(countal,al); - int argc=1; - while ((arg= va_arg(countal, char*))) - argc++; - va_end(countal); - - char **argv= malloc(sizeof(*argv) * (argc+1)); - argc=0; - argv[argc++]= (char*)arg0; - while ((arg= va_arg(al, char*))) - argv[argc++]= arg; - argv[argc]= 0; - - char **envp= e ? va_arg(al, char**) : environ; - - if (p) return execvep(path, argv, envp); - else return execve(path, argv, envp); -} - - -#define REIMPLEMENTLCOREV(FN,E,P) \ - int FN(const char *path, const char *arg, ...) { \ - va_list al; \ - va_start(al,arg); \ - execl_corev(E,P,path,arg,al); \ - va_end(al); \ - return -1; \ - } - -REIMPLEMENTLCOREV( execl, 0,0 ) -REIMPLEMENTLCOREV( execle, 1,0 ) -REIMPLEMENTLCOREV( execlp, 0,1 )