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 <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

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 <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 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 <b...@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));
+}

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 <b...@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 *);
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to