chiark / gitweb /
portability: Provide implementation of fmemopen
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Tue, 26 Nov 2019 22:16:22 +0000 (22:16 +0000)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Sat, 15 Feb 2020 21:56:49 +0000 (21:56 +0000)
We are going to want one of these.  I have tested it as follows:

1. In configure.ac just before AC_CHECK_FUNCS, add:  LIBS+=-lbsd
2. In osdep.c, add:  #include <bsd/stdio.h>
3. Change all fmemopen to Yfmemopen, with
     git-ls-files | perl -lne 'print if lstat and -f _' | xargs perl -i~ -pe 's/fmemopen/Y$&/gi'

The result is that we do not find Yfmemopen.  The tests still pass and
I have verified that my stunt implementation is called.

FTR, this rune undoes the Y:
     git-ls-files | perl -lne 'print if lstat and -f _' | xargs perl -i~ -pe 's/Y(fmemopen)/$1/gi'

Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
config.h.in
configure
configure.ac
osdep.c
osdep.h

index 8cce8b0643bda1e7edb89f41e052da760916647d..a99e83f1ce52faef56789141ec8041ea4957eb63 100644 (file)
 /* Define to 1 to use IPv6 support in system and adns */
 #undef CONFIG_IPV6
 
+/* Define to 1 if you have the `fmemopen' function. */
+#undef HAVE_FMEMOPEN
+
+/* Define to 1 if you have the `funopen' function. */
+#undef HAVE_FUNOPEN
+
 /* Define to 1 if you have the `adns' library (-ladns). */
 #undef HAVE_LIBADNS
 
index b9cf39a164d763ab5e2586c02033738abf647a88..43de16e885044aaede33ad0150f872308ca93a1a 100755 (executable)
--- a/configure
+++ b/configure
@@ -4119,6 +4119,19 @@ fi
 
 
 
+for ac_func in fmemopen funopen
+do :
+  as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+
 { $as_echo "$as_me:${as_lineno-$LINENO}: Checking requirements for IPv6 support..." >&5
 $as_echo "$as_me: Checking requirements for IPv6 support..." >&6;}
 enable_ipv6=true
index 7b06f099e92912622989f51b1f3f4dd8627f2034..674ed3642da6ef96a0e5cd27b171fef83af451fa 100644 (file)
@@ -100,6 +100,8 @@ SECNET_C_GETFUNC(inet_aton,resolv)
 AC_CHECK_LIB(adns,adns_init)
 REQUIRE_HEADER([adns.h])
 
+AC_CHECK_FUNCS([fmemopen funopen])
+
 AC_MSG_NOTICE([Checking requirements for IPv6 support...])
 enable_ipv6=true
 m4_define(NO_IPV6,[enable_ipv6=false])
diff --git a/osdep.c b/osdep.c
index 7bb7aaa622dd81fee8933972a43768b8a8c0cfe1..24076988ee6811101b74cd29e7bf64eec1e694d3 100644 (file)
--- a/osdep.c
+++ b/osdep.c
 #include "osdep.h"
 #include "secnet.h"
 #include "util.h"
+
+#ifndef HAVE_FMEMOPEN
+# ifdef HAVE_FUNOPEN
+
+struct fmemopen_state {
+    const char *bufp;
+    size_t remain;
+};
+
+static int fmemopen_readfn(void *sst, char *out, int sz)
+{
+    struct fmemopen_state *st=sst;
+    assert(sz>=0);
+    int now=MIN((size_t)sz,st->remain);
+    memcpy(out,st->bufp,now);
+    st->remain-=now;
+    return now;
+}
+static int fmemopen_close(void *sst) { free(sst); return 0; }
+
+FILE *fmemopen(void *buf, size_t size, const char *mode)
+{
+    /* this is just a fake plastic imitation */
+    assert(!strcmp(mode,"r"));
+    struct fmemopen_state *st;
+    NEW(st);
+    st->bufp=buf;
+    st->remain=size;
+    FILE *f=funopen(st,fmemopen_readfn,0,0,fmemopen_close);
+    if (!f) free(st);
+    return f;
+}
+
+# else /* HAVE_FUNOPEN */
+#  error no fmemopen, no funopen, cannot proceed
+# endif
+
+#endif /* HAVE_FMEMOPEN */
diff --git a/osdep.h b/osdep.h
index a89958d3e0e024de45bf266bd1149c0e294ec9ad..46c532b0ede6d15d3affe1bbac0a476d7d23f832 100644 (file)
--- a/osdep.h
+++ b/osdep.h
 
 #include "config.h"
 
+#include <stdio.h>
+
+#ifndef HAVE_FMEMOPEN
+extern FILE *fmemopen(void *buf, size_t size, const char *mode);
+#endif
+
 #endif /* osdep_h */