Re: [Bug-tar] [PATCH] Do not fail when 'compress' is unable to provide sufficient compress ratio

2013-04-29 Thread Pavel Raiskup
On Sunday, April 28, 2013 07:23:05 PM Antonio Diaz Diaz wrote:
 Paul Eggert wrote:
 Converting gzip to the general API seems the right thing to do in the long 
 term.
 
  That might be wise, yes, but there might be other users who
  expect the current behavior, and we'd need to consult with them.

 To my surprise I have found that the current behavior is that gzip does
 not return '2' even if the compressed file is larger than the original:

Thanks, there are probably other circumstances in 'gzip' invoking warning?

  And there are a lot of other compressor programs to update.
  In the meantime 'tar' should work with what's out there.

 If it is not broken, don't fix it.  I think nobody has reported a problem
 caused by any compressor other than compress returning 2.

I would not wait for a bugreport..  Tar should really accept API of
compressors it uses imo.

 Most probably it is the documentation of those other compressors
 (including gzip) what is wrong, not the code.

I guess it is not bug in gzip doc, but afaik Paul is also 'gzip'
maintainer so he would be able to talk about gzip more.

Pavel




Re: [Bug-tar] [PATCH] Do not fail when 'compress' is unable to provide sufficient compress ratio

2013-04-29 Thread Paul Eggert
If you look at the gzip source code you'll
find a number of circumstances that will
cause it to exit with status 2, as a warning.
This API isn't likely to change any time soon,
I'm afraid, as gzip is fairly frozen.



Re: [Bug-tar] [PATCH] Do not fail when 'compress' is unable to provide sufficient compress ratio

2013-04-28 Thread Antonio Diaz Diaz

Paul Eggert wrote:

Converting gzip to the general API seems the right thing to do in the long term.


That might be wise, yes, but there might be other users who
expect the current behavior, and we'd need to consult with them.


To my surprise I have found that the current behavior is that gzip does 
not return '2' even if the compressed file is larger than the original:


$ dd if=/dev/urandom of=testfile bs=1K count=1
$ ls -go testfile*
-rw-r--r--  1 1024 2013-04-28 19:04 testfile
$ gzip testfile ; echo $?
0
$ ls -go testfile*
-rw-r--r--  1 1056 2013-04-28 19:04 testfile.gz



And there are a lot of other compressor programs to update.
In the meantime 'tar' should work with what's out there.


If it is not broken, don't fix it. I think nobody has reported a problem 
caused by any compressor other than compress returning 2. Most probably 
it is the documentation of those other compressors (including gzip) what 
is wrong, not the code.



Best regards,
Antonio.




Re: [Bug-tar] [PATCH] Do not fail when 'compress' is unable to provide sufficient compress ratio

2013-04-26 Thread Paul Eggert
On 04/26/2013 12:56 AM, Pavel Raiskup wrote:
 So you think something like remove the leading path '/usr/bin/' before
 comparison with 'GZIP_PROGRAM'?

I'm afraid that will lead to even more confusion; among other things,
tar shouldn't care what the program names are.

It may be better to have two different options.  One, designed
for programs that behave like 'compress' does, where exit status 2
is OK.  The other, for normal programs, where only exit status 0
is OK.  When tar infers a compressor it can also infer which of these
two options to use.



Re: [Bug-tar] [PATCH] Do not fail when 'compress' is unable to provide sufficient compress ratio

2013-04-26 Thread Pavel Raiskup
 When tar infers a compressor it can also infer which of these two
 options to use.

That means, using the -Z, -z, .. options will setup some new flag, same
as the new use-compress-program-like option will.  Do you have some
requirements for this option name?  This is the hard one..

Would you be OK if I tried to prepare the patch?




Re: [Bug-tar] [PATCH] Do not fail when 'compress' is unable to provide sufficient compress ratio

2013-04-26 Thread Paul Eggert
On 04/26/2013 01:17 AM, Pavel Raiskup wrote:
 Do you have some
 requirements for this option name?

We could have --use-compress-program for the compress API,
and --use-filter-program for the more-vanilla API.
Or something like that.  I'm fine with your preparing
a patch.



Re: [Bug-tar] [PATCH] Do not fail when 'compress' is unable to provide sufficient compress ratio

2013-04-26 Thread Pavel Raiskup
On Friday, April 26, 2013 01:36:02 AM Paul Eggert wrote:
 On 04/26/2013 01:17 AM, Pavel Raiskup wrote:
  Do you have some
  requirements for this option name?
 
 We could have --use-compress-program for the compress API,
 and --use-filter-program for the more-vanilla API.
 Or something like that.  I'm fine with your preparing
 a patch.

I agree that this would be the most logical.  But there is a problem with
backward compatibility.  The behaviour of --use-compress-program will
change.. what about this:

  -I, --use-filter-program (general 'vanilla' API)
  --use-compress-program (obsoleted alias to ^^^)
  // remove from --help  man  info to not confuse people
  --use-compress-like-program (with a *proper* definition what it does)
  // or choose a better name?

Pavel




Re: [Bug-tar] [PATCH] Do not fail when 'compress' is unable to provide sufficient compress ratio

2013-04-26 Thread Paul Eggert
On 04/26/2013 03:07 AM, Pavel Raiskup wrote:
   -I, --use-filter-program (general 'vanilla' API)
   --use-compress-program (obsoleted alias to ^^^)
   // remove from --help  man  info to not confuse people
   --use-compress-like-program (with a *proper* definition what it does)
   // or choose a better name?

Something like this sounds good.  But how about
dropping the use- for the new options?
That will simplify things a bit.  Like this:

  -I, --filter-program (general 'vanilla' API)
  --use-compress-program (obsoleted alias for --filter-program)
  // remove from --help  man  info to not confuse people
  --compress-program (with a *proper* definition what it does)




Re: [Bug-tar] [PATCH] Do not fail when 'compress' is unable to provide sufficient compress ratio

2013-04-26 Thread Paul Eggert
On 04/26/2013 10:07 AM, Antonio Diaz Diaz wrote:
 Converting gzip to the general API seems the right thing to do in the long 
 term.

That might be wise, yes, but there might be other users who
expect the current behavior, and we'd need to consult with them.
And there are a lot of other compressor programs to update.
In the meantime 'tar' should work with what's out there.



Re: [Bug-tar] [PATCH] Do not fail when 'compress' is unable to provide sufficient compress ratio

2013-04-25 Thread Pavel Raiskup
On Wednesday, April 24, 2013 10:58:10 PM Paul Eggert wrote:
 I think I'd rather have tar assume the gzip exit-status
 convention, and depart from that only for bzip2 and lzip
 (which don't use the convention).  That's a bit simpler
 and is more likely to match some random future compressor.

Should I fix that patch then?  This will probably bring
incompatibilities into dealing with user-defined scripts passed by
--use-compress-program (until that change, tar was accepted non-zero
exit value as an error).  Don't really know how much we should care
about this..

Pavel




Re: [Bug-tar] [PATCH] Do not fail when 'compress' is unable to provide sufficient compress ratio

2013-04-25 Thread Antonio Diaz Diaz

Paul Eggert wrote:

I think I'd rather have tar assume the gzip exit-status
convention, and depart from that only for bzip2 and lzip
(which don't use the convention).  That's a bit simpler
and is more likely to match some random future compressor.


Only if the random future compressor continues repeating the errors of 
the past.


Bzip2 and lzip follow a deeper convention; that any non-zero exit status 
means failure[1]:


[1]http://www.gnu.org/software/bash/manual/html_node/Exit-Status.html#Exit-Status

For the shell's purposes, a command which exits with a zero exit status 
has succeeded. A non-zero exit status indicates failure. This seemingly 
counter-intuitive scheme is used so there is one well-defined way to 
indicate success and a variety of ways to indicate various failure modes.



Routing around gzip's quirks may be necessary, but if we begin 
considering some non-zero exit statuses as success, chaos will develop. 
The --use-compress-program is a general mechanism, not only for 
compressors[2]:


[2]http://www.gnu.org/software/tar/manual/html_node/gzip.html#SEC132

The '--use-compress-program' option, in particular, lets you implement 
your own filters, not necessarily dealing with 
compression/decompression. For example, suppose you wish to implement 
PGP encryption on top of compression, using gpg



And it happens that '2' is in the range gpg reserves for fatal errors[3]:

[3]http://www.gnupg.org/documentation/manuals/gnupg/GPG-Examples.html#GPG-Examples

The program returns 0 if everything was fine, 1 if at least a signature 
was bad, and other error codes for fatal errors.



So, please, don't break --use-compress-program.


Best regards,
Antonio.



Re: [Bug-tar] [PATCH] Do not fail when 'compress' is unable to provide sufficient compress ratio

2013-04-24 Thread Paul Eggert
I think I'd rather have tar assume the gzip exit-status
convention, and depart from that only for bzip2 and lzip
(which don't use the convention).  That's a bit simpler
and is more likely to match some random future compressor.



Re: [Bug-tar] [PATCH] Do not fail when 'compress' is unable to provide sufficient compress ratio

2013-04-22 Thread Pavel Raiskup
On Tuesday, February 26, 2013 08:32:25 AM Pavel Raiskup wrote:
 On Mon, 2013-02-25 at 11:39 -0800, Paul Eggert wrote:
  I suggest something simpler: namely, just declare that the
  -Z (compress) program must conform to the compress API,
  so that its exit status 2 really means OK.  That way,
  we can change only src/system.c and NEWS.  The compress API
  is obsolete and isn't likely to change so this sounds safe.
 
 Thanks for comments!  Attaching approach with just src/system.c
 and NEWS edited.

Hi, I have looked once again on usual compressors and I see now that not
only 'compress' API exits with 2 exit status in case of warning .. 'gzip',
'xz', 'lzma' and 'lzop' behave similarly.

Attaching probably better fix, any comment is welcome!

Pavel
From 5f316c5500c6c62bae9c5a83de711eacd2615611 Mon Sep 17 00:00:00 2001
From: Pavel Raiskup prais...@redhat.com
Date: Mon, 25 Feb 2013 10:18:15 +0100
Subject: [PATCH] tar: do not fail hardly when compressor just warns
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Usual compressor exit status API is that 0 means successful
compression, 1 is fatal error and 2 is warning.  The two
exceptions used by tar by default are Bzip2 and lzip at the
moment — any non-zero value is fatal error.

* src/system.c (sys_wait_for_child): Warn only when child process
exited with 2 and the compressing command wasn't bzip2 or lzip.
* NEWS: Document.
---
 NEWS |  9 +
 src/system.c | 22 +++---
 2 files changed, 28 insertions(+), 3 deletions(-)

diff --git a/NEWS b/NEWS
index 3108798..aa8c82e 100644
--- a/NEWS
+++ b/NEWS
@@ -6,6 +6,15 @@ version 1.26.90 (Git)
 
 * Bug fixes
 
+** tar successes now when compressor warns only
+
+Tar does not fail with fatal exit status 2 if the tar's child
+compressor exited with warning exit status 2.  This is usual default
+for 'xz', 'gzip', 'compress', 'lzop' and 'lzma' compressors.  The
+'bzip2' and 'lzip' compressors are throwing non-zero exit status in
+case of fatal error.  Tar still fails hardly if user specified script
+passed by --use-compress-program returns non-zero status.
+
 ** Sparse files with large data
 
 When creating a PAX-format archive, tar no longer arbitrarily restricts
diff --git a/src/system.c b/src/system.c
index e1fd263..4cd12e9 100644
--- a/src/system.c
+++ b/src/system.c
@@ -189,9 +189,25 @@ sys_wait_for_child (pid_t child_pid, bool eof)
 	  if (!(!eof  sig == SIGPIPE))
 	FATAL_ERROR ((0, 0, _(Child died with signal %d), sig));
 	}
-  else if (WEXITSTATUS (wait_status) != 0)
-	FATAL_ERROR ((0, 0, _(Child returned status %d),
-		  WEXITSTATUS (wait_status)));
+  /* Exit value of common compressors usually conforms to following
+ defaults: 0 is successful compression, 1 is fatal error and 2 is
+ warning.
+ Bzip2 and lzip return non-zero value in case of fatal error - use
+ this as default behavior also for user-defined scripts.
+ */
+  else if (WEXITSTATUS (wait_status) == 0)
+return;
+  else if (WEXITSTATUS (wait_status) == 2
+(!strcmp (use_compress_program_option, GZIP_PROGRAM)
+|| !strcmp (use_compress_program_option, XZ_PROGRAM)
+|| !strcmp (use_compress_program_option, LZMA_PROGRAM)
+|| !strcmp (use_compress_program_option, LZOP_PROGRAM)
+|| !strcmp (use_compress_program_option, COMPRESS_PROGRAM)))
+WARN ((0, 0, _(%lu: Child (compressor '%s') exited with warning),
+   (unsigned long) child_pid, use_compress_program_option));
+  else
+FATAL_ERROR ((0, 0, _(Child '%s' returned exit status %d),
+  use_compress_program_option, WEXITSTATUS (wait_status)));
 }
 }
 
-- 
1.8.1.4



Re: [Bug-tar] [PATCH] Do not fail when 'compress' is unable to provide sufficient compress ratio

2013-02-25 Thread Pavel Raiskup
 I'm attaching one possible solution, could you look at it?

Sorry for the typo, re-attaching because of this:

| diff --git a/src/system.c b/src/system.c
| index ca0ad05..d722352 100644
| --- a/src/system.c
| +++ b/src/system.c
| @@ -192,7 +192,7 @@ sys_wait_for_child (pid_t child_pid, bool eof)
|  #ifdef HAVE_COMPRESS_EXIT_HACK
|else if (!strcmp (use_compress_program_option, HAVE_COMPRESS_EXIT_HACK)
| WEXITSTATUS (wait_status) == 2)
| -WARN ((0, 0, _(%lu: Child says that compressed output is larger
| +WARN ((0, 0, _(%lu: Child says that compressed output is larger 
|then original data.),
|(unsigned long) child_pid));
|  #endif


From 3281269662a7d361ef8a360600352e93cc2ebdcf Mon Sep 17 00:00:00 2001
From: Pavel Raiskup prais...@redhat.com
Date: Mon, 25 Feb 2013 10:18:15 +0100
Subject: [PATCH] tar: The Lempel-Ziv coding bugfix

Do not exit with fatal error 2 after compressing tarball by the
'compress' utility (-Z option) when the child process running the
compressor exited with just-a-warning exit value 2.  There is still
possible to restore the old tar behavior by running
'./configure --without-compress-exit-hack' (e.g. in situations when
there resides different compress implementation on the target system).

* acinclude.m4 (TAR_COMPRESS_EXIT_HACK): New function.
* configure.ac: Use TAR_COMPRESS_EXIT_HACK.
* src/system.c (sys_wait_for_child) [#ifdef HAVE_COMPRESS_EXIT_HACK]:
Warn when the compressed data are larger then the original data if
the child process command exited with 2 while the compressing
command was called 'compress'.
* NEWS: Document.
---
 NEWS |  7 +++
 acinclude.m4 | 19 +++
 configure.ac |  3 +++
 src/system.c |  7 +++
 4 files changed, 36 insertions(+)

diff --git a/NEWS b/NEWS
index 3108798..863cf52 100644
--- a/NEWS
+++ b/NEWS
@@ -6,6 +6,13 @@ version 1.26.90 (Git)
 
 * Bug fixes
 
+** The Lempel-Ziv coding compression bugfix (compress)
+
+Do not exit with fatal error during compressing by the 'compress'
+utility (-Z option) when the child process running the compressor exits
+with warning exit value 2.  It just means that the compressed output is
+bigger then original data.  Just warn the user now instead of hard fail.
+
 ** Sparse files with large data
 
 When creating a PAX-format archive, tar no longer arbitrarily restricts
diff --git a/acinclude.m4 b/acinclude.m4
index d48c881..1367eed 100644
--- a/acinclude.m4
+++ b/acinclude.m4
@@ -52,3 +52,22 @@ AC_DEFUN([TAR_HEADERS_ATTR_XATTR_H],
 )
   fi
 ])
+
+# Allow maintainer to disable compress's exit-2-value hack
+AC_DEFUN([TAR_COMPRESS_EXIT_HACK],[
+  AC_ARG_WITH(
+[compress-exit-hack],
+AS_HELP_STRING(
+  [--without-compress-exit-hack],
+  [fail when -Z (compress) compressor exists with non-error value 2]),
+[with_compress_exit_hack=no]
+  )
+  if test x$with_compress_exit_hack != xno; then
+AC_DEFINE_UNQUOTED(
+  HAVE_COMPRESS_EXIT_HACK,
+  $tar_cv_compressor_compress,
+  Define to name of compress utility when we don't want to fail hardly
+  if this utility exits with exit code 2.  It should just mean that the
+  compressed file is bigger than original file.)
+  fi
+])
diff --git a/configure.ac b/configure.ac
index 3303c53..b0a4f14 100644
--- a/configure.ac
+++ b/configure.ac
@@ -253,6 +253,9 @@ TAR_COMPR_PROGRAM(lzma)
 TAR_COMPR_PROGRAM(lzop)
 TAR_COMPR_PROGRAM(xz)
 
+# must be called after TAR_COMPR_PROGRAM(compress) call
+TAR_COMPRESS_EXIT_HACK
+
 AC_MSG_CHECKING(for default archive format)
 
 AC_ARG_VAR([DEFAULT_ARCHIVE_FORMAT],
diff --git a/src/system.c b/src/system.c
index e1fd263..d722352 100644
--- a/src/system.c
+++ b/src/system.c
@@ -189,6 +189,13 @@ sys_wait_for_child (pid_t child_pid, bool eof)
 	  if (!(!eof  sig == SIGPIPE))
 	FATAL_ERROR ((0, 0, _(Child died with signal %d), sig));
 	}
+#ifdef HAVE_COMPRESS_EXIT_HACK
+  else if (!strcmp (use_compress_program_option, HAVE_COMPRESS_EXIT_HACK)
+	WEXITSTATUS (wait_status) == 2)
+WARN ((0, 0, _(%lu: Child says that compressed output is larger 
+		   then original data.),
+	   (unsigned long) child_pid));
+#endif
   else if (WEXITSTATUS (wait_status) != 0)
 	FATAL_ERROR ((0, 0, _(Child returned status %d),
 		  WEXITSTATUS (wait_status)));
-- 
1.8.1.2



Re: [Bug-tar] [PATCH] Do not fail when 'compress' is unable to provide sufficient compress ratio

2013-02-25 Thread Paul Eggert
I suggest something simpler: namely, just declare that the
-Z (compress) program must conform to the compress API,
so that its exit status 2 really means OK.  That way,
we can change only src/system.c and NEWS.  The compress API
is obsolete and isn't likely to change so this sounds safe.



Re: [Bug-tar] [PATCH] Do not fail when 'compress' is unable to provide sufficient compress ratio

2013-02-25 Thread Pavel Raiskup
On Mon, 2013-02-25 at 11:39 -0800, Paul Eggert wrote:
 I suggest something simpler: namely, just declare that the
 -Z (compress) program must conform to the compress API,
 so that its exit status 2 really means OK.  That way,
 we can change only src/system.c and NEWS.  The compress API
 is obsolete and isn't likely to change so this sounds safe.

Thanks for comments!  Attaching approach with just src/system.c
and NEWS edited.

Pavel

From eab80fb7c5a5500a9d4c20321b4f00e019cb3735 Mon Sep 17 00:00:00 2001
From: Pavel Raiskup prais...@redhat.com
Date: Mon, 25 Feb 2013 10:18:15 +0100
Subject: [PATCH] tar: The Lempel-Ziv coding handler bugfix

Do not exit with fatal error 2 after compressing tarball by the
'compress' utility (-Z option) when the child process running the
compressor exited with just-a-warning exit value 2 (compressed
output is larger than original data).

* src/system.c (sys_wait_for_child): Warn only when child process
exited with 2 and the compressing command was called 'compress'.
* NEWS: Document.
---
 NEWS | 11 +++
 src/system.c |  7 +++
 2 files changed, 18 insertions(+)

diff --git a/NEWS b/NEWS
index 3108798..17df594 100644
--- a/NEWS
+++ b/NEWS
@@ -6,6 +6,17 @@ version 1.26.90 (Git)
 
 * Bug fixes
 
+** The Lempel-Ziv coding compression bugfix (compress)
+
+Do not exit with fatal error 2 after the tarball compressing when
+the tar's child 'compress' process (-Z option) exited with
+just-a-warning exit value 2.  It just means that output of the
+'compress' utility became bigger than it's original data
+(insufficient compress ratio).  Tar just warns now under these
+circumstances instead of failing hard.  Any compressor used by the
+'-Z' option must conform to compress API now - thus the exit value
+'2' must signify successful exit status.
+
 ** Sparse files with large data
 
 When creating a PAX-format archive, tar no longer arbitrarily restricts
diff --git a/src/system.c b/src/system.c
index e1fd263..10f76a3 100644
--- a/src/system.c
+++ b/src/system.c
@@ -189,6 +189,13 @@ sys_wait_for_child (pid_t child_pid, bool eof)
 	  if (!(!eof  sig == SIGPIPE))
 	FATAL_ERROR ((0, 0, _(Child died with signal %d), sig));
 	}
+  /* Any compressor used by the '-Z' option must conform to the 'compress'
+ API - value 2 is OK exit status (not a fatal error) */
+  else if (WEXITSTATUS (wait_status) == 2
+	!strcmp (use_compress_program_option, COMPRESS_PROGRAM))
+WARN ((0, 0, _(%lu: Child says that compressed output is larger 
+		   than original data.),
+	   (unsigned long) child_pid));
   else if (WEXITSTATUS (wait_status) != 0)
 	FATAL_ERROR ((0, 0, _(Child returned status %d),
 		  WEXITSTATUS (wait_status)));
-- 
1.8.1.2