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  
    111111    port = 1234 
    112112 
    113113    # 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 
    115117    unless listener goto ERR_NO_SOCKET 
    116118 
    117119    # Pack a sockaddr_in structure with IP and port 
    118     address = sockaddr host, port 
     120    address = sock.'sockaddr'(host, port) 
    119121    ret = listener.'bind'(address) 
    120122    if ret == -1 goto ERR_bind 
    121123    $S0 = port 
  • include/parrot/io.h

    diff --git a/include/parrot/io.h b/include/parrot/io.h
    index 88953ab..2efc85b 100644
    a b  
    829829PARROT_EXPORT 
    830830PARROT_WARN_UNUSED_RESULT 
    831831PARROT_CANNOT_RETURN_NULL 
    832 PMC * Parrot_io_socket(PARROT_INTERP, INTVAL fam, INTVAL type, INTVAL proto) 
    833         __attribute__nonnull__(1); 
     832PMC * 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); 
    834839 
    835840PARROT_EXPORT 
    836841PARROT_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  
    11/* io_unix.h 
    22 *  Copyright (C) 2001-2003, Parrot Foundation. 
    33 *  SVN Info 
    4  *     $Id$ 
     4 *     $Id: io_unix.h 36833 2009-02-17 20:09:26Z allison $ 
    55 *  Overview: 
    66 *      Parrot IO subsystem 
    77 *  Data Structure and Algorithms: 
     
    220220 
    221221PARROT_WARN_UNUSED_RESULT 
    222222PARROT_CAN_RETURN_NULL 
    223 PMC * Parrot_io_socket_unix(PARROT_INTERP, int fam, int type, int proto) 
    224         __attribute__nonnull__(1); 
     223PMC * 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); 
    225230 
    226231#define ASSERT_ARGS_Parrot_io_accept_unix __attribute__unused__ int _ASSERT_ARGS_CHECK = \ 
    227232       PARROT_ASSERT_ARG(interp) \ 
     
    249254       PARROT_ASSERT_ARG(interp) \ 
    250255    || PARROT_ASSERT_ARG(addr) 
    251256#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) 
    253259/* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */ 
    254260/* HEADERIZER END: src/io/socket_unix.c */ 
    255261 
     
    275281 
    276282#define PIO_POLL(interp, pmc, which, sec, usec) \ 
    277283    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)) 
    280286#define PIO_RECV(interp, pmc, buf) \ 
    281287    Parrot_io_recv_unix((interp), (pmc), (buf)) 
    282288#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  
    199199 
    200200PARROT_WARN_UNUSED_RESULT 
    201201PARROT_CAN_RETURN_NULL 
    202 PMC * Parrot_io_socket_win32(PARROT_INTERP, int fam, int type, int proto) 
    203         __attribute__nonnull__(1); 
     202PMC * 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); 
    204209 
    205210#define ASSERT_ARGS_Parrot_io_accept_win32 __attribute__unused__ int _ASSERT_ARGS_CHECK = \ 
    206211       PARROT_ASSERT_ARG(interp) \ 
     
    228233       PARROT_ASSERT_ARG(interp) \ 
    229234    || PARROT_ASSERT_ARG(addr) 
    230235#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) 
    232238/* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */ 
    233239/* HEADERIZER END: src/io/socket_win32.c */ 
    234240 
     
    252258 
    253259#define PIO_POLL(interp, pmc, which, sec, usec) \ 
    254260    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)) 
    257263#define PIO_RECV(interp, pmc, buf) \ 
    258264    Parrot_io_recv_win32((interp), (pmc), (buf)) 
    259265#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  
    8383PARROT_WARN_UNUSED_RESULT 
    8484PARROT_CANNOT_RETURN_NULL 
    8585PMC * 
    86 Parrot_io_socket(PARROT_INTERP, INTVAL fam, INTVAL type, INTVAL proto) 
     86Parrot_io_socket(PARROT_INTERP, ARGMOD_NULLOK(PMC * socket), INTVAL fam, 
     87            INTVAL type, INTVAL proto) 
    8788{ 
    8889    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); 
    9099} 
    91100 
    92101/* 
  • 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  
    127127PARROT_WARN_UNUSED_RESULT 
    128128PARROT_CAN_RETURN_NULL 
    129129PMC * 
    130 Parrot_io_socket_unix(PARROT_INTERP, int fam, int type, int proto) 
     130Parrot_io_socket_unix(PARROT_INTERP, ARGIN(PMC *s), int fam, int type, int proto) 
    131131{ 
    132132    ASSERT_ARGS(Parrot_io_socket_unix) 
    133133    int i; 
    134134    const int sock = socket(fam, type, proto); 
    135135    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; 
    141140    } 
    142141    return PMCNULL; 
    143142} 
  • 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  
    7373PARROT_WARN_UNUSED_RESULT 
    7474PARROT_CAN_RETURN_NULL 
    7575PMC * 
    76 Parrot_io_socket_win32(PARROT_INTERP, int fam, int type, int proto) 
     76Parrot_io_socket_win32(PARROT_INTERP, ARGIN(PMC * s), int fam, int type, int proto) 
    7777{ 
    7878    ASSERT_ARGS(Parrot_io_socket_win32) 
    7979    int i; 
    8080    const int sock = socket(fam, type, proto); 
    8181    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); 
    8584        SOCKADDR_REMOTE(io)->sin_family = fam; 
    8685        return io; 
    8786    } 
  • src/ops/io.ops

    diff --git a/src/ops/io.ops b/src/ops/io.ops
    index 52e3b2e..04a9d43 100644
    a b  
    508508 
    509509=item B<socket>(out PMC, in INT, in INT, in INT) 
    510510 
    511 Create new socket 
     511Create new Socket PMC 
    512512 
    513513=cut 
    514514 
    515515op 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); 
    567517} 
    568518 
    569519=back 
  • src/ops/ops.num

    diff --git a/src/ops/ops.num b/src/ops/ops.num
    index df8be16..7748fb7 100644
    a b  
    12801280sockaddr_p_sc_i                1256 
    12811281sockaddr_p_s_ic                1257 
    12821282sockaddr_p_sc_ic               1258 
    1283 bind_i_p_p                     1259 
    1284 bind_i_pc_p                    1260 
    1285 bind_i_p_pc                    1261 
    1286 bind_i_pc_pc                   1262 
    1287 listen_i_p_i                   1263 
    1288 listen_i_pc_i                  1264 
    1289 listen_i_p_ic                  1265 
    1290 listen_i_pc_ic                 1266 
    1291 accept_p_p                     1267 
    1292 accept_p_pc                    1268 
    1293 recv_i_p_s                     1269 
    1294 recv_i_pc_s                    1270 
    1295 send_i_p_s                     1271 
    1296 send_i_pc_s                    1272 
    1297 send_i_p_sc                    1273 
    1298 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  
    3737 
    3838    VTABLE void init() { 
    3939        Parrot_Socket_attributes *data_struct = 
    40                 mem_allocate_typed(Parrot_Socket_attributes); 
     40                mem_allocate_zeroed_typed(Parrot_Socket_attributes); 
    4141 
    4242        PMC_data(SELF)      = data_struct; 
    4343        data_struct->local  = PMCNULL; 
    4444        data_struct->remote = PMCNULL; 
    4545 
    46         /* Initialize the os_handle to the platform-specific value for closed. */ 
    47 #ifdef PIO_OS_WIN32 
    48     data_struct->os_handle    = (PIOHANDLE)INVALID_HANDLE_VALUE; 
    49 #endif 
    50 #ifdef PIO_OS_UNIX 
    51     data_struct->os_handle    = (PIOHANDLE)-1; 
    52 #endif 
    53 #ifdef PIO_OS_STDIO 
    54     data_struct->os_handle    = (PIOHANDLE)NULL; 
    55 #endif 
    56  
    5746        PObj_custom_mark_destroy_SETALL(SELF); 
    5847    } 
    5948 
     
    6857*/ 
    6958 
    7059    VTABLE PMC *clone() { 
    71         Parrot_Socket_attributes * const old_struct  = PARROT_SOCKET(SELF); 
    72         PMC * 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); 
    7362        Parrot_Socket_attributes * const data_struct = PARROT_SOCKET(copy); 
    7463 
    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); 
    7666 
    7767        return SELF; 
    7868    } 
     
    115105        } 
    116106    } 
    117107 
    118     METHOD close() { 
    119         INTVAL status = 0; 
    120         close(PARROT_SOCKET(SELF)->os_handle); 
    121         RETURN(INTVAL status); 
    122     } 
     108/* 
    123109 
     110=item C<INTVAL get_bool()> 
     111 
     112Returns 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    } 
    124130 
    125131/* 
    126132 
     
    130136 
    131137=over 4 
    132138 
     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 
     155C<sockaddr> returns an object representing a socket address, generated 
     156from 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 
    133169=item C<connect> 
    134170 
    135171Connects a socket object to an address. 
     
    191227        RETURN(INTVAL res); 
    192228    } 
    193229 
     230/* 
     231 
     232=item C<bind> 
     233 
     234C<bind> binds a socket object to the port and address specified by an 
     235address object (the packed result of C<sockaddr>). 
     236 
     237The asynchronous version takes an additional final PMC callback 
     238argument, and only returns a status object. When the bind operation is 
     239complete, it invokes the callback, passing it a status object and the 
     240socket object it was called on. [If you want notification when a bind 
     241operation is completed, you probably want to do something with that 
     242bound socket object.] 
     243 
     244=cut 
     245 
     246*/ 
     247 
    194248    METHOD bind(PMC *host) { 
    195249        INTVAL res = Parrot_io_bind(INTERP, SELF, host); 
    196250        RETURN(INTVAL res); 
    197251    } 
    198252 
     253/* 
     254 
     255=item C<listen> 
     256 
     257C<listen> specifies that a socket object is willing to accept incoming 
     258connections. The integer argument gives the maximum size of the queue 
     259for pending connections. 
     260 
     261There is no asynchronous version. C<listen> marks a set of attributes on 
     262the socket object. 
     263 
     264=cut 
     265 
     266*/ 
     267 
    199268    METHOD listen(INTVAL backlog) { 
    200269        INTVAL res = Parrot_io_listen(INTERP, SELF, backlog); 
    201270        RETURN(INTVAL res); 
    202271    } 
    203272 
     273/* 
     274 
     275=item C<accept> 
     276 
     277C<accept> accepts a new connection on a given socket object, and returns 
     278a newly created socket object for the connection. 
     279 
     280The asynchronous version takes an additional final PMC callback 
     281argument, and only returns a status object. When the accept operation 
     282receives a new connection, it invokes the callback, passing it a status 
     283object and a newly created socket object for the connection. [While the 
     284synchronous C<accept> has to be called repeatedly in a loop (once for 
     285each connection received), the asynchronous version is only called once, 
     286but continues to send new connection events until the socket is closed.] 
     287 
     288=cut 
     289 
     290*/ 
     291 
    204292    METHOD accept() { 
    205293        PMC * res = Parrot_io_accept(INTERP, SELF); 
    206294        RETURN(PMC * res);