utils: Provide a fmemopen(3) fallback using BSD funopen()
authorMartin Willi <martin@revosec.ch>
Thu, 24 Oct 2013 09:49:32 +0000 (11:49 +0200)
committerMartin Willi <martin@revosec.ch>
Thu, 24 Oct 2013 11:17:05 +0000 (13:17 +0200)
configure.ac
src/libstrongswan/utils/utils.c
src/libstrongswan/utils/utils.h

index ffcb7a5..9ac5169 100644 (file)
@@ -489,6 +489,7 @@ AC_CHECK_FUNC(
 )
 
 AC_CHECK_FUNCS(prctl mallinfo getpass closefrom getpwnam_r getgrnam_r getpwuid_r)
+AC_CHECK_FUNCS(fmemopen funopen)
 
 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)
index 30084cd..3a535c5 100644 (file)
@@ -29,6 +29,7 @@
 
 #include "collections/enumerator.h"
 #include "utils/debug.h"
+#include "utils/chunk.h"
 
 ENUM(status_names, SUCCESS, NEED_MORE,
        "SUCCESS",
@@ -513,6 +514,51 @@ _cas_impl(ptr, void*)
 
 #endif /* HAVE_GCC_ATOMIC_OPERATIONS */
 
+
+#if HAVE_FMEMOPEN == fallback
+
+static int fmemread(chunk_t *cookie, char *buf, int size)
+{
+       int len;
+
+       len = min(size, cookie->len);
+       memcpy(buf, cookie->ptr, len);
+       *cookie = chunk_skip(*cookie, len);
+
+       return len;
+}
+
+static int fmemwrite(chunk_t *cookie, const char *buf, int size)
+{
+       int len;
+
+       len = min(size, cookie->len);
+       memcpy(cookie->ptr, buf, len);
+       *cookie = chunk_skip(*cookie, len);
+
+       return len;
+}
+
+static int fmemclose(void *cookie)
+{
+       free(cookie);
+       return 0;
+}
+
+FILE *fmemopen(void *buf, size_t size, const char *mode)
+{
+       chunk_t *cookie;
+
+       INIT(cookie,
+               .ptr = buf,
+               .len = size,
+       );
+
+       return funopen(cookie, (void*)fmemread, (void*)fmemwrite, NULL, fmemclose);
+}
+
+#endif /* FMEMOPEN fallback*/
+
 /**
  * Described in header.
  */
index 5c237a7..2cbab5b 100644 (file)
@@ -765,6 +765,21 @@ bool cas_ptr(void **ptr, void *oldval, void *newval);
 
 #endif /* HAVE_GCC_ATOMIC_OPERATIONS */
 
+#ifndef HAVE_FMEMOPEN
+# ifdef HAVE_FUNOPEN
+#  define HAVE_FMEMOPEN fallback
+/**
+ * fmemopen(3) fallback using BSD funopen.
+ *
+ * We could also provide one using fopencookie(), but should we have it we
+ * most likely have fmemopen().
+ *
+ * fseek() is currently not supported.
+ */
+FILE *fmemopen(void *buf, size_t size, const char *mode);
+# endif /* FUNOPEN */
+#endif /* FMEMOPEN */
+
 /**
  * printf hook for time_t.
  *