about summary refs log tree commit diff
path: root/pkgs/games/build-support
diff options
context:
space:
mode:
Diffstat (limited to 'pkgs/games/build-support')
-rw-r--r--pkgs/games/build-support/build-game.nix17
-rw-r--r--pkgs/games/build-support/build-sandbox/default.nix60
-rw-r--r--pkgs/games/build-support/build-sandbox/sandbox.c (renamed from pkgs/games/build-support/sandbox.c)0
-rw-r--r--pkgs/games/build-support/default.nix1
-rw-r--r--pkgs/games/build-support/setup-hooks/make-sandbox.sh103
5 files changed, 63 insertions, 118 deletions
diff --git a/pkgs/games/build-support/build-game.nix b/pkgs/games/build-support/build-game.nix
index e402787c..f23ddd9a 100644
--- a/pkgs/games/build-support/build-game.nix
+++ b/pkgs/games/build-support/build-game.nix
@@ -1,4 +1,4 @@
-{ stdenv, lib, file, unzip, gcc, makeSetupHook
+{ stdenv, lib, file, unzip
 
 , withPulseAudio ? true, libpulseaudio ? null
 , alsaLib
@@ -16,15 +16,7 @@ assert withPulseAudio -> libpulseaudio != null;
 , ...
 }@attrs:
 
-let
-  sandboxHook = makeSetupHook {
-    substitutions = {
-      inherit gcc;
-      sandbox_main = ./sandbox.c;
-    };
-  } ./setup-hooks/make-sandbox.sh;
-
-in stdenv.mkDerivation ({
+stdenv.mkDerivation ({
   buildInputs = [ stdenv.cc.cc ] ++ buildInputs;
 
   nativeBuildInputs = [
@@ -48,11 +40,6 @@ in stdenv.mkDerivation ({
     fi
   '';
 
-  # Use ":!*!:" as delimiter as we can consider this highly unlikely to
-  # be part of a real path component and we're out of Nix territory, so
-  # the path components could contain almost anything.
-  extraSandboxPaths = lib.concatStringsSep ":!*!:" extraSandboxPaths;
-
   runtimeDependencies = let
     deps = lib.singleton alsaLib
         ++ lib.optional withPulseAudio libpulseaudio
diff --git a/pkgs/games/build-support/build-sandbox/default.nix b/pkgs/games/build-support/build-sandbox/default.nix
new file mode 100644
index 00000000..3b41e1bd
--- /dev/null
+++ b/pkgs/games/build-support/build-sandbox/default.nix
@@ -0,0 +1,60 @@
+{ stdenv, lib }:
+
+drv: { extraSandboxPaths ? [], ... }@attrs:
+
+stdenv.mkDerivation ({
+  name = "${drv.name}-sandboxed";
+
+  src = drv;
+
+  phases = [ "buildPhase" "installPhase" ];
+
+  exportReferencesGraph = [ "sandbox-closure" drv ];
+
+  buildPhase = ''
+    runtimeDeps="$(sed -ne '
+      p; n; n
+
+      :cdown
+      /^0*$/b
+      :l; s/0\(X*\)$/X\1/; tl
+
+      s/^\(X*\)$/9\1/; tdone
+      ${lib.concatMapStrings (num: ''
+        s/${toString num}\(X*\)$/${toString (num - 1)}\1/; tdone
+      '') (lib.range 1 9)}
+
+      :done
+      y/X/9/
+      x; n; p; x
+      bcdown
+    ' sandbox-closure | sort -u)"
+
+    echo 'static bool setup_app_paths(void) {' > params.c
+
+    for dep in $runtimeDeps; do
+      echo 'if (!bind_mount("'"$dep"'", true)) return false;' >> params.c
+    done
+
+    ${lib.concatMapStrings (extra: let
+      escaped = lib.escapeShellArg (lib.escape ["\\" "\""] extra);
+      result = "echo 'if (!extra_mount(\"'${escaped}'\")) return false;'";
+    in "${result} >> params.c") extraSandboxPaths}
+
+    echo 'return true; }' >> params.c
+    cat params.c
+  '';
+
+  installPhase = ''
+    mkdir -p "$out/bin"
+    for bin in "$src"/bin/*; do
+      progname="$(basename "$bin")"
+      gcc -g -std=gnu11 -Wall \
+        -DWRAPPED_PATH=\""$bin"\" \
+        -DWRAPPED_PROGNAME=\""$progname"\" \
+        -DPARAMS_FILE=\""$(pwd)/params.c"\" \
+        -o "$out/bin/$progname" ${./sandbox.c}
+    done
+  '';
+
+} // removeAttrs attrs [ "extraSandboxPaths" ])
diff --git a/pkgs/games/build-support/sandbox.c b/pkgs/games/build-support/build-sandbox/sandbox.c
index 69553628..69553628 100644
--- a/pkgs/games/build-support/sandbox.c
+++ b/pkgs/games/build-support/build-sandbox/sandbox.c
diff --git a/pkgs/games/build-support/default.nix b/pkgs/games/build-support/default.nix
index 8e227afc..3017fe8e 100644
--- a/pkgs/games/build-support/default.nix
+++ b/pkgs/games/build-support/default.nix
@@ -4,5 +4,6 @@
   buildGame = callPackage ./build-game.nix {
     withPulseAudio = config.pulseaudio or true;
   };
+  buildSandbox = callPackage ./build-sandbox {};
   buildUnity = callPackage ./build-unity.nix {};
 }
diff --git a/pkgs/games/build-support/setup-hooks/make-sandbox.sh b/pkgs/games/build-support/setup-hooks/make-sandbox.sh
deleted file mode 100644
index 7779234f..00000000
--- a/pkgs/games/build-support/setup-hooks/make-sandbox.sh
+++ /dev/null
@@ -1,103 +0,0 @@
-sandbox_params_include="$(mktemp --suffix=.c)"
-trap "rm -f '$sandbox_params_include'" EXIT
-sandbox_references=""
-
-hasReference() {
-    local ref
-    for ref in $sandbox_references; do
-        if [ "$1" = "$ref" ]; then return 0; fi
-    done
-
-    return 1
-}
-
-addReference() {
-    local toAdd="$1"
-
-    sandbox_references="$sandbox_references $toAdd"
-
-    echo 'if (!bind_mount("'"$toAdd"'", true)) return false;' \
-        >> "$sandbox_params_include"
-}
-
-gatherReferencesRecursive() {
-    local path="$1"
-
-    if hasReference "$path"; then return; fi
-    addReference "$path"
-
-    local valid_hash='[0-9a-df-np-sv-z]\{32\}'
-    local valid_name='[A-Za-z0-9+_?=-][A-Za-z0-9+._?=-]*'
-    local valid_path="$NIX_STORE/$valid_hash-$valid_name"
-
-    local hashpaths="$(
-        find "$path" -type f -exec grep -hao "$valid_path" {} +
-        find "$path" -type l -exec readlink {} +
-    )"
-
-    local hashpath
-    for hashpath in $hashpaths; do
-        local realsp
-        for realsp in "$NIX_STORE"/*; do
-            if echo "$hashpath" | grep -q -m 1 "^${realsp//./\\.}"; then
-                gatherReferencesRecursive "$realsp"
-                break
-            fi
-        done
-    done
-}
-
-gatherReferences() {
-    [ -z "$sandbox_references" ] || return 0
-
-    echo 'static bool setup_app_paths(void) {' > "$sandbox_params_include"
-
-    for output in $outputs; do
-        [ -e "${!output}" ] || continue
-        gatherReferencesRecursive "${!output}"
-    done
-
-    if [ -n "$extraSandboxPaths" ]; then
-        local oldIfs="$IFS"
-        IFS=':!*!:'
-        local extra
-        for extra in $extraSandboxPaths; do
-            local extraC="$(echo "$extra" | sed -e 's/"\\/\\&/g')"
-            echo 'if (!extra_mount("'"$extraC"'")) return false;' \
-                >> "$sandbox_params_include"
-        done
-        IFS="$oldIfs"
-    fi
-
-    echo 'return true; }' >> "$sandbox_params_include"
-    cat "$sandbox_params_include"
-}
-
-wrapSandbox() {
-    local progname="$1"
-    local wrapped="$2"
-    local output="$3"
-
-    @gcc@/bin/gcc -g -std=gnu11 -Wall \
-        -DWRAPPED_PATH=\""$wrapped"\" \
-        -DWRAPPED_PROGNAME=\""$progname"\" \
-        -DPARAMS_FILE=\""$sandbox_params_include"\" \
-        -o "$output" @sandbox_main@
-}
-
-makeSandbox() {
-    gatherReferences
-
-    for output in $outputs; do
-        [ -e "${!output}" ] || continue
-        local bin
-        for bin in "${!output}"/bin/*; do
-            local binbase="$(basename "$bin")"
-            local newdest="$(dirname "$bin")/.$binbase-wrapped"
-            mv "$bin" "$newdest"
-            wrapSandbox "$binbase" "$newdest" "$bin"
-        done
-    done
-}
-
-postFixupHooks+=(makeSandbox)