<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">diff --git a/CHANGELOG b/CHANGELOG
index 5a594ff..3e801e2 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -18,6 +18,7 @@
 - cthon fix expire of wildcard and program mounts broken by above
   patches.
 - tidy up directory cleanup and add validation check to rmdir_path.
+- remove SIGCHLD handler.
 
 13/7/2006 autofs-5.0.1 rc1
 --------------------------
diff --git a/daemon/automount.c b/daemon/automount.c
index 736d54a..5217347 100644
--- a/daemon/automount.c
+++ b/daemon/automount.c
@@ -1519,13 +1519,6 @@ #endif
 		close(start_pipefd[1]);
 		exit(1);
 	}
-
-	if (!sigchld_start_handler()) {
-		crit(LOGOPT_ANY, "failed to create SIGCHLD handler thread!");
-		master_kill(master_list);
-		close(start_pipefd[1]);
-		exit(1);
-	}
 #if 0
 	if (!load_autofs4_module()) {
 		crit(LOGOPT_ANY, "%s: can't load %s filesystem module",
diff --git a/daemon/spawn.c b/daemon/spawn.c
index a85b667..7dc4a81 100644
--- a/daemon/spawn.c
+++ b/daemon/spawn.c
@@ -31,44 +31,6 @@ #ifdef ENABLE_MOUNT_LOCKING
 static pthread_mutex_t spawn_mutex = PTHREAD_MUTEX_INITIALIZER;
 #endif
 
-/*
- * SIGCHLD handling.
- *
- * We need to manage SIGCHLD process wide so that when we fork
- * programs we can reap the exit status in the calling thread by
- * blocking the signal. There is also the need to be able to reap
- * the exit status for child processes that are asynchronous to
- * the main program such as submount processes.
- * 
- * The method used to achieve this in our threaded environment
- * is to define a signal handler thread for SIGCHLD (and SIGCONT)
- * and, before we fork, tell it not to wait for signals so that
- * the waitpid in the subroutine that forks and execs can reap the
- * exit status.
- *
- * An added complication is that more than one thread at a time
- * may be forking program execution so we can't just simply tell
- * the handler to start listening for the signal again when done.
- * To deal with this a usage counter is used to identify when
- * there are no more threads that need to obtain an exit status
- * and we can tell the handler to start listening for the signal
- * again.
- */
-struct sigchld_mutex {
-	pthread_mutex_t mutex;
-	pthread_cond_t ready;
-	pthread_t thid;
-	unsigned int catch;
-	unsigned int count;
-};
-
-/* Start out catching SIGCHLD signals */
-static struct sigchld_mutex sm = {PTHREAD_MUTEX_INITIALIZER,
-				  PTHREAD_COND_INITIALIZER,
-				  0, 1, 0};
-
-extern pthread_attr_t thread_attr;
-
 inline void dump_core(void)
 {
 	sigset_t segv;
@@ -81,134 +43,6 @@ inline void dump_core(void)
 	raise(SIGSEGV);
 }
 
-void *sigchld(void *dummy)
-{
-	pid_t pid;
-	sigset_t sig_child;
-	int sig;
-	int status;
-
-	sigemptyset(&amp;sig_child);
-	sigaddset(&amp;sig_child, SIGCHLD);
-	sigaddset(&amp;sig_child, SIGCONT);
-
-	while (1) {
-		sigwait(&amp;sig_child, &amp;sig);
-
-		status = pthread_mutex_lock(&amp;sm.mutex);
-		if (status)
-			fatal(status);
-
-		/*
-		 * We could receive SIGCONT from two sources at the same
-		 * time. For example if we are a submount process whose startup
-		 * up is now complete and from a thread performing a fork and
-		 * exec (via sigchld_block below). So we are being told to
-		 * continue at the same time as we are bieng told to wait on
-		 * the condition. In this case catching the signal is enough
-		 * for us to continue and we also wait on the condition
-		 * (sm.catch == 0).
-		 */
-		if (!sm.catch) {
-			status = pthread_cond_wait(&amp;sm.ready, &amp;sm.mutex);
-			if (status)
-				error(LOGOPT_ANY,
-				      "SIGCHLD condition wait failed");
-		}
-
-		if (sig != SIGCONT)
-			while ((pid = waitpid(-1, NULL, WNOHANG)) &gt; 0)
-				debug(LOGOPT_NONE,
-				      "received SIGCHLD from %d", pid);
-
-		status = pthread_mutex_unlock(&amp;sm.mutex);
-		if (status)
-			error(LOGOPT_ANY,
-			      "failed to unlock SIGCHLD handler mutex");
-	}
-}
-
-int sigchld_start_handler(void)
-{
-	pthread_attr_t attrs;
-	pthread_attr_t *pattrs = &amp;attrs;
-	int status;
-
-	status = pthread_attr_init(pattrs);
-	if (status)
-		pattrs = NULL;
-	else {
-		pthread_attr_setdetachstate(pattrs, PTHREAD_CREATE_DETACHED);
-#ifdef _POSIX_THREAD_ATTR_STACKSIZE
-		pthread_attr_setstacksize(pattrs, PTHREAD_STACK_MIN*4);
-#endif
-	}
-
-	status = pthread_create(&amp;sm.thid, pattrs, sigchld, NULL);
-	if (status)
-	 	return 0;
-
-	return 1;
-}
-
-int sigchld_block(void)
-{
-	int status;
-
-	status = pthread_mutex_lock(&amp;sm.mutex);
-	if (status) {
-		error(LOGOPT_ANY, "failed to lock SIGCHLD mutex");
-		return 0;
-	}
-
-	/*
-	 * If this is the first request to block then disable
-	 * signal catching and tell the handler.
-	 */
-	if (sm.count == 0) {
-		sm.catch = 0;
-		pthread_kill(sm.thid, SIGCONT);
-	}
-
-	sm.count++;
-
-	status = pthread_mutex_unlock(&amp;sm.mutex);
-	if (status)
-		error(LOGOPT_ANY, "failed to unlock SIGCHLD mutex");
-
-	return 1;
-}
-
-int sigchld_unblock(void)
-{
-	int status;
-
-	status = pthread_mutex_lock(&amp;sm.mutex);
-	if (status) {
-		error(LOGOPT_ANY, "failed to lock SIGCHLD mutex");
-		return 0;
-	}
-
-	sm.count--;
-
-	/*
-	 * If this is the last request for blocking then enable
-	 * signal catching and tell the handler.
-	 */
-	if (sm.count == 0) {
-		sm.catch = 1;
-		status = pthread_cond_signal(&amp;sm.ready);
-		if (status)
-			error(LOGOPT_ANY, "SIGCHLD condition signal failed");
-	}
-
-	status = pthread_mutex_unlock(&amp;sm.mutex);
-	if (status)
-		error(LOGOPT_ANY, "failed to unlock SIGCHLD mutex");
-	
-	return 1;
-}
-
 /*
  * Used by subprocesses which exec to avoid carrying over the main
  * daemon's signalling environment
@@ -268,20 +102,23 @@ static int do_spawn(logger *log, int use
 	int status, pipefd[2];
 	char errbuf[ERRBUFSIZ + 1], *p, *sp;
 	int errp, errn;
-#ifdef ENABLE_MOUNT_LOCKING
 	int cancel_state;
-#endif
+	sigset_t allsigs, tmpsig, oldsig;
 
 	if (pipe(pipefd))
 		return -1;
 
-	sigchld_block();
+	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &amp;cancel_state);
+
+	sigfillset(&amp;allsigs);
+	pthread_sigmask(SIG_BLOCK, &amp;allsigs, &amp;oldsig);
 
 #ifdef ENABLE_MOUNT_LOCKING
-	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &amp;cancel_state);
 	if (use_lock) {
 		if (pthread_mutex_lock(&amp;spawn_mutex)) {
 			log(LOGOPT_ANY, "failed to lock spawn_mutex");
+			pthread_sigmask(SIG_SETMASK, &amp;oldsig, NULL);
+			pthread_setcancelstate(cancel_state, NULL);
 			return -1;
 		}
 	}
@@ -298,14 +135,20 @@ #endif
 		execv(prog, (char *const *) argv);
 		_exit(255);	/* execv() failed */
 	} else {
+		tmpsig = oldsig;
+
+		sigaddset(&amp;tmpsig, SIGCHLD);
+		pthread_sigmask(SIG_SETMASK, &amp;tmpsig, NULL);
+
 		close(pipefd[1]);
 
 		if (f &lt; 0) {
 			close(pipefd[0]);
+			pthread_sigmask(SIG_SETMASK, &amp;oldsig, NULL);
 #ifdef ENABLE_MOUNT_LOCKING
 			spawn_unlock(&amp;use_lock);
 #endif
-			sigchld_unblock();
+			pthread_setcancelstate(cancel_state, NULL);
 			return -1;
 		}
 
@@ -350,11 +193,11 @@ #endif
 		if (waitpid(f, &amp;status, 0) != f)
 			status = -1;	/* waitpid() failed */
 
+		pthread_sigmask(SIG_SETMASK, &amp;oldsig, NULL);
 #ifdef ENABLE_MOUNT_LOCKING
 		spawn_unlock(&amp;use_lock);
-		pthread_setcancelstate(cancel_state, &amp;cancel_state);
 #endif
-		sigchld_unblock();
+		pthread_setcancelstate(cancel_state, NULL);
 
 		return status;
 	}
diff --git a/include/automount.h b/include/automount.h
index 1c6e0dc..54a7180 100644
--- a/include/automount.h
+++ b/include/automount.h
@@ -191,9 +191,6 @@ int compare_argv(int argc1, const char *
 int free_argv(int argc, const char **argv);
 
 inline void dump_core(void);
-int sigchld_start_handler(void);
-int sigchld_block(void);
-int sigchld_unblock(void);
 int aquire_lock(void);
 void release_lock(void);
 int spawnl(logger *log, const char *prog, ...);
diff --git a/modules/lookup_program.c b/modules/lookup_program.c
index 0076596..eb18638 100644
--- a/modules/lookup_program.c
+++ b/modules/lookup_program.c
@@ -174,19 +174,14 @@ int lookup_mount(struct autofs_point *ap
 	 * want to send stderr to the syslog, and we don't use spawnl()
 	 * because we need the pipe hooks
 	 */
-
-	sigchld_block();
-
 	if (pipe(pipefd)) {
 		char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
 		error(ap-&gt;logopt, MODPREFIX "pipe: %s", estr);
-		sigchld_unblock();
 		goto out_free;
 	}
 	if (pipe(epipefd)) {
 		close(pipefd[0]);
 		close(pipefd[1]);
-		sigchld_unblock();
 		goto out_free;
 	}
 
@@ -198,7 +193,6 @@ int lookup_mount(struct autofs_point *ap
 		close(pipefd[1]);
 		close(epipefd[0]);
 		close(epipefd[1]);
-		sigchld_unblock();
 		goto out_free;
 	} else if (f == 0) {
 		reset_signals();
@@ -339,8 +333,6 @@ int lookup_mount(struct autofs_point *ap
 		goto out_free;
 	}
 
-	sigchld_unblock();
-
 	if (mapp == mapent || !WIFEXITED(status) || WEXITSTATUS(status) != 0) {
 		error(ap-&gt;logopt, MODPREFIX "lookup for %s failed", name);
 		goto out_free;
</pre></body></html>