[前][次][番号順一覧][スレッド一覧]

ruby-changes:10983

From: akr <ko1@a...>
Date: Mon, 23 Feb 2009 20:32:54 +0900 (JST)
Subject: [ruby-changes:10983] Ruby:r22570 (trunk): * ext/socket/ancdata.c (inspect_bintime_as_abstime): new function to

akr	2009-02-23 20:32:43 +0900 (Mon, 23 Feb 2009)

  New Revision: 22570

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=22570

  Log:
    * ext/socket/ancdata.c (inspect_bintime_as_abstime): new function to
      show struct bintime.
      (ancillary_inspect): use it for SCM_BINTIME on FreeBSD.
    * ext/socket/mkconstants.rb: define SCM_BINTIME.

  Modified files:
    trunk/ChangeLog
    trunk/ext/socket/ancdata.c
    trunk/ext/socket/mkconstants.rb
    trunk/test/socket/test_socket.rb

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 22569)
+++ ChangeLog	(revision 22570)
@@ -1,3 +1,11 @@
+Mon Feb 23 20:30:06 2009  Tanaka Akira  <akr@f...>
+
+	* ext/socket/ancdata.c (inspect_bintime_as_abstime): new function to
+	  show struct bintime.
+	  (ancillary_inspect): use it for SCM_BINTIME on FreeBSD.
+
+	* ext/socket/mkconstants.rb: define SCM_BINTIME.
+
 Mon Feb 23 20:18:49 2009  Tanaka Akira  <akr@f...>
 
 	* ext/socket/ancdata.c (inspect_timeval_as_abstime): use time_t
Index: ext/socket/mkconstants.rb
===================================================================
--- ext/socket/mkconstants.rb	(revision 22569)
+++ ext/socket/mkconstants.rb	(revision 22570)
@@ -668,6 +668,7 @@
 SCM_TIMESTAMP
 SCM_TIMESTAMPNS
 SCM_UCRED
+SCM_BINTIME
 
 LOCAL_PEERCRED
 LOCAL_CREDS
Index: ext/socket/ancdata.c
===================================================================
--- ext/socket/ancdata.c	(revision 22569)
+++ ext/socket/ancdata.c	(revision 22570)
@@ -722,6 +722,54 @@
 }
 #endif
 
+#if defined(SCM_BINTIME)
+static int
+inspect_bintime_as_abstime(int level, int optname, VALUE data, VALUE ret)
+{
+    if (RSTRING_LEN(data) == sizeof(struct bintime)) {
+        struct bintime bt;
+        struct tm tm;
+	uint64_t frac_h, frac_l;
+	uint64_t scale_h, scale_l;
+	uint64_t tmp1, tmp2;
+	uint64_t res_h, res_l;
+        char buf[32];
+        memcpy((char*)&bt, RSTRING_PTR(data), sizeof(bt));
+        tm = *localtime(&bt.sec);
+        strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", &tm);
+
+	/* res_h = frac * 10**19 / 2**64 */
+
+	frac_h = bt.frac >> 32;
+	frac_l = bt.frac & 0xffffffff;
+
+	scale_h = 0x8ac72304; /* 0x8ac7230489e80000 == 10**19 */
+	scale_l = 0x89e80000;
+
+	res_h = frac_h * scale_h;
+	res_l = frac_l * scale_l;
+
+	tmp1 = frac_h * scale_l;
+	res_h += tmp1 >> 32;
+	tmp2 = res_l;
+	res_l += tmp1 & 0xffffffff;
+	if (res_l < tmp2) res_h++;
+
+	tmp1 = frac_l * scale_h;
+	res_h += tmp1 >> 32;
+	tmp2 = res_l;
+	res_l += tmp1 & 0xffffffff;
+	if (res_l < tmp2) res_h++;
+
+        rb_str_catf(ret, " %s.%019"PRIu64, buf, res_h);
+        return 1;
+    }
+    else {
+        return 0;
+    }
+}
+#endif
+
 /*
  * call-seq:
  *   ancillarydata.inspect => string
@@ -795,6 +843,9 @@
 #            if defined(SCM_TIMESTAMP) /* GNU/Linux, FreeBSD, NetBSD, OpenBSD, MacOS X, Solaris */
               case SCM_TIMESTAMP: inspected = inspect_timeval_as_abstime(level, type, data, ret); break;
 #            endif
+#            if defined(SCM_BINTIME) /* FreeBSD */
+              case SCM_BINTIME: inspected = inspect_bintime_as_abstime(level, type, data, ret); break;
+#            endif
 #            if defined(SCM_RIGHTS) /* 4.4BSD */
               case SCM_RIGHTS: inspected = anc_inspect_socket_rights(level, type, data, ret); break;
 #            endif
Index: test/socket/test_socket.rb
===================================================================
--- test/socket/test_socket.rb	(revision 22569)
+++ test/socket/test_socket.rb	(revision 22570)
@@ -291,4 +291,22 @@
     assert_match(pat, stamp.inspect)
   end
 
+  def test_bintime
+    return if /freebsd/ !~ RUBY_PLATFORM
+    t1 = Time.now.strftime("%Y-%m-%d")
+    stamp = nil
+    Addrinfo.udp("127.0.0.1", 0).bind {|s1|
+      Addrinfo.udp("127.0.0.1", 0).bind {|s2|
+        s1.setsockopt(:SOCKET, :BINTIME, true)
+        s2.send "a", 0, s1.local_address
+        msg, addr, rflags, stamp = s1.recvmsg
+        assert_equal("a", msg)
+        assert(stamp.cmsg_is?(:SOCKET, :BINTIME))
+      }
+    }
+    t2 = Time.now.strftime("%Y-%m-%d")
+    pat = Regexp.union([t1, t2].uniq)
+    assert_match(pat, stamp.inspect)
+  end
+
 end if defined?(Socket)

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]