Ticket #514: socket2.patch
File socket2.patch, 14.8 KB (added by bacek, 13 years ago) |
---|
-
examples/io/httpd.pir
diff --git a/examples/io/httpd.pir b/examples/io/httpd.pir index fe6a1c1..01a596c 100644
a b 111 111 port = 1234 112 112 113 113 # TODO provide sys/socket constants 114 listener = socket 2, 1, 6 # PF_INET, SOCK_STREAM, tcp 114 .local pmc sock 115 sock = new 'Socket' 116 listener = sock.'socket'(2, 1, 6) # PF_INET, SOCK_STREAM, tcp 115 117 unless listener goto ERR_NO_SOCKET 116 118 117 119 # Pack a sockaddr_in structure with IP and port 118 address = sock addr host, port120 address = sock.'sockaddr'(host, port) 119 121 ret = listener.'bind'(address) 120 122 if ret == -1 goto ERR_bind 121 123 $S0 = port -
include/parrot/io.h
diff --git a/include/parrot/io.h b/include/parrot/io.h index 88953ab..2efc85b 100644
a b 829 829 PARROT_EXPORT 830 830 PARROT_WARN_UNUSED_RESULT 831 831 PARROT_CANNOT_RETURN_NULL 832 PMC * Parrot_io_socket(PARROT_INTERP, INTVAL fam, INTVAL type, INTVAL proto) 833 __attribute__nonnull__(1); 832 PMC * Parrot_io_socket(PARROT_INTERP, 833 ARGMOD_NULLOK(PMC * socket), 834 INTVAL fam, 835 INTVAL type, 836 INTVAL proto) 837 __attribute__nonnull__(1) 838 FUNC_MODIFIES(* socket); 834 839 835 840 PARROT_EXPORT 836 841 PARROT_WARN_UNUSED_RESULT -
include/parrot/io_unix.h
diff --git a/include/parrot/io_unix.h b/include/parrot/io_unix.h index 4dd53cb..307f94c 100644
a b 1 1 /* io_unix.h 2 2 * Copyright (C) 2001-2003, Parrot Foundation. 3 3 * SVN Info 4 * $Id $4 * $Id: io_unix.h 36833 2009-02-17 20:09:26Z allison $ 5 5 * Overview: 6 6 * Parrot IO subsystem 7 7 * Data Structure and Algorithms: … … 220 220 221 221 PARROT_WARN_UNUSED_RESULT 222 222 PARROT_CAN_RETURN_NULL 223 PMC * Parrot_io_socket_unix(PARROT_INTERP, int fam, int type, int proto) 224 __attribute__nonnull__(1); 223 PMC * Parrot_io_socket_unix(PARROT_INTERP, 224 ARGIN(PMC *s), 225 int fam, 226 int type, 227 int proto) 228 __attribute__nonnull__(1) 229 __attribute__nonnull__(2); 225 230 226 231 #define ASSERT_ARGS_Parrot_io_accept_unix __attribute__unused__ int _ASSERT_ARGS_CHECK = \ 227 232 PARROT_ASSERT_ARG(interp) \ … … 249 254 PARROT_ASSERT_ARG(interp) \ 250 255 || PARROT_ASSERT_ARG(addr) 251 256 #define ASSERT_ARGS_Parrot_io_socket_unix __attribute__unused__ int _ASSERT_ARGS_CHECK = \ 252 PARROT_ASSERT_ARG(interp) 257 PARROT_ASSERT_ARG(interp) \ 258 || PARROT_ASSERT_ARG(s) 253 259 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */ 254 260 /* HEADERIZER END: src/io/socket_unix.c */ 255 261 … … 275 281 276 282 #define PIO_POLL(interp, pmc, which, sec, usec) \ 277 283 Parrot_io_poll_unix((interp), (pmc), (which), (sec), (usec)) 278 #define PIO_ NEW_SOCKET(interp, fam, type, proto) \279 Parrot_io_socket_unix((interp), ( fam), (type), (proto))284 #define PIO_SOCKET(interp, socket, fam, type, proto) \ 285 Parrot_io_socket_unix((interp), (socket), (fam), (type), (proto)) 280 286 #define PIO_RECV(interp, pmc, buf) \ 281 287 Parrot_io_recv_unix((interp), (pmc), (buf)) 282 288 #define PIO_SEND(interp, pmc, buf) \ -
include/parrot/io_win32.h
diff --git a/include/parrot/io_win32.h b/include/parrot/io_win32.h index 96f943f..b39d8fd 100644
a b 199 199 200 200 PARROT_WARN_UNUSED_RESULT 201 201 PARROT_CAN_RETURN_NULL 202 PMC * Parrot_io_socket_win32(PARROT_INTERP, int fam, int type, int proto) 203 __attribute__nonnull__(1); 202 PMC * Parrot_io_socket_win32(PARROT_INTERP, 203 ARGIN(PMC * s), 204 int fam, 205 int type, 206 int proto) 207 __attribute__nonnull__(1) 208 __attribute__nonnull__(2); 204 209 205 210 #define ASSERT_ARGS_Parrot_io_accept_win32 __attribute__unused__ int _ASSERT_ARGS_CHECK = \ 206 211 PARROT_ASSERT_ARG(interp) \ … … 228 233 PARROT_ASSERT_ARG(interp) \ 229 234 || PARROT_ASSERT_ARG(addr) 230 235 #define ASSERT_ARGS_Parrot_io_socket_win32 __attribute__unused__ int _ASSERT_ARGS_CHECK = \ 231 PARROT_ASSERT_ARG(interp) 236 PARROT_ASSERT_ARG(interp) \ 237 || PARROT_ASSERT_ARG(s) 232 238 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */ 233 239 /* HEADERIZER END: src/io/socket_win32.c */ 234 240 … … 252 258 253 259 #define PIO_POLL(interp, pmc, which, sec, usec) \ 254 260 Parrot_io_poll_win32((interp), (pmc), (which), (sec), (usec)) 255 #define PIO_ NEW_SOCKET(interp, fam, type, proto) \256 Parrot_io_socket_win32((interp), ( fam), (type), (proto))261 #define PIO_SOCKET(interp, socket, fam, type, proto) \ 262 Parrot_io_socket_win32((interp), (socket), (fam), (type), (proto)) 257 263 #define PIO_RECV(interp, pmc, buf) \ 258 264 Parrot_io_recv_win32((interp), (pmc), (buf)) 259 265 #define PIO_SEND(interp, pmc, buf) \ -
src/io/socket_api.c
diff --git a/src/io/socket_api.c b/src/io/socket_api.c index fe25f94..d148018 100644
a b 83 83 PARROT_WARN_UNUSED_RESULT 84 84 PARROT_CANNOT_RETURN_NULL 85 85 PMC * 86 Parrot_io_socket(PARROT_INTERP, INTVAL fam, INTVAL type, INTVAL proto) 86 Parrot_io_socket(PARROT_INTERP, ARGMOD_NULLOK(PMC * socket), INTVAL fam, 87 INTVAL type, INTVAL proto) 87 88 { 88 89 ASSERT_ARGS(Parrot_io_socket) 89 return PIO_NEW_SOCKET(interp, fam, type, proto); 90 PMC *new_socket; 91 92 if (PMC_IS_NULL(socket)) 93 new_socket = Parrot_io_new_socket_pmc(interp, 94 PIO_F_SOCKET|PIO_F_READ|PIO_F_WRITE); 95 else 96 new_socket = socket; 97 98 return PIO_SOCKET(interp, socket, fam, type, proto); 90 99 } 91 100 92 101 /* -
src/io/socket_unix.c
diff --git a/src/io/socket_unix.c b/src/io/socket_unix.c index db52817..1362e62 100644
a b 127 127 PARROT_WARN_UNUSED_RESULT 128 128 PARROT_CAN_RETURN_NULL 129 129 PMC * 130 Parrot_io_socket_unix(PARROT_INTERP, int fam, int type, int proto)130 Parrot_io_socket_unix(PARROT_INTERP, ARGIN(PMC *s), int fam, int type, int proto) 131 131 { 132 132 ASSERT_ARGS(Parrot_io_socket_unix) 133 133 int i; 134 134 const int sock = socket(fam, type, proto); 135 135 if (sock >= 0) { 136 PMC * io = Parrot_io_new_socket_pmc(interp, PIO_F_SOCKET|PIO_F_READ|PIO_F_WRITE); 137 PARROT_SOCKET(io)->os_handle = sock; 138 setsockopt(PARROT_SOCKET(io)->os_handle, SOL_SOCKET, SO_REUSEADDR, &i, sizeof (i)); 139 SOCKADDR_REMOTE(io)->sin_family = fam; 140 return io; 136 setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &i, sizeof (i)); 137 Parrot_io_set_os_handle(interp, s, sock); 138 SOCKADDR_REMOTE(s)->sin_family = fam; 139 return s; 141 140 } 142 141 return PMCNULL; 143 142 } -
src/io/socket_win32.c
diff --git a/src/io/socket_win32.c b/src/io/socket_win32.c index 1f07d5b..b458313 100644
a b 73 73 PARROT_WARN_UNUSED_RESULT 74 74 PARROT_CAN_RETURN_NULL 75 75 PMC * 76 Parrot_io_socket_win32(PARROT_INTERP, int fam, int type, int proto)76 Parrot_io_socket_win32(PARROT_INTERP, ARGIN(PMC * s), int fam, int type, int proto) 77 77 { 78 78 ASSERT_ARGS(Parrot_io_socket_win32) 79 79 int i; 80 80 const int sock = socket(fam, type, proto); 81 81 if (sock >= 0) { 82 PMC * io = Parrot_io_new_socket_pmc(interp, PIO_F_SOCKET|PIO_F_READ|PIO_F_WRITE); 83 PARROT_SOCKET(io)->os_handle = (void*)sock; 84 setsockopt((int)PARROT_SOCKET(io)->os_handle, SOL_SOCKET, SO_REUSEADDR, &i, sizeof (i)); 82 setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &i, sizeof (i)); 83 Parrot_io_set_os_handle(interp, s, sock); 85 84 SOCKADDR_REMOTE(io)->sin_family = fam; 86 85 return io; 87 86 } -
src/ops/io.ops
diff --git a/src/ops/io.ops b/src/ops/io.ops index 52e3b2e..04a9d43 100644
a b 508 508 509 509 =item B<socket>(out PMC, in INT, in INT, in INT) 510 510 511 Create new socket511 Create new Socket PMC 512 512 513 513 =cut 514 514 515 515 op socket(out PMC, in INT, in INT, in INT) { 516 $1 = Parrot_io_socket(interp, $2, $3, $4); 517 } 518 519 =item B<bind>(out INT, in PMC, in PMC) 520 521 Bind socket to address 522 523 =cut 524 525 op bind(out INT, in PMC, in PMC) { 526 $1 = Parrot_io_bind(interp, $2, $3); 527 } 528 529 =item B<listen>(out INT, in PMC, in INT) 530 531 Start listening on previously bound socket 532 533 =cut 534 535 op listen(out INT, in PMC, in INT) { 536 $1 = Parrot_io_listen(interp, $2, $3); 537 } 538 539 =item B<accept>(out PMC, in PMC) 540 541 Accept incoming connection 542 543 =cut 544 545 op accept(out PMC, in PMC) { 546 $1 = Parrot_io_accept(interp, $2); 547 } 548 549 =item B<recv>(out INT, in PMC, out STR) 550 551 Receive data from socket 552 553 =cut 554 555 op recv(out INT, in PMC, out STR) { 556 $1 = Parrot_io_recv(interp, $2, &$3); 557 } 558 559 =item B<send>(out INT, in PMC, in STR) 560 561 Send data to socket 562 563 =cut 564 565 op send(out INT, in PMC, in STR) { 566 $1 = Parrot_io_send(interp, $2, $3); 516 $1 = Parrot_io_socket(interp, PMCNULL, $2, $3, $4); 567 517 } 568 518 569 519 =back -
src/ops/ops.num
diff --git a/src/ops/ops.num b/src/ops/ops.num index df8be16..7748fb7 100644
a b 1280 1280 sockaddr_p_sc_i 1256 1281 1281 sockaddr_p_s_ic 1257 1282 1282 sockaddr_p_sc_ic 1258 1283 bind_i_p_p 12591284 bind_i_pc_p 12601285 bind_i_p_pc 12611286 bind_i_pc_pc 12621287 listen_i_p_i 12631288 listen_i_pc_i 12641289 listen_i_p_ic 12651290 listen_i_pc_ic 12661291 accept_p_p 12671292 accept_p_pc 12681293 recv_i_p_s 12691294 recv_i_pc_s 12701295 send_i_p_s 12711296 send_i_pc_s 12721297 send_i_p_sc 12731298 send_i_pc_sc 1274 -
src/pmc/socket.pmc
diff --git a/src/pmc/socket.pmc b/src/pmc/socket.pmc index 9f71c17..ae8664e 100644
a b 37 37 38 38 VTABLE void init() { 39 39 Parrot_Socket_attributes *data_struct = 40 mem_allocate_ typed(Parrot_Socket_attributes);40 mem_allocate_zeroed_typed(Parrot_Socket_attributes); 41 41 42 42 PMC_data(SELF) = data_struct; 43 43 data_struct->local = PMCNULL; 44 44 data_struct->remote = PMCNULL; 45 45 46 /* Initialize the os_handle to the platform-specific value for closed. */47 #ifdef PIO_OS_WIN3248 data_struct->os_handle = (PIOHANDLE)INVALID_HANDLE_VALUE;49 #endif50 #ifdef PIO_OS_UNIX51 data_struct->os_handle = (PIOHANDLE)-1;52 #endif53 #ifdef PIO_OS_STDIO54 data_struct->os_handle = (PIOHANDLE)NULL;55 #endif56 57 46 PObj_custom_mark_destroy_SETALL(SELF); 58 47 } 59 48 … … 68 57 */ 69 58 70 59 VTABLE PMC *clone() { 71 P arrot_Socket_attributes * const old_struct = PARROT_SOCKET(SELF);72 P MC * const copy = Parrot_io_new_socket_pmc(interp, old_struct->flags);60 PMC * copy = SUPER(); 61 Parrot_Socket_attributes * const old_struct = PARROT_SOCKET(SELF); 73 62 Parrot_Socket_attributes * const data_struct = PARROT_SOCKET(copy); 74 63 75 data_struct->os_handle = Parrot_dup(old_struct->os_handle); 64 data_struct->local = VTABLE_clone(interp, old_struct->local); 65 data_struct->remote = VTABLE_clone(interp, old_struct->remote); 76 66 77 67 return SELF; 78 68 } … … 115 105 } 116 106 } 117 107 118 METHOD close() { 119 INTVAL status = 0; 120 close(PARROT_SOCKET(SELF)->os_handle); 121 RETURN(INTVAL status); 122 } 108 /* 123 109 110 =item C<INTVAL get_bool()> 111 112 Returns whether the Socket was successfully created. 113 114 =cut 115 116 */ 117 118 VTABLE INTVAL get_bool() { 119 /* Initialize the os_handle to the platform-specific value for closed. */ 120 #ifdef PIO_OS_WIN32 121 return (PARROT_SOCKET(SELF)->os_handle != (PIOHANDLE)INVALID_HANDLE_VALUE); 122 #endif 123 #ifdef PIO_OS_UNIX 124 return (PARROT_SOCKET(SELF)->os_handle != (PIOHANDLE)-1); 125 #endif 126 #ifdef PIO_OS_STDIO 127 return (PARROT_SOCKET(SELF)->os_handle != (PIOHANDLE)NULL); 128 #endif 129 } 124 130 125 131 /* 126 132 … … 130 136 131 137 =over 4 132 138 139 =item C<socket> 140 141 =cut 142 143 */ 144 145 146 METHOD socket(INTVAL type, INTVAL fam, INTVAL proto) { 147 PMC * res = Parrot_io_socket(interp, SELF, type, fam, proto); 148 RETURN(PMC * res); 149 } 150 151 /* 152 153 =item C<sockaddr> 154 155 C<sockaddr> returns an object representing a socket address, generated 156 from a port number (integer) and an address (string). 157 158 =cut 159 160 */ 161 162 METHOD sockaddr(STRING * address, INTVAL port) { 163 PMC * res = Parrot_io_sockaddr_in(interp, address, port); 164 RETURN(PMC * res); 165 } 166 167 /* 168 133 169 =item C<connect> 134 170 135 171 Connects a socket object to an address. … … 191 227 RETURN(INTVAL res); 192 228 } 193 229 230 /* 231 232 =item C<bind> 233 234 C<bind> binds a socket object to the port and address specified by an 235 address object (the packed result of C<sockaddr>). 236 237 The asynchronous version takes an additional final PMC callback 238 argument, and only returns a status object. When the bind operation is 239 complete, it invokes the callback, passing it a status object and the 240 socket object it was called on. [If you want notification when a bind 241 operation is completed, you probably want to do something with that 242 bound socket object.] 243 244 =cut 245 246 */ 247 194 248 METHOD bind(PMC *host) { 195 249 INTVAL res = Parrot_io_bind(INTERP, SELF, host); 196 250 RETURN(INTVAL res); 197 251 } 198 252 253 /* 254 255 =item C<listen> 256 257 C<listen> specifies that a socket object is willing to accept incoming 258 connections. The integer argument gives the maximum size of the queue 259 for pending connections. 260 261 There is no asynchronous version. C<listen> marks a set of attributes on 262 the socket object. 263 264 =cut 265 266 */ 267 199 268 METHOD listen(INTVAL backlog) { 200 269 INTVAL res = Parrot_io_listen(INTERP, SELF, backlog); 201 270 RETURN(INTVAL res); 202 271 } 203 272 273 /* 274 275 =item C<accept> 276 277 C<accept> accepts a new connection on a given socket object, and returns 278 a newly created socket object for the connection. 279 280 The asynchronous version takes an additional final PMC callback 281 argument, and only returns a status object. When the accept operation 282 receives a new connection, it invokes the callback, passing it a status 283 object and a newly created socket object for the connection. [While the 284 synchronous C<accept> has to be called repeatedly in a loop (once for 285 each connection received), the asynchronous version is only called once, 286 but continues to send new connection events until the socket is closed.] 287 288 =cut 289 290 */ 291 204 292 METHOD accept() { 205 293 PMC * res = Parrot_io_accept(INTERP, SELF); 206 294 RETURN(PMC * res);