diff options
author | Dag-Erling Smørgrav <des@FreeBSD.org> | 2003-04-08 18:04:30 +0000 |
---|---|---|
committer | Dag-Erling Smørgrav <des@FreeBSD.org> | 2003-04-08 18:04:30 +0000 |
commit | bc9a598f3014f05e5fc086563322e926a36eff6d (patch) | |
tree | b7dc24c26e007fd0861a7385ea5a5c6663e1b4a8 /libutil/pw_util.c | |
parent | f7530cb47347259698a9d3a38867de86bfca8789 (diff) | |
download | pw-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.c | 16 |
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; |