summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Eggert <eggert@cs.ucla.edu>2014-07-10 22:34:25 -0700
committerPaul Eggert <eggert@cs.ucla.edu>2014-07-10 22:35:05 -0700
commit4423e1743e10c79ce8430c9740923c82281ca579 (patch)
tree77c4ac84eb9d005daa9aa022f3a75bd6ee9424b3
parent8d087fbb0b5222b12e2dcceb5b653127ccc4b66a (diff)
downloadtar-4423e1743e10c79ce8430c9740923c82281ca579.tar.gz
tar: minor fixups related to recent checkpoint.c change
* src/checkpoint.c (getwidth, format_checkpoint_string): Use long and strtol, not int, to avoid overflow issues. (getwidth): Don't assume termios.h defines TIOCGWINSZ, as it doesn't on some older hosts.
-rw-r--r--src/checkpoint.c43
1 files changed, 24 insertions, 19 deletions
diff --git a/src/checkpoint.c b/src/checkpoint.c
index 4bda0152..54e7b596 100644
--- a/src/checkpoint.c
+++ b/src/checkpoint.c
@@ -141,21 +141,26 @@ static const char *checkpoint_total_format[] = {
"D"
};
-static int
+static long
getwidth (FILE *fp)
{
+ char const *columns;
+
+#ifdef TIOCGWINSZ
struct winsize ws;
+ if (ioctl (fileno (fp), TIOCGWINSZ, &ws) == 0 && 0 < ws.ws_col)
+ return ws.ws_col;
+#endif
- ws.ws_col = ws.ws_row = 0;
- if ((ioctl (fileno (fp), TIOCGWINSZ, (char *) &ws) < 0) || ws.ws_col == 0)
+ columns = getenv ("COLUMNS");
+ if (columns)
{
- const char *col = getenv ("COLUMNS");
- if (col)
- return strtol (col, NULL, 10);
- else
- return 80;
+ long int col = strtol (columns, NULL, 10);
+ if (0 < col)
+ return col;
}
- return ws.ws_col;
+
+ return 80;
}
static char *
@@ -202,7 +207,7 @@ format_checkpoint_string (FILE *fp, size_t len,
static char *argbuf = NULL;
static size_t arglen = 0;
char *arg = NULL;
-
+
if (!input)
{
if (do_write)
@@ -218,7 +223,7 @@ format_checkpoint_string (FILE *fp, size_t len,
*not* "Leyendo un punto de comprobaci@'on" */
input = gettext ("Read checkpoint %u");
}
-
+
for (ip = input; *ip; ip++)
{
if (*ip == '%')
@@ -240,7 +245,7 @@ format_checkpoint_string (FILE *fp, size_t len,
len += format_checkpoint_string (fp, len, def_format, do_write,
cpn);
break;
-
+
case 'u':
fputs (cps, fp);
len += strlen (cps);
@@ -254,13 +259,13 @@ format_checkpoint_string (FILE *fp, size_t len,
case 'd':
len += fprintf (fp, "%.0f", compute_duration ());
break;
-
+
case 'T':
{
const char **fmt = checkpoint_total_format, *fmtbuf[3];
struct wordsplit ws;
compute_duration ();
-
+
if (arg)
{
ws.ws_delim = ",";
@@ -296,15 +301,15 @@ format_checkpoint_string (FILE *fp, size_t len,
len += fprintftime (fp, fmt, tm, 0, tv.tv_usec * 1000);
}
break;
-
+
case '*':
{
- int w = arg ? strtoul (arg, NULL, 10) : getwidth (fp);
+ long w = arg ? strtol (arg, NULL, 10) : getwidth (fp);
for (; w > len; len++)
fputc (' ', fp);
}
break;
-
+
default:
fputc ('%', fp);
fputc (*ip, fp);
@@ -393,7 +398,7 @@ void
checkpoint_flush_actions (void)
{
struct checkpoint_action *p;
-
+
for (p = checkpoint_action; p; p = p->next)
{
switch (p->opcode)
@@ -401,7 +406,7 @@ checkpoint_flush_actions (void)
case cop_ttyout:
if (tty && tty_cleanup)
{
- int w = getwidth (tty);
+ long w = getwidth (tty);
while (w--)
fputc (' ', tty);
fputc ('\r', tty);