ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/EV/schmorp.h
(Generate patch)

Comparing EV/schmorp.h (file contents):
Revision 1.1 by root, Tue Jul 14 00:09:59 2009 UTC vs.
Revision 1.3 by root, Tue Jul 14 20:31:21 2009 UTC

1#ifndef SCHMORP_PERL_H_ 1#ifndef SCHMORP_PERL_H_
2#define SCHMORP_PERL_H_ 2#define SCHMORP_PERL_H_
3 3
4/* WARNING
5 * This header file is a shared resource between many modules.
6 */
7
4/* useful stuff, used by schmorp mostly */ 8/* useful stuff, used by schmorp mostly */
9
10#include "patchlevel.h"
5 11
6#define PERL_VERSION_ATLEAST(a,b,c) \ 12#define PERL_VERSION_ATLEAST(a,b,c) \
7 (PERL_REVISION > (a) \ 13 (PERL_REVISION > (a) \
8 || (PERL_REVISION == (a) \ 14 || (PERL_REVISION == (a) \
9 && (PERL_VERSION > (b) \ 15 && (PERL_VERSION > (b) \
68#ifndef SIG_SIZE 74#ifndef SIG_SIZE
69 /* kudos to Slaven Rezic for the idea */ 75 /* kudos to Slaven Rezic for the idea */
70 static char sig_size [] = { SIG_NUM }; 76 static char sig_size [] = { SIG_NUM };
71# define SIG_SIZE (sizeof (sig_size) + 1) 77# define SIG_SIZE (sizeof (sig_size) + 1)
72#endif 78#endif
79 dTHX;
73 int signum; 80 int signum;
74 81
75 SvGETMAGIC (sig); 82 SvGETMAGIC (sig);
76 83
77 for (signum = 1; signum < SIG_SIZE; ++signum) 84 for (signum = 1; signum < SIG_SIZE; ++signum)
90s_signum_croak (SV *sig) 97s_signum_croak (SV *sig)
91{ 98{
92 int signum = s_signum (sig); 99 int signum = s_signum (sig);
93 100
94 if (signum < 0) 101 if (signum < 0)
102 {
103 dTHX;
95 croak ("%s: invalid signal name or number", SvPV_nolen (sig)); 104 croak ("%s: invalid signal name or number", SvPV_nolen (sig));
105 }
96 106
97 return signum; 107 return signum;
98} 108}
99 109
100static int 110static int
101s_fileno (SV *fh, int wr) 111s_fileno (SV *fh, int wr)
102{ 112{
113 dTHX;
103 SvGETMAGIC (fh); 114 SvGETMAGIC (fh);
104 115
105 if (SvROK (fh)) 116 if (SvROK (fh))
106 { 117 {
107 fh = SvRV (fh); 118 fh = SvRV (fh);
121s_fileno_croak (SV *fh, int wr) 132s_fileno_croak (SV *fh, int wr)
122{ 133{
123 int fd = s_fileno (fh, wr); 134 int fd = s_fileno (fh, wr);
124 135
125 if (fd < 0) 136 if (fd < 0)
137 {
138 dTHX;
126 croak ("%s: illegal fh argument, either not an OS file or read/write mode mismatch", SvPV_nolen (fh)); 139 croak ("%s: illegal fh argument, either not an OS file or read/write mode mismatch", SvPV_nolen (fh));
140 }
127 141
128 return fd; 142 return fd;
129} 143}
130 144
131static SV * 145static SV *
132s_get_cv (SV *cb_sv) 146s_get_cv (SV *cb_sv)
133{ 147{
148 dTHX;
134 HV *st; 149 HV *st;
135 GV *gvp; 150 GV *gvp;
151
136 CV *cv = sv_2cv (cb_sv, &st, &gvp, 0); 152 return (SV *)sv_2cv (cb_sv, &st, &gvp, 0);
137
138 return (SV *)cv;
139} 153}
140 154
141static SV * 155static SV *
142s_get_cv_croak (SV *cb_sv) 156s_get_cv_croak (SV *cb_sv)
143{ 157{
144 cb_sv = s_get_cv (cb_sv); 158 SV *cv = s_get_cv (cb_sv);
145 159
146 if (!cb_sv) 160 if (!cv)
161 {
162 dTHX;
147 croak ("%s: callback must be a CODE reference or another callable object", SvPV_nolen (cb_sv)); 163 croak ("%s: callback must be a CODE reference or another callable object", SvPV_nolen (cb_sv));
164 }
148 165
149 return cb_sv; 166 return cv;
150} 167}
151 168
152/*****************************************************************************/ 169/*****************************************************************************/
153/* gensub: simple closure generation utility */ 170/* gensub: simple closure generation utility */
154 171
170 S_GENSUB_ARG = arg; 187 S_GENSUB_ARG = arg;
171 188
172 return newRV_noinc ((SV *)cv); 189 return newRV_noinc ((SV *)cv);
173} 190}
174 191
175#endif 192/** portable pipe/socketpair */
176 193
194#ifdef USE_SOCKETS_AS_HANDLES
195# define S_TO_SOCKET(x) (win32_get_osfhandle (x))
196#else
197# define S_TO_SOCKET(x) (x)
198#endif
199
200#ifdef _WIN32
201/* taken almost verbatim from libev's ev_win32.c */
202/* oh, the humanity! */
203static int
204s_pipe (int filedes [2])
205{
206 struct sockaddr_in addr = { 0 };
207 int addr_size = sizeof (addr);
208 struct sockaddr_in adr2;
209 int adr2_size = sizeof (adr2);
210 SOCKET listener;
211 SOCKET sock [2] = { -1, -1 };
212
213 if ((listener = socket (AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
214 return -1;
215
216 addr.sin_family = AF_INET;
217 addr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
218 addr.sin_port = 0;
219
220 if (bind (listener, (struct sockaddr *)&addr, addr_size))
221 goto fail;
222
223 if (getsockname (listener, (struct sockaddr *)&addr, &addr_size))
224 goto fail;
225
226 if (listen (listener, 1))
227 goto fail;
228
229 if ((sock [0] = socket (AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
230 goto fail;
231
232 if (connect (sock [0], (struct sockaddr *)&addr, addr_size))
233 goto fail;
234
235 if ((sock [1] = accept (listener, 0, 0)) < 0)
236 goto fail;
237
238 /* windows vista returns fantasy port numbers for getpeername.
239 * example for two interconnected tcp sockets:
240 *
241 * (Socket::unpack_sockaddr_in getsockname $sock0)[0] == 53364
242 * (Socket::unpack_sockaddr_in getpeername $sock0)[0] == 53363
243 * (Socket::unpack_sockaddr_in getsockname $sock1)[0] == 53363
244 * (Socket::unpack_sockaddr_in getpeername $sock1)[0] == 53365
245 *
246 * wow! tridirectional sockets!
247 *
248 * this way of checking ports seems to work:
249 */
250 if (getpeername (sock [0], (struct sockaddr *)&addr, &addr_size))
251 goto fail;
252
253 if (getsockname (sock [1], (struct sockaddr *)&adr2, &adr2_size))
254 goto fail;
255
256 errno = WSAEINVAL;
257 if (addr_size != adr2_size
258 || addr.sin_addr.s_addr != adr2.sin_addr.s_addr /* just to be sure, I mean, it's windows */
259 || addr.sin_port != adr2.sin_port)
260 goto fail;
261
262 closesocket (listener);
263
264#ifdef USE_SOCKETS_AS_HANDLES
265 /* when select isn't winsocket, we also expect socket, connect, accept etc.
266 * to work on fds */
267 filedes [0] = sock [0];
268 filedes [1] = sock [1];
269#else
270 filedes [0] = _open_osfhandle (sock [0], 0);
271 filedes [1] = _open_osfhandle (sock [1], 0);
272#endif
273
274 return 0;
275
276fail:
277 closesocket (listener);
278
279 if (sock [0] != INVALID_SOCKET) closesocket (sock [0]);
280 if (sock [1] != INVALID_SOCKET) closesocket (sock [1]);
281
282 return -1;
283}
284
285#define s_socketpair(domain,type,protocol,filedes) s_pipe (filedes)
286
287#else
288
289#define s_socketpair(domain,type,protocol,filedes) socketpair (domain, type, protocol, filedes)
290#define s_pipe(filedes) pipe (filedes)
291
292#endif
293
294#endif
295

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines