aboutsummaryrefslogtreecommitdiff
path: root/X11/xtrans/Xtranssock.c
diff options
context:
space:
mode:
Diffstat (limited to 'X11/xtrans/Xtranssock.c')
-rwxr-xr-xX11/xtrans/Xtranssock.c138
1 files changed, 98 insertions, 40 deletions
diff --git a/X11/xtrans/Xtranssock.c b/X11/xtrans/Xtranssock.c
index adae5769c..b07b10b73 100755
--- a/X11/xtrans/Xtranssock.c
+++ b/X11/xtrans/Xtranssock.c
@@ -2200,6 +2200,20 @@ TRANS(SocketSendFd) (XtransConnInfo ciptr, int fd, int do_close)
return 0;
}
+static int
+TRANS(SocketRecvFdInvalid)(XtransConnInfo ciptr)
+{
+ errno = EINVAL;
+ return -1;
+}
+
+static int
+TRANS(SocketSendFdInvalid)(XtransConnInfo ciptr, int fd, int do_close)
+{
+ errno = EINVAL;
+ return -1;
+}
+
#define MAX_FDS 128
struct fd_pass {
@@ -2226,20 +2240,6 @@ static inline void init_msg_send(struct msghdr *msg, struct iovec *iov, int niov
#endif /* XTRANS_SEND_FDS */
static int
-TRANS(SocketRecvFdInvalid)(XtransConnInfo ciptr)
-{
- errno = EINVAL;
- return -1;
-}
-
-static int
-TRANS(SocketSendFdInvalid)(XtransConnInfo ciptr, int fd, int do_close)
-{
- errno = EINVAL;
- return -1;
-}
-
-static int
TRANS(SocketRead) (XtransConnInfo ciptr, char *buf, int size)
{
@@ -2256,26 +2256,33 @@ TRANS(SocketRead) (XtransConnInfo ciptr, char *buf, int size)
#else
#if XTRANS_SEND_FDS
{
- struct msghdr msg;
- struct iovec iov;
- struct fd_pass pass;
+ struct iovec iov = {
+ .iov_base = buf,
+ .iov_len = size
+ };
+ char cmsgbuf[CMSG_SPACE(sizeof(int) * MAX_FDS)];
+ struct msghdr msg = {
+ .msg_name = NULL,
+ .msg_namelen = 0,
+ .msg_iov = &iov,
+ .msg_iovlen = 1,
+ .msg_control = cmsgbuf,
+ .msg_controllen = CMSG_LEN(MAX_FDS * sizeof(int))
+ };
- iov.iov_base = buf;
- iov.iov_len = size;
-
- init_msg_recv(&msg, &iov, 1, &pass, MAX_FDS);
size = recvmsg(ciptr->fd, &msg, 0);
- if (size >= 0 && msg.msg_controllen > sizeof (struct cmsghdr)) {
- if (pass.cmsghdr.cmsg_level == SOL_SOCKET &&
- pass.cmsghdr.cmsg_type == SCM_RIGHTS &&
- !((msg.msg_flags & MSG_TRUNC) ||
- (msg.msg_flags & MSG_CTRUNC)))
- {
- int nfd = (msg.msg_controllen - sizeof (struct cmsghdr)) / sizeof (int);
- int *fd = (int *) CMSG_DATA(&pass.cmsghdr);
- int i;
- for (i = 0; i < nfd; i++)
- appendFd(&ciptr->recv_fds, fd[i], 0);
+ if (size >= 0) {
+ struct cmsghdr *hdr;
+
+ for (hdr = CMSG_FIRSTHDR(&msg); hdr; hdr = CMSG_NXTHDR(&msg, hdr)) {
+ if (hdr->cmsg_level == SOL_SOCKET && hdr->cmsg_type == SCM_RIGHTS) {
+ int nfd = (hdr->cmsg_len - CMSG_LEN(0)) / sizeof (int);
+ int i;
+ int *fd = (int *) CMSG_DATA(hdr);
+
+ for (i = 0; i < nfd; i++)
+ appendFd(&ciptr->recv_fds, fd[i], 0);
+ }
}
}
return size;
@@ -2292,7 +2299,38 @@ TRANS(SocketReadv) (XtransConnInfo ciptr, struct iovec *buf, int size)
{
prmsg (2,"SocketReadv(%d,%p,%d)\n", ciptr->fd, buf, size);
+#if XTRANS_SEND_FDS
+ {
+ char cmsgbuf[CMSG_SPACE(sizeof(int) * MAX_FDS)];
+ struct msghdr msg = {
+ .msg_name = NULL,
+ .msg_namelen = 0,
+ .msg_iov = buf,
+ .msg_iovlen = size,
+ .msg_control = cmsgbuf,
+ .msg_controllen = CMSG_LEN(MAX_FDS * sizeof(int))
+ };
+
+ size = recvmsg(ciptr->fd, &msg, 0);
+ if (size >= 0) {
+ struct cmsghdr *hdr;
+
+ for (hdr = CMSG_FIRSTHDR(&msg); hdr; hdr = CMSG_NXTHDR(&msg, hdr)) {
+ if (hdr->cmsg_level == SOL_SOCKET && hdr->cmsg_type == SCM_RIGHTS) {
+ int nfd = (hdr->cmsg_len - CMSG_LEN(0)) / sizeof (int);
+ int i;
+ int *fd = (int *) CMSG_DATA(hdr);
+
+ for (i = 0; i < nfd; i++)
+ appendFd(&ciptr->recv_fds, fd[i], 0);
+ }
+ }
+ }
+ return size;
+ }
+#else
return READV (ciptr, buf, size);
+#endif
}
@@ -2305,22 +2343,32 @@ TRANS(SocketWritev) (XtransConnInfo ciptr, struct iovec *buf, int size)
#if XTRANS_SEND_FDS
if (ciptr->send_fds)
{
- struct msghdr msg;
- struct fd_pass pass;
- int nfd;
- struct _XtransConnFd *cf;
+ char cmsgbuf[CMSG_SPACE(sizeof(int) * MAX_FDS)];
+ int nfd = nFd(&ciptr->send_fds);
+ struct _XtransConnFd *cf = ciptr->send_fds;
+ struct msghdr msg = {
+ .msg_name = NULL,
+ .msg_namelen = 0,
+ .msg_iov = buf,
+ .msg_iovlen = size,
+ .msg_control = cmsgbuf,
+ .msg_controllen = CMSG_LEN(nfd * sizeof(int))
+ };
+ struct cmsghdr *hdr = CMSG_FIRSTHDR(&msg);
int i;
+ int *fds;
- nfd = nFd(&ciptr->send_fds);
- cf = ciptr->send_fds;
+ hdr->cmsg_len = msg.msg_controllen;
+ hdr->cmsg_level = SOL_SOCKET;
+ hdr->cmsg_type = SCM_RIGHTS;
+ fds = (int *) CMSG_DATA(hdr);
/* Set up fds */
for (i = 0; i < nfd; i++) {
- pass.fd[i] = cf->fd;
+ fds[i] = cf->fd;
cf = cf->next;
}
- init_msg_send(&msg, buf, size, &pass, nfd);
i = sendmsg(ciptr->fd, &msg, 0);
if (i > 0)
discardFd(&ciptr->send_fds, cf, 0);
@@ -2501,8 +2549,10 @@ Xtransport TRANS(SocketTCPFuncs) = {
TRANS(SocketWrite),
TRANS(SocketReadv),
TRANS(SocketWritev),
+#if XTRANS_SEND_FDS
TRANS(SocketSendFdInvalid),
TRANS(SocketRecvFdInvalid),
+#endif
TRANS(SocketDisconnect),
TRANS(SocketINETClose),
TRANS(SocketINETClose),
@@ -2543,8 +2593,10 @@ Xtransport TRANS(SocketINETFuncs) = {
TRANS(SocketWrite),
TRANS(SocketReadv),
TRANS(SocketWritev),
+#if XTRANS_SEND_FDS
TRANS(SocketSendFdInvalid),
TRANS(SocketRecvFdInvalid),
+#endif
TRANS(SocketDisconnect),
TRANS(SocketINETClose),
TRANS(SocketINETClose),
@@ -2586,8 +2638,10 @@ Xtransport TRANS(SocketINET6Funcs) = {
TRANS(SocketWrite),
TRANS(SocketReadv),
TRANS(SocketWritev),
+#if XTRANS_SEND_FDS
TRANS(SocketSendFdInvalid),
TRANS(SocketRecvFdInvalid),
+#endif
TRANS(SocketDisconnect),
TRANS(SocketINETClose),
TRANS(SocketINETClose),
@@ -2636,8 +2690,10 @@ Xtransport TRANS(SocketLocalFuncs) = {
TRANS(SocketWrite),
TRANS(SocketReadv),
TRANS(SocketWritev),
+#if XTRANS_SEND_FDS
TRANS(SocketSendFd),
TRANS(SocketRecvFd),
+#endif
TRANS(SocketDisconnect),
TRANS(SocketUNIXClose),
TRANS(SocketUNIXCloseForCloning),
@@ -2692,8 +2748,10 @@ Xtransport TRANS(SocketUNIXFuncs) = {
TRANS(SocketWrite),
TRANS(SocketReadv),
TRANS(SocketWritev),
+#if XTRANS_SEND_FDS
TRANS(SocketSendFd),
TRANS(SocketRecvFd),
+#endif
TRANS(SocketDisconnect),
TRANS(SocketUNIXClose),
TRANS(SocketUNIXCloseForCloning),