diff options
Diffstat (limited to 'networking/inetd.c')
-rw-r--r-- | networking/inetd.c | 25 |
1 files changed, 18 insertions, 7 deletions
diff --git a/networking/inetd.c b/networking/inetd.c index 331c49441..391bb9ba6 100644 --- a/networking/inetd.c +++ b/networking/inetd.c | |||
@@ -1031,10 +1031,10 @@ static void reap_child(int sig UNUSED_PARAM) | |||
1031 | continue; | 1031 | continue; |
1032 | /* One of our "wait" services */ | 1032 | /* One of our "wait" services */ |
1033 | if (WIFEXITED(status) && WEXITSTATUS(status)) | 1033 | if (WIFEXITED(status) && WEXITSTATUS(status)) |
1034 | bb_error_msg("%s: exit status 0x%x", | 1034 | bb_error_msg("%s: exit status %u", |
1035 | sep->se_program, WEXITSTATUS(status)); | 1035 | sep->se_program, WEXITSTATUS(status)); |
1036 | else if (WIFSIGNALED(status)) | 1036 | else if (WIFSIGNALED(status)) |
1037 | bb_error_msg("%s: exit signal 0x%x", | 1037 | bb_error_msg("%s: exit signal %u", |
1038 | sep->se_program, WTERMSIG(status)); | 1038 | sep->se_program, WTERMSIG(status)); |
1039 | sep->se_wait = 1; | 1039 | sep->se_wait = 1; |
1040 | add_fd_to_set(sep->se_fd); | 1040 | add_fd_to_set(sep->se_fd); |
@@ -1119,7 +1119,12 @@ int inetd_main(int argc UNUSED_PARAM, char **argv) | |||
1119 | else | 1119 | else |
1120 | bb_sanitize_stdio(); | 1120 | bb_sanitize_stdio(); |
1121 | if (!(opt & 4)) { | 1121 | if (!(opt & 4)) { |
1122 | openlog(applet_name, LOG_PID, LOG_DAEMON); | 1122 | /* LOG_NDELAY: connect to syslog daemon NOW. |
1123 | * Otherwise, we may open syslog socket | ||
1124 | * in vforked child, making opened fds and syslog() | ||
1125 | * internal state inconsistent. | ||
1126 | * This was observed to leak file descriptors. */ | ||
1127 | openlog(applet_name, LOG_PID | LOG_NDELAY, LOG_DAEMON); | ||
1123 | logmode = LOGMODE_SYSLOG; | 1128 | logmode = LOGMODE_SYSLOG; |
1124 | } | 1129 | } |
1125 | 1130 | ||
@@ -1355,17 +1360,23 @@ int inetd_main(int argc UNUSED_PARAM, char **argv) | |||
1355 | if (rlim_ofile.rlim_cur != rlim_ofile_cur) | 1360 | if (rlim_ofile.rlim_cur != rlim_ofile_cur) |
1356 | if (setrlimit(RLIMIT_NOFILE, &rlim_ofile) < 0) | 1361 | if (setrlimit(RLIMIT_NOFILE, &rlim_ofile) < 0) |
1357 | bb_perror_msg("setrlimit"); | 1362 | bb_perror_msg("setrlimit"); |
1358 | closelog(); | 1363 | |
1364 | /* closelog(); - WRONG. we are after vfork, | ||
1365 | * this may confuse syslog() internal state. | ||
1366 | * Let's hope libc sets syslog fd to CLOEXEC... | ||
1367 | */ | ||
1359 | xmove_fd(ctrl, STDIN_FILENO); | 1368 | xmove_fd(ctrl, STDIN_FILENO); |
1360 | xdup2(STDIN_FILENO, STDOUT_FILENO); | 1369 | xdup2(STDIN_FILENO, STDOUT_FILENO); |
1361 | /* manpages of inetd I managed to find either say | 1370 | /* manpages of inetd I managed to find either say |
1362 | * that stderr is also redirected to the network, | 1371 | * that stderr is also redirected to the network, |
1363 | * or do not talk about redirection at all (!) */ | 1372 | * or do not talk about redirection at all (!) */ |
1364 | xdup2(STDIN_FILENO, STDERR_FILENO); | 1373 | if (!sep->se_wait) /* only for usual "tcp nowait" */ |
1365 | /* NB: among others, this loop closes listening socket | 1374 | xdup2(STDIN_FILENO, STDERR_FILENO); |
1375 | /* NB: among others, this loop closes listening sockets | ||
1366 | * for nowait stream children */ | 1376 | * for nowait stream children */ |
1367 | for (sep2 = serv_list; sep2; sep2 = sep2->se_next) | 1377 | for (sep2 = serv_list; sep2; sep2 = sep2->se_next) |
1368 | maybe_close(sep2->se_fd); | 1378 | if (sep2->se_fd != ctrl) |
1379 | maybe_close(sep2->se_fd); | ||
1369 | sigaction_set(SIGPIPE, &saved_pipe_handler); | 1380 | sigaction_set(SIGPIPE, &saved_pipe_handler); |
1370 | restore_sigmask(&omask); | 1381 | restore_sigmask(&omask); |
1371 | BB_EXECVP(sep->se_program, sep->se_argv); | 1382 | BB_EXECVP(sep->se_program, sep->se_argv); |