From decda92874250a1e25d185fa8fd1f2d2f4b94d20 Mon Sep 17 00:00:00 2001 From: Simon Tatham Date: Tue, 16 May 2017 07:03:19 +0100 Subject: Use an LD_PRELOAD library in place of symlink to /home. Apart from dependency on native-code DLLs, the one other quirk of running WiX under mono is that it doesn't seem to quite get the right answers when combining $PWD with a Unix absolute path to one of its own supporting files - it doesn't interpret the leading slash on the latter as meaning $PWD should be ignored, so it tries to look for /home/my/build/dir/home/my/wix/install/dir/some.file. Previously I was bodging around that by having my build dir contain a symlink 'home' pointing at /home; this is marginally less intrusive. --- Makefile.wixfakelibs | 4 +++- preload.c | 42 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 1 deletion(-) create mode 100644 preload.c diff --git a/Makefile.wixfakelibs b/Makefile.wixfakelibs index f53c539..6cce710 100644 --- a/Makefile.wixfakelibs +++ b/Makefile.wixfakelibs @@ -2,7 +2,7 @@ .SUFFIXES: .c .lo .la -all: libwinterop.so.la libmsi.so.la +all: libwinterop.so.la libmsi.so.la libpreload.la %.la: libtool --mode=link gcc -o $@ $^ -rpath /usr/local/lib @@ -14,6 +14,8 @@ libwinterop.so.la: fake-winterop.lo fake-lib.lo libmsi.so.la: fake-msi.lo fake-lib.lo +libpreload.la: preload.lo + clean: rm -rf .libs rm -f *.o *.lo *.la diff --git a/preload.c b/preload.c new file mode 100644 index 0000000..1665515 --- /dev/null +++ b/preload.c @@ -0,0 +1,42 @@ +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include + +static const char *munge(const char *n) { + static const char *e = NULL; + static size_t elen; + if (!e) { + e = getenv("WIX"); + if (!e) + return n; + elen = strlen(e); + } + + const char *last_slash = strrchr(n, '/'); + if (!last_slash) + return n; + if (last_slash - n > elen && !strncmp(last_slash - elen, e, elen)) + return last_slash - elen; + return n; +} + +#define dofunc(rettype,sym,proto,proto2) \ + rettype sym proto { \ + rettype (*real) proto; \ + real = dlsym(RTLD_NEXT, #sym); \ + fname = munge(fname); \ + return real proto2; \ + } + +dofunc(int,open,(const char *fname,int flags,mode_t mode),(fname,flags,mode)) +dofunc(int,open64,(const char *fname,int flags,mode_t mode),(fname,flags,mode)) +dofunc(int,__open,(const char *fname,int flags,mode_t mode),(fname,flags,mode)) +dofunc(int,__open64,(const char *fname,int flags,mode_t mode),(fname,flags,mode)) +dofunc(int,stat,(const char *fname,struct stat *sbuf),(fname,sbuf)) +dofunc(int,lstat,(const char *fname,struct stat *sbuf),(fname,sbuf)) +dofunc(int,access,(const char *fname,int mode),(fname,mode)) -- cgit v1.2.3-55-g6feb