(adapted from http://achurch.org/patch-pile/).
- resizing the window with the scrollbar disabled via the escapes
sequence could make the window bigger again (Mikachu).
+ - make sure the alignment for fd passing control messages
+ is correct and work around some NetBSD issues (Taylor R Campbell).
+ - update to libptytty 1.3.
9.06 Sat Nov 8 17:47:18 CET 2008
- NOTICE: this release updates terminfo/termcap.
#include "../config.h"
#include <cstddef> // needed by broken bsds for NULL used in sys/uio.h
+#include <cstdlib>
#include <sys/types.h>
#include <sys/uio.h>
#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;
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;
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;
}