On 08/22/2012 03:34 AM, Cyril Roelandt wrote:
Hi !
I've just tried tarfs, and it seems to me that it does not handle tar.gz
files very well. I got the code from the Hurd incubator, compiled it,
and ran the following commands to create a simple tar.gz file:
$ mkdir -p a/b/c
$ touch a/foo
$ touch a/b/c/bar
$ tar czvf foobar.tar.gz a/
Here is what I got when trying to run tarfs:
$ settrans -ca ./foobar ./tarfs -z ./foobar.tar.gz -D -
gzip_open: Underlying file size is 183 bytes
gzip_read_header: Gzip compression method: 0x08
gzip_open: start_file_offs = 10
gzip_stream_read: End of file
gzip_stream_read: offset file/zip = 10 / 0
gzip_stream_read: avail in/out = 173 / 8192
gzip_stream_read: requested/read = 8192 / 8192
gzip_stream_read: offset file/zip = 170 / 8192
gzip_stream_read: avail in/out = 13 / 8192
gzip_stream_read: End of stream
gzip_verify_crc: Valid gzip CRC
gzip_verify_crc: Valid gzip uncompressed stream size (10240)
gzip_stream_read: requested/read = 8192 / 2048
traverse: file traversed (offset file/zip = 175 / 10240)
gzip_open: Uncompressed stream size is 10240
gzip_stream_read: End of file
gzip_stream_read: offset file/zip = 10 / 0
gzip_stream_read: avail in/out = 173 / 512
gzip_error: zlib error: stream error
gzip_stream_read: requested/read = 512 / 0
./tarfs: Read error (offset=0): Invalid argument
settrans: ./tarfs: Translator died
I think this is caused by the call to ZIP_DECOMPRESS in the "ZIP
(stream_read)" function. It fails when stream->next_out is NULL (cf.
http://www.zlib.net/manual.html : inflate() returns Z_STREAM_ERROR if
the next_out field is NULL).
stream->next_out is set in zipstores.c, at line 370:
stream->next_out = (uchar *) buf;
"buf" is a parameter of the "ZIP (stream_read)" function, which is
called by the "ZIP (read)" function:
static error_t
ZIP (read) (struct store *store,
store_offset_t offset, size_t index, size_t amount, void **buf,
size_t *len)
{
...
}
This function is called with *buf == NULL, which, I think, leads to the
failure of tarfs.
OK, Ludovic Courtès and I looked at this issue today, and I think the
following patch fixes the issue:
diff --git a/tar.c b/tar.c
index e7391f9..65f94b3 100644
--- a/tar.c
+++ b/tar.c
@@ -119,7 +119,7 @@ static union record *
tar_get_next_record (struct archive *archive)
{
error_t err;
- void *buf = NULL;
+ void *buf = mmap(NULL, RECORDSIZE, PROT_READ|PROT_WRITE,
MAP_ANONYMOUS, 0, 0);
size_t n = 0;
err = store_read (archive->tar_file,
archive->current_tar_position, RECORDSIZE, &buf, &n);
WBR,
Cyril Roelandt.