/*
* Copyright (c) 2002, 2005 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_wait.c,v 1.7 2005/11/28 18:59:59 ca Exp $")
#include "sm/assert.h"
#include "sm/types.h"
#include "sm/time.h"
#include "sm/fdset.h"
#include "sm/io.h"
#include "io-int.h"
#include "sm/error.h"
/*
** SM_WRITE_WAIT -- wait for fd to become ready for writing (with timeout)
**
** Parameters:
** fd -- file descriptor to write data to
** timeout -- timeout
**
** Returns:
** = 0: fd ready for writing
** < 0: usual sm_error code
*/
sm_ret_T
sm_write_wait(int fd, int timeout)
{
#if HAVE_SELECT
int r;
fd_set write_fds;
fd_set except_fds;
struct timeval tv;
struct timeval *tp;
/* XXX could switch to poll... */
/* XXX return an error instead of aborting? */
SM_REQUIRE(FD_SETSIZE > fd);
FD_ZERO(&write_fds);
SM_FD_SET(fd, &write_fds);
FD_ZERO(&except_fds);
SM_FD_SET(fd, &except_fds);
if (timeout >= 0)
{
tv.tv_usec = 0;
tv.tv_sec = timeout;
tp = &tv;
}
else
tp = NULL;
for (;;)
{
r = select(fd + 1, (fd_set *) NULL, &write_fds, &except_fds,
tp);
if (r == -1)
{
if (errno == EINTR)
continue;
else
return sm_error_perm(SM_EM_IO, errno);
}
else if (r == 0)
return sm_error_temp(SM_EM_IO, ETIMEDOUT);
else
return SM_SUCCESS;
}
#else /* HAVE_SELECT */
/* XXX try poll ? */
#endif /* HAVE_SELECT */
}
syntax highlighted by Code2HTML, v. 0.9.1