apk: implement --progress-fd to write progress to a specified fd
parent
8a4371ccd7
commit
43850a126b
|
@ -48,6 +48,7 @@ static struct apk_option generic_options[] = {
|
||||||
{ 'f', "force", "Do what was asked even if it looks dangerous" },
|
{ 'f', "force", "Do what was asked even if it looks dangerous" },
|
||||||
{ 'U', "update-cache", "Update the repository cache" },
|
{ 'U', "update-cache", "Update the repository cache" },
|
||||||
{ 0x101, "progress", "Show a progress bar" },
|
{ 0x101, "progress", "Show a progress bar" },
|
||||||
|
{ 0x10f, "progress-fd", "Write progress to fd", required_argument, "FD" },
|
||||||
{ 0x110, "no-progress", "Disable progress bar even for TTYs" },
|
{ 0x110, "no-progress", "Disable progress bar even for TTYs" },
|
||||||
{ 0x102, "clean-protected", "Do not create .apk-new files to "
|
{ 0x102, "clean-protected", "Do not create .apk-new files to "
|
||||||
"configuration dirs" },
|
"configuration dirs" },
|
||||||
|
@ -265,6 +266,7 @@ static void setup_terminal(void)
|
||||||
{
|
{
|
||||||
setvbuf(stderr, NULL, _IOLBF, BUFSIZ);
|
setvbuf(stderr, NULL, _IOLBF, BUFSIZ);
|
||||||
signal(SIGWINCH, on_sigwinch);
|
signal(SIGWINCH, on_sigwinch);
|
||||||
|
signal(SIGPIPE, SIG_IGN);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void setup_automatic_flags(void)
|
static void setup_automatic_flags(void)
|
||||||
|
@ -383,6 +385,9 @@ int main(int argc, char **argv)
|
||||||
case 0x110:
|
case 0x110:
|
||||||
apk_flags &= ~APK_PROGRESS;
|
apk_flags &= ~APK_PROGRESS;
|
||||||
break;
|
break;
|
||||||
|
case 0x10f:
|
||||||
|
dbopts.progress_fd = atoi(optarg);
|
||||||
|
break;
|
||||||
case 0x102:
|
case 0x102:
|
||||||
apk_flags |= APK_CLEAN_PROTECTED;
|
apk_flags |= APK_CLEAN_PROTECTED;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -108,7 +108,7 @@ struct apk_repository_list {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct apk_db_options {
|
struct apk_db_options {
|
||||||
int lock_wait;
|
int lock_wait, progress_fd;
|
||||||
unsigned long open_flags;
|
unsigned long open_flags;
|
||||||
char *root;
|
char *root;
|
||||||
char *arch;
|
char *arch;
|
||||||
|
@ -127,7 +127,7 @@ struct apk_repository_tag {
|
||||||
|
|
||||||
struct apk_database {
|
struct apk_database {
|
||||||
char *root;
|
char *root;
|
||||||
int root_fd, lock_fd, cache_fd, cachetmp_fd, keys_fd;
|
int root_fd, lock_fd, cache_fd, cachetmp_fd, keys_fd, progress_fd;
|
||||||
unsigned num_repos, num_repo_tags;
|
unsigned num_repos, num_repo_tags;
|
||||||
const char *cache_dir;
|
const char *cache_dir;
|
||||||
char *cache_remount_dir;
|
char *cache_remount_dir;
|
||||||
|
|
|
@ -1359,6 +1359,7 @@ int apk_db_open(struct apk_database *db, struct apk_db_options *dbopts)
|
||||||
int r, fd, write_arch = FALSE;
|
int r, fd, write_arch = FALSE;
|
||||||
|
|
||||||
memset(db, 0, sizeof(*db));
|
memset(db, 0, sizeof(*db));
|
||||||
|
db->progress_fd = dbopts->progress_fd;
|
||||||
if (apk_flags & APK_SIMULATE) {
|
if (apk_flags & APK_SIMULATE) {
|
||||||
dbopts->open_flags &= ~(APK_OPENF_CREATE | APK_OPENF_WRITE);
|
dbopts->open_flags &= ~(APK_OPENF_CREATE | APK_OPENF_WRITE);
|
||||||
dbopts->open_flags |= APK_OPENF_READ;
|
dbopts->open_flags |= APK_OPENF_READ;
|
||||||
|
|
42
src/solver.c
42
src/solver.c
|
@ -10,6 +10,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <unistd.h>
|
||||||
#include "apk_defines.h"
|
#include "apk_defines.h"
|
||||||
#include "apk_database.h"
|
#include "apk_database.h"
|
||||||
#include "apk_package.h"
|
#include "apk_package.h"
|
||||||
|
@ -1650,23 +1651,34 @@ struct progress {
|
||||||
struct apk_stats done;
|
struct apk_stats done;
|
||||||
struct apk_stats total;
|
struct apk_stats total;
|
||||||
struct apk_package *pkg;
|
struct apk_package *pkg;
|
||||||
size_t count;
|
size_t percent;
|
||||||
|
int progress_fd;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void progress_cb(void *ctx, size_t progress)
|
static void update_progress(struct progress *prog, size_t percent)
|
||||||
|
{
|
||||||
|
if (prog->percent == percent)
|
||||||
|
return;
|
||||||
|
prog->percent = percent;
|
||||||
|
if (apk_flags & APK_PROGRESS)
|
||||||
|
draw_progress(percent);
|
||||||
|
if (prog->progress_fd != 0) {
|
||||||
|
char buf[8];
|
||||||
|
size_t n = snprintf(buf, sizeof(buf), "%d\n", percent);
|
||||||
|
write(prog->progress_fd, buf, n);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void progress_cb(void *ctx, size_t pkg_percent)
|
||||||
{
|
{
|
||||||
struct progress *prog = (struct progress *) ctx;
|
struct progress *prog = (struct progress *) ctx;
|
||||||
size_t partial = 0, count;
|
size_t partial = 0, percent;
|
||||||
|
|
||||||
if (prog->pkg != NULL)
|
if (prog->pkg != NULL)
|
||||||
partial = muldiv(progress, prog->pkg->installed_size, APK_PROGRESS_SCALE);
|
partial = muldiv(pkg_percent, prog->pkg->installed_size, APK_PROGRESS_SCALE);
|
||||||
|
percent = muldiv(100, prog->done.bytes + prog->done.packages + partial,
|
||||||
count = muldiv(100, prog->done.bytes + prog->done.packages + partial,
|
|
||||||
prog->total.bytes + prog->total.packages);
|
prog->total.bytes + prog->total.packages);
|
||||||
|
update_progress(prog, percent);
|
||||||
if (prog->count != count)
|
|
||||||
draw_progress(count);
|
|
||||||
prog->count = count;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dump_packages(struct apk_changeset *changeset,
|
static int dump_packages(struct apk_changeset *changeset,
|
||||||
|
@ -1784,6 +1796,7 @@ int apk_solver_commit_changeset(struct apk_database *db,
|
||||||
|
|
||||||
/* Count what needs to be done */
|
/* Count what needs to be done */
|
||||||
memset(&prog, 0, sizeof(prog));
|
memset(&prog, 0, sizeof(prog));
|
||||||
|
prog.progress_fd = db->progress_fd;
|
||||||
for (i = 0; i < changeset->changes->num; i++) {
|
for (i = 0; i < changeset->changes->num; i++) {
|
||||||
change = &changeset->changes->item[i];
|
change = &changeset->changes->item[i];
|
||||||
count_change(change, &prog.total);
|
count_change(change, &prog.total);
|
||||||
|
@ -1831,17 +1844,15 @@ int apk_solver_commit_changeset(struct apk_database *db,
|
||||||
change = &changeset->changes->item[i];
|
change = &changeset->changes->item[i];
|
||||||
|
|
||||||
print_change(db, change, i, changeset->changes->num);
|
print_change(db, change, i, changeset->changes->num);
|
||||||
if (apk_flags & APK_PROGRESS)
|
|
||||||
draw_progress(prog.count);
|
|
||||||
prog.pkg = change->newpkg;
|
prog.pkg = change->newpkg;
|
||||||
|
progress_cb(&prog, 0);
|
||||||
|
|
||||||
if (!(apk_flags & APK_SIMULATE)) {
|
if (!(apk_flags & APK_SIMULATE)) {
|
||||||
if (change->oldpkg != change->newpkg ||
|
if (change->oldpkg != change->newpkg ||
|
||||||
(change->reinstall && pkg_available(db, change->newpkg)))
|
(change->reinstall && pkg_available(db, change->newpkg)))
|
||||||
r = apk_db_install_pkg(db,
|
r = apk_db_install_pkg(db,
|
||||||
change->oldpkg, change->newpkg,
|
change->oldpkg, change->newpkg,
|
||||||
(apk_flags & APK_PROGRESS) ? progress_cb : NULL,
|
progress_cb, &prog);
|
||||||
&prog);
|
|
||||||
if (r != 0)
|
if (r != 0)
|
||||||
break;
|
break;
|
||||||
if (change->newpkg)
|
if (change->newpkg)
|
||||||
|
@ -1850,8 +1861,7 @@ int apk_solver_commit_changeset(struct apk_database *db,
|
||||||
|
|
||||||
count_change(change, &prog.done);
|
count_change(change, &prog.done);
|
||||||
}
|
}
|
||||||
if (apk_flags & APK_PROGRESS)
|
update_progress(&prog, 100);
|
||||||
draw_progress(100);
|
|
||||||
|
|
||||||
run_triggers(db);
|
run_triggers(db);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue