1
0
mirror of https://git.tartarus.org/simon/putty.git synced 2025-01-09 01:18:00 +00:00
putty-source/unix/uxsel.c
Simon Tatham 5d718ef64b Whitespace rationalisation of entire code base.
The number of people has been steadily increasing who read our source
code with an editor that thinks tab stops are 4 spaces apart, as
opposed to the traditional tty-derived 8 that the PuTTY code expects.

So I've been wondering for ages about just fixing it, and switching to
a spaces-only policy throughout the code. And I recently found out
about 'git blame -w', which should make this change not too disruptive
for the purposes of source-control archaeology; so perhaps now is the
time.

While I'm at it, I've also taken the opportunity to remove all the
trailing spaces from source lines (on the basis that git dislikes
them, and is the only thing that seems to have a strong opinion one
way or the other).
    
Apologies to anyone downstream of this code who has complicated patch
sets to rebase past this change. I don't intend it to be needed again.
2019-09-08 20:29:21 +01:00

128 lines
2.9 KiB
C

/*
* uxsel.c
*
* This module is a sort of all-purpose interchange for file
* descriptors. At one end it talks to uxnet.c and pty.c and
* anything else which might have one or more fds that need
* select() or poll()-type things doing to them during an extended
* program run; at the other end it talks to pterm.c or uxplink.c or
* anything else which might have its own means of actually doing
* those select()-type things.
*/
#include <assert.h>
#include "putty.h"
#include "tree234.h"
struct fd {
int fd;
int rwx; /* 4=except 2=write 1=read */
uxsel_callback_fn callback;
uxsel_id *id; /* for uxsel_input_remove */
};
static tree234 *fds;
static int uxsel_fd_cmp(void *av, void *bv)
{
struct fd *a = (struct fd *)av;
struct fd *b = (struct fd *)bv;
if (a->fd < b->fd)
return -1;
if (a->fd > b->fd)
return +1;
return 0;
}
static int uxsel_fd_findcmp(void *av, void *bv)
{
int *a = (int *)av;
struct fd *b = (struct fd *)bv;
if (*a < b->fd)
return -1;
if (*a > b->fd)
return +1;
return 0;
}
void uxsel_init(void)
{
fds = newtree234(uxsel_fd_cmp);
}
/*
* Here is the interface to fd-supplying modules. They supply an
* fd, a set of read/write/execute states, and a callback function
* for when the fd satisfies one of those states. Repeated calls to
* uxsel_set on the same fd are perfectly legal and serve to change
* the rwx state (typically you only want to select an fd for
* writing when you actually have pending data you want to write to
* it!).
*/
void uxsel_set(int fd, int rwx, uxsel_callback_fn callback)
{
struct fd *newfd;
assert(fd >= 0);
uxsel_del(fd);
if (rwx) {
newfd = snew(struct fd);
newfd->fd = fd;
newfd->rwx = rwx;
newfd->callback = callback;
newfd->id = uxsel_input_add(fd, rwx);
add234(fds, newfd);
}
}
void uxsel_del(int fd)
{
struct fd *oldfd = find234(fds, &fd, uxsel_fd_findcmp);
if (oldfd) {
if (oldfd->id)
uxsel_input_remove(oldfd->id);
del234(fds, oldfd);
sfree(oldfd);
}
}
/*
* And here is the interface to select-functionality-supplying
* modules.
*/
int next_fd(int *state, int *rwx)
{
struct fd *fd;
fd = index234(fds, (*state)++);
if (fd) {
*rwx = fd->rwx;
return fd->fd;
} else
return -1;
}
int first_fd(int *state, int *rwx)
{
*state = 0;
return next_fd(state, rwx);
}
void select_result(int fd, int event)
{
struct fd *fdstruct = find234(fds, &fd, uxsel_fd_findcmp);
noise_ultralight(NOISE_SOURCE_IOID, fd);
/*
* Apparently this can sometimes be NULL. Can't see how, but I
* assume it means I need to ignore the event since it's on an
* fd I've stopped being interested in. Sigh.
*/
if (fdstruct)
fdstruct->callback(fd, event);
}