File mit-zlibsupport-use-mmap.patch of Package module-init-tools
---
zlibsupport.c | 137 ++++++++++++++++++++++++++++++++--------------------------
1 file changed, 77 insertions(+), 60 deletions(-)
--- zlibsupport.c.orig
+++ zlibsupport.c
@@ -11,80 +11,44 @@
#include <stdlib.h>
#include <unistd.h>
#include <sys/mman.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
#include "zlibsupport.h"
#include "testing.h"
#ifdef CONFIG_USE_ZLIB
#include <zlib.h>
+#endif
-void *grab_contents(gzFile *gzfd, unsigned long *size)
-{
- unsigned int max = 16384;
- void *buffer = malloc(max);
- int ret;
-
- if (!buffer)
- return NULL;
-
- *size = 0;
- while ((ret = gzread(gzfd, buffer + *size, max - *size)) > 0) {
- *size += ret;
- if (*size == max) {
- void *p;
-
- p = realloc(buffer, max *= 2);
- if (!p)
- goto out_err;
-
- buffer = p;
- }
- }
- if (ret < 0)
- goto out_err;
-
- return buffer;
-
-out_err:
- free(buffer);
- return NULL;
-}
-
-void *grab_fd(int fd, unsigned long *size)
+#ifdef CONFIG_USE_ZLIB
+static int check_gz_magic(int fd)
{
- gzFile gzfd;
-
- gzfd = gzdopen(fd, "rb");
- if (!gzfd)
- return NULL;
+ unsigned char magic[2];
- /* gzclose(gzfd) would close fd, which would drop locks.
- Don't blame zlib: POSIX locking semantics are so horribly
- broken that they should be ripped out. */
- return grab_contents(gzfd, size);
+ if (read(fd, magic, 2) != 2)
+ return -1;
+ lseek(fd, 0, SEEK_SET);
+ if (magic[0] == 0x1f && magic[1] == 0x8b)
+ return 1;
+ return 0;
}
-/* gzopen handles uncompressed files transparently. */
-void *grab_file(const char *filename, unsigned long *size)
+static char *tmpdir(void)
{
- gzFile gzfd;
- void *buffer;
+ static char *TMPDIR;
- gzfd = gzopen(filename, "rb");
- if (!gzfd)
- return NULL;
- buffer = grab_contents(gzfd, size);
- gzclose(gzfd);
- return buffer;
-}
-
-void release_file(void *data, unsigned long size)
-{
- free(data);
+ if (TMPDIR)
+ return TMPDIR;
+ TMPDIR = getenv("TMPDIR");
+ if (!TMPDIR)
+ TMPDIR = "/tmp";
+ return TMPDIR;
}
-#else /* ... !CONFIG_USE_ZLIB */
+#endif
-void *grab_fd(int fd, unsigned long *size)
+static void *do_grab_fd(int fd, unsigned long *size)
{
struct stat st;
void *map;
@@ -100,6 +64,59 @@ void *grab_fd(int fd, unsigned long *siz
return map;
}
+void *grab_fd(int fd, unsigned long *size)
+{
+#ifdef CONFIG_USE_ZLIB
+ int magic = check_gz_magic(fd);
+ if (magic == -1)
+ return NULL;
+ if (magic) {
+ gzFile gzfd;
+ int tmp;
+ char buffer[4096];
+ char *template;
+ int r, w;
+ void *ret = NULL;
+
+ template = malloc(strlen(tmpdir()) + sizeof("/m-i-t.XXXXXX"));
+ if (!template)
+ return ret;
+ sprintf(template, "%s/m-i-t.XXXXXX", tmpdir());
+ gzfd = gzdopen(dup(fd), "rb");
+ if (!gzfd)
+ goto out_template;
+ tmp = mkstemp(template);
+ if (tmp == -1)
+ goto out_template;
+
+ while ((r = gzread(gzfd, buffer, sizeof(buffer))) > 0) {
+ char *p = buffer;
+ do {
+ w = write(tmp, p, r);
+ if (w > 0) {
+ r -= w;
+ p += w;
+ }
+ } while (w > 0 || (w == -1 && errno == EINTR));
+ if (w == -1)
+ goto out;
+ }
+ if (r < 0)
+ goto out;
+ gzclose(gzfd);
+ ret = do_grab_fd(tmp, size);
+out:
+ close(tmp);
+ unlink(template);
+out_template:
+ free(template);
+ return ret;
+ } else
+#endif
+ return do_grab_fd(fd, size);
+}
+
+
void *grab_file(const char *filename, unsigned long *size)
{
int fd;
@@ -117,4 +134,4 @@ void release_file(void *data, unsigned l
{
munmap(data, size);
}
-#endif
+