]> andersk Git - openssh.git/blobdiff - progressmeter.c
- djm@cvs.openbsd.org 2010/01/30 02:54:53
[openssh.git] / progressmeter.c
index 7b76c959ecd562a39bd9305cc66d2d102bd3e295..0f95222d24874f760eb14227fdc772cbb7927b8a 100644 (file)
@@ -1,3 +1,4 @@
+/* $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.18 2003/12/02 12:15:10 markus 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"
@@ -42,21 +53,26 @@ static int can_output(void);
 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);
 
 /* signal handler for updating the progress meter */
 static void update_progress_meter(int);
 
-static time_t start;           /* start progress */
-static time_t last_update;     /* last progress update */
-static char *file;             /* name of the file being transferred */
-static off_t end_pos;          /* ending position of transfer */
-static off_t cur_pos;          /* transfer position as of last refresh */
+static time_t start;           /* start progress */
+static time_t last_update;     /* last progress update */
+static char *file;             /* name of the file being transferred */
+static off_t end_pos;          /* ending position of transfer */
+static off_t cur_pos;          /* transfer position as of last refresh */
 static volatile off_t *counter;        /* progress counter */
-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 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";
@@ -80,8 +96,8 @@ format_rate(char *buf, int size, off_t bytes)
                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" : " ");
 }
@@ -94,7 +110,7 @@ format_size(char *buf, int size, off_t bytes)
        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" : " ");
 }
@@ -107,7 +123,7 @@ refresh_progress_meter(void)
        off_t transferred;
        double elapsed;
        int percent;
-       int bytes_left;
+       off_t bytes_left;
        int cur_speed;
        int hours, minutes, seconds;
        int i, len;
@@ -147,7 +163,9 @@ refresh_progress_meter(void)
                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';
        }
@@ -167,7 +185,7 @@ refresh_progress_meter(void)
 
        /* bandwidth usage */
        format_rate(buf + strlen(buf), win_size - strlen(buf),
-           bytes_per_second);
+           (off_t)bytes_per_second);
        strlcat(buf, "/s ", win_size);
 
        /* ETA */
@@ -208,6 +226,7 @@ refresh_progress_meter(void)
        last_update = now;
 }
 
+/*ARGSUSED*/
 static void
 update_progress_meter(int ignore)
 {
@@ -215,6 +234,10 @@ update_progress_meter(int ignore)
 
        save_errno = errno;
 
+       if (win_resized) {
+               setscreensize();
+               win_resized = 0;
+       }
        if (can_output())
                refresh_progress_meter();
 
@@ -224,32 +247,22 @@ update_progress_meter(int ignore)
 }
 
 void
-start_progress_meter(char *f, off_t filesize, off_t *stat)
+start_progress_meter(char *f, off_t filesize, off_t *ctr)
 {
-       struct winsize winsize;
-
        start = last_update = time(NULL);
        file = f;
        end_pos = filesize;
        cur_pos = 0;
-       counter = stat;
+       counter = ctr;
        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);
 }
 
@@ -267,3 +280,26 @@ stop_progress_meter(void)
 
        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 */
+}
This page took 0.051612 seconds and 4 git commands to generate.