summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTimo Teräs <timo.teras@iki.fi>2011-03-19 15:20:47 +0200
committerTimo Teräs <timo.teras@iki.fi>2011-03-19 15:20:47 +0200
commit116d9a0ea7a5e903a344f7e6044dd019349bc01c (patch)
tree01eca1b5db71ffca39bc07951f9e0eaf17cc34e8
parent7b6e44b11b4b419a6af91555270b1ddc981c5a74 (diff)
downloadapk-tools-116d9a0ea7a5e903a344f7e6044dd019349bc01c.tar.bz2
apk-tools-116d9a0ea7a5e903a344f7e6044dd019349bc01c.tar.xz
apk: improve progress bar
* make it as wide as the screen * make sure it's drawn after package change * and draw it using ansi escapes in line buffered stderr
-rw-r--r--src/apk.c20
-rw-r--r--src/apk_defines.h1
-rw-r--r--src/state.c20
3 files changed, 29 insertions, 12 deletions
diff --git a/src/apk.c b/src/apk.c
index e8b8b12..55963b0 100644
--- a/src/apk.c
+++ b/src/apk.c
@@ -19,6 +19,7 @@
#include <getopt.h>
#include <unistd.h>
#include <sys/stat.h>
+#include <sys/ioctl.h>
#include <openssl/crypto.h>
#ifndef OPENSSL_NO_ENGINE
@@ -32,6 +33,7 @@
#include "apk_print.h"
char **apk_argv;
+int apk_screen_width;
static struct apk_option generic_options[] = {
{ 'h', "help", "Show generic help or applet specific help" },
@@ -238,6 +240,20 @@ static void init_openssl(void)
#endif
}
+static void setup_terminal(void)
+{
+ struct winsize w;
+
+ setvbuf(stderr, NULL, _IOLBF, BUFSIZ);
+ if (ioctl(STDERR_FILENO,TIOCGWINSZ, &w) == 0)
+ apk_screen_width = w.ws_col;
+ else
+ apk_screen_width = 70;
+ if (isatty(STDOUT_FILENO) && isatty(STDERR_FILENO) && isatty(STDIN_FILENO))
+ apk_flags |= APK_PROGRESS;
+
+}
+
int main(int argc, char **argv)
{
struct apk_applet *applet;
@@ -257,9 +273,7 @@ int main(int argc, char **argv)
list_init(&dbopts.repository_list);
apk_atom_init();
umask(0);
-
- if (isatty(STDOUT_FILENO) && isatty(STDERR_FILENO) && isatty(STDIN_FILENO))
- apk_flags |= APK_PROGRESS;
+ setup_terminal();
applet = deduce_applet(argc, argv);
num_options = ARRAY_SIZE(generic_options) + 1;
diff --git a/src/apk_defines.h b/src/apk_defines.h
index b11d181..b5ad12e 100644
--- a/src/apk_defines.h
+++ b/src/apk_defines.h
@@ -51,6 +51,7 @@ extern int apk_verbosity;
extern unsigned int apk_flags;
extern const char *apk_arch;
extern char **apk_argv;
+extern int apk_screen_width;
#define APK_FORCE 0x0001
#define APK_SIMULATE 0x0002
diff --git a/src/state.c b/src/state.c
index 3a8d3a6..cb6e5cc 100644
--- a/src/state.c
+++ b/src/state.c
@@ -668,19 +668,19 @@ static void apk_count_change(struct apk_change *change, struct apk_stats *stats)
stats->packages ++;
}
-static inline void apk_draw_progress(int percent)
+static void apk_draw_progress(int percent)
{
- char tmp[128];
- char reset[128];
+ const int bar_width = (apk_screen_width - 15);
int i;
- snprintf(tmp, sizeof(tmp), "-[ ]- %3i%%", percent);
- for (i = 0; (i < (percent/5)) && (i < (sizeof(tmp)-2)); i++)
- tmp[2+i] = '#';
- memset(reset, '\b', strlen(tmp));
- fwrite(tmp, strlen(tmp), 1, stderr);
- fwrite(reset, strlen(tmp), 1, stderr);
+ fputs("\e7-[", stderr);
+ for (i = 0; i < bar_width * percent / 100; i++)
+ fputc('#', stderr);
+ for (; i < bar_width; i++)
+ fputc(' ', stderr);
+ fprintf(stderr, "]- %3i%%", percent);
fflush(stderr);
+ fputs("\e8\e[0K", stderr);
}
struct progress {
@@ -950,6 +950,8 @@ int apk_state_commit(struct apk_state *state,
list_for_each_entry(change, &state->change_list_head, change_list) {
n++;
apk_print_change(db, change->oldpkg, change->newpkg, n, state->num_changes);
+ if (apk_flags & APK_PROGRESS)
+ apk_draw_progress(prog.count);
prog.pkg = change->newpkg;
if (!(apk_flags & APK_SIMULATE)) {