Пример #1
0
INTVAL
Parrot_io_connect_win32(PARROT_INTERP, ARGMOD(PMC *socket), ARGIN(PMC *r))
{
    ASSERT_ARGS(Parrot_io_connect_win32)
    const Parrot_Socket_attributes * const io = PARROT_SOCKET(socket);

    if (!r)
        return -1;

    PARROT_SOCKET(socket)->remote = r;

AGAIN:
    if ((connect((int)io->os_handle, (struct sockaddr *)SOCKADDR_REMOTE(socket),
                 sizeof (struct sockaddr_in))) != 0) {
        switch (errno) {
        case WSAEINTR:
            goto AGAIN;
        case WSAEINPROGRESS:
            goto AGAIN;
        case WSAEISCONN:
            return 0;
        default:
            return -1;
        }
    }

    return 0;
}
Пример #2
0
PARROT_WARN_UNUSED_RESULT
PARROT_CAN_RETURN_NULL
PMC *
Parrot_io_accept_win32(PARROT_INTERP, ARGMOD(PMC *socket))
{
    ASSERT_ARGS(Parrot_io_accept_win32)
    const Parrot_Socket_attributes * const io = PARROT_SOCKET(socket);
    PMC * newio   = Parrot_io_new_socket_pmc(interp,
                    PIO_F_SOCKET | PIO_F_READ|PIO_F_WRITE);
    Parrot_Socklen_t    addrlen = sizeof (struct sockaddr_in);
    struct sockaddr_in *saddr;
    int newsock;

    PARROT_SOCKET(newio)->local  = PARROT_SOCKET(socket)->local;
    PARROT_SOCKET(newio)->remote = Parrot_pmc_new(interp, enum_class_Sockaddr);
    saddr                        = SOCKADDR_REMOTE(newio);

    newsock = accept((int)io->os_handle, (struct sockaddr *)saddr, &addrlen);

    if (newsock == -1) {
        return PMCNULL;
    }

    PARROT_SOCKET(newio)->os_handle = (void*)newsock;

    /* XXX FIXME: Need to do a getsockname and getpeername here to
     * fill in the sockaddr_in structs for local and peer */

    /* Optionally do a gethostyaddr() to resolve remote IP address.
     * This should be based on an option set in the master socket */

    return newio;
}
Пример #3
0
PARROT_EXPORT
void
Parrot_io_socket_initialize_handle(SHIM_INTERP, ARGMOD(PMC *socket))
{
    ASSERT_ARGS(Parrot_io_socket_initialize_handle)
    PARROT_SOCKET(socket)->os_handle = (PIOHANDLE)PIO_INVALID_HANDLE;
}
Пример #4
0
INTVAL
Parrot_io_listen_win32(SHIM_INTERP, ARGMOD(PMC *socket), INTVAL sec)
{
    ASSERT_ARGS(Parrot_io_listen_win32)
    const Parrot_Socket_attributes * const io = PARROT_SOCKET(socket);
    if ((listen((int)io->os_handle, sec)) == -1) {
        return -1;
    }
    return 0;
}
Пример #5
0
INTVAL
Parrot_io_bind_win32(PARROT_INTERP, ARGMOD(PMC *socket), ARGMOD(PMC *sockaddr))
{
    ASSERT_ARGS(Parrot_io_bind_win32)
    const Parrot_Socket_attributes * const io = PARROT_SOCKET(socket);
    struct sockaddr_in * saddr;

    if (!sockaddr)
        return -1;

    PARROT_SOCKET(socket)->local = sockaddr;

    saddr = SOCKADDR_LOCAL(socket);

    if ((bind((int)io->os_handle, (struct sockaddr *) saddr,
              sizeof (struct sockaddr_in))) == -1) {
        return -1;
    }

    return 0;
}
Пример #6
0
PARROT_EXPORT
INTVAL
Parrot_io_poll_handle(PARROT_INTERP, ARGMOD(PMC *pmc), INTVAL which, INTVAL sec, INTVAL usec)
{
    ASSERT_ARGS(Parrot_io_poll_handle)
    Parrot_Socket_attributes *io = PARROT_SOCKET(pmc);

    if (Parrot_io_socket_is_closed(interp, pmc))
        Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_PIO_ERROR,
                "Can't poll closed socket");

    return Parrot_io_poll(interp, io->os_handle, which, sec, usec);
}
Пример #7
0
PARROT_EXPORT
PARROT_WARN_UNUSED_RESULT
INTVAL
Parrot_io_send_handle(PARROT_INTERP, ARGMOD(PMC *pmc), ARGMOD(STRING *buf))
{
    ASSERT_ARGS(Parrot_io_send_handle)
    Parrot_Socket_attributes *io = PARROT_SOCKET(pmc);

    if (Parrot_io_socket_is_closed(interp, pmc))
        Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_PIO_ERROR,
                "Can't send to closed socket");

    return Parrot_io_send(interp, io->os_handle, buf->strstart, buf->bufused);
}
Пример #8
0
PARROT_EXPORT
PARROT_CANNOT_RETURN_NULL
STRING *
Parrot_io_recv_handle(PARROT_INTERP, ARGMOD(PMC *pmc), size_t len)
{
    ASSERT_ARGS(Parrot_io_recv_handle)
    Parrot_Socket_attributes *io = PARROT_SOCKET(pmc);
    STRING *res;
    INTVAL  received;

    if (Parrot_io_socket_is_closed(interp, pmc))
        Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_PIO_ERROR,
                "Can't recv from closed socket");

    /* This must stay ASCII to make Rakudo and UTF-8 work for now */
    res      = Parrot_str_new_noinit(interp, len);
    received = Parrot_io_recv(interp, io->os_handle, res->strstart, len);

    res->bufused = received;
    res->strlen  = received;

    return res;
}
Пример #9
0
/*

=item C<INTVAL Parrot_io_send_win32(PARROT_INTERP, PMC *socket, STRING *s)>

Send the message C<*s> to C<*io>'s connected socket.

=cut

*/

INTVAL
Parrot_io_send_win32(SHIM_INTERP, ARGMOD(PMC *socket), ARGMOD(STRING *s))
{
    ASSERT_ARGS(Parrot_io_send_win32)
    int error, bytes, byteswrote;
    const Parrot_Socket_attributes * const io = PARROT_SOCKET(socket);

    bytes = s->bufused;
    byteswrote = 0;
AGAIN:
    /*
     * Ignore encoding issues for now.
     */
    if ((error = send((int)io->os_handle, (char *)s->strstart + byteswrote,
                      bytes, 0)) >= 0) {
        byteswrote += error;
        bytes -= error;
        if (!bytes) {
            return byteswrote;
        }
        goto AGAIN;
Пример #10
0
/*

=item C<void Parrot_io_connect_handle(PARROT_INTERP, PMC *pmc, PMC *address)>

Connects C<*pmc> to C<*address>.

=cut

*/

PARROT_EXPORT
void
Parrot_io_connect_handle(PARROT_INTERP, ARGMOD(PMC *pmc), ARGMOD(PMC *address))
{
    ASSERT_ARGS(Parrot_io_connect_handle)
    Parrot_Socket_attributes * const io = PARROT_SOCKET(pmc);
    int i;

    if (Parrot_io_socket_is_closed(interp, pmc))
        Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_PIO_ERROR,
                "Can't connect closed socket");
    if (PMC_IS_NULL(address))
        Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_PIO_ERROR,
                "Address is null");

    /* Iterate over all addresses if an array is passed */
    if (address->vtable->base_type != enum_class_Sockaddr) {
        INTVAL len = VTABLE_elements(interp, address);

        for (i = 0; i < len; ++i) {
            PMC *sa = VTABLE_get_pmc_keyed_int(interp, address, i);