aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlns <matzeton@googlemail.com>2019-12-25 22:25:37 +0100
committerlns <matzeton@googlemail.com>2019-12-25 22:25:37 +0100
commitd85f361b1cb7f6b55b41a3224b3ffae6841e6385 (patch)
tree133c50662cedb1275037dd57b0051d983c0dacab
parent25b6686948c1602ad0800d54bd2160970c245bca (diff)
splitted terminal properties and file_info data, restrict final printf length, increased minimal required progressbar width to 16 chars
-rw-r--r--progressbar.c96
1 files changed, 57 insertions, 39 deletions
diff --git a/progressbar.c b/progressbar.c
index 52c168f..9683d09 100644
--- a/progressbar.c
+++ b/progressbar.c
@@ -142,11 +142,14 @@ struct file_info {
float last_reported_rate;
} xfer_rate_history;
struct {
- struct winsize dimensions;
- char output[MAX_TERMINAL_LEN];
+ char buf[MAX_TERMINAL_LEN];
size_t printable_chars;
size_t unprintable_chars;
- } terminal;
+ } terminal_output;
+};
+
+struct terminal {
+ struct winsize dimensions;
};
static int setup_file_info(struct file_info * const finfo, int proc_fd_fd, int proc_fdinfo_fd)
@@ -226,26 +229,33 @@ static void read_proc_cmdline(char * const dest, size_t size,
strncpy(dest, buf, size);
}
-static int reset_terminal_output(struct file_info * const finfo)
+static void reset_terminal_output_buffer(struct file_info * const finfo)
{
assert(finfo);
- finfo->terminal.output[0] = '\r';
- finfo->terminal.output[1] = '\0';
- finfo->terminal.unprintable_chars = 1;
- finfo->terminal.printable_chars = 0;
- return ioctl(0, TIOCGWINSZ, &finfo->terminal.dimensions);
+ finfo->terminal_output.buf[0] = '\r';
+ finfo->terminal_output.buf[1] = '\0';
+ finfo->terminal_output.unprintable_chars = 1;
+ finfo->terminal_output.printable_chars = 0;
}
-static size_t remaining_printable_chars(struct file_info * const finfo)
+static int get_terminal_dimensions(struct terminal * const term)
{
- assert(finfo);
+ return ioctl(0, TIOCGWINSZ, &term->dimensions);
+}
- return finfo->terminal.dimensions.ws_col -
- strnlen(finfo->terminal.output, finfo->terminal.printable_chars);
+static size_t remaining_printable_chars(struct terminal const * const term,
+ struct file_info const * const finfo)
+{
+ assert(term && finfo);
+
+ return term->dimensions.ws_col -
+ strnlen(finfo->terminal_output.buf, finfo->terminal_output.printable_chars);
}
-static int vadd_printable_buf(struct file_info * const finfo, const char * const format, va_list ap)
+static int vadd_printable_buf(struct terminal const * const term,
+ struct file_info * const finfo,
+ const char * const format, va_list ap)
{
char tmp_buf[MAX_TERMINAL_LEN];
int snprintf_retval;
@@ -253,25 +263,28 @@ static int vadd_printable_buf(struct file_info * const finfo, const char * const
assert(finfo && format);
- remaining_len = remaining_printable_chars(finfo);
+ remaining_len = remaining_printable_chars(term, finfo);
if (!remaining_len) {
return -1;
}
snprintf_retval = vsnprintf(tmp_buf, sizeof tmp_buf, format, ap);
if (snprintf_retval > 0) {
- if ((size_t)snprintf_retval > remaining_len) {
+ size_t buf_len = snprintf_retval;
+ if (buf_len > remaining_len) {
return -1;
}
- memcpy(finfo->terminal.output + finfo->terminal.printable_chars +
- finfo->terminal.unprintable_chars,
- tmp_buf, snprintf_retval);
- finfo->terminal.printable_chars += snprintf_retval;
+ memcpy(finfo->terminal_output.buf + finfo->terminal_output.printable_chars +
+ finfo->terminal_output.unprintable_chars,
+ tmp_buf, buf_len);
+ finfo->terminal_output.printable_chars += snprintf_retval;
}
return snprintf_retval;
}
-static int add_printable_buf(struct file_info * const finfo, const char * const format, ...)
+static int add_printable_buf(struct terminal const * const term,
+ struct file_info * const finfo,
+ const char * const format, ...)
{
int ret;
va_list ap;
@@ -279,7 +292,7 @@ static int add_printable_buf(struct file_info * const finfo, const char * const
assert(finfo && format);
va_start(ap, format);
- ret = vadd_printable_buf(finfo, format, ap);
+ ret = vadd_printable_buf(term, finfo, format, ap);
va_end(ap);
return ret;
}
@@ -340,7 +353,8 @@ static void prettify_with_units(long int bytes, char * const buf, size_t siz)
}
}
-static void show_positions(struct file_info * const finfo)
+static void show_positions(struct terminal * const term,
+ struct file_info * const finfo)
{
char curpos[64];
char maxpos[64];
@@ -350,7 +364,7 @@ static void show_positions(struct file_info * const finfo)
prettify_with_units(finfo->current_position, curpos, sizeof curpos);
prettify_with_units(finfo->max_size, maxpos, sizeof maxpos);
- add_printable_buf(finfo, "[%s/%s]", curpos, maxpos);
+ add_printable_buf(term, finfo, "[%s/%s]", curpos, maxpos);
}
static void measure_realtime(struct timespec * const tp)
@@ -372,7 +386,8 @@ static void loop_end(struct file_info * const finfo)
}
#define NANO_CONVERSION_F ((float)(1000.0f * 1000.0f * 1000.0f))
-static void show_rate(struct file_info * const finfo)
+static void show_rate(struct terminal * const term,
+ struct file_info * const finfo)
{
char out[64];
size_t xfer_rate_index;
@@ -419,25 +434,26 @@ static void show_rate(struct file_info * const finfo)
/* print it to the output buffer after "prettified" and units appended */
prettify_with_units(finfo->xfer_rate_history.last_reported_rate, out, sizeof out);
- add_printable_buf(finfo, "[%s/s]", out);
+ add_printable_buf(term, finfo, "[%s/s]", out);
}
-static void show_progressbar(struct file_info * const finfo)
+static void show_progressbar(struct terminal const * const term,
+ struct file_info * const finfo)
{
char buf[BUFSIZ];
size_t remaining_len;
assert(finfo);
- remaining_len = remaining_printable_chars(finfo);
- if (remaining_len < 8 || remaining_len >= sizeof buf) {
+ remaining_len = remaining_printable_chars(term, finfo);
+ if (remaining_len < 16 || remaining_len >= sizeof buf) {
return;
}
float progress = (float)finfo->current_position / finfo->max_size;
- add_printable_buf(finfo, "[%.2f%%]", progress * 100.0f);
+ add_printable_buf(term, finfo, "[%.2f%%]", progress * 100.0f);
- remaining_len = remaining_printable_chars(finfo);
+ remaining_len = remaining_printable_chars(term, finfo);
if (remaining_len < 3 || remaining_len >= sizeof buf) {
return;
}
@@ -446,7 +462,7 @@ static void show_progressbar(struct file_info * const finfo)
memset(buf, '-', remaining_len - 2);
memset(buf, '#', (size_t)printable_progress);
buf[remaining_len - 2] = '\0';
- add_printable_buf(finfo, "[%s]", buf);
+ add_printable_buf(term, finfo, "[%s]", buf);
}
static int nsleep(unsigned long long int nanosecs)
@@ -621,19 +637,21 @@ int main(int argc, char ** argv)
cur->proc_fd_fd = -1;
}
+ struct terminal term = {};
loop_start(&finfo);
while (!read_and_parse_fd_pos(&finfo)) {
- if (reset_terminal_output(&finfo) < 0) {
- break;
- }
+ reset_terminal_output_buffer(&finfo);
+ get_terminal_dimensions(&term);
loop_end(&finfo);
- show_positions(&finfo);
- show_rate(&finfo);
- show_progressbar(&finfo);
+ show_positions(&term, &finfo);
+ show_rate(&term, &finfo);
+ show_progressbar(&term, &finfo);
loop_start(&finfo);
- printf("%s", finfo.terminal.output);
+ int print_len = finfo.terminal_output.printable_chars +
+ finfo.terminal_output.unprintable_chars;
+ printf("%.*s", print_len, finfo.terminal_output.buf);
fflush(stdout);
nsleep(150000000L);
}