Fix suspended vipw hangs
Obtained from: NetBSD
This commit is contained in:
parent
632f53dd4f
commit
b603d90c20
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user