summaryrefslogtreecommitdiff
path: root/regress/netcat.c
diff options
context:
space:
mode:
authorDamien Miller <djm@mindrot.org>2015-02-26 20:33:22 -0800
committerDamien Miller <djm@mindrot.org>2015-02-26 20:34:06 -0800
commit1ad3a77cc9d5568f5437ff99d377aa7a41859b83 (patch)
tree4cfbfcf67197b3fe865dea5ed01b33d738084538 /regress/netcat.c
parent9e1cfca7e1fe9cf8edb634fc894e43993e4da1ea (diff)
make regress/netcat.c fd passing (more) portable
Diffstat (limited to 'regress/netcat.c')
-rw-r--r--regress/netcat.c46
1 files changed, 25 insertions, 21 deletions
diff --git a/regress/netcat.c b/regress/netcat.c
index 3f100bdd6..29e85bf5a 100644
--- a/regress/netcat.c
+++ b/regress/netcat.c
@@ -1014,43 +1014,44 @@ fillbuf(int fd, unsigned char *buf, size_t *bufpos)
1014void 1014void
1015fdpass(int nfd) 1015fdpass(int nfd)
1016{ 1016{
1017 struct msghdr mh; 1017#if defined(HAVE_SENDMSG) && (defined(HAVE_ACCRIGHTS_IN_MSGHDR) || defined(HAVE_CONTROL_IN_MSGHDR))
1018 struct msghdr msg;
1019#ifndef HAVE_ACCRIGHTS_IN_MSGHDR
1018 union { 1020 union {
1019 struct cmsghdr hdr; 1021 struct cmsghdr hdr;
1020 char buf[CMSG_SPACE(sizeof(int))]; 1022 char buf[CMSG_SPACE(sizeof(int))];
1021 } cmsgbuf; 1023 } cmsgbuf;
1022 struct cmsghdr *cmsg; 1024 struct cmsghdr *cmsg;
1023 struct iovec iov; 1025#endif
1024 char c = '\0'; 1026 struct iovec vec;
1025 ssize_t r; 1027 char ch = '\0';
1026 struct pollfd pfd; 1028 struct pollfd pfd;
1029 ssize_t r;
1027 1030
1028 /* Avoid obvious stupidity */ 1031 memset(&msg, 0, sizeof(msg));
1029 if (isatty(STDOUT_FILENO)) 1032#ifdef HAVE_ACCRIGHTS_IN_MSGHDR
1030 errx(1, "Cannot pass file descriptor to tty"); 1033 msg.msg_accrights = (caddr_t)&nfd;
1031 1034 msg.msg_accrightslen = sizeof(nfd);
1032 bzero(&mh, sizeof(mh)); 1035#else
1033 bzero(&cmsgbuf, sizeof(cmsgbuf)); 1036 memset(&cmsgbuf, 0, sizeof(cmsgbuf));
1034 bzero(&iov, sizeof(iov)); 1037 msg.msg_control = (caddr_t)&cmsgbuf.buf;
1035 bzero(&pfd, sizeof(pfd)); 1038 msg.msg_controllen = sizeof(cmsgbuf.buf);
1036 1039 cmsg = CMSG_FIRSTHDR(&msg);
1037 mh.msg_control = (caddr_t)&cmsgbuf.buf;
1038 mh.msg_controllen = sizeof(cmsgbuf.buf);
1039 cmsg = CMSG_FIRSTHDR(&mh);
1040 cmsg->cmsg_len = CMSG_LEN(sizeof(int)); 1040 cmsg->cmsg_len = CMSG_LEN(sizeof(int));
1041 cmsg->cmsg_level = SOL_SOCKET; 1041 cmsg->cmsg_level = SOL_SOCKET;
1042 cmsg->cmsg_type = SCM_RIGHTS; 1042 cmsg->cmsg_type = SCM_RIGHTS;
1043 *(int *)CMSG_DATA(cmsg) = nfd; 1043 *(int *)CMSG_DATA(cmsg) = nfd;
1044#endif
1044 1045
1045 iov.iov_base = &c; 1046 vec.iov_base = &ch;
1046 iov.iov_len = 1; 1047 vec.iov_len = 1;
1047 mh.msg_iov = &iov; 1048 msg.msg_iov = &vec;
1048 mh.msg_iovlen = 1; 1049 msg.msg_iovlen = 1;
1049 1050
1050 bzero(&pfd, sizeof(pfd)); 1051 bzero(&pfd, sizeof(pfd));
1051 pfd.fd = STDOUT_FILENO; 1052 pfd.fd = STDOUT_FILENO;
1052 for (;;) { 1053 for (;;) {
1053 r = sendmsg(STDOUT_FILENO, &mh, 0); 1054 r = sendmsg(STDOUT_FILENO, &msg, 0);
1054 if (r == -1) { 1055 if (r == -1) {
1055 if (errno == EAGAIN || errno == EINTR) { 1056 if (errno == EAGAIN || errno == EINTR) {
1056 pfd.events = POLLOUT; 1057 pfd.events = POLLOUT;
@@ -1065,6 +1066,9 @@ fdpass(int nfd)
1065 break; 1066 break;
1066 } 1067 }
1067 exit(0); 1068 exit(0);
1069#else
1070 errx(1, "%s: file descriptor passing not supported", __func__);
1071#endif
1068} 1072}
1069 1073
1070/* Deal with RFC 854 WILL/WONT DO/DONT negotiation. */ 1074/* Deal with RFC 854 WILL/WONT DO/DONT negotiation. */