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
+
openSUSE Build Service is sponsored by