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

ruby-changes:10573

From: akr <ko1@a...>
Date: Sun, 8 Feb 2009 21:56:04 +0900 (JST)
Subject: [ruby-changes:10573] Ruby:r22129 (trunk): * ext/socket/extconf.rb: check struct cmsgcred.

akr	2009-02-08 21:53:55 +0900 (Sun, 08 Feb 2009)

  New Revision: 22129

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

  Log:
    * ext/socket/extconf.rb: check struct cmsgcred.
    * ext/socket/ancdata.c (anc_inspect_passcred_credentials): add
      "(ucred)".
      (anc_inspect_socket_creds): show struct cmsgcred too, for FreeBSD.

  Modified files:
    trunk/ChangeLog
    trunk/ext/socket/ancdata.c
    trunk/ext/socket/extconf.rb
    trunk/test/socket/test_unix.rb

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 22128)
+++ ChangeLog	(revision 22129)
@@ -1,3 +1,11 @@
+Sun Feb  8 21:47:50 2009  Tanaka Akira  <akr@f...>
+
+	* ext/socket/extconf.rb: check struct cmsgcred.
+
+	* ext/socket/ancdata.c (anc_inspect_passcred_credentials): add
+	  "(ucred)".
+	  (anc_inspect_socket_creds): show struct cmsgcred too, for FreeBSD.
+
 Sun Feb  8 21:05:35 2009  Tanaka Akira  <akr@f...>
 
 	* lib/drb/extservm.rb (DRb::ExtServManager#invoke_service_command):
Index: ext/socket/extconf.rb
===================================================================
--- ext/socket/extconf.rb	(revision 22128)
+++ ext/socket/extconf.rb	(revision 22129)
@@ -309,6 +309,7 @@
 }
 
 have_type("struct sockcred", headers)
+have_type("struct cmsgcred", headers)
 
 $distcleanfiles << "constants.h" << "constdefs.*"
 
Index: ext/socket/ancdata.c
===================================================================
--- ext/socket/ancdata.c	(revision 22128)
+++ ext/socket/ancdata.c	(revision 22129)
@@ -385,6 +385,7 @@
         struct ucred cred;
         memcpy(&cred, RSTRING_PTR(data), sizeof(struct ucred));
         rb_str_catf(ret, " pid=%u uid=%u gid=%u", cred.pid, cred.uid, cred.gid);
+	rb_str_cat2(ret, " (ucred)");
         return 0;
     }
     else {
@@ -393,38 +394,71 @@
 }
 #endif
 
-#if defined(SCM_CREDS) && defined(HAVE_TYPE_STRUCT_SOCKCRED) /* NetBSD */
+#if defined(SCM_CREDS)
 #define INSPECT_SCM_CREDS
 static int
 anc_inspect_socket_creds(int level, int type, VALUE data, VALUE ret)
 {
     int i;
-    if (level == SOL_SOCKET && type == SCM_CREDS &&
-        RSTRING_LEN(data) >= SOCKCREDSIZE(0)) {
-	struct sockcred cred0, *cred;
-        memcpy(&cred0, RSTRING_PTR(data), SOCKCREDSIZE(0));
-	if (RSTRING_LEN(data) != SOCKCREDSIZE(cred0.sc_ngroups)) {
-	    return -1;
-	}
-	cred = (struct sockcred *)ALLOCA_N(char, SOCKCREDSIZE(cred0.sc_ngroups));
-        memcpy(cred, RSTRING_PTR(data), SOCKCREDSIZE(cred0.sc_ngroups));
-        rb_str_catf(ret, " uid=%u", cred->sc_uid);
-        rb_str_catf(ret, " euid=%u", cred->sc_euid);
-        rb_str_catf(ret, " gid=%u", cred->sc_gid);
-        rb_str_catf(ret, " egid=%u", cred->sc_egid);
-	if (cred0.sc_ngroups) {
+    if (level != SOL_SOCKET && type != SCM_CREDS)
+	return -1;
+
+    /*
+     * FreeBSD has struct cmsgcred and struct sockcred.
+     * They use both SOL_SOCKET/SCM_CREDS in the ancillary message.
+     * They are not ambiguous from the view of the caller
+     * because struct sockcred is sent if and only if the caller sets LOCAL_CREDS socket option.
+     * But inspect method doesn't know it.
+     * So they are ambiguous from the view of inspect.
+     * This function distinguish them by the size of the ancillary message.
+     * This heuristics works well except when sc_ngroups == CMGROUP_MAX.
+     */
+
+#if defined(HAVE_TYPE_STRUCT_CMSGCRED) /* FreeBSD */
+    if (RSTRING_LEN(data) == sizeof(struct cmsgcred)) {
+	struct cmsgcred cred;
+        memcpy(&cred, RSTRING_PTR(data), sizeof(struct cmsgcred));
+        rb_str_catf(ret, " pid=%u", cred.cmcred_pid);
+        rb_str_catf(ret, " uid=%u", cred.cmcred_uid);
+        rb_str_catf(ret, " euid=%u", cred.cmcred_euid);
+        rb_str_catf(ret, " gid=%u", cred.cmcred_gid);
+	if (cred.cmcred_ngroups) {
 	    char *sep = "=";
             rb_str_cat2(ret, " groups");
-	    for (i = 0; i < cred0.sc_ngroups; i++) {
-		rb_str_catf(ret, "%s%u", sep, cred->sc_groups[i]);
+	    for (i = 0; i < cred.cmcred_ngroups; i++) {
+		rb_str_catf(ret, "%s%u", sep, cred.cmcred_groups[i]);
 		sep = ",";
 	    }
 	}
+	rb_str_cat2(ret, " (cmsgcred)");
         return 0;
     }
-    else {
-        return -1;
+#endif
+#if defined(HAVE_TYPE_STRUCT_SOCKCRED) /* FreeBSD, NetBSD */
+    if (RSTRING_LEN(data) >= SOCKCREDSIZE(0)) {
+	struct sockcred cred0, *cred;
+        memcpy(&cred0, RSTRING_PTR(data), SOCKCREDSIZE(0));
+	if (RSTRING_LEN(data) == SOCKCREDSIZE(cred0.sc_ngroups)) {
+	    cred = (struct sockcred *)ALLOCA_N(char, SOCKCREDSIZE(cred0.sc_ngroups));
+	    memcpy(cred, RSTRING_PTR(data), SOCKCREDSIZE(cred0.sc_ngroups));
+	    rb_str_catf(ret, " uid=%u", cred->sc_uid);
+	    rb_str_catf(ret, " euid=%u", cred->sc_euid);
+	    rb_str_catf(ret, " gid=%u", cred->sc_gid);
+	    rb_str_catf(ret, " egid=%u", cred->sc_egid);
+	    if (cred0.sc_ngroups) {
+		char *sep = "=";
+		rb_str_cat2(ret, " groups");
+		for (i = 0; i < cred0.sc_ngroups; i++) {
+		    rb_str_catf(ret, "%s%u", sep, cred->sc_groups[i]);
+		    sep = ",";
+		}
+	    }
+	    rb_str_cat2(ret, " (sockcred)");
+	    return 0;
+	}
     }
+#endif
+    return -1;
 }
 #endif
 
Index: test/socket/test_unix.rb
===================================================================
--- test/socket/test_unix.rb	(revision 22128)
+++ test/socket/test_unix.rb	(revision 22129)
@@ -296,7 +296,7 @@
     }
   end
 
-  def test_cred_linux
+  def test_cred_ucred
     return if /linux/ !~ RUBY_PLATFORM
     Dir.mktmpdir {|d|
       sockpath = "#{d}/sock"
@@ -306,15 +306,17 @@
       s.setsockopt(:SOCKET, :PASSCRED, 1)
       c.print "a"
       msg, cliend_ai, rflags, cred = s.recvmsg
+      inspect = cred.inspect
       assert_equal("a", msg)
-      assert_match(/ pid=#{$$} /, cred.inspect)
-      assert_match(/ uid=#{Process.uid} /, cred.inspect)
-      assert_match(/ gid=#{Process.gid}>/, cred.inspect)
+      assert_match(/ pid=#{$$} /, inspect)
+      assert_match(/ uid=#{Process.uid} /, inspect)
+      assert_match(/ gid=#{Process.gid}>/, inspect)
+      assert_match(/ \(ucred\)/, inspect)
     }
   end
 
-  def test_cred_netbsd
-    return if /netbsd/ !~ RUBY_PLATFORM
+  def test_cred_sockcred
+    return if /netbsd|freebsd/ !~ RUBY_PLATFORM
     Dir.mktmpdir {|d|
       sockpath = "#{d}/sock"
       serv = Socket.unix_server_socket(sockpath)
@@ -324,11 +326,34 @@
       c.print "a"
       msg, cliend_ai, rflags, cred = s.recvmsg
       assert_equal("a", msg)
-      assert_match(/ uid=#{Process.uid} /, cred.inspect)
-      assert_match(/ euid=#{Process.euid} /, cred.inspect)
-      assert_match(/ gid=#{Process.gid} /, cred.inspect)
-      assert_match(/ egid=#{Process.egid} /, cred.inspect)
+      inspect = cred.inspect
+      p inspect
+      assert_match(/ uid=#{Process.uid} /, inspect)
+      assert_match(/ euid=#{Process.euid} /, inspect)
+      assert_match(/ gid=#{Process.gid} /, inspect)
+      assert_match(/ egid=#{Process.egid} /, inspect)
+      assert_match(/ \(sockcred\)/, inspect)
     }
   end
 
+  def test_cred_cmsgcred
+    return if /freebsd/ !~ RUBY_PLATFORM
+    Dir.mktmpdir {|d|
+      sockpath = "#{d}/sock"
+      serv = Socket.unix_server_socket(sockpath)
+      c = Socket.unix(sockpath)
+      s, = serv.accept
+      c.sendmsg("a", 0, nil, [:SOCKET, Socket::SCM_CREDS, ""])      
+      msg, cliend_ai, rflags, cred = s.recvmsg
+      assert_equal("a", msg)
+      inspect = cred.inspect
+      p inspect
+      assert_match(/ pid=#{$$} /, inspect)
+      assert_match(/ uid=#{Process.uid} /, inspect)
+      assert_match(/ euid=#{Process.euid} /, inspect)
+      assert_match(/ gid=#{Process.gid} /, inspect)
+      assert_match(/ \(cmsgcred\)/, inspect)
+    }
+  end
+
 end if defined?(UNIXSocket) && /cygwin/ !~ RUBY_PLATFORM

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

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