From owner-freebsd-bugs Wed Mar 8 13:20:10 1995 Return-Path: bugs-owner Received: (from majordom@localhost) by freefall.cdrom.com (8.6.10/8.6.6) id NAA14714 for bugs-outgoing; Wed, 8 Mar 1995 13:20:10 -0800 Received: (from gnats@localhost) by freefall.cdrom.com (8.6.10/8.6.6) id NAA14701; Wed, 8 Mar 1995 13:20:04 -0800 Date: Wed, 8 Mar 1995 13:20:04 -0800 Message-Id: <199503082120.NAA14701@freefall.cdrom.com> From: Mike Grupenhoff Reply-To: Mike Grupenhoff To: freebsd-bugs Subject: bin/234: suspending vipw hangs In-Reply-To: Your message of Wed, 8 Mar 1995 16:10:22 -0500 <199503082110.QAA23790@snarf.dorm.umd.edu> Sender: bugs-owner@FreeBSD.org Precedence: bulk >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: