Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 8 Mar 1995 13:20:04 -0800
From:      Mike Grupenhoff <kashmir@snarf.dorm.umd.edu>
To:        freebsd-bugs
Subject:   bin/234: suspending vipw hangs
Message-ID:  <199503082120.NAA14701@freefall.cdrom.com>
In-Reply-To: Your message of Wed, 8 Mar 1995 16:10:22 -0500 <199503082110.QAA23790@snarf.dorm.umd.edu>

next in thread | previous in thread | raw e-mail | index | archive | help

>Number:         234
>Category:       bin
>Synopsis:       suspending vipw hangs the whole process
>Confidential:   no
>Severity:       serious
>Priority:       low
>Responsible:    freebsd-bugs (FreeBSD bugs mailing list)
>State:          open
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Wed Mar  8 13:20:02 1995
>Originator:     Mike Grupenhoff
>Organization:
>Release:        FreeBSD 2.0-RELEASE i386
>Environment:

2.0 Release, i486DX2/50

>Description:

Hitting ^Z while in vipw causes the whole mess to hang.  vipw is not 
recognizing that the child has stopped, and waits forever.

>How-To-Repeat:

vipw
^Z

>Fix:

Here's how NetBSD fixed it:

(/usr/src/usr.sbin/vipw/pw_util.c)

--- 1.1	1995/03/08 20:42:03
+++ pw_util.c	1995/03/08 20:42:09
@@ -60,6 +60,17 @@
 #include "pw_util.h"
 
 extern char *tempname;
+static pid_t editpid = -1;
+static int lockfd;
+
+void
+pw_cont(sig)
+	int sig;
+{
+
+	if (editpid != -1)
+		kill(editpid, sig);
+}
 
 void
 pw_init()
@@ -85,15 +96,12 @@
 	(void)signal(SIGPIPE, SIG_IGN);
 	(void)signal(SIGQUIT, SIG_IGN);
 	(void)signal(SIGTERM, SIG_IGN);
-	(void)signal(SIGTSTP, SIG_IGN);
-	(void)signal(SIGTTOU, SIG_IGN);
+	(void)signal(SIGCONT, pw_cont);
 
 	/* Create with exact permissions. */
 	(void)umask(0);
 }
 
-static int lockfd;
-
 int
 pw_lock()
 {
@@ -153,7 +161,6 @@
 	int notsetuid;
 {
 	int pstat;
-	pid_t pid;
 	char *p, *editor;
 
 	if (!(editor = getenv("EDITOR")))
@@ -163,7 +170,7 @@
 	else 
 		p = editor;
 
-	if (!(pid = vfork())) {
+	if (!(editpid = vfork())) {
 		if (notsetuid) {
 			(void)setgid(getgid());
 			(void)setuid(getuid());
@@ -171,9 +178,18 @@
 		execlp(editor, p, tempname, NULL);
 		_exit(1);
 	}
-	pid = waitpid(pid, (int *)&pstat, 0);
-	if (pid == -1 || !WIFEXITED(pstat) || WEXITSTATUS(pstat) != 0)
-		pw_error(editor, 1, 1);
+	for (;;) {
+		editpid = waitpid(editpid, (int *)&pstat, WUNTRACED);
+		if (editpid == -1)
+			pw_error(editor, 1, 1);
+		else if (WIFSTOPPED(pstat))
+			raise(WSTOPSIG(pstat));
+		else if (WIFEXITED(pstat) && WEXITSTATUS(pstat) == 0)
+			break;
+		else
+			pw_error(editor, 1, 1);
+	}
+	editpid = -1;
 }
 
 void
>Audit-Trail:
>Unformatted:





Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199503082120.NAA14701>