diff options
| author | tron <tron@NetBSD.org> | 2000-07-09 23:07:14 +0000 |
|---|---|---|
| committer | tron <tron@NetBSD.org> | 2000-07-09 23:07:14 +0000 |
| commit | 93cb6f8300a126ba5e8ff024410f69795d96f7d4 (patch) | |
| tree | f316c79b64fe3731fd7e37a89c856ef45348d21a /libexec/makewhatis | |
| parent | 1cfb5e64568c3c2b0769e226fc25b9e734774f09 (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/makewhatis')
| -rw-r--r-- | libexec/makewhatis/makewhatis.c | 94 |
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(§ion[2], ") - "); } } + else if (strncasecmp(buffer, ".Ds", 3) == 0) + return nroff(in); } while ((strncasecmp(buffer, ".Sh NAME", 8) != 0)); do { |
