--- apmd-3.2.1/apmd.c.orig 2004-04-19 20:03:37 +0400 +++ apmd-3.2.1/apmd.c 2004-04-19 20:04:29 +0400 @@ -201,6 +201,25 @@ static void usage(FILE *fd) ); } +#include + +static void close_all_fds (void) +{ + static int max_fd; + int fd; + + /* Just in case. */ + umask (077); + + if (!max_fd) + max_fd = sysconf(_SC_OPEN_MAX); + if (max_fd < NR_OPEN) + max_fd = NR_OPEN; + + /* Close all the rest. */ + for (fd = STDERR_FILENO + 1; fd < max_fd; ++fd) + close(fd); +} /* * call_proxy() is a generic outcalling dispatcher. It calls a @@ -324,10 +343,6 @@ static int call_proxy(apm_event_t event) /* child */ close(fds[0]); - /* Don't inherit stdin; use /dev/null instead */ - close(0); - open("/dev/null", O_RDONLY); - /* Send stdout and stderr to the pipe */ dup2(fds[1], 1); dup2(fds[1], 2); @@ -337,6 +352,8 @@ static int call_proxy(apm_event_t event) fcntl(1, F_SETFD, 0); fcntl(2, F_SETFD, 0); + close_all_fds(); + execvp(argv[0], (char **)argv); _exit(142); /* We only do this if the execvp fails */ } else { @@ -1181,16 +1198,34 @@ int main(int argc, char **argv) * Addison-Wesley Publishing Co., 1992, p. 417. */ if (setsid() < 0) { - APMD_TRACE0(LOG_ERR, "setsid() failed: %m"); + APMD_TRACE0(LOG_ERR, "setsid failed: %m"); unlink(PID_FILE); exit(1); } - chdir("/"); + if (chdir("/") < 0) { + APMD_TRACE0(LOG_ERR, "chdir failed: %m"); + unlink(PID_FILE); + exit(1); + } + close(0); - close(1); - if (verbosity < LOG_DEBUG) - close(2); - umask(0); + if (open("/dev/null", O_RDWR) != 0) { + APMD_TRACE0(LOG_ERR, "/dev/null: open failed: %m"); + unlink(PID_FILE); + exit(1); + } + if (dup2(0, 1) != 1) { + APMD_TRACE0(LOG_ERR, "stdout: dup2 failed: %m"); + unlink(PID_FILE); + exit(1); + } + if ((verbosity < LOG_DEBUG) && (dup2(0, 2) != 2)) { + APMD_TRACE0(LOG_ERR, "stderr: dup2 failed: %m"); + unlink(PID_FILE); + exit(1); + } + + close_all_fds(); apmd_fd = open(APM_DEVICE, O_RDWR); if (apmd_fd < 0) {