summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSören Tempel <soeren+git@soeren-tempel.net>2015-11-27 00:38:51 +0100
committerNatanael Copa <ncopa@alpinelinux.org>2016-02-03 18:21:02 +0000
commite8e0b9e90a9934dae27f1aea438a48b0abf9d2dd (patch)
tree9b59b6a0e95d8e9ef4b3cf71119c8dadf5905cba
parent042921b798ba7d96c79b85df1d682745d0ddaf13 (diff)
downloadabuild-e8e0b9e90a9934dae27f1aea438a48b0abf9d2dd.tar.gz
abuild-e8e0b9e90a9934dae27f1aea438a48b0abf9d2dd.tar.bz2
abuild-e8e0b9e90a9934dae27f1aea438a48b0abf9d2dd.tar.xz
abuild-e8e0b9e90a9934dae27f1aea438a48b0abf9d2dd.zip
abuild: rewrite hardlink handling when compressing man pages
The problem is that gzip refuses to run if it detects that a file has more than 1 link. Our existing solution (removing hardlinks, compressing the man page and recreating the hardlinks) made certain assumptions about inode order that are only given on Unix v7 like filesystems meaning it didn't work properly on 'tree-based' filesystems like BTRFS or ZFS. This patch has a different more bulletproof approach: It simply replaces all hardlinks with symlinks. This is way easier because symlinks (unlike hardlinks) can point to a file that doesn't exist, therefore we can update all links before compressing the file in an easy way.
-rw-r--r--abuild.in40
1 files changed, 22 insertions, 18 deletions
diff --git a/abuild.in b/abuild.in
index 0ab0474..da84a83 100644
--- a/abuild.in
+++ b/abuild.in
@@ -1407,29 +1407,33 @@ default_doc() {
done
# compress man pages
- local previnode= prevname= mandir="$subpkgdir"/usr/share/man
- [ -d "$mandir" ] && find "$subpkgdir"/usr/share/man \
- -type f \( -name \*.[0-8n] -o -name \*.[0-8][a-z]* \) \
- -exec stat -c "%i %n" {} \; | sort -n \
- | while read inode name; do
-
- if [ "$inode" = "$previnode" ]; then
- # update hard link
- rm "$name"
- ln "$prevname".gz "$name".gz
- else
- gzip -9 "$name"
- fi
+ local mandir="$subpkgdir"/usr/share/man
+ [ -d "$mandir" ] && find "$mandir" -type f \
+ -a \( -name \*.[0-8n] -o -name \*.[0-8][a-z]* \) \
+ -exec stat -c "%i %n" \{\} \; | while read inode name; do
+
+ # Skip hardlinks removed in last iteration.
+ [ -f "$name" ] || continue
+
+ local islink=0
+ find "$mandir" -type f -links +1 \
+ -a \( -name \*.[0-8n] -o -name \*.[0-8][a-z]* \) \
+ -exec stat -c "%i %n" \{\} \; | while read linode lname; do
+ if [ "$linode" = "$inode" -a "$lname" != "$name" ]; then
+ islink=1
+ rm -f "$lname"
+ ln -s "${name##*/}".gz "$lname".gz
+ fi
+ done
- previnode="$inode"
- prevname="$name"
+ [ $islink -eq 0 ] && gzip -9 "$name"
done
- [ -d "$mandir" ] && find "$subpkgdir"/usr/share/man \
- -type l \( -name \*.[0-8n] -o -name \*.[0-8][a-z]* \) \
+ [ -d "$mandir" ] && find "$mandir" -type l \
+ -a \( -name \*.[0-8n] -o -name \*.[0-8][a-z]* \) \
| while read symlink; do
ln -s $(readlink $symlink).gz "$symlink".gz
- rm "$symlink"
+ rm -f "$symlink"
done
rm -f "$subpkgdir/usr/share/info/dir"