From: Martin Willi Date: Thu, 21 Nov 2013 13:07:12 +0000 (+0100) Subject: chunk: Provide a fallback chunk_map() if mmap is not available X-Git-Tag: 5.1.2rc1~42^2~8 X-Git-Url: http://git.ipfire.org/gitweb/gitweb.cgi?a=commitdiff_plain;h=37374a292aea466063bf7777929122299d493326;p=thirdparty%2Fstrongswan.git chunk: Provide a fallback chunk_map() if mmap is not available --- diff --git a/configure.ac b/configure.ac index ab90571f78..10f1e1929a 100644 --- a/configure.ac +++ b/configure.ac @@ -495,7 +495,7 @@ AC_CHECK_FUNC( ) AC_CHECK_FUNCS(prctl mallinfo getpass closefrom getpwnam_r getgrnam_r getpwuid_r) -AC_CHECK_FUNCS(fmemopen funopen) +AC_CHECK_FUNCS(fmemopen funopen mmap) AC_CHECK_HEADERS(sys/sockio.h glob.h net/if_tun.h linux/fib_rules.h) AC_CHECK_HEADERS(net/pfkeyv2.h netipsec/ipsec.h netinet6/ipsec.h linux/udp.h) diff --git a/src/libstrongswan/utils/chunk.c b/src/libstrongswan/utils/chunk.c index e308418dfd..5961407dd2 100644 --- a/src/libstrongswan/utils/chunk.c +++ b/src/libstrongswan/utils/chunk.c @@ -18,7 +18,9 @@ #include #include #include -#include +#ifdef HAVE_MMAP +# include +#endif #include #include #include @@ -317,6 +319,8 @@ typedef struct { void *map; /* size of map */ size_t len; + /* do we write? */ + bool wr; } mmaped_chunk_t; /** @@ -330,6 +334,7 @@ chunk_t *chunk_map(char *path, bool wr) INIT(chunk, .fd = open(path, wr ? O_RDWR : O_RDONLY), + .wr = wr, ); if (chunk->fd == -1) @@ -344,6 +349,7 @@ chunk_t *chunk_map(char *path, bool wr) errno = tmp; return NULL; } +#ifdef HAVE_MMAP chunk->len = sb.st_size; /* map non-empty files only, as mmap() complains otherwise */ if (chunk->len) @@ -360,6 +366,17 @@ chunk_t *chunk_map(char *path, bool wr) } } chunk->public = chunk_create(chunk->map, chunk->len); +#else /* !HAVE_MMAP */ + if (!chunk_from_fd(chunk->fd, &chunk->public)) + { + tmp = errno; + chunk_unmap(&chunk->public); + errno = tmp; + return NULL; + } + chunk->map = chunk->public.ptr; + chunk->len = chunk->public.len; +#endif /* !HAVE_MMAP */ return &chunk->public; } @@ -373,11 +390,39 @@ bool chunk_unmap(chunk_t *public) int tmp = 0; chunk = (mmaped_chunk_t*)public; +#ifdef HAVE_MMAP if (chunk->map && chunk->map != MAP_FAILED) { ret = munmap(chunk->map, chunk->len) == 0; tmp = errno; } +#else /* !HAVE_MMAP */ + if (chunk->wr) + { + if (lseek(chunk->fd, 0, SEEK_SET) != -1) + { + int len, total = 0; + + ret = TRUE; + while (total < chunk->len) + { + len = write(chunk->fd, chunk->map + total, chunk->len - total); + if (len <= 0) + { + ret = FALSE; + break; + } + total += len; + } + } + tmp = errno; + } + else + { + ret = TRUE; + } + free(chunk->map); +#endif /* !HAVE_MMAP */ close(chunk->fd); free(chunk); errno = tmp;