Sync usage with man page.
[netbsd-mini2440.git] / external / ibm-public / postfix / dist / src / util / timed_write.c
blob77d66777fb725421fc0f2296585c8005da93b128
1 /* $NetBSD$ */
3 /*++
4 /* NAME
5 /* timed_write 3
6 /* SUMMARY
7 /* write operation with pre-write timeout
8 /* SYNOPSIS
9 /* #include <iostuff.h>
11 /* ssize_t timed_write(fd, buf, len, timeout, context)
12 /* int fd;
13 /* const void *buf;
14 /* size_t len;
15 /* int timeout;
16 /* void *context;
17 /* DESCRIPTION
18 /* timed_write() performs a write() operation when the specified
19 /* descriptor becomes writable within a user-specified deadline.
21 /* Arguments:
22 /* .IP fd
23 /* File descriptor in the range 0..FD_SETSIZE.
24 /* .IP buf
25 /* Write buffer pointer.
26 /* .IP len
27 /* Write buffer size.
28 /* .IP timeout
29 /* The deadline in seconds. If this is <= 0, the deadline feature
30 /* is disabled.
31 /* .IP context
32 /* Application context. This parameter is unused. It exists only
33 /* for the sake of VSTREAM compatibility.
34 /* DIAGNOSTICS
35 /* When the operation does not complete within the deadline, the
36 /* result value is -1, and errno is set to ETIMEDOUT.
37 /* All other returns are identical to those of a write(2) operation.
38 /* LICENSE
39 /* .ad
40 /* .fi
41 /* The Secure Mailer license must be distributed with this software.
42 /* AUTHOR(S)
43 /* Wietse Venema
44 /* IBM T.J. Watson Research
45 /* P.O. Box 704
46 /* Yorktown Heights, NY 10598, USA
47 /*--*/
49 /* System library. */
51 #include <sys_defs.h>
52 #include <unistd.h>
53 #include <errno.h>
55 /* Utility library. */
57 #include <msg.h>
58 #include <iostuff.h>
60 /* timed_write - write with deadline */
62 ssize_t timed_write(int fd, void *buf, size_t len,
63 int timeout, void *unused_context)
65 ssize_t ret;
68 * Wait for a limited amount of time for something to happen. If nothing
69 * happens, report an ETIMEDOUT error.
71 * XXX Solaris 8 read() fails with EAGAIN after read-select() returns
72 * success. The code below exists just in case their write implementation
73 * is equally broken.
75 * This condition may also be found on systems where select() returns
76 * success on pipes with less than PIPE_BUF bytes of space, and with
77 * badly designed software where multiple writers are fighting for access
78 * to the same resource.
80 for (;;) {
81 if (timeout > 0 && write_wait(fd, timeout) < 0)
82 return (-1);
83 if ((ret = write(fd, buf, len)) < 0 && timeout > 0 && errno == EAGAIN) {
84 msg_warn("write() returns EAGAIN on a writable file descriptor!");
85 msg_warn("pausing to avoid going into a tight select/write loop!");
86 sleep(1);
87 continue;
88 } else if (ret < 0 && errno == EINTR) {
89 continue;
90 } else {
91 return (ret);