source: filezilla/trunk/fuentes/src/putty/unix/uxsel.c @ 3185

Last change on this file since 3185 was 3185, checked in by jrpelegrina, 3 years ago

Update new version: 3.15.02

File size: 2.7 KB
Line 
1/*
2 * uxsel.c
3 *
4 * This module is a sort of all-purpose interchange for file
5 * descriptors. At one end it talks to uxnet.c and pty.c and
6 * anything else which might have one or more fds that need
7 * select()-type things doing to them during an extended program
8 * run; at the other end it talks to pterm.c or uxplink.c or
9 * anything else which might have its own means of actually doing
10 * those select()-type things.
11 */
12
13#include <assert.h>
14
15#include "putty.h"
16#include "tree234.h"
17
18struct fd {
19    int fd;
20    int rwx;                           /* 4=except 2=write 1=read */
21    uxsel_callback_fn callback;
22    uxsel_id *id;                      /* for uxsel_input_remove */
23};
24
25static tree234 *fds;
26
27static int uxsel_fd_cmp(void *av, void *bv)
28{
29    struct fd *a = (struct fd *)av;
30    struct fd *b = (struct fd *)bv;
31    if (a->fd < b->fd)
32        return -1;
33    if (a->fd > b->fd)
34        return +1;
35    return 0;
36}
37static int uxsel_fd_findcmp(void *av, void *bv)
38{
39    int *a = (int *)av;
40    struct fd *b = (struct fd *)bv;
41    if (*a < b->fd)
42        return -1;
43    if (*a > b->fd)
44        return +1;
45    return 0;
46}
47
48void uxsel_init(void)
49{
50    fds = newtree234(uxsel_fd_cmp);
51}
52
53/*
54 * Here is the interface to fd-supplying modules. They supply an
55 * fd, a set of read/write/execute states, and a callback function
56 * for when the fd satisfies one of those states. Repeated calls to
57 * uxsel_set on the same fd are perfectly legal and serve to change
58 * the rwx state (typically you only want to select an fd for
59 * writing when you actually have pending data you want to write to
60 * it!).
61 */
62
63void uxsel_set(int fd, int rwx, uxsel_callback_fn callback)
64{
65    struct fd *newfd;
66
67    assert(fd >= 0);
68
69    uxsel_del(fd);
70
71    if (rwx) {
72        newfd = snew(struct fd);
73        newfd->fd = fd;
74        newfd->rwx = rwx;
75        newfd->callback = callback;
76        newfd->id = uxsel_input_add(fd, rwx);
77        add234(fds, newfd);
78    }
79}
80
81void uxsel_del(int fd)
82{
83    struct fd *oldfd = find234(fds, &fd, uxsel_fd_findcmp);
84    if (oldfd) {
85        if (oldfd->id)
86            uxsel_input_remove(oldfd->id);
87        del234(fds, oldfd);
88        sfree(oldfd);
89    }
90}
91
92/*
93 * And here is the interface to select-functionality-supplying
94 * modules.
95 */
96
97int next_fd(int *state, int *rwx)
98{
99    struct fd *fd;
100    fd = index234(fds, (*state)++);
101    if (fd) {
102        *rwx = fd->rwx;
103        return fd->fd;
104    } else
105        return -1;
106}
107
108int first_fd(int *state, int *rwx)
109{
110    *state = 0;
111    return next_fd(state, rwx);
112}
113
114int select_result(int fd, int event)
115{
116    struct fd *fdstruct = find234(fds, &fd, uxsel_fd_findcmp);
117    /*
118     * Apparently this can sometimes be NULL. Can't see how, but I
119     * assume it means I need to ignore the event since it's on an
120     * fd I've stopped being interested in. Sigh.
121     */
122    if (fdstruct)
123        return fdstruct->callback(fd, event);
124    else
125        return 1;
126}
Note: See TracBrowser for help on using the repository browser.