aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordsl <dsl@NetBSD.org>2005-02-23 22:32:31 +0000
committerdsl <dsl@NetBSD.org>2005-02-23 22:32:31 +0000
commitbb9c4e7d0b634baa7634106ed0f4bb650b979eed (patch)
treebed08218708b2a45634ec0c07dbde9a29828cbad
parentdf4d2fb54d404977d480974085b1efa070c177fc (diff)
downloadbsd-progress-bb9c4e7d0b634baa7634106ed0f4bb650b979eed.tar.gz
bsd-progress-bb9c4e7d0b634baa7634106ed0f4bb650b979eed.tar.zst
bsd-progress-bb9c4e7d0b634baa7634106ed0f4bb650b979eed.zip
Exit with any failure code from the cmd or gzip.
Decode gzip -l output with strtoimax() (not sscanf()) so we don't use an uninitialised variable if the output format isn't what we expect. This might fix some installation PRs (no error being reported)
-rw-r--r--progress.c47
1 files changed, 29 insertions, 18 deletions
diff --git a/progress.c b/progress.c
index d08c5d4..6e9d898 100644
--- a/progress.c
+++ b/progress.c
@@ -1,4 +1,4 @@
-/* $NetBSD: progress.c,v 1.9 2004/04/03 06:19:22 lukem Exp $ */
+/* $NetBSD: progress.c,v 1.10 2005/02/23 22:32:31 dsl Exp $ */
/*-
* Copyright (c) 2003 The NetBSD Foundation, Inc.
@@ -34,7 +34,7 @@
#include <sys/cdefs.h>
#ifndef lint
-__RCSID("$NetBSD: progress.c,v 1.9 2004/04/03 06:19:22 lukem Exp $");
+__RCSID("$NetBSD: progress.c,v 1.10 2005/02/23 22:32:31 dsl Exp $");
#endif /* not lint */
#include <sys/types.h>
@@ -84,8 +84,9 @@ main(int argc, char *argv[])
{
static char fb_buf[BUFSIZ];
char *infile = NULL;
- pid_t pid = 0, gzippid = 0;
- int ch, fd, outpipe[2], waitstat;
+ pid_t pid = 0, gzippid = 0, deadpid;
+ int ch, fd, outpipe[2];
+ int ws, gzipstat, cmdstat;
int lflag = 0, zflag = 0;
ssize_t nr, nw, off;
struct stat statb;
@@ -134,8 +135,7 @@ main(int argc, char *argv[])
/* gzip -l the file if we have the name and -z is given */
if (zflag && !lflag && infile != NULL) {
FILE *gzipsizepipe;
- char buf[256], *cmd;
- long size;
+ char buf[256], *cp, *cmd;
/*
* Read second word of last line of gzip -l output. Looks like:
@@ -149,8 +149,8 @@ main(int argc, char *argv[])
err(1, "reading compressed file length");
for (; fgets(buf, 256, gzipsizepipe) != NULL;)
continue;
- sscanf(buf, "%*d %ld", &size);
- filesize = size;
+ strtoimax(buf, &cp, 10);
+ filesize = strtoimax(cp, NULL, 10);
if (pclose(gzipsizepipe) < 0)
err(1, "closing compressed file length pipe");
free(cmd);
@@ -215,22 +215,33 @@ main(int argc, char *argv[])
(unsigned) nr);
close(outpipe[1]);
+ gzipstat = 0;
+ cmdstat = 0;
while (pid || gzippid) {
- int deadpid;
-
- deadpid = wait(&waitstat);
+ deadpid = wait(&ws);
+ /*
+ * We need to exit with an error if the command (or gzip)
+ * exited abnormally.
+ * Unfortunately we can't generate a true 'exited by signal'
+ * error without sending the signal to ourselves :-(
+ */
+ ws = WIFSIGNALED(ws) ? WTERMSIG(ws) : WEXITSTATUS(ws);
- if (deadpid == pid)
+ if (deadpid != -1 && errno == EINTR)
+ continue;
+ if (deadpid == pid) {
pid = 0;
- else if (deadpid == gzippid)
- gzippid = 0;
- else if (deadpid != -1)
+ cmdstat = ws;
continue;
- else if (errno == EINTR)
+ }
+ if (deadpid == gzippid) {
+ gzippid = 0;
+ gzipstat = ws;
continue;
- else break;
+ }
+ break;
}
progressmeter(1);
- return 0;
+ exit(cmdstat ? cmdstat : gzipstat);
}