[1765] | 1 | /* vi: set sw=4 ts=4: */
|
---|
| 2 | /*
|
---|
| 3 | * Generic non-forking server infrastructure.
|
---|
| 4 | * Intended to make writing telnetd-type servers easier.
|
---|
| 5 | *
|
---|
[2725] | 6 | * Copyright (C) 2007 Denys Vlasenko
|
---|
[1765] | 7 | *
|
---|
[2725] | 8 | * Licensed under GPLv2, see file LICENSE in this source tree.
|
---|
[1765] | 9 | */
|
---|
| 10 |
|
---|
[2725] | 11 | PUSH_AND_SET_FUNCTION_VISIBILITY_TO_HIDDEN
|
---|
| 12 |
|
---|
[1765] | 13 | /* opaque structure */
|
---|
| 14 | struct isrv_state_t;
|
---|
| 15 | typedef struct isrv_state_t isrv_state_t;
|
---|
| 16 |
|
---|
| 17 | /* callbacks */
|
---|
| 18 | void isrv_want_rd(isrv_state_t *state, int fd);
|
---|
| 19 | void isrv_want_wr(isrv_state_t *state, int fd);
|
---|
| 20 | void isrv_dont_want_rd(isrv_state_t *state, int fd);
|
---|
| 21 | void isrv_dont_want_wr(isrv_state_t *state, int fd);
|
---|
| 22 | int isrv_register_fd(isrv_state_t *state, int peer, int fd);
|
---|
| 23 | void isrv_close_fd(isrv_state_t *state, int fd);
|
---|
| 24 | int isrv_register_peer(isrv_state_t *state, void *param);
|
---|
| 25 |
|
---|
[3621] | 26 | /* Driver:
|
---|
| 27 | *
|
---|
| 28 | * Select on listen_fd for <linger_timeout> (or forever if 0).
|
---|
| 29 | *
|
---|
| 30 | * If we time out and we have no peers, exit.
|
---|
| 31 | * If we have peers, call do_timeout(peer_param),
|
---|
| 32 | * if it returns !0, peer is removed.
|
---|
| 33 | *
|
---|
| 34 | * If listen_fd is active, accept new connection ("peer"),
|
---|
| 35 | * call new_peer() on it, and if it returns 0,
|
---|
| 36 | * add it to fds to select on.
|
---|
| 37 | * Now, select will wait for <timeout>, not <linger_timeout>
|
---|
| 38 | * (as long as we have more than zero peers).
|
---|
| 39 | *
|
---|
| 40 | * If a peer's fd is active, we call do_rd() on it if read
|
---|
| 41 | * bit was set, and then do_wr() if write bit was also set.
|
---|
| 42 | * If either returns !0, peer is removed.
|
---|
| 43 | * Reaching this place also resets timeout counter for this peer.
|
---|
| 44 | *
|
---|
| 45 | * Note that peer must indicate that he wants to be selected
|
---|
| 46 | * for read and/or write using isrv_want_rd()/isrv_want_wr()
|
---|
| 47 | * [can be called in new_peer() or in do_rd()/do_wr()].
|
---|
| 48 | * If it never wants to be selected for write, do_wr()
|
---|
| 49 | * will never be called (can be NULL).
|
---|
| 50 | */
|
---|
[1765] | 51 | void isrv_run(
|
---|
| 52 | int listen_fd,
|
---|
| 53 | int (*new_peer)(isrv_state_t *state, int fd),
|
---|
| 54 | int (*do_rd)(int fd, void **),
|
---|
| 55 | int (*do_wr)(int fd, void **),
|
---|
| 56 | int (*do_timeout)(void **),
|
---|
| 57 | int timeout,
|
---|
| 58 | int linger_timeout
|
---|
| 59 | );
|
---|
[2725] | 60 |
|
---|
| 61 | POP_SAVED_FUNCTION_VISIBILITY
|
---|