aboutsummaryrefslogtreecommitdiffstats
path: root/brp-mangle-shebangs
diff options
context:
space:
mode:
Diffstat (limited to 'brp-mangle-shebangs')
-rwxr-xr-xbrp-mangle-shebangs72
1 files changed, 48 insertions, 24 deletions
diff --git a/brp-mangle-shebangs b/brp-mangle-shebangs
index ecf8ae7..f27ad73 100755
--- a/brp-mangle-shebangs
+++ b/brp-mangle-shebangs
@@ -1,4 +1,4 @@
-#!/bin/bash -eu
+#!/usr/bin/bash -eu
# If using normal root, avoid changing anything.
if [ -z "$RPM_BUILD_ROOT" -o "$RPM_BUILD_ROOT" = "/" ]; then
@@ -70,13 +70,17 @@ done
cd "$RPM_BUILD_ROOT"
-trim() {
- printf '%s' "$*"
-}
-
+# Large packages such as kernel can have thousands of executable files.
+# We take care to not fork/exec thousands of "file"s and "grep"s,
+# but run just two of them.
+# (Take care to exclude filenames which would mangle "file" output).
+find -executable -type f ! -path '*:*' ! -path $'*\n*' \
+| file -N --mime-type -f - \
+| grep -P ".+(?=: (text/|application/javascript))" \
+| {
fail=0
-while IFS= read -r -d $'\0' f; do
- file -N --mime-type "$f" | grep -q -P ".+(?=: text/)" || continue
+while IFS= read -r line; do
+ f=${line%%:*}
# Remove the dot
path="${f#.}"
@@ -88,24 +92,41 @@ while IFS= read -r -d $'\0' f; do
echo "$path" | grep -q -E -f "$exclude_files_from" && continue
fi
- ts=$(stat -c %y "$f")
- read shebang_line < "$f" || :
- orig_shebang=$(trim $(echo "$shebang_line" | grep -Po "#!\K.*" || echo))
- shebang="$orig_shebang"
- if [ -n "$exclude_shebangs" ]; then
- echo "$shebang" | grep -q -E "$exclude_shebangs" && continue
+ if ! read shebang_line < "$f"; then
+ echo >&2 "*** WARNING: Cannot read the first line from $f, removing executable bit"
+ ts=$(stat -c %y "$f")
+ chmod -x "$f"
+ touch -d "$ts" "$f"
+ continue
fi
- if [ -n "$exclude_shebangs_from" ]; then
- echo "$shebang" | grep -q -E -f "$exclude_shebangs_from" && continue
+
+ orig_shebang="${shebang_line#\#!}"
+ if [ "$orig_shebang" = "$shebang_line" ]; then
+ echo >&2 "*** WARNING: $f is executable but has no shebang, removing executable bit"
+ ts=$(stat -c %y "$f")
+ chmod -x "$f"
+ touch -d "$ts" "$f"
+ continue
fi
+ # Trim spaces
+ while shebang="${orig_shebang// / }"; [ "$shebang" != "$orig_shebang" ]; do
+ orig_shebang="$shebang"
+ done
+ # Treat "#! /path/to " as "#!/path/to"
+ orig_shebang="${orig_shebang# }"
+
+ shebang="$orig_shebang"
+
if [ -z "$shebang" ]; then
- echo >&2 "*** WARNING: $f is executable but has empty or no shebang, removing executable bit"
+ echo >&2 "*** WARNING: $f is executable but has empty shebang, removing executable bit"
+ ts=$(stat -c %y "$f")
chmod -x "$f"
touch -d "$ts" "$f"
continue
- elif [ -n "${shebang##/*}" ]; then
+ fi
+ if [ -n "${shebang##/*}" ]; then
echo >&2 "*** ERROR: $f has shebang which doesn't start with '/' ($shebang)"
fail=1
continue
@@ -116,10 +137,10 @@ while IFS= read -r -d $'\0' f; do
fi
# Replace "special" env shebang:
- # /whatsoever/env /whatever/foo → /whatever/foo
- shebang=$(echo "$shebang" | sed -r -e 's@^(.+)/env /(.+)$@/\2@')
- # /whatsoever/env foo → /whatsoever/foo
- shebang=$(echo "$shebang" | sed -r -e 's@^(.+/)env (.+)$@\1\2@')
+ # /whatsoever/env -whatever /whatever/foo → /whatever/foo
+ shebang=$(echo "$shebang" | sed -r -e 's@^(.+)/env( -[^ ]+)* /(.+)$@/\3@')
+ # /whatsoever/env -whatever foo → /whatsoever/foo
+ shebang=$(echo "$shebang" | sed -r -e 's@^(.+/)env( -[^ ]+)* (.+)$@\1\3@')
# If the shebang now starts with /bin, change it to /usr/bin
# https://bugzilla.redhat.com/show_bug.cgi?id=1581757
@@ -130,12 +151,15 @@ while IFS= read -r -d $'\0' f; do
if [ "$shebang" != "$py_shebang" ]; then
echo >&2 "*** ERROR: ambiguous python shebang in $path: #!$orig_shebang. Change it to python3 (or python2) explicitly."
+ fail=1
elif [ "#!$shebang" != "#!$orig_shebang" ]; then
- sed -i -e "1c #!$shebang" "$f"
echo "mangling shebang in $path from $orig_shebang to #!$shebang"
+ ts=$(stat -c %y "$f")
+ sed -i -e "1c #!$shebang" "$f"
+ touch -d "$ts" "$f"
fi
- touch -d "$ts" "$f"
-done < <(find -executable -type f -print0)
+done
exit $fail
+}