aboutsummaryrefslogtreecommitdiffstats
path: root/main/apk-tools/0002-apk-implement-progress-fd-to-write-progress-to-a-spe.patch
blob: 7f57ac78d02bc9d7bfdf0c2ebbbe0beb3f8cfd39 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
From 43850a126b94690302bc2564905141b077b490e7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timo=20Ter=C3=A4s?= <timo.teras@iki.fi>
Date: Thu, 20 Sep 2012 15:12:15 +0300
Subject: [PATCH] apk: implement --progress-fd to write progress to a
 specified fd

---
 src/apk.c          |  5 +++++
 src/apk_database.h |  4 ++--
 src/database.c     |  1 +
 src/solver.c       | 44 +++++++++++++++++++++++++++-----------------
 4 files changed, 35 insertions(+), 19 deletions(-)

diff --git a/src/apk.c b/src/apk.c
index 3bf1154..0404831 100644
--- a/src/apk.c
+++ b/src/apk.c
@@ -48,6 +48,7 @@ static struct apk_option generic_options[] = {
 	{ 'f', "force",		"Do what was asked even if it looks dangerous" },
 	{ 'U', "update-cache",	"Update the repository cache" },
 	{ 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" },
 	{ 0x102, "clean-protected", "Do not create .apk-new files to "
 				"configuration dirs" },
@@ -265,6 +266,7 @@ static void setup_terminal(void)
 {
 	setvbuf(stderr, NULL, _IOLBF, BUFSIZ);
 	signal(SIGWINCH, on_sigwinch);
+	signal(SIGPIPE, SIG_IGN);
 }
 
 static void setup_automatic_flags(void)
@@ -383,6 +385,9 @@ int main(int argc, char **argv)
 		case 0x110:
 			apk_flags &= ~APK_PROGRESS;
 			break;
+		case 0x10f:
+			dbopts.progress_fd = atoi(optarg);
+			break;
 		case 0x102:
 			apk_flags |= APK_CLEAN_PROTECTED;
 			break;
diff --git a/src/apk_database.h b/src/apk_database.h
index 235030c..4628c23 100644
--- a/src/apk_database.h
+++ b/src/apk_database.h
@@ -108,7 +108,7 @@ struct apk_repository_list {
 };
 
 struct apk_db_options {
-	int lock_wait;
+	int lock_wait, progress_fd;
 	unsigned long open_flags;
 	char *root;
 	char *arch;
@@ -127,7 +127,7 @@ struct apk_repository_tag {
 
 struct apk_database {
 	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;
 	const char *cache_dir;
 	char *cache_remount_dir;
diff --git a/src/database.c b/src/database.c
index d1a8f1a..e130f0b 100644
--- a/src/database.c
+++ b/src/database.c
@@ -1359,6 +1359,7 @@ int apk_db_open(struct apk_database *db, struct apk_db_options *dbopts)
 	int r, fd, write_arch = FALSE;
 
 	memset(db, 0, sizeof(*db));
+	db->progress_fd = dbopts->progress_fd;
 	if (apk_flags & APK_SIMULATE) {
 		dbopts->open_flags &= ~(APK_OPENF_CREATE | APK_OPENF_WRITE);
 		dbopts->open_flags |= APK_OPENF_READ;
diff --git a/src/solver.c b/src/solver.c
index 457d5ff..ec44958 100644
--- a/src/solver.c
+++ b/src/solver.c
@@ -10,6 +10,7 @@
  */
 
 #include <stdint.h>
+#include <unistd.h>
 #include "apk_defines.h"
 #include "apk_database.h"
 #include "apk_package.h"
@@ -1650,23 +1651,34 @@ struct progress {
 	struct apk_stats done;
 	struct apk_stats total;
 	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;
-	size_t partial = 0, count;
+	size_t partial = 0, percent;
 
 	if (prog->pkg != NULL)
-		partial = muldiv(progress, prog->pkg->installed_size, APK_PROGRESS_SCALE);
-
-        count = muldiv(100, prog->done.bytes + prog->done.packages + partial,
-		       prog->total.bytes + prog->total.packages);
-
-	if (prog->count != count)
-		draw_progress(count);
-	prog->count = count;
+		partial = muldiv(pkg_percent, prog->pkg->installed_size, APK_PROGRESS_SCALE);
+	percent = muldiv(100, prog->done.bytes + prog->done.packages + partial,
+			 prog->total.bytes + prog->total.packages);
+	update_progress(prog, percent);
 }
 
 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 */
 	memset(&prog, 0, sizeof(prog));
+	prog.progress_fd = db->progress_fd;
 	for (i = 0; i < changeset->changes->num; i++) {
 		change = &changeset->changes->item[i];
 		count_change(change, &prog.total);
@@ -1831,17 +1844,15 @@ int apk_solver_commit_changeset(struct apk_database *db,
 		change = &changeset->changes->item[i];
 
 		print_change(db, change, i, changeset->changes->num);
-		if (apk_flags & APK_PROGRESS)
-			draw_progress(prog.count);
 		prog.pkg = change->newpkg;
+		progress_cb(&prog, 0);
 
 		if (!(apk_flags & APK_SIMULATE)) {
 			if (change->oldpkg != change->newpkg ||
 			    (change->reinstall && pkg_available(db, change->newpkg)))
 				r = apk_db_install_pkg(db,
 						       change->oldpkg, change->newpkg,
-						       (apk_flags & APK_PROGRESS) ? progress_cb : NULL,
-						       &prog);
+						       progress_cb, &prog);
 			if (r != 0)
 				break;
 			if (change->newpkg)
@@ -1850,8 +1861,7 @@ int apk_solver_commit_changeset(struct apk_database *db,
 
 		count_change(change, &prog.done);
 	}
-	if (apk_flags & APK_PROGRESS)
-		draw_progress(100);
+	update_progress(&prog, 100);
 
 	run_triggers(db);
 
-- 
1.7.12.2