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/