#include "defs.h" Prototype int SendMsg(int to_fd, int send_fd, DnsRes *dres); Prototype int RecvMsg(int from_fd, int *recv_fd, DnsRes *dres); int SendMsg(int to_fd, int send_fd, DnsRes *dres) { struct msghdr msg; struct iovec iov; struct { #if FDPASS_USES_CMSG struct cmsghdr cmsg; #endif int fd; } cmsg; int res = 0; int cmsgsize; int sent = 0; bzero(&msg, sizeof(msg)); bzero(&cmsg, sizeof(cmsg)); iov.iov_base = (void *)dres; iov.iov_len = sizeof(DnsRes); msg.msg_iov = &iov; msg.msg_iovlen = 1; if (send_fd >= 0) { cmsgsize = sizeof(cmsg); } else { #if FDPASS_USES_CMSG cmsgsize = sizeof(struct cmsghdr); #else cmsgsize = 0; #endif } #if FDPASS_USES_ACC msg.msg_accrights = (caddr_t)&cmsg; msg.msg_accrightslen = cmsgsize; #else msg.msg_control = (caddr_t)&cmsg; msg.msg_controllen = cmsgsize; #endif #if FDPASS_USES_CMSG msg.msg_flags = 0; cmsg.cmsg.cmsg_len = cmsgsize; cmsg.cmsg.cmsg_level = SOL_SOCKET; cmsg.cmsg.cmsg_type = SCM_RIGHTS; #endif cmsg.fd = send_fd; errno = 0; /* * If we do not turn off nagle, lots of little 'group' transactions * can result in major delays even if nagle only kicks in on a few * of them. */ #ifdef TCP_NODELAY /* * Turn on TCP_NODELAY */ if (send_fd >= 0) { int one = 1; setsockopt(send_fd, IPPROTO_TCP, TCP_NODELAY, (void *)&one, sizeof(one)); } #endif /* * Send the message. This should never fail. If it does, try to core * the reader subprocess. Certainly kill it. */ if (DebugOpt) printf("SendMsg() pid= %d fd=%d size=%d\n", (int)getpid(), cmsg.fd, sizeof(DnsRes)); while (!sent) { res = sendmsg(to_fd, &msg, 0); sent = 1; if (res < 0) { if (errno == EAGAIN) sent = 0; else logit(LOG_ERR, "sendmsg error (%s)", strerror(errno)); } } return(res); } int RecvMsg(int from_fd, int *recv_fd, DnsRes *dres) { int result = 0; struct msghdr msg; struct iovec iov; struct { #if FDPASS_USES_CMSG struct cmsghdr cmsg; #endif int fd; } cmsg; bzero(&msg, sizeof(msg)); iov.iov_base = (void *)dres; iov.iov_len = sizeof(DnsRes); msg.msg_iov = &iov; msg.msg_iovlen = 1; #if FDPASS_USES_ACC msg.msg_accrights = (caddr_t)&cmsg; msg.msg_accrightslen = sizeof(cmsg); #else msg.msg_control = (caddr_t)&cmsg; msg.msg_controllen = sizeof(cmsg); #endif #if FDPASS_USES_CMSG msg.msg_flags = 0; cmsg.cmsg.cmsg_len = sizeof(cmsg); #endif cmsg.fd = -1; errno = 0; /* * receive message w/ file descriptor */ result = recvmsg(from_fd, &msg, MSG_EOR|MSG_WAITALL); if (result >= 0 || errno == EAGAIN) { *recv_fd = cmsg.fd; if (DebugOpt && errno != EAGAIN) printf("RecvMsg() pid=%d fd=%d size=%d\n", (int)getpid(), cmsg.fd, result); } else { logit(LOG_ERR, "recvmsg error (%s)", strerror(errno)); } return(result); }