/* * 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 */ }