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

ruby-changes:10581

From: akr <ko1@a...>
Date: Mon, 9 Feb 2009 00:38:07 +0900 (JST)
Subject: [ruby-changes:10581] Ruby:r22137 (trunk): * ext/socket/extconf.rb: check sys/param.h and sys/ucred.h.

akr	2009-02-09 00:37:55 +0900 (Mon, 09 Feb 2009)

  New Revision: 22137

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

  Log:
    * ext/socket/extconf.rb: check sys/param.h and sys/ucred.h.
    * ext/socket/rubysocket.h: include sys/param.h and sys/ucred.h.
    
    * ext/socket/option.c (inspect_local_peercred): new function to show
      LOCAL_PEERCRED socket option on FreeBSD.
      (sockopt_inspect): show as LOCAL_* socket option if AF_UNIX and level
      is 0.

  Modified files:
    trunk/ChangeLog
    trunk/ext/socket/extconf.rb
    trunk/ext/socket/mkconstants.rb
    trunk/ext/socket/option.c
    trunk/ext/socket/rubysocket.h
    trunk/test/socket/test_unix.rb

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 22136)
+++ ChangeLog	(revision 22137)
@@ -1,3 +1,14 @@
+Mon Feb  9 00:30:56 2009  Tanaka Akira  <akr@f...>
+
+	* ext/socket/extconf.rb: check sys/param.h and sys/ucred.h.
+
+	* ext/socket/rubysocket.h: include sys/param.h and sys/ucred.h.
+
+	* ext/socket/option.c (inspect_local_peercred): new function to show
+	  LOCAL_PEERCRED socket option on FreeBSD.
+	  (sockopt_inspect): show as LOCAL_* socket option if AF_UNIX and level
+	  is 0.
+
 Mon Feb  9 00:01:47 2009  Tanaka Akira  <akr@f...>
 
 	* ext/socket/rubysocket.h (sockopt_new): add family argument.
@@ -25,7 +36,7 @@
 Sun Feb  8 23:22:35 2009  Tanaka Akira  <akr@f...>
 
 	* ext/socket/option.c (inspect_peercred): new function to show
-	  SO_PEERCRED socket option.
+	  SO_PEERCRED socket option on GNU/Linux.
 
 Sun Feb  8 22:44:20 2009  Nobuyoshi Nakada  <nobu@r...>
 
Index: ext/socket/rubysocket.h
===================================================================
--- ext/socket/rubysocket.h	(revision 22136)
+++ ext/socket/rubysocket.h	(revision 22137)
@@ -73,6 +73,13 @@
 #include <net/if.h>
 #endif
 
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+#ifdef HAVE_SYS_UCRED_H
+#include <sys/ucred.h>
+#endif
+
 #ifndef EWOULDBLOCK
 #define EWOULDBLOCK EAGAIN
 #endif
Index: ext/socket/option.c
===================================================================
--- ext/socket/option.c	(revision 22136)
+++ ext/socket/option.c	(revision 22137)
@@ -256,6 +256,32 @@
 }
 #endif
 
+#if defined(LOCAL_PEERCRED) /* FreeBSD */
+static int
+inspect_local_peercred(int level, int optname, VALUE data, VALUE ret)
+{
+    if (RSTRING_LEN(data) == sizeof(struct xucred)) {
+        struct xucred cred;
+        memcpy(&cred, RSTRING_PTR(data), sizeof(struct xucred));
+        rb_str_catf(ret, " version=%u", cred.cr_version);
+        rb_str_catf(ret, " uid=%u", cred.cr_uid);
+	if (cred.cr_ngroups) {
+	    int i;
+	    char *sep = " groups=";
+	    for (i = 0; i < cred.cr_ngroups; i++) {
+		rb_str_catf(ret, "%s%u", sep, cred.cr_groups[i]);
+		sep = ",";
+	    }
+	}
+        rb_str_cat2(ret, " (xucred)");
+        return 0;
+    }
+    else {
+        return -1;
+    }
+}
+#endif
+
 static VALUE
 sockopt_inspect(VALUE self)
 {
@@ -264,7 +290,7 @@
     int optname = NUM2INT(sockopt_optname(self));
     VALUE data = sockopt_data(self);
     VALUE v, ret;
-    ID family_id, level_id;
+    ID family_id, level_id, optname_id;
 
     StringValue(data);
 
@@ -276,18 +302,36 @@
     else
         rb_str_catf(ret, "family:%d", family);
 
-    level_id = intern_level(level);
-    if (level_id)
-        rb_str_catf(ret, " %s", rb_id2name(level_id));
-    else
-        rb_str_catf(ret, " level:%d", level);
+    if (family == AF_UNIX && level == 0) {
+	rb_str_catf(ret, " level:%d", level);
 
-    v = optname_to_sym(level, optname);
-    if (SYMBOL_P(v))
-        rb_str_catf(ret, " %s", rb_id2name(SYM2ID(v)));
-    else
-        rb_str_catf(ret, " optname:%d", optname);
+	optname_id = intern_local_optname(optname);
+	if (optname_id)
+	    rb_str_catf(ret, " %s", rb_id2name(optname_id));
+	else
+	    rb_str_catf(ret, " optname:%d", optname);
+    }
+    else {
+	level_id = intern_level(level);
+	if (level_id)
+	    rb_str_catf(ret, " %s", rb_id2name(level_id));
+	else
+	    rb_str_catf(ret, " level:%d", level);
 
+	v = optname_to_sym(level, optname);
+	if (SYMBOL_P(v))
+	    rb_str_catf(ret, " %s", rb_id2name(SYM2ID(v)));
+	else
+	    rb_str_catf(ret, " optname:%d", optname);
+    }
+
+    if (family == AF_UNIX && level == 0) {
+	if (optname == LOCAL_PEERCRED) {
+	    if (inspect_local_peercred(level, optname, data, ret) == -1) goto dump;
+	    goto finish;
+	}
+    }
+
     switch (level) {
 #    if defined(SOL_SOCKET)
       case SOL_SOCKET:
@@ -391,6 +435,7 @@
         rb_str_catf(ret, " %s", StringValueCStr(data));
     }
 
+  finish:
     rb_str_cat2(ret, ">");
 
     return ret;
Index: ext/socket/mkconstants.rb
===================================================================
--- ext/socket/mkconstants.rb	(revision 22136)
+++ ext/socket/mkconstants.rb	(revision 22137)
@@ -262,6 +262,7 @@
 def_intern('intern_tcp_optname',  /\ATCP_/, "TCP_")
 def_intern('intern_udp_optname',  /\AUDP_/, "UDP_")
 def_intern('intern_scm_optname',  /\ASCM_/, "SCM_")
+def_intern('intern_local_optname',  /\ALOCAL_/, "LOCAL_")
 
 result = ERB.new(<<'EOS', nil, '%').result(binding)
 /* autogenerated file */
Index: ext/socket/extconf.rb
===================================================================
--- ext/socket/extconf.rb	(revision 22136)
+++ ext/socket/extconf.rb	(revision 22137)
@@ -293,6 +293,9 @@
 have_header("sys/sockio.h")
 have_header("net/if.h", headers)
 
+have_header("sys/param.h", headers)
+have_header("sys/ucred.h", headers)
+
 unless have_type("socklen_t", headers)
   $defs << "-Dsocklen_t=int"
 end
Index: test/socket/test_unix.rb
===================================================================
--- test/socket/test_unix.rb	(revision 22136)
+++ test/socket/test_unix.rb	(revision 22137)
@@ -312,6 +312,20 @@
     }
   end
 
+  def test_getcred_xucred
+    return if /freebsd/ !~ RUBY_PLATFORM
+    Dir.mktmpdir {|d|
+      sockpath = "#{d}/sock"
+      serv = Socket.unix_server_socket(sockpath)
+      c = Socket.unix(sockpath)
+      s, = serv.accept
+      cred = s.getsockopt(0, Socket::LOCAL_PEERCRED)
+      inspect = cred.inspect
+      assert_match(/ uid=#{Process.uid} /, inspect)
+      assert_match(/ \(xucred\)/, inspect)
+    }
+  end
+
   def test_sendcred_ucred
     return if /linux/ !~ RUBY_PLATFORM
     Dir.mktmpdir {|d|

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

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