Prefer C99 formats like %jd to doing it by hand

It’s now safe to assume support for C99 formats like %jd, so remove
some of the longwinded formatting code put in only to be portable to
pre-C99 platforms.
* gnulib.modules: Add intprops.
* src/buffer.c (format_total_stats, try_new_volume)
(write_volume_label):
* src/checkpoint.c (format_checkpoint_string):
* src/compare.c (verify_volume):
* src/create.c (to_chars_subst, dump_regular_file):
* src/incremen.c (read_num):
* src/list.c (read_and, from_header, simple_print_header)
(print_for_mkdir):
* src/sparse.c (sparse_dump_region):
* src/system.c (dec_to_env, sys_exec_info_script)
(sys_exec_checkpoint_script):
* src/xheader.c (out_of_range_header):
Prefer C99 formats like %jd and %ju to STRINGIFY_BIGINT.
* src/common.h: Sort includes.
Include intprops.h, verify.h.  All other includes of verify.h
removed.
(intmax, uintmax): New functions and macros.
(STRINGIFY_BIGINT): Remove; no longer used.
(TIMESPEC_STRSIZE_BOUND): Make it 1 byte bigger, for negatives.
* src/create.c (MAX_VAL_WITH_DIGITS, to_base256):
Use *_WIDTH macros rather than assuming no padding bits.
Prefer UINTMAX_MAX to (uintmax_t) -1.
* src/list.c (tartime): Use strftime result rather
than running strlen later.
* src/misc.c (timetostr): New function.  Prefer it when
printing time_t values.
This commit is contained in:
Paul Eggert
2024-08-01 19:31:50 -07:00
parent 6c91bd82e1
commit c26111742a
13 changed files with 171 additions and 234 deletions

View File

@@ -63,6 +63,7 @@ gitlog-to-changelog
hash
human
idx
intprops
inttostr
inttypes
largefile

View File

@@ -28,7 +28,6 @@
#include <fnmatch.h>
#include <human.h>
#include <quotearg.h>
#include <verify.h>
#include "common.h"
#include <rmt.h>
@@ -543,7 +542,6 @@ format_total_stats (FILE *fp, char const *const *formats, int eor, int eol)
case DELETE_SUBCOMMAND:
{
char buf[UINTMAX_STRSIZE_BOUND];
n = print_stats (fp, formats[TF_READ],
records_read * record_size);
@@ -553,15 +551,10 @@ format_total_stats (FILE *fp, char const *const *formats, int eor, int eol)
n += print_stats (fp, formats[TF_WRITE],
prev_written + bytes_written);
fputc (eor, fp);
n++;
if (formats[TF_DELETED] && formats[TF_DELETED][0])
n += fprintf (fp, "%s: ", gettext (formats[TF_DELETED]));
n += fprintf (fp, "%s",
STRINGIFY_BIGINT ((records_read - records_skipped)
* record_size
- (prev_written + bytes_written), buf));
intmax_t deleted = ((records_read - records_skipped) * record_size
- (prev_written + bytes_written));
n += fprintf (fp, "%c%s: %jd", eor, gettext (formats[TF_DELETED]),
deleted);
}
break;
@@ -1528,7 +1521,6 @@ try_new_volume (void)
if (bufmap_head)
{
uintmax_t s;
if (!continued_file_name)
{
WARN ((0, 0, _("%s is not continued on this volume"),
@@ -1553,34 +1545,25 @@ try_new_volume (void)
}
}
s = continued_file_size + continued_file_offset;
if (bufmap_head->sizetotal != s || s < continued_file_offset)
uintmax_t s;
if (ckd_add (&s, continued_file_size, continued_file_offset)
|| s != bufmap_head->sizetotal)
{
char totsizebuf[UINTMAX_STRSIZE_BOUND];
char s1buf[UINTMAX_STRSIZE_BOUND];
char s2buf[UINTMAX_STRSIZE_BOUND];
WARN ((0, 0, _("%s is the wrong size (%s != %s + %s)"),
WARN ((0, 0, _("%s is the wrong size (%jd != %ju + %ju)"),
quote (continued_file_name),
STRINGIFY_BIGINT (bufmap_head->sizetotal, totsizebuf),
STRINGIFY_BIGINT (continued_file_size, s1buf),
STRINGIFY_BIGINT (continued_file_offset, s2buf)));
intmax (bufmap_head->sizetotal),
uintmax (continued_file_size),
uintmax (continued_file_offset)));
return false;
}
if (bufmap_head->sizetotal - bufmap_head->sizeleft !=
continued_file_offset)
if (bufmap_head->sizetotal - bufmap_head->sizeleft
!= continued_file_offset)
{
char totsizebuf[UINTMAX_STRSIZE_BOUND];
char s1buf[UINTMAX_STRSIZE_BOUND];
char s2buf[UINTMAX_STRSIZE_BOUND];
WARN ((0, 0, _("This volume is out of sequence (%s - %s != %s)"),
STRINGIFY_BIGINT (bufmap_head->sizetotal, totsizebuf),
STRINGIFY_BIGINT (bufmap_head->sizeleft, s1buf),
STRINGIFY_BIGINT (continued_file_offset, s2buf)));
WARN ((0, 0, _("This volume is out of sequence (%jd - %jd != %ju)"),
intmax (bufmap_head->sizetotal),
intmax (bufmap_head->sizeleft),
uintmax (continued_file_offset)));
return false;
}
}
@@ -1700,11 +1683,9 @@ _write_volume_label (const char *str)
static void
add_volume_label (void)
{
char buf[UINTMAX_STRSIZE_BOUND];
char *p = STRINGIFY_BIGINT (volno, buf);
char *s = xmalloc (strlen (volume_label_option) + sizeof VOL_SUFFIX
+ strlen (p) + 2);
sprintf (s, "%s %s %s", volume_label_option, VOL_SUFFIX, p);
+ INT_BUFSIZE_BOUND (int) + 2);
sprintf (s, "%s %s %d", volume_label_option, VOL_SUFFIX, volno);
_write_volume_label (s);
free (s);
}

View File

@@ -234,8 +234,6 @@ format_checkpoint_string (FILE *fp, size_t len,
unsigned cpn)
{
const char *opstr = do_write ? gettext ("write") : gettext ("read");
char uintbuf[UINTMAX_STRSIZE_BOUND];
char *cps = STRINGIFY_BIGINT (cpn, uintbuf);
const char *ip;
static char *argbuf = NULL;
@@ -281,8 +279,7 @@ format_checkpoint_string (FILE *fp, size_t len,
break;
case 'u':
fputs (cps, fp);
len += strlen (cps);
len += fprintf (fp, "%u", cpn);
break;
case 's':

View File

@@ -39,25 +39,28 @@
#include "arith.h"
#include <attribute.h>
#include <backupfile.h>
#include <exclude.h>
#include <full-write.h>
#include <idx.h>
#include <inttostr.h>
#include <modechange.h>
#include <quote.h>
#include <safe-read.h>
#include <full-read.h>
#include <stat-time.h>
#include <timespec.h>
#define obstack_chunk_alloc xmalloc
#define obstack_chunk_free free
#include <obstack.h>
#include <progname.h>
#include <xvasprintf.h>
#include <attribute.h>
#include <backupfile.h>
#include <exclude.h>
#include <full-read.h>
#include <full-write.h>
#include <idx.h>
#include <intprops.h>
#include <inttostr.h>
#include <modechange.h>
#include <paxlib.h>
#include <progname.h>
#include <quote.h>
#include <safe-read.h>
#include <stat-time.h>
#include <timespec.h>
#include <verify.h>
#include <xvasprintf.h>
/* Log base 2 of common values. */
#define LG_8 3
@@ -661,6 +664,23 @@ char *namebuf_name (namebuf_t buf, const char *name);
const char *tar_dirname (void);
/* intmax (N) is like ((intmax_t) (N)) except without a cast so
that it is an error if N is a pointer. Similarly for uintmax. */
COMMON_INLINE intmax_t
intmax (intmax_t n)
{
return n;
}
COMMON_INLINE uintmax_t
uintmax (uintmax_t n)
{
return n;
}
/* intmax should be used only with signed types, and uintmax for unsigned.
To bypass this check parenthesize the function, e.g., (intmax) (n). */
#define intmax(n) verify_expr (EXPR_SIGNED (n), (intmax) (n))
#define uintmax(n) verify_expr (!EXPR_SIGNED (n), (uintmax) (n))
/* Represent N using a signed integer I such that (uintmax_t) I == N.
With a good optimizing compiler, this is equivalent to (intmax_t) i
and requires zero machine instructions. */
@@ -679,18 +699,18 @@ represent_uintmax (uintmax_t n)
}
}
#define STRINGIFY_BIGINT(i, b) umaxtostr (i, b)
enum { UINTMAX_STRSIZE_BOUND = INT_BUFSIZE_BOUND (intmax_t) };
enum { SYSINT_BUFSIZE =
max (UINTMAX_STRSIZE_BOUND, INT_BUFSIZE_BOUND (intmax_t)) };
char *sysinttostr (uintmax_t, intmax_t, uintmax_t, char buf[SYSINT_BUFSIZE]);
intmax_t strtosysint (char const *, char **, intmax_t, uintmax_t);
char *timetostr (time_t, char buf[SYSINT_BUFSIZE]);
void code_ns_fraction (int ns, char *p);
enum { BILLION = 1000000000, LOG10_BILLION = 9 };
enum { TIMESPEC_STRSIZE_BOUND =
UINTMAX_STRSIZE_BOUND + LOG10_BILLION + sizeof "-." - 1 };
SYSINT_BUFSIZE + LOG10_BILLION + sizeof "." - 1 };
char const *code_timespec (struct timespec ts,
char sbuf[TIMESPEC_STRSIZE_BOUND]);
char tsbuf[TIMESPEC_STRSIZE_BOUND]);
struct timespec decode_timespec (char const *, char **, bool);
/* Return true if T does not represent an out-of-range or invalid value. */

View File

@@ -607,15 +607,13 @@ verify_volume (void)
set_next_block_after (current_header);
if (!ignore_zeros_option)
{
char buf[UINTMAX_STRSIZE_BOUND];
status = read_header (&current_header, &current_stat_info,
read_header_auto);
if (status == HEADER_ZERO_BLOCK)
break;
WARNOPT (WARN_ALONE_ZERO_BLOCK,
(0, 0, _("A lone zero block at %s"),
STRINGIFY_BIGINT (current_block_ordinal (), buf)));
(0, 0, _("A lone zero block at %jd"),
intmax (current_block_ordinal ())));
}
continue;
}

View File

@@ -125,9 +125,9 @@ cachedir_file_p (int fd)
/* The maximum uintmax_t value that can be represented with DIGITS digits,
assuming that each digit is BITS_PER_DIGIT wide. */
#define MAX_VAL_WITH_DIGITS(digits, bits_per_digit) \
((digits) * (bits_per_digit) < sizeof (uintmax_t) * CHAR_BIT \
((digits) * (bits_per_digit) < UINTMAX_WIDTH \
? ((uintmax_t) 1 << ((digits) * (bits_per_digit))) - 1 \
: (uintmax_t) -1)
: UINTMAX_MAX)
/* The maximum uintmax_t value that can be represented with octal
digits and a trailing NUL in BUFFER. */
@@ -185,7 +185,7 @@ to_base256 (bool negative, uintmax_t value, char *where, size_t size)
{
uintmax_t v = value;
uintmax_t propagated_sign_bits =
((uintmax_t) - negative << (CHAR_BIT * sizeof v - LG_256));
((uintmax_t) - negative << (UINTMAX_WIDTH - LG_256));
size_t i = size;
do
@@ -218,31 +218,12 @@ to_chars_subst (bool negative, bool gnu_format, uintmax_t value, size_t valsize,
uintmax_t maxval = (gnu_format
? MAX_VAL_WITH_DIGITS (size - 1, LG_256)
: MAX_VAL_WITH_DIGITS (size - 1, LG_8));
char valbuf[UINTMAX_STRSIZE_BOUND + 1];
char maxbuf[UINTMAX_STRSIZE_BOUND];
char minbuf[UINTMAX_STRSIZE_BOUND + 1];
char const *minval_string;
char const *maxval_string = STRINGIFY_BIGINT (maxval, maxbuf);
char const *value_string;
if (gnu_format)
{
uintmax_t m = maxval + 1 ? maxval + 1 : maxval / 2 + 1;
char *p = STRINGIFY_BIGINT (m, minbuf + 1);
*--p = '-';
minval_string = p;
}
else
minval_string = "0";
intmax_t minval = (!gnu_format ? 0
: ckd_sub (&minval, -1, maxval) ? INTMAX_MIN
: minval);
char const *valuesign = &"-"[!negative];
if (negative)
{
char *p = STRINGIFY_BIGINT (- value, valbuf + 1);
*--p = '-';
value_string = p;
}
else
value_string = STRINGIFY_BIGINT (value, valbuf);
value = -value;
if (substitute)
{
@@ -256,18 +237,15 @@ to_chars_subst (bool negative, bool gnu_format, uintmax_t value, size_t valsize,
Apart from this they are completely identical. */
uintmax_t s = (negsub &= archive_format == GNU_FORMAT) ? - sub : sub;
char subbuf[UINTMAX_STRSIZE_BOUND + 1];
char *sub_string = STRINGIFY_BIGINT (s, subbuf + 1);
if (negsub)
*--sub_string = '-';
WARN ((0, 0, _("value %s out of %s range %s..%s; substituting %s"),
value_string, type, minval_string, maxval_string,
sub_string));
char const *ssign = &"-"[!negsub];
WARN ((0, 0, _("value %s%ju out of %s range %jd..%ju;"
" substituting %s%ju"),
valuesign, value, type, minval, maxval, ssign, s));
return to_chars (negsub, s, valsize, 0, where, size, type);
}
else
ERROR ((0, 0, _("value %s out of %s range %s..%s"),
value_string, type, minval_string, maxval_string));
ERROR ((0, 0, _("value %s%ju out of %s range %jd..%ju"),
valuesign, value, type, minval, maxval));
return false;
}
@@ -1097,15 +1075,16 @@ dump_regular_file (int fd, struct tar_stat_info *st)
if (count != bufsize)
{
char buf[UINTMAX_STRSIZE_BOUND];
memset (blk->buffer + count, 0, bufsize - count);
WARNOPT (WARN_FILE_SHRANK,
(0, 0,
ngettext ("%s: File shrank by %s byte; padding with zeros",
"%s: File shrank by %s bytes; padding with zeros",
ngettext (("%s: File shrank by %jd byte;"
" padding with zeros"),
("%s: File shrank by %jd bytes;"
" padding with zeros"),
size_left),
quotearg_colon (st->orig_file_name),
STRINGIFY_BIGINT (size_left, buf)));
intmax (size_left)));
if (! ignore_failed_read_option)
set_exit_status (TAREXIT_DIFFERS);
pad_archive (size_left - (bufsize - count));

View File

@@ -1126,9 +1126,6 @@ read_num (FILE *fp, char const *fieldname,
{
int i;
char buf[INT_BUFSIZE_BOUND (intmax_t)];
char offbuf[INT_BUFSIZE_BOUND (off_t)];
char minbuf[INT_BUFSIZE_BOUND (intmax_t)];
char maxbuf[INT_BUFSIZE_BOUND (intmax_t)];
int conversion_errno;
int c = getc (fp);
bool negative = c == '-';
@@ -1138,9 +1135,9 @@ read_num (FILE *fp, char const *fieldname,
buf[i] = c;
if (i == sizeof buf - 1)
FATAL_ERROR ((0, 0,
_("%s: byte %s: %s %.*s... too long"),
_("%s: byte %jd: %s %.*s... too long"),
quotearg_colon (listed_incremental_option),
offtostr (ftello (fp), offbuf),
intmax (ftello (fp)),
fieldname, i + 1, buf));
c = getc (fp);
}
@@ -1162,9 +1159,9 @@ read_num (FILE *fp, char const *fieldname,
{
unsigned uc = c;
FATAL_ERROR ((0, 0,
_("%s: byte %s: %s %s followed by invalid byte 0x%02x"),
_("%s: byte %jd: %s %s followed by invalid byte 0x%02x"),
quotearg_colon (listed_incremental_option),
offtostr (ftello (fp), offbuf),
intmax (ftello (fp)),
fieldname, buf, uc));
}
@@ -1175,16 +1172,14 @@ read_num (FILE *fp, char const *fieldname,
{
case ERANGE:
FATAL_ERROR ((0, conversion_errno,
_("%s: byte %s: (valid range %s..%s)\n\t%s %s"),
_("%s: byte %jd: (valid range %jd..%ju)\n\t%s %s"),
quotearg_colon (listed_incremental_option),
offtostr (ftello (fp), offbuf),
imaxtostr (min_val, minbuf),
umaxtostr (max_val, maxbuf), fieldname, buf));
intmax (ftello (fp)), min_val, max_val, fieldname, buf));
default:
FATAL_ERROR ((0, conversion_errno,
_("%s: byte %s: %s %s"),
_("%s: byte %jd: %s %s"),
quotearg_colon (listed_incremental_option),
offtostr (ftello (fp), offbuf), fieldname, buf));
intmax (ftello (fp)), fieldname, buf));
case 0:
break;
}
@@ -1420,11 +1415,10 @@ write_directory_file_entry (void *entry, void *data)
s = DIR_IS_NFS (directory) ? "1" : "0";
fwrite (s, 2, 1, fp);
s = sysinttostr (directory->mtime.tv_sec, TYPE_MINIMUM (time_t),
TYPE_MAXIMUM (time_t), buf);
fwrite (s, strlen (s) + 1, 1, fp);
s = imaxtostr (directory->mtime.tv_nsec, buf);
s = timetostr (directory->mtime.tv_sec, buf);
fwrite (s, strlen (s) + 1, 1, fp);
int ns = directory->mtime.tv_nsec;
fprintf (fp, "%d%c", ns, 0);
s = sysinttostr (directory->device_number,
TYPE_MINIMUM (dev_t), TYPE_MAXIMUM (dev_t), buf);
fwrite (s, strlen (s) + 1, 1, fp);
@@ -1454,26 +1448,20 @@ void
write_directory_file (void)
{
FILE *fp = listed_incremental_stream;
char buf[UINTMAX_STRSIZE_BOUND];
char *s;
if (! fp)
return;
if (fseeko (fp, 0L, SEEK_SET) != 0)
if (fseeko (fp, 0, SEEK_SET) != 0)
seek_error (listed_incremental_option);
if (sys_truncate (fileno (fp)) != 0)
truncate_error (listed_incremental_option);
fprintf (fp, "%s-%s-%d\n", PACKAGE_NAME, PACKAGE_VERSION,
TAR_INCREMENTAL_VERSION);
s = (TYPE_SIGNED (time_t)
? imaxtostr (start_time.tv_sec, buf)
: umaxtostr (start_time.tv_sec, buf));
fwrite (s, strlen (s) + 1, 1, fp);
s = umaxtostr (start_time.tv_nsec, buf);
fwrite (s, strlen (s) + 1, 1, fp);
int nsec = start_time.tv_nsec;
char buf[SYSINT_BUFSIZE];
fprintf (fp, "%s-%s-%d\n%s%c%d%c",
PACKAGE_NAME, PACKAGE_VERSION, TAR_INCREMENTAL_VERSION,
timetostr (start_time.tv_sec, buf),
0, nsec, 0);
if (! ferror (fp) && directory_table)
hash_do_for_each (directory_table, write_directory_file_entry, fp);

View File

@@ -232,25 +232,20 @@ read_and (void (*do_something) (void))
case HEADER_ZERO_BLOCK:
if (block_number_option)
{
char buf[UINTMAX_STRSIZE_BOUND];
fprintf (stdlis, _("block %s: ** Block of NULs **\n"),
STRINGIFY_BIGINT (current_block_ordinal (), buf));
}
fprintf (stdlis, _("block %jd: ** Block of NULs **\n"),
intmax (current_block_ordinal ()));
set_next_block_after (current_header);
if (!ignore_zeros_option)
{
char buf[UINTMAX_STRSIZE_BOUND];
status = read_header (&current_header, &current_stat_info,
read_header_auto);
if (status == HEADER_ZERO_BLOCK)
break;
WARNOPT (WARN_ALONE_ZERO_BLOCK,
(0, 0, _("A lone zero block at %s"),
STRINGIFY_BIGINT (current_block_ordinal (), buf)));
(0, 0, _("A lone zero block at %jd"),
intmax (current_block_ordinal ())));
break;
}
status = prev_status;
@@ -258,18 +253,12 @@ read_and (void (*do_something) (void))
case HEADER_END_OF_FILE:
if (!ignore_zeros_option)
{
char buf[UINTMAX_STRSIZE_BOUND];
WARNOPT (WARN_MISSING_ZERO_BLOCKS,
(0, 0, _("Terminating zero blocks missing at %s"),
STRINGIFY_BIGINT (current_block_ordinal (), buf)));
}
WARNOPT (WARN_MISSING_ZERO_BLOCKS,
(0, 0, _("Terminating zero blocks missing at %jd"),
intmax (current_block_ordinal ())));
if (block_number_option)
{
char buf[UINTMAX_STRSIZE_BOUND];
fprintf (stdlis, _("block %s: ** End of File **\n"),
STRINGIFY_BIGINT (current_block_ordinal (), buf));
}
fprintf (stdlis, _("block %jd: ** End of File **\n"),
intmax (current_block_ordinal ()));
break;
case HEADER_FAILURE:
@@ -285,12 +274,11 @@ read_and (void (*do_something) (void))
case HEADER_SUCCESS:
if (block_number_option)
{
char buf[UINTMAX_STRSIZE_BOUND];
off_t block_ordinal = current_block_ordinal ();
block_ordinal -= recent_long_name_blocks;
block_ordinal -= recent_long_link_blocks;
fprintf (stdlis, _("block %s: "),
STRINGIFY_BIGINT (block_ordinal, buf));
fprintf (stdlis, _("block %jd: "),
intmax (block_ordinal));
}
ERROR ((0, 0, _("Skipping to next header")));
break;
@@ -942,19 +930,10 @@ from_header (char const *where0, size_t digs, char const *type,
if (type && !silent)
{
char minval_buf[UINTMAX_STRSIZE_BOUND + 1];
char maxval_buf[UINTMAX_STRSIZE_BOUND];
char value_buf[UINTMAX_STRSIZE_BOUND + 1];
char *minval_string = STRINGIFY_BIGINT (minus_minval, minval_buf + 1);
char *value_string = STRINGIFY_BIGINT (value, value_buf + 1);
if (negative)
*--value_string = '-';
if (minus_minval)
*--minval_string = '-';
char const *value_sign = &"-"[!negative];
/* TRANSLATORS: Second %s is type name (gid_t,uid_t,etc.) */
ERROR ((0, 0, _("Archive value %s is out of %s range %s..%s"),
value_string, type,
minval_string, STRINGIFY_BIGINT (maxval, maxval_buf)));
ERROR ((0, 0, _("Archive value %s%ju is out of %s range %jd..%ju"),
value_sign, value, type, minval, maxval));
}
return -1;
@@ -1070,8 +1049,8 @@ tartime (struct timespec t, bool full_time)
{
if (full_time)
{
strftime (buffer, sizeof buffer, "%Y-%m-%d %H:%M:%S", tm);
code_ns_fraction (ns, buffer + strlen (buffer));
size_t n = strftime (buffer, sizeof buffer, "%Y-%m-%d %H:%M:%S", tm);
code_ns_fraction (ns, buffer + n);
}
else
strftime (buffer, sizeof buffer, "%Y-%m-%d %H:%M", tm);
@@ -1129,12 +1108,11 @@ simple_print_header (struct tar_stat_info *st, union block *blk,
char *temp_name;
/* These hold formatted ints. */
char uform[max (INT_BUFSIZE_BOUND (intmax_t), UINTMAX_STRSIZE_BOUND)];
char gform[sizeof uform];
char uform[SYSINT_BUFSIZE];
char gform[SYSINT_BUFSIZE];
char *user, *group;
char size[2 * UINTMAX_STRSIZE_BOUND];
/* holds formatted size or major,minor */
char uintbuf[UINTMAX_STRSIZE_BOUND];
int pad;
int sizelen;
@@ -1145,13 +1123,11 @@ simple_print_header (struct tar_stat_info *st, union block *blk,
if (block_number_option)
{
char buf[UINTMAX_STRSIZE_BOUND];
if (block_ordinal < 0)
block_ordinal = current_block_ordinal ();
block_ordinal -= recent_long_name_blocks;
block_ordinal -= recent_long_link_blocks;
fprintf (stdlis, _("block %s: "),
STRINGIFY_BIGINT (block_ordinal, buf));
fprintf (stdlis, _("block %jd: "), intmax (block_ordinal));
}
if (verbose_option <= 1)
@@ -1235,7 +1211,8 @@ simple_print_header (struct tar_stat_info *st, union block *blk,
&& !numeric_owner_option)
user = st->uname;
else
user = STRINGIFY_BIGINT (st->stat.st_uid, uform);
user = sysinttostr (st->stat.st_uid, TYPE_MINIMUM (uid_t),
TYPE_MAXIMUM (uid_t), uform);
if (st->gname
&& st->gname[0]
@@ -1243,7 +1220,8 @@ simple_print_header (struct tar_stat_info *st, union block *blk,
&& !numeric_owner_option)
group = st->gname;
else
group = STRINGIFY_BIGINT (st->stat.st_gid, gform);
group = sysinttostr (st->stat.st_gid, TYPE_MINIMUM (gid_t),
TYPE_MAXIMUM (gid_t), gform);
/* Format the file size or major/minor device numbers. */
@@ -1251,22 +1229,24 @@ simple_print_header (struct tar_stat_info *st, union block *blk,
{
case CHRTYPE:
case BLKTYPE:
strcpy (size,
STRINGIFY_BIGINT (major (st->stat.st_rdev), uintbuf));
strcat (size, ",");
strcat (size,
STRINGIFY_BIGINT (minor (st->stat.st_rdev), uintbuf));
sizelen = ((EXPR_SIGNED (major (st->stat.st_rdev))
&& EXPR_SIGNED (minor (st->stat.st_rdev)))
? sprintf (size, "%jd,%jd",
(intmax) (major (st->stat.st_rdev)),
(intmax) (minor (st->stat.st_rdev)))
: sprintf (size, "%ju,%ju",
(uintmax) (major (st->stat.st_rdev)),
(uintmax) (minor (st->stat.st_rdev))));
break;
default:
/* st->stat.st_size keeps stored file size */
strcpy (size, STRINGIFY_BIGINT (st->stat.st_size, uintbuf));
sizelen = sprintf (size, "%jd", intmax (st->stat.st_size));
break;
}
/* Figure out padding and print the whole line. */
sizelen = strlen (size);
pad = strlen (user) + 1 + strlen (group) + 1 + sizelen;
if (pad > ugswidth)
ugswidth = pad;
@@ -1324,11 +1304,8 @@ simple_print_header (struct tar_stat_info *st, union block *blk,
break;
case GNUTYPE_MULTIVOL:
strcpy (size,
STRINGIFY_BIGINT
(UINTMAX_FROM_HEADER (blk->oldgnu_header.offset),
uintbuf));
fprintf (stdlis, _("--Continued at byte %s--\n"), size);
fprintf (stdlis, _("--Continued at byte %ju--\n"),
UINTMAX_FROM_HEADER (blk->oldgnu_header.offset));
break;
}
}
@@ -1384,11 +1361,8 @@ print_for_mkdir (char *dirname, mode_t mode)
pax_decode_mode (mode, modes + 1);
if (block_number_option)
{
char buf[UINTMAX_STRSIZE_BOUND];
fprintf (stdlis, _("block %s: "),
STRINGIFY_BIGINT (current_block_ordinal (), buf));
}
fprintf (stdlis, _("block %jd: "),
intmax (current_block_ordinal ()));
fprintf (stdlis, "%s %*s %s\n", modes, ugswidth + 1 + datewidth,
_("Creating directory:"), quotearg (dirname));

View File

@@ -372,7 +372,7 @@ replace_prefix (char **pname, const char *samp, size_t slen,
/* Handling numbers. */
/* Convert VALUE, which is converted from a system integer type whose
minimum value is MINVAL and maximum MINVAL, to an decimal
minimum value is MINVAL and maximum MINVAL, to a decimal
integer string. Use the storage in BUF and return a pointer to the
converted string. If VALUE is converted from a negative integer in
the range MINVAL .. -1, represent it with a string representation
@@ -392,6 +392,14 @@ sysinttostr (uintmax_t value, intmax_t minval, uintmax_t maxval,
}
}
/* Convert T to a decimal integer string. Use the storage in BUF and
return a pointer to the converted string. */
char *
timetostr (time_t t, char buf[SYSINT_BUFSIZE])
{
return sysinttostr (t, TYPE_MINIMUM (time_t), TYPE_MAXIMUM (time_t), buf);
}
/* Convert a prefix of the string ARG to a system integer type whose
minimum value is MINVAL and maximum MAXVAL. If MINVAL is negative,
negative integers MINVAL .. -1 are assumed to be represented using
@@ -472,11 +480,10 @@ code_ns_fraction (int ns, char *p)
}
char const *
code_timespec (struct timespec t, char sbuf[TIMESPEC_STRSIZE_BOUND])
code_timespec (struct timespec t, char tsbuf[TIMESPEC_STRSIZE_BOUND])
{
time_t s = t.tv_sec;
int ns = t.tv_nsec;
char *np;
bool negative = s < 0;
/* ignore invalid values of ns */
@@ -489,11 +496,12 @@ code_timespec (struct timespec t, char sbuf[TIMESPEC_STRSIZE_BOUND])
ns = BILLION - ns;
}
np = umaxtostr (negative ? - (uintmax_t) s : (uintmax_t) s, sbuf + 1);
if (negative)
*--np = '-';
code_ns_fraction (ns, sbuf + UINTMAX_STRSIZE_BOUND);
return np;
bool minus_zero = negative & !s;
char *sstr = timetostr (s, tsbuf + 1);
sstr[-1] = '-';
sstr -= minus_zero;
code_ns_fraction (ns, sstr + strlen (sstr));
return sstr;
}
struct timespec

View File

@@ -439,9 +439,8 @@ sparse_dump_region (struct tar_sparse_file *file, size_t i)
}
else
{
char buf[UINTMAX_STRSIZE_BOUND];
struct stat st;
size_t n;
off_t n;
if (fstat (file->fd, &st) == 0)
n = file->stat_info->stat.st_size - st.st_size;
else
@@ -452,11 +451,11 @@ sparse_dump_region (struct tar_sparse_file *file, size_t i)
WARNOPT (WARN_FILE_SHRANK,
(0, 0,
ngettext ("%s: File shrank by %s byte; padding with zeros",
"%s: File shrank by %s bytes; padding with zeros",
ngettext ("%s: File shrank by %jd byte; padding with zeros",
"%s: File shrank by %jd bytes; padding with zeros",
n),
quotearg_colon (file->stat_info->orig_file_name),
STRINGIFY_BIGINT (n, buf)));
intmax (n)));
if (! ignore_failed_read_option)
set_exit_status (TAREXIT_DIFFERS);
return false;

View File

@@ -662,10 +662,8 @@ sys_child_open_for_uncompress (void)
static void
dec_to_env (char const *envar, uintmax_t num)
{
char buf[UINTMAX_STRSIZE_BOUND];
char *numstr;
numstr = STRINGIFY_BIGINT (num, buf);
char numstr[UINTMAX_STRSIZE_BOUND];
sprintf (numstr, "%ju", num);
if (setenv (envar, numstr, 1) != 0)
xalloc_die ();
}
@@ -823,15 +821,13 @@ sys_wait_command (void)
int
sys_exec_info_script (const char **archive_name, int volume_number)
{
pid_t pid;
char uintbuf[UINTMAX_STRSIZE_BOUND];
int p[2];
static void (*saved_handler) (int sig);
xpipe (p);
saved_handler = signal (SIGPIPE, SIG_IGN);
pid = xfork ();
pid_t pid = xfork ();
if (pid != 0)
{
@@ -877,14 +873,17 @@ sys_exec_info_script (const char **archive_name, int volume_number)
/* Child */
setenv ("TAR_VERSION", PACKAGE_VERSION, 1);
setenv ("TAR_ARCHIVE", *archive_name, 1);
setenv ("TAR_VOLUME", STRINGIFY_BIGINT (volume_number, uintbuf), 1);
setenv ("TAR_BLOCKING_FACTOR",
STRINGIFY_BIGINT (blocking_factor, uintbuf), 1);
char intbuf[INT_BUFSIZE_BOUND (int)];
sprintf (intbuf, "%d", volume_number);
setenv ("TAR_VOLUME", intbuf, 1);
sprintf (intbuf, "%d", blocking_factor);
setenv ("TAR_BLOCKING_FACTOR", intbuf, 1);
setenv ("TAR_SUBCOMMAND", subcommand_string (subcommand_option), 1);
setenv ("TAR_FORMAT",
archive_format_string (current_format == DEFAULT_FORMAT ?
archive_format : current_format), 1);
setenv ("TAR_FD", STRINGIFY_BIGINT (p[PWRITE], uintbuf), 1);
sprintf (intbuf, "%d", p[PWRITE]);
setenv ("TAR_FD", intbuf, 1);
xclose (p[PREAD]);
@@ -897,10 +896,7 @@ sys_exec_checkpoint_script (const char *script_name,
const char *archive_name,
int checkpoint_number)
{
pid_t pid;
char uintbuf[UINTMAX_STRSIZE_BOUND];
pid = xfork ();
pid_t pid = xfork ();
if (pid != 0)
{
@@ -921,9 +917,11 @@ sys_exec_checkpoint_script (const char *script_name,
/* Child */
setenv ("TAR_VERSION", PACKAGE_VERSION, 1);
setenv ("TAR_ARCHIVE", archive_name, 1);
setenv ("TAR_CHECKPOINT", STRINGIFY_BIGINT (checkpoint_number, uintbuf), 1);
setenv ("TAR_BLOCKING_FACTOR",
STRINGIFY_BIGINT (blocking_factor, uintbuf), 1);
char intbuf[INT_BUFSIZE_BOUND (int)];
sprintf (intbuf, "%d", checkpoint_number);
setenv ("TAR_CHECKPOINT", intbuf, 1);
sprintf (intbuf, "%d", blocking_factor);
setenv ("TAR_BLOCKING_FACTOR", intbuf, 1);
setenv ("TAR_SUBCOMMAND", subcommand_string (subcommand_option), 1);
setenv ("TAR_FORMAT",
archive_format_string (current_format == DEFAULT_FORMAT ?

View File

@@ -130,7 +130,6 @@ bool delay_directory_restore_option;
#include <wordsplit.h>
#include <sysexits.h>
#include <quotearg.h>
#include <verify.h>
#include <version-etc.h>
#include <xstrtol.h>
#include <stdopen.h>

View File

@@ -999,15 +999,10 @@ static void
out_of_range_header (char const *keyword, char const *value,
intmax_t minval, uintmax_t maxval)
{
char minval_buf[INT_BUFSIZE_BOUND (intmax_t)];
char maxval_buf[UINTMAX_STRSIZE_BOUND];
char *minval_string = imaxtostr (minval, minval_buf);
char *maxval_string = umaxtostr (maxval, maxval_buf);
/* TRANSLATORS: The first %s is the pax extended header keyword
(atime, gid, etc.). */
ERROR ((0, 0, _("Extended header %s=%s is out of range %s..%s"),
keyword, value, minval_string, maxval_string));
ERROR ((0, 0, _("Extended header %s=%s is out of range %jd..%ju"),
keyword, value, minval, maxval));
}
static void