#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);
}
syntax highlighted by Code2HTML, v. 0.9.1