nixpkgs/pkgs/build-support/trivial-builders.nix
Nicolas Pierron 9d62d5a35c * Add a wrapper to find any set-uid version of a program in the environment.
svn path=/nixpkgs/trunk/; revision=19181
2010-01-03 11:08:45 +00:00

102 lines
3 KiB
Nix

{ stdenv, lndir }:
rec {
# Run the shell command `buildCommand' to produce a store path named
# `name'. The attributes in `env' are added to the environment
# prior to running the command.
runCommand = name: env: buildCommand:
stdenv.mkDerivation ({
inherit name buildCommand;
} // env);
# Create a single file.
writeTextFile =
{ name # the name of the derivation
, text
, executable ? false # run chmod +x ?
, destination ? "" # relative path appended to $out eg "/bin/foo"
}:
runCommand name {inherit text executable; }
''
n=$out${destination}
mkdir -p "$(dirname "$n")"
echo -n "$text" > "$n"
(test -n "$executable" && chmod +x "$n") || true
'';
# Shorthands for `writeTextFile'.
writeText = name: text: writeTextFile {inherit name text;};
writeScript = name: text: writeTextFile {inherit name text; executable = true;};
writeScriptBin = name: text: writeTextFile {inherit name text; executable = true; destination = "/bin/${name}";};
# Create a forest of symlinks to the files in `paths'.
symlinkJoin = name: paths:
runCommand name { inherit paths; }
''
mkdir -p $out
for i in $paths; do
${lndir}/bin/lndir $i $out
done
'';
# Make a package that just contains a setup hook with the given contents.
makeSetupHook = script:
runCommand "hook" {}
''
ensureDir $out/nix-support
cp ${script} $out/nix-support/setup-hook
'';
# Write the references (i.e. the runtime dependencies in the Nix store) of `path' to a file.
writeReferencesToFile = path: runCommand "runtime-deps"
{
exportReferencesGraph = ["graph" path];
}
''
touch $out
while read path; do
echo $path >> $out
read dummy
read nrRefs
for ((i = 0; i < nrRefs; i++)); do read ref; done
done < graph
'';
# Quickly create a set of symlinks to derivations.
# entries is a list of attribute sets like { name = "name" ; path = "/nix/store/..."; }
linkFarm = name: entries: runCommand name {} ("mkdir -p $out; cd $out; \n" +
(stdenv.lib.concatMapStrings (x: "ln -s '${x.path}' '${x.name}';\n") entries));
# Search in the environment if the same program exists with a set uid or
# set gid bit. If it exists, run the first program found, otherwise run
# the default binary.
useSetUID = drv: path:
let
name = stdenv.lib.basename path;
bin = "${drv}${path}";
in assert name != "";
writeScript "setUID-${name}" ''
#!${stdenv.shell}
inode=$(stat -Lc %i ${bin})
for file in $(type -ap ${name}); do
case $(stat -Lc %a $file) in
([2-7][0-7][0-7][0-7])
if test -r "$file".real; then
orig=$(cat "$file".real)
if test $inode = $(stat -Lc %i "$orig"); then
exec "$file" "$@"
fi
fi;;
esac
done
exec ${bin} "$@"
'';
}