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