--- rxvt-unicode/src/fdpass.C 2006/01/24 11:35:17 1.10 +++ rxvt-unicode/src/fdpass.C 2010/07/21 08:46:13 1.15 @@ -23,26 +23,37 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *----------------------------------------------------------------------*/ -#include "../config.h" +#include "config.h" -#include // needed by freebsd for NULL used in sys/uio.h +#include // needed by broken bsds for NULL used in sys/uio.h +#include -#include #include +#include #include #include "libptytty.h" -#ifndef CMSG_LEN // CMSG_SPACe && CMSG_LEN are rfc2292 extensions to unix +// CMSG_SPACE & CMSG_LEN are rfc2292 extensions to unix +#ifndef CMSG_SPACE +# define CMSG_SPACE(len) (sizeof (cmsghdr) + len) +#endif + +#ifndef CMSG_LEN # define CMSG_LEN(len) (sizeof (cmsghdr) + len) #endif bool ptytty::send_fd (int socket, int fd) { + void *buf = malloc (CMSG_SPACE (sizeof (int))); + + if (!buf) + return 0; + msghdr msg; iovec iov; - char buf [CMSG_LEN (sizeof (int))]; + cmsghdr *cmsg; char data = 0; iov.iov_base = &data; @@ -52,27 +63,33 @@ msg.msg_namelen = 0; msg.msg_iov = &iov; msg.msg_iovlen = 1; - msg.msg_control = (void *)buf; - msg.msg_controllen = sizeof buf; + msg.msg_control = buf; + msg.msg_controllen = CMSG_SPACE (sizeof (int)); - cmsghdr *cmsg = CMSG_FIRSTHDR (&msg); + cmsg = CMSG_FIRSTHDR (&msg); cmsg->cmsg_level = SOL_SOCKET; cmsg->cmsg_type = SCM_RIGHTS; cmsg->cmsg_len = CMSG_LEN (sizeof (int)); *(int *)CMSG_DATA (cmsg) = fd; - msg.msg_controllen = cmsg->cmsg_len; + ssize_t result = sendmsg (socket, &msg, 0); + + free (buf); - return sendmsg (socket, &msg, 0) >= 0; + return result >= 0; } int ptytty::recv_fd (int socket) { + void *buf = malloc (CMSG_SPACE (sizeof (int))); + + if (!buf) + return -1; + msghdr msg; iovec iov; - char buf [CMSG_LEN (sizeof (int))]; /* ancillary data buffer */ char data = 1; iov.iov_base = &data; @@ -83,23 +100,24 @@ msg.msg_iov = &iov; msg.msg_iovlen = 1; msg.msg_control = buf; - msg.msg_controllen = sizeof buf; + msg.msg_controllen = CMSG_SPACE (sizeof (int)); - cmsghdr *cmsg = CMSG_FIRSTHDR (&msg); - cmsg->cmsg_level = SOL_SOCKET; - cmsg->cmsg_type = SCM_RIGHTS; - cmsg->cmsg_len = CMSG_LEN (sizeof (int)); + int fd = -1; - msg.msg_controllen = cmsg->cmsg_len; + if (recvmsg (socket, &msg, 0) > 0 + && data == 0 + && msg.msg_controllen >= CMSG_SPACE (sizeof (int))) + { + cmsghdr *cmsg = CMSG_FIRSTHDR (&msg); - if (recvmsg (socket, &msg, 0) <= 0 - || data != 0 - || msg.msg_controllen < CMSG_LEN (sizeof (int)) - || cmsg->cmsg_level != SOL_SOCKET - || cmsg->cmsg_type != SCM_RIGHTS - || cmsg->cmsg_len < CMSG_LEN (sizeof (int))) - return -1; + if (cmsg->cmsg_level == SOL_SOCKET + && cmsg->cmsg_type == SCM_RIGHTS + && cmsg->cmsg_len >= CMSG_LEN (sizeof (int))) + fd = *(int *)CMSG_DATA (cmsg); + } + + free (buf); - return *(int *)CMSG_DATA (cmsg); + return fd; }