Welcome to mirror list, hosted at ThFree Co, Russian Federation.

select-cli.c « windows - github.com/mRemoteNG/PuTTYNG.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 9bf8411ed6f17f4e168701165cb2cb1e6d3d9fa1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
/*
 * Implementation of do_select() for network.c to use, suitable for use
 * when there's no GUI window to have network activity reported to.
 *
 * It uses WSAEventSelect, where available, to convert network
 * activity into activity on an event object, for integration into an
 * event loop that includes WaitForMultipleObjects.
 *
 * It also maintains a list of currently active sockets, which can be
 * retrieved by a front end that wants to use WinSock's synchronous
 * select() function.
 */

#include "putty.h"

static tree234 *winselcli_sockets;

static int socket_cmp(void *av, void *bv)
{
    return memcmp(av, bv, sizeof(SOCKET));
} 

HANDLE winselcli_event = INVALID_HANDLE_VALUE;

void winselcli_setup(void)
{
    if (!winselcli_sockets)
        winselcli_sockets = newtree234(socket_cmp);

    if (p_WSAEventSelect && winselcli_event == INVALID_HANDLE_VALUE)
        winselcli_event = CreateEvent(NULL, false, false, NULL);
}

SOCKET winselcli_unique_socket(void)
{
    if (!winselcli_sockets)
        return INVALID_SOCKET;

    assert(count234(winselcli_sockets) <= 1);

    SOCKET *p = index234(winselcli_sockets, 0);
    if (!p)
        return INVALID_SOCKET;

    return *p;
}

const char *do_select(SOCKET skt, bool enable)
{
    /* Check everything's been set up, for convenience of callers. */
    winselcli_setup();

    if (enable) {
        SOCKET *ptr = snew(SOCKET);
        *ptr = skt;
        if (add234(winselcli_sockets, ptr) != ptr)
            sfree(ptr);                /* already there */
    } else {
        SOCKET *ptr = del234(winselcli_sockets, &skt);
        if (ptr)
            sfree(ptr);
    }

    if (p_WSAEventSelect) {
        int events;
        if (enable) {
            events = (FD_CONNECT | FD_READ | FD_WRITE |
                      FD_OOB | FD_CLOSE | FD_ACCEPT);
        } else {
            events = 0;
        }

        if (p_WSAEventSelect(skt, winselcli_event, events) == SOCKET_ERROR)
            return winsock_error_string(p_WSAGetLastError());
    }

    return NULL;
}