diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2007-10-17 14:33:31 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2007-10-17 14:33:31 +0000 |
commit | e87b8689d245083b355f32a751d05dfdf5176aba (patch) | |
tree | 13b38b7415c16427d8f93007ae065a7437352992 /networking/telnetd.c | |
parent | 9e23767ef59e3b84fe621adc4f30854dd03142d1 (diff) | |
download | busybox-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.c | 35 |
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 */ | ||
318 | enum { | ||
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 | ||
319 | static void | 327 | static 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. */ |
367 | void 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; |