1 // src/select.cc
2 // This file is part of libpbe; see http://decimail.org
3 // (C) 2004-2005 Philip Endecott
4 
5 // This program is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation; either version 2 of the License, or
8 // any later version.
9 //
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 // GNU General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software
17 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 
19 #include "select.hh"
20 
21 #include "Exception.hh"
22 
23 #include <sys/select.h>
24 
25 #include <cmath>
26 #include <algorithm>
27 
28 using namespace std;
29 using namespace pbe;
30 
31 
select_r(int fd1)32 int select_r(int fd1)
33 {
34   fd_set rd_fds;
35   FD_ZERO(&rd_fds);
36   fd_set wr_fds;
37   FD_ZERO(&wr_fds);
38   fd_set ex_fds;
39   FD_ZERO(&ex_fds);
40 
41   FD_SET(fd1,&rd_fds);
42 
43   int rc;
44   do {
45     rc = select(fd1+1,&rd_fds,&wr_fds,&ex_fds,NULL);
46     if (rc==-1) {
47       if (errno==EINTR) {
48         continue;
49       }
50       throw_ErrnoException("select()");
51     }
52     break;
53   } while (1);
54 
55   if (FD_ISSET(fd1,&rd_fds)) {
56     return fd1;
57   }
58 
59   return -2;
60 }
61 
62 
select_rr(int fd1,int fd2)63 int select_rr(int fd1, int fd2)
64 {
65   fd_set rd_fds;
66   FD_ZERO(&rd_fds);
67   fd_set wr_fds;
68   FD_ZERO(&wr_fds);
69   fd_set ex_fds;
70   FD_ZERO(&ex_fds);
71 
72   FD_SET(fd1,&rd_fds);
73   FD_SET(fd2,&rd_fds);
74 
75   int rc;
76   do {
77     rc = select(max(fd1,fd2)+1,&rd_fds,&wr_fds,&ex_fds,NULL);
78     if (rc==-1) {
79       if (errno==EINTR) {
80         continue;
81       }
82       throw_ErrnoException("select()");
83     }
84   } while (0);
85 
86   if (FD_ISSET(fd1,&rd_fds)) {
87     return fd1;
88   } else if (FD_ISSET(fd2,&rd_fds)) {
89     return fd2;
90   }
91 
92   return -2;
93 }
94 
95 
select_rt(int fd1,float timeout)96 int select_rt(int fd1, float timeout)
97 {
98   fd_set rd_fds;
99   FD_ZERO(&rd_fds);
100   fd_set wr_fds;
101   FD_ZERO(&wr_fds);
102   fd_set ex_fds;
103   FD_ZERO(&ex_fds);
104 
105   FD_SET(fd1,&rd_fds);
106 
107   struct timeval tv;
108   float timeout_whole;
109   float timeout_frac;
110   timeout_frac = modff(timeout, &timeout_whole);
111   tv.tv_sec = (int)timeout_whole;
112   tv.tv_usec = (int)(1000000.0*timeout_frac);
113 
114   int rc;
115   do {
116     rc = select(fd1+1,&rd_fds,&wr_fds,&ex_fds,&tv);
117     if (rc==-1) {
118       if (errno==EINTR) {
119         continue;
120       }
121       throw_ErrnoException("select()");
122     }
123   } while (0);
124 
125   if (rc==0) {
126     return -1;
127   } else if (FD_ISSET(fd1,&rd_fds)) {
128     return fd1;
129   }
130 
131   return -2;
132 }
133