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