summaryrefslogtreecommitdiffstats
path: root/pkgs
diff options
context:
space:
mode:
authorTobias Bergkvist <tobias@bergkv.ist>2021-05-27 01:11:06 +0200
committerTobias Bergkvist <tobias@bergkv.ist>2021-05-27 01:11:06 +0200
commitde1f53b84d5f9549730693aa1e33f69069477395 (patch)
tree37fe954c6822c5e7378e09270cd14ad83709d1ce /pkgs
parent5edd17c4c2a17e7e964f360d83de39e66ea6865b (diff)
Add make-c-wrapper.sh for creating binary executable wrappers
Diffstat (limited to 'pkgs')
-rw-r--r--pkgs/build-support/setup-hooks/make-c-wrapper.sh73
1 files changed, 73 insertions, 0 deletions
diff --git a/pkgs/build-support/setup-hooks/make-c-wrapper.sh b/pkgs/build-support/setup-hooks/make-c-wrapper.sh
new file mode 100644
index 000000000000..2c67d9ab16e6
--- /dev/null
+++ b/pkgs/build-support/setup-hooks/make-c-wrapper.sh
@@ -0,0 +1,73 @@
+#!/bin/bash
+# make-c-wrapper.sh EXECUTABLE ARGS
+#
+# ARGS:
+# --argv0 NAME : set name of executed process to NAME
+# (defaults to EXECUTABLE)
+# --set VAR VAL : add VAR with value VAL to the executable’s
+# environment
+# --set-default VAR VAL : like --set, but only adds VAR if not already set in
+# the environment
+# --unset VAR : remove VAR from the environment
+#
+# To debug a binary wrapper after you compiled it, use the `strings` command
+
+escape_string_literal() {
+ # We need to make sure that special characters are escaped
+ # before trying to create C string literals
+ result=${1//$'\\'/$'\\\\'}
+ result=${result//\"/'\"'}
+ result=${result//$'\n'/"\n"}
+ result=${result//$'\r'/"\r"}
+}
+
+escape_string_literal "$1"
+executable="${result}"
+args=("$@")
+
+printf "%s\n" "#include <unistd.h>"
+printf "%s\n" "#include <stdlib.h>"
+printf "\n%s\n" "int main(int argc, char **argv) {"
+for ((n = 1; n < ${#args[*]}; n += 1)); do
+ p="${args[$n]}"
+ if [[ "$p" == "--set" ]]; then
+ escape_string_literal "${args[$((n + 1))]}"
+ key="${result}"
+ escape_string_literal "${args[$((n + 2))]}"
+ value="${result}"
+ n=$((n + 2))
+ printf "%s\n" " putenv(\"${key}=${value}\");"
+ docs="${docs:+$docs$'\n'}putenv(\"${key}=${value}\");"
+ elif [[ "$p" == "--set-default" ]]; then
+ escape_string_literal "${args[$((n + 1))]}"
+ key="${result}"
+ escape_string_literal "${args[$((n + 2))]}"
+ value="${result}"
+ n=$((n + 2))
+ printf "%s\n" " setenv(\"${key}\", \"${value}\", 0);"
+ docs="${docs:+$docs$'\n'}setenv(\"${key}=${value}\", 0);"
+ elif [[ "$p" == "--unset" ]]; then
+ escape_string_literal "${args[$((n + 1))]}"
+ key="${result}"
+ printf "%s\n" " unsetenv(\"$key\");"
+ docs="${docs:+$docs$'\n'}unsetenv(\"${key}=${value}\", 0);"
+ n=$((n + 1))
+ elif [[ "$p" == "--argv0" ]]; then
+ escape_string_literal "${args[$((n + 1))]}"
+ argv0="${result}"
+ n=$((n + 1))
+ else
+ # Using an error macro, we will make sure the compiler gives an understandable error message
+ printf "%s\n" " #error make-c-wrapper.sh did not understand argument ${p}"
+ fi
+done
+printf "%s\n" " argv[0] = \"${argv0:-${executable}}\";"
+printf "%s\n" " return execv(\"${executable}\", argv);"
+printf "%s\n" "}"
+
+docs="${docs:+$docs$'\n'}argv[0] = \"${argv0:-${executable}}\";"
+docs="${docs:+$docs$'\n'}execv(\"${executable}\", argv);"
+docs="----------"$'\n'"This binary wrapper (created from generated C-code) is configured with the following settings:${docs:+$'\n'$docs}"
+escape_string_literal "$docs"
+docs=$result
+printf "\n%s\n" "const char* DOCS = \"$docs\";"