File Coverage

lib/IO/Ppoll.xs
Criterion Covered Total %
statement 60 61 98.3
branch 33 46 71.7
condition n/a
subroutine n/a
pod n/a
total 93 107 86.9


line stmt bran cond sub pod time code
1             /* You may distribute under the terms of either the GNU General Public License
2             * or the Artistic License (the same terms as Perl itself)
3             *
4             * (C) Paul Evans, 2007,2008 -- leonerd@leonerd.org.uk
5             */
6              
7             #include "EXTERN.h"
8             #include "perl.h"
9             #include "XSUB.h"
10              
11             #include "poll.h"
12              
13             /* mPUSHi is a 5.8 thing. We'll have to define it ourselves to support older
14             * perls
15             */
16              
17             #ifndef PUSHmortal
18             # define PUSHmortal PUSHs(sv_newmortal())
19             #endif
20              
21             #ifndef mPUSHi
22             # define mPUSHi(i) sv_setiv_mg(PUSHmortal, (IV)(i))
23             #endif
24              
25             MODULE = IO::Ppoll PACKAGE = IO::Ppoll
26              
27             BOOT:
28             {
29             HV *stash;
30 4           stash = gv_stashpvn("IO::Ppoll", 9, TRUE);
31 4           newCONSTSUB(stash, "POLLIN", newSViv(POLLIN));
32 4           newCONSTSUB(stash, "POLLOUT", newSViv(POLLOUT));
33 4           newCONSTSUB(stash, "POLLPRI", newSViv(POLLPRI));
34 4           newCONSTSUB(stash, "POLLERR", newSViv(POLLERR));
35 4           newCONSTSUB(stash, "POLLHUP", newSViv(POLLHUP));
36 4           newCONSTSUB(stash, "POLLNVAL",newSViv(POLLNVAL));
37             }
38              
39             SV *
40             get_events(fds, nfds, fd)
41             SV *fds
42             int nfds
43             int fd
44             INIT:
45             int i;
46             struct pollfd *fds_real;
47             CODE:
48 4           fds_real = (struct pollfd *)SvPV_nolen(fds);
49 4 50         for(i = 0; i < nfds; i++) {
50 4 50         if(fds_real[i].fd == fd)
51 4           XSRETURN_IV(fds_real[i].events);
52             }
53 0           XSRETURN_NO;
54              
55             int
56             get_revents(fds, nfds, fd)
57             SV *fds
58             int nfds
59             int fd
60             INIT:
61             int i;
62             struct pollfd *fds_real;
63             CODE:
64 3           fds_real = (struct pollfd *)SvPV_nolen(fds);
65 6 100         for(i = 0; i < nfds; i++) {
66 5 100         if(fds_real[i].fd == fd)
67 2           XSRETURN_IV(fds_real[i].revents);
68             }
69 1           XSRETURN_NO;
70              
71             void
72             get_fds(fds, nfds)
73             SV *fds
74             int nfds
75             INIT:
76             int i;
77             struct pollfd *fds_real;
78             PPCODE:
79 3           fds_real = (struct pollfd *)SvPV_nolen(fds);
80 3 50         EXTEND(SP, nfds);
    50          
81 4 100         for(i = 0; i < nfds; i++) {
82 1           int fd = fds_real[i].fd;
83 1           mPUSHi(fd);
84             }
85              
86             void
87             get_fds_for(fds, nfds, events)
88             SV *fds
89             int nfds
90             int events
91             INIT:
92             int i;
93             struct pollfd *fds_real;
94             PPCODE:
95 1           fds_real = (struct pollfd *)SvPV_nolen(fds);
96 1 50         EXTEND(SP, nfds);
    50          
97 3 100         for(i = 0; i < nfds; i++) {
98             int fd;
99 2 100         if((fds_real[i].revents & events) == 0)
100 1           continue;
101 1           fd = fds_real[i].fd;
102 1           mPUSHi(fd);
103             }
104              
105             void
106             mas_events(fds, nfds, fd, maskbits, setbits)
107             SV *fds
108             int &nfds
109             int fd
110             int maskbits
111             int setbits
112             CODE:
113 6           struct pollfd *fds_real = (struct pollfd *)SvPV_nolen(fds);
114             int i;
115 7 100         for(i = 0; i < nfds; i++) {
116 4 100         if(fds_real[i].fd == fd) {
117 3           fds_real[i].events &= maskbits;
118 3           fds_real[i].events |= setbits;
119 3           break;
120             }
121             }
122 6 100         if(i == nfds) {
123 3           nfds++;
124 3 100         SvGROW(fds, nfds * sizeof(struct pollfd));
    50          
125 3           SvCUR_set(fds, nfds * sizeof(struct pollfd));
126 3           SvPOK_only(fds);
127 3           fds_real = (struct pollfd *)SvPV(fds, PL_na);
128 3           fds_real[i].fd = fd;
129 3           fds_real[i].events = setbits;
130             }
131             OUTPUT:
132             nfds
133              
134             void
135             del_events(fds, nfds, fd)
136             SV *fds
137             int &nfds
138             int fd
139             INIT:
140             struct pollfd *fds_real;
141             CODE:
142 1           fds_real = (struct pollfd *)SvPV_nolen(fds);
143             int i;
144 1 50         for(i = 0; i < nfds; i++) {
145 1 50         if(fds_real[i].fd == fd) {
146             /* Since we don't care about the ordering here, just move the
147             * top one down */
148 1           fds_real[i] = fds_real[nfds-1];
149             nfds--;
150 1           SvCUR_set(fds, nfds * sizeof(struct pollfd));
151 1           break;
152             }
153             }
154             OUTPUT:
155             nfds
156              
157             int
158             do_poll(fds, nfds, timeout, sigmask)
159             SV *fds
160             int nfds
161             SV *timeout
162             SV *sigmask
163             INIT:
164             struct pollfd *fds_real;
165             struct timespec timeout_real; char timeout_valid;
166             sigset_t *sigmask_real;
167             int pollret;
168             CODE:
169 3           fds_real = (struct pollfd *)SvPV_nolen(fds);
170              
171 3 50         if(SvOK(timeout)) {
172 3 100         if(SvNOK(timeout)) {
173 2           double timeout_msec = SvNV(timeout);
174 2           timeout_real.tv_sec = ((long)timeout_msec) / 1000;
175 2           timeout_real.tv_nsec = 1000000 * (timeout_msec - 1000*timeout_real.tv_sec);
176             }
177             else {
178 1           long timeout_msec = SvIV(timeout);
179 1           timeout_real.tv_sec = timeout_msec / 1000;
180 1           timeout_real.tv_nsec = 1000000 * (timeout_msec % 1000);
181             }
182             timeout_valid = 1;
183             }
184             else
185             timeout_valid = 0;
186              
187 3 50         if(SvOK(sigmask)) {
188             /* This code borrowed from POSIX.xs */
189             #if PERL_VERSION > 15 || PERL_VERSION == 15 && PERL_SUBVERSION > 2
190 3           sigmask_real = (sigset_t *) SvPV_nolen(SvRV(sigmask));
191             #else
192             IV tmp = SvIV((SV*)SvRV(sigmask));
193             sigmask_real = INT2PTR(sigset_t*, tmp);
194             #endif
195             }
196             else
197             sigmask_real = NULL;
198              
199 3 50         RETVAL = ppoll(fds_real, nfds, timeout_valid ? &timeout_real : NULL, sigmask_real);
    50          
200             OUTPUT:
201             RETVAL