aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/term_tag.c
diff options
context:
space:
mode:
authorIngo Schwarze <schwarze@openbsd.org>2020-04-02 22:12:55 +0000
committerIngo Schwarze <schwarze@openbsd.org>2020-04-02 22:12:55 +0000
commit4f3f1706132956d635c2c2cefb04b0418c6f0f18 (patch)
tree6c68a2e2991f2fd5e47e9443ee208b4f5c769924 /term_tag.c
parent735c1e543343b638b339077b91a5874260cdf14b (diff)
downloadmandoc-4f3f1706132956d635c2c2cefb04b0418c6f0f18.tar.gz
mandoc-4f3f1706132956d635c2c2cefb04b0418c6f0f18.tar.zst
mandoc-4f3f1706132956d635c2c2cefb04b0418c6f0f18.zip
When the last file formatted yielded no tags, the tags file got
deleted before starting the pager, even when earlier input files had written to it; thanks to weerd@ for reporting that bug. Since we now generate tags for section headers, we almost always generate at least some. Consequently, while fixing the above bug, simplify the code by never deleting the tags file before the pager exits, not even in the rare case that the file happens to be empty. Hence, this patch is -75 +63 LOC even though it fixes two bugs. While deleting the output files belongs after exit from the pager, closing them should be done before it is started. Collect the related code, which was scattered in various places, to where it belongs, in a dedicated function in the term_tag.c module. As a side benefit, never fclose(2) stdout, only dup2(2) to it. Similarly, when the -O tag argument wasn't found in the last file formatted, there was a complaint about "no such tag" even when the argument did occur in earlier files. Fix that by looking for a matching tag after every formatted file rather than just once at the very end. Given that command line arguments aren't properties of the file(s) being formatted, that check is a job for the main program, not for the formatters, so while fixing the check, move it from term_tag.c to main.c.
Diffstat (limited to 'term_tag.c')
-rw-r--r--term_tag.c54
1 files changed, 25 insertions, 29 deletions
diff --git a/term_tag.c b/term_tag.c
index cb9fa16d..f6203a6c 100644
--- a/term_tag.c
+++ b/term_tag.c
@@ -1,4 +1,4 @@
-/* $Id: term_tag.c,v 1.1 2020/03/13 15:32:29 schwarze Exp $ */
+/* $Id: term_tag.c,v 1.2 2020/04/02 22:12:55 schwarze Exp $ */
/*
* Copyright (c) 2015,2016,2018,2019,2020 Ingo Schwarze <schwarze@openbsd.org>
*
@@ -45,7 +45,7 @@ static struct tag_files tag_files;
* but for simplicity, create it anyway.
*/
struct tag_files *
-term_tag_init(char *tagname)
+term_tag_init(void)
{
struct sigaction sa;
int ofd; /* In /tmp/, dup(2)ed to stdout. */
@@ -54,7 +54,6 @@ term_tag_init(char *tagname)
ofd = tfd = -1;
tag_files.tfs = NULL;
tag_files.tcpgid = -1;
- tag_files.tagname = tagname;
/* Clean up when dying from a signal. */
@@ -119,7 +118,6 @@ fail:
close(tag_files.ofd);
tag_files.ofd = -1;
}
- tag_files.tagname = NULL;
return NULL;
}
@@ -141,27 +139,29 @@ term_tag_write(struct roff_node *n, size_t line)
len, cp, tag_files.ofn, line);
}
-void
-term_tag_finish(void)
+/*
+ * Close both output files and restore the original standard output
+ * to the terminal. In the unlikely case that the latter fails,
+ * trying to start a pager would be useless, so report the failure
+ * to the main program.
+ */
+int
+term_tag_close(void)
{
- if (tag_files.tfs == NULL)
- return;
- fclose(tag_files.tfs);
- tag_files.tfs = NULL;
- switch (tag_check(tag_files.tagname)) {
- case TAG_EMPTY:
- unlink(tag_files.tfn);
- *tag_files.tfn = '\0';
- /* FALLTHROUGH */
- case TAG_MISS:
- if (tag_files.tagname == NULL)
- break;
- mandoc_msg(MANDOCERR_TAG, 0, 0, "%s", tag_files.tagname);
- tag_files.tagname = NULL;
- break;
- case TAG_OK:
- break;
+ int irc = 0;
+
+ if (tag_files.tfs != NULL) {
+ fclose(tag_files.tfs);
+ tag_files.tfs = NULL;
+ }
+ if (tag_files.ofd != -1) {
+ fflush(stdout);
+ if ((irc = dup2(tag_files.ofd, STDOUT_FILENO)) == -1)
+ mandoc_msg(MANDOCERR_DUP, 0, 0, "%s", strerror(errno));
+ close(tag_files.ofd);
+ tag_files.ofd = -1;
}
+ return irc;
}
void
@@ -170,11 +170,11 @@ term_tag_unlink(void)
pid_t tc_pgid;
if (tag_files.tcpgid != -1) {
- tc_pgid = tcgetpgrp(tag_files.ofd);
+ tc_pgid = tcgetpgrp(STDOUT_FILENO);
if (tc_pgid == tag_files.pager_pid ||
tc_pgid == getpgid(0) ||
getpgid(tc_pgid) == -1)
- (void)tcsetpgrp(tag_files.ofd, tag_files.tcpgid);
+ (void)tcsetpgrp(STDOUT_FILENO, tag_files.tcpgid);
}
if (*tag_files.ofn != '\0') {
unlink(tag_files.ofn);
@@ -184,10 +184,6 @@ term_tag_unlink(void)
unlink(tag_files.tfn);
*tag_files.tfn = '\0';
}
- if (tag_files.tfs != NULL) {
- fclose(tag_files.tfs);
- tag_files.tfs = NULL;
- }
}
static void