=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/cvs/logmsg.c,v retrieving revision 1.38 retrieving revision 1.39 diff -c -r1.38 -r1.39 *** src/usr.bin/cvs/logmsg.c 2007/02/22 06:42:09 1.38 --- src/usr.bin/cvs/logmsg.c 2007/04/20 08:36:00 1.39 *************** *** 1,4 **** ! /* $OpenBSD: logmsg.c,v 1.38 2007/02/22 06:42:09 otto Exp $ */ /* * Copyright (c) 2007 Joris Vink * --- 1,4 ---- ! /* $OpenBSD: logmsg.c,v 1.39 2007/04/20 08:36:00 xsa Exp $ */ /* * Copyright (c) 2007 Joris Vink * *************** *** 16,24 **** --- 16,28 ---- */ #include + #include + #include #include #include + #include + #include #include #include *************** *** 28,33 **** --- 32,39 ---- #define CVS_LOGMSG_LINE \ "----------------------------------------------------------------------" + int cvs_logmsg_edit(const char *); + char * cvs_logmsg_read(const char *path) { *************** *** 88,97 **** struct cvs_flisthead *modified) { FILE *fp; ! int c, fd, argc, saved_errno; struct cvs_filelist *cf; struct stat st1, st2; ! char *fpath, *logmsg, *argv[4]; (void)xasprintf(&fpath, "%s/cvsXXXXXXXXXX", cvs_tmpdir); --- 94,103 ---- struct cvs_flisthead *modified) { FILE *fp; ! int c, fd, saved_errno; struct cvs_filelist *cf; struct stat st1, st2; ! char *fpath, *logmsg; (void)xasprintf(&fpath, "%s/cvsXXXXXXXXXX", cvs_tmpdir); *************** *** 143,157 **** 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) break; if (fstat(fd, &st2) == -1) { --- 149,158 ---- fatal("cvs_logmsg_create: fstat %s", strerror(saved_errno)); } logmsg = NULL; for (;;) { ! if (cvs_logmsg_edit(fpath) == -1 && errno != ECHILD) break; if (fstat(fd, &st2) == -1) { *************** *** 189,192 **** --- 190,246 ---- xfree(fpath); 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); }