1 /*
2    BAREOS® - Backup Archiving REcovery Open Sourced
3 
4    Copyright (C) 2011-2012 Planets Communications B.V.
5    Copyright (C) 2013-2013 Bareos GmbH & Co. KG
6 
7    This program is Free Software; you can redistribute it and/or
8    modify it under the terms of version three of the GNU Affero General Public
9    License as published by the Free Software Foundation and included
10    in the file LICENSE.
11 
12    This program is distributed in the hope that it will be useful, but
13    WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15    Affero General Public License for more details.
16 
17    You should have received a copy of the GNU Affero General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20    02110-1301, USA.
21 */
22 
23 /*
24  *  Marco van Wieringen, May 2012
25  */
26 
27 #include "include/bareos.h"
28 
29 #ifdef HAVE_POLL_H
30 #include <poll.h>
31 #elif HAVE_SYS_POLL_H
32 #include <sys/poll.h>
33 #endif
34 
35 #ifdef HAVE_POLL
36 /*
37  *   Returns: 1 if data available
38  *            0 if timeout
39  *           -1 if error
40  */
WaitForReadableFd(int fd,int msec,bool ignore_interupts)41 int WaitForReadableFd(int fd, int msec, bool ignore_interupts)
42 {
43    struct pollfd pfds[1];
44    int events;
45 
46    events = POLLIN;
47 #if defined(POLLRDNORM)
48    events |= POLLRDNORM;
49 #endif
50 #if defined(POLLRDBAND)
51    events |= POLLRDBAND;
52 #endif
53 #if defined(POLLPRI)
54    events |= POLLPRI;
55 #endif
56 
57    memset(pfds, 0, sizeof(pfds));
58    pfds[0].fd = fd;
59    pfds[0].events = events;
60 
61    for ( ;; ) {
62       switch(poll(pfds, 1, msec)) {
63       case 0:                         /* timeout */
64          return 0;
65       case -1:
66          if (ignore_interupts && (errno == EINTR || errno == EAGAIN)) {
67             continue;
68          }
69          return -1;                  /* error return */
70       default:
71          if (pfds[0].revents & events) {
72             return 1;
73          } else {
74             return 0;
75          }
76       }
77    }
78 }
79 
80 /*
81  *   Returns: 1 if data available
82  *            0 if timeout
83  *           -1 if error
84  */
WaitForWritableFd(int fd,int msec,bool ignore_interupts)85 int WaitForWritableFd(int fd, int msec, bool ignore_interupts)
86 {
87    struct pollfd pfds[1];
88    int events;
89 
90    events = POLLOUT;
91 #if defined(POLLWRNORM)
92    events |= POLLWRNORM;
93 #endif
94 #if defined POLLWRBAND
95    events |= POLLWRBAND;
96 #endif
97 
98    memset(pfds, 0, sizeof(pfds));
99    pfds[0].fd = fd;
100    pfds[0].events = events;
101 
102    for ( ;; ) {
103       switch(poll(pfds, 1, msec)) {
104       case 0:                         /* timeout */
105          return 0;
106       case -1:
107          if (ignore_interupts && (errno == EINTR || errno == EAGAIN)) {
108             continue;
109          }
110          return -1;                  /* error return */
111       default:
112          if (pfds[0].revents & events) {
113             return 1;
114          } else {
115             return 0;
116          }
117       }
118    }
119 }
120 #else
121 /*
122  *   Returns: 1 if data available
123  *            0 if timeout
124  *           -1 if error
125  */
WaitForReadableFd(int fd,int msec,bool ignore_interupts)126 int WaitForReadableFd(int fd, int msec, bool ignore_interupts)
127 {
128    fd_set fdset;
129    struct timeval tv;
130 
131    tv.tv_sec = msec / 1000;
132    tv.tv_usec = (msec % 1000) * 1000;
133 
134    for ( ;; ) {
135       FD_ZERO(&fdset);
136       FD_SET((unsigned)fd, &fdset);
137       switch(select(fd + 1, &fdset, NULL, NULL, &tv)) {
138       case 0:                         /* timeout */
139          return 0;
140       case -1:
141          if (ignore_interupts && (errno == EINTR || errno == EAGAIN)) {
142             continue;
143          }
144          return -1;                  /* error return */
145       default:
146          return 1;
147       }
148    }
149 }
150 
151 /*
152  *   Returns: 1 if data available
153  *            0 if timeout
154  *           -1 if error
155  */
WaitForWritableFd(int fd,int msec,bool ignore_interupts)156 int WaitForWritableFd(int fd, int msec, bool ignore_interupts)
157 {
158 #if defined(HAVE_WIN32)
159    return 1;
160 #else
161    fd_set fdset;
162    struct timeval tv;
163 
164    tv.tv_sec = msec / 1000;
165    tv.tv_usec = (msec % 1000) * 1000;
166 
167    for ( ;; ) {
168       FD_ZERO(&fdset);
169       FD_SET((unsigned)fd, &fdset);
170       switch(select(fd + 1, NULL, &fdset, NULL, &tv)) {
171       case 0:                         /* timeout */
172          return 0;
173       case -1:
174          if (ignore_interupts && (errno == EINTR || errno == EAGAIN)) {
175             continue;
176          }
177          return -1;                  /* error return */
178       default:
179          return 1;
180       }
181    }
182 #endif /* defined(HAVE_WIN32) */
183 }
184 #endif /* HAVE_POLL */
185