summaryrefslogtreecommitdiffstats
path: root/otherlibs/unix/socketaddr.c
diff options
context:
space:
mode:
Diffstat (limited to 'otherlibs/unix/socketaddr.c')
-rw-r--r--otherlibs/unix/socketaddr.c81
1 files changed, 81 insertions, 0 deletions
diff --git a/otherlibs/unix/socketaddr.c b/otherlibs/unix/socketaddr.c
new file mode 100644
index 000000000..1cb9115a0
--- /dev/null
+++ b/otherlibs/unix/socketaddr.c
@@ -0,0 +1,81 @@
+#include <mlvalues.h>
+#include <alloc.h>
+#include <memory.h>
+#include <str.h>
+#include <errno.h>
+#include "unix.h"
+
+#ifdef HAS_SOCKETS
+
+#include "socketaddr.h"
+
+value alloc_inet_addr(a)
+ unsigned long a;
+{
+ value res;
+ res = alloc(1, Abstract_tag);
+ GET_INET_ADDR(res) = a;
+ return res;
+}
+
+void get_sockaddr(a)
+ value a;
+{
+ switch(Tag_val(a)) {
+ case 0: /* ADDR_UNIX */
+ { value path;
+ mlsize_t len;
+ path = Field(a, 0);
+ len = string_length(path);
+ sock_addr.s_unix.sun_family = AF_UNIX;
+ if (len >= sizeof(sock_addr.s_unix.sun_path)) {
+ unix_error(ENAMETOOLONG, "", path);
+ }
+ bcopy(String_val(path), sock_addr.s_unix.sun_path, (int) len + 1);
+ sock_addr_len = sizeof(sock_addr.s_unix.sun_family) + len;
+ break;
+ }
+ case 1: /* ADDR_INET */
+ {
+ char * p;
+ int n;
+ for (p = (char *) &sock_addr.s_inet, n = sizeof(sock_addr.s_inet);
+ n > 0; p++, n--)
+ *p = 0;
+ sock_addr.s_inet.sin_family = AF_INET;
+ sock_addr.s_inet.sin_addr.s_addr = GET_INET_ADDR(Field(a, 0));
+ sock_addr.s_inet.sin_port = htons(Int_val(Field(a, 1)));
+ sock_addr_len = sizeof(struct sockaddr_in);
+ break;
+ }
+ }
+}
+
+value alloc_sockaddr()
+{
+ value res;
+ switch(sock_addr.s_gen.sa_family) {
+ case AF_UNIX:
+ { Push_roots(n, 1);
+ n[0] = copy_string(sock_addr.s_unix.sun_path);
+ res = alloc(1, 0);
+ Field(res,0) = n[0];
+ Pop_roots();
+ break;
+ }
+ case AF_INET:
+ { Push_roots(a, 1);
+ a[0] = alloc_inet_addr(sock_addr.s_inet.sin_addr.s_addr);
+ res = alloc(2, 1);
+ Field(res,0) = a[0];
+ Field(res,1) = Val_int(ntohs(sock_addr.s_inet.sin_port));
+ Pop_roots();
+ break;
+ }
+ default:
+ unix_error(EAFNOSUPPORT, "", Nothing);
+ }
+ return res;
+}
+
+#endif