diff options
author | Jo-Philipp Wich <jo@mein.io> | 2016-09-14 20:50:35 +0200 |
---|---|---|
committer | Felix Fietkau <nbd@nbd.name> | 2016-12-27 09:50:00 +0100 |
commit | e1d1c3189093ebe384953519083f815a420c4a4e (patch) | |
tree | 369a94779f5520fc26bb13e2f274d75c4b454c83 /package/system/opkg/patches/071-use_gzipped_pkg_list.patch | |
parent | dc5f496a0df8d125ce172fc40100098b18da2300 (diff) | |
download | mtk-20170518-e1d1c3189093ebe384953519083f815a420c4a4e.zip mtk-20170518-e1d1c3189093ebe384953519083f815a420c4a4e.tar.gz mtk-20170518-e1d1c3189093ebe384953519083f815a420c4a4e.tar.bz2 |
opkg: vfork external gzip command to uncompress data
Opkg's builtin decompression code is unsuitable to process nested archives as
it uses a single shared state and relies on undefined seek behaviour for pipes.
Rework the extraction logic to use the external gzip command as I/O filter for
decompressing data and remove the builtin inflate code entirely.
This shrinks the final opkg binary by about 4KB and results in less runtime
memory consumption due to efficient use of vfork() and less copy-on-write
operations in the forked child.
Rework by Felix: create a thread that relays data to the gzip process
instead of using a fragile poll loop
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Diffstat (limited to 'package/system/opkg/patches/071-use_gzipped_pkg_list.patch')
-rw-r--r-- | package/system/opkg/patches/071-use_gzipped_pkg_list.patch | 124 |
1 files changed, 124 insertions, 0 deletions
diff --git a/package/system/opkg/patches/071-use_gzipped_pkg_list.patch b/package/system/opkg/patches/071-use_gzipped_pkg_list.patch new file mode 100644 index 0000000..e102868 --- /dev/null +++ b/package/system/opkg/patches/071-use_gzipped_pkg_list.patch @@ -0,0 +1,124 @@ +--- a/libopkg/opkg.c ++++ b/libopkg/opkg.c +@@ -592,49 +592,8 @@ opkg_update_package_lists(opkg_progress_ + src->gzip ? "Packages.gz" : "Packages"); + + sprintf_alloc(&list_file_name, "%s/%s", lists_dir, src->name); +- if (src->gzip) { +- FILE *in, *out; +- struct _curl_cb_data cb_data; +- char *tmp_file_name = NULL; +- +- sprintf_alloc(&tmp_file_name, "%s/%s.gz", tmp, +- src->name); +- +- opkg_msg(INFO, "Downloading %s to %s...\n", url, +- tmp_file_name); +- +- cb_data.cb = progress_callback; +- cb_data.progress_data = &pdata; +- cb_data.user_data = user_data; +- cb_data.start_range = +- 100 * sources_done / sources_list_count; +- cb_data.finish_range = +- 100 * (sources_done + 1) / sources_list_count; +- +- err = opkg_download(url, tmp_file_name, +- (curl_progress_func) curl_progress_cb, +- &cb_data, 0); + +- if (err == 0) { +- opkg_msg(INFO, "Inflating %s...\n", +- tmp_file_name); +- in = fopen(tmp_file_name, "r"); +- out = fopen(list_file_name, "w"); +- if (in && out) +- unzip(in, out); +- else +- err = 1; +- if (in) +- fclose(in); +- if (out) +- fclose(out); +- unlink(tmp_file_name); +- } +- free(tmp_file_name); +- } else +- err = opkg_download(url, list_file_name, NULL, NULL, 0); +- +- if (err) { ++ if (opkg_download(url, list_file_name, NULL, NULL, 0)) { + opkg_msg(ERROR, "Couldn't retrieve %s\n", url); + result = -1; + } +--- a/libopkg/opkg_cmd.c ++++ b/libopkg/opkg_cmd.c +@@ -162,30 +162,7 @@ opkg_update_cmd(int argc, char **argv) + sprintf_alloc(&url, "%s/%s", src->value, src->gzip ? "Packages.gz" : "Packages"); + + sprintf_alloc(&list_file_name, "%s/%s", lists_dir, src->name); +- if (src->gzip) { +- char *tmp_file_name; +- FILE *in, *out; +- +- sprintf_alloc (&tmp_file_name, "%s/%s.gz", tmp, src->name); +- err = opkg_download(url, tmp_file_name, NULL, NULL, 0); +- if (err == 0) { +- opkg_msg(NOTICE, "Inflating %s.\n", url); +- in = fopen (tmp_file_name, "r"); +- out = fopen (list_file_name, "w"); +- if (in && out) +- unzip (in, out); +- else +- err = 1; +- if (in) +- fclose (in); +- if (out) +- fclose (out); +- unlink (tmp_file_name); +- } +- free(tmp_file_name); +- } else +- err = opkg_download(url, list_file_name, NULL, NULL, 0); +- if (err) { ++ if (opkg_download(url, list_file_name, NULL, NULL, 0)) { + failures++; + } else { + opkg_msg(NOTICE, "Updated list of available packages in %s.\n", +--- a/libopkg/pkg_hash.c ++++ b/libopkg/pkg_hash.c +@@ -29,6 +29,7 @@ + #include "sprintf_alloc.h" + #include "file_util.h" + #include "libbb/libbb.h" ++#include "libbb/gzip.h" + + void + pkg_hash_init(void) +@@ -106,8 +107,15 @@ pkg_hash_add_from_file(const char *file_ + char *buf; + const size_t len = 4096; + int ret = 0; ++ struct gzip_handle zh; ++ ++ if (src && src->gzip) { ++ fp = gzip_fdopen(&zh, file_name); ++ } ++ else { ++ fp = fopen(file_name, "r"); ++ } + +- fp = fopen(file_name, "r"); + if (fp == NULL) { + opkg_perror(ERROR, "Failed to open %s", file_name); + return -1; +@@ -155,6 +163,9 @@ pkg_hash_add_from_file(const char *file_ + free(buf); + fclose(fp); + ++ if (src && src->gzip) ++ gzip_close(&zh); ++ + return ret; + } + |