openbsd-ports/lang/ruby/1.8/patches/patch-ext_socket_socket_c
jeremy ccb66ed2cc Fix a backport of a patch that never made it to ruby 1.8.7, which left
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@
2012-09-18 16:02:53 +00:00

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)) {