diff --git a/killproc-2.20.dif b/killproc-2.20.dif index 215a06a..b315108 100644 --- a/killproc-2.20.dif +++ b/killproc-2.20.dif @@ -260,7 +260,7 @@ .SH EXAMPLE .TP --- startproc.c -+++ startproc.c 2011-10-17 15:43:02.443647315 +0000 ++++ startproc.c 2011-10-20 12:19:33.523206609 +0000 @@ -109,7 +109,7 @@ int main(int argc, char **argv) } @@ -280,3 +280,100 @@ case 'p': /* Former option -f */ if (force) warn("option -p does not work in force mode\n"); +@@ -412,6 +415,8 @@ static int do_start(const char *inname, + const char * fullname; + char proc_exe[6+9+4+1]; + static struct stat itsme; ++ sigset_t newset, oldset; ++ int pipe[2]; + + if ((n = snprintf(proc_exe, sizeof(proc_exe) - 1, "/proc/%d/exe", getpid())) > 0) { + proc_exe[n] = '\0'; +@@ -445,11 +450,17 @@ static int do_start(const char *inname, + if (sdaemon) + pid = 0; + else { ++ sigemptyset(&newset); ++ sigaddset(&newset, SIGQUIT); ++ sigaddset(&newset, SIGCHLD); ++ sigprocmask(SIG_UNBLOCK, &newset, &oldset); + save_sigquit = signal(SIGQUIT, sig_quit); + if (sigchld) + (void)signal(SIGCHLD, sig_chld); + else + (void)signal(SIGCHLD, SIG_DFL); ++ if (pipe2(pipe, O_CLOEXEC) < 0) ++ error(100, "cannot open a pipe: %m\n"); + if ((pid = fork()) == 0) { + /* Update again to point to the child pid */ + fwd_sd_listen_pid(); +@@ -459,10 +470,15 @@ static int do_start(const char *inname, + switch (pid) { + case 0: + if (!sdaemon) { ++ sigprocmask(SIG_SETMASK, &oldset, NULL); + (void)signal(SIGINT, SIG_DFL); + (void)signal(SIGQUIT, SIG_DFL); + (void)signal(SIGSEGV, SIG_DFL); + (void)signal(SIGTERM, SIG_DFL); ++ ++ close(pipe[1]); ++ read(pipe[0], proc_exe, 1); /* Wait on parent with the pipe here */ ++ close(pipe[0]); + } + + if (root) { +@@ -615,8 +631,8 @@ static int do_start(const char *inname, + fclose(tmp); + fflush(stdout); + fflush(stderr); /* flush stdout and especially stderr */ +- usleep(1); /* Force the kernel to run the scheduler and update +- the environment of the current processes */ ++ ++ close(pipe[0]); + + if ((n = snprintf(proc_exe, sizeof(proc_exe) - 1, "/proc/%d/exe", pid)) > 0) { + proc_exe[n] = '\0'; +@@ -628,17 +644,21 @@ static int do_start(const char *inname, + * pid but before the execve() is done by the kernel, in later + * case be sure not to run on our own binary. + */ ++ n = 0; + do { + struct stat serv; + + errno = 0; + if (stat(proc_exe, &serv) < 0) { + if (errno == ENOENT) +- break; /* Seems to be a fast system */ +- ++ break; /* Seems to be a very fast system ++ * should not happen due to the pipe */ + error(100, "cannot stat %s: %s\n", proc_exe, strerror(errno)); + } + ++ if (n++ == 0) ++ close(pipe[1]); /* Sync child over the pipe */ ++ + if (itsme.st_dev != serv.st_dev || itsme.st_ino != serv.st_ino) + break; /* Seems to be a slow system */ + +@@ -647,6 +667,9 @@ static int do_start(const char *inname, + } while (true); + + } else { ++ ++ close(pipe[1]); /* Sync child over the pipe */ ++ + warn("error in snprintf: %s\n", strerror(errno)); + usleep(100*1000); + } +@@ -657,7 +680,7 @@ retry: + case -1: /* WNOHANG and hopefully no child but daemon */ + if (errno == EINTR) + goto retry; +- if (errno != ECHILD) /* ECHILD shouldn´t happen, should it? (it does) */ ++ if (errno != ECHILD) /* ECHILD should not happen, should it? (it does) */ + error(LSB_PROOFE," waitpid on %s: %s\n", fullname, strerror(errno)); + break; + case 0: /* WNOHANG and no status available */ diff --git a/sysvinit.changes b/sysvinit.changes index 5441641..9e6c82f 100644 --- a/sysvinit.changes +++ b/sysvinit.changes @@ -1,3 +1,8 @@ +------------------------------------------------------------------- +Thu Oct 20 12:31:09 UTC 2011 - werner@suse.de + +- Use pipe to synch parent with child in startproc (bnc#713342) + ------------------------------------------------------------------- Tue Oct 18 09:30:36 UTC 2011 - werner@suse.de