=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/mandoc/mandocdb.c,v retrieving revision 1.203 retrieving revision 1.204 diff -c -r1.203 -r1.204 *** src/usr.bin/mandoc/mandocdb.c 2017/08/26 12:59:13 1.203 --- src/usr.bin/mandoc/mandocdb.c 2017/08/26 15:55:41 1.204 *************** *** 1,4 **** ! /* $OpenBSD: mandocdb.c,v 1.203 2017/08/26 12:59:13 schwarze Exp $ */ /* * Copyright (c) 2011, 2012 Kristaps Dzonsons * Copyright (c) 2011-2017 Ingo Schwarze --- 1,4 ---- ! /* $OpenBSD: mandocdb.c,v 1.204 2017/08/26 15:55:41 schwarze Exp $ */ /* * Copyright (c) 2011, 2012 Kristaps Dzonsons * Copyright (c) 2011-2017 Ingo Schwarze *************** *** 17,24 **** * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include #include - #include #include #include --- 17,24 ---- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include + #include #include #include #include *************** *** 303,309 **** size_t j, sz; int ch, i; ! if (pledge("stdio rpath wpath cpath fattr flock proc exec", NULL) == -1) { warn("pledge"); return (int)MANDOCLEVEL_SYSERR; } --- 303,309 ---- size_t j, sz; int ch, i; ! if (pledge("stdio rpath wpath cpath", NULL) == -1) { warn("pledge"); return (int)MANDOCLEVEL_SYSERR; } *************** *** 414,426 **** * The existing database is usable. Process * all files specified on the command-line. */ - if (!nodb) { - if (pledge("stdio rpath wpath cpath fattr flock", NULL) == -1) { - warn("pledge"); - exitcode = (int)MANDOCLEVEL_SYSERR; - goto out; - } - } use_all = 1; for (i = 0; i < argc; i++) filescan(argv[i]); --- 414,419 ---- *************** *** 2079,2087 **** static void dbwrite(struct dba *dba) { ! char tfn[33]; ! int status; ! pid_t child; /* * Do not write empty databases, and delete existing ones --- 2072,2081 ---- static void dbwrite(struct dba *dba) { ! struct stat sb1, sb2; ! char tfn[33], *cp1, *cp2; ! off_t i; ! int fd1, fd2; /* * Do not write empty databases, and delete existing ones *************** *** 2120,2158 **** say("", "&%s", tfn); return; } ! (void)strlcat(tfn, "/" MANDOC_DB, sizeof(tfn)); if (dba_write(tfn, dba) == -1) { - exitcode = (int)MANDOCLEVEL_SYSERR; say(tfn, "&dba_write"); ! goto out; } ! ! switch (child = fork()) { ! case -1: ! exitcode = (int)MANDOCLEVEL_SYSERR; ! say("", "&fork cmp"); ! return; ! case 0: ! execlp("cmp", "cmp", "-s", tfn, MANDOC_DB, (char *)NULL); ! say("", "&exec cmp"); ! exit(0); ! default: ! break; } ! if (waitpid(child, &status, 0) == -1) { ! exitcode = (int)MANDOCLEVEL_SYSERR; ! say("", "&wait cmp"); ! } else if (WIFSIGNALED(status)) { ! exitcode = (int)MANDOCLEVEL_SYSERR; ! say("", "cmp died from signal %d", WTERMSIG(status)); ! } else if (WEXITSTATUS(status)) { ! exitcode = (int)MANDOCLEVEL_SYSERR; ! say(MANDOC_DB, ! "Data changed, but cannot replace database"); } out: unlink(tfn); *strrchr(tfn, '/') = '\0'; rmdir(tfn); --- 2114,2172 ---- say("", "&%s", tfn); return; } ! cp1 = cp2 = NULL; ! fd1 = fd2 = -1; (void)strlcat(tfn, "/" MANDOC_DB, sizeof(tfn)); if (dba_write(tfn, dba) == -1) { say(tfn, "&dba_write"); ! goto err; } ! if ((fd1 = open(MANDOC_DB, O_RDONLY, 0)) == -1) { ! say(MANDOC_DB, "&open"); ! goto err; } ! if ((fd2 = open(tfn, O_RDONLY, 0)) == -1) { ! say(tfn, "&open"); ! goto err; } + if (fstat(fd1, &sb1) == -1) { + say(MANDOC_DB, "&fstat"); + goto err; + } + if (fstat(fd2, &sb2) == -1) { + say(tfn, "&fstat"); + goto err; + } + if (sb1.st_size != sb2.st_size) + goto err; + if ((cp1 = mmap(NULL, sb1.st_size, PROT_READ, MAP_PRIVATE, + fd1, 0)) == NULL) { + say(MANDOC_DB, "&mmap"); + goto err; + } + if ((cp2 = mmap(NULL, sb2.st_size, PROT_READ, MAP_PRIVATE, + fd2, 0)) == NULL) { + say(tfn, "&mmap"); + goto err; + } + for (i = 0; i < sb1.st_size; i++) + if (cp1[i] != cp2[i]) + goto err; + goto out; + err: + exitcode = (int)MANDOCLEVEL_SYSERR; + say(MANDOC_DB, "Data changed, but cannot replace database"); + out: + if (cp1 != NULL) + munmap(cp1, sb1.st_size); + if (cp2 != NULL) + munmap(cp2, sb2.st_size); + if (fd1 != -1) + close(fd1); + if (fd2 != -1) + close(fd2); unlink(tfn); *strrchr(tfn, '/') = '\0'; rmdir(tfn);