|
|
6fbbf4 |
diff -up ./nss/lib/freebl/shvfy.c.block_sigchld ./nss/lib/freebl/shvfy.c
|
|
|
6fbbf4 |
--- ./nss/lib/freebl/shvfy.c.block_sigchld 2014-10-23 10:38:01.494609227 -0700
|
|
|
6fbbf4 |
+++ ./nss/lib/freebl/shvfy.c 2014-10-23 10:44:35.395609071 -0700
|
|
|
6fbbf4 |
@@ -45,8 +45,50 @@
|
|
|
6fbbf4 |
#include <stdlib.h>
|
|
|
6fbbf4 |
#include <unistd.h>
|
|
|
6fbbf4 |
#include <fcntl.h>
|
|
|
6fbbf4 |
-#include <sys/wait.h>
|
|
|
6fbbf4 |
#include <sys/stat.h>
|
|
|
6fbbf4 |
+#include <errno.h>
|
|
|
6fbbf4 |
+
|
|
|
6fbbf4 |
+#define __USE_POSIX199309 1 /* need to use posix signal handler */
|
|
|
6fbbf4 |
+#include <signal.h>
|
|
|
6fbbf4 |
+#include <sys/wait.h> /* must be after signal.h */
|
|
|
6fbbf4 |
+
|
|
|
6fbbf4 |
+
|
|
|
6fbbf4 |
+/*
|
|
|
6fbbf4 |
+ * handler to block our sigchld call to keep from confusing parent apps
|
|
|
6fbbf4 |
+ */
|
|
|
6fbbf4 |
+static struct sigaction parent_handler;
|
|
|
6fbbf4 |
+static int child_pid = 0;
|
|
|
6fbbf4 |
+
|
|
|
6fbbf4 |
+static void
|
|
|
6fbbf4 |
+handle_sigchld(int signum, siginfo_t *sinfo, void *utcx)
|
|
|
6fbbf4 |
+{
|
|
|
6fbbf4 |
+ int status;
|
|
|
6fbbf4 |
+ int save_errno = errno;
|
|
|
6fbbf4 |
+ int ret;
|
|
|
6fbbf4 |
+
|
|
|
6fbbf4 |
+ if ((signum == SIGCHLD) && (sinfo->si_pid == child_pid)) {
|
|
|
6fbbf4 |
+ waitpid(sinfo->si_pid,&status, 0);
|
|
|
6fbbf4 |
+ errno = save_errno;
|
|
|
6fbbf4 |
+ return;
|
|
|
6fbbf4 |
+ }
|
|
|
6fbbf4 |
+
|
|
|
6fbbf4 |
+
|
|
|
6fbbf4 |
+ /* call parent, first set the parents mask */
|
|
|
6fbbf4 |
+ ret = sigprocmask(SIG_BLOCK, &parent_handler.sa_mask, NULL);
|
|
|
6fbbf4 |
+ errno = save_errno; /* restore previous errno. allow parent to change
|
|
|
6fbbf4 |
+ * errno if it needs to */
|
|
|
6fbbf4 |
+ if (ret < 0) {
|
|
|
6fbbf4 |
+ return;
|
|
|
6fbbf4 |
+ }
|
|
|
6fbbf4 |
+ /* now call the parent */
|
|
|
6fbbf4 |
+ if (parent_handler.sa_flags & SA_SIGINFO) {
|
|
|
6fbbf4 |
+ (*parent_handler.sa_sigaction)(signum, sinfo, utcx);
|
|
|
6fbbf4 |
+ } else {
|
|
|
6fbbf4 |
+ (*parent_handler.sa_handler)(signum);
|
|
|
6fbbf4 |
+ }
|
|
|
6fbbf4 |
+ /* libc/kernel should restore our mask as this point, so we don't
|
|
|
6fbbf4 |
+ * need to restore the mask we set above. */
|
|
|
6fbbf4 |
+}
|
|
|
6fbbf4 |
|
|
|
6fbbf4 |
/*
|
|
|
6fbbf4 |
* This function returns an NSPR PRFileDesc * which the caller can read to
|
|
|
6fbbf4 |
@@ -72,6 +114,8 @@ bl_OpenUnPrelink(const char *shName, int
|
|
|
6fbbf4 |
pid_t child;
|
|
|
6fbbf4 |
int argc = 0, argNext = 0;
|
|
|
6fbbf4 |
struct stat statBuf;
|
|
|
6fbbf4 |
+ struct sigaction our_handler;
|
|
|
6fbbf4 |
+ sigset_t inMask,outMask;
|
|
|
6fbbf4 |
int pipefd[2] = {-1,-1};
|
|
|
6fbbf4 |
int ret;
|
|
|
6fbbf4 |
|
|
|
6fbbf4 |
@@ -155,6 +199,25 @@ bl_OpenUnPrelink(const char *shName, int
|
|
|
6fbbf4 |
goto loser;
|
|
|
6fbbf4 |
}
|
|
|
6fbbf4 |
|
|
|
6fbbf4 |
+ child_pid = 0;
|
|
|
6fbbf4 |
+ our_handler.sa_flags = SA_SIGINFO;
|
|
|
6fbbf4 |
+ our_handler.sa_sigaction = handle_sigchld;
|
|
|
6fbbf4 |
+ sigemptyset(&our_handler.sa_mask);
|
|
|
6fbbf4 |
+ ret = sigaction(SIGCHLD, &our_handler, &parent_handler);
|
|
|
6fbbf4 |
+ if (ret < 0) {
|
|
|
6fbbf4 |
+ goto loser;
|
|
|
6fbbf4 |
+ }
|
|
|
6fbbf4 |
+
|
|
|
6fbbf4 |
+ /* don't accept a sigchild until we've set out child pid */
|
|
|
6fbbf4 |
+ sigemptyset(&inMask);
|
|
|
6fbbf4 |
+ sigemptyset(&outMask);
|
|
|
6fbbf4 |
+ sigaddset(&inMask,SIGCHLD);
|
|
|
6fbbf4 |
+ ret = sigprocmask(SIG_BLOCK, &inMask, &outMask);
|
|
|
6fbbf4 |
+ if (ret < 0) {
|
|
|
6fbbf4 |
+ sigaction(SIGCHLD, &parent_handler, NULL);
|
|
|
6fbbf4 |
+ goto loser;
|
|
|
6fbbf4 |
+ }
|
|
|
6fbbf4 |
+
|
|
|
6fbbf4 |
/* use vfork() so we don't trigger the pthread_at_fork() handlers */
|
|
|
6fbbf4 |
child = vfork();
|
|
|
6fbbf4 |
if (child < 0) goto loser;
|
|
|
6fbbf4 |
@@ -174,6 +237,8 @@ bl_OpenUnPrelink(const char *shName, int
|
|
|
6fbbf4 |
/* avoid at_exit() handlers */
|
|
|
6fbbf4 |
_exit(1); /* shouldn't reach here except on an error */
|
|
|
6fbbf4 |
}
|
|
|
6fbbf4 |
+ child_pid = child;
|
|
|
6fbbf4 |
+ sigprocmask(SIG_SETMASK, &outMask, 0); /* child is set,accept signals now */
|
|
|
6fbbf4 |
close(pipefd[1]);
|
|
|
6fbbf4 |
pipefd[1] = -1;
|
|
|
6fbbf4 |
|
|
|
6fbbf4 |
@@ -218,6 +283,9 @@ bl_CloseUnPrelink( PRFileDesc *file, int
|
|
|
6fbbf4 |
/* reap the child */
|
|
|
6fbbf4 |
if (pid) {
|
|
|
6fbbf4 |
waitpid(pid, NULL, 0);
|
|
|
6fbbf4 |
+ /* restore the parent handler */
|
|
|
6fbbf4 |
+ sigaction(SIGCHLD, &parent_handler, NULL);
|
|
|
6fbbf4 |
+ child_pid = 0;
|
|
|
6fbbf4 |
}
|
|
|
6fbbf4 |
}
|
|
|
6fbbf4 |
#endif
|