summaryrefslogtreecommitdiff
path: root/libexec
diff options
context:
space:
mode:
authortron <tron@NetBSD.org>2000-07-09 23:07:14 +0000
committertron <tron@NetBSD.org>2000-07-09 23:07:14 +0000
commit93cb6f8300a126ba5e8ff024410f69795d96f7d4 (patch)
treef316c79b64fe3731fd7e37a89c856ef45348d21a /libexec
parent1cfb5e64568c3c2b0769e226fc25b9e734774f09 (diff)
Invoke "nroff" and parse its output if an unformatted manual page uses
macros. Fixes PR bin/9083 by Geoff C. Wing.
Diffstat (limited to 'libexec')
-rw-r--r--libexec/makewhatis/makewhatis.c94
1 files changed, 91 insertions, 3 deletions
diff --git a/libexec/makewhatis/makewhatis.c b/libexec/makewhatis/makewhatis.c
index df0147dd8b4..c74c40715f2 100644
--- a/libexec/makewhatis/makewhatis.c
+++ b/libexec/makewhatis/makewhatis.c
@@ -1,4 +1,4 @@
-/* $NetBSD: makewhatis.c,v 1.7 2000/01/24 23:03:54 tron Exp $ */
+/* $NetBSD: makewhatis.c,v 1.8 2000/07/09 23:07:14 tron Exp $ */
/*-
* Copyright (c) 1999 The NetBSD Foundation, Inc.
@@ -43,17 +43,20 @@ __COPYRIGHT("@(#) Copyright (c) 1999 The NetBSD Foundation, Inc.\n\
#endif /* not lint */
#ifndef lint
-__RCSID("$NetBSD: makewhatis.c,v 1.7 2000/01/24 23:03:54 tron Exp $");
+__RCSID("$NetBSD: makewhatis.c,v 1.8 2000/07/09 23:07:14 tron Exp $");
#endif /* not lint */
#include <sys/types.h>
+#include <sys/param.h>
#include <sys/stat.h>
+#include <sys/wait.h>
#include <ctype.h>
#include <err.h>
#include <errno.h>
#include <fts.h>
#include <locale.h>
+#include <paths.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -74,6 +77,7 @@ struct whatisstruct {
};
int main (int, char **);
+void sigchildhandler(int);
char *findwhitespace(char *);
char *GetS(gzFile, char *, int);
int manpagesection (char *);
@@ -83,6 +87,7 @@ char *replacestring (char *, char *, char *);
void catpreprocess (char *);
char *parsecatpage (gzFile *);
int manpreprocess (char *);
+char *nroff (gzFile *);
char *parsemanpage (gzFile *, int);
char *getwhatisdata (char *);
void processmanpages (manpage **,whatis **);
@@ -109,6 +114,7 @@ main(int argc,char **argv)
FILE *out;
(void)setlocale(LC_ALL, "");
+ (void)signal(SIGCHLD, sigchildhandler);
manpath = (argc < 2) ? default_manpath : &argv[1];
@@ -135,7 +141,7 @@ main(int argc,char **argv)
default:
errx(EXIT_FAILURE, "%s: %s", fe->fts_path,
strerror(fe->fts_errno));
- /* NOTREACHED */
+
}
}
@@ -158,6 +164,13 @@ main(int argc,char **argv)
return EXIT_SUCCESS;
}
+void
+sigchildhandler(int signum)
+
+{
+ while (waitpid(-1, NULL, WNOHANG) > 0);
+}
+
char
*findwhitespace(char *str)
@@ -448,6 +461,79 @@ manpreprocess(char *line)
}
char *
+nroff(gzFile *in)
+{
+ char tempname[MAXPATHLEN], buffer[8192], *data;
+ int tempfd, bytes, pipefd[2];
+ pid_t child;
+
+ if (gzrewind(in) < 0) {
+ perror(__progname);
+ return NULL;
+ }
+
+ (void)strcpy(tempname, _PATH_TMP "makewhatis.XXXXXX");
+ if ((tempfd = mkstemp(tempname)) < 0) {
+ perror(__progname);
+ return NULL;
+ }
+
+ while ((bytes = gzread(in, buffer, sizeof(buffer))) > 0)
+ if (write(tempfd, buffer, bytes) != bytes) {
+ bytes = -1;
+ break;
+ }
+
+ if ((bytes < 0) ||
+ (lseek(tempfd, 0, SEEK_SET) < 0) ||
+ (pipe(pipefd) < 0)) {
+ perror(__progname);
+ (void)close(tempfd);
+ (void)unlink(tempname);
+ return NULL;
+ }
+
+ switch (child = vfork()) {
+ case -1:
+ perror(__progname);
+ (void)close(pipefd[1]);
+ (void)close(pipefd[0]);
+ (void)close(tempfd);
+ (void)unlink(tempname);
+ return NULL;
+ /* NOTREACHED */
+ case 0:
+ (void)close(pipefd[0]);
+ if (pipefd[1] != STDOUT_FILENO) {
+ (void)dup2(pipefd[1], STDOUT_FILENO);
+ (void)close(pipefd[1]);
+ }
+ (void)execlp("nroff", "nroff", "-mandoc", tempname, NULL);
+ _exit(EXIT_FAILURE);
+ default:
+ (void)close(pipefd[1]);
+ (void)close(tempfd);
+ /* NOTREACHED */
+ }
+
+ if ((in = gzdopen(pipefd[0], "r")) == NULL) {
+ if (errno == 0)
+ errno = ENOMEM;
+ perror(__progname);
+ (void)close(pipefd[0]); /* Child will be killed by SIGPIPE. */
+ (void)unlink(tempname);
+ return NULL;
+ }
+
+ data = parsecatpage(in);
+
+ (void)gzclose(in); /* Child will be killed by SIGPIPE. */
+ (void)unlink(tempname);
+
+ return data;
+}
+
+char *
parsemanpage(gzFile *in, int defaultsection)
{
char *section, buffer[8192], *ptr;
@@ -480,6 +566,8 @@ parsemanpage(gzFile *in, int defaultsection)
(void) strcat(&section[2], ") - ");
}
}
+ else if (strncasecmp(buffer, ".Ds", 3) == 0)
+ return nroff(in);
} while ((strncasecmp(buffer, ".Sh NAME", 8) != 0));
do {