Dr. Werner Fink 2011-10-20 12:32:20 +00:00 committed by Git OBS Bridge
parent 29a282460b
commit eec8419ea9
2 changed files with 103 additions and 1 deletions

View File

@ -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 */

View File

@ -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