aboutsummaryrefslogtreecommitdiff
path: root/networking/telnetd.c
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2007-10-17 14:33:31 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2007-10-17 14:33:31 +0000
commite87b8689d245083b355f32a751d05dfdf5176aba (patch)
tree13b38b7415c16427d8f93007ae065a7437352992 /networking/telnetd.c
parent9e23767ef59e3b84fe621adc4f30854dd03142d1 (diff)
downloadbusybox-w32-e87b8689d245083b355f32a751d05dfdf5176aba.tar.gz
busybox-w32-e87b8689d245083b355f32a751d05dfdf5176aba.tar.bz2
busybox-w32-e87b8689d245083b355f32a751d05dfdf5176aba.zip
telnetd: make sure telnetd -K exits if child dies
Diffstat (limited to 'networking/telnetd.c')
-rw-r--r--networking/telnetd.c35
1 files changed, 15 insertions, 20 deletions
diff --git a/networking/telnetd.c b/networking/telnetd.c
index 1ca6fdece..cccf03dfd 100644
--- a/networking/telnetd.c
+++ b/networking/telnetd.c
@@ -314,6 +314,14 @@ make_new_session(
314 _exit(1); /*bb_perror_msg_and_die("execv %s", loginpath);*/ 314 _exit(1); /*bb_perror_msg_and_die("execv %s", loginpath);*/
315} 315}
316 316
317/* Must match getopt32 string */
318enum {
319 OPT_WATCHCHILD = (1 << 2), /* -K */
320 OPT_INETD = (1 << 3) * ENABLE_FEATURE_TELNETD_STANDALONE, /* -i */
321 OPT_PORT = (1 << 4) * ENABLE_FEATURE_TELNETD_STANDALONE, /* -p */
322 OPT_FOREGROUND = (1 << 6) * ENABLE_FEATURE_TELNETD_STANDALONE, /* -F */
323};
324
317#if ENABLE_FEATURE_TELNETD_STANDALONE 325#if ENABLE_FEATURE_TELNETD_STANDALONE
318 326
319static void 327static void
@@ -321,6 +329,9 @@ free_session(struct tsession *ts)
321{ 329{
322 struct tsession *t = sessions; 330 struct tsession *t = sessions;
323 331
332 if (option_mask32 & OPT_INETD)
333 exit(0);
334
324 /* Unlink this telnet session from the session list */ 335 /* Unlink this telnet session from the session list */
325 if (t == ts) 336 if (t == ts)
326 sessions = ts->next; 337 sessions = ts->next;
@@ -341,7 +352,7 @@ free_session(struct tsession *ts)
341 close(ts->sockfd_read); 352 close(ts->sockfd_read);
342 /* We do not need to close(ts->sockfd_write), it's the same 353 /* We do not need to close(ts->sockfd_write), it's the same
343 * as sockfd_read unless we are in inetd mode. But in inetd mode 354 * as sockfd_read unless we are in inetd mode. But in inetd mode
344 * we do not free_session(), ever */ 355 * we do not reach this */
345 free(ts); 356 free(ts);
346 357
347 /* Scan all sessions and find new maxfd */ 358 /* Scan all sessions and find new maxfd */
@@ -363,8 +374,8 @@ free_session(struct tsession *ts)
363 374
364#else /* !FEATURE_TELNETD_STANDALONE */ 375#else /* !FEATURE_TELNETD_STANDALONE */
365 376
366/* Never actually called */ 377/* Used in main() only, thus exits. */
367void free_session(struct tsession *ts); 378#define free_session(ts) return 0
368 379
369#endif 380#endif
370 381
@@ -407,13 +418,6 @@ int telnetd_main(int argc, char **argv)
407 portnbr = 23, 418 portnbr = 23,
408 }; 419 };
409#endif 420#endif
410 enum {
411 OPT_WATCHCHILD = (1 << 2), /* -K */
412 OPT_INETD = (1 << 3) * ENABLE_FEATURE_TELNETD_STANDALONE, /* -i */
413 OPT_PORT = (1 << 4) * ENABLE_FEATURE_TELNETD_STANDALONE, /* -p */
414 OPT_FOREGROUND = (1 << 6) * ENABLE_FEATURE_TELNETD_STANDALONE, /* -F */
415 };
416
417 /* Even if !STANDALONE, we accept (and ignore) -i, thus people 421 /* Even if !STANDALONE, we accept (and ignore) -i, thus people
418 * don't need to guess whether it's ok to pass -i to us */ 422 * don't need to guess whether it's ok to pass -i to us */
419 opt = getopt32(argv, "f:l:Ki" USE_FEATURE_TELNETD_STANDALONE("p:b:F"), 423 opt = getopt32(argv, "f:l:Ki" USE_FEATURE_TELNETD_STANDALONE("p:b:F"),
@@ -493,11 +497,8 @@ int telnetd_main(int argc, char **argv)
493 while (ts) { 497 while (ts) {
494 struct tsession *next = ts->next; /* in case we free ts. */ 498 struct tsession *next = ts->next; /* in case we free ts. */
495 if (ts->shell_pid == -1) { 499 if (ts->shell_pid == -1) {
496#if !ENABLE_FEATURE_TELNETD_STANDALONE 500 /* Child died ad we detected that */
497 return 0;
498#else
499 free_session(ts); 501 free_session(ts);
500#endif
501 } else { 502 } else {
502 if (ts->size1 > 0) /* can write to pty */ 503 if (ts->size1 > 0) /* can write to pty */
503 FD_SET(ts->ptyfd, &wrfdset); 504 FD_SET(ts->ptyfd, &wrfdset);
@@ -632,14 +633,8 @@ int telnetd_main(int argc, char **argv)
632 ts = next; 633 ts = next;
633 continue; 634 continue;
634 kill_session: 635 kill_session:
635#if !ENABLE_FEATURE_TELNETD_STANDALONE
636 return 0;
637#else
638 if (IS_INETD)
639 return 0;
640 free_session(ts); 636 free_session(ts);
641 ts = next; 637 ts = next;
642#endif
643 } 638 }
644 639
645 goto again; 640 goto again;