[pacman-dev] [RFC] [PATCH] Implement a du --apparent-size equivalent
From: Alastair Hughes <hobbitalastair@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@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@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
On 11/06/16 17:53, Alastair Hughes wrote:
From: Alastair Hughes <hobbitalastair@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@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.
I really don't want to provide a binary just to do this. My preferred solution is just to test "du -sk --apparent-size" in a temporary directory during configure and switch to just "du -sk" if it fails. Allan
On 6/12/16, Allan McRae <allan@archlinux.org> wrote:
On 11/06/16 17:53, Alastair Hughes wrote:
From: Alastair Hughes <hobbitalastair@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@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.
I really don't want to provide a binary just to do this.
My preferred solution is just to test "du -sk --apparent-size" in a temporary directory during configure and switch to just "du -sk" if it fails.
Allan
I'm cross compiling; in that case, the host system has a different du than the target system, so testing at configure time would not be appropriate. Would checking at runtime be acceptable? Alternatively, I would be happy with a configure flag to override the default choice. Alastair Hughes
On 13.06.2016 22:07, Alastair Hughes wrote:
I really don't want to provide a binary just to do this.
I'm cross compiling; in that case, the host system has a different du than the target system
How about implementing the functionality in something like awk or perl? Those should be sufficiently fast and widely available. makepkg already uses awk so maybe that would be a good fit. Florian
On 17/06/16 01:37, Florian Pritz wrote:
On 13.06.2016 22:07, Alastair Hughes wrote:
I really don't want to provide a binary just to do this.
I'm cross compiling; in that case, the host system has a different du than the target system
How about implementing the functionality in something like awk or perl? Those should be sufficiently fast and widely available. makepkg already uses awk so maybe that would be a good fit.
Because history! https://lists.archlinux.org/pipermail/pacman-dev/2012-March/015293.html
On 14/06/16 06:07, Alastair Hughes wrote:
On 6/12/16, Allan McRae <allan@archlinux.org> wrote:
On 11/06/16 17:53, Alastair Hughes wrote:
From: Alastair Hughes <hobbitalastair@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@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.
I really don't want to provide a binary just to do this.
My preferred solution is just to test "du -sk --apparent-size" in a temporary directory during configure and switch to just "du -sk" if it fails.
Allan
I'm cross compiling; in that case, the host system has a different du than the target system, so testing at configure time would not be appropriate. Would checking at runtime be acceptable? Alternatively, I would be happy with a configure flag to override the default choice.
Would something like: DUFLAGS="-sk" ./configure work for you? This would be added to the "Some influential environment variables" section of the "./configure --help" output? Now I just need to figure out how to do this! A
On 6/23/16, Allan McRae <allan@archlinux.org> wrote:
Would something like:
DUFLAGS="-sk" ./configure
work for you? This would be added to the "Some influential environment variables" section of the "./configure --help" output?
Now I just need to figure out how to do this!
A
That would be fine :D I've sent in a patch to add DUFLAGS as a "precious" variable; I apologize for it not being inline :( Alastair Hughes
participants (3)
-
Alastair Hughes
-
Allan McRae
-
Florian Pritz