From owner-svn-src-all@freebsd.org Sat Jun 9 20:24:19 2018 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 7CFF810188EB; Sat, 9 Jun 2018 20:24:19 +0000 (UTC) (envelope-from bapt@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 2E23073DA1; Sat, 9 Jun 2018 20:24:19 +0000 (UTC) (envelope-from bapt@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 0B6D322B34; Sat, 9 Jun 2018 20:24:19 +0000 (UTC) (envelope-from bapt@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id w59KOIdO098742; Sat, 9 Jun 2018 20:24:18 GMT (envelope-from bapt@FreeBSD.org) Received: (from bapt@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id w59KOIwO098738; Sat, 9 Jun 2018 20:24:18 GMT (envelope-from bapt@FreeBSD.org) Message-Id: <201806092024.w59KOIwO098738@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: bapt set sender to bapt@FreeBSD.org using -f From: Baptiste Daroussin Date: Sat, 9 Jun 2018 20:24:18 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r334894 - head/usr.bin/diff X-SVN-Group: head X-SVN-Commit-Author: bapt X-SVN-Commit-Paths: head/usr.bin/diff X-SVN-Commit-Revision: 334894 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.26 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 09 Jun 2018 20:24:19 -0000 Author: bapt Date: Sat Jun 9 20:24:17 2018 New Revision: 334894 URL: https://svnweb.freebsd.org/changeset/base/334894 Log: Isolate the pr(1) related code in its own source files This keeps diffreg.c closer to what it is supposed to do: diffing regular files. It also allows my code to get a proper license Added: head/usr.bin/diff/pr.c (contents, props changed) head/usr.bin/diff/pr.h (contents, props changed) Modified: head/usr.bin/diff/Makefile head/usr.bin/diff/diffreg.c Modified: head/usr.bin/diff/Makefile ============================================================================== --- head/usr.bin/diff/Makefile Sat Jun 9 20:06:06 2018 (r334893) +++ head/usr.bin/diff/Makefile Sat Jun 9 20:24:17 2018 (r334894) @@ -3,7 +3,7 @@ .include PROG= diff -SRCS= diff.c diffdir.c diffreg.c xmalloc.c +SRCS= diff.c diffdir.c diffreg.c xmalloc.c pr.c HAS_TESTS= SUBDIR.${MK_TESTS}+= tests Modified: head/usr.bin/diff/diffreg.c ============================================================================== --- head/usr.bin/diff/diffreg.c Sat Jun 9 20:06:06 2018 (r334893) +++ head/usr.bin/diff/diffreg.c Sat Jun 9 20:24:17 2018 (r334894) @@ -70,11 +70,7 @@ __FBSDID("$FreeBSD$"); #include -#include #include -#include -#include -#include #include #include @@ -88,15 +84,11 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include -#include -#include +#include "pr.h" #include "diff.h" #include "xmalloc.h" -#define _PATH_PR "/usr/bin/pr" - /* * diff - compare two files. */ @@ -260,13 +252,9 @@ diffreg(char *file1, char *file2, int flags, int capsi { FILE *f1, *f2; int i, rval; - int ostdout = -1; - int pr_pd, kq; - struct kevent *e; + struct pr *pr = NULL; cap_rights_t rights_ro; - e = NULL; - kq = -1; f1 = f2 = NULL; rval = D_SAME; anychange = 0; @@ -324,53 +312,9 @@ diffreg(char *file1, char *file2, int flags, int capsi goto closem; } - if (lflag) { - /* redirect stdout to pr */ - int pfd[2]; - pid_t pid; - char *header; + if (lflag) + pr = start_pr(file1, file2); - xasprintf(&header, "%s %s %s", diffargs, file1, file2); - signal(SIGPIPE, SIG_IGN); - fflush(stdout); - rewind(stdout); - pipe(pfd); - switch ((pid = pdfork(&pr_pd, PD_CLOEXEC))) { - case -1: - status |= 2; - free(header); - err(2, "No more processes"); - case 0: - /* child */ - if (pfd[0] != STDIN_FILENO) { - dup2(pfd[0], STDIN_FILENO); - close(pfd[0]); - } - close(pfd[1]); - execl(_PATH_PR, _PATH_PR, "-h", header, (char *)0); - _exit(127); - default: - - /* parent */ - if (pfd[1] != STDOUT_FILENO) { - ostdout = dup(STDOUT_FILENO); - dup2(pfd[1], STDOUT_FILENO); - close(pfd[1]); - } - close(pfd[0]); - rewind(stdout); - free(header); - kq = kqueue(); - if (kq == -1) - err(2, "kqueue"); - e = xmalloc(sizeof(struct kevent)); - EV_SET(e, pr_pd, EVFILT_PROCDESC, EV_ADD, NOTE_EXIT, 0, - NULL); - if (kevent(kq, e, 1, NULL, 0, NULL) == -1) - err(2, "kevent"); - } - } - if (capsicum) { cap_rights_init(&rights_ro, CAP_READ, CAP_FSTAT, CAP_SEEK); if (cap_rights_limit(fileno(f1), &rights_ro) < 0 @@ -443,26 +387,8 @@ diffreg(char *file1, char *file2, int flags, int capsi ixnew = xreallocarray(ixnew, len[1] + 2, sizeof(*ixnew)); check(f1, f2, flags); output(file1, f1, file2, f2, flags); - if (ostdout != -1 && e != NULL) { - /* close the pipe to pr and restore stdout */ - int wstatus; - - fflush(stdout); - if (ostdout != STDOUT_FILENO) { - close(STDOUT_FILENO); - dup2(ostdout, STDOUT_FILENO); - close(ostdout); - } - if (kevent(kq, NULL, 0, e, 1, NULL) == -1) - err(2, "kevent"); - wstatus = e[0].data; - close(kq); - if (WIFEXITED(wstatus) && WEXITSTATUS(wstatus) != 0) - errx(2, "pr exited abnormally"); - else if (WIFSIGNALED(wstatus)) - errx(2, "pr killed by signal %d", - WTERMSIG(wstatus)); - } + if (pr != NULL) + stop_pr(pr); closem: if (anychange) { Added: head/usr.bin/diff/pr.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/usr.bin/diff/pr.c Sat Jun 9 20:24:17 2018 (r334894) @@ -0,0 +1,124 @@ +/*- + * Copyright (c) 2017 Baptiste Daroussin + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer + * in this position and unchanged. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "pr.h" +#include "diff.h" +#include "xmalloc.h" + +#define _PATH_PR "/usr/bin/pr" + +struct pr * +start_pr(char *file1, char *file2) +{ + int pfd[2]; + int pr_pd; + pid_t pid; + char *header; + struct pr *pr; + + pr = xcalloc(1, sizeof(*pr)); + + xasprintf(&header, "%s %s %s", diffargs, file1, file2); + signal(SIGPIPE, SIG_IGN); + fflush(stdout); + rewind(stdout); + pipe(pfd); + switch ((pid = pdfork(&pr_pd, PD_CLOEXEC))) { + case -1: + status |= 2; + free(header); + err(2, "No more processes"); + case 0: + /* child */ + if (pfd[0] != STDIN_FILENO) { + dup2(pfd[0], STDIN_FILENO); + close(pfd[0]); + } + close(pfd[1]); + execl(_PATH_PR, _PATH_PR, "-h", header, (char *)0); + _exit(127); + default: + + /* parent */ + if (pfd[1] != STDOUT_FILENO) { + pr->ostdout = dup(STDOUT_FILENO); + dup2(pfd[1], STDOUT_FILENO); + close(pfd[1]); + close(pfd[1]); + } + close(pfd[0]); + rewind(stdout); + free(header); + pr->kq = kqueue(); + if (pr->kq == -1) + err(2, "kqueue"); + pr->e = xmalloc(sizeof(struct kevent)); + EV_SET(pr->e, pr_pd, EVFILT_PROCDESC, EV_ADD, NOTE_EXIT, 0, + NULL); + if (kevent(pr->kq, pr->e, 1, NULL, 0, NULL) == -1) + err(2, "kevent"); + } + return (pr); +} + +/* close the pipe to pr and restore stdout */ +void +stop_pr(struct pr *pr) +{ + int wstatus; + + if (pr == NULL) + return; + + fflush(stdout); + if (pr->ostdout != STDOUT_FILENO) { + close(STDOUT_FILENO); + dup2(pr->ostdout, STDOUT_FILENO); + close(pr->ostdout); + } + if (kevent(pr->kq, NULL, 0, pr->e, 1, NULL) == -1) + err(2, "kevent"); + wstatus = pr->e[0].data; + close(pr->kq); + if (WIFEXITED(wstatus) && WEXITSTATUS(wstatus) != 0) + errx(2, "pr exited abnormally"); + else if (WIFSIGNALED(wstatus)) + errx(2, "pr killed by signal %d", + WTERMSIG(wstatus)); +} Added: head/usr.bin/diff/pr.h ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/usr.bin/diff/pr.h Sat Jun 9 20:24:17 2018 (r334894) @@ -0,0 +1,38 @@ +/*- + * Copyright (c) 2017 Baptiste Daroussin + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer + * in this position and unchanged. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#include + +struct pr { + int ostdout; + int kq; + struct kevent *e; +}; + +struct pr *start_pr(char *file1, char *file2); +void stop_pr(struct pr *);