root/tools/perf/util/zlib.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. gzip_decompress_to_file
  2. gzip_is_compressed

   1 // SPDX-License-Identifier: GPL-2.0
   2 #include <fcntl.h>
   3 #include <stdio.h>
   4 #include <string.h>
   5 #include <unistd.h>
   6 #include <sys/stat.h>
   7 #include <sys/mman.h>
   8 #include <zlib.h>
   9 #include <linux/compiler.h>
  10 #include <internal/lib.h>
  11 
  12 #include "util/compress.h"
  13 
  14 #define CHUNK_SIZE  16384
  15 
  16 int gzip_decompress_to_file(const char *input, int output_fd)
  17 {
  18         int ret = Z_STREAM_ERROR;
  19         int input_fd;
  20         void *ptr;
  21         int len;
  22         struct stat stbuf;
  23         unsigned char buf[CHUNK_SIZE];
  24         z_stream zs = {
  25                 .zalloc         = Z_NULL,
  26                 .zfree          = Z_NULL,
  27                 .opaque         = Z_NULL,
  28                 .avail_in       = 0,
  29                 .next_in        = Z_NULL,
  30         };
  31 
  32         input_fd = open(input, O_RDONLY);
  33         if (input_fd < 0)
  34                 return -1;
  35 
  36         if (fstat(input_fd, &stbuf) < 0)
  37                 goto out_close;
  38 
  39         ptr = mmap(NULL, stbuf.st_size, PROT_READ, MAP_PRIVATE, input_fd, 0);
  40         if (ptr == MAP_FAILED)
  41                 goto out_close;
  42 
  43         if (inflateInit2(&zs, 16 + MAX_WBITS) != Z_OK)
  44                 goto out_unmap;
  45 
  46         zs.next_in = ptr;
  47         zs.avail_in = stbuf.st_size;
  48 
  49         do {
  50                 zs.next_out = buf;
  51                 zs.avail_out = CHUNK_SIZE;
  52 
  53                 ret = inflate(&zs, Z_NO_FLUSH);
  54                 switch (ret) {
  55                 case Z_NEED_DICT:
  56                         ret = Z_DATA_ERROR;
  57                         /* fall through */
  58                 case Z_DATA_ERROR:
  59                 case Z_MEM_ERROR:
  60                         goto out;
  61                 default:
  62                         break;
  63                 }
  64 
  65                 len = CHUNK_SIZE - zs.avail_out;
  66                 if (writen(output_fd, buf, len) != len) {
  67                         ret = Z_DATA_ERROR;
  68                         goto out;
  69                 }
  70 
  71         } while (ret != Z_STREAM_END);
  72 
  73 out:
  74         inflateEnd(&zs);
  75 out_unmap:
  76         munmap(ptr, stbuf.st_size);
  77 out_close:
  78         close(input_fd);
  79 
  80         return ret == Z_STREAM_END ? 0 : -1;
  81 }
  82 
  83 bool gzip_is_compressed(const char *input)
  84 {
  85         int fd = open(input, O_RDONLY);
  86         const uint8_t magic[2] = { 0x1f, 0x8b };
  87         char buf[2] = { 0 };
  88         ssize_t rc;
  89 
  90         if (fd < 0)
  91                 return -1;
  92 
  93         rc = read(fd, buf, sizeof(buf));
  94         close(fd);
  95         return rc == sizeof(buf) ?
  96                memcmp(buf, magic, sizeof(buf)) == 0 : false;
  97 }

/* [<][>][^][v][top][bottom][index][help] */