/*
 * Copyright (c) 2002, 2003, 2005, 2006 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: rcbsnd.c,v 1.12 2006/10/17 04:29:27 ca Exp $")

#include "sm/assert.h"
#include "sm/magic.h"
#include "sm/memops.h"
#include "sm/rpool.h"
#include "sm/limits.h"
#include "sm/io.h"
#include "sm/rcb.h"
#include "sm/str2rcb.h"
#include "sm/str-int.h"
#include "sm/reccom.h"

/*
**  SM_RCB_SND -- Send data from rcb to fd.
**
**	Parameters:
**		fd -- file descriptor to send data to.
**		rcb -- sm_rcb_P object to read from.
**
**	Returns:
**		= 0: done sending.
**		> 0: need to send more data.
**		< 0: usual sm_error code
*/

sm_ret_T
sm_rcb_snd(rcb_fd_T fd, sm_rcb_P rcb
#if SM_RCB_ST
	, st_utime_t timeout
#endif
	)
{
	size_t l;
	ssize_t r;

	SM_IS_RCB(rcb);
#if SM_RCB_CHECK
	SM_REQUIRE(rcb->sm_rcb_state == SM_RCB_SND);
#endif

	/* number of bytes to write */
	l = rcb->sm_rcb_len - rcb->sm_rcb_rw;
	if (l == 0)
		return 0;

#if SM_RCB_ST
	r = st_write_resid(fd, rcb->sm_rcb_base + rcb->sm_rcb_rw, &l, timeout);
#else
	r = write(fd, rcb->sm_rcb_base + rcb->sm_rcb_rw, l);
#endif
	if (r == -1)
	{
		if (errno == EINTR)
		{
#if SM_RCB_ST
			rcb->sm_rcb_rw += l;
#endif
			return l;
		}
		return sm_error_perm(SM_EM_RECCOM,
				(errno != 0) ? errno : SM_E_UNEXPECTED);
	}
#if SM_RCB_ST
	rcb->sm_rcb_rw += l;
	return 0;
#else /* SM_RCB_ST */
	if (r == 0)
	{
		/* wrote no data? since fd was writable, it's an error */
		return SM_IO_EOF;
	}
	rcb->sm_rcb_rw += r;
	return l - r;
#endif /* SM_RCB_ST */
}


syntax highlighted by Code2HTML, v. 0.9.1