summaryrefslogtreecommitdiffstats
path: root/libutil/pw_util.c
diff options
context:
space:
mode:
authorDag-Erling Smørgrav <des@FreeBSD.org>2003-04-08 18:04:30 +0000
committerDag-Erling Smørgrav <des@FreeBSD.org>2003-04-08 18:04:30 +0000
commitbc9a598f3014f05e5fc086563322e926a36eff6d (patch)
treeb7dc24c26e007fd0861a7385ea5a5c6663e1b4a8 /libutil/pw_util.c
parentf7530cb47347259698a9d3a38867de86bfca8789 (diff)
downloadpw-darwin-bc9a598f3014f05e5fc086563322e926a36eff6d.tar.gz
pw-darwin-bc9a598f3014f05e5fc086563322e926a36eff6d.tar.zst
pw-darwin-bc9a598f3014f05e5fc086563322e926a36eff6d.zip
Band-aid for the "^C kills the editor" problem. I haven't yet found the
proper way to fix this. The way this works is to prepend "exec " to the editor command to eliminate the "shell in the middle" which prevents us from properly reawakening the editor after a SIGTSTP. PR: bin/50679
Diffstat (limited to 'libutil/pw_util.c')
-rw-r--r--libutil/pw_util.c16
1 files changed, 6 insertions, 10 deletions
diff --git a/libutil/pw_util.c b/libutil/pw_util.c
index 5eb0953..5d831e0 100644
--- a/libutil/pw_util.c
+++ b/libutil/pw_util.c
@@ -290,7 +290,6 @@ pw_edit(int notsetuid)
struct stat st1, st2;
const char *editor;
char *editcmd;
- int editcmdlen;
int pstat;
if ((editor = getenv("EDITOR")) == NULL)
@@ -306,14 +305,8 @@ pw_edit(int notsetuid)
(void)setgid(getgid());
(void)setuid(getuid());
}
- if ((editcmdlen = sysconf(_SC_ARG_MAX) - 6) <= 0 ||
- (editcmd = malloc(editcmdlen)) == NULL)
+ if (asprintf(&editcmd, "exec %s %s", editor, tempname) == NULL)
_exit(EXIT_FAILURE);
- if (snprintf(editcmd, editcmdlen, "%s %s",
- editor, tempname) >= editcmdlen) {
- free(editcmd); /* pedantry */
- _exit(EXIT_FAILURE);
- }
errno = 0;
execl(_PATH_BSHELL, "sh", "-c", editcmd, NULL);
free(editcmd);
@@ -322,13 +315,16 @@ pw_edit(int notsetuid)
/* parent */
break;
}
+ setpgid(editpid, editpid);
+ tcsetpgrp(1, editpid);
for (;;) {
- editpid = waitpid(editpid, &pstat, WUNTRACED);
- if (editpid == -1) {
+ if (waitpid(editpid, &pstat, WUNTRACED) == -1) {
unlink(tempname);
return (-1);
} else if (WIFSTOPPED(pstat)) {
raise(WSTOPSIG(pstat));
+ tcsetpgrp(1, getpgid(editpid));
+ kill(editpid, SIGCONT);
} else if (WIFEXITED(pstat) && WEXITSTATUS(pstat) == 0) {
editpid = -1;
break;