Sync usage with man page.
[netbsd-mini2440.git] / external / ibm-public / postfix / dist / src / util / writable.c
blob964eea8a4e023d755c18a3e0ba30b1cb1e6c250c
1 /* $NetBSD$ */
3 /*++
4 /* NAME
5 /* writable 3
6 /* SUMMARY
7 /* test if descriptor is writable
8 /* SYNOPSIS
9 /* #include <iostuff.h>
11 /* int writable(fd)
12 /* int fd;
13 /* DESCRIPTION
14 /* writable() asks the kernel if the specified file descriptor
15 /* is writable, i.e. a write operation would not block.
17 /* Arguments:
18 /* .IP fd
19 /* File descriptor in the range 0..FD_SETSIZE.
20 /* DIAGNOSTICS
21 /* All system call errors are fatal.
22 /* LICENSE
23 /* .ad
24 /* .fi
25 /* The Secure Mailer license must be distributed with this software.
26 /* AUTHOR(S)
27 /* Wietse Venema
28 /* IBM T.J. Watson Research
29 /* P.O. Box 704
30 /* Yorktown Heights, NY 10598, USA
31 /*--*/
33 /* System library. */
35 #include <sys_defs.h>
36 #include <sys/time.h>
37 #include <signal.h>
38 #include <errno.h>
39 #include <unistd.h>
40 #include <string.h>
42 #ifdef USE_SYSV_POLL
43 #include <poll.h>
44 #endif
46 #ifdef USE_SYS_SELECT_H
47 #include <sys/select.h>
48 #endif
50 /* Utility library. */
52 #include <msg.h>
53 #include <iostuff.h>
55 /* writable - see if file descriptor is writable */
57 int writable(int fd)
59 #ifndef USE_SYSV_POLL
60 struct timeval tv;
61 fd_set write_fds;
62 fd_set except_fds;
65 * Sanity checks.
67 if (fd >= FD_SETSIZE)
68 msg_fatal("fd %d does not fit in FD_SETSIZE", fd);
71 * Initialize.
73 FD_ZERO(&write_fds);
74 FD_SET(fd, &write_fds);
75 FD_ZERO(&except_fds);
76 FD_SET(fd, &except_fds);
77 tv.tv_sec = 0;
78 tv.tv_usec = 0;
81 * Loop until we have an authoritative answer.
83 for (;;) {
84 switch (select(fd + 1, (fd_set *) 0, &write_fds, &except_fds, &tv)) {
85 case -1:
86 if (errno != EINTR)
87 msg_fatal("select: %m");
88 continue;
89 default:
90 return (FD_ISSET(fd, &write_fds));
91 case 0:
92 return (0);
95 #else
98 * System-V poll() is optimal for polling a few descriptors.
100 struct pollfd pollfd;
102 #define DONT_WAIT_FOR_EVENT 0
104 pollfd.fd = fd;
105 pollfd.events = POLLOUT;
106 for (;;) {
107 switch (poll(&pollfd, 1, DONT_WAIT_FOR_EVENT)) {
108 case -1:
109 if (errno != EINTR)
110 msg_fatal("poll: %m");
111 continue;
112 case 0:
113 return (0);
114 default:
115 if (pollfd.revents & POLLNVAL)
116 msg_fatal("poll: %m");
117 return (1);
120 #endif