Subject: bin/26688: gzip -d reports incorrect read error
To: None <gnats-bugs@gnats.netbsd.org>
From: Darrin B. Jewell <dbj@netbsd.org>
List: netbsd-bugs
Date: 08/16/2004 17:40:17
>Number:         26688
>Category:       bin
>Synopsis:       gzip -d reports incorrect read error
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    bin-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Mon Aug 16 21:43:00 UTC 2004
>Closed-Date:
>Last-Modified:
>Originator:     Darrin B. Jewell
>Release:        netbsd-2-0 via cvs ~20040722T1714Z
>Organization:
>Environment:
# ident /usr/bin/gzip
/usr/bin/gzip:
     $NetBSD: crt0.c,v 1.13 2003/07/26 19:24:27 salo Exp $
     $NetBSD: gzip.c,v 1.29.2.29 2004/07/19 09:57:24 tron Exp $

>Description:
gzip reports incorrect error when failing to read
the gzip header on stdin.

Code inspection of gzip.c shows this:

  if (read(STDIN_FILENO, header1, sizeof header1) != sizeof header1) {
    maybe_warn("can't read stdin");
    return;
  }

  method = file_gettype(header1);

but read does not set errno unless it returns -1.  For short or
zero length reads, it will return the amount read.

>How-To-Repeat:

# dd if=/dev/null 2> /dev/null | gzip -d > /dev/null
gzip: can't read stdin: Inappropriate ioctl for device
# gzip -d > /dev/null < /dev/null
gzip: can't read stdin: Operation not supported

>Fix:

Something like this:

  rv = read(STDIN_FILENO, header1, sizeof header1);
  if (rv < 0);
    maybe_warn("can't read stdin");
    return;
  } else if (rv < sizeof sizeof header1) {
    method = FS_UNKNOWN;
  } else {
    method = file_gettype(header1);
  }

Note that i think this problem also occurs elsewhere in gzip.c
for other uses of read.

Darrin
>Release-Note:
>Audit-Trail:
>Unformatted: