Author: iratqq
Date: Sun Jan 18 19:49:34 2009
New Revision: 5750

Modified:
   trunk/uim/uim-posix.c

Log:
* uim/uim-posix.c (find_flags_equal, ref_args_or, c_make_addrinfo)
  (c_delete_addrinfo, c_addrinfo_set_ai_flags, c_addrinfo_ref_ai_flags)
  (c_addrinfo_set_ai_family, c_addrinfo_ref_ai_family)
  (c_addrinfo_set_ai_socktype, c_addrinfo_ref_ai_socktype)
  (c_addrinfo_set_ai_protocol, c_addrinfo_ref_ai_protocol)
  (c_addrinfo_ref_ai_addrlen, c_addrinfo_ref_ai_addr, c_getaddrinfo)
  (c_freeaddrinfo, c_socket, c_connect):
  - New functions.

  Import low-level socket functions.
  Now, uim-scm will read/write network packet immediately.


Modified: trunk/uim/uim-posix.c
==============================================================================
--- trunk/uim/uim-posix.c       (original)
+++ trunk/uim/uim-posix.c       Sun Jan 18 19:49:34 2009
@@ -46,6 +46,9 @@
 #include <errno.h>
 #include <assert.h>
 #include <fcntl.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#include <netinet/in.h>

 #include "uim.h"
 #include "uim-internal.h"
@@ -328,6 +331,28 @@
   char *arg;
 } opt_args;

+static const char *
+find_flags_equal(const opt_args *list, int flag, const char **errstrp)
+{
+  char *arg = NULL;
+  int i = 0;
+  const static char *err = N_("Invalid argument");
+
+  *errstrp = NULL;
+  while (1) {
+    if (list[i].arg == 0) {
+      *errstrp = err;
+      return 0;
+    }
+    if (list[i].flag == flag) {
+      arg = list[i].arg;
+      break;
+    }
+    i++;
+  }
+  return arg;
+}
+
 static int
 find_args_equal(const opt_args *list, char *arg, const char **errstrp)
 {
@@ -351,6 +376,21 @@
 }

 static uim_lisp
+ref_args_or(const opt_args *list, int flags)
+{
+  int i = 0;
+  uim_lisp ret_ = uim_scm_null();
+
+  while (list[i].arg != 0) {
+    if (list[i].flag & flags) {
+      ret_ = CONS(MAKE_SYM(list[i].arg), ret_);
+    }
+    i++;
+  }
+  return uim_scm_callf("reverse", "o", ret_);
+}
+
+static uim_lisp
 make_arg_list(const opt_args *list)
 {
   uim_lisp ret_;
@@ -488,6 +528,271 @@
   return ret_;
 }

+static uim_lisp
+c_make_addrinfo()
+{
+  struct addrinfo *addrinfo = uim_malloc(sizeof(struct addrinfo));
+
+  memset(addrinfo, 0, sizeof(struct addrinfo));
+  return MAKE_PTR(addrinfo);
+}
+
+static uim_lisp
+c_delete_addrinfo(uim_lisp addrinfo_)
+{
+  free(C_PTR(addrinfo_));
+  return uim_scm_t();
+}
+
+const static opt_args ai_flags[] = {
+  { AI_CANONNAME,   "$AI_CANONNAME" },
+  { AI_NUMERICHOST, "$AI_NUMERICHOST" },
+  { AI_PASSIVE,     "$AI_PASSIVE" },
+  { 0, 0 }
+};
+static uim_lisp
+c_addrinfo_set_ai_flags(uim_lisp addrinfo_, uim_lisp ai_flags_)
+{
+  struct addrinfo *addrinfo = C_PTR(addrinfo_);
+  int flags = 0;
+  const char *errstr;
+
+  while (!NULLP(ai_flags_)) {
+    char *f = C_SYM(CAR(ai_flags_));
+
+    flags |= find_args_equal(ai_flags, f, &errstr);
+    free(f);
+    if (errstr) {
+      uim_notify_fatal("addrinfo-set-ai-flags!: %s", errstr);
+      ERROR_OBJ(errstr, CAR(ai_flags_));
+    }
+    ai_flags_ = CDR(ai_flags_);
+  }
+
+  addrinfo->ai_flags = flags;
+  return uim_scm_t();
+}
+static uim_lisp
+c_addrinfo_ref_ai_flags(uim_lisp addrinfo_)
+{
+  struct addrinfo *addrinfo = C_PTR(addrinfo_);
+
+  return ref_args_or(ai_flags, addrinfo->ai_flags);
+}
+
+const static opt_args ai_family[] = {
+  { PF_UNSPEC, "$PF_UNSPEC" },
+  { PF_LOCAL,  "$PF_LOCAL" },
+  { PF_INET,   "$PF_INET" },
+  { PF_INET6,  "$PF_INET6" },
+  { 0, 0 }
+};
+
+static uim_lisp
+c_addrinfo_set_ai_family(uim_lisp addrinfo_, uim_lisp ai_family_)
+{
+  struct addrinfo *addrinfo = C_PTR(addrinfo_);
+  char *f = C_SYM(ai_family_);
+  int family;
+  const char *errstr;
+
+  family = find_args_equal(ai_family, f, &errstr);
+  free(f);
+  if (errstr) {
+    uim_notify_fatal("addrinfo-set-ai-family!: %s", errstr);
+    ERROR_OBJ(errstr, ai_family_);
+  }
+  addrinfo->ai_family = family;
+  return uim_scm_t();
+}
+static uim_lisp
+c_addrinfo_ref_ai_family(uim_lisp addrinfo_)
+{
+  struct addrinfo *addrinfo = C_PTR(addrinfo_);
+  const char *family;
+  const char *errstr;
+
+  family = find_flags_equal(ai_family, addrinfo->ai_family, &errstr);
+  if (errstr) {
+    uim_notify_fatal("addrinfo-ai-family?: %s", errstr);
+    ERROR_OBJ(errstr, addrinfo_);
+  }
+  return MAKE_SYM(family);
+}
+
+const static opt_args ai_socktype[] = {
+  { SOCK_STREAM, "$SOCK_STREAM" },
+  { SOCK_DGRAM,  "$SOCK_DGRAM" },
+  { SOCK_RAW,    "$SOCK_RAW" },
+  { 0, 0 }
+};
+
+static uim_lisp
+c_addrinfo_set_ai_socktype(uim_lisp addrinfo_, uim_lisp ai_socktype_)
+{
+  struct addrinfo *addrinfo = C_PTR(addrinfo_);
+  char *f = C_SYM(ai_socktype_);
+  int socktype;
+  const char *errstr;
+
+  socktype = find_args_equal(ai_socktype, f, &errstr);
+  free(f);
+  if (errstr) {
+    uim_notify_fatal("addrinfo-set-ai-socktype!: %s", errstr);
+    ERROR_OBJ(errstr, ai_socktype_);
+  }
+  addrinfo->ai_socktype = socktype;
+  return uim_scm_t();
+}
+static uim_lisp
+c_addrinfo_ref_ai_socktype(uim_lisp addrinfo_)
+{
+  struct addrinfo *addrinfo = C_PTR(addrinfo_);
+  const char *socktype;
+  const char *errstr;
+
+  socktype = find_flags_equal(ai_socktype, addrinfo->ai_socktype, &errstr);
+  if (errstr) {
+    uim_notify_fatal("addrinfo-ai-socktype?: %s", errstr);
+    ERROR_OBJ(errstr, addrinfo_);
+  }
+  return MAKE_SYM(socktype);
+}
+
+const static opt_args ai_protocol[] = {
+  { IPPROTO_UDP, "$IPPROTO_UDP" },
+  { IPPROTO_TCP, "$IPPROTO_TCP" },
+  { 0, 0 }
+};
+
+static uim_lisp
+c_addrinfo_set_ai_protocol(uim_lisp addrinfo_, uim_lisp ai_protocol_)
+{
+  struct addrinfo *addrinfo = C_PTR(addrinfo_);
+  char *f = C_SYM(ai_protocol_);
+  int protocol;
+  const char *errstr;
+
+  protocol = find_args_equal(ai_protocol, f, &errstr);
+  free(f);
+  if (errstr) {
+    uim_notify_fatal("addrinfo-set-ai-protocol!: %s", errstr);
+    ERROR_OBJ(errstr, ai_protocol_);
+  }
+  addrinfo->ai_protocol = protocol;
+  return uim_scm_t();
+}
+static uim_lisp
+c_addrinfo_ref_ai_protocol(uim_lisp addrinfo_)
+{
+  struct addrinfo *addrinfo = C_PTR(addrinfo_);
+  const char *protocol;
+  const char *errstr;
+
+  protocol = find_flags_equal(ai_protocol, addrinfo->ai_protocol, &errstr);
+  if (errstr) {
+    uim_notify_fatal("addrinfo-ai-protocol?: %s", errstr);
+    ERROR_OBJ(errstr, addrinfo_);
+  }
+  return MAKE_SYM(protocol);
+}
+
+static uim_lisp
+c_addrinfo_ref_ai_addrlen(uim_lisp addrinfo_)
+{
+  struct addrinfo *addrinfo = C_PTR(addrinfo_);
+
+  return MAKE_INT(addrinfo->ai_addrlen);
+}
+
+static uim_lisp
+c_addrinfo_ref_ai_addr(uim_lisp addrinfo_)
+{
+  struct addrinfo *addrinfo = C_PTR(addrinfo_);
+
+  return MAKE_PTR(addrinfo->ai_addr);
+}
+
+static uim_lisp
+c_getaddrinfo(uim_lisp hostname_, uim_lisp servname_, uim_lisp hint_)
+{
+  const char *hostname = REFER_C_STR(hostname_);
+  char *servname = NULL;
+  struct addrinfo *hints = C_PTR(hint_);
+  struct addrinfo *res, *res0;
+  uim_lisp ret_ = uim_scm_null();
+  int error;
+
+  if (INTP(servname_)) {
+    uim_asprintf(&servname, "%d", C_INT(servname_));
+  } else {
+    servname = C_STR(servname_);
+  }
+
+  error = getaddrinfo(hostname, servname, hints, &res0);
+  if (error) {
+    const char *errstr = gai_strerror(error);
+
+    free(servname);
+    uim_notify_fatal("getaddrinfo: %s", gai_strerror(error));
+    ERROR_OBJ(errstr, CONS(hostname_, servname_));
+  }
+
+  free(servname);
+  for (res = res0; res; res = res->ai_next) {
+    ret_ = CONS(MAKE_PTR(res) , ret_);
+  }
+  return uim_scm_callf("reverse", "o", ret_);
+}
+
+
+static uim_lisp
+c_freeaddrinfo(uim_lisp addrinfo_)
+{
+  freeaddrinfo(C_PTR(addrinfo_));
+  return uim_scm_t();
+}
+
+static uim_lisp
+c_socket(uim_lisp domain_, uim_lisp type_, uim_lisp protocol_)
+{
+  int domain;
+  int type;
+  int protocol;
+  char *sym;
+  const char *errstr;
+
+  sym = C_SYM(domain_);
+  domain = find_args_equal(ai_family, sym, &errstr);
+  free(sym);
+  if (errstr) {
+    uim_notify_fatal("socket: %s", errstr);
+    ERROR_OBJ(errstr, domain_);
+  }
+  sym = C_SYM(type_);
+  type = find_args_equal(ai_socktype, sym, &errstr);
+  free(sym);
+  if (errstr) {
+    uim_notify_fatal("socket: %s", errstr);
+    ERROR_OBJ(errstr, type_);
+  }
+  sym = C_SYM(protocol_);
+  protocol = find_args_equal(ai_protocol, sym, &errstr);
+  free(sym);
+  if (errstr) {
+    uim_notify_fatal("socket: %s", errstr);
+    ERROR_OBJ(errstr, protocol_);
+  }
+
+  return MAKE_INT(socket(domain, type, protocol));
+}
+
+static uim_lisp
+c_connect(uim_lisp s_, uim_lisp name_, uim_lisp namelen_)
+{
+  return MAKE_INT(connect(C_INT(s_), C_PTR(name_), C_INT(namelen_)));
+}
+
 void
 uim_init_posix_subrs(void)
 {
@@ -524,4 +829,23 @@

   uim_scm_init_proc0("file-open-flags?", c_file_open_flags);
   uim_scm_init_proc0("file-open-mode?", c_file_open_mode);
+
+  uim_scm_init_proc0("make-addrinfo", c_make_addrinfo);
+  uim_scm_init_proc1("delete-addrinfo", c_delete_addrinfo);
+
+  uim_scm_init_proc2("addrinfo-set-ai-flags!", c_addrinfo_set_ai_flags);
+  uim_scm_init_proc1("addrinfo-ai-flags?", c_addrinfo_ref_ai_flags);
+  uim_scm_init_proc2("addrinfo-set-ai-family!", c_addrinfo_set_ai_family);
+  uim_scm_init_proc1("addrinfo-ai-family?", c_addrinfo_ref_ai_family);
+ uim_scm_init_proc2("addrinfo-set-ai-socktype!", c_addrinfo_set_ai_socktype);
+  uim_scm_init_proc1("addrinfo-ai-socktype?", c_addrinfo_ref_ai_socktype);
+ uim_scm_init_proc2("addrinfo-set-ai-protocol!", c_addrinfo_set_ai_protocol);
+  uim_scm_init_proc1("addrinfo-ai-protocol?", c_addrinfo_ref_ai_protocol);
+  uim_scm_init_proc1("addrinfo-ai-addrlen?", c_addrinfo_ref_ai_addrlen);
+  uim_scm_init_proc1("addrinfo-ai-addr?", c_addrinfo_ref_ai_addr);
+
+  uim_scm_init_proc3("getaddrinfo", c_getaddrinfo);
+  uim_scm_init_proc1("freeaddrinfo", c_freeaddrinfo);
+  uim_scm_init_proc3("socket", c_socket);
+  uim_scm_init_proc3("connect", c_connect);
 }

Reply via email to