linux/tools/perf/util/lzma.c
<<
>>
Prefs
   1#include <lzma.h>
   2#include <stdio.h>
   3#include <linux/compiler.h>
   4#include "util.h"
   5#include "debug.h"
   6
   7#define BUFSIZE 8192
   8
   9static const char *lzma_strerror(lzma_ret ret)
  10{
  11        switch ((int) ret) {
  12        case LZMA_MEM_ERROR:
  13                return "Memory allocation failed";
  14        case LZMA_OPTIONS_ERROR:
  15                return "Unsupported decompressor flags";
  16        case LZMA_FORMAT_ERROR:
  17                return "The input is not in the .xz format";
  18        case LZMA_DATA_ERROR:
  19                return "Compressed file is corrupt";
  20        case LZMA_BUF_ERROR:
  21                return "Compressed file is truncated or otherwise corrupt";
  22        default:
  23                return "Unknown error, possibly a bug";
  24        }
  25}
  26
  27int lzma_decompress_to_file(const char *input, int output_fd)
  28{
  29        lzma_action action = LZMA_RUN;
  30        lzma_stream strm   = LZMA_STREAM_INIT;
  31        lzma_ret ret;
  32
  33        u8 buf_in[BUFSIZE];
  34        u8 buf_out[BUFSIZE];
  35        FILE *infile;
  36
  37        infile = fopen(input, "rb");
  38        if (!infile) {
  39                pr_err("lzma: fopen failed on %s: '%s'\n",
  40                       input, strerror(errno));
  41                return -1;
  42        }
  43
  44        ret = lzma_stream_decoder(&strm, UINT64_MAX, LZMA_CONCATENATED);
  45        if (ret != LZMA_OK) {
  46                pr_err("lzma: lzma_stream_decoder failed %s (%d)\n",
  47                        lzma_strerror(ret), ret);
  48                return -1;
  49        }
  50
  51        strm.next_in   = NULL;
  52        strm.avail_in  = 0;
  53        strm.next_out  = buf_out;
  54        strm.avail_out = sizeof(buf_out);
  55
  56        while (1) {
  57                if (strm.avail_in == 0 && !feof(infile)) {
  58                        strm.next_in  = buf_in;
  59                        strm.avail_in = fread(buf_in, 1, sizeof(buf_in), infile);
  60
  61                        if (ferror(infile)) {
  62                                pr_err("lzma: read error: %s\n", strerror(errno));
  63                                return -1;
  64                        }
  65
  66                        if (feof(infile))
  67                                action = LZMA_FINISH;
  68                }
  69
  70                ret = lzma_code(&strm, action);
  71
  72                if (strm.avail_out == 0 || ret == LZMA_STREAM_END) {
  73                        ssize_t write_size = sizeof(buf_out) - strm.avail_out;
  74
  75                        if (writen(output_fd, buf_out, write_size) != write_size) {
  76                                pr_err("lzma: write error: %s\n", strerror(errno));
  77                                return -1;
  78                        }
  79
  80                        strm.next_out  = buf_out;
  81                        strm.avail_out = sizeof(buf_out);
  82                }
  83
  84                if (ret != LZMA_OK) {
  85                        if (ret == LZMA_STREAM_END)
  86                                return 0;
  87
  88                        pr_err("lzma: failed %s\n", lzma_strerror(ret));
  89                        return -1;
  90                }
  91        }
  92
  93        fclose(infile);
  94        return 0;
  95}
  96