#include "sm/generic.h"
SM_RCSID("@(#)$Id: sendfd.c,v 1.6 2005/06/16 20:39:02 ca Exp $")
#include "sm/assert.h"
#include "sm/error.h"
#include "sm/memops.h"
#include "sm/varargs.h"
#include "sm/limits.h"
#include "sm/types.h"
#include "sm/heap.h"
/*
** not used by any application; see write_fd.c instead.
*/
#if LIB44_FD
#include <sys/types.h>
#include <sys/socket.h> /* struct msghdr */
#include <sys/uio.h> /* struct iovec */
#include <errno.h>
#include <stddef.h>
/* XXX !!! */
static struct cmsghdr *cmptr = NULL; /* buffer is malloc'ed first time */
#define CONTROLLEN (sizeof(struct cmsghdr) + sizeof(int))
/* size of control buffer to send/recv one file descriptor */
/* Pass a file descriptor to another process.
* If fd<0, then -fd is sent back instead as the error status. */
sm_ret_T
send_fd(int clifd, int fd)
{
struct iovec iov[2];
struct msghdr msg;
char buf[2]; /* send_fd()/recv_fd() 2-byte protocol */
int r;
iov[0].iov_base = buf;
iov[0].iov_len = 2;
iov[1].iov_base = buf;
iov[1].iov_len = 2;
msg.msg_iov = iov;
msg.msg_iovlen = 1;
msg.msg_name = NULL;
msg.msg_namelen = 0;
msg.msg_flags = 0;
if (fd < 0)
{
msg.msg_control = NULL;
msg.msg_controllen = 0;
buf[1] = -fd; /* nonzero status means error */
if (buf[1] == 0)
buf[1] = 1; /* -256, etc. would screw up protocol */
}
else
{
if (cmptr == NULL && (cmptr = sm_malloc(CONTROLLEN)) == NULL)
return sm_error_temp(SM_EM_IO, ENOMEM);
cmptr->cmsg_level = SOL_SOCKET;
cmptr->cmsg_type = SCM_RIGHTS;
cmptr->cmsg_len = CONTROLLEN;
msg.msg_control = (caddr_t) cmptr;
msg.msg_controllen = CONTROLLEN;
*(int *)CMSG_DATA(cmptr) = fd; /* the fd to pass */
buf[1] = 0; /* zero status means OK */
}
buf[0] = 0; /* null byte flag to recv_fd() */
errno = 0;
r = sendmsg(clifd, &msg, 0);
if (r != 2)
return sm_error_perm(SM_EM_IO, errno);
return(0);
}
#endif /* LIB44_FD */
#if LIBSUN_FD
#include <sys/types.h>
#include <sys/socket.h> /* struct msghdr */
#include <sys/uio.h> /* struct iovec */
#include <errno.h>
#include <stddef.h>
/* Pass a file descriptor to another process.
* If fd<0, then -fd is sent back instead as the error status. */
int
send_fd(int clifd, int fd)
{
struct iovec iov[1];
struct msghdr msg;
char buf[2]; /* send_fd()/recv_fd() 2-byte protocol */
iov[0].iov_base = buf;
iov[0].iov_len = 2;
msg.msg_iov = iov;
msg.msg_iovlen = 1;
msg.msg_name = NULL;
msg.msg_namelen = 0;
if (fd < 0)
{
msg.msg_accrights = NULL;
msg.msg_accrightslen = 0;
buf[1] = -fd; /* nonzero status means error */
if (buf[1] == 0)
buf[1] = 1; /* -256, etc. would screw up protocol */
}
else
{
msg.msg_accrights = (caddr_t) &fd; /* addr of descriptor */
msg.msg_accrightslen = sizeof(int); /* pass 1 descriptor */
buf[1] = 0; /* zero status means OK */
}
buf[0] = 0; /* null byte flag to recv_fd() */
if (sendmsg(clifd, &msg, 0) != 2)
return(-1);
return(0);
}
#endif /* LIBSUN_FD */
#if LIBSYSV_FD
#include <sys/types.h>
#include <stropts.h>
/* Pass a file descriptor to another process.
* If fd<0, then -fd is sent back instead as the error status. */
int
send_fd(int clifd, int fd)
{
char buf[2]; /* send_fd()/recv_fd() 2-byte protocol */
buf[0] = 0; /* null byte flag to recv_fd() */
if (fd < 0)
{
buf[1] = -fd; /* nonzero status means error */
if (buf[1] == 0)
buf[1] = 1; /* -256, etc. would screw up protocol */
}
else
{
buf[1] = 0; /* zero status means OK */
}
if (write(clifd, buf, 2) != 2)
return(-1);
if (fd >= 0)
if (ioctl(clifd, I_SENDFD, fd) < 0)
return(-1);
return(0);
}
#endif /* LIBSYSV_FD */
syntax highlighted by Code2HTML, v. 0.9.1