1 #include "EXTERN.h"
2 #include "perl.h"
3 #include "XSUB.h"
4
5 #include <fcntl.h>
6 #include <sys/types.h>
7 #include <sys/socket.h>
8 #include <errno.h>
9
10 #ifndef EWOULDBLOCK
11 #define EWOULDBLOCK EAGAIN
12 #endif
13
14 MODULE = POSIX::Socket PACKAGE = POSIX::Socket PREFIX = smh
15
16 IV
17 smh_close(fd)
18 IV fd
19
20 PROTOTYPE: DISABLE
21
22 CODE:
23 RETVAL = close(fd);
24 OUTPUT:
25 RETVAL
26
27 IV
28 smh_socket(socket_family, socket_type, protocol)
29 IV socket_family;
30 IV socket_type;
31 IV protocol;
32
33 PROTOTYPE: DISABLE
34
35 CODE:
36 RETVAL = socket(socket_family, socket_type, protocol);
37 OUTPUT:
38 RETVAL
39
40 #ifndef WIN32
41
42 IV
43 smh_fcntl(fildes, cmd, arg)
44 IV fildes;
45 IV cmd;
46 IV arg;
47
48 PROTOTYPE: DISABLE
49
50 CODE:
51 RETVAL = fcntl(fildes, cmd, arg);
52 OUTPUT:
53 RETVAL
54
55 #endif
56
57 IV
58 smh_bind(fd, addr)
59 IV fd;
60 SV * addr;
61
62 PROTOTYPE: DISABLE
63 PREINIT:
64 STRLEN addrlen;
65 char *sockaddr_pv = SvPVbyte(addr, addrlen);
66
67 CODE:
68 RETVAL = bind(fd, (struct sockaddr*)sockaddr_pv, addrlen);
69 OUTPUT:
70 RETVAL
71
72 IV
73 smh_connect(fd, addr)
74 IV fd;
75 SV * addr;
76
77 PROTOTYPE: DISABLE
78 PREINIT:
79 STRLEN addrlen;
80 char *sockaddr_pv = SvPVbyte(addr, addrlen);
81
82 CODE:
83 RETVAL = connect(fd, (struct sockaddr*)sockaddr_pv, addrlen);
84 OUTPUT:
85 RETVAL
86
87 IV
88 smh_recv(fd, sv_buffer, len, flags)
89 IV fd;
90 SV * sv_buffer;
91 IV len;
92 IV flags;
93
94 PREINIT:
95 int count;
96
97 PROTOTYPE: DISABLE
98
99 CODE:
100 if (!SvOK(sv_buffer)) {
101 sv_setpvn(sv_buffer, "", 0);
102 }
103 SvUPGRADE((SV*)ST(1), SVt_PV);
104 sv_buffer = (SV*)SvGROW((SV*)ST(1), len);
105 count = recv(fd, (void*)sv_buffer, len, flags);
106 if (count >= 0)
107 {
108 SvCUR_set((SV*)ST(1), count);
109 SvTAINT(ST(1));
110 SvSETMAGIC(ST(1));
111 }
112 RETVAL = count;
113
114 OUTPUT:
115 RETVAL
116
117 IV
118 smh_recvfrom(fd, sv_buffer, len, flags, sv_sock_addr)
119 IV fd;
120 SV * sv_buffer;
121 IV len;
122 IV flags;
123 SV * sv_sock_addr;
124
125 PREINIT:
126 int count;
127 int fromSockSize = sizeof(struct sockaddr);
128
129 PROTOTYPE: DISABLE
130
131 CODE:
132 if (!SvOK(sv_buffer)) {
133 sv_setpvn(sv_buffer, "", 0);
134 }
135 SvUPGRADE((SV*)ST(1), SVt_PV);
136 sv_buffer = (SV*)SvGROW((SV*)ST(1), len);
137
138 if (!SvOK(sv_sock_addr)) {
139 sv_setpvn(sv_sock_addr, "", 0);
140 }
141 SvUPGRADE((SV*)ST(4), SVt_PV);
142 sv_sock_addr = (SV*)SvGROW((SV*)ST(4), fromSockSize);
143
144 count = recvfrom( fd, (void*)sv_buffer, len, flags, (struct sockaddr*)sv_sock_addr, &fromSockSize );
145 if (count >= 0)
146 {
147 SvCUR_set((SV*)ST(1), count);
148 SvTAINT(ST(1));
149 SvSETMAGIC(ST(1));
150
151 SvCUR_set((SV*)ST(4), fromSockSize);
152 SvTAINT(ST(4));
153 SvSETMAGIC(ST(4));
154 }
155 RETVAL = count;
156
157 OUTPUT:
158 sv_sock_addr
159 RETVAL
160
161 IV
162 smh_recvn(fd, sv_buffer, len, flags)
163 IV fd;
164 SV * sv_buffer;
165 IV len;
166 IV flags;
167
168 PREINIT:
169 int nrecv;
170 int nleft = len;
171 void * ptr;
172
173 PROTOTYPE: DISABLE
174
175 CODE:
176 if (!SvOK(sv_buffer)) {
177 sv_setpvn(sv_buffer, "", 0);
178 }
179 SvUPGRADE((SV*)ST(1), SVt_PV);
180 sv_buffer = (SV*)SvGROW((SV*)ST(1), len);
181 ptr = (void *) sv_buffer;
182 RETVAL = len;
183 while (nleft > 0)
184 {
185 nrecv = recv(fd, ptr, nleft, flags);
186 if (nrecv == -1)
187 {
188 if ((errno == EAGAIN) || (errno == EINTR) || (errno == EWOULDBLOCK))
189 {
190 continue;
191 } else {
192 RETVAL = -1;
193 break;
194 }
195 }
196 else if (nrecv == 0)
197 {
198 RETVAL = 0;
199 break;
200 }
201 else
202 {
203 nleft -= nrecv;
204 ptr += nrecv;
205 }
206
207 }
208 SvCUR_set((SV*)ST(1), len-nleft);
209 SvTAINT(ST(1));
210 SvSETMAGIC(ST(1));
211
212 OUTPUT:
213 RETVAL
214
215
216 IV
217 smh_getsockname(fd, sv_sock_addr)
218 IV fd;
219 SV * sv_sock_addr;
220
221 PREINIT:
222 int count = sizeof(struct sockaddr);
223 char * sock_addr;
224
225 PROTOTYPE: DISABLE
226
227 CODE:
228 if (!SvOK(sv_sock_addr)) {
229 sv_setpvn(sv_sock_addr, "", 0);
230 }
231 SvUPGRADE((SV*)ST(1), SVt_PV);
232 sv_sock_addr = (SV*)SvGROW((SV*)ST(1), count);
233 RETVAL = getsockname(fd, (struct sockaddr*)sv_sock_addr, &count);
234 if (count >= 0)
235 {
236 SvCUR_set((SV*)ST(1), count);
237 SvTAINT(ST(1));
238 SvSETMAGIC(ST(1));
239 }
240
241 OUTPUT:
242 RETVAL
243
244
245 IV
smh_getsockopt(fd,level,optname,optval,optlen)246 smh_getsockopt(fd, level, optname, optval, optlen)
247 IV fd;
248 IV level;
249 IV optname;
250 SV * optval;
251 int optlen;
252
253 PREINIT:
254
255 PROTOTYPE: DISABLE
256
257 CODE:
258 if (!SvOK(optval)) {
259 sv_setpvn(optval, "", 0);
260 }
261 SvUPGRADE((SV*)ST(3), SVt_PV);
262 optval = (SV*)SvGROW((SV*)ST(3), optlen);
263 if (RETVAL = getsockopt(fd, level, optname, (void*)optval, (socklen_t*)&optlen) != -1)
264 {
265 SvCUR_set((SV*)ST(3), optlen);
266 SvTAINT(ST(3));
267 SvSETMAGIC(ST(3));
268 }
269
270 OUTPUT:
271 RETVAL
272
273
274 IV
275 smh_setsockopt(fd, level, optname, optval)
276 IV fd;
277 IV level;
278 IV optname;
279 SV * optval;
280
281 PREINIT:
282 STRLEN len;
283 char *msg = SvPVbyte(optval,len);
284
285 PROTOTYPE: DISABLE
286
287 CODE:
288 RETVAL = setsockopt(fd, level, optname, (void*)msg, len);
289
290 OUTPUT:
291 RETVAL
292
293
294 IV
295 smh_send(fd, buf, flags)
296 IV fd;
297 SV * buf;
298 IV flags;
299
300 PROTOTYPE: DISABLE
301 PREINIT:
302 STRLEN len;
303 char *msg = SvPVbyte(buf, len);
304
305
306 CODE:
307 RETVAL = send(fd, msg, len, flags);
308 OUTPUT:
309
310 IV
311 smh_sendn(fd, buf, flags)
312 IV fd;
313 SV * buf;
314 IV flags;
315
316 PROTOTYPE: DISABLE
317
318 PREINIT:
319 STRLEN len;
320 char *msg = SvPVbyte(buf, len);
321 int nwritten;
322 int nleft = len;
323
324 CODE:
325 RETVAL = len;
326 while (nleft > 0)
327 {
328 nwritten = send(fd, msg, nleft, flags);
329 if (nwritten == -1)
330 {
331 if ((errno == EAGAIN) || (errno == EINTR) || (errno == EWOULDBLOCK))
332 {
333 continue;
334 } else {
335 RETVAL = -1;
336 break;
337 }
338 }
339 else
340 {
341 nleft -= nwritten;
342 msg += nwritten;
343 }
344 }
345
346 OUTPUT:
347 RETVAL
348
349
350 IV
351 smh_sendto(fd, buf, flags, dest_addr)
352 IV fd;
353 SV * buf;
354 IV flags;
355 SV * dest_addr;
356
357 PROTOTYPE: DISABLE
358 PREINIT:
359 STRLEN addrlen;
360 STRLEN len;
361 char *msg = SvPVbyte(buf,len);
362 char *sockaddr_pv = SvPVbyte(dest_addr, addrlen);
363
364
365 CODE:
366 RETVAL = sendto(fd, msg, len, flags, (struct sockaddr*)sockaddr_pv, addrlen);
367 OUTPUT:
368 RETVAL
369
370 IV
371 smh_accept(fd)
372 IV fd;
373
374 PROTOTYPE: DISABLE
375
376 CODE:
377 RETVAL = accept(fd, NULL, NULL);
378 OUTPUT:
379 RETVAL
380
381 IV
382 smh_listen(fd, backlog)
383 IV fd;
384 IV backlog;
385
386 PROTOTYPE: DISABLE
387
388 CODE:
389 RETVAL = listen(fd, backlog);
390 OUTPUT:
391 RETVAL
392
393