diff options
-rw-r--r-- | usr.bin/cvs/logmsg.c | 72 | ||||
-rw-r--r-- | usr.bin/cvs/util.c | 26 | ||||
-rw-r--r-- | usr.bin/cvs/util.h | 3 |
3 files changed, 65 insertions, 36 deletions
diff --git a/usr.bin/cvs/logmsg.c b/usr.bin/cvs/logmsg.c index 5af73f47bb0..9d7b2218610 100644 --- a/usr.bin/cvs/logmsg.c +++ b/usr.bin/cvs/logmsg.c @@ -1,4 +1,4 @@ -/* $OpenBSD: logmsg.c,v 1.38 2007/02/22 06:42:09 otto Exp $ */ +/* $OpenBSD: logmsg.c,v 1.39 2007/04/20 08:36:00 xsa Exp $ */ /* * Copyright (c) 2007 Joris Vink <joris@openbsd.org> * @@ -16,9 +16,13 @@ */ #include <sys/stat.h> +#include <sys/types.h> +#include <sys/wait.h> #include <errno.h> #include <fcntl.h> +#include <paths.h> +#include <signal.h> #include <string.h> #include <unistd.h> @@ -28,6 +32,8 @@ #define CVS_LOGMSG_LINE \ "----------------------------------------------------------------------" +int cvs_logmsg_edit(const char *); + char * cvs_logmsg_read(const char *path) { @@ -88,10 +94,10 @@ cvs_logmsg_create(struct cvs_flisthead *added, struct cvs_flisthead *removed, struct cvs_flisthead *modified) { FILE *fp; - int c, fd, argc, saved_errno; + int c, fd, saved_errno; struct cvs_filelist *cf; struct stat st1, st2; - char *fpath, *logmsg, *argv[4]; + char *fpath, *logmsg; (void)xasprintf(&fpath, "%s/cvsXXXXXXXXXX", cvs_tmpdir); @@ -143,15 +149,10 @@ cvs_logmsg_create(struct cvs_flisthead *added, struct cvs_flisthead *removed, fatal("cvs_logmsg_create: fstat %s", strerror(saved_errno)); } - argc = 0; - argv[argc++] = cvs_editor; - argv[argc++] = fpath; - argv[argc] = NULL; - logmsg = NULL; for (;;) { - if (cvs_exec(argc, argv) < 0) + if (cvs_logmsg_edit(fpath) == -1 && errno != ECHILD) break; if (fstat(fd, &st2) == -1) { @@ -190,3 +191,56 @@ cvs_logmsg_create(struct cvs_flisthead *added, struct cvs_flisthead *removed, return (logmsg); } + +int +cvs_logmsg_edit(const char *pathname) +{ + char *argp[] = {"sh", "-c", NULL, NULL}, *p; + sig_t sighup, sigint, sigquit; + pid_t pid; + int st; + + (void)xasprintf(&p, "%s %s", cvs_editor, pathname); + 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; + } + xfree(p); + errno = saved_errno; + return (-1); + } + if (pid == 0) { + execv(_PATH_BSHELL, argp); + _exit(127); + } + xfree(p); + for (;;) { + if (waitpid(pid, &st, WUNTRACED) == -1) { + if (errno != EINTR) + return (-1); + } else if (WIFSTOPPED(st)) + raise(WSTOPSIG(st)); + 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); +} diff --git a/usr.bin/cvs/util.c b/usr.bin/cvs/util.c index 3848daec7f7..3603f718e5f 100644 --- a/usr.bin/cvs/util.c +++ b/usr.bin/cvs/util.c @@ -1,4 +1,4 @@ -/* $OpenBSD: util.c,v 1.107 2007/02/22 06:42:09 otto Exp $ */ +/* $OpenBSD: util.c,v 1.108 2007/04/20 08:36:00 xsa Exp $ */ /* * Copyright (c) 2004 Jean-Francois Brousseau <jfb@openbsd.org> * Copyright (c) 2005, 2006 Joris Vink <joris@openbsd.org> @@ -370,30 +370,6 @@ cvs_freeargv(char **argv, int argc) } /* - * cvs_exec() - */ -int -cvs_exec(int argc, char **argv) -{ - int ret; - pid_t pid; - - if ((pid = fork()) == -1) { - cvs_log(LP_ERR, "failed to fork"); - return (-1); - } else if (pid == 0) { - execvp(argv[0], argv); - cvs_log(LP_ERR, "failed to exec %s", argv[0]); - exit(1); - } - - if (waitpid(pid, &ret, 0) == -1) - cvs_log(LP_ERR, "failed to waitpid"); - - return (ret); -} - -/* * cvs_chdir() * * Change to directory <path>. diff --git a/usr.bin/cvs/util.h b/usr.bin/cvs/util.h index 13db61da576..fa4e063d955 100644 --- a/usr.bin/cvs/util.h +++ b/usr.bin/cvs/util.h @@ -1,4 +1,4 @@ -/* $OpenBSD: util.h,v 1.17 2007/02/19 11:40:00 otto Exp $ */ +/* $OpenBSD: util.h,v 1.18 2007/04/20 08:36:00 xsa Exp $ */ /* * Copyright (c) 2006 Niall O'Higgins <niallo@openbsd.org> * All rights reserved. @@ -36,7 +36,6 @@ void cvs_mkadmin(const char *, const char *, const char *, char *, char *, int); void cvs_mkpath(const char *); int cvs_cksum(const char *, char *, size_t); -int cvs_exec(int, char **); int cvs_getargv(const char *, char **, int); int cvs_chdir(const char *, int); int cvs_rename(const char *, const char *); |