fix codetest failure - ASSERT_ARGS does not have a ; after and
[parrot.git] / src / io / socket_api.c
blobc15b939f2c81d0fe90ef8a675639a41f720e4475
1 /*
2 Copyright (C) 2001-2009, Parrot Foundation.
3 $Id$
5 =head1 NAME
7 src/io/socket_api.c - Socket I/O API
9 =head1 DESCRIPTION
11 These are the primary interface functions for working with socket objects.
13 =head2 Networking Functions
15 =over 4
17 =cut
21 #include "parrot/parrot.h"
22 #include "io_private.h"
23 #include "api.str"
24 #include "pmc/pmc_socket.h"
26 #include <stdarg.h>
28 /* HEADERIZER HFILE: include/parrot/io.h */
32 =item C<INTVAL Parrot_io_socket_is_closed(PMC *socket)>
34 Returns 1 if the socket is closed, 0 if it is open.
36 =cut
42 * Mapping between PIO_PF_* constants and system-specific PF_* constants.
44 * Uses -1 for unsupported protocols.
47 static int pio_pf[PIO_PF_MAX+1] = {
48 #ifdef PF_LOCAL
49 PF_LOCAL, /* PIO_PF_LOCAL */
50 #else
51 -1, /* PIO_PF_LOCAL */
52 #endif
53 #ifdef PF_UNIX
54 PF_UNIX, /* PIO_PF_UNIX */
55 #else
56 -1, /* PIO_PF_UNIX */
57 #endif
58 #ifdef PF_INET
59 PF_INET, /* PIO_PF_INET */
60 #else
61 -1, /* PIO_PF_INET */
62 #endif
63 #ifdef PF_INET6
64 PF_INET6, /* PIO_PF_INET6 */
65 #else
66 -1, /* PIO_PF_INET6 */
67 #endif
71 * Mapping between PIO_SOCK_* constants and system-specific SOCK_* constants.
72 * Uses -1 for unsupported socket types.
75 static int pio_sock[PIO_SOCK_MAX+1] = {
76 #ifdef SOCK_PACKET
77 SOCK_PACKET, /* PIO_SOCK_PACKET */
78 #else
79 -1, /* PIO_SOCK_PACKET */
80 #endif
81 #ifdef SOCK_STREAM
82 SOCK_STREAM, /* PIO_SOCK_STREAM */
83 #else
84 -1, /* PIO_SOCK_STREAM */
85 #endif
86 #ifdef SOCK_DGRAM
87 SOCK_DGRAM, /* PIO_SOCK_DGRAM */
88 #else
89 -1, /* PIO_SOCK_DGRAM */
90 #endif
91 #ifdef SOCK_RAW
92 SOCK_RAW, /* PIO_SOCK_RAW */
93 #else
94 -1, /* PIO_SOCK_RAW */
95 #endif
96 #ifdef SOCK_RDM
97 SOCK_RDM, /* PIO_SOCK_RDM */
98 #else
99 -1, /* PIO_SOCK_RDM */
100 #endif
101 #ifdef SOCK_SEQPACKET
102 SOCK_SEQPACKET, /* PIO_SOCK_SEQPACKET */
103 #else
104 -1, /* PIO_SOCK_SEQPACKET */
105 #endif
109 PARROT_EXPORT
110 PARROT_PURE_FUNCTION
111 PARROT_WARN_UNUSED_RESULT
112 PARROT_CANNOT_RETURN_NULL
113 INTVAL
114 Parrot_io_socket_is_closed(ARGMOD(PMC *socket))
116 ASSERT_ARGS(Parrot_io_socket_is_closed)
117 #ifdef PIO_OS_WIN32
118 return (PARROT_SOCKET(socket)->os_handle == (PIOHANDLE)INVALID_HANDLE_VALUE);
119 #endif
120 #ifdef PIO_OS_UNIX
121 return (PARROT_SOCKET(socket)->os_handle == (PIOHANDLE)-1);
122 #endif
123 #ifdef PIO_OS_STDIO
124 return (PARROT_SOCKET(socket)->os_handle == (PIOHANDLE)NULL);
125 #endif
130 =item C<INTVAL Parrot_io_poll(PARROT_INTERP, PMC *pmc, INTVAL which, INTVAL sec,
131 INTVAL usec)>
133 Polls C<*pmc> for the events in C<which> every C<sec> seconds + C<usec>
134 microseconds.
136 =cut
140 PARROT_EXPORT
141 INTVAL
142 Parrot_io_poll(PARROT_INTERP, ARGMOD(PMC *pmc), INTVAL which, INTVAL sec, INTVAL usec)
144 ASSERT_ARGS(Parrot_io_poll)
145 if (PMC_IS_NULL(pmc))
146 Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
147 "Can't poll a NULL socket object");
149 return PIO_POLL(interp, pmc, which, sec, usec);
154 =item C<INTVAL Parrot_io_socket(PARROT_INTERP, PMC *socket, INTVAL fam, INTVAL
155 type, INTVAL proto)>
157 Creates and returns a socket using the specified address family, socket type,
158 and protocol number. Check the returned PMC with a boolean test to see whether
159 the socket was successfully created.
161 =cut
165 PARROT_EXPORT
166 PARROT_WARN_UNUSED_RESULT
167 PARROT_CANNOT_RETURN_NULL
168 INTVAL
169 Parrot_io_socket(PARROT_INTERP, ARGMOD_NULLOK(PMC *socket), INTVAL fam,
170 INTVAL type, INTVAL proto)
172 ASSERT_ARGS(Parrot_io_socket)
173 PMC *new_socket;
175 /* convert Parrot's family to system family */
176 if (fam < 0 || fam >= PIO_PF_MAX)
177 return -1;
178 fam = pio_pf[fam];
179 if (fam < 0)
180 return -1;
182 /* convert Parrot's socket type to system type */
183 if (type < 0 || type >= PIO_SOCK_MAX)
184 return -1;
185 type = pio_sock[type];
186 if (type < 0)
187 return -1;
189 if (PMC_IS_NULL(socket))
190 new_socket = Parrot_io_new_socket_pmc(interp,
191 PIO_F_SOCKET|PIO_F_READ|PIO_F_WRITE);
192 else
193 new_socket = socket;
194 /* XXX new_socket is assigned, but never used. Probably a bug? */
196 return PIO_SOCKET(interp, socket, fam, type, proto);
201 =item C<INTVAL Parrot_io_recv(PARROT_INTERP, PMC *pmc, STRING **buf)>
203 Receives a message from the connected socket C<*pmc> in C<*buf>. Returns C<-1>
204 if it fails.
206 =cut
210 PARROT_EXPORT
211 INTVAL
212 Parrot_io_recv(PARROT_INTERP, ARGMOD(PMC *pmc), ARGOUT(STRING **buf))
214 ASSERT_ARGS(Parrot_io_recv)
215 if (Parrot_io_socket_is_closed(pmc))
216 return -1;
218 return PIO_RECV(interp, pmc, buf);
223 =item C<INTVAL Parrot_io_send(PARROT_INTERP, PMC *pmc, STRING *buf)>
225 Sends the message C<*buf> to the connected socket C<*pmc>. Returns
226 C<-1> if it cannot send the message.
228 =cut
232 PARROT_EXPORT
233 PARROT_WARN_UNUSED_RESULT
234 INTVAL
235 Parrot_io_send(PARROT_INTERP, ARGMOD(PMC *pmc), ARGMOD(STRING *buf))
237 ASSERT_ARGS(Parrot_io_send)
238 if (Parrot_io_socket_is_closed(pmc))
239 return -1;
241 return PIO_SEND(interp, pmc, buf);
246 =item C<INTVAL Parrot_io_connect(PARROT_INTERP, PMC *pmc, PMC *address)>
248 Connects C<*pmc> to C<*address>. Returns C<-1> on failure.
250 =cut
254 PARROT_EXPORT
255 INTVAL
256 Parrot_io_connect(PARROT_INTERP, ARGMOD(PMC *pmc), ARGMOD(PMC *address))
258 ASSERT_ARGS(Parrot_io_connect)
259 if (Parrot_io_socket_is_closed(pmc))
260 return -1;
262 return PIO_CONNECT(interp, pmc, address);
267 =item C<INTVAL Parrot_io_bind(PARROT_INTERP, PMC *pmc, PMC *address)>
269 Binds C<*pmc>'s socket to the local address and port specified by
270 C<*address>. Returns C<-1> on failure.
272 =cut
276 PARROT_EXPORT
277 INTVAL
278 Parrot_io_bind(PARROT_INTERP, ARGMOD(PMC *pmc), ARGMOD(PMC *address))
280 ASSERT_ARGS(Parrot_io_bind)
281 if (Parrot_io_socket_is_closed(pmc))
282 return -1;
284 return PIO_BIND(interp, pmc, address);
289 =item C<INTVAL Parrot_io_listen(PARROT_INTERP, PMC *pmc, INTVAL backlog)>
291 Listens for new connections on socket C<*pmc>. Returns C<-1> on failure.
293 =cut
297 PARROT_EXPORT
298 PARROT_WARN_UNUSED_RESULT
299 INTVAL
300 Parrot_io_listen(PARROT_INTERP, ARGMOD(PMC *pmc), INTVAL backlog)
302 ASSERT_ARGS(Parrot_io_listen)
303 if (Parrot_io_socket_is_closed(pmc))
304 return -1;
306 return PIO_LISTEN(interp, pmc, backlog);
311 =item C<PMC * Parrot_io_accept(PARROT_INTERP, PMC *pmc)>
313 Accepts a new connection and returns a newly created C<ParrotIO> socket.
314 Returns C<NULL> on failure.
316 =cut
320 PARROT_EXPORT
321 PARROT_WARN_UNUSED_RESULT
322 PARROT_CAN_RETURN_NULL
323 PMC *
324 Parrot_io_accept(PARROT_INTERP, ARGMOD(PMC *pmc))
326 ASSERT_ARGS(Parrot_io_accept)
327 if (Parrot_io_socket_is_closed(pmc))
328 return PMCNULL;
330 return PIO_ACCEPT(interp, pmc);
335 =item C<PMC * Parrot_io_new_socket_pmc(PARROT_INTERP, INTVAL flags)>
337 Creates a new I/O socket object. The value of C<flags> is set
338 in the returned PMC.
340 =cut
344 PARROT_EXPORT
345 PARROT_WARN_UNUSED_RESULT
346 PARROT_CANNOT_RETURN_NULL
347 PMC *
348 Parrot_io_new_socket_pmc(PARROT_INTERP, INTVAL flags)
350 ASSERT_ARGS(Parrot_io_new_socket_pmc)
351 PMC * const new_io = Parrot_pmc_new(interp, enum_class_Socket);
353 Parrot_io_set_flags(interp, new_io, flags);
355 return new_io;
359 =back
361 =head1 SEE ALSO
363 F<io/api.c>
365 =cut
372 * Local variables:
373 * c-file-style: "parrot"
374 * End:
375 * vim: expandtab shiftwidth=4: