mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* 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. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@32655 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
6b3ec75c7f
commit
f5b9de7502
3 changed files with 101 additions and 5 deletions
|
@ -1,3 +1,10 @@
|
||||||
|
Sun Jul 24 08:42:51 2011 Tanaka Akira <akr@fsij.org>
|
||||||
|
|
||||||
|
* 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@segment7.net>
|
Sun Jul 24 01:04:50 2011 Eric Hodel <drbrain@segment7.net>
|
||||||
|
|
||||||
* lib/rubygems/specification.rb: Restore behavior of
|
* lib/rubygems/specification.rb: Restore behavior of
|
||||||
|
|
|
@ -1379,12 +1379,14 @@ rb_recvmsg(int fd, struct msghdr *msg, int flags)
|
||||||
static void
|
static void
|
||||||
discard_cmsg(struct cmsghdr *cmh, char *msg_end, int msg_peek_p)
|
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]
|
* FreeBSD 8.2.0, NetBSD 5 and MacOS X Snow Leopard doesn't
|
||||||
* naruse finds FreeBSD behaves as so too and comment in kernel of FreeBSD 8.2.0. [ruby-dev:44189]
|
* allocate fds by recvmsg with MSG_PEEK.
|
||||||
* kosaki finds same comment in MacOS X Snow Leopard. [ruby-dev:44192]
|
* [ruby-dev:44189]
|
||||||
* Takahiro Kambe finds same comment since NetBSD 5. [ruby-dev:44205]
|
* http://redmine.ruby-lang.org/issues/5075
|
||||||
|
*
|
||||||
|
* Linux 2.6.38 allocate fds by recvmsg with MSG_PEEK.
|
||||||
*/
|
*/
|
||||||
if (msg_peek_p)
|
if (msg_peek_p)
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -124,6 +124,93 @@ if have_func("sendmsg") | have_func("recvmsg")
|
||||||
have_struct_member('struct msghdr', 'msg_accrights', ['sys/types.h', 'sys/socket.h'])
|
have_struct_member('struct msghdr', 'msg_accrights', ['sys/types.h', 'sys/socket.h'])
|
||||||
end
|
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) ||
|
getaddr_info_ok = (enable_config("wide-getaddrinfo") && :wide) ||
|
||||||
(checking_for("wide getaddrinfo") {try_run(<<EOF)} && :os)
|
(checking_for("wide getaddrinfo") {try_run(<<EOF)} && :os)
|
||||||
#{cpp_include(headers)}
|
#{cpp_include(headers)}
|
||||||
|
|
Loading…
Add table
Reference in a new issue