Thanks for reporting that problem. The full fix is a bit trickier than I'd like, but I've installed the following into the gzip CVS sources.
2006-12-23 Paul Eggert <[EMAIL PROTECTED]> * NEWS: Fix bug reported by Martin Mares in <http://bugs.debian.org/177942>. * gzip.c (treat_stdin): Remove NO_STDIN_FSTAT and NO_PIPE_TIMESTAMP stuff. It didn't work (led to syntax errors) and was confusing. Report an error if stdin cannot be statted even if !list && no_time. Get stdin's size if it is regular. (treat_file): Do not report an error with setuid, setgid, sticky, or non-regular, non-directory files if to_stdout. Allow 'force' to override the caution about sticky files. Use the same form for time stamps that treat_stdin uses. --- NEWS 24 Dec 2006 05:25:19 -0000 1.11 +++ NEWS 24 Dec 2006 05:45:05 -0000 @@ -2,6 +2,9 @@ Gzip 1.3.10 (200?-??-??) * zcmp and zdiff did not work in the usual case, due to a typo. +* gzip -c and zcat now work on special files, files with special mode bits, + and files with multiple hard links. + Gzip 1.3.9 (2006-12-15) * No major changes; only porting fixes. --- gzip.c 12 Dec 2006 00:03:17 -0000 1.11 +++ gzip.c 24 Dec 2006 05:45:05 -0000 @@ -616,22 +616,16 @@ local void treat_stdin() strcpy(ifname, "stdin"); strcpy(ofname, "stdout"); - /* Get the time stamp on the input file. */ - time_stamp.tv_nsec = -1; /* The time is unknown by default. */ - -#ifndef NO_STDIN_FSTAT - if (list || !no_time) { - if (fstat(fileno(stdin), &istat) != 0) { - progerror("standard input"); - do_exit(ERROR); - } -# ifdef NO_PIPE_TIMESTAMP - if (S_ISREG(istat.st_mode)) -# endif - time_stamp = get_stat_mtime (&istat); -#endif /* NO_STDIN_FSTAT */ - } - ifile_size = -1L; /* convention for unknown size */ + /* Get the file's time stamp and size. */ + if (fstat (fileno (stdin), &istat) != 0) + { + progerror ("standard input"); + do_exit (ERROR); + } + ifile_size = S_ISREG (istat.st_mode) ? istat.st_size : -1; + time_stamp.tv_nsec = -1; + if (!no_time || list) + time_stamp = get_stat_mtime (&istat); clear_bufs(); /* clear input and output buffers */ to_stdout = 1; @@ -710,48 +704,57 @@ local void treat_file(iname) program_name, ifname)); return; } - if (!S_ISREG(istat.st_mode)) { - WARN((stderr, - "%s: %s is not a directory or a regular file - ignored\n", - program_name, ifname)); - close (ifd); - return; - } - if (istat.st_mode & S_ISUID) + if (! to_stdout) { - WARN ((stderr, "%s: %s is set-user-ID on execution - ignored\n", - program_name, ifname)); - close (ifd); - return; - } - if (istat.st_mode & S_ISGID) - { - WARN ((stderr, "%s: %s is set-group-ID on execution - ignored\n", - program_name, ifname)); - close (ifd); - return; - } - if (istat.st_mode & S_ISVTX) - { - WARN ((stderr, "%s: %s has the sticky bit set - file ignored\n", - program_name, ifname)); - close (ifd); - return; - } + if (! S_ISREG (istat.st_mode)) + { + WARN ((stderr, + "%s: %s is not a directory or a regular file - ignored\n", + program_name, ifname)); + close (ifd); + return; + } + if (istat.st_mode & S_ISUID) + { + WARN ((stderr, "%s: %s is set-user-ID on execution - ignored\n", + program_name, ifname)); + close (ifd); + return; + } + if (istat.st_mode & S_ISGID) + { + WARN ((stderr, "%s: %s is set-group-ID on execution - ignored\n", + program_name, ifname)); + close (ifd); + return; + } - if (istat.st_nlink > 1 && !to_stdout && !force) { - WARN((stderr, "%s: %s has %lu other link%c -- unchanged\n", - program_name, ifname, (unsigned long) istat.st_nlink - 1, - istat.st_nlink > 2 ? 's' : ' ')); - close (ifd); - return; - } + if (! force) + { + if (istat.st_mode & S_ISVTX) + { + WARN ((stderr, + "%s: %s has the sticky bit set - file ignored\n", + program_name, ifname)); + close (ifd); + return; + } + if (2 <= istat.st_nlink) + { + WARN ((stderr, "%s: %s has %lu other link%c -- unchanged\n", + program_name, ifname, + (unsigned long int) istat.st_nlink - 1, + istat.st_nlink == 2 ? ' ' : 's')); + close (ifd); + return; + } + } + } - ifile_size = istat.st_size; - if (no_time && !list) - time_stamp.tv_nsec = -1; - else + ifile_size = S_ISREG (istat.st_mode) ? istat.st_size : -1; + time_stamp.tv_nsec = -1; + if (!no_time || list) time_stamp = get_stat_mtime (&istat); /* Generate output file name. For -r and (-t or -l), skip files