summaryrefslogtreecommitdiffstats
path: root/libutil
diff options
context:
space:
mode:
authorAndrey A. Chernov <ache@FreeBSD.org>1995-03-09 21:53:12 +0000
committerAndrey A. Chernov <ache@FreeBSD.org>1995-03-09 21:53:12 +0000
commitdf3e060f6ca69cec91cb52d0e0f1b6cd2b856884 (patch)
tree353b9114495a7fe7de1599587b17446bb4a8e0f4 /libutil
parentce9febd5daa1c8a6e0fd87e9a28d40a11733bd4a (diff)
downloadpw-darwin-df3e060f6ca69cec91cb52d0e0f1b6cd2b856884.tar.gz
pw-darwin-df3e060f6ca69cec91cb52d0e0f1b6cd2b856884.tar.zst
pw-darwin-df3e060f6ca69cec91cb52d0e0f1b6cd2b856884.zip
Fix suspended vipw hangs
Obtained from: NetBSD
Diffstat (limited to 'libutil')
-rw-r--r--libutil/pw_util.c34
1 files changed, 25 insertions, 9 deletions
diff --git a/libutil/pw_util.c b/libutil/pw_util.c
index 9873f74..c851fcb 100644
--- a/libutil/pw_util.c
+++ b/libutil/pw_util.c
@@ -60,6 +60,17 @@ static char sccsid[] = "@(#)pw_util.c 8.3 (Berkeley) 4/2/94";
#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 @@ pw_init()
(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 @@ pw_edit(notsetuid)
int notsetuid;
{
int pstat;
- pid_t pid;
char *p, *editor;
if (!(editor = getenv("EDITOR")))
@@ -163,7 +170,7 @@ pw_edit(notsetuid)
else
p = editor;
- if (!(pid = vfork())) {
+ if (!(editpid = vfork())) {
if (notsetuid) {
(void)setgid(getgid());
(void)setuid(getuid());
@@ -171,9 +178,18 @@ pw_edit(notsetuid)
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