[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Patches for GNU tar 1.13.25
From: |
Bruce Lilly |
Subject: |
Patches for GNU tar 1.13.25 |
Date: |
Sat, 13 Jul 2002 10:51:44 -0400 |
The attached patch addresses most of the issues
when compiling GNU tar 1.13.25 on UWIN
(http://www.research.att.com/sw/tools/uwin).
Several issues noted remain unresolved, some
others (e.g. application of unary minus to
unsigned quantities) have not even been
addressed [most of those issues could be avoided
by using double throughout for large quantities
(double has a 64-bit mantissa) rather than
non-portable and implementation-dependent
constructs].
Brief description of issues and patches:
1. no supplied conversion between uintmax_t and
double. Portable and efficient conversion
code supplied.
2. getdate.[cy] needs to declare mktime if the
replacement function is used. extern
declaration should be harmless even if the
system mktime is used.
3. do-nothing code in human.c #ifdef'ed out.
4. inconsistent placement of const qualifiers
made more consistent.
5. non-portable tests which assume that size_t
is signed replaced by portable tests.
6. another case of the iconv "bug" accounted for.
7. test for O_ECL vs. O_TRUNC for file creation
during extraction corrected.
Best regards,
Bruce Lilly
*** lib/exclude.c.orig Mon Sep 03 14:26:33 2001
--- lib/exclude.c Sat Jul 13 08:21:10 2002
***************
*** 77,83 ****
struct patopts
{
! char const *pattern;
int options;
};
--- 77,83 ----
struct patopts
{
! const char *pattern;
int options;
};
***************
*** 116,122 ****
(unlike fnmatch) wildcards are disabled in PATTERN. */
static int
! fnmatch_no_wildcards (char const *pattern, char const *f, int options)
{
if (! (options & FNM_LEADING_DIR))
return ((options & FNM_CASEFOLD)
--- 116,122 ----
(unlike fnmatch) wildcards are disabled in PATTERN. */
static int
! fnmatch_no_wildcards (const char *pattern, const char *f, int options)
{
if (! (options & FNM_LEADING_DIR))
return ((options & FNM_CASEFOLD)
***************
*** 141,147 ****
/* Return true if EX excludes F. */
bool
! excluded_filename (struct exclude const *ex, char const *f)
{
size_t exclude_count = ex->exclude_count;
--- 141,147 ----
/* Return true if EX excludes F. */
bool
! excluded_filename (const struct exclude *ex, const char *f)
{
size_t exclude_count = ex->exclude_count;
***************
*** 150,156 ****
return 0;
else
{
! struct patopts const *exclude = ex->exclude;
size_t i;
/* Otherwise, the default is the opposite of the first option. */
--- 150,156 ----
return 0;
else
{
! const struct patopts *exclude = ex->exclude;
size_t i;
/* Otherwise, the default is the opposite of the first option. */
***************
*** 160,175 ****
excluded to included or vice versa. */
for (i = 0; i < exclude_count; i++)
{
! char const *pattern = exclude[i].pattern;
int options = exclude[i].options;
if (excluded == !! (options & EXCLUDE_INCLUDE))
{
! int (*matcher) PARAMS ((char const *, char const *, int)) =
(options & EXCLUDE_WILDCARDS
? fnmatch
: fnmatch_no_wildcards);
bool matched = ((*matcher) (pattern, f, options) == 0);
! char const *p;
if (! (options & EXCLUDE_ANCHORED))
for (p = f; *p && ! matched; p++)
--- 160,175 ----
excluded to included or vice versa. */
for (i = 0; i < exclude_count; i++)
{
! const char *pattern = exclude[i].pattern;
int options = exclude[i].options;
if (excluded == !! (options & EXCLUDE_INCLUDE))
{
! int (*matcher) PARAMS ((const char *, const char *, int)) =
(options & EXCLUDE_WILDCARDS
? fnmatch
: fnmatch_no_wildcards);
bool matched = ((*matcher) (pattern, f, options) == 0);
! const char *p;
if (! (options & EXCLUDE_ANCHORED))
for (p = f; *p && ! matched; p++)
***************
*** 187,193 ****
/* Append to EX the exclusion PATTERN with OPTIONS. */
void
! add_exclude (struct exclude *ex, char const *pattern, int options)
{
struct patopts *patopts;
--- 187,193 ----
/* Append to EX the exclusion PATTERN with OPTIONS. */
void
! add_exclude (struct exclude *ex, const char *pattern, int options)
{
struct patopts *patopts;
***************
*** 212,227 ****
int
add_exclude_file (void (*add_func) PARAMS ((struct exclude *,
! char const *, int)),
! struct exclude *ex, char const *filename, int options,
char line_end)
{
bool use_stdin = filename[0] == '-' && !filename[1];
FILE *in;
char *buf;
char *p;
! char const *pattern;
! char const *lim;
size_t buf_alloc = (1 << 10); /* This must be a power of two. */
size_t buf_count = 0;
int c;
--- 212,227 ----
int
add_exclude_file (void (*add_func) PARAMS ((struct exclude *,
! const char *, int)),
! struct exclude *ex, const char *filename, int options,
char line_end)
{
bool use_stdin = filename[0] == '-' && !filename[1];
FILE *in;
char *buf;
char *p;
! const char *pattern;
! const char *lim;
size_t buf_alloc = (1 << 10); /* This must be a power of two. */
size_t buf_count = 0;
int c;
*** lib/exclude.h.orig Sun Aug 26 19:07:15 2001
--- lib/exclude.h Tue Jul 02 14:13:28 2002
***************
*** 30,43 ****
/* Patterns must match the start of file names, instead of matching
anywhere after a '/'. */
! #define EXCLUDE_ANCHORED (1 << 5)
/* Include instead of exclude. */
! #define EXCLUDE_INCLUDE (1 << 6)
/* '?', '*', '[', and '\\' are special in patterns. Without this
option, these characters are ordinary and fnmatch is not used. */
! #define EXCLUDE_WILDCARDS (1 << 7)
struct exclude;
--- 30,43 ----
/* Patterns must match the start of file names, instead of matching
anywhere after a '/'. */
! #define EXCLUDE_ANCHORED (1 << 7)
/* Include instead of exclude. */
! #define EXCLUDE_INCLUDE (1 << 8)
/* '?', '*', '[', and '\\' are special in patterns. Without this
option, these characters are ordinary and fnmatch is not used. */
! #define EXCLUDE_WILDCARDS (1 << 9)
struct exclude;
*** lib/getdate.c.orig Thu Sep 13 21:39:21 2001
--- lib/getdate.c Sat Jul 13 10:02:25 2002
***************
*** 1550,1558 ****
#ifndef localtime
struct tm *localtime ();
#endif
! #ifndef mktime
! time_t mktime ();
! #endif
static table const meridian_table[] =
{
--- 1550,1556 ----
#ifndef localtime
struct tm *localtime ();
#endif
! extern time_t mktime ();
static table const meridian_table[] =
{
*** lib/getdate.y.orig Sat Apr 21 10:37:47 2001
--- lib/getdate.y Sat Jul 13 10:02:10 2002
***************
*** 455,463 ****
#ifndef localtime
struct tm *localtime ();
#endif
! #ifndef mktime
! time_t mktime ();
! #endif
static table const meridian_table[] =
{
--- 455,461 ----
#ifndef localtime
struct tm *localtime ();
#endif
! extern time_t mktime ();
static table const meridian_table[] =
{
*** lib/human.c.orig Sat Jun 17 14:36:21 2000
--- lib/human.c Sat Jul 13 10:16:23 2002
***************
*** 84,94 ****
/* Do not use the floor or ceil functions, as that would mean
linking with the standard math library, which is a porting pain.
So leave the value alone if it is too large to easily round. */
if (inexact_style != human_round_to_even && value < (uintmax_t) -1)
{
! uintmax_t u = value;
! value = u + (inexact_style == human_ceiling && u != value);
}
return value;
}
--- 84,101 ----
/* Do not use the floor or ceil functions, as that would mean
linking with the standard math library, which is a porting pain.
So leave the value alone if it is too large to easily round. */
+ #if 0
+ /* this code snippet:
+ a) generates compiler errors due to conversion from uintmax_t to double
+ b) does nothing useful (see comments below)
+ */
if (inexact_style != human_round_to_even && value < (uintmax_t) -1)
{
! uintmax_t u = value; /* N.B. u == value (unconditionally) */
! value = u + (inexact_style == human_ceiling && u != value); /* &&
condition never fulfilled since u == value (always) */
! /* so we have: u = value; value = u + 0; I.E. a very expensive noop! */
}
+ #endif
return value;
}
***************
*** 124,129 ****
--- 131,143 ----
-OUTPUT_BLOCK_SIZE is 1024, 8500 would be converted to 8.3k,
133456345 to 127M, 56990456345 to 53G, and so on. Numbers smaller
than -OUTPUT_BLOCK_SIZE aren't modified. */
+ /* N.B. 1024 != 1000.
+ 56908316672 Bytes = 56.908316672 GB = 53 GiB, or approx. 57 GB and
definitely nowhere near 53 GB.
+ See http://physics.nist.gov/cuu/Units/binary.html
+ and http://physics.nist.gov/cuu/Units/prefixes.html
+ These have been *international* standards for years.
+ Most of the code in this file needs substantial revision.
+ */
char *
human_readable_inexact (uintmax_t n, char *buf,
***************
*** 187,194 ****
or from_block_size is zero. Fall back on floating point.
FIXME: This can yield answers that are slightly off. */
! double damt = n * (from_block_size / (double) to_block_size);
if (! base)
sprintf (buf, "%.0f", adjust_value (inexact_style, damt));
else
--- 201,218 ----
or from_block_size is zero. Fall back on floating point.
FIXME: This can yield answers that are slightly off. */
! uintmax_t a = 0, un = 1;
! double damt = 0.0, dn = 1.0;
+ while (un < n/2)
+ un *= 2, dn *= 2.0; /* loop invariants: un is a power of two, un <
n, dn = un */
+ while (a < n)
+ if (n - a >= un)
+ a += un, damt += dn;
+ else
+ un /= 2, dn /= 2.0;
+ damt *= ( from_block_size / (double) to_block_size);
+
if (! base)
sprintf (buf, "%.0f", adjust_value (inexact_style, damt));
else
*** lib/savedir.c.orig Tue Aug 28 16:28:47 2001
--- lib/savedir.c Wed Jul 03 01:34:55 2002
***************
*** 97,110 ****
if (entry[entry[0] != '.' ? 0 : entry[1] != '.' ? 1 : 2] != '\0')
{
size_t entry_size = strlen (entry) + 1;
! if (used + entry_size < used)
! xalloc_die ();
if (allocated <= used + entry_size)
{
do
{
! if (2 * allocated < allocated)
! xalloc_die ();
allocated *= 2;
}
while (allocated <= used + entry_size);
--- 97,116 ----
if (entry[entry[0] != '.' ? 0 : entry[1] != '.' ? 1 : 2] != '\0')
{
size_t entry_size = strlen (entry) + 1;
! if (used + entry_size > INT_MAX / 2)
! {
! free (name_space);
! xalloc_die ();
! }
if (allocated <= used + entry_size)
{
do
{
! if (allocated > INT_MAX / 2)
! {
! free (name_space);
! xalloc_die ();
! }
allocated *= 2;
}
while (allocated <= used + entry_size);
*** lib/unicodeio.c.orig Tue Sep 25 18:52:20 2001
--- lib/unicodeio.c Tue Jul 02 21:14:16 2002
***************
*** 209,215 ****
/* Avoid glibc-2.1 bug and Solaris 2.7 bug. */
# if defined _LIBICONV_VERSION \
! || !((__GLIBC__ - 0 == 2 && __GLIBC_MINOR__ - 0 <= 1) || defined __sun)
/* Get back to the initial shift state. */
res = iconv (utf8_to_local, NULL, NULL, &outptr, &outbytesleft);
--- 209,215 ----
/* Avoid glibc-2.1 bug and Solaris 2.7 bug. */
# if defined _LIBICONV_VERSION \
! || !((__GLIBC__ - 0 == 2 && __GLIBC_MINOR__ - 0 <= 1) || defined __sun ||
defined _UWIN)
/* Get back to the initial shift state. */
res = iconv (utf8_to_local, NULL, NULL, &outptr, &outbytesleft);
*** src/create.c.orig Wed Aug 29 17:21:02 2001
--- src/create.c Tue Jul 02 20:25:17 2002
***************
*** 1108,1114 ****
(entrylen = strlen (entry)) != 0;
entry += entrylen + 1)
{
! if (buflen <= len + entrylen)
{
buflen = len + entrylen;
namebuf = xrealloc (namebuf, buflen + 1);
--- 1108,1114 ----
(entrylen = strlen (entry)) != 0;
entry += entrylen + 1)
{
! if (buflen < len + entrylen)
{
buflen = len + entrylen;
namebuf = xrealloc (namebuf, buflen + 1);
***************
*** 1203,1209 ****
{
/* Check the size of the file against the number of blocks
allocated for it, counting both data and indirect blocks.
! If there is a smaller number of blocks that would be
necessary to accommodate a file of this size, this is safe
to say that we have a sparse file: at least one of those
blocks in the file is just a useless hole. For sparse
--- 1203,1209 ----
{
/* Check the size of the file against the number of blocks
allocated for it, counting both data and indirect blocks.
! If there is a smaller number of blocks than would be
necessary to accommodate a file of this size, this is safe
to say that we have a sparse file: at least one of those
blocks in the file is just a useless hole. For sparse
*** src/extract.c.orig Mon Sep 24 14:55:17 2001
--- src/extract.c Sat Jul 13 08:13:17 2002
***************
*** 766,772 ****
again_file:
openflag = (O_WRONLY | O_BINARY | O_CREAT
! | (old_files_option == OVERWRITE_OLD_FILES
? O_TRUNC
: O_EXCL));
mode = current_stat.st_mode & MODE_RWX & ~ current_umask;
--- 766,772 ----
again_file:
openflag = (O_WRONLY | O_BINARY | O_CREAT
! | (old_files_option != KEEP_OLD_FILES
? O_TRUNC
: O_EXCL));
mode = current_stat.st_mode & MODE_RWX & ~ current_umask;
*** src/tar.c.orig Thu Sep 20 20:11:27 2001
--- src/tar.c Tue Jul 02 14:20:29 2002
***************
*** 720,730 ****
case 'L':
{
! uintmax_t u;
if (xstrtoumax (optarg, 0, 10, &u, "") != LONGINT_OK)
USAGE_ERROR ((0, 0, "%s: %s", quotearg_colon (optarg),
_("Invalid tape length")));
! tape_length_option = 1024 * (tarlong) u;
multi_volume_option = 1;
}
break;
--- 720,738 ----
case 'L':
{
! uintmax_t a = 0, u, un = 1;
! double d, dn = 1.0;
if (xstrtoumax (optarg, 0, 10, &u, "") != LONGINT_OK)
USAGE_ERROR ((0, 0, "%s: %s", quotearg_colon (optarg),
_("Invalid tape length")));
! while (un < u/2)
! un *= 2, dn *= 2.0; /* loop invariants: un is a power of two, un <
u, dn = un */
! while (a < u) /* not finished until a = d = u */
! if (u - a >= un) /* add un (dn) */
! a += un, d += dn;
! else /* can't add un (dn), reduce un (dn) */
! un /= 2, dn /= 2.0;
! tape_length_option = 1024 * (tarlong) d;
multi_volume_option = 1;
}
break;
- Patches for GNU tar 1.13.25,
Bruce Lilly <=