Skip to content

Instantly share code, notes, and snippets.

@haesbaert
Created December 1, 2022 18:05
Show Gist options
  • Save haesbaert/146a0271796f9c6ee0e43bd4e51f5c82 to your computer and use it in GitHub Desktop.
Save haesbaert/146a0271796f9c6ee0e43bd4e51f5c82 to your computer and use it in GitHub Desktop.
--- /d/ocaml/otherlibs/unix/getaddrinfo.c 2022-07-06 00:03:07.244921517 +0200
+++ lib_eio_linux/getaddrinfo_stubs.c 2022-12-01 18:46:51.464740970 +0100
@@ -2,10 +2,11 @@
/* */
/* OCaml */
/* */
-/* Xavier Leroy, projet Cristal, INRIA Rocquencourt */
-/* */
+/* Xavier Leroy, projet Cristal, INRIA Rocquencourt, */
+/* Christiano Haesbaert, Tarides */
/* Copyright 2004 Institut National de Recherche en Informatique et */
/* en Automatique. */
+/* Copyright 2022 Tarides */
/* */
/* All rights reserved. This file is distributed under the terms of */
/* the GNU Lesser General Public License version 2.1, with the */
@@ -13,24 +14,19 @@
/* */
/**************************************************************************/
-#include <string.h>
-#include <caml/mlvalues.h>
-#include <caml/alloc.h>
-#include <caml/fail.h>
-#include <caml/memory.h>
-#include <caml/misc.h>
-#include <caml/signals.h>
-#include "unixsupport.h"
-#include "cst2constr.h"
-
-#if defined(HAS_SOCKETS) && defined(HAS_IPV6)
-
-#include "socketaddr.h"
-#ifndef _WIN32
#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <errno.h>
#include <netdb.h>
-#endif
+#include <caml/mlvalues.h>
+#include <caml/memory.h>
+#include <caml/alloc.h>
+#include <caml/unixsupport.h>
+#include <caml/socketaddr.h>
+
+extern value caml_unix_cst_to_constr(int, int *, int, int);
extern int caml_unix_socket_domain_table[]; /* from socket.c */
extern int caml_unix_socket_type_table[]; /* from socket.c */
@@ -57,14 +53,55 @@
CAMLreturn(vres);
}
-CAMLprim value caml_unix_getaddrinfo(value vnode, value vserv, value vopts)
+/* glibc doesn't define a bunch of EAI_, so fake one since code gets copied around */
+
+#ifndef EAI_ADDRFAMILY
+#define EAI_ADDRFAMILY (-3000)
+#endif /* EAI_ADDRFAMILY */
+
+#ifndef EAI_BADHINTS
+#define EAI_BADHINTS (-3013)
+#endif /* EAI_BADHINTS */
+
+#ifndef EAI_NODATA
+#define EAI_NODATA (-3007)
+#endif /* EAI_NODATA */
+
+#ifndef EAI_OVERFLOW
+#define EAI_OVERFLOW (-3009)
+#endif /* EAI_OVERFLOW */
+
+#ifndef EAI_PROTOCOL
+#define EAI_PROTOCOL (-3014)
+#endif /* EAI_PROTOCOL */
+
+static int gai_errors[] = {
+ EAI_ADDRFAMILY,
+ EAI_AGAIN,
+ EAI_BADFLAGS,
+ EAI_BADHINTS,
+ EAI_FAIL,
+ EAI_FAMILY,
+ EAI_MEMORY,
+ EAI_NODATA,
+ EAI_NONAME,
+ EAI_OVERFLOW,
+ EAI_PROTOCOL,
+ EAI_SERVICE,
+ EAI_SOCKTYPE,
+ EAI_SYSTEM /* NOTE: must be last */
+};
+
+#define nmemb_gai_errors (sizeof(gai_errors) / sizeof(int))
+
+CAMLprim value caml_eio_getaddrinfo(value vnode, value vserv, value vopts)
{
CAMLparam3(vnode, vserv, vopts);
- CAMLlocal3(vres, v, e);
+ CAMLlocal4(vres, v, e, vret);
char * node, * serv;
struct addrinfo hints;
struct addrinfo * res, * r;
- int retcode;
+ int retcode, i;
if (! (caml_string_is_c_safe(vnode) && caml_string_is_c_safe(vserv)))
CAMLreturn (Val_emptylist);
@@ -124,14 +161,21 @@
Field(v, 1) = vres;
vres = v;
}
+ vret = caml_alloc_small(1, 0); /* 0 = Ok */
+ Field(vret, 0) = vres;
freeaddrinfo(res);
+ } else {
+ for (i = 0; i < nmemb_gai_errors; i++)
+ if (gai_errors[i] == retcode)
+ break;
+ /* Paranoia keeps the world spinning */
+ if (i == nmemb_gai_errors) {
+ errno = EINVAL;
+ i = gai_errors[nmemb_gai_errors - 1]; /* EAI_SYSTEM */
+ }
+ vret = caml_alloc_small(1, 1); /* 1 = Error */
+ Field(vret, 0) = Val_int(i);
}
- CAMLreturn(vres);
-}
-
-#else
-CAMLprim value caml_unix_getaddrinfo(value vnode, value vserv, value vopts)
-{ caml_invalid_argument("getaddrinfo not implemented"); }
-
-#endif
+ CAMLreturn(vret);
+}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment