chiark / gitweb /
new wrapper script actually works
authorIan Jackson <ian@liberator.relativity.greenend.org.uk>
Sun, 1 Nov 2009 22:43:26 +0000 (22:43 +0000)
committerIan Jackson <ian@liberator.relativity.greenend.org.uk>
Sun, 1 Nov 2009 22:43:26 +0000 (22:43 +0000)
  ian@liberator:~$ ~/Pctb-java/linkfarmer/jpctb ~/Pctb-java/installer-unpacked yohoho/yohoho
jpctb:
   jpctb tree:   "/home/ian/Pctb-java/linkfarmer"
   yohoho:       "yohoho/yohoho"
   java:         "/home/ian/yohoho/java"
   PCTB jars:    "/home/ian/Pctb-java/installer-unpacked"
   jpctb tmpdir: "/home/ian/Pctb-java/linkfarmer/tmp"

.gitignore
Makefile [deleted file]
jpctb
jwrap-script-jpctb [deleted file]
libjwrap.c [deleted file]

index b1e012f..a393599 100644 (file)
@@ -2,3 +2,4 @@
 *.o
 *.so
 *.so.*
+tmp
diff --git a/Makefile b/Makefile
deleted file mode 100644 (file)
index 0b52505..0000000
--- a/Makefile
+++ /dev/null
@@ -1,26 +0,0 @@
-OPTIMISE=      -O2
-LDFLAGS=       -g
-LIBS=          -ldl -lc
-CFLAGS=                -g $(OPTIMISE) \
-               -Wall -Wwrite-strings -Wpointer-arith -Wimplicit \
-               -Wnested-externs -Wmissing-prototypes -Wstrict-prototypes
-CPPFLAGS=
-
-MAJOR=1
-MINOR=0
-LIBCANON=      libjwrap.so.$(MAJOR)
-LIBTARGET=     $(LIBCANON).$(MINOR)
-
-TARGETS=                $(LIBTARGET)
-
-all:                    $(TARGETS)
-
-
-$(LIBTARGET):          libjwrap.o
-               ld -shared -soname $(LIBCANON) -o $@ $< $(LIBS)
-
-libjwrap.o:          libjwrap.c
-               $(CC) -D_REENTRANT $(CFLAGS) $(CPPFLAGS) -c -o $@ -fPIC $<
-
-clean:
-               rm -f *.o $(TARGETS) *~
diff --git a/jpctb b/jpctb
index c50b43b..a2cb243 100755 (executable)
--- a/jpctb
+++ b/jpctb
@@ -4,15 +4,116 @@ usage: .../jpctb /path/to/dir/with/PCTB*.jar /path/to/yohoho/yohoho [...]
 END
 }
 
-jpctb_base="$0"
-jpctb_base="${jpctb_base%/*}"
+fail () {
+       echo >&2 "jpctb: $*"
+       exit 127
+}
+
+if [ $# -lt 2 ]; then usage; fail 'bad usage'; exit 127; fi
+
+srcjardir="$1"; shift
+yohoho="$1"; shift
+
+#---------- find ourselves ----------
+
+jpctbdir="$0"
+jpctbdir="${jpctbdir%/*}"
+
+case "$jpctbdir" in
+/*)    ;;
+*)     jpctbdir="$PWD/$jpctbdir" ;;
+esac
+
+#---------- find YPP client and the Java installation it uses ----------
+
+yppdir="${yohoho%/*}"
+
+if [ -x "$yppdir/java/bin/java" ]; then
+       javadir="$yppdir/java"
+elif [ x"$JAVA_HOME" != x ] && [ -x "$JAVA_HOME/bin/java" ]; then
+       javadir="$JAVA_HOME"
+else
+       fail "could not find java runtime system"
+fi
+
+case "$javadir" in
+/*)    ;;
+*)     javadir="$PWD/$javadir" ;;
+esac
+
+jtmp="$jpctbdir/tmp"
+linkfarm="$jtmp/linkfarm"
+extdir="$jtmp/ext"
+
+#---------- confirm for the user which paths we're using ----------
+
+cat <<END
+jpctb:
+   jpctb tree:  "$jpctbdir"
+   yohoho:       "$yohoho"
+   java:         "$javadir"
+   PCTB jars:    "$srcjardir"
+   jpctb tmpdir: "$jtmp"
+END
+
+#---------- create the temporary are and link farm ----------
+
+rm -rf -- "$jtmp"
+mkdir -- "$jtmp" "$extdir" "$linkfarm"
+cp "$srcjardir"/PCTB*.jar "$extdir"
 
-if [ $# -lt 2 ]; then usage >&2; exit 127; fi
+lndir -silent "$javadir" "$linkfarm"
+
+#---------- edit the linkfarm to have our jvm wrapper ----------
+
+wrapper="$linkfarm"/jre/bin/java
+rm -- "$wrapper"
+
+export JPCTB_EXTDIR="$extdir"
+export JPCTB_JRE="$javadir/jre"
+
+cat <<'END' >"$wrapper"
+#!/bin/bash
+       set -e$JPCTB_JWRAP_X
+
+       log () {
+               lh=`date +'%Y/%m/%d %H:%M:%S jpctb'`
+               printf >&2 "%s: %s |\f\n" "$lh" "$*"
+       }
+
+       log "invoked as $*"
+
+#echo >&2 "$djava-wrap 
+#exec 4>>/home/ian/u
+#date >&4
+#exec 4>&-
+
+       yppclass=com.threerings.yohoho.client.YoApp
+       atclass=com.tedpearson.ypp.market.MarketUploader
+
+       args=( "$@" )
+       nargs=${#args[*]}
+       lastarg="${args[$(( $nargs - 1 ))]}"
+
+       fail () { echo >&2 "jpctb-java: $*"; exit 127; }
+
+       if [ x"$lastarg" = x"$yppclass" ]; then
+
+               [ x"$JPCTB_EXTDIR" != x ] || fail 'JPCTB_EXTDIR not set'
+
+               set     -e$JPCTB_JWRAP_X -- \
+                       -Djavax.accessibility.assistive_technologies=$atclass \
+                       -Djava.ext.dirs="$JPCTB_EXTDIR:$JPCTB_JRE/lib/ext" \
+                       "$@"
+       fi
+
+       real="$JPCTB_JRE/bin/java"
+       log "running $real $*"
+       exec "$real" "$@"
+END
 
-export JWRAP_EXTDIR="$1"; shift
-export JWRAP_SCRIPT="$jpctb_base/jwrap-script-jpctb"
+chmod +x -- "$wrapper"
 
-if [ x"$LD_PRELOAD" != x ]; then LD_PRELOAD="$LD_PRELOAD:"; fi
-export LD_PRELOAD="${LD_PRELOAD}$jpctb_base/libjwrap.so.1.0"
+#---------- now run it ----------
 
-exec "$@"
+exec "$yohoho" -Djava.home="$linkfarm/jre"
diff --git a/jwrap-script-jpctb b/jwrap-script-jpctb
deleted file mode 100755 (executable)
index 72aa83e..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-#!/bin/bash
-set -e$JWRAP_SCRIPT_X
-
-#exec 4>&2
-#exec 2>>/home/ian/u
-#date >&2
-
-unwire () {
-       ldp="$LD_PRELOAD:"
-       ldp2=''
-
-       while [ "x$ldp" != x ]; do
-               this="${ldp%%:*}"
-               ldp="${ldp#*:}"
-               case "$this" in
-               *libjwrap*.so.*)                                ;;
-               *)                      ldp2="$ldp2$this:"      ;;
-               esac
-       done
-
-       if [ "x$ldp2" != x ]; then
-               LD_PRELOAD="${ldp2%:}"
-       else
-               unset LD_PRELOAD
-       fi
-
-       unset JWRAP_SCRIPT
-}
-
-true jwrap-script-pctb: "$@"
-
-path="$1"; shift
-arg0="$1"; shift
-
-args=( "$@" )
-nargs=${#args[*]}
-lastarg="${args[$(( $nargs - 1 ))]}"
-
-fail () {
-       echo >&2 "jwrap-script: $*"
-       exit 127
-}
-
-if [ x"$lastarg" = x"com.threerings.yohoho.client.YoApp" ]; then
-       case "$path" in
-       */bin/java) ;;
-       *)      fail "unexpected path format $path" ;;
-       esac
-       [ x"$JWRAP_EXTDIR" != x ] || fail 'JWRAP_EXTDIR not set'
-       extdirs="$JWRAP_EXTDIR:${path%/bin/java}/lib/ext"
-
-       set     -e$JWRAP_SCRIPT_X -- \
-               -Djavax.accessibility.assistive_technologies=com.tedpearson.ypp.market.MarketUploader \
-               -Djava.ext.dirs="$extdirs" \
-               "$@"
-
-       unwire
-fi
-
-exec -a "$arg0" /dev/jwrap/bypass "$path" "$@"
-#2>&4
diff --git a/libjwrap.c b/libjwrap.c
deleted file mode 100644 (file)
index 23ee7d6..0000000
+++ /dev/null
@@ -1,194 +0,0 @@
-/**/
-
-#define _GNU_SOURCE
-#include <dlfcn.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <string.h>
-#include <errno.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <stdarg.h>
-
-#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 )