mirror of
https://github.com/freebsd/freebsd-src
synced 2024-10-15 21:05:08 +00:00
Support SIGINFO.
Obtained from: NetBSD MFC after: 2 weeks
This commit is contained in:
parent
c0a0f12f9b
commit
90f528e8d7
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=326052
|
@ -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
|
||||
|
|
|
@ -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 <sys/cdefs.h>
|
||||
#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 removed upon SIGINT */
|
|||
|
||||
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 *, off_t, off_t);
|
|||
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
|
||||
|
||||
/*
|
||||
|
@ -617,7 +636,7 @@ gz_compress(int in, int out, off_t *gsizep, const char *origname, uint32_t mtime
|
|||
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 *origname, uint32_t mtime
|
|||
}
|
||||
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 *origname, uint32_t mtime
|
|||
|
||||
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;
|
||||
|
@ -697,7 +717,7 @@ gz_compress(int in, int out, off_t *gsizep, const char *origname, uint32_t mtime
|
|||
(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 prelen, off_t *gsizep,
|
|||
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 prelen, off_t *gsizep,
|
|||
} 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 prelen, off_t *gsizep,
|
|||
/* 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;
|
||||
}
|
||||
|
@ -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 outsize)
|
|||
{
|
||||
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 outsize)
|
|||
}
|
||||
#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 outsize)
|
|||
} 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 outsize)
|
|||
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 outsize)
|
|||
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 outsize)
|
|||
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 outsize)
|
|||
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) {
|
||||
|
@ -1444,8 +1532,6 @@ file_uncompress(char *file, char *outfile, size_t outsize)
|
|||
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 outsize)
|
|||
#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 outsize)
|
|||
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 outsize)
|
|||
#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 outsize)
|
|||
}
|
||||
|
||||
#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 *gsizep, int fd)
|
|||
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 *gsizep, int fd)
|
|||
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 *gsizep, int fd)
|
|||
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,7 +1829,7 @@ 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;
|
||||
|
@ -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,49 +1875,54 @@ handle_stdin(void)
|
|||
print_verbage(NULL, NULL, usize, gsize);
|
||||
if (vflag && tflag)
|
||||
print_test("(stdin)", usize != -1);
|
||||
#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);
|
||||
|
@ -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,7 +2009,7 @@ handle_file(char *file, struct stat *sbp)
|
|||
return;
|
||||
usize = sbp->st_size;
|
||||
}
|
||||
|
||||
infile_clear();
|
||||
|
||||
#ifndef SMALL
|
||||
if (vflag && !tflag)
|
||||
|
@ -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.
|
||||
|
@ -2172,3 +2291,25 @@ read_retry(int fd, void *buf, size_t sz)
|
|||
|
||||
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;
|
||||
}
|
||||
|
||||
return sz - left;
|
||||
}
|
||||
|
|
|
@ -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_t *bytes_in)
|
|||
*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_t *bytes_in)
|
|||
maybe_err("read");
|
||||
if (n == 0)
|
||||
end_of_file = 1;
|
||||
infile_newdata(n);
|
||||
bzs.next_in = inbuf;
|
||||
bzs.avail_in = n;
|
||||
if (bytes_in)
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
/* $FreeBSD$ */
|
||||
/* $NetBSD: unpack.c,v 1.3 2017/08/04 07:27:08 mrg Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2009 Xin LI <delphij@FreeBSD.org>
|
||||
* All rights reserved.
|
||||
|
@ -152,6 +155,9 @@ unpack_parse_header(int in, int out, char *pre, size_t prelen, off_t *bytes_in,
|
|||
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 prelen, off_t *bytes_in,
|
|||
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 prelen, off_t *bytes_in,
|
|||
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 prelen, off_t *bytes_in,
|
|||
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_t *bytes_in)
|
|||
|
||||
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,
|
||||
|
|
|
@ -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 *bytes_in)
|
|||
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 *bytes_in)
|
|||
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 *bytes_in)
|
|||
action = LZMA_FINISH;
|
||||
break;
|
||||
default:
|
||||
infile_newdata(strm.avail_in);
|
||||
*bytes_in += strm.avail_in;
|
||||
break;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue