[pacman-dev] [PATCH 1/2] read cachedir from config file
--- contrib/paccache.sh.in | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/contrib/paccache.sh.in b/contrib/paccache.sh.in index 039ac8a..57c0458 100644 --- a/contrib/paccache.sh.in +++ b/contrib/paccache.sh.in @@ -25,7 +25,7 @@ declare -r myver='@PACKAGE_VERSION@' declare -a candidates=() cmdopts=() whitelist=() blacklist=() declare -i delete=0 dryrun=0 filecount=0 move=0 needsroot=0 totalsaved=0 verbose=0 -declare cachedir=@localstatedir@/cache/pacman/pkg delim=$'\n' keep=3 movedir= scanarch= +declare cachedir= delim=$'\n' keep=3 movedir= scanarch= USE_COLOR='y' @@ -37,6 +37,19 @@ die() { exit 1 } +get_cachedir_from_config() { + local key value + + while IFS=$'= \t' read -r key value _; do + if [[ $key = CacheDir ]]; then + echo "$value" + return 0 + fi + done <"$1" + + return 1 +} + # reads a list of files on stdin and prints out deletion candidates pkgfilter() { # there's whitelist and blacklist parameters passed to this @@ -165,8 +178,7 @@ Usage: ${myname} <operation> [options] [targets...] Options: -a, --arch <arch> scan for "arch" (default: all architectures). - -c, --cachedir <dir> scan "dir" for packages. - (default: @localstatedir@/cache/pacman/pkg). + -c, --cachedir <dir> scan "dir" for packages. (default: $cachedir). -f, --force apply force to mv(1) and rm(1) operations. -h, --help display this help message and exit. -i, --ignore <pkgs> ignore "pkgs", comma-separated. Alternatively, specify @@ -191,6 +203,8 @@ OPT_SHORT=':a:c:dfhi:k:m:rsuVvz' OPT_LONG=('arch:' 'cachedir:' 'dryrun' 'force' 'help' 'ignore:' 'keep:' 'move' 'nocolor' 'remove' 'uninstalled' 'version' 'verbose' 'null') +cachedir=$(get_cachedir_from_config "@sysconfdir@/pacman.conf") + if ! parseopts "$OPT_SHORT" "${OPT_LONG[@]}" -- "$@"; then exit 1 fi -- 2.0.0
Refactoring getcols, yet again. We do the following: 1) Introduce a static global in src/pacman/util.c 2) getcols always prefers this cached value, but will derive it from the COLUMNS environment var, the characteristics of stdout, or a sane default (in that order). 3) Introduce a SIGWINCH signal handler to reset the cached value, meaning we only call ioctl when we don't know the value. On my machine, pacman -Syy goes from ~4300 ioctl calls to 3. --- src/pacman/callback.c | 6 +++--- src/pacman/package.c | 4 ++-- src/pacman/pacman.c | 5 ++++- src/pacman/util.c | 59 +++++++++++++++++++++++++++++++++++++-------------- src/pacman/util.h | 3 ++- 5 files changed, 54 insertions(+), 23 deletions(-) diff --git a/src/pacman/callback.c b/src/pacman/callback.c index 9cde1de..6be20ec 100644 --- a/src/pacman/callback.c +++ b/src/pacman/callback.c @@ -424,7 +424,7 @@ void cb_question(alpm_question_t *question) "The following package cannot be upgraded due to unresolvable dependencies:\n", "The following packages cannot be upgraded due to unresolvable dependencies:\n", count)); - list_display(" ", namelist, getcols(fileno(stdout))); + list_display(" ", namelist, getcols()); printf("\n"); q->skip = noyes(_n( "Do you want to skip the above package for this upgrade?", @@ -494,7 +494,7 @@ void cb_progress(alpm_progress_t event, const char *pkgname, int percent, int len, wclen, wcwid, padwid; wchar_t *wcstr; - const unsigned short cols = getcols(fileno(stdout)); + const unsigned short cols = getcols(); if(config->noprogressbar || cols == 0) { return; @@ -664,7 +664,7 @@ void cb_dl_progress(const char *filename, off_t file_xfered, off_t file_total) const char *rate_label, *xfered_label; int file_percent = 0, total_percent = 0; - const unsigned short cols = getcols(fileno(stdout)); + const unsigned short cols = getcols(); if(config->noprogressbar || cols == 0 || file_total == -1) { if(file_xfered == 0) { diff --git a/src/pacman/package.c b/src/pacman/package.c index 3be996d..1ac0fca 100644 --- a/src/pacman/package.c +++ b/src/pacman/package.c @@ -140,7 +140,7 @@ void dump_pkg_full(alpm_pkg_t *pkg, int extra) optionalfor = alpm_pkg_compute_optionalfor(pkg); } - cols = getcols(fileno(stdout)); + cols = getcols(); /* actual output */ if(from == ALPM_PKG_FROM_SYNCDB) { @@ -404,7 +404,7 @@ int dump_pkg_search(alpm_db_t *db, alpm_list_t *targets, int show_status) return 1; } - cols = getcols(fileno(stdout)); + cols = getcols(); for(i = searchlist; i; i = alpm_list_next(i)) { alpm_list_t *grp; alpm_pkg_t *pkg = i->data; diff --git a/src/pacman/pacman.c b/src/pacman/pacman.c index e8c5f9e..ec200a9 100644 --- a/src/pacman/pacman.c +++ b/src/pacman/pacman.c @@ -312,6 +312,9 @@ static void handler(int signum) /* a transaction is being interrupted, don't exit pacman yet. */ return; } + } else if(signum == SIGWINCH) { + columns_cache_reset(); + return; } /* SIGINT/SIGHUP: no committing transaction, release it now and then exit pacman * SIGTERM: release no matter what */ @@ -1019,7 +1022,7 @@ int main(int argc, char *argv[]) int ret = 0; size_t i; struct sigaction new_action, old_action; - const int signals[] = { SIGHUP, SIGINT, SIGTERM, SIGSEGV }; + const int signals[] = { SIGHUP, SIGINT, SIGTERM, SIGSEGV, SIGWINCH }; uid_t myuid = getuid(); /* Set signal handlers */ diff --git a/src/pacman/util.c b/src/pacman/util.c index ebf15db..9244870 100644 --- a/src/pacman/util.c +++ b/src/pacman/util.c @@ -46,6 +46,7 @@ #include "conf.h" #include "callback.h" +static int cached_columns = 0; struct table_cell_t { char *label; @@ -155,29 +156,55 @@ static int flush_term_input(int fd) return 0; } -/* gets the current screen column width */ -unsigned short getcols(int fd) -{ - const unsigned short default_tty = 80; - const unsigned short default_notty = 0; - unsigned short termwidth = 0; +void columns_cache_reset() { + cached_columns = 0; +} - if(!isatty(fd)) { - return default_notty; - } +static int getcols_fd(int fd) { + int width = -1; #if defined(TIOCGSIZE) struct ttysize win; if(ioctl(fd, TIOCGSIZE, &win) == 0) { - termwidth = win.ts_cols; + width = win.ts_cols; } #elif defined(TIOCGWINSZ) struct winsize win; if(ioctl(fd, TIOCGWINSZ, &win) == 0) { - termwidth = win.ws_col; + width = win.ws_col; } #endif - return termwidth == 0 ? default_tty : termwidth; + + if(width <= 0) { + return -EIO; + } + + return width; +} + +unsigned short getcols(void) { + const char *e; + int c = 0; + + if(cached_columns > 0) { + return cached_columns; + } + + e = getenv("COLUMNS"); + if(e) { + c = strtol(e, NULL, 10); + } + + if(c <= 0) { + c = getcols_fd(STDOUT_FILENO); + } + + if(c <= 0) { + c = 80; + } + + cached_columns = c; + return c; } /* does the same thing as 'rm -rf' */ @@ -892,7 +919,7 @@ static void _display_targets(alpm_list_t *targets, int verbose) pm_asprintf(&str, "%s (%zd)", _("Packages"), alpm_list_count(targets)); printf("\n"); - cols = getcols(fileno(stdout)); + cols = getcols(); if(verbose) { header = create_verbose_header(alpm_list_count(targets)); if(table_display(header, rows, cols) != 0) { @@ -1196,7 +1223,7 @@ void display_new_optdepends(alpm_pkg_t *oldpkg, alpm_pkg_t *newpkg) if(optstrings) { printf(_("New optional dependencies for %s\n"), alpm_pkg_get_name(newpkg)); - unsigned short cols = getcols(fileno(stdout)); + unsigned short cols = getcols(); list_display_linebreak(" ", optstrings, cols); } @@ -1218,7 +1245,7 @@ void display_optdepends(alpm_pkg_t *pkg) if(optstrings) { printf(_("Optional dependencies for %s\n"), alpm_pkg_get_name(pkg)); - unsigned short cols = getcols(fileno(stdout)); + unsigned short cols = getcols(); list_display_linebreak(" ", optstrings, cols); } @@ -1241,7 +1268,7 @@ void select_display(const alpm_list_t *pkglist) alpm_list_t *list = NULL; char *string = NULL; const char *dbname = NULL; - unsigned short cols = getcols(fileno(stdout)); + unsigned short cols = getcols(); for(i = pkglist; i; i = i->next) { alpm_pkg_t *pkg = i->data; diff --git a/src/pacman/util.h b/src/pacman/util.h index 4a31e89..b591fba 100644 --- a/src/pacman/util.h +++ b/src/pacman/util.h @@ -49,7 +49,8 @@ int trans_init(alpm_transflag_t flags, int check_valid); int trans_release(void); int needs_root(void); int check_syncdbs(size_t need_repos, int check_valid); -unsigned short getcols(int fd); +unsigned short getcols(void); +void columns_cache_reset(void); int rmrf(const char *path); void indentprint(const char *str, unsigned short indent, unsigned short cols); size_t strtrim(char *str); -- 2.0.0
On 06/24/14 at 04:32pm, Dave Reisner wrote:
Refactoring getcols, yet again. We do the following:
1) Introduce a static global in src/pacman/util.c 2) getcols always prefers this cached value, but will derive it from the COLUMNS environment var, the characteristics of stdout, or a sane default (in that order). 3) Introduce a SIGWINCH signal handler to reset the cached value, meaning we only call ioctl when we don't know the value.
On my machine, pacman -Syy goes from ~4300 ioctl calls to 3. --- src/pacman/callback.c | 6 +++--- src/pacman/package.c | 4 ++-- src/pacman/pacman.c | 5 ++++- src/pacman/util.c | 59 +++++++++++++++++++++++++++++++++++++-------------- src/pacman/util.h | 3 ++- 5 files changed, 54 insertions(+), 23 deletions(-)
A few small nitpicks. <snip>
diff --git a/src/pacman/util.c b/src/pacman/util.c index ebf15db..9244870 100644 --- a/src/pacman/util.c +++ b/src/pacman/util.c @@ -46,6 +46,7 @@ #include "conf.h" #include "callback.h"
+static int cached_columns = 0;
struct table_cell_t { char *label; @@ -155,29 +156,55 @@ static int flush_term_input(int fd) return 0; }
-/* gets the current screen column width */ -unsigned short getcols(int fd) -{ - const unsigned short default_tty = 80; - const unsigned short default_notty = 0; - unsigned short termwidth = 0; +void columns_cache_reset() {
Opening brace needs to be on its own line and missing void parameter.
+ cached_columns = 0; +}
- if(!isatty(fd)) { - return default_notty; - } +static int getcols_fd(int fd) {
Opening brace.
+ int width = -1;
#if defined(TIOCGSIZE) struct ttysize win; if(ioctl(fd, TIOCGSIZE, &win) == 0) { - termwidth = win.ts_cols; + width = win.ts_cols; } #elif defined(TIOCGWINSZ) struct winsize win; if(ioctl(fd, TIOCGWINSZ, &win) == 0) { - termwidth = win.ws_col; + width = win.ws_col; } #endif - return termwidth == 0 ? default_tty : termwidth; + + if(width <= 0) { + return -EIO; + } + + return width; +} + +unsigned short getcols(void) {
Opening brace.
+ const char *e; + int c = 0; + + if(cached_columns > 0) { + return cached_columns; + } + + e = getenv("COLUMNS"); + if(e) { + c = strtol(e, NULL, 10); + } + + if(c <= 0) { + c = getcols_fd(STDOUT_FILENO); + } + + if(c <= 0) { + c = 80; + } + + cached_columns = c; + return c; }
/* does the same thing as 'rm -rf' */
On 28/06/14 12:44, Andrew Gregory wrote:
On 06/24/14 at 04:32pm, Dave Reisner wrote:
Refactoring getcols, yet again. We do the following:
1) Introduce a static global in src/pacman/util.c 2) getcols always prefers this cached value, but will derive it from the COLUMNS environment var, the characteristics of stdout, or a sane default (in that order). 3) Introduce a SIGWINCH signal handler to reset the cached value, meaning we only call ioctl when we don't know the value.
On my machine, pacman -Syy goes from ~4300 ioctl calls to 3. --- src/pacman/callback.c | 6 +++--- src/pacman/package.c | 4 ++-- src/pacman/pacman.c | 5 ++++- src/pacman/util.c | 59 +++++++++++++++++++++++++++++++++++++-------------- src/pacman/util.h | 3 ++- 5 files changed, 54 insertions(+), 23 deletions(-)
A few small nitpicks.
Made those changes as I pulled. A
On 06/24/14 at 04:32pm, Dave Reisner wrote:
--- contrib/paccache.sh.in | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-)
The default should be left in so this doesn't die if no CacheDir is specified in pacman.conf and the user doesn't provide one on the command-line: $ ./paccache -d ==> ERROR: cachedir '' does not exist or is not a directory apg
diff --git a/contrib/paccache.sh.in b/contrib/paccache.sh.in index 039ac8a..57c0458 100644 --- a/contrib/paccache.sh.in +++ b/contrib/paccache.sh.in @@ -25,7 +25,7 @@ declare -r myver='@PACKAGE_VERSION@'
declare -a candidates=() cmdopts=() whitelist=() blacklist=() declare -i delete=0 dryrun=0 filecount=0 move=0 needsroot=0 totalsaved=0 verbose=0 -declare cachedir=@localstatedir@/cache/pacman/pkg delim=$'\n' keep=3 movedir= scanarch= +declare cachedir= delim=$'\n' keep=3 movedir= scanarch=
USE_COLOR='y'
@@ -37,6 +37,19 @@ die() { exit 1 }
+get_cachedir_from_config() { + local key value + + while IFS=$'= \t' read -r key value _; do + if [[ $key = CacheDir ]]; then + echo "$value" + return 0 + fi + done <"$1" + + return 1 +} + # reads a list of files on stdin and prints out deletion candidates pkgfilter() { # there's whitelist and blacklist parameters passed to this @@ -165,8 +178,7 @@ Usage: ${myname} <operation> [options] [targets...]
Options: -a, --arch <arch> scan for "arch" (default: all architectures). - -c, --cachedir <dir> scan "dir" for packages. - (default: @localstatedir@/cache/pacman/pkg). + -c, --cachedir <dir> scan "dir" for packages. (default: $cachedir). -f, --force apply force to mv(1) and rm(1) operations. -h, --help display this help message and exit. -i, --ignore <pkgs> ignore "pkgs", comma-separated. Alternatively, specify @@ -191,6 +203,8 @@ OPT_SHORT=':a:c:dfhi:k:m:rsuVvz' OPT_LONG=('arch:' 'cachedir:' 'dryrun' 'force' 'help' 'ignore:' 'keep:' 'move' 'nocolor' 'remove' 'uninstalled' 'version' 'verbose' 'null')
+cachedir=$(get_cachedir_from_config "@sysconfdir@/pacman.conf") + if ! parseopts "$OPT_SHORT" "${OPT_LONG[@]}" -- "$@"; then exit 1 fi -- 2.0.0
participants (3)
-
Allan McRae
-
Andrew Gregory
-
Dave Reisner