--- trunk/mkinitrd-magellan/busybox/networking/inetd.c 2010/04/29 20:38:48 983 +++ trunk/mkinitrd-magellan/busybox/networking/inetd.c 2010/05/30 11:32:42 984 @@ -239,36 +239,36 @@ #ifdef INETD_BUILTINS_ENABLED /* Echo received data */ #if ENABLE_FEATURE_INETD_SUPPORT_BUILTIN_ECHO -static void echo_stream(int, servtab_t *); -static void echo_dg(int, servtab_t *); +static void FAST_FUNC echo_stream(int, servtab_t *); +static void FAST_FUNC echo_dg(int, servtab_t *); #endif /* Internet /dev/null */ #if ENABLE_FEATURE_INETD_SUPPORT_BUILTIN_DISCARD -static void discard_stream(int, servtab_t *); -static void discard_dg(int, servtab_t *); +static void FAST_FUNC discard_stream(int, servtab_t *); +static void FAST_FUNC discard_dg(int, servtab_t *); #endif /* Return 32 bit time since 1900 */ #if ENABLE_FEATURE_INETD_SUPPORT_BUILTIN_TIME -static void machtime_stream(int, servtab_t *); -static void machtime_dg(int, servtab_t *); +static void FAST_FUNC machtime_stream(int, servtab_t *); +static void FAST_FUNC machtime_dg(int, servtab_t *); #endif /* Return human-readable time */ #if ENABLE_FEATURE_INETD_SUPPORT_BUILTIN_DAYTIME -static void daytime_stream(int, servtab_t *); -static void daytime_dg(int, servtab_t *); +static void FAST_FUNC daytime_stream(int, servtab_t *); +static void FAST_FUNC daytime_dg(int, servtab_t *); #endif /* Familiar character generator */ #if ENABLE_FEATURE_INETD_SUPPORT_BUILTIN_CHARGEN -static void chargen_stream(int, servtab_t *); -static void chargen_dg(int, servtab_t *); +static void FAST_FUNC chargen_stream(int, servtab_t *); +static void FAST_FUNC chargen_dg(int, servtab_t *); #endif struct builtin { /* NB: not necessarily NUL terminated */ char bi_service7[7]; /* internally provided service name */ uint8_t bi_fork; /* 1 if stream fn should run in child */ - void (*bi_stream_fn)(int, servtab_t *); - void (*bi_dgram_fn)(int, servtab_t *); + void (*bi_stream_fn)(int, servtab_t *) FAST_FUNC; + void (*bi_dgram_fn)(int, servtab_t *) FAST_FUNC; }; static const struct builtin builtins[] = { @@ -658,7 +658,7 @@ } { - static int8_t SOCK_xxx[] ALIGN1 = { + static const int8_t SOCK_xxx[] ALIGN1 = { -1, SOCK_STREAM, SOCK_DGRAM, SOCK_RDM, SOCK_SEQPACKET, SOCK_RAW @@ -1031,10 +1031,10 @@ continue; /* One of our "wait" services */ if (WIFEXITED(status) && WEXITSTATUS(status)) - bb_error_msg("%s: exit status 0x%x", + bb_error_msg("%s: exit status %u", sep->se_program, WEXITSTATUS(status)); else if (WIFSIGNALED(status)) - bb_error_msg("%s: exit signal 0x%x", + bb_error_msg("%s: exit signal %u", sep->se_program, WTERMSIG(status)); sep->se_wait = 1; add_fd_to_set(sep->se_fd); @@ -1119,7 +1119,12 @@ else bb_sanitize_stdio(); if (!(opt & 4)) { - openlog(applet_name, LOG_PID | LOG_NOWAIT, LOG_DAEMON); + /* LOG_NDELAY: connect to syslog daemon NOW. + * Otherwise, we may open syslog socket + * in vforked child, making opened fds and syslog() + * internal state inconsistent. + * This was observed to leak file descriptors. */ + openlog(applet_name, LOG_PID | LOG_NDELAY, LOG_DAEMON); logmode = LOGMODE_SYSLOG; } @@ -1299,7 +1304,7 @@ if (sep->se_builtin) { if (pid) { /* "pid" is -1: we did vfork */ close(sep->se_fd); /* listening socket */ - logmode = 0; /* make xwrite etc silent */ + logmode = LOGMODE_NONE; /* make xwrite etc silent */ } restore_sigmask(&omask); if (sep->se_socktype == SOCK_STREAM) @@ -1355,14 +1360,23 @@ if (rlim_ofile.rlim_cur != rlim_ofile_cur) if (setrlimit(RLIMIT_NOFILE, &rlim_ofile) < 0) bb_perror_msg("setrlimit"); - closelog(); - xmove_fd(ctrl, 0); - xdup2(0, 1); - xdup2(0, 2); - /* NB: among others, this loop closes listening socket + + /* closelog(); - WRONG. we are after vfork, + * this may confuse syslog() internal state. + * Let's hope libc sets syslog fd to CLOEXEC... + */ + xmove_fd(ctrl, STDIN_FILENO); + xdup2(STDIN_FILENO, STDOUT_FILENO); + /* manpages of inetd I managed to find either say + * that stderr is also redirected to the network, + * or do not talk about redirection at all (!) */ + if (!sep->se_wait) /* only for usual "tcp nowait" */ + xdup2(STDIN_FILENO, STDERR_FILENO); + /* NB: among others, this loop closes listening sockets * for nowait stream children */ for (sep2 = serv_list; sep2; sep2 = sep2->se_next) - maybe_close(sep2->se_fd); + if (sep2->se_fd != ctrl) + maybe_close(sep2->se_fd); sigaction_set(SIGPIPE, &saved_pipe_handler); restore_sigmask(&omask); BB_EXECVP(sep->se_program, sep->se_argv); @@ -1386,7 +1400,7 @@ #if ENABLE_FEATURE_INETD_SUPPORT_BUILTIN_ECHO /* Echo service -- echo data back. */ /* ARGSUSED */ -static void echo_stream(int s, servtab_t *sep UNUSED_PARAM) +static void FAST_FUNC echo_stream(int s, servtab_t *sep UNUSED_PARAM) { #if BB_MMU while (1) { @@ -1407,7 +1421,7 @@ /* on failure we return to main, which does exit(EXIT_FAILURE) */ #endif } -static void echo_dg(int s, servtab_t *sep) +static void FAST_FUNC echo_dg(int s, servtab_t *sep) { enum { BUFSIZE = 12*1024 }; /* for jumbo sized packets! :) */ char *buf = xmalloc(BUFSIZE); /* too big for stack */ @@ -1427,7 +1441,7 @@ #if ENABLE_FEATURE_INETD_SUPPORT_BUILTIN_DISCARD /* Discard service -- ignore data. */ /* ARGSUSED */ -static void discard_stream(int s, servtab_t *sep UNUSED_PARAM) +static void FAST_FUNC discard_stream(int s, servtab_t *sep UNUSED_PARAM) { #if BB_MMU while (safe_read(s, line, LINE_SIZE) > 0) @@ -1446,7 +1460,7 @@ #endif } /* ARGSUSED */ -static void discard_dg(int s, servtab_t *sep UNUSED_PARAM) +static void FAST_FUNC discard_dg(int s, servtab_t *sep UNUSED_PARAM) { /* dgram builtins are non-forking - DONT BLOCK! */ recv(s, line, LINE_SIZE, MSG_DONTWAIT); @@ -1461,13 +1475,12 @@ int i; end_ring = ring; - for (i = 0; i <= 128; ++i) - if (isprint(i)) - *end_ring++ = i; + for (i = ' '; i < 127; i++) + *end_ring++ = i; } /* Character generator. MMU arches only. */ /* ARGSUSED */ -static void chargen_stream(int s, servtab_t *sep UNUSED_PARAM) +static void FAST_FUNC chargen_stream(int s, servtab_t *sep UNUSED_PARAM) { char *rs; int len; @@ -1495,7 +1508,7 @@ } } /* ARGSUSED */ -static void chargen_dg(int s, servtab_t *sep) +static void FAST_FUNC chargen_dg(int s, servtab_t *sep) { int len; char text[LINESIZ + 2]; @@ -1544,14 +1557,14 @@ return htonl((uint32_t)(tv.tv_sec + 2208988800)); } /* ARGSUSED */ -static void machtime_stream(int s, servtab_t *sep UNUSED_PARAM) +static void FAST_FUNC machtime_stream(int s, servtab_t *sep UNUSED_PARAM) { uint32_t result; result = machtime(); full_write(s, &result, sizeof(result)); } -static void machtime_dg(int s, servtab_t *sep) +static void FAST_FUNC machtime_dg(int s, servtab_t *sep) { uint32_t result; len_and_sockaddr *lsa = alloca(LSA_LEN_SIZE + sep->se_lsa->len); @@ -1569,14 +1582,14 @@ #if ENABLE_FEATURE_INETD_SUPPORT_BUILTIN_DAYTIME /* Return human-readable time of day */ /* ARGSUSED */ -static void daytime_stream(int s, servtab_t *sep UNUSED_PARAM) +static void FAST_FUNC daytime_stream(int s, servtab_t *sep UNUSED_PARAM) { time_t t; t = time(NULL); fdprintf(s, "%.24s\r\n", ctime(&t)); } -static void daytime_dg(int s, servtab_t *sep) +static void FAST_FUNC daytime_dg(int s, servtab_t *sep) { time_t t; len_and_sockaddr *lsa = alloca(LSA_LEN_SIZE + sep->se_lsa->len);