inetd: fix a case when we have zero services

This commit is contained in:
Denis Vlasenko 2008-11-05 11:36:22 +00:00
parent a643816fe3
commit 4cb576ea98

View File

@ -223,7 +223,7 @@ typedef struct servtab_t {
smallint se_checked; /* looked at during merge */ smallint se_checked; /* looked at during merge */
unsigned se_max; /* allowed instances per minute */ unsigned se_max; /* allowed instances per minute */
unsigned se_count; /* number started since se_time */ unsigned se_count; /* number started since se_time */
unsigned se_time; /* whem we started counting */ unsigned se_time; /* when we started counting */
char *se_user; /* user name to run as */ char *se_user; /* user name to run as */
char *se_group; /* group name to run as, can be NULL */ char *se_group; /* group name to run as, can be NULL */
#ifdef INETD_BUILTINS_ENABLED #ifdef INETD_BUILTINS_ENABLED
@ -295,8 +295,10 @@ struct globals {
struct rlimit rlim_ofile; struct rlimit rlim_ofile;
servtab_t *serv_list; servtab_t *serv_list;
int global_queuelen; int global_queuelen;
int maxsock; /* max fd# in allsock, -1: unknown */
/* whenever maxsock grows, prev_maxsock is set to new maxsock,
* but if maxsock is set to -1, prev_maxsock is not changed */
int prev_maxsock; int prev_maxsock;
int maxsock;
unsigned max_concurrency; unsigned max_concurrency;
smallint alarm_armed; smallint alarm_armed;
uid_t real_uid; /* user ID who ran us */ uid_t real_uid; /* user ID who ran us */
@ -321,8 +323,8 @@ struct BUG_G_too_big {
#define rlim_ofile (G.rlim_ofile ) #define rlim_ofile (G.rlim_ofile )
#define serv_list (G.serv_list ) #define serv_list (G.serv_list )
#define global_queuelen (G.global_queuelen) #define global_queuelen (G.global_queuelen)
#define prev_maxsock (G.prev_maxsock )
#define maxsock (G.maxsock ) #define maxsock (G.maxsock )
#define prev_maxsock (G.prev_maxsock )
#define max_concurrency (G.max_concurrency) #define max_concurrency (G.max_concurrency)
#define alarm_armed (G.alarm_armed ) #define alarm_armed (G.alarm_armed )
#define real_uid (G.real_uid ) #define real_uid (G.real_uid )
@ -459,7 +461,7 @@ static void add_fd_to_set(int fd)
FD_SET(fd, &allsock); FD_SET(fd, &allsock);
if (maxsock >= 0 && fd > maxsock) { if (maxsock >= 0 && fd > maxsock) {
prev_maxsock = maxsock = fd; prev_maxsock = maxsock = fd;
if ((rlim_t)maxsock > rlim_ofile_cur - FD_MARGIN) if ((rlim_t)fd > rlim_ofile_cur - FD_MARGIN)
bump_nofile(); bump_nofile();
} }
} }
@ -468,6 +470,10 @@ static void add_fd_to_set(int fd)
static void recalculate_maxsock(void) static void recalculate_maxsock(void)
{ {
int fd = 0; int fd = 0;
/* We may have no services, in this case maxsock should still be >= 0
* (code elsewhere is not happy with maxsock == -1) */
maxsock = 0;
while (fd <= prev_maxsock) { while (fd <= prev_maxsock) {
if (FD_ISSET(fd, &allsock)) if (FD_ISSET(fd, &allsock))
maxsock = fd; maxsock = fd;
@ -1161,7 +1167,8 @@ int inetd_main(int argc UNUSED_PARAM, char **argv)
readable = allsock; /* struct copy */ readable = allsock; /* struct copy */
/* if there are no fds to wait on, we will block /* if there are no fds to wait on, we will block
* until signal wakes us up */ * until signal wakes us up (maxsock == 0, but readable
* never contains fds 0 and 1...) */
ready_fd_cnt = select(maxsock + 1, &readable, NULL, NULL, NULL); ready_fd_cnt = select(maxsock + 1, &readable, NULL, NULL, NULL);
if (ready_fd_cnt < 0) { if (ready_fd_cnt < 0) {
if (errno != EINTR) { if (errno != EINTR) {
@ -1418,7 +1425,7 @@ static void echo_dg(int s, servtab_t *sep)
#if ENABLE_FEATURE_INETD_SUPPORT_BUILTIN_DISCARD #if ENABLE_FEATURE_INETD_SUPPORT_BUILTIN_DISCARD
/* Discard service -- ignore data. MMU arches only. */ /* Discard service -- ignore data. */
/* ARGSUSED */ /* ARGSUSED */
static void discard_stream(int s, servtab_t *sep UNUSED_PARAM) static void discard_stream(int s, servtab_t *sep UNUSED_PARAM)
{ {