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

ruby-changes:20607

From: akr <ko1@a...>
Date: Sun, 24 Jul 2011 08:57:58 +0900 (JST)
Subject: [ruby-changes:20607] akr:r32655 (trunk, ruby_1_9_3): * ext/socket/extconf.rb: test recvmsg allocates file descriptors for

akr	2011-07-24 08:57:50 +0900 (Sun, 24 Jul 2011)

  New Revision: 32655

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

  Log:
    * ext/socket/extconf.rb: test recvmsg allocates file descriptors for
      fd passing even with MSG_PEEK.
    
    * ext/socket/ancdata.c: use the above test result.

  Modified files:
    branches/ruby_1_9_3/ChangeLog
    branches/ruby_1_9_3/ext/socket/ancdata.c
    branches/ruby_1_9_3/ext/socket/extconf.rb
    trunk/ChangeLog
    trunk/ext/socket/ancdata.c
    trunk/ext/socket/extconf.rb

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 32654)
+++ ChangeLog	(revision 32655)
@@ -1,3 +1,10 @@
+Sun Jul 24 08:42:51 2011  Tanaka Akira  <akr@f...>
+
+	* ext/socket/extconf.rb: test recvmsg allocates file descriptors for
+	  fd passing even with MSG_PEEK.
+
+	* ext/socket/ancdata.c: use the above test result.
+
 Sun Jul 24 01:04:50 2011  Eric Hodel  <drbrain@s...>
 
 	* lib/rubygems/specification.rb:  Restore behavior of
Index: ext/socket/extconf.rb
===================================================================
--- ext/socket/extconf.rb	(revision 32654)
+++ ext/socket/extconf.rb	(revision 32655)
@@ -124,6 +124,93 @@
   have_struct_member('struct msghdr', 'msg_accrights', ['sys/types.h', 'sys/socket.h'])
 end
 
+if checking_for("recvmsg() with MSG_PEEK allocate file descriptors") {try_run(<<EOF)}
+#{cpp_include(headers)}
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <unistd.h>
+
+int main(int argc, char *argv[])
+{
+    int sv[2];
+    int ret;
+    ssize_t ss;
+    int s_fd, r_fd;
+    struct msghdr s_msg, r_msg;
+    union {
+        struct cmsghdr hdr;
+        char dummy[CMSG_SPACE(sizeof(int))];
+    } s_cmsg, r_cmsg;
+    struct iovec s_iov, r_iov;
+    char s_buf[1], r_buf[1];
+    struct stat statbuf;
+
+    s_fd = 0; /* stdin */
+
+    ret = socketpair(AF_UNIX, SOCK_DGRAM, 0, sv);
+    if (ret == -1) { perror("socketpair"); exit(EXIT_FAILURE); }
+
+    s_msg.msg_name = NULL;
+    s_msg.msg_namelen = 0;
+    s_msg.msg_iov = &s_iov;
+    s_msg.msg_iovlen = 1;
+    s_msg.msg_control = &s_cmsg;
+    s_msg.msg_controllen = CMSG_SPACE(sizeof(int));;
+    s_msg.msg_flags = 0;
+
+    s_iov.iov_base = &s_buf;
+    s_iov.iov_len = sizeof(s_buf);
+
+    s_buf[0] = 'a';
+
+    s_cmsg.hdr.cmsg_len = CMSG_LEN(sizeof(int));
+    s_cmsg.hdr.cmsg_level = SOL_SOCKET;
+    s_cmsg.hdr.cmsg_type = SCM_RIGHTS;
+    memcpy(CMSG_DATA(&s_cmsg.hdr), (char *)&s_fd, sizeof(int));
+
+    ss = sendmsg(sv[0], &s_msg, 0);
+    if (ss == -1) { perror("sendmsg"); exit(EXIT_FAILURE); }
+
+    r_msg.msg_name = NULL;
+    r_msg.msg_namelen = 0;
+    r_msg.msg_iov = &r_iov;
+    r_msg.msg_iovlen = 1;
+    r_msg.msg_control = &r_cmsg;
+    r_msg.msg_controllen = CMSG_SPACE(sizeof(int));
+    r_msg.msg_flags = 0;
+
+    r_iov.iov_base = &r_buf;
+    r_iov.iov_len = sizeof(r_buf);
+
+    r_buf[0] = '0';
+
+    memset(&r_cmsg, 0xff, CMSG_SPACE(sizeof(int)));
+
+    ss = recvmsg(sv[1], &r_msg, MSG_PEEK);
+    if (ss == -1) { perror("recvmsg"); exit(EXIT_FAILURE); }
+
+    if (ss != 1) { exit(EXIT_FAILURE); }
+    if (r_buf[0] != 'a') { exit(EXIT_FAILURE); }
+
+    if (r_msg.msg_controllen < CMSG_LEN(sizeof(int))) exit(EXIT_FAILURE);
+    if (r_cmsg.hdr.cmsg_len < CMSG_LEN(sizeof(int))) exit(EXIT_FAILURE);
+    memcpy((char *)&r_fd, CMSG_DATA(&s_cmsg.hdr), sizeof(int));
+
+    if (r_fd < 0) exit(EXIT_FAILURE);
+
+    ret = fstat(r_fd, &statbuf);
+    if (ret == -1) { exit(EXIT_FAILURE); }
+
+    return EXIT_SUCCESS;
+}
+EOF
+  $defs << "-DFD_PASSING_WORK_WITH_RECVMSG_MSG_PEEK"
+end
+
 getaddr_info_ok = (enable_config("wide-getaddrinfo") && :wide) ||
   (checking_for("wide getaddrinfo") {try_run(<<EOF)} && :os)
 #{cpp_include(headers)}
Index: ext/socket/ancdata.c
===================================================================
--- ext/socket/ancdata.c	(revision 32654)
+++ ext/socket/ancdata.c	(revision 32655)
@@ -1379,12 +1379,14 @@
 static void
 discard_cmsg(struct cmsghdr *cmh, char *msg_end, int msg_peek_p)
 {
-# if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__APPLE__)
+# if !defined(FD_PASSING_WORK_WITH_RECVMSG_MSG_PEEK)
     /* 
-     * nagachika finds recvmsg with MSG_PEEK doesn't return fds on MacOS X Snow Leopard. [ruby-dev:44209]
-     * naruse finds FreeBSD behaves as so too and comment in kernel of FreeBSD 8.2.0. [ruby-dev:44189]
-     * kosaki finds same comment in MacOS X Snow Leopard.  [ruby-dev:44192]
-     * Takahiro Kambe finds same comment since NetBSD 5. [ruby-dev:44205]
+     * FreeBSD 8.2.0, NetBSD 5 and MacOS X Snow Leopard doesn't
+     * allocate fds by recvmsg with MSG_PEEK.
+     * [ruby-dev:44189]
+     * http://redmine.ruby-lang.org/issues/5075
+     *
+     * Linux 2.6.38 allocate fds by recvmsg with MSG_PEEK.
      */
     if (msg_peek_p)
         return;
Index: ruby_1_9_3/ChangeLog
===================================================================
--- ruby_1_9_3/ChangeLog	(revision 32654)
+++ ruby_1_9_3/ChangeLog	(revision 32655)
@@ -1,3 +1,10 @@
+Sun Jul 24 08:42:51 2011  Tanaka Akira  <akr@f...>
+
+	* ext/socket/extconf.rb: test recvmsg allocates file descriptors for
+	  fd passing even with MSG_PEEK.
+
+	* ext/socket/ancdata.c: use the above test result.
+
 Sun Jul 24 01:24:31 2011  Eric Hodel  <drbrain@s...>
 
 	* lib/rubygems/specification.rb:  Restore behavior of
Index: ruby_1_9_3/ext/socket/extconf.rb
===================================================================
--- ruby_1_9_3/ext/socket/extconf.rb	(revision 32654)
+++ ruby_1_9_3/ext/socket/extconf.rb	(revision 32655)
@@ -124,6 +124,93 @@
   have_struct_member('struct msghdr', 'msg_accrights', ['sys/types.h', 'sys/socket.h'])
 end
 
+if checking_for("recvmsg() with MSG_PEEK allocate file descriptors") {try_run(<<EOF)}
+#{cpp_include(headers)}
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <unistd.h>
+
+int main(int argc, char *argv[])
+{
+    int sv[2];
+    int ret;
+    ssize_t ss;
+    int s_fd, r_fd;
+    struct msghdr s_msg, r_msg;
+    union {
+        struct cmsghdr hdr;
+        char dummy[CMSG_SPACE(sizeof(int))];
+    } s_cmsg, r_cmsg;
+    struct iovec s_iov, r_iov;
+    char s_buf[1], r_buf[1];
+    struct stat statbuf;
+
+    s_fd = 0; /* stdin */
+
+    ret = socketpair(AF_UNIX, SOCK_DGRAM, 0, sv);
+    if (ret == -1) { perror("socketpair"); exit(EXIT_FAILURE); }
+
+    s_msg.msg_name = NULL;
+    s_msg.msg_namelen = 0;
+    s_msg.msg_iov = &s_iov;
+    s_msg.msg_iovlen = 1;
+    s_msg.msg_control = &s_cmsg;
+    s_msg.msg_controllen = CMSG_SPACE(sizeof(int));;
+    s_msg.msg_flags = 0;
+
+    s_iov.iov_base = &s_buf;
+    s_iov.iov_len = sizeof(s_buf);
+
+    s_buf[0] = 'a';
+
+    s_cmsg.hdr.cmsg_len = CMSG_LEN(sizeof(int));
+    s_cmsg.hdr.cmsg_level = SOL_SOCKET;
+    s_cmsg.hdr.cmsg_type = SCM_RIGHTS;
+    memcpy(CMSG_DATA(&s_cmsg.hdr), (char *)&s_fd, sizeof(int));
+
+    ss = sendmsg(sv[0], &s_msg, 0);
+    if (ss == -1) { perror("sendmsg"); exit(EXIT_FAILURE); }
+
+    r_msg.msg_name = NULL;
+    r_msg.msg_namelen = 0;
+    r_msg.msg_iov = &r_iov;
+    r_msg.msg_iovlen = 1;
+    r_msg.msg_control = &r_cmsg;
+    r_msg.msg_controllen = CMSG_SPACE(sizeof(int));
+    r_msg.msg_flags = 0;
+
+    r_iov.iov_base = &r_buf;
+    r_iov.iov_len = sizeof(r_buf);
+
+    r_buf[0] = '0';
+
+    memset(&r_cmsg, 0xff, CMSG_SPACE(sizeof(int)));
+
+    ss = recvmsg(sv[1], &r_msg, MSG_PEEK);
+    if (ss == -1) { perror("recvmsg"); exit(EXIT_FAILURE); }
+
+    if (ss != 1) { exit(EXIT_FAILURE); }
+    if (r_buf[0] != 'a') { exit(EXIT_FAILURE); }
+
+    if (r_msg.msg_controllen < CMSG_LEN(sizeof(int))) exit(EXIT_FAILURE);
+    if (r_cmsg.hdr.cmsg_len < CMSG_LEN(sizeof(int))) exit(EXIT_FAILURE);
+    memcpy((char *)&r_fd, CMSG_DATA(&s_cmsg.hdr), sizeof(int));
+
+    if (r_fd < 0) exit(EXIT_FAILURE);
+
+    ret = fstat(r_fd, &statbuf);
+    if (ret == -1) { exit(EXIT_FAILURE); }
+
+    return EXIT_SUCCESS;
+}
+EOF
+  $defs << "-DFD_PASSING_WORK_WITH_RECVMSG_MSG_PEEK"
+end
+
 getaddr_info_ok = (enable_config("wide-getaddrinfo") && :wide) ||
   (checking_for("wide getaddrinfo") {try_run(<<EOF)} && :os)
 #{cpp_include(headers)}
Index: ruby_1_9_3/ext/socket/ancdata.c
===================================================================
--- ruby_1_9_3/ext/socket/ancdata.c	(revision 32654)
+++ ruby_1_9_3/ext/socket/ancdata.c	(revision 32655)
@@ -1379,12 +1379,14 @@
 static void
 discard_cmsg(struct cmsghdr *cmh, char *msg_end, int msg_peek_p)
 {
-# if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__APPLE__)
+# if !defined(FD_PASSING_WORK_WITH_RECVMSG_MSG_PEEK)
     /* 
-     * nagachika finds recvmsg with MSG_PEEK doesn't return fds on MacOS X Snow Leopard. [ruby-dev:44209]
-     * naruse finds FreeBSD behaves as so too and comment in kernel of FreeBSD 8.2.0. [ruby-dev:44189]
-     * kosaki finds same comment in MacOS X Snow Leopard.  [ruby-dev:44192]
-     * Takahiro Kambe finds same comment since NetBSD 5. [ruby-dev:44205]
+     * FreeBSD 8.2.0, NetBSD 5 and MacOS X Snow Leopard doesn't
+     * allocate fds by recvmsg with MSG_PEEK.
+     * [ruby-dev:44189]
+     * http://redmine.ruby-lang.org/issues/5075
+     *
+     * Linux 2.6.38 allocate fds by recvmsg with MSG_PEEK.
      */
     if (msg_peek_p)
         return;

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

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