linux/tools/perf/util/zlib.c
<<
>>
Prefs
   1#include <stdio.h>
   2#include <unistd.h>
   3#include <sys/stat.h>
   4#include <sys/mman.h>
   5#include <zlib.h>
   6
   7#include "util/util.h"
   8#include "util/debug.h"
   9
  10
  11#define CHUNK_SIZE  16384
  12
  13int gzip_decompress_to_file(const char *input, int output_fd)
  14{
  15        int ret = Z_STREAM_ERROR;
  16        int input_fd;
  17        void *ptr;
  18        int len;
  19        struct stat stbuf;
  20        unsigned char buf[CHUNK_SIZE];
  21        z_stream zs = {
  22                .zalloc         = Z_NULL,
  23                .zfree          = Z_NULL,
  24                .opaque         = Z_NULL,
  25                .avail_in       = 0,
  26                .next_in        = Z_NULL,
  27        };
  28
  29        input_fd = open(input, O_RDONLY);
  30        if (input_fd < 0)
  31                return -1;
  32
  33        if (fstat(input_fd, &stbuf) < 0)
  34                goto out_close;
  35
  36        ptr = mmap(NULL, stbuf.st_size, PROT_READ, MAP_PRIVATE, input_fd, 0);
  37        if (ptr == MAP_FAILED)
  38                goto out_close;
  39
  40        if (inflateInit2(&zs, 16 + MAX_WBITS) != Z_OK)
  41                goto out_unmap;
  42
  43        zs.next_in = ptr;
  44        zs.avail_in = stbuf.st_size;
  45
  46        do {
  47                zs.next_out = buf;
  48                zs.avail_out = CHUNK_SIZE;
  49
  50                ret = inflate(&zs, Z_NO_FLUSH);
  51                switch (ret) {
  52                case Z_NEED_DICT:
  53                        ret = Z_DATA_ERROR;
  54                        /* fall through */
  55                case Z_DATA_ERROR:
  56                case Z_MEM_ERROR:
  57                        goto out;
  58                default:
  59                        break;
  60                }
  61
  62                len = CHUNK_SIZE - zs.avail_out;
  63                if (writen(output_fd, buf, len) != len) {
  64                        ret = Z_DATA_ERROR;
  65                        goto out;
  66                }
  67
  68        } while (ret != Z_STREAM_END);
  69
  70out:
  71        inflateEnd(&zs);
  72out_unmap:
  73        munmap(ptr, stbuf.st_size);
  74out_close:
  75        close(input_fd);
  76
  77        return ret == Z_STREAM_END ? 0 : -1;
  78}
  79