telnetd: make sure telnetd -K exits if child dies

This commit is contained in:
Denis Vlasenko 2007-10-17 14:33:31 +00:00
parent 9e23767ef5
commit e87b8689d2

View File

@ -314,6 +314,14 @@ make_new_session(
_exit(1); /*bb_perror_msg_and_die("execv %s", loginpath);*/ _exit(1); /*bb_perror_msg_and_die("execv %s", loginpath);*/
} }
/* Must match getopt32 string */
enum {
OPT_WATCHCHILD = (1 << 2), /* -K */
OPT_INETD = (1 << 3) * ENABLE_FEATURE_TELNETD_STANDALONE, /* -i */
OPT_PORT = (1 << 4) * ENABLE_FEATURE_TELNETD_STANDALONE, /* -p */
OPT_FOREGROUND = (1 << 6) * ENABLE_FEATURE_TELNETD_STANDALONE, /* -F */
};
#if ENABLE_FEATURE_TELNETD_STANDALONE #if ENABLE_FEATURE_TELNETD_STANDALONE
static void static void
@ -321,6 +329,9 @@ free_session(struct tsession *ts)
{ {
struct tsession *t = sessions; struct tsession *t = sessions;
if (option_mask32 & OPT_INETD)
exit(0);
/* Unlink this telnet session from the session list */ /* Unlink this telnet session from the session list */
if (t == ts) if (t == ts)
sessions = ts->next; sessions = ts->next;
@ -341,7 +352,7 @@ free_session(struct tsession *ts)
close(ts->sockfd_read); close(ts->sockfd_read);
/* We do not need to close(ts->sockfd_write), it's the same /* We do not need to close(ts->sockfd_write), it's the same
* as sockfd_read unless we are in inetd mode. But in inetd mode * as sockfd_read unless we are in inetd mode. But in inetd mode
* we do not free_session(), ever */ * we do not reach this */
free(ts); free(ts);
/* Scan all sessions and find new maxfd */ /* Scan all sessions and find new maxfd */
@ -363,8 +374,8 @@ free_session(struct tsession *ts)
#else /* !FEATURE_TELNETD_STANDALONE */ #else /* !FEATURE_TELNETD_STANDALONE */
/* Never actually called */ /* Used in main() only, thus exits. */
void free_session(struct tsession *ts); #define free_session(ts) return 0
#endif #endif
@ -407,13 +418,6 @@ int telnetd_main(int argc, char **argv)
portnbr = 23, portnbr = 23,
}; };
#endif #endif
enum {
OPT_WATCHCHILD = (1 << 2), /* -K */
OPT_INETD = (1 << 3) * ENABLE_FEATURE_TELNETD_STANDALONE, /* -i */
OPT_PORT = (1 << 4) * ENABLE_FEATURE_TELNETD_STANDALONE, /* -p */
OPT_FOREGROUND = (1 << 6) * ENABLE_FEATURE_TELNETD_STANDALONE, /* -F */
};
/* Even if !STANDALONE, we accept (and ignore) -i, thus people /* Even if !STANDALONE, we accept (and ignore) -i, thus people
* don't need to guess whether it's ok to pass -i to us */ * don't need to guess whether it's ok to pass -i to us */
opt = getopt32(argv, "f:l:Ki" USE_FEATURE_TELNETD_STANDALONE("p:b:F"), opt = getopt32(argv, "f:l:Ki" USE_FEATURE_TELNETD_STANDALONE("p:b:F"),
@ -493,11 +497,8 @@ int telnetd_main(int argc, char **argv)
while (ts) { while (ts) {
struct tsession *next = ts->next; /* in case we free ts. */ struct tsession *next = ts->next; /* in case we free ts. */
if (ts->shell_pid == -1) { if (ts->shell_pid == -1) {
#if !ENABLE_FEATURE_TELNETD_STANDALONE /* Child died ad we detected that */
return 0;
#else
free_session(ts); free_session(ts);
#endif
} else { } else {
if (ts->size1 > 0) /* can write to pty */ if (ts->size1 > 0) /* can write to pty */
FD_SET(ts->ptyfd, &wrfdset); FD_SET(ts->ptyfd, &wrfdset);
@ -632,14 +633,8 @@ int telnetd_main(int argc, char **argv)
ts = next; ts = next;
continue; continue;
kill_session: kill_session:
#if !ENABLE_FEATURE_TELNETD_STANDALONE
return 0;
#else
if (IS_INETD)
return 0;
free_session(ts); free_session(ts);
ts = next; ts = next;
#endif
} }
goto again; goto again;