lol
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

hipchat: Fix access to /usr/share/X11/xkb

HipChat (or rather its copy of Qt) expects to find keyboard data in
/usr/share/X11/xkb. So use a LD_PRELOAD library to intercept and
rewrite the Glibc calls that access those paths. We've been doing the
same thing with packages like Spotify, but now this functionality has
been abstracted into a reusable library, libredirect.so. It uses an
environment variable $NIX_REDIRECTS containing a colon-separated list
of path prefixes to be rewritten, e.g. "/foo=bar:/xyzzy=/fnord".

+128 -5
+8 -5
pkgs/applications/networking/instant-messengers/hipchat/default.nix
··· 1 1 { stdenv, fetchurl, libtool, xlibs, freetype, fontconfig, openssl, glib 2 2 , mesa, gstreamer, gst_plugins_base, dbus, alsaLib, zlib, libuuid 3 - , libxml2, libxslt, sqlite, libogg, libvorbis, xz, libcanberra, makeWrapper }: 3 + , libxml2, libxslt, sqlite, libogg, libvorbis, xz, libcanberra 4 + , makeWrapper, libredirect, xkeyboard_config }: 4 5 5 6 let 6 7 ··· 67 68 buildCommand = '' 68 69 tar xf ${src} 69 70 70 - d=$out/libexec/hipchat 71 - mkdir -p $out/libexec 71 + mkdir -p $out/libexec/hipchat/bin 72 + d=$out/libexec/hipchat/lib 72 73 rm -rfv opt/HipChat/lib/{libstdc++*,libz*,libuuid*,libxml2*,libxslt*,libsqlite*,libogg*,libvorbis*,liblzma*,libcanberra.*,libcanberra-*} 73 74 mv opt/HipChat/lib/ $d 74 75 mv usr/share $out ··· 85 86 86 87 makeWrapper $d/hipchat.bin $out/bin/hipchat \ 87 88 --set HIPCHAT_LD_LIBRARY_PATH '"$LD_LIBRARY_PATH"' \ 88 - --set HIPCHAT_QT_PLUGIN_PATH '"$QT_PLUGIN_PATH"' 89 + --set HIPCHAT_QT_PLUGIN_PATH '"$QT_PLUGIN_PATH"' \ 90 + --set LD_PRELOAD "${libredirect}/lib/libredirect.so" \ 91 + --set NIX_REDIRECTS /usr/share/X11/xkb=${xkeyboard_config}/share/X11/xkb 89 92 90 - mv opt/HipChat/bin/linuxbrowserlaunch $out/bin 93 + mv opt/HipChat/bin/linuxbrowserlaunch $out/libexec/hipchat/bin/ 91 94 ''; 92 95 93 96 meta = {
+14
pkgs/build-support/libredirect/default.nix
··· 1 + { stdenv }: 2 + 3 + stdenv.mkDerivation { 4 + name = "libredirect-0"; 5 + 6 + unpackPhase = "cp ${./libredirect.c} libredirect.c"; 7 + 8 + buildPhase = 9 + '' 10 + gcc -Wall -std=c99 -O3 -shared libredirect.c -o libredirect.so -fPIC -ldl 11 + ''; 12 + 13 + installPhase = "mkdir -p $out/lib; cp libredirect.so $out/lib"; 14 + }
+104
pkgs/build-support/libredirect/libredirect.c
··· 1 + #define _GNU_SOURCE 2 + #include <stdio.h> 3 + #include <stdarg.h> 4 + #include <stdlib.h> 5 + #include <dlfcn.h> 6 + #include <sys/types.h> 7 + #include <sys/stat.h> 8 + #include <fcntl.h> 9 + #include <limits.h> 10 + #include <string.h> 11 + 12 + #define MAX_REDIRECTS 128 13 + 14 + static int nrRedirects = 0; 15 + static char * from[MAX_REDIRECTS]; 16 + static char * to[MAX_REDIRECTS]; 17 + 18 + // FIXME: might run too late. 19 + static void init() __attribute__((constructor)); 20 + 21 + static void init() 22 + { 23 + char * spec = getenv("NIX_REDIRECTS"); 24 + if (!spec) return; 25 + 26 + unsetenv("NIX_REDIRECTS"); 27 + 28 + char * spec2 = malloc(strlen(spec) + 1); 29 + strcpy(spec2, spec); 30 + 31 + char * pos = spec2, * eq; 32 + while ((eq = strchr(pos, '='))) { 33 + *eq = 0; 34 + from[nrRedirects] = pos; 35 + pos = eq + 1; 36 + to[nrRedirects] = pos; 37 + nrRedirects++; 38 + if (nrRedirects == MAX_REDIRECTS) break; 39 + char * end = strchr(pos, ':'); 40 + if (!end) break; 41 + *end = 0; 42 + pos = end + 1; 43 + } 44 + 45 + } 46 + 47 + static const char * rewrite(const char * path, char * buf) 48 + { 49 + for (int n = 0; n < nrRedirects; ++n) { 50 + int len = strlen(from[n]); 51 + if (strncmp(path, from[n], len) != 0) continue; 52 + if (snprintf(buf, PATH_MAX, "%s%s", to[n], path + len) >= PATH_MAX) 53 + abort(); 54 + return buf; 55 + } 56 + 57 + return path; 58 + } 59 + 60 + /* The following set of Glibc library functions is very incomplete - 61 + it contains only what we needed for programs in Nixpkgs. Just add 62 + more functions as needed. */ 63 + 64 + int open(const char * path, int flags, ...) 65 + { 66 + int (*open_real) (const char *, int, mode_t) = dlsym(RTLD_NEXT, "open"); 67 + mode_t mode = 0; 68 + if (flags & O_CREAT) { 69 + va_list ap; 70 + va_start(ap, flags); 71 + mode = va_arg(ap, mode_t); 72 + va_end(ap); 73 + } 74 + char buf[PATH_MAX]; 75 + return open_real(rewrite(path, buf), flags, mode); 76 + } 77 + 78 + int open64(const char * path, int flags, ...) 79 + { 80 + int (*open64_real) (const char *, int, mode_t) = dlsym(RTLD_NEXT, "open64"); 81 + mode_t mode = 0; 82 + if (flags & O_CREAT) { 83 + va_list ap; 84 + va_start(ap, flags); 85 + mode = va_arg(ap, mode_t); 86 + va_end(ap); 87 + } 88 + char buf[PATH_MAX]; 89 + return open64_real(rewrite(path, buf), flags, mode); 90 + } 91 + 92 + FILE * fopen(const char * path, const char * mode) 93 + { 94 + FILE * (*fopen_real) (const char *, const char *) = dlsym(RTLD_NEXT, "fopen"); 95 + char buf[PATH_MAX]; 96 + return fopen_real(rewrite(path, buf), mode); 97 + } 98 + 99 + int __xstat(int ver, const char * path, struct stat * st) 100 + { 101 + int (*__xstat_real) (int ver, const char *, struct stat *) = dlsym(RTLD_NEXT, "__xstat"); 102 + char buf[PATH_MAX]; 103 + return __xstat_real(ver, rewrite(path, buf), st); 104 + }
+2
pkgs/top-level/all-packages.nix
··· 373 373 inherit url; 374 374 }; 375 375 376 + libredirect = callPackage ../build-support/libredirect { }; 377 + 376 378 makeDesktopItem = import ../build-support/make-desktopitem { 377 379 inherit stdenv; 378 380 };