out the definition of a new function added in the patch. Allows usage of the ruby 1.8 socket extension with LD_BIND_NOW=1. OK naddy@
81 lines
3.0 KiB
Plaintext
81 lines
3.0 KiB
Plaintext
$OpenBSD: patch-ext_socket_socket_c,v 1.2 2012/09/18 16:02:53 jeremy Exp $
|
|
|
|
Fix UnixSocket#recv_io on 64-bit archs, backported from ruby SVN
|
|
revisions 22141 and 22633.
|
|
|
|
--- ext/socket/socket.c.orig Fri May 20 15:25:41 2011
|
|
+++ ext/socket/socket.c Mon Sep 17 14:10:31 2012
|
|
@@ -2027,6 +2027,28 @@ unix_send_io(sock, val)
|
|
#endif
|
|
}
|
|
|
|
+#if defined(HAVE_RECVMSG) && FD_PASSING_BY_MSG_CONTROL
|
|
+void
|
|
+rsock_discard_cmsg_resource(struct msghdr *mh)
|
|
+{
|
|
+ struct cmsghdr *cmh;
|
|
+
|
|
+ if (mh->msg_controllen == 0)
|
|
+ return;
|
|
+
|
|
+ for (cmh = CMSG_FIRSTHDR(mh); cmh != NULL; cmh = CMSG_NXTHDR(mh, cmh)) {
|
|
+ if (cmh->cmsg_level == SOL_SOCKET && cmh->cmsg_type == SCM_RIGHTS) {
|
|
+ int *fdp = (int *)CMSG_DATA(cmh);
|
|
+ int *end = (int *)((char *)cmh + cmh->cmsg_len);
|
|
+ while (fdp < end) {
|
|
+ close(*fdp);
|
|
+ fdp++;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+}
|
|
+#endif
|
|
+
|
|
#if defined(HAVE_RECVMSG) && (FD_PASSING_BY_MSG_CONTROL || FD_PASSING_BY_MSG_ACCRIGHTS)
|
|
static void
|
|
thread_read_select(fd)
|
|
@@ -2097,16 +2119,11 @@ unix_recv_io(argc, argv, sock)
|
|
rb_sys_fail("recvmsg(2)");
|
|
|
|
#if FD_PASSING_BY_MSG_CONTROL
|
|
- if (msg.msg_controllen != CMSG_SPACE(sizeof(int))) {
|
|
- rb_raise(rb_eSocket,
|
|
- "file descriptor was not passed (msg_controllen=%d, %d expected)",
|
|
- msg.msg_controllen, CMSG_SPACE(sizeof(int)));
|
|
+ if (msg.msg_controllen < sizeof(struct cmsghdr)) {
|
|
+ rb_raise(rb_eSocket,
|
|
+ "file descriptor was not passed (msg_controllen=%d smaller than sizeof(struct cmsghdr)=%d)",
|
|
+ (int)msg.msg_controllen, (int)sizeof(struct cmsghdr));
|
|
}
|
|
- if (cmsg.hdr.cmsg_len != CMSG_LEN(sizeof(int))) {
|
|
- rb_raise(rb_eSocket,
|
|
- "file descriptor was not passed (cmsg_len=%d, %d expected)",
|
|
- cmsg.hdr.cmsg_len, CMSG_LEN(sizeof(int)));
|
|
- }
|
|
if (cmsg.hdr.cmsg_level != SOL_SOCKET) {
|
|
rb_raise(rb_eSocket,
|
|
"file descriptor was not passed (cmsg_level=%d, %d expected)",
|
|
@@ -2116,6 +2133,22 @@ unix_recv_io(argc, argv, sock)
|
|
rb_raise(rb_eSocket,
|
|
"file descriptor was not passed (cmsg_type=%d, %d expected)",
|
|
cmsg.hdr.cmsg_type, SCM_RIGHTS);
|
|
+ }
|
|
+ if (msg.msg_controllen < CMSG_LEN(sizeof(int))) {
|
|
+ rb_raise(rb_eSocket,
|
|
+ "file descriptor was not passed (msg_controllen=%d smaller than CMSG_LEN(sizeof(int))=%d)",
|
|
+ (int)msg.msg_controllen, (int)CMSG_LEN(sizeof(int)));
|
|
+ }
|
|
+ if (CMSG_SPACE(sizeof(int)) < msg.msg_controllen) {
|
|
+ rb_raise(rb_eSocket,
|
|
+ "file descriptor was not passed (msg_controllen=%d bigger than CMSG_SPACE(sizeof(int))=%d)",
|
|
+ (int)msg.msg_controllen, (int)CMSG_SPACE(sizeof(int)));
|
|
+ }
|
|
+ if (cmsg.hdr.cmsg_len != CMSG_LEN(sizeof(int))) {
|
|
+ rsock_discard_cmsg_resource(&msg);
|
|
+ rb_raise(rb_eSocket,
|
|
+ "file descriptor was not passed (cmsg_len=%d, %d expected)",
|
|
+ (int)cmsg.hdr.cmsg_len, (int)CMSG_LEN(sizeof(int)));
|
|
}
|
|
#else
|
|
if (msg.msg_accrightslen != sizeof(fd)) {
|