~ubuntu-branches/ubuntu/trusty/postfix/trusty-updates

« back to all changes in this revision

Viewing changes to src/util/read_wait.c

  • Committer: Package Import Robot
  • Author(s): LaMont Jones, LaMont Jones, localization folks
  • Date: 2014-02-11 07:44:30 UTC
  • mfrom: (58.1.1 sid)
  • Revision ID: package-import@ubuntu.com-20140211074430-kwkoxdz0fbajn0fj
Tags: 2.11.0-1
[LaMont Jones]

* New upstream release: 2.11.0

[localization folks]

* l10n: Updated German translations.  Closes: #734893 (Helge Kreutzmann)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*++
2
 
/* NAME
3
 
/*      read_wait 3
4
 
/* SUMMARY
5
 
/*      wait until descriptor becomes readable
6
 
/* SYNOPSIS
7
 
/*      #include <iostuff.h>
8
 
/*
9
 
/*      int     read_wait(fd, timeout)
10
 
/*      int     fd;
11
 
/*      int     timeout;
12
 
/* DESCRIPTION
13
 
/*      read_wait() blocks the current process until the specified file
14
 
/*      descriptor becomes readable, or until the deadline is exceeded.
15
 
/*
16
 
/*      Arguments:
17
 
/* .IP fd
18
 
/*      File descriptor in the range 0..FD_SETSIZE (on systems that
19
 
/*      need to use select(2)).
20
 
/* .IP timeout
21
 
/*      If positive, deadline in seconds. A zero value effects a poll.
22
 
/*      A negative value means wait until something happens.
23
 
/* DIAGNOSTICS
24
 
/*      Panic: interface violation. All system call errors are fatal.
25
 
/*
26
 
/*      A zero result means success.  When the specified deadline is
27
 
/*      exceeded, read_wait() returns -1 and sets errno to ETIMEDOUT.
28
 
/* LICENSE
29
 
/* .ad
30
 
/* .fi
31
 
/*      The Secure Mailer license must be distributed with this software.
32
 
/* AUTHOR(S)
33
 
/*      Wietse Venema
34
 
/*      IBM T.J. Watson Research
35
 
/*      P.O. Box 704
36
 
/*      Yorktown Heights, NY 10598, USA
37
 
/*--*/
38
 
 
39
 
/* System library. */
40
 
 
41
 
#include <sys_defs.h>
42
 
#include <sys/time.h>
43
 
#include <signal.h>
44
 
#include <errno.h>
45
 
#include <unistd.h>
46
 
#include <string.h>
47
 
 
48
 
#ifdef USE_SYSV_POLL
49
 
#include <poll.h>
50
 
#endif
51
 
 
52
 
#ifdef USE_SYS_SELECT_H
53
 
#include <sys/select.h>
54
 
#endif
55
 
 
56
 
/* Utility library. */
57
 
 
58
 
#include <msg.h>
59
 
#include <iostuff.h>
60
 
 
61
 
/* read_wait - block with timeout until file descriptor is readable */
62
 
 
63
 
int     read_wait(int fd, int timeout)
64
 
{
65
 
#ifndef USE_SYSV_POLL
66
 
    fd_set  read_fds;
67
 
    fd_set  except_fds;
68
 
    struct timeval tv;
69
 
    struct timeval *tp;
70
 
 
71
 
    /*
72
 
     * Sanity checks.
73
 
     */
74
 
    if (FD_SETSIZE <= fd)
75
 
        msg_panic("descriptor %d does not fit FD_SETSIZE %d", fd, FD_SETSIZE);
76
 
 
77
 
    /*
78
 
     * Use select() so we do not depend on alarm() and on signal() handlers.
79
 
     * Restart the select when interrupted by some signal. Some select()
80
 
     * implementations reduce the time to wait when interrupted, which is
81
 
     * exactly what we want.
82
 
     */
83
 
    FD_ZERO(&read_fds);
84
 
    FD_SET(fd, &read_fds);
85
 
    FD_ZERO(&except_fds);
86
 
    FD_SET(fd, &except_fds);
87
 
    if (timeout >= 0) {
88
 
        tv.tv_usec = 0;
89
 
        tv.tv_sec = timeout;
90
 
        tp = &tv;
91
 
    } else {
92
 
        tp = 0;
93
 
    }
94
 
 
95
 
    for (;;) {
96
 
        switch (select(fd + 1, &read_fds, (fd_set *) 0, &except_fds, tp)) {
97
 
        case -1:
98
 
            if (errno != EINTR)
99
 
                msg_fatal("select: %m");
100
 
            continue;
101
 
        case 0:
102
 
            errno = ETIMEDOUT;
103
 
            return (-1);
104
 
        default:
105
 
            return (0);
106
 
        }
107
 
    }
108
 
#else
109
 
 
110
 
    /*
111
 
     * System-V poll() is optimal for polling a few descriptors.
112
 
     */
113
 
    struct pollfd pollfd;
114
 
 
115
 
#define WAIT_FOR_EVENT  (-1)
116
 
 
117
 
    pollfd.fd = fd;
118
 
    pollfd.events = POLLIN;
119
 
    for (;;) {
120
 
        switch (poll(&pollfd, 1, timeout < 0 ?
121
 
                     WAIT_FOR_EVENT : timeout * 1000)) {
122
 
        case -1:
123
 
            if (errno != EINTR)
124
 
                msg_fatal("poll: %m");
125
 
            continue;
126
 
        case 0:
127
 
            errno = ETIMEDOUT;
128
 
            return (-1);
129
 
        default:
130
 
            if (pollfd.revents & POLLNVAL)
131
 
                msg_fatal("poll: %m");
132
 
            return (0);
133
 
        }
134
 
    }
135
 
#endif
136
 
}