Subject: bin/35048: when compressing, gzip(1) unlinks input even if output can't be written
To: None <gnats-admin@netbsd.org, netbsd-bugs@netbsd.org>
From: None <b1ff@fr33.b33r.net>
List: netbsd-bugs
Date: 11/13/2006 21:30:01
>Number: 35048
>Category: bin
>Synopsis: when compressing, gzip(1) unlinks input even if output can't be written
>Confidential: no
>Severity: non-critical
>Priority: low
>Responsible: bin-bug-people
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Mon Nov 13 21:30:00 +0000 2006
>Originator: Mathieu
>Release: 3.0.1
>Organization:
>Environment:
>Description:
If writing fails (like when the FS gets full), gzip will still delete the input file. Ouch.
>How-To-Repeat:
$ df -h .
Filesystem Size Used Avail Capacity Mounted on
/dev/vnd1a 19M 1.0K 18M 0% /mnt
$ dd if=/dev/zero of=test bs=1m count=10
10+0 records in
10+0 records out
10485760 bytes transferred in 0.225 secs (46603377 bytes/sec)
$ cp /netbsd .
$ gzip netbsd
/mnt: write failed, file system is full
gzip: write: No space left on device
$ ls -l
total 10448
-rwx------ 1 mathieu wheel 196608 Nov 13 15:46 netbsd.gz
-rw------- 1 mathieu wheel 10485760 Nov 13 15:46 test
$ gzip -t netbsd.gz
gzip: netbsd.gz: unexpected end of file
>Fix:
/* $NetBSD: gzip.c,v 1.71.2.5 2005/11/27 23:09:46 riz Exp $ */
--- gzip.c 2006-11-13 16:12:57.000000000 -0500
+++ gzip.c.orig 2006-11-13 16:13:45.000000000 -0500
@@ -561,7 +561,7 @@
if (z.avail_out == 0) {
if (write(out, outbufp, BUFLEN) != BUFLEN) {
maybe_warn("write");
- in_tot = -1;
+ out_tot = -1;
goto out;
}
It seems like there's a simple typo there. I'm not sure if it fixes completely the problem yet... but it does seem to work here.
$ gzip netbsd
gzip: output file: netbsd.gz wrong size (2293760 != -1), deleting
gzip: leaving original netbsd
$ ls -l
total 16528
-rwx------ 1 mathieu wheel 8514752 Nov 13 16:12 netbsd
-rw------- 1 mathieu wheel 8388608 Nov 13 15:58 test