summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/import/importctl.c2
-rw-r--r--src/libsystemd/sd-bus/bus-common-errors.c2
-rw-r--r--src/libsystemd/sd-bus/bus-common-errors.h2
-rw-r--r--src/partition/repart.c2
-rw-r--r--src/shared/pretty-print.c51
-rw-r--r--src/shared/pretty-print.h2
-rw-r--r--src/sysupdate/sysupdated.c5
-rw-r--r--src/sysupdate/updatectl.c34
-rw-r--r--src/test/test-progress-bar.c2
9 files changed, 70 insertions, 32 deletions
diff --git a/src/import/importctl.c b/src/import/importctl.c
index 27c26a70e8..85903bb8c6 100644
--- a/src/import/importctl.c
+++ b/src/import/importctl.c
@@ -45,7 +45,7 @@ static const char* arg_format = NULL;
static sd_json_format_flags_t arg_json_format_flags = SD_JSON_FORMAT_OFF;
static ImageClass arg_image_class = _IMAGE_CLASS_INVALID;
-#define PROGRESS_PREFIX "Total: "
+#define PROGRESS_PREFIX "Total:"
static int settle_image_class(void) {
diff --git a/src/libsystemd/sd-bus/bus-common-errors.c b/src/libsystemd/sd-bus/bus-common-errors.c
index 5b18241f00..db1285e7f0 100644
--- a/src/libsystemd/sd-bus/bus-common-errors.c
+++ b/src/libsystemd/sd-bus/bus-common-errors.c
@@ -153,5 +153,7 @@ BUS_ERROR_MAP_ELF_REGISTER const sd_bus_error_map bus_common_errors[] = {
SD_BUS_ERROR_MAP(BUS_ERROR_REBALANCE_NOT_NEEDED, EALREADY),
SD_BUS_ERROR_MAP(BUS_ERROR_HOME_NOT_REFERENCED, EBADR),
+ SD_BUS_ERROR_MAP(BUS_ERROR_NO_UPDATE_CANDIDATE, EALREADY),
+
SD_BUS_ERROR_MAP_END
};
diff --git a/src/libsystemd/sd-bus/bus-common-errors.h b/src/libsystemd/sd-bus/bus-common-errors.h
index fb1d421168..622cf4933d 100644
--- a/src/libsystemd/sd-bus/bus-common-errors.h
+++ b/src/libsystemd/sd-bus/bus-common-errors.h
@@ -158,4 +158,6 @@
#define BUS_ERROR_REBALANCE_NOT_NEEDED "org.freedesktop.home1.RebalanceNotNeeded"
#define BUS_ERROR_HOME_NOT_REFERENCED "org.freedesktop.home1.HomeNotReferenced"
+#define BUS_ERROR_NO_UPDATE_CANDIDATE "org.freedesktop.sysupdate1.NoCandidate"
+
BUS_ERROR_MAP_ELF_USE(bus_common_errors);
diff --git a/src/partition/repart.c b/src/partition/repart.c
index e14c9a4750..48b3b43013 100644
--- a/src/partition/repart.c
+++ b/src/partition/repart.c
@@ -4553,7 +4553,7 @@ static int progress_bytes(uint64_t n_bytes, void *userdata) {
p->copy_blocks_done += n_bytes;
- if (asprintf(&s, "%s %s %s %s/%s ",
+ if (asprintf(&s, "%s %s %s %s/%s",
strna(p->copy_blocks_path),
special_glyph(SPECIAL_GLYPH_ARROW_RIGHT),
strna(p->definition_path),
diff --git a/src/shared/pretty-print.c b/src/shared/pretty-print.c
index f361c4760a..cc226e72ea 100644
--- a/src/shared/pretty-print.c
+++ b/src/shared/pretty-print.c
@@ -460,21 +460,16 @@ bool shall_tint_background(void) {
return cache != 0;
}
-void draw_progress_bar(const char *prefix, double percentage) {
-
- /* We are going output a bunch of small strings that shall appear as a single line to STDERR which is
- * unbuffered by default. Let's temporarily turn on full buffering, so that this is passed to the tty
- * as a single buffer, to make things more efficient. */
- char buffer[LONG_LINE_MAX];
- setvbuf(stderr, buffer, _IOFBF, sizeof(buffer));
-
+void draw_progress_bar_unbuffered(const char *prefix, double percentage) {
fputc('\r', stderr);
- if (prefix)
+ if (prefix) {
fputs(prefix, stderr);
+ fputc(' ', stderr);
+ }
if (!terminal_is_dumb()) {
size_t cols = columns();
- size_t prefix_width = utf8_console_width(prefix);
+ size_t prefix_width = utf8_console_width(prefix) + 1 /* space */;
size_t length = cols > prefix_width + 6 ? cols - prefix_width - 6 : 0;
if (length > 5 && percentage >= 0.0 && percentage <= 100.0) {
@@ -518,30 +513,46 @@ void draw_progress_bar(const char *prefix, double percentage) {
fputs(ANSI_ERASE_TO_END_OF_LINE, stderr);
fputc('\r', stderr);
- fflush(stderr);
- /* Disable buffering again */
- setvbuf(stderr, NULL, _IONBF, 0);
}
-void clear_progress_bar(const char *prefix) {
-
- char buffer[LONG_LINE_MAX];
- setvbuf(stderr, buffer, _IOFBF, sizeof(buffer));
-
+void clear_progress_bar_unbuffered(const char *prefix) {
fputc('\r', stderr);
if (terminal_is_dumb())
fputs(strrepa(" ",
- prefix ? utf8_console_width(prefix) + 4 :
- LESS_BY(columns(), 1U)), /* 4: %3.0f%% */
+ prefix ? utf8_console_width(prefix) + 5 : /* %3.0f%% (4 chars) + space */
+ LESS_BY(columns(), 1U)),
stderr);
else
fputs(ANSI_ERASE_TO_END_OF_LINE, stderr);
fputc('\r', stderr);
+}
+
+void draw_progress_bar(const char *prefix, double percentage) {
+
+ /* We are going output a bunch of small strings that shall appear as a single line to STDERR which is
+ * unbuffered by default. Let's temporarily turn on full buffering, so that this is passed to the tty
+ * as a single buffer, to make things more efficient. */
+ char buffer[LONG_LINE_MAX];
+ setvbuf(stderr, buffer, _IOFBF, sizeof(buffer));
+
+ draw_progress_bar_unbuffered(prefix, percentage);
+
fflush(stderr);
/* Disable buffering again */
setvbuf(stderr, NULL, _IONBF, 0);
}
+
+void clear_progress_bar(const char *prefix) {
+ char buffer[LONG_LINE_MAX];
+ setvbuf(stderr, buffer, _IOFBF, sizeof(buffer));
+
+ clear_progress_bar_unbuffered(prefix);
+
+ fflush(stderr);
+
+ setvbuf(stderr, NULL, _IONBF, 0);
+}
diff --git a/src/shared/pretty-print.h b/src/shared/pretty-print.h
index 2c97c354ef..d3af149a2e 100644
--- a/src/shared/pretty-print.h
+++ b/src/shared/pretty-print.h
@@ -55,3 +55,5 @@ bool shall_tint_background(void);
void draw_progress_bar(const char *prefix, double percentage);
void clear_progress_bar(const char *prefix);
+void draw_progress_bar_unbuffered(const char *prefix, double percentage);
+void clear_progress_bar_unbuffered(const char *prefix);
diff --git a/src/sysupdate/sysupdated.c b/src/sysupdate/sysupdated.c
index 4edfea937e..9a078aa84a 100644
--- a/src/sysupdate/sysupdated.c
+++ b/src/sysupdate/sysupdated.c
@@ -4,6 +4,7 @@
#include "sd-json.h"
#include "build-path.h"
+#include "bus-common-errors.h"
#include "bus-error.h"
#include "bus-get-properties.h"
#include "bus-label.h"
@@ -1044,8 +1045,8 @@ static int target_method_update_finished_early(
/* Called when job finishes w/ a successful exit code, but before any work begins.
* This happens when there is no candidate (i.e. we're already up-to-date), or
* specified update is already installed. */
- return sd_bus_error_setf(error, "org.freedesktop.sysupdate1.NoCandidate",
- "Job exited successfully with no work to do, assume already updated");
+ return sd_bus_error_setf(error, BUS_ERROR_NO_UPDATE_CANDIDATE,
+ "Job exited successfully with no work to do, assume already updated");
}
static int target_method_update_detach(sd_bus_message *msg, const Job *j) {
diff --git a/src/sysupdate/updatectl.c b/src/sysupdate/updatectl.c
index d5f74bff3e..c298b24464 100644
--- a/src/sysupdate/updatectl.c
+++ b/src/sysupdate/updatectl.c
@@ -13,6 +13,7 @@
#include "bus-map-properties.h"
#include "bus-util.h"
#include "errno-list.h"
+#include "fileio.h"
#include "format-table.h"
#include "json-util.h"
#include "main-func.h"
@@ -775,6 +776,7 @@ static int verb_check(int argc, char **argv, void *userdata) {
}
#define UPDATE_PROGRESS_FAILED INT_MIN
+#define UPDATE_PROGRESS_DONE INT_MAX
/* Make sure it doesn't overlap w/ errno values */
assert_cc(UPDATE_PROGRESS_FAILED < -ERRNO_MAX);
@@ -794,6 +796,11 @@ static int update_render_progress(sd_event_source *source, void *userdata) {
if (n == 0)
return 0;
+ /* We're outputting lots of small strings to STDERR, which is unbuffered by default. So let's turn
+ * on full buffering, so we pass this all to the TTY in one go, to make things more efficient */
+ char buffer[LONG_LINE_MAX];
+ setvbuf(stderr, buffer, _IOFBF, sizeof(buffer));
+
if (!terminal_is_dumb()) {
for (size_t i = 0; i <= n; i++)
fputs("\n", stderr); /* Possibly scroll the terminal to make room (including total)*/
@@ -808,24 +815,36 @@ static int update_render_progress(sd_event_source *source, void *userdata) {
int progress = PTR_TO_INT(p);
if (progress == UPDATE_PROGRESS_FAILED) {
- fprintf(stderr, "%s %s\n", RED_CROSS_MARK(), target);
+ clear_progress_bar_unbuffered(target);
+ fprintf(stderr, "%s: %s Unknown failure\n", target, RED_CROSS_MARK());
total += 100;
} else if (progress == -EALREADY) {
- fprintf(stderr, "%s %s (Already up-to-date)\n", GREEN_CHECK_MARK(), target);
+ clear_progress_bar_unbuffered(target);
+ fprintf(stderr, "%s: %s Already up-to-date\n", target, GREEN_CHECK_MARK());
n--; /* Don't consider this target in the total */
} else if (progress < 0) {
- fprintf(stderr, "%s %s (%s)\n", RED_CROSS_MARK(), target, STRERROR(progress));
+ clear_progress_bar_unbuffered(target);
+ fprintf(stderr, "%s: %s %s\n", target, RED_CROSS_MARK(), STRERROR(progress));
+ total += 100;
+ } else if (progress == UPDATE_PROGRESS_DONE) {
+ clear_progress_bar_unbuffered(target);
+ fprintf(stderr, "%s: %s Done\n", target, GREEN_CHECK_MARK());
total += 100;
} else {
- draw_progress_bar(target, progress);
+ draw_progress_bar_unbuffered(target, progress);
fputs("\n", stderr);
total += progress;
}
}
if (n > 1) {
- draw_progress_bar("TOTAL", (double) total / n);
- fputs("\n", stderr);
+ if (exiting)
+ clear_progress_bar_unbuffered(target);
+ else {
+ draw_progress_bar_unbuffered("Total", (double) total / n);
+ if (terminal_is_dumb())
+ fputs("\n", stderr);
+ }
}
if (!terminal_is_dumb()) {
@@ -837,6 +856,7 @@ static int update_render_progress(sd_event_source *source, void *userdata) {
fputs("------\n", stderr);
fflush(stderr);
+ setvbuf(stderr, NULL, _IONBF, 0); /* Disable buffering again */
return 0;
}
@@ -895,7 +915,7 @@ static int update_finished(sd_bus_message *m, void *userdata, sd_bus_error *erro
}
if (status == 0) /* success */
- status = 100;
+ status = UPDATE_PROGRESS_DONE;
else if (status > 0) /* exit status without errno */
status = UPDATE_PROGRESS_FAILED; /* i.e. EXIT_FAILURE */
/* else errno */
diff --git a/src/test/test-progress-bar.c b/src/test/test-progress-bar.c
index b47adf0c28..abc1d292dc 100644
--- a/src/test/test-progress-bar.c
+++ b/src/test/test-progress-bar.c
@@ -4,7 +4,7 @@
#include "random-util.h"
#include "tests.h"
-#define PROGRESS_PREFIX "test: "
+#define PROGRESS_PREFIX "test:"
TEST(progress_bar) {