/*
 * Copyright (c) 2002-2004 Sendmail, Inc. and its suppliers.
 *	All rights reserved.
 *
 * By using this file, you agree to the terms and conditions set
 * forth in the LICENSE file which can be found at the top level of
 * the sendmail distribution.
 */

#include "sm/generic.h"
SM_RCSID("@(#)$Id: write_fd.c,v 1.9 2004/12/29 23:47:35 ca Exp $")
#include "sm/assert.h"
#include "sm/error.h"
#include "sm/io.h"
#include "sm/varargs.h"
#include "sm/limits.h"
#include "sm/types.h"
#include "sm/socket.h"		/* struct msghdr */
#include "sm/uio.h"		/* struct iovec */
#include "sm/cmsg.h"

/*
**  WRITE_FD -- send filedescriptor sendfd over open file fd and some data
**
**	Parameters:
**		fd -- fd to use for communication
**		ptr -- buffer to send too
**		nbytes -- number of bytes to send from buffer
**		sendfd -- fd to send
**
**	Returns:
**		result of sendmsg()
*/

ssize_t
sm_write_fd(fd_T fd, void *ptr, size_t nbytes, int sendfd)
{
	struct msghdr	msg;
	struct iovec	iov[1];

#if HAVE_MSGHDR_MSG_CONTROL
	char		control[CMSG_SPACE(sizeof(int))];
	struct cmsghdr	*cmptr;

	msg.msg_control = (caddr_t)control;
	msg.msg_controllen = CMSG_LEN(sizeof(int));

	cmptr = CMSG_FIRSTHDR(&msg);
	cmptr->cmsg_len = CMSG_LEN(sizeof(int));
	cmptr->cmsg_level = SOL_SOCKET;
	cmptr->cmsg_type = SCM_RIGHTS;
	*((int *) CMSG_DATA(cmptr)) = sendfd;
#else /* HAVE_MSGHDR_MSG_CONTROL */
	msg.msg_accrights = (caddr_t) &sendfd;
	msg.msg_accrightslen = sizeof(int);
#endif /* HAVE_MSGHDR_MSG_CONTROL */

	msg.msg_name = NULL;
	msg.msg_namelen = 0;

	iov[0].iov_base = ptr;
	iov[0].iov_len = nbytes;
	msg.msg_iov = iov;
	msg.msg_iovlen = 1;

	return sm_sendmsg(fd, &msg, 0);
}


syntax highlighted by Code2HTML, v. 0.9.1