diff options
author | Ray Lai <ray@cvs.openbsd.org> | 2007-04-28 01:06:19 +0000 |
---|---|---|
committer | Ray Lai <ray@cvs.openbsd.org> | 2007-04-28 01:06:19 +0000 |
commit | 111e4f2187e2e7d9357dcad5794a3edd102863af (patch) | |
tree | c132b9967ba7b44cd35d91e1306f26e4f8fdff3c /sbin/scsi | |
parent | 2f7a71cf274843eb0ba4e1fbf6cfdcfb271faa5c (diff) |
Copy sendbug's editit().
OK deraadt@.
Diffstat (limited to 'sbin/scsi')
-rw-r--r-- | sbin/scsi/scsi.c | 82 |
1 files changed, 63 insertions, 19 deletions
diff --git a/sbin/scsi/scsi.c b/sbin/scsi/scsi.c index eea7caee0ea..1b9ec4c1131 100644 --- a/sbin/scsi/scsi.c +++ b/sbin/scsi/scsi.c @@ -1,4 +1,4 @@ -/* $OpenBSD: scsi.c,v 1.23 2006/10/13 02:11:28 cloder Exp $ */ +/* $OpenBSD: scsi.c,v 1.24 2007/04/28 01:06:18 ray Exp $ */ /* $FreeBSD: scsi.c,v 1.11 1996/04/06 11:00:28 joerg Exp $ */ /* @@ -43,6 +43,9 @@ * SUCH DAMAGE. */ +#include <sys/types.h> +#include <sys/wait.h> + #include <stdio.h> #include <string.h> #include <stdlib.h> @@ -642,24 +645,61 @@ edit_get(void *hook, char *name) return arg; } -static void -edit_edit(void) +int +editit(const char *pathname) { - char *system_line; - char *editor = getenv("EDITOR"); - if (!editor) - editor = _PATH_VI; - - fclose(edit_file); - - if (asprintf(&system_line, "%s %s", editor, edit_name) == -1) - err(1, NULL); - - system(system_line); - free(system_line); - - if ( (edit_file = fopen(edit_name, "r")) == 0) - err(errno, "open %s", edit_name); + char *argp[] = {"sh", "-c", NULL, NULL}, *ed, *p; + sig_t sighup, sigint, sigquit; + pid_t pid; + int st; + + ed = getenv("VISUAL"); + if (ed == NULL || ed[0] == '\0') + ed = getenv("EDITOR"); + if (ed == NULL || ed[0] == '\0') + ed = _PATH_VI; + if (asprintf(&p, "%s %s", ed, pathname) == -1) + return (-1); + argp[2] = p; + + top: + sighup = signal(SIGHUP, SIG_IGN); + sigint = signal(SIGINT, SIG_IGN); + sigquit = signal(SIGQUIT, SIG_IGN); + if ((pid = fork()) == -1) { + int saved_errno = errno; + + (void)signal(SIGHUP, sighup); + (void)signal(SIGINT, sigint); + (void)signal(SIGQUIT, sigquit); + if (saved_errno == EAGAIN) { + sleep(1); + goto top; + } + free(p); + errno = saved_errno; + return (-1); + } + if (pid == 0) { + execv(_PATH_BSHELL, argp); + _exit(127); + } + free(p); + for (;;) { + if (waitpid(pid, &st, 0) == -1) { + if (errno != EINTR) + return (-1); + } else + break; + } + (void)signal(SIGHUP, sighup); + (void)signal(SIGINT, sigint); + (void)signal(SIGQUIT, sigquit); + if (!WIFEXITED(st) || WEXITSTATUS(st) != 0) { + errno = ECHILD; + return (-1); + } + return (0); } static void @@ -728,7 +768,11 @@ mode_edit(int fd, int page, int edit, int argc, char *argv[]) scsireq_buff_decode_visit(mode_pars, mh->mdl, fmt, edit_report, 0); - edit_edit(); + fclose(edit_file); + if (editit(edit_name) == -1 && errno != SIGCHLD) + err(1, "edit %s", edit_name); + if ((edit_file = fopen(edit_name, "r")) == NULL) + err(1, "open %s", edit_name); edit_rewind(); scsireq_buff_encode_visit(mode_pars, mh->mdl, |