Support platforms without mmap
authorJ. Ali Harlow <ali@juiblex.co.uk>
Tue, 6 Jan 2009 17:33:37 +0000 (17:33 +0000)
committerJ. Ali Harlow <ali@juiblex.co.uk>
Tue, 6 Jan 2009 17:33:37 +0000 (17:33 +0000)
configure.ac
librazor/razor-internal.h
librazor/razor.c
librazor/rpm.c
librazor/util.c

index 56f2ea0..6923ba8 100644 (file)
@@ -21,6 +21,7 @@ AC_ISC_POSIX
 AC_PROG_CC
 AM_PROG_CC_STDC
 AC_HEADER_STDC
+AC_CHECK_HEADERS([sys/mman.h])
 AM_PROG_LIBTOOL
 AC_PROG_MAKE_SET
 AC_PROG_LN_S
index b82a468..70e468c 100644 (file)
@@ -222,6 +222,9 @@ razor_package_get_details_varg(struct razor_set *set,
 int razor_create_dir(const char *root, const char *path);
 int razor_write(int fd, const void *data, size_t size);
 
+void *razor_file_get_contents(const char *filename, size_t *length);
+int razor_file_free_contents(void *addr, size_t length);
+
 
 typedef int (*razor_compare_with_data_func_t)(const void *p1,
                                              const void *p,
index 6ed90c7..f80d497 100644 (file)
@@ -27,7 +27,6 @@
 #include <string.h>
 #include <sys/types.h>
 #include <sys/stat.h>
-#include <sys/mman.h>
 #include <unistd.h>
 #include <fcntl.h>
 #include <errno.h>
@@ -101,18 +100,13 @@ razor_set_bind_sections(struct razor_set *set,
                        const char *filename)
 {
        struct razor_set_section *s, *sections;
-       struct stat stat;
        struct array *array;
        const char *pool;
-       int fd, i;
+       int i;
 
-       fd = open(filename, O_RDONLY);
-       if (fstat(fd, &stat) < 0)
-               return -1;
-       *header = mmap(NULL, stat.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
-       if (*header == MAP_FAILED)
+       *header = razor_file_get_contents(filename, header_size);
+       if (!*header)
                return -1;
-       *header_size = stat.st_size;
 
        sections = (void *) *header + sizeof **header;
        pool = (void *) sections + (*header)->num_sections * sizeof *sections;
@@ -131,7 +125,6 @@ razor_set_bind_sections(struct razor_set *set,
                array->size = s->size;
                array->alloc = s->size;
        }
-       close(fd);
 
        return 0;
 }
@@ -180,7 +173,7 @@ razor_set_destroy(struct razor_set *set)
        assert (set != NULL);
 
        if (set->header) {
-               munmap(set->header, set->header_size);
+               razor_file_free_contents(set->header, set->header_size);
        } else {
                for (i = 0; i < ARRAY_SIZE(razor_sections); i++) {
                        a = (void *) set + razor_sections[i].offset;
@@ -189,7 +182,8 @@ razor_set_destroy(struct razor_set *set)
        }
 
        if (set->details_header) {
-               munmap(set->details_header, set->details_header_size);
+               razor_file_free_contents(set->details_header,
+                       set->details_header_size);
        } else {
                for (i = 0; i < ARRAY_SIZE(razor_details_sections); i++) {
                        a = (void *) set + razor_details_sections[i].offset;
@@ -198,7 +192,8 @@ razor_set_destroy(struct razor_set *set)
        }
 
        if (set->files_header) {
-               munmap(set->files_header, set->files_header_size);
+               razor_file_free_contents(set->files_header,
+                       set->files_header_size);
        } else {
                for (i = 0; i < ARRAY_SIZE(razor_files_sections); i++) {
                        a = (void *) set + razor_files_sections[i].offset;
index 9435354..03e77a0 100644 (file)
@@ -23,7 +23,6 @@
 #include <string.h>
 #include <errno.h>
 #include <sys/stat.h>
-#include <sys/mman.h>
 #include <sys/types.h>
 #include <sys/wait.h>
 #include <fcntl.h>
@@ -353,10 +352,8 @@ razor_rpm_open(const char *filename)
 {
        struct razor_rpm *rpm;
        struct rpm_header_index *base, *index;
-       struct stat buf;
        unsigned int count, i, nindex, hsize;
        const char *name;
-       int fd;
 
        assert (filename != NULL);
 
@@ -365,24 +362,11 @@ razor_rpm_open(const char *filename)
                return NULL;
        memset(rpm, 0, sizeof *rpm);
 
-       fd = open(filename, O_RDONLY);
-       if (fd < 0) {
-               fprintf(stderr, "couldn't open %s\n", filename);
-               return NULL;
-       }
-
-       if (fstat(fd, &buf) < 0) {
-               fprintf(stderr, "failed to stat %s (%m)\n", filename);
-               return NULL;
-       }
-
-       rpm->size = buf.st_size;
-       rpm->map = mmap(NULL, rpm->size, PROT_READ, MAP_PRIVATE, fd, 0);
-       if (rpm->map == MAP_FAILED) {
-               fprintf(stderr, "couldn't mmap %s\n", filename);
+       rpm->map = razor_file_get_contents(filename, &rpm->size);
+       if (!rpm->map) {
+               fprintf(stderr, "couldn't get contents of %s (%m)\n", filename);
                return NULL;
        }
-       close(fd);
 
        rpm->signature = rpm->map + RPM_LEAD_SIZE;
        nindex = ntohl(rpm->signature->nindex);
@@ -780,7 +764,7 @@ razor_rpm_close(struct razor_rpm *rpm)
        assert (rpm != NULL);
 
        free(rpm->dirs);
-       err = munmap(rpm->map, rpm->size);
+       err = razor_file_free_contents(rpm->map, rpm->size);
        free(rpm);
 
        return err;
index 64a26d4..401f990 100644 (file)
@@ -1,6 +1,7 @@
 /*
  * Copyright (C) 2008  Kristian Høgsberg <krh@redhat.com>
  * Copyright (C) 2008  Red Hat, Inc
+ * Copyright (C) 2009  J. Ali Harlow <ali@juiblex.co.uk>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
 
+#include "config.h"
+
 #include <limits.h>
 #include <string.h>
+#include <sys/types.h>
 #include <sys/stat.h>
 #include <stdlib.h>
 #include <stdio.h>
 #include <stdint.h>
 #include <unistd.h>
+#include <fcntl.h>
+#if HAVE_SYS_MMAN_H
+#include <sys/mman.h>
+#endif
 
 #include "razor-internal.h"
 
+#ifndef O_BINARY
+#define O_BINARY       0
+#endif
+
 int
 razor_create_dir(const char *root, const char *path)
 {
@@ -92,6 +104,65 @@ razor_write(int fd, const void *data, size_t size)
        return 0;
 }
 
+void *
+razor_file_get_contents(const char *filename, size_t *length)
+{
+       int fd;
+       struct stat st;
+       void *addr;
+#if !HAVE_SYS_MMAN_H
+       size_t nb;
+       ssize_t res;
+#endif
+
+       fd = open(filename, O_RDONLY | O_BINARY);
+       if (fd < 0)
+               return NULL;
+
+       if (fstat(fd, &st) < 0) {
+               close(fd);
+               return NULL;
+       }
+
+       *length = st.st_size;
+#if HAVE_SYS_MMAN_H
+       addr = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
+#else
+       addr = malloc(st.st_size);
+       if (addr) {
+               nb = 0;
+               while(nb < st.st_size) {
+                       res = read(fd, addr + nb, st.st_size - nb);
+                       if (res <= 0) {
+                               free(addr);
+                               addr = NULL;
+                               break;
+                       }
+                       nb += res;
+               }
+       }
+#endif
+       close(fd);
+
+#if HAVE_SYS_MMAN_H
+       if (addr == MAP_FAILED)
+               addr = NULL;
+#endif
+
+       return addr;
+}
+
+int
+razor_file_free_contents(void *addr, size_t length)
+{
+#if HAVE_SYS_MMAN_H
+       return munmap(addr, length);
+#else
+       free(addr);
+       return 0;
+#endif
+}
+
 struct qsort_context {
        size_t size;
        razor_compare_with_data_func_t compare;