+/* $OpenBSD: progressmeter.c,v 1.37 2006/08/03 03:34:42 deraadt Exp $ */
/*
* Copyright (c) 2003 Nils Nordman. All rights reserved.
*
*/
#include "includes.h"
-RCSID("$OpenBSD: progressmeter.c,v 1.22 2004/07/11 17:48:47 deraadt Exp $");
+
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <sys/uio.h>
+
+#include <errno.h>
+#include <signal.h>
+#include <stdio.h>
+#include <string.h>
+#include <time.h>
+#include <unistd.h>
#include "progressmeter.h"
#include "atomicio.h"
static void format_size(char *, int, off_t);
static void format_rate(char *, int, off_t);
+/* window resizing */
+static void sig_winch(int);
+static void setscreensize(void);
+
/* updates the progressmeter to reflect the current state of the transfer */
void refresh_progress_meter(void);
static long stalled; /* how long we have been stalled */
static int bytes_per_second; /* current speed in bytes per second */
static int win_size; /* terminal window size */
+static volatile sig_atomic_t win_resized; /* for window resizing */
/* units for format_size */
static const char unit[] = " KMGT";
bytes = (bytes + 512) / 1024;
}
snprintf(buf, size, "%3lld.%1lld%c%s",
- (int64_t) (bytes + 5) / 100,
- (int64_t) (bytes + 5) / 10 % 10,
+ (long long) (bytes + 5) / 100,
+ (long long) (bytes + 5) / 10 % 10,
unit[i],
i ? "B" : " ");
}
for (i = 0; bytes >= 10000 && unit[i] != 'T'; i++)
bytes = (bytes + 512) / 1024;
snprintf(buf, size, "%4lld%c%s",
- (int64_t) bytes,
+ (long long) bytes,
unit[i],
i ? "B" : " ");
}
len = snprintf(buf, file_len + 1, "\r%s", file);
if (len < 0)
len = 0;
- for (i = len; i < file_len; i++ )
+ if (len >= file_len + 1)
+ len = file_len;
+ for (i = len; i < file_len; i++)
buf[i] = ' ';
buf[file_len] = '\0';
}
last_update = now;
}
+/*ARGSUSED*/
static void
update_progress_meter(int ignore)
{
save_errno = errno;
+ if (win_resized) {
+ setscreensize();
+ win_resized = 0;
+ }
if (can_output())
refresh_progress_meter();
void
start_progress_meter(char *f, off_t filesize, off_t *ctr)
{
- struct winsize winsize;
-
start = last_update = time(NULL);
file = f;
end_pos = filesize;
stalled = 0;
bytes_per_second = 0;
- if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &winsize) != -1 &&
- winsize.ws_col != 0) {
- if (winsize.ws_col > MAX_WINSIZE)
- win_size = MAX_WINSIZE;
- else
- win_size = winsize.ws_col;
- } else
- win_size = DEFAULT_WINSIZE;
- win_size += 1; /* trailing \0 */
-
+ setscreensize();
if (can_output())
refresh_progress_meter();
signal(SIGALRM, update_progress_meter);
+ signal(SIGWINCH, sig_winch);
alarm(UPDATE_INTERVAL);
}
atomicio(vwrite, STDOUT_FILENO, "\n", 1);
}
+
+/*ARGSUSED*/
+static void
+sig_winch(int sig)
+{
+ win_resized = 1;
+}
+
+static void
+setscreensize(void)
+{
+ struct winsize winsize;
+
+ if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &winsize) != -1 &&
+ winsize.ws_col != 0) {
+ if (winsize.ws_col > MAX_WINSIZE)
+ win_size = MAX_WINSIZE;
+ else
+ win_size = winsize.ws_col;
+ } else
+ win_size = DEFAULT_WINSIZE;
+ win_size += 1; /* trailing \0 */
+}