[pacman-dev] [RFC] [PATCH] Implement a du --apparent-size equivalent
Alastair Hughes
hobbitalastair at gmail.com
Sat Jun 11 07:53:37 UTC 2016
From: Alastair Hughes <hobbitalastair at yandex.com>
Add a pkgsize binary which mimics the behaviour of GNU du --apparent-size -skl.
Fixes FS#47943.
Signed-off-by: Alastair Hughes <hobbitalastair at gmail.com>
---
I haven't done much C programming before - I'd appreciate any feedback you have.
At the moment, this patch creates a new pkgsize binary as an extra utility, and
installs with the other utilities.
I think that it would be better if it installed it to a libexec dir, but I'm
not entirely sure how to do that without making a mess.
---
configure.ac | 5 ---
scripts/Makefile.am | 2 --
scripts/makepkg.sh.in | 2 +-
src/util/.gitignore | 2 ++
src/util/Makefile.am | 4 ++-
src/util/pkgsize.c | 88 +++++++++++++++++++++++++++++++++++++++++++++++++++
6 files changed, 94 insertions(+), 9 deletions(-)
create mode 100644 src/util/pkgsize.c
diff --git a/configure.ac b/configure.ac
index dd4ac04..ee5f7ea 100644
--- a/configure.ac
+++ b/configure.ac
@@ -332,7 +332,6 @@ OWNERCMD="stat -c '%u:%g'"
MODECMD="stat -c '%a'"
SIZECMD="stat -c %s"
SEDINPLACE="sed --follow-symlinks -i"
-DUFLAGS="-sk --apparent-size"
STRIP_BINARIES="--strip-all"
STRIP_SHARED="--strip-unneeded"
STRIP_STATIC="--strip-debug"
@@ -343,7 +342,6 @@ case "${host_os}" in
MODECMD="stat -f '%Lp'"
SIZECMD="stat -f %z"
SEDINPLACE="sed -i \"\""
- DUFLAGS="-sk"
;;
darwin*)
host_os_darwin=yes
@@ -352,7 +350,6 @@ case "${host_os}" in
MODECMD="/usr/bin/stat -f '%Lp'"
SIZECMD="/usr/bin/stat -f %z"
SEDINPLACE="/usr/bin/sed -i ''"
- DUFLAGS="-sk"
STRIP_BINARIES=""
STRIP_SHARED="-S"
STRIP_STATIC="-S"
@@ -360,13 +357,11 @@ case "${host_os}" in
esac
AM_CONDITIONAL([DARWIN], test "x$host_os_darwin" = "xyes")
-AC_PATH_PROGS([DUPATH], [du], [du], [/usr/bin$PATH_SEPARATOR/bin] )
AC_SUBST(INODECMD)
AC_SUBST(OWNERCMD)
AC_SUBST(MODECMD)
AC_SUBST(SIZECMD)
AC_SUBST(SEDINPLACE)
-AC_SUBST(DUFLAGS)
AC_SUBST(STRIP_BINARIES)
AC_SUBST(STRIP_SHARED)
AC_SUBST(STRIP_STATIC)
diff --git a/scripts/Makefile.am b/scripts/Makefile.am
index e4f9fb1..ea14e73 100644
--- a/scripts/Makefile.am
+++ b/scripts/Makefile.am
@@ -138,8 +138,6 @@ edit = sed \
-e "s|@MODECMD[@]|$(MODECMD)|g" \
-e 's|@SIZECMD[@]|$(SIZECMD)|g' \
-e 's|@SEDINPLACE[@]|$(SEDINPLACE)|g' \
- -e 's|@DUFLAGS[@]|$(DUFLAGS)|g' \
- -e 's|@DUPATH[@]|$(DUPATH)|g' \
-e 's|@SCRIPTNAME[@]|$@|g' \
-e 's|@configure_input[@]|Generated from $@.sh.in; do not edit by hand.|g'
diff --git a/scripts/makepkg.sh.in b/scripts/makepkg.sh.in
index 7b2ce51..249c878 100644
--- a/scripts/makepkg.sh.in
+++ b/scripts/makepkg.sh.in
@@ -605,7 +605,7 @@ write_pkginfo() {
local packager="Unknown Packager"
fi
- local size="$(@DUPATH@ @DUFLAGS@)"
+ local size="$(pkgsize .)"
size="$(( ${size%%[^0-9]*} * 1024 ))"
merge_arch_attrs
diff --git a/src/util/.gitignore b/src/util/.gitignore
index 202fb75..7dbefe8 100644
--- a/src/util/.gitignore
+++ b/src/util/.gitignore
@@ -6,6 +6,8 @@ pacsort
pacsort.exe
pactree
pactree.exe
+pkgsize
+pkgsize.exe
testpkg
testpkg.exe
vercmp
diff --git a/src/util/Makefile.am b/src/util/Makefile.am
index 6a89ea6..84dfce9 100644
--- a/src/util/Makefile.am
+++ b/src/util/Makefile.am
@@ -4,7 +4,7 @@ dbpath = ${localstatedir}/lib/pacman/
gpgdir = ${sysconfdir}/pacman.d/gnupg/
cachedir = ${localstatedir}/cache/pacman/pkg/
-bin_PROGRAMS = vercmp testpkg cleanupdelta pacsort pactree
+bin_PROGRAMS = vercmp testpkg cleanupdelta pacsort pactree pkgsize
AM_CPPFLAGS = \
-imacros $(top_builddir)/config.h \
@@ -27,6 +27,8 @@ pacsort_LDADD = $(top_builddir)/lib/libalpm/.libs/libalpm.la
pactree_SOURCES = pactree.c util-common.c
pactree_LDADD = $(top_builddir)/lib/libalpm/.libs/libalpm.la
+pkgsize_SOURCES = pkgsize.c
+
testpkg_SOURCES = testpkg.c
testpkg_LDADD = $(top_builddir)/lib/libalpm/.libs/libalpm.la
diff --git a/src/util/pkgsize.c b/src/util/pkgsize.c
new file mode 100644
index 0000000..5e1b3fc
--- /dev/null
+++ b/src/util/pkgsize.c
@@ -0,0 +1,88 @@
+/*
+ * pkgsize.c - a du --apparent-size equivalent for systems without GNU du
+ *
+ * Copyright (c) 2016 Pacman Development Team <pacman-dev at archlinux.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* This is equivalent to "du -skl --apparent-size".
+ * Unforunately, there appears to be no easy way of ignoring hard links, hence
+ * the additional '-l' argument.
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <dirent.h>
+#include <unistd.h>
+
+static long size(char *path)
+{
+ long total_size, subsize;
+ DIR *dir;
+ struct dirent *entry;
+ struct stat buf;
+
+ if(lstat(path, &buf) != 0) { return -1; }
+
+ if(S_ISLNK(buf.st_mode) || S_ISREG(buf.st_mode)) {
+ return buf.st_size;
+ } else if(S_ISDIR(buf.st_mode)) {
+ total_size = buf.st_size;
+ dir = opendir(path);
+ if(dir == NULL || chdir(path) != 0) { return -1; }
+ while(entry = readdir(dir)) {
+ if(strcmp(entry->d_name, "..") == 0 || strcmp(entry->d_name, ".") == 0) {
+ continue;
+ }
+ subsize = size(entry->d_name);
+ if(subsize == -1) {
+ closedir(dir);
+ return -1;
+ }
+ total_size += subsize;
+ }
+
+ closedir(dir);
+ if(chdir("../") != 0) { return -1; }
+ return total_size;
+ }
+ return 0;
+}
+
+int main(int argc, char *argv[])
+{
+ long total_size;
+
+ if(argc != 2) {
+ printf("Invalid argument count %d!\n", argc - 1);
+ exit(EXIT_FAILURE);
+ }
+
+ total_size = size(argv[1]);
+ if(total_size == -1) {
+ perror("");
+ exit(EXIT_FAILURE);
+ }
+
+ /* Use KB, rounded up - should be equivalent to the du -k flag */
+ printf("%ld %s\n", (total_size / 1024) + (total_size % 1024 != 0), argv[1]);
+
+ exit(EXIT_SUCCESS);
+}
+
+/* vim: set noet: */
--
2.8.3
More information about the pacman-dev
mailing list