1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
|
From d606837b56d46eb7f815b5d85f07fcc3f1555d00 Mon Sep 17 00:00:00 2001
From: Yousong Zhou <yszhou4tech@gmail.com>
Date: Sun, 1 Feb 2015 00:10:07 +0800
Subject: [PATCH 1/5] Fix zlib/lzma decompression.
Let {zlib,lzma}_decompress_file() return NULL if anything wrong happened
to allow the other method to have a chance to run.
Signed-off-by: Yousong Zhou <yszhou4tech@gmail.com>
Signed-off-by: Simon Horman <horms@verge.net.au>
---
kexec/lzma.c | 33 ++++++++++++++++++++++-----------
kexec/zlib.c | 57 +++++++++++++++++++++++++++++++++++----------------------
2 files changed, 57 insertions(+), 33 deletions(-)
diff --git a/kexec/lzma.c b/kexec/lzma.c
index 939aeb3..5bfccb7 100644
--- a/kexec/lzma.c
+++ b/kexec/lzma.c
@@ -162,13 +162,16 @@ char *lzma_decompress_file(const char *filename, off_t *r_size)
off_t size, allocated;
ssize_t result;
- if (!filename) {
- *r_size = 0;
- return 0;
- }
+ dbgprintf("Try LZMA decompression.\n");
+
+ *r_size = 0;
+ if (!filename)
+ return NULL;
+
fp = lzopen(filename, "rb");
if (fp == 0) {
- die("Cannot open `%s'\n", filename);
+ dbgprintf("Cannot open `%s'\n", filename);
+ return NULL;
}
size = 0;
allocated = 65536;
@@ -183,17 +186,25 @@ char *lzma_decompress_file(const char *filename, off_t *r_size)
if ((errno == EINTR) || (errno == EAGAIN))
continue;
- die ("read on %s of %ld bytes failed\n",
- filename, (allocated - size) + 0UL);
+ dbgprintf("%s: read on %s of %ld bytes failed\n",
+ __func__, filename, (allocated - size) + 0UL);
+ break;
}
size += result;
- } while(result > 0);
- result = lzclose(fp);
- if (result != LZMA_OK) {
- die ("Close of %s failed\n", filename);
+ } while (result > 0);
+
+ if (lzclose(fp) != LZMA_OK) {
+ dbgprintf("%s: Close of %s failed\n", __func__, filename);
+ goto fail;
}
+ if (result < 0)
+ goto fail;
+
*r_size = size;
return buf;
+fail:
+ free(buf);
+ return NULL;
}
#else
char *lzma_decompress_file(const char *UNUSED(filename), off_t *UNUSED(r_size))
diff --git a/kexec/zlib.c b/kexec/zlib.c
index d44df12..7170ac3 100644
--- a/kexec/zlib.c
+++ b/kexec/zlib.c
@@ -15,29 +15,39 @@
#include <ctype.h>
#include <zlib.h>
+static void _gzerror(gzFile fp, int *errnum, const char **errmsg)
+{
+ *errmsg = gzerror(fp, errnum);
+ if (*errnum == Z_ERRNO) {
+ *errmsg = strerror(*errnum);
+ }
+}
+
char *zlib_decompress_file(const char *filename, off_t *r_size)
{
gzFile fp;
int errnum;
const char *msg;
char *buf;
- off_t size, allocated;
+ off_t size = 0, allocated;
ssize_t result;
+ dbgprintf("Try gzip decompression.\n");
+
+ *r_size = 0;
if (!filename) {
- *r_size = 0;
- return 0;
+ return NULL;
}
fp = gzopen(filename, "rb");
if (fp == 0) {
- msg = gzerror(fp, &errnum);
- if (errnum == Z_ERRNO) {
- msg = strerror(errno);
- }
- fprintf(stderr, "Cannot open `%s': %s\n", filename, msg);
+ _gzerror(fp, &errnum, &msg);
+ dbgprintf("Cannot open `%s': %s\n", filename, msg);
+ return NULL;
+ }
+ if (gzdirect(fp)) {
+ /* It's not in gzip format */
return NULL;
}
- size = 0;
allocated = 65536;
buf = xmalloc(allocated);
do {
@@ -49,25 +59,28 @@ char *zlib_decompress_file(const char *filename, off_t *r_size)
if (result < 0) {
if ((errno == EINTR) || (errno == EAGAIN))
continue;
-
- msg = gzerror(fp, &errnum);
- if (errnum == Z_ERRNO) {
- msg = strerror(errno);
- }
- die ("read on %s of %ld bytes failed: %s\n",
- filename, (allocated - size) + 0UL, msg);
+ _gzerror(fp, &errnum, &msg);
+ dbgprintf("Read on %s of %ld bytes failed: %s\n",
+ filename, (allocated - size) + 0UL, msg);
+ size = 0;
+ goto fail;
}
size += result;
} while(result > 0);
+
+fail:
result = gzclose(fp);
if (result != Z_OK) {
- msg = gzerror(fp, &errnum);
- if (errnum == Z_ERRNO) {
- msg = strerror(errno);
- }
- die ("Close of %s failed: %s\n", filename, msg);
+ _gzerror(fp, &errnum, &msg);
+ dbgprintf(" Close of %s failed: %s\n", filename, msg);
+ }
+
+ if (size > 0) {
+ *r_size = size;
+ } else {
+ free(buf);
+ buf = NULL;
}
- *r_size = size;
return buf;
}
#else
--
1.7.10.4
|