bug-gnu-utils
[Top][All Lists]
Advanced

[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;

reply via email to

[Prev in Thread] Current Thread [Next in Thread]