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>
index | next in thread | previous in thread | raw e-mail
>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:
help
Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199503082120.NAA14701>
