fakeidentd: fix daemon mode (was thinking that it is in
inetd-wait mode and dying after timeout). Minor fixes, comments are improved in places.
This commit is contained in:
parent
ffcef2d1f7
commit
19250813a8
@ -21,6 +21,8 @@
|
|||||||
|
|
||||||
/* Helpers */
|
/* Helpers */
|
||||||
|
|
||||||
|
/* Even if _POSIX_MONOTONIC_CLOCK is defined, this
|
||||||
|
* may require librt */
|
||||||
#if 0 /*def _POSIX_MONOTONIC_CLOCK*/
|
#if 0 /*def _POSIX_MONOTONIC_CLOCK*/
|
||||||
static time_t monotonic_time(void)
|
static time_t monotonic_time(void)
|
||||||
{
|
{
|
||||||
@ -194,7 +196,8 @@ static void handle_accept(isrv_state_t *state, int fd)
|
|||||||
if (newfd < 0) {
|
if (newfd < 0) {
|
||||||
if (errno == EAGAIN) return;
|
if (errno == EAGAIN) return;
|
||||||
/* Most probably someone gave us wrong fd type
|
/* Most probably someone gave us wrong fd type
|
||||||
* (for example, non-socket) */
|
* (for example, non-socket). Don't want
|
||||||
|
* to loop forever. */
|
||||||
bb_perror_msg_and_die("accept");
|
bb_perror_msg_and_die("accept");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -210,6 +213,7 @@ static void handle_fd_set(isrv_state_t *state, fd_set *fds, int (*h)(int, void *
|
|||||||
enum { LONG_CNT = sizeof(fd_set) / sizeof(long) };
|
enum { LONG_CNT = sizeof(fd_set) / sizeof(long) };
|
||||||
int fds_pos;
|
int fds_pos;
|
||||||
int fd, peer;
|
int fd, peer;
|
||||||
|
/* need to know value at _the beginning_ of this routine */
|
||||||
int fd_cnt = FD_COUNT;
|
int fd_cnt = FD_COUNT;
|
||||||
|
|
||||||
if (LONG_CNT * sizeof(long) != sizeof(fd_set))
|
if (LONG_CNT * sizeof(long) != sizeof(fd_set))
|
||||||
@ -235,10 +239,15 @@ static void handle_fd_set(isrv_state_t *state, fd_set *fds, int (*h)(int, void *
|
|||||||
}
|
}
|
||||||
break; /* all words are zero */
|
break; /* all words are zero */
|
||||||
found_fd:
|
found_fd:
|
||||||
if (fd >= fd_cnt) /* paranoia */
|
if (fd >= fd_cnt) { /* paranoia */
|
||||||
|
DPRINTF("handle_fd_set: fd > fd_cnt?? (%d > %d)",
|
||||||
|
fd, fd_cnt);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
DPRINTF("handle_fd_set: fd %d is active", fd);
|
DPRINTF("handle_fd_set: fd %d is active", fd);
|
||||||
peer = FD2PEER[fd];
|
peer = FD2PEER[fd];
|
||||||
|
if (peer < 0)
|
||||||
|
continue; /* peer is already gone */
|
||||||
if (peer == 0) {
|
if (peer == 0) {
|
||||||
handle_accept(state, fd);
|
handle_accept(state, fd);
|
||||||
continue;
|
continue;
|
||||||
@ -259,9 +268,9 @@ static void handle_timeout(isrv_state_t *state, int (*do_timeout)(void **))
|
|||||||
peer = PEER_COUNT-1;
|
peer = PEER_COUNT-1;
|
||||||
/* peer 0 is not checked */
|
/* peer 0 is not checked */
|
||||||
while (peer > 0) {
|
while (peer > 0) {
|
||||||
DPRINTF("peer %d: time diff %d", peer, (int)(CURTIME - TIMEO_TBL[peer]));
|
DPRINTF("peer %d: time diff %d", peer,
|
||||||
|
(int)(CURTIME - TIMEO_TBL[peer]));
|
||||||
if ((CURTIME - TIMEO_TBL[peer]) > TIMEOUT) {
|
if ((CURTIME - TIMEO_TBL[peer]) >= TIMEOUT) {
|
||||||
DPRINTF("peer %d: do_timeout()", peer);
|
DPRINTF("peer %d: do_timeout()", peer);
|
||||||
n = do_timeout(&PARAM_TBL[peer]);
|
n = do_timeout(&PARAM_TBL[peer]);
|
||||||
if (n)
|
if (n)
|
||||||
@ -279,7 +288,7 @@ void isrv_run(
|
|||||||
int (*do_wr)(int fd, void **),
|
int (*do_wr)(int fd, void **),
|
||||||
int (*do_timeout)(void **),
|
int (*do_timeout)(void **),
|
||||||
int timeout,
|
int timeout,
|
||||||
int exit_if_no_clients)
|
int linger_timeout)
|
||||||
{
|
{
|
||||||
isrv_state_t *state = xzalloc(sizeof(*state));
|
isrv_state_t *state = xzalloc(sizeof(*state));
|
||||||
state->new_peer = new_peer;
|
state->new_peer = new_peer;
|
||||||
@ -300,6 +309,8 @@ void isrv_run(
|
|||||||
int n;
|
int n;
|
||||||
|
|
||||||
tv.tv_sec = timeout;
|
tv.tv_sec = timeout;
|
||||||
|
if (PEER_COUNT <= 1)
|
||||||
|
tv.tv_sec = linger_timeout;
|
||||||
tv.tv_usec = 0;
|
tv.tv_usec = 0;
|
||||||
rd = state->rd;
|
rd = state->rd;
|
||||||
if (WR_COUNT) {
|
if (WR_COUNT) {
|
||||||
@ -307,8 +318,9 @@ void isrv_run(
|
|||||||
wrp = ≀
|
wrp = ≀
|
||||||
}
|
}
|
||||||
|
|
||||||
DPRINTF("run: select(FD_COUNT:%d,timeout:%d)...", FD_COUNT, timeout);
|
DPRINTF("run: select(FD_COUNT:%d,timeout:%d)...",
|
||||||
n = select(FD_COUNT, &rd, wrp, NULL, timeout ? &tv : NULL);
|
FD_COUNT, (int)tv.tv_sec);
|
||||||
|
n = select(FD_COUNT, &rd, wrp, NULL, tv.tv_sec ? &tv : NULL);
|
||||||
DPRINTF("run: ...select:%d", n);
|
DPRINTF("run: ...select:%d", n);
|
||||||
|
|
||||||
if (n < 0) {
|
if (n < 0) {
|
||||||
@ -317,7 +329,7 @@ void isrv_run(
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (exit_if_no_clients && n == 0 && PEER_COUNT <= 1)
|
if (n == 0 && linger_timeout && PEER_COUNT <= 1)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (timeout) {
|
if (timeout) {
|
||||||
@ -334,4 +346,5 @@ void isrv_run(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
DPRINTF("run: bailout");
|
DPRINTF("run: bailout");
|
||||||
|
/* NB: accept socket is not closed. Caller is to decide what to do */
|
||||||
}
|
}
|
||||||
|
@ -13,14 +13,6 @@
|
|||||||
|
|
||||||
enum { TIMEOUT = 20 };
|
enum { TIMEOUT = 20 };
|
||||||
|
|
||||||
/* Why use alarm(TIMEOUT-1)?
|
|
||||||
* isrv's internal select() will run with timeout=TIMEOUT.
|
|
||||||
* If nothing happens during TIMEOUT-1 seconds (no accept/read),
|
|
||||||
* then ALL sessions timed out by now. Instead of closing them one-by-one
|
|
||||||
* (isrv calls do_timeout for each 'stale' session),
|
|
||||||
* SIGALRM triggered by alarm(TIMEOUT-1) will kill us, terminating them all.
|
|
||||||
*/
|
|
||||||
|
|
||||||
typedef struct identd_buf_t {
|
typedef struct identd_buf_t {
|
||||||
int pos;
|
int pos;
|
||||||
int fd_flag;
|
int fd_flag;
|
||||||
@ -34,8 +26,6 @@ static int new_peer(isrv_state_t *state, int fd)
|
|||||||
int peer;
|
int peer;
|
||||||
identd_buf_t *buf = xzalloc(sizeof(*buf));
|
identd_buf_t *buf = xzalloc(sizeof(*buf));
|
||||||
|
|
||||||
alarm(TIMEOUT - 1);
|
|
||||||
|
|
||||||
peer = isrv_register_peer(state, buf);
|
peer = isrv_register_peer(state, buf);
|
||||||
if (peer < 0)
|
if (peer < 0)
|
||||||
return 0; /* failure */
|
return 0; /* failure */
|
||||||
@ -53,11 +43,9 @@ static int do_rd(int fd, void **paramp)
|
|||||||
char *cur, *p;
|
char *cur, *p;
|
||||||
int sz;
|
int sz;
|
||||||
|
|
||||||
alarm(TIMEOUT - 1);
|
|
||||||
|
|
||||||
cur = buf->buf + buf->pos;
|
cur = buf->buf + buf->pos;
|
||||||
|
|
||||||
fcntl(fd, F_SETFL, buf->fd_flag | O_NONBLOCK);
|
fcntl(fd, F_SETFL, buf->fd_flag);
|
||||||
sz = safe_read(fd, cur, sizeof(buf->buf) - buf->pos);
|
sz = safe_read(fd, cur, sizeof(buf->buf) - buf->pos);
|
||||||
|
|
||||||
if (sz < 0) {
|
if (sz < 0) {
|
||||||
@ -95,6 +83,8 @@ static void inetd_mode(void)
|
|||||||
identd_buf_t *buf = xzalloc(sizeof(*buf));
|
identd_buf_t *buf = xzalloc(sizeof(*buf));
|
||||||
/* We do NOT want nonblocking I/O here! */
|
/* We do NOT want nonblocking I/O here! */
|
||||||
buf->fd_flag = fcntl(0, F_GETFL, 0);
|
buf->fd_flag = fcntl(0, F_GETFL, 0);
|
||||||
|
do
|
||||||
|
alarm(TIMEOUT);
|
||||||
while (do_rd(0, (void*)&buf) == 0) /* repeat */;
|
while (do_rd(0, (void*)&buf) == 0) /* repeat */;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -139,6 +129,7 @@ int fakeidentd_main(int argc, char **argv)
|
|||||||
xlisten(fd, 5);
|
xlisten(fd, 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
isrv_run(fd, new_peer, do_rd, NULL, do_timeout, TIMEOUT, 1);
|
isrv_run(fd, new_peer, do_rd, /*do_wr:*/ NULL, do_timeout,
|
||||||
|
TIMEOUT, (opt & OPT_inetdwait) ? TIMEOUT : 0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user