Skip to content

Commit

Permalink
libkmod: Move zlib-related functions to separate file
Browse files Browse the repository at this point in the history
Move zlib-related function to a separate file so it's easier to isolate
the dependency on each decompression library.

Signed-off-by: Lucas De Marchi <lucas.de.marchi@gmail.com>
  • Loading branch information
lucasdemarchi committed Jul 19, 2024
1 parent 1392887 commit 0fd95c7
Show file tree
Hide file tree
Showing 5 changed files with 94 additions and 72 deletions.
4 changes: 4 additions & 0 deletions Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,10 @@ if ENABLE_XZ
libkmod_libkmod_la_SOURCES += libkmod/libkmod-file-xz.c
endif

if ENABLE_ZLIB
libkmod_libkmod_la_SOURCES += libkmod/libkmod-file-zlib.c
endif

EXTRA_DIST += libkmod/libkmod.sym
EXTRA_DIST += libkmod/README \
libkmod/COPYING testsuite/COPYING tools/COPYING COPYING
Expand Down
1 change: 1 addition & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ AS_IF([test "x$with_zlib" != "xno"], [
AC_MSG_NOTICE([zlib support not requested])
])
CC_FEATURE_APPEND([with_features], [with_zlib], [ZLIB])
AM_CONDITIONAL([ENABLE_ZLIB], [test "x$with_zlib" != "xno"])

AC_ARG_WITH([openssl],
AS_HELP_STRING([--with-openssl], [handle PKCS7 signatures @<:@default=disabled@:>@]),
Expand Down
81 changes: 81 additions & 0 deletions libkmod/libkmod-file-zlib.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
// SPDX-License-Identifier: LGPL-2.1-or-later
/*
* Copyright © 2024 Intel Corporation
*/

#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <zlib.h>

#include <shared/util.h>

#include "libkmod.h"
#include "libkmod-internal.h"
#include "libkmod-internal-file.h"

#define READ_STEP (4 * 1024 * 1024)

int kmod_file_load_zlib(struct kmod_file *file)
{
int err = 0;
off_t did = 0, total = 0;
_cleanup_free_ unsigned char *p = NULL;
gzFile gzf;
int gzfd;

errno = 0;
gzfd = fcntl(file->fd, F_DUPFD_CLOEXEC, 3);
if (gzfd < 0)
return -errno;

gzf = gzdopen(gzfd, "rb"); /* takes ownership of the fd */
if (gzf == NULL) {
close(gzfd);
return -errno;
}

for (;;) {
int r;

if (did == total) {
void *tmp = realloc(p, total + READ_STEP);
if (tmp == NULL) {
err = -errno;
goto error;
}
total += READ_STEP;
p = tmp;
}

r = gzread(gzf, p + did, total - did);
if (r == 0)
break;
else if (r < 0) {
int gzerr;
const char *gz_errmsg = gzerror(gzf, &gzerr);

ERR(file->ctx, "gzip: %s\n", gz_errmsg);

/* gzip might not set errno here */
err = gzerr == Z_ERRNO ? -errno : -EINVAL;
goto error;
}
did += r;
}

file->memory = p;
file->size = did;
p = NULL;
gzclose(gzf);
return 0;

error:
gzclose(gzf); /* closes the gzfd */
return err;
}

73 changes: 1 addition & 72 deletions libkmod/libkmod-file.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,6 @@
#ifdef ENABLE_ZSTD
#include <zstd.h>
#endif
#ifdef ENABLE_ZLIB
#include <zlib.h>
#endif

#include <shared/util.h>

Expand Down Expand Up @@ -175,74 +172,6 @@ static int load_zstd(struct kmod_file *file)

static const char magic_zstd[] = {0x28, 0xB5, 0x2F, 0xFD};
static const char magic_xz[] = {0xfd, '7', 'z', 'X', 'Z', 0};

#ifdef ENABLE_ZLIB
#define READ_STEP (4 * 1024 * 1024)
static int load_zlib(struct kmod_file *file)
{
int err = 0;
off_t did = 0, total = 0;
_cleanup_free_ unsigned char *p = NULL;
gzFile gzf;
int gzfd;

errno = 0;
gzfd = fcntl(file->fd, F_DUPFD_CLOEXEC, 3);
if (gzfd < 0)
return -errno;

gzf = gzdopen(gzfd, "rb"); /* takes ownership of the fd */
if (gzf == NULL) {
close(gzfd);
return -errno;
}

for (;;) {
int r;

if (did == total) {
void *tmp = realloc(p, total + READ_STEP);
if (tmp == NULL) {
err = -errno;
goto error;
}
total += READ_STEP;
p = tmp;
}

r = gzread(gzf, p + did, total - did);
if (r == 0)
break;
else if (r < 0) {
int gzerr;
const char *gz_errmsg = gzerror(gzf, &gzerr);

ERR(file->ctx, "gzip: %s\n", gz_errmsg);

/* gzip might not set errno here */
err = gzerr == Z_ERRNO ? -errno : -EINVAL;
goto error;
}
did += r;
}

file->memory = p;
file->size = did;
p = NULL;
gzclose(gzf);
return 0;

error:
gzclose(gzf); /* closes the gzfd */
return err;
}
#else
static int load_zlib(struct kmod_file *file)
{
return -ENOSYS;
}
#endif

static const char magic_zlib[] = {0x1f, 0x8b};

static int load_reg(struct kmod_file *file)
Expand Down Expand Up @@ -271,7 +200,7 @@ static const struct comp_type {
} comp_types[] = {
{sizeof(magic_zstd), KMOD_FILE_COMPRESSION_ZSTD, magic_zstd, load_zstd},
{sizeof(magic_xz), KMOD_FILE_COMPRESSION_XZ, magic_xz, kmod_file_load_xz},
{sizeof(magic_zlib), KMOD_FILE_COMPRESSION_ZLIB, magic_zlib, load_zlib},
{sizeof(magic_zlib), KMOD_FILE_COMPRESSION_ZLIB, magic_zlib, kmod_file_load_zlib},
{0, KMOD_FILE_COMPRESSION_NONE, NULL, load_reg}
};

Expand Down
7 changes: 7 additions & 0 deletions libkmod/libkmod-internal-file.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,10 @@ int kmod_file_load_xz(struct kmod_file *file);
#else
static inline int kmod_file_load_xz(struct kmod_file *file) { return -ENOSYS; }
#endif

#if ENABLE_ZLIB
int kmod_file_load_zlib(struct kmod_file *file);
#else
static inline int kmod_file_load_zlib(struct kmod_file *file) { return -ENOSYS; }
#endif

0 comments on commit 0fd95c7

Please sign in to comment.