summaryrefslogtreecommitdiffstats
path: root/lib/libutil
diff options
context:
space:
mode:
authordes <des@FreeBSD.org>2003-04-09 16:39:47 +0000
committerdes <des@FreeBSD.org>2003-04-09 16:39:47 +0000
commit12196b5a56e42dc797dbf1fa7da46413dad7921c (patch)
tree2879d81ad1ada7a84110a5239aa7efbfd4fcc3d6 /lib/libutil
parent04fd973e424b1f7d2d78b8a549c504b025e7a089 (diff)
downloadFreeBSD-src-12196b5a56e42dc797dbf1fa7da46413dad7921c.zip
FreeBSD-src-12196b5a56e42dc797dbf1fa7da46413dad7921c.tar.gz
Apply the correct fix for bin/50679: don't mess around with process groups
or the tty, just block selected signals in the parent like system(3) does. Many thanks to bde for his assistance in finding the correct solution. PR: bin/50679
Diffstat (limited to 'lib/libutil')
-rw-r--r--lib/libutil/pw_util.c32
1 files changed, 19 insertions, 13 deletions
diff --git a/lib/libutil/pw_util.c b/lib/libutil/pw_util.c
index 5d831e0..053ac56 100644
--- a/lib/libutil/pw_util.c
+++ b/lib/libutil/pw_util.c
@@ -287,54 +287,60 @@ pw_mkdb(const char *user)
int
pw_edit(int notsetuid)
{
+ struct sigaction sa, sa_int, sa_quit;
+ sigset_t sigset, oldsigset;
struct stat st1, st2;
const char *editor;
- char *editcmd;
int pstat;
if ((editor = getenv("EDITOR")) == NULL)
editor = _PATH_VI;
if (stat(tempname, &st1) == -1)
return (-1);
+ sa.sa_handler = SIG_IGN;
+ sigemptyset(&sa.sa_mask);
+ sa.sa_flags = 0;
+ sigaction(SIGINT, &sa, &sa_int);
+ sigaction(SIGQUIT, &sa, &sa_quit);
+ sigemptyset(&sigset);
+ sigaddset(&sigset, SIGCHLD);
+ sigprocmask(SIG_BLOCK, &sigset, &oldsigset);
switch ((editpid = fork())) {
case -1:
return (-1);
case 0:
- /* child */
+ sigaction(SIGINT, &sa_int, NULL);
+ sigaction(SIGQUIT, &sa_quit, NULL);
+ sigprocmask(SIG_SETMASK, &oldsigset, NULL);
if (notsetuid) {
(void)setgid(getgid());
(void)setuid(getuid());
}
- if (asprintf(&editcmd, "exec %s %s", editor, tempname) == NULL)
- _exit(EXIT_FAILURE);
errno = 0;
- execl(_PATH_BSHELL, "sh", "-c", editcmd, NULL);
- free(editcmd);
+ execlp(editor, editor, tempname, NULL);
_exit(errno);
default:
/* parent */
break;
}
- setpgid(editpid, editpid);
- tcsetpgrp(1, editpid);
for (;;) {
if (waitpid(editpid, &pstat, WUNTRACED) == -1) {
unlink(tempname);
- return (-1);
+ break;
} else if (WIFSTOPPED(pstat)) {
raise(WSTOPSIG(pstat));
- tcsetpgrp(1, getpgid(editpid));
- kill(editpid, SIGCONT);
} else if (WIFEXITED(pstat) && WEXITSTATUS(pstat) == 0) {
editpid = -1;
break;
} else {
unlink(tempname);
- *tempname = '\0';
editpid = -1;
- return (-1);
+ break;
}
}
+ sigaction(SIGINT, &sa_int, NULL);
+ sigaction(SIGQUIT, &sa_quit, NULL);
+ sigprocmask(SIG_SETMASK, &oldsigset, NULL);
if (stat(tempname, &st2) == -1)
return (-1);
return (st1.st_mtime != st2.st_mtime);
OpenPOWER on IntegriCloud