From owner-svn-src-all@freebsd.org Tue Nov 21 08:14:31 2017 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id D7A1BDE7308; Tue, 21 Nov 2017 08:14:31 +0000 (UTC) (envelope-from delphij@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 9E6C86446D; Tue, 21 Nov 2017 08:14:31 +0000 (UTC) (envelope-from delphij@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id vAL8EUx5047093; Tue, 21 Nov 2017 08:14:30 GMT (envelope-from delphij@FreeBSD.org) Received: (from delphij@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id vAL8EUgM047088; Tue, 21 Nov 2017 08:14:30 GMT (envelope-from delphij@FreeBSD.org) Message-Id: <201711210814.vAL8EUgM047088@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: delphij set sender to delphij@FreeBSD.org using -f From: Xin LI Date: Tue, 21 Nov 2017 08:14:30 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r326052 - head/usr.bin/gzip X-SVN-Group: head X-SVN-Commit-Author: delphij X-SVN-Commit-Paths: head/usr.bin/gzip X-SVN-Commit-Revision: 326052 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.25 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 21 Nov 2017 08:14:31 -0000 Author: delphij Date: Tue Nov 21 08:14:30 2017 New Revision: 326052 URL: https://svnweb.freebsd.org/changeset/base/326052 Log: Support SIGINFO. Obtained from: NetBSD MFC after: 2 weeks Modified: head/usr.bin/gzip/gzip.1 head/usr.bin/gzip/gzip.c head/usr.bin/gzip/unbzip2.c head/usr.bin/gzip/unpack.c head/usr.bin/gzip/unxz.c Modified: head/usr.bin/gzip/gzip.1 ============================================================================== --- head/usr.bin/gzip/gzip.1 Tue Nov 21 07:35:29 2017 (r326051) +++ head/usr.bin/gzip/gzip.1 Tue Nov 21 08:14:30 2017 (r326052) @@ -1,6 +1,6 @@ -.\" $NetBSD: gzip.1,v 1.26 2015/10/27 07:36:18 mrg Exp $ +.\" $NetBSD: gzip.1,v 1.30 2017/10/22 17:36:49 abhinav Exp $ .\" -.\" Copyright (c) 1997, 2003, 2004 Matthew R. Green +.\" Copyright (c) 1997, 2003, 2004, 2008, 2009, 2015, 2017 Matthew R. Green .\" All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without @@ -25,11 +25,13 @@ .\" SUCH DAMAGE. .\" .\" $FreeBSD$ -.Dd October 26, 2015 +.Dd November 21, 2017 .Dt GZIP 1 .Os .Sh NAME -.Nm gzip +.Nm gzip , +.Nm gunzip , +.Nm zcat .Nd compression/decompression tool using Lempel-Ziv coding (LZ77) .Sh SYNOPSIS .Nm @@ -112,67 +114,68 @@ or .Sh OPTIONS The following options are available: .Bl -tag -width XXrXXXrecursiveX -.It Fl 1 , -fast +.It Fl 1 , Fl Fl fast .It Fl 2 , 3 , 4 , 5 , 6 , 7 , 8 -.It Fl 9 , -best +.It Fl 9 , Fl Fl best These options change the compression level used, with the .Fl 1 option being the fastest, with less compression, and the .Fl 9 option being the slowest, with optimal compression. The default compression level is 6. -.It Fl c , -stdout , -to-stdout +.It Fl c , Fl Fl stdout , Fl Fl to-stdout This option specifies that output will go to the standard output stream, leaving files intact. -.It Fl d , -decompress , -uncompress +.It Fl d , Fl Fl decompress , Fl Fl uncompress This option selects decompression rather than compression. -.It Fl f , -force +.It Fl f , Fl Fl force This option turns on force mode. This allows files with multiple links, symbolic links to regular files, overwriting of pre-existing files, reading from or writing to a terminal, and when combined with the .Fl c option, allowing non-compressed data to pass through unchanged. -.It Fl h , -help +.It Fl h , Fl Fl help This option prints a usage summary and exits. -.It Fl k , -keep -Keep (do not delete) input files during compression -or decompression. +.It Fl k , Fl Fl keep +This option prevents +.Nm +from deleting input files after (de)compression. .It Fl L , -license This option prints .Nm license. -.It Fl l , -list +.It Fl l , Fl Fl list This option displays information about the file's compressed and uncompressed size, ratio, uncompressed name. With the .Fl v option, it also displays the compression method, CRC, date and time embedded in the file. -.It Fl N , -name +.It Fl N , Fl Fl name This option causes the stored filename in the input file to be used as the output file. -.It Fl n , -no-name +.It Fl n , Fl Fl no-name This option stops the filename and timestamp from being stored in the output file. -.It Fl q , -quiet +.It Fl q , Fl Fl quiet With this option, no warnings or errors are printed. -.It Fl r , -recursive +.It Fl r , Fl Fl recursive This option is used to .Nm the files in a directory tree individually, using the .Xr fts 3 library. -.It Fl S Ar suffix , Fl -suffix Ar suffix +.It Fl S Ar suffix , Fl Fl suffix Ar suffix This option changes the default suffix from .gz to .Ar suffix . -.It Fl t , -test +.It Fl t , Fl Fl test This option will test compressed files for integrity. -.It Fl V , -version +.It Fl V , Fl Fl version This option prints the version of the .Nm program. -.It Fl v , -verbose +.It Fl v , Fl Fl verbose This option turns on verbose mode, which prints the compression ratio for each file compressed. .El @@ -189,6 +192,13 @@ The utility exits 0 on success, 1 on errors, and 2 if a warning occurs. +.Sh SIGNALS +.Nm +responds to the following signals: +.Bl -tag -width indent +.It Dv SIGINFO +Report progress to standard error. +.El .Sh SEE ALSO .Xr bzip2 1 , .Xr compress 1 , @@ -213,7 +223,8 @@ This implementation of .Nm was ported based on the .Nx -.Nm , +.Nm +version 20170803, and first appeared in .Fx 7.0 . .Sh AUTHORS Modified: head/usr.bin/gzip/gzip.c ============================================================================== --- head/usr.bin/gzip/gzip.c Tue Nov 21 07:35:29 2017 (r326051) +++ head/usr.bin/gzip/gzip.c Tue Nov 21 08:14:30 2017 (r326052) @@ -1,7 +1,8 @@ -/* $NetBSD: gzip.c,v 1.109 2015/10/27 07:36:18 mrg Exp $ */ +/* $NetBSD: gzip.c,v 1.112 2017/08/23 13:04:17 christos Exp $ */ /*- - * Copyright (c) 1997, 1998, 2003, 2004, 2006 Matthew R. Green + * Copyright (c) 1997, 1998, 2003, 2004, 2006, 2008, 2009, 2010, 2011, 2015, 2017 + * Matthew R. Green * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -29,8 +30,8 @@ #include #ifndef lint -__COPYRIGHT("@(#) Copyright (c) 1997, 1998, 2003, 2004, 2006\ - Matthew R. Green. All rights reserved."); +__COPYRIGHT("@(#) Copyright (c) 1997, 1998, 2003, 2004, 2006, 2008,\ + 2009, 2010, 2011, 2015, 2017 Matthew R. Green. All rights reserved."); __FBSDID("$FreeBSD$"); #endif /* not lint */ @@ -158,7 +159,7 @@ static suffixes_t suffixes[] = { #define NUM_SUFFIXES (nitems(suffixes)) #define SUFFIX_MAXLEN 30 -static const char gzip_version[] = "FreeBSD gzip 20150413"; +static const char gzip_version[] = "FreeBSD gzip 20171121"; #ifndef SMALL static const char gzip_copyright[] = \ @@ -192,8 +193,10 @@ static int dflag; /* decompress mode */ static int lflag; /* list mode */ static int numflag = 6; /* gzip -1..-9 value */ -#ifndef SMALL +static const char *remove_file = NULL; /* file to be removed upon SIGINT */ + static int fflag; /* force mode */ +#ifndef SMALL static int kflag; /* don't delete input files */ static int nflag; /* don't save name/timestamp */ static int Nflag; /* don't restore name/timestamp */ @@ -201,7 +204,7 @@ static int qflag; /* quiet mode */ static int rflag; /* recursive mode */ static int tflag; /* test */ static int vflag; /* verbose mode */ -static const char *remove_file = NULL; /* file to be removed upon SIGINT */ +static sig_atomic_t print_info = 0; #else #define qflag 0 #define tflag 0 @@ -209,7 +212,7 @@ static const char *remove_file = NULL; /* file to be r static int exit_value = 0; /* exit value */ -static char *infile; /* name of file coming in */ +static const char *infile; /* name of file coming in */ static void maybe_err(const char *fmt, ...) __printflike(1, 2) __dead2; #if !defined(NO_BZIP2_SUPPORT) || !defined(NO_PACK_SUPPORT) || \ @@ -236,14 +239,26 @@ static void usage(void) __dead2; static void display_version(void) __dead2; #ifndef SMALL static void display_license(void); -static void sigint_handler(int); #endif static const suffixes_t *check_suffix(char *, int); static ssize_t read_retry(int, void *, size_t); +static ssize_t write_retry(int, const void *, size_t); #ifdef SMALL +#define infile_set(f,t) infile_set(f) +#endif +static void infile_set(const char *newinfile, off_t total); + +#ifdef SMALL #define unlink_input(f, sb) unlink(f) +#define check_siginfo() /* nothing */ +#define setup_signals() /* nothing */ +#define infile_newdata(t) /* nothing */ #else +static off_t infile_total; /* total expected to read/write */ +static off_t infile_current; /* current read/write */ + +static void check_siginfo(void); static off_t cat_fd(unsigned char *, size_t, off_t *, int fd); static void prepend_gzip(char *, int *, char ***); static void handle_dir(char *); @@ -251,6 +266,9 @@ static void print_verbage(const char *, const char *, static void print_test(const char *, int); static void copymodes(int fd, const struct stat *, const char *file); static int check_outfile(const char *outfile); +static void setup_signals(void); +static void infile_newdata(size_t newdata); +static void infile_clear(void); #endif #ifndef NO_BZIP2_SUPPORT @@ -308,10 +326,11 @@ main(int argc, char **argv) #endif int ch; + setup_signals(); + #ifndef SMALL if ((gzip = getenv("GZIP")) != NULL) prepend_gzip(gzip, &argc, &argv); - signal(SIGINT, sigint_handler); #endif /* @@ -587,7 +606,7 @@ gz_compress(int in, int out, off_t *gsizep, const char origname = ""; } - i = snprintf(outbufp, BUFLEN, "%c%c%c%c%c%c%c%c%c%c%s", + i = snprintf(outbufp, BUFLEN, "%c%c%c%c%c%c%c%c%c%c%s", GZIP_MAGIC0, GZIP_MAGIC1, Z_DEFLATED, *origname ? ORIG_NAME : 0, mtime & 0xff, @@ -596,7 +615,7 @@ gz_compress(int in, int out, off_t *gsizep, const char (mtime >> 24) & 0xff, numflag == 1 ? 4 : numflag == 9 ? 2 : 0, OS_CODE, origname); - if (i >= BUFLEN) + if (i >= BUFLEN) /* this need PATH_MAX > BUFLEN ... */ maybe_err("snprintf"); if (*origname) @@ -617,7 +636,7 @@ gz_compress(int in, int out, off_t *gsizep, const char crc = crc32(0L, Z_NULL, 0); for (;;) { if (z.avail_out == 0) { - if (write(out, outbufp, BUFLEN) != BUFLEN) { + if (write_retry(out, outbufp, BUFLEN) != BUFLEN) { maybe_warn("write"); out_tot = -1; goto out; @@ -637,6 +656,7 @@ gz_compress(int in, int out, off_t *gsizep, const char } if (in_size == 0) break; + infile_newdata(in_size); crc = crc32(crc, (const Bytef *)inbufp, (unsigned)in_size); in_tot += in_size; @@ -666,7 +686,7 @@ gz_compress(int in, int out, off_t *gsizep, const char len = (char *)z.next_out - outbufp; - w = write(out, outbufp, len); + w = write_retry(out, outbufp, len); if (w == -1 || (size_t)w != len) { maybe_warn("write"); out_tot = -1; @@ -686,7 +706,7 @@ gz_compress(int in, int out, off_t *gsizep, const char goto out; } - i = snprintf(outbufp, BUFLEN, "%c%c%c%c%c%c%c%c", + i = snprintf(outbufp, BUFLEN, "%c%c%c%c%c%c%c%c", (int)crc & 0xff, (int)(crc >> 8) & 0xff, (int)(crc >> 16) & 0xff, @@ -697,7 +717,7 @@ gz_compress(int in, int out, off_t *gsizep, const char (int)(in_tot >> 24) & 0xff); if (i != 8) maybe_err("snprintf"); - if (write(out, outbufp, i) != i) { + if (write_retry(out, outbufp, i) != i) { maybe_warn("write"); in_tot = -1; } else @@ -774,6 +794,7 @@ gz_uncompress(int in, int out, char *pre, size_t prele out_tot = 0; for (;;) { + check_siginfo(); if ((z.avail_in == 0 || needmore) && done_reading == 0) { ssize_t in_size; @@ -790,6 +811,7 @@ gz_uncompress(int in, int out, char *pre, size_t prele } else if (in_size == 0) { done_reading = 1; } + infile_newdata(in_size); z.avail_in += in_size; needmore = 0; @@ -962,7 +984,7 @@ gz_uncompress(int in, int out, char *pre, size_t prele /* don't write anything with -t */ tflag == 0 && #endif - write(out, outbufp, wr) != wr) { + write_retry(out, outbufp, wr) != wr) { maybe_warn("error writing to output"); goto stop_and_fail; } @@ -1083,7 +1105,7 @@ copymodes(int fd, const struct stat *sbp, const char * (void)fchmod(fd, DEFFILEMODE & ~mask); (void)umask(mask); - return; + return; } sb = *sbp; @@ -1190,15 +1212,58 @@ unlink_input(const char *file, const struct stat *sb) } static void -sigint_handler(int signo __unused) +got_sigint(int signo __unused) { if (remove_file != NULL) unlink(remove_file); _exit(2); } + +static void +got_siginfo(int signo __unused) +{ + + print_info = 1; +} + +static void +setup_signals(void) +{ + + signal(SIGINFO, got_siginfo); + signal(SIGINT, got_sigint); +} + +static void +infile_newdata(size_t newdata) +{ + + infile_current += newdata; +} #endif +static void +infile_set(const char *newinfile, off_t total) +{ + + if (newinfile) + infile = newinfile; +#ifndef SMALL + infile_total = total; +#endif +} + +static void +infile_clear(void) +{ + + infile = NULL; +#ifndef SMALL + infile_total = infile_current = 0; +#endif +} + static const suffixes_t * check_suffix(char *file, int xlate) { @@ -1229,7 +1294,7 @@ file_compress(char *file, char *outfile, size_t outsiz { int in; int out; - off_t size, insize; + off_t size, in_size; #ifndef SMALL struct stat isb, osb; const suffixes_t *suff; @@ -1249,14 +1314,24 @@ file_compress(char *file, char *outfile, size_t outsiz } #endif +#ifndef SMALL + if (fstat(in, &isb) != 0) { + close(in); + maybe_warn("can't stat %s", file); + return -1; + } + infile_set(file, isb.st_size); +#endif + if (cflag == 0) { #ifndef SMALL if (isb.st_nlink > 1 && fflag == 0) { - maybe_warnx("%s has %ju other link%s -- skipping", - file, (uintmax_t)isb.st_nlink - 1, - (isb.st_nlink - 1) == 1 ? "" : "s"); + maybe_warnx("%s has %ju other link%s -- " + "skipping", file, + (uintmax_t)isb.st_nlink - 1, + isb.st_nlink == 1 ? "" : "s"); close(in); - return (-1); + return -1; } if (fflag == 0 && (suff = check_suffix(file, 0)) && @@ -1295,19 +1370,19 @@ file_compress(char *file, char *outfile, size_t outsiz } else out = STDOUT_FILENO; - insize = gz_compress(in, out, &size, basename(file), (uint32_t)isb.st_mtime); + in_size = gz_compress(in, out, &size, basename(file), (uint32_t)isb.st_mtime); (void)close(in); /* - * If there was an error, insize will be -1. + * If there was an error, in_size will be -1. * If we compressed to stdout, just return the size. * Otherwise stat the file and check it is the correct size. * We only blow away the file if we can stat the output and it * has the expected size. */ if (cflag != 0) - return (insize == -1 ? -1 : size); + return in_size == -1 ? -1 : size; #ifndef SMALL if (fstat(out, &osb) != 0) { @@ -1352,6 +1427,7 @@ file_uncompress(char *file, char *outfile, size_t outs unsigned char header1[4]; enum filetype method; int fd, ofd, zfd = -1; + size_t in_size; #ifndef SMALL ssize_t rv; time_t timestamp = 0; @@ -1365,6 +1441,16 @@ file_uncompress(char *file, char *outfile, size_t outs maybe_warn("can't open %s", file); goto lose; } + if (fstat(fd, &isb) != 0) { + close(fd); + maybe_warn("can't stat %s", file); + goto lose; + } + if (S_ISREG(isb.st_mode)) + in_size = isb.st_size; + else + in_size = 0; + infile_set(file, in_size); strlcpy(outfile, file, outsize); if (check_suffix(outfile, 1) == NULL && !(cflag || lflag)) { @@ -1385,6 +1471,7 @@ file_uncompress(char *file, char *outfile, size_t outs goto unexpected_EOF; goto lose; } + infile_newdata(rbytes); method = file_gettype(header1); #ifndef SMALL @@ -1407,6 +1494,7 @@ file_uncompress(char *file, char *outfile, size_t outs maybe_warn("can't read %s", file); goto lose; } + infile_newdata(rv); timestamp = ts[3] << 24 | ts[2] << 16 | ts[1] << 8 | ts[0]; if (header1[3] & ORIG_NAME) { @@ -1435,7 +1523,7 @@ file_uncompress(char *file, char *outfile, size_t outs else dp++; snprintf(outfile, outsize, "%.*s%.*s", - (int) (dp - file), + (int) (dp - file), file, (int) rbytes, nf); } } @@ -1444,8 +1532,6 @@ file_uncompress(char *file, char *outfile, size_t outs lseek(fd, 0, SEEK_SET); if (cflag == 0 || lflag) { - if (fstat(fd, &isb) != 0) - goto lose; #ifndef SMALL if (isb.st_nlink > 1 && lflag == 0 && fflag == 0) { maybe_warnx("%s has %ju other links -- skipping", @@ -1459,7 +1545,11 @@ file_uncompress(char *file, char *outfile, size_t outs #endif } - if (cflag == 0 && lflag == 0) { + if (cflag) + zfd = STDOUT_FILENO; + else if (lflag) + zfd = -1; + else { zfd = open(outfile, O_WRONLY|O_CREAT|O_EXCL, 0600); if (zfd == STDOUT_FILENO) { /* We won't close STDOUT_FILENO later... */ @@ -1470,11 +1560,8 @@ file_uncompress(char *file, char *outfile, size_t outs maybe_warn("can't open %s", outfile); goto lose; } -#ifndef SMALL remove_file = outfile; -#endif - } else - zfd = STDOUT_FILENO; + } switch (method) { #ifndef NO_BZIP2_SUPPORT @@ -1560,7 +1647,7 @@ file_uncompress(char *file, char *outfile, size_t outs #endif default: if (lflag) { - print_list(fd, isb.st_size, outfile, isb.st_mtime); + print_list(fd, in_size, outfile, isb.st_mtime); close(fd); return -1; /* XXX */ } @@ -1635,6 +1722,25 @@ file_uncompress(char *file, char *outfile, size_t outs } #ifndef SMALL +static void +check_siginfo(void) +{ + if (print_info == 0) + return; + if (infile) { + if (infile_total) { + int pcent = (int)((100.0 * infile_current) / infile_total); + + fprintf(stderr, "%s: done %llu/%llu bytes %d%%\n", + infile, (unsigned long long)infile_current, + (unsigned long long)infile_total, pcent); + } else + fprintf(stderr, "%s: done %llu bytes\n", + infile, (unsigned long long)infile_current); + } + print_info = 0; +} + static off_t cat_fd(unsigned char * prepend, size_t count, off_t *gsizep, int fd) { @@ -1643,7 +1749,7 @@ cat_fd(unsigned char * prepend, size_t count, off_t *g ssize_t w; in_tot = count; - w = write(STDOUT_FILENO, prepend, count); + w = write_retry(STDOUT_FILENO, prepend, count); if (w == -1 || (size_t)w != count) { maybe_warn("write to stdout"); return -1; @@ -1658,8 +1764,9 @@ cat_fd(unsigned char * prepend, size_t count, off_t *g maybe_warn("read from fd %d", fd); break; } + infile_newdata(rv); - if (write(STDOUT_FILENO, buf, rv) != rv) { + if (write_retry(STDOUT_FILENO, buf, rv) != rv) { maybe_warn("write to stdout"); break; } @@ -1675,7 +1782,9 @@ cat_fd(unsigned char * prepend, size_t count, off_t *g static void handle_stdin(void) { + struct stat isb; unsigned char header1[4]; + size_t in_size; off_t usize, gsize; enum filetype method; ssize_t bytes_read; @@ -1686,29 +1795,32 @@ handle_stdin(void) #ifndef SMALL if (fflag == 0 && lflag == 0 && isatty(STDIN_FILENO)) { maybe_warnx("standard input is a terminal -- ignoring"); - return; + goto out; } #endif - if (lflag) { - struct stat isb; + if (fstat(STDIN_FILENO, &isb) < 0) { + maybe_warn("fstat"); + goto out; + } + if (S_ISREG(isb.st_mode)) + in_size = isb.st_size; + else + in_size = 0; + infile_set("(stdin)", in_size); - /* XXX could read the whole file, etc. */ - if (fstat(STDIN_FILENO, &isb) < 0) { - maybe_warn("fstat"); - return; - } - print_list(STDIN_FILENO, isb.st_size, "stdout", isb.st_mtime); - return; + if (lflag) { + print_list(STDIN_FILENO, in_size, infile, isb.st_mtime); + goto out; } bytes_read = read_retry(STDIN_FILENO, header1, sizeof header1); if (bytes_read == -1) { maybe_warn("can't read stdin"); - return; + goto out; } else if (bytes_read != sizeof(header1)) { maybe_warnx("(stdin): unexpected end of file"); - return; + goto out; } method = file_gettype(header1); @@ -1717,13 +1829,13 @@ handle_stdin(void) #ifndef SMALL if (fflag == 0) { maybe_warnx("unknown compression format"); - return; + goto out; } usize = cat_fd(header1, sizeof header1, &gsize, STDIN_FILENO); break; #endif case FT_GZIP: - usize = gz_uncompress(STDIN_FILENO, STDOUT_FILENO, + usize = gz_uncompress(STDIN_FILENO, STDOUT_FILENO, (char *)header1, sizeof header1, &gsize, "(stdin)"); break; #ifndef NO_BZIP2_SUPPORT @@ -1736,7 +1848,7 @@ handle_stdin(void) case FT_Z: if ((in = zdopen(STDIN_FILENO)) == NULL) { maybe_warnx("zopen of stdin"); - return; + goto out; } usize = zuncompress(in, stdout, (char *)header1, @@ -1763,53 +1875,58 @@ handle_stdin(void) print_verbage(NULL, NULL, usize, gsize); if (vflag && tflag) print_test("(stdin)", usize != -1); -#endif +#else + (void)&usize; +#endif +out: + infile_clear(); } static void handle_stdout(void) { - off_t gsize, usize; + off_t gsize; +#ifndef SMALL + off_t usize; struct stat sb; time_t systime; uint32_t mtime; int ret; -#ifndef SMALL + infile_set("(stdout)", 0); + if (fflag == 0 && isatty(STDOUT_FILENO)) { maybe_warnx("standard output is a terminal -- ignoring"); return; } -#endif + /* If stdin is a file use its mtime, otherwise use current time */ ret = fstat(STDIN_FILENO, &sb); - -#ifndef SMALL if (ret < 0) { maybe_warn("Can't stat stdin"); return; } -#endif - if (S_ISREG(sb.st_mode)) + if (S_ISREG(sb.st_mode)) { + infile_set("(stdout)", sb.st_size); mtime = (uint32_t)sb.st_mtime; - else { + } else { systime = time(NULL); -#ifndef SMALL if (systime == -1) { maybe_warn("time"); return; - } -#endif + } mtime = (uint32_t)systime; } - usize = gz_compress(STDIN_FILENO, STDOUT_FILENO, &gsize, "", mtime); + usize = +#endif + gz_compress(STDIN_FILENO, STDOUT_FILENO, &gsize, "", mtime); #ifndef SMALL if (vflag && !tflag && usize != -1 && gsize != -1) print_verbage(NULL, NULL, usize, gsize); -#endif +#endif } /* do what is asked for, for the path name */ @@ -1876,7 +1993,7 @@ handle_file(char *file, struct stat *sbp) off_t usize, gsize; char outfile[PATH_MAX]; - infile = file; + infile_set(file, sbp->st_size); if (dflag) { usize = file_uncompress(file, outfile, sizeof(outfile)); #ifndef SMALL @@ -1892,8 +2009,8 @@ handle_file(char *file, struct stat *sbp) return; usize = sbp->st_size; } + infile_clear(); - #ifndef SMALL if (vflag && !tflag) print_verbage(file, (cflag) ? NULL : outfile, usize, gsize); @@ -1946,7 +2063,9 @@ print_ratio(off_t in, off_t out, FILE *where) int len; diff = in - out/2; - if (diff <= 0) + if (in == 0 && out == 0) + percent10 = 0; + else if (diff < 0) /* * Output is more than double size of input! print -99.9% * Quite possibly we've failed to get the original size. @@ -2165,6 +2284,28 @@ read_retry(int fd, void *buf, size_t sz) return ret; } else if (ret == 0) { break; /* EOF */ + } + cp += ret; + left -= ret; + } + + return sz - left; +} + +static ssize_t +write_retry(int fd, const void *buf, size_t sz) +{ + const char *cp = buf; + size_t left = MIN(sz, (size_t) SSIZE_MAX); + + while (left > 0) { + ssize_t ret; + + ret = write(fd, cp, left); + if (ret == -1) { + return ret; + } else if (ret == 0) { + abort(); /* Can't happen */ } cp += ret; left -= ret; Modified: head/usr.bin/gzip/unbzip2.c ============================================================================== --- head/usr.bin/gzip/unbzip2.c Tue Nov 21 07:35:29 2017 (r326051) +++ head/usr.bin/gzip/unbzip2.c Tue Nov 21 08:14:30 2017 (r326052) @@ -1,4 +1,4 @@ -/* $NetBSD: unbzip2.c,v 1.13 2009/12/05 03:23:37 mrg Exp $ */ +/* $NetBSD: unbzip2.c,v 1.14 2017/08/04 07:27:08 mrg Exp $ */ /*- * Copyright (c) 2006 The NetBSD Foundation, Inc. @@ -65,6 +65,7 @@ unbzip2(int in, int out, char *pre, size_t prelen, off *bytes_in = prelen; while (ret == BZ_OK) { + check_siginfo(); if (bzs.avail_in == 0 && !end_of_file) { ssize_t n; @@ -73,6 +74,7 @@ unbzip2(int in, int out, char *pre, size_t prelen, off maybe_err("read"); if (n == 0) end_of_file = 1; + infile_newdata(n); bzs.next_in = inbuf; bzs.avail_in = n; if (bytes_in) Modified: head/usr.bin/gzip/unpack.c ============================================================================== --- head/usr.bin/gzip/unpack.c Tue Nov 21 07:35:29 2017 (r326051) +++ head/usr.bin/gzip/unpack.c Tue Nov 21 08:14:30 2017 (r326052) @@ -1,3 +1,6 @@ +/* $FreeBSD$ */ +/* $NetBSD: unpack.c,v 1.3 2017/08/04 07:27:08 mrg Exp $ */ + /*- * Copyright (c) 2009 Xin LI * All rights reserved. @@ -152,6 +155,9 @@ unpack_parse_header(int in, int out, char *pre, size_t ssize_t bytesread; /* Bytes read from the file */ int i, j, thisbyte; + if (prelen > sizeof hdr) + maybe_err("prelen too long"); + /* Prepend the header buffer if we already read some data */ if (prelen != 0) memcpy(hdr, pre, prelen); @@ -160,6 +166,7 @@ unpack_parse_header(int in, int out, char *pre, size_t bytesread = read(in, hdr + prelen, PACK_HEADER_LENGTH - prelen); if (bytesread < 0) maybe_err("Error reading pack header"); + infile_newdata(bytesread); accepted_bytes(bytes_in, PACK_HEADER_LENGTH); @@ -206,6 +213,7 @@ unpack_parse_header(int in, int out, char *pre, size_t accepted_bytes(bytes_in, unpackd->treelevels); if (unpackd->symbol_size > 256) maybe_errx("Bad symbol table"); + infile_newdata(unpackd->treelevels); /* Allocate for the symbol table, point symbol_eob at the beginning */ unpackd->symbol_eob = unpackd->symbol = calloc(1, unpackd->symbol_size); @@ -229,6 +237,7 @@ unpack_parse_header(int in, int out, char *pre, size_t maybe_errx("Symbol table truncated"); *unpackd->symbol_eob++ = (char)thisbyte; } + infile_newdata(unpackd->symbolsin[i]); accepted_bytes(bytes_in, unpackd->symbolsin[i]); } @@ -266,6 +275,8 @@ unpack_decode(const unpack_descriptor_t *unpackd, off_ while ((thisbyte = fgetc(unpackd->fpIn)) != EOF) { accepted_bytes(bytes_in, 1); + infile_newdata(1); + check_siginfo(); /* * Split one bit from thisbyte, from highest to lowest, Modified: head/usr.bin/gzip/unxz.c ============================================================================== --- head/usr.bin/gzip/unxz.c Tue Nov 21 07:35:29 2017 (r326051) +++ head/usr.bin/gzip/unxz.c Tue Nov 21 08:14:30 2017 (r326052) @@ -1,4 +1,4 @@ -/* $NetBSD: unxz.c,v 1.6 2016/01/29 15:19:01 christos Exp $ */ +/* $NetBSD: unxz.c,v 1.7 2017/08/04 07:27:08 mrg Exp $ */ /*- * Copyright (c) 2011 The NetBSD Foundation, Inc. @@ -56,6 +56,7 @@ unxz(int i, int o, char *pre, size_t prelen, off_t *by strm.avail_in = read(i, ibuf + prelen, sizeof(ibuf) - prelen); if (strm.avail_in == (size_t)-1) maybe_err("read failed"); + infile_newdata(strm.avail_in); strm.avail_in += prelen; *bytes_in = strm.avail_in; @@ -72,6 +73,7 @@ unxz(int i, int o, char *pre, size_t prelen, off_t *by strm.avail_out = sizeof(obuf); for (;;) { + check_siginfo(); if (strm.avail_in == 0) { strm.next_in = ibuf; strm.avail_in = read(i, ibuf, sizeof(ibuf)); @@ -83,6 +85,7 @@ unxz(int i, int o, char *pre, size_t prelen, off_t *by action = LZMA_FINISH; break; default: + infile_newdata(strm.avail_in); *bytes_in += strm.avail_in; break; }