summaryrefslogtreecommitdiff
path: root/usr.bin/diff
diff options
context:
space:
mode:
authorBaptiste Daroussin <bapt@FreeBSD.org>2018-06-09 20:24:17 +0000
committerBaptiste Daroussin <bapt@FreeBSD.org>2018-06-09 20:24:17 +0000
commit6fa5bf0832efe8a894f612968c5afe1ad91f3a03 (patch)
tree63c447bffc0581ca045a4b097996f01b66933108 /usr.bin/diff
parentdd0bdd6b456dcc3a798f6dba142eac0e334824b0 (diff)
downloadsrc-test2-6fa5bf0832efe8a894f612968c5afe1ad91f3a03.tar.gz
src-test2-6fa5bf0832efe8a894f612968c5afe1ad91f3a03.zip
Notes
Diffstat (limited to 'usr.bin/diff')
-rw-r--r--usr.bin/diff/Makefile2
-rw-r--r--usr.bin/diff/diffreg.c86
-rw-r--r--usr.bin/diff/pr.c124
-rw-r--r--usr.bin/diff/pr.h38
4 files changed, 169 insertions, 81 deletions
diff --git a/usr.bin/diff/Makefile b/usr.bin/diff/Makefile
index 18c4495cf1c7..a9f79d3d81e1 100644
--- a/usr.bin/diff/Makefile
+++ b/usr.bin/diff/Makefile
@@ -3,7 +3,7 @@
.include <src.opts.mk>
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
diff --git a/usr.bin/diff/diffreg.c b/usr.bin/diff/diffreg.c
index b7a0135bdf12..84cb4ac58c21 100644
--- a/usr.bin/diff/diffreg.c
+++ b/usr.bin/diff/diffreg.c
@@ -70,11 +70,7 @@
__FBSDID("$FreeBSD$");
#include <sys/capsicum.h>
-#include <sys/procdesc.h>
#include <sys/stat.h>
-#include <sys/types.h>
-#include <sys/event.h>
-#include <sys/wait.h>
#include <capsicum_helpers.h>
#include <ctype.h>
@@ -88,15 +84,11 @@ __FBSDID("$FreeBSD$");
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <unistd.h>
-#include <limits.h>
-#include <signal.h>
+#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 capsicum)
{
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,52 +312,8 @@ diffreg(char *file1, char *file2, int flags, int capsicum)
goto closem;
}
- if (lflag) {
- /* redirect stdout to pr */
- int pfd[2];
- pid_t pid;
- char *header;
-
- 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 (lflag)
+ pr = start_pr(file1, file2);
if (capsicum) {
cap_rights_init(&rights_ro, CAP_READ, CAP_FSTAT, CAP_SEEK);
@@ -443,26 +387,8 @@ diffreg(char *file1, char *file2, int flags, int capsicum)
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) {
diff --git a/usr.bin/diff/pr.c b/usr.bin/diff/pr.c
new file mode 100644
index 000000000000..eaf6e37f9f4f
--- /dev/null
+++ b/usr.bin/diff/pr.c
@@ -0,0 +1,124 @@
+/*-
+ * Copyright (c) 2017 Baptiste Daroussin <bapt@FreeBSD.org>
+ * 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 <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/procdesc.h>
+#include <sys/wait.h>
+
+#include <err.h>
+#include <paths.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#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));
+}
diff --git a/usr.bin/diff/pr.h b/usr.bin/diff/pr.h
new file mode 100644
index 000000000000..e442d5fd4423
--- /dev/null
+++ b/usr.bin/diff/pr.h
@@ -0,0 +1,38 @@
+/*-
+ * Copyright (c) 2017 Baptiste Daroussin <bapt@FreeBSD.org>
+ * 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 <sys/event.h>
+
+struct pr {
+ int ostdout;
+ int kq;
+ struct kevent *e;
+};
+
+struct pr *start_pr(char *file1, char *file2);
+void stop_pr(struct pr *);