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.
20 int rwx; /* 4=except 2=write 1=read */
21 uxsel_callback_fn callback;
22 int id; /* for uxsel_input_remove */
27 static int uxsel_fd_cmp(void *av, void *bv)
29 struct fd *a = (struct fd *)av;
30 struct fd *b = (struct fd *)bv;
37 static int uxsel_fd_findcmp(void *av, void *bv)
40 struct fd *b = (struct fd *)bv;
50 fds = newtree234(uxsel_fd_cmp);
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
63 void uxsel_set(int fd, int rwx, uxsel_callback_fn callback)
65 struct fd *newfd = snew(struct fd);
70 newfd->callback = callback;
72 oldfd = find234(fds, newfd, NULL);
74 uxsel_input_remove(oldfd->id);
80 newfd->id = uxsel_input_add(fd, rwx);
83 void uxsel_del(int fd)
85 struct fd *oldfd = find234(fds, &fd, uxsel_fd_findcmp);
87 uxsel_input_remove(oldfd->id);
94 * And here is the interface to select-functionality-supplying
98 int next_fd(int *state, int *rwx)
101 fd = index234(fds, (*state)++);
109 int first_fd(int *state, int *rwx)
112 return next_fd(state, rwx);
115 int select_result(int fd, int event)
117 struct fd *fdstruct = find234(fds, &fd, uxsel_fd_findcmp);
119 * Apparently this can sometimes be NULL. Can't see how, but I
120 * assume it means I need to ignore the event since it's on an
121 * fd I've stopped being interested in. Sigh.
124 return fdstruct->callback(fd, event);