Module Name:    src
Committed By:   gutteridge
Date:           Thu May 19 04:08:03 UTC 2022

Modified Files:
        src/usr.sbin/makemandb: apropos-utils.c apropos.c

Log Message:
apropos(1): improve error handling in edge cases

Patch from RVP on NetBSD-Users, with an additional comment tweak by me.
Summary from RVP:

1. Ignore SIGPIPE so that we're not killed in the middle of some
   DB operation by a botched $PAGER:

$ env PAGER=/non-existent apropos -p ...

2. Return proper exit status in case of write errors:

$ apropos ... >/dev/full || echo fail


To generate a diff of this commit:
cvs rdiff -u -r1.48 -r1.49 src/usr.sbin/makemandb/apropos-utils.c
cvs rdiff -u -r1.25 -r1.26 src/usr.sbin/makemandb/apropos.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/usr.sbin/makemandb/apropos-utils.c
diff -u src/usr.sbin/makemandb/apropos-utils.c:1.48 src/usr.sbin/makemandb/apropos-utils.c:1.49
--- src/usr.sbin/makemandb/apropos-utils.c:1.48	Sat Nov 27 22:30:25 2021
+++ src/usr.sbin/makemandb/apropos-utils.c	Thu May 19 04:08:03 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: apropos-utils.c,v 1.48 2021/11/27 22:30:25 rillig Exp $	*/
+/*	$NetBSD: apropos-utils.c,v 1.49 2022/05/19 04:08:03 gutteridge Exp $	*/
 /*-
  * Copyright (c) 2011 Abhinav Upadhyay <er.abhinav.upadh...@gmail.com>
  * All rights reserved.
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: apropos-utils.c,v 1.48 2021/11/27 22:30:25 rillig Exp $");
+__RCSID("$NetBSD: apropos-utils.c,v 1.49 2022/05/19 04:08:03 gutteridge Exp $");
 
 #include <sys/queue.h>
 #include <sys/stat.h>
@@ -665,7 +665,7 @@ get_stmt_col_text(sqlite3_stmt *stmt, in
  * Execute the full text search query and return the number of results
  * obtained.
  */
-static unsigned int
+static int
 execute_search_query(sqlite3 *db, char *query, query_args *args)
 {
 	sqlite3_stmt *stmt;
@@ -699,8 +699,8 @@ execute_search_query(sqlite3 *db, char *
 		return -1;
 	}
 
-	unsigned int nresults = 0;
-	while (sqlite3_step(stmt) == SQLITE_ROW) {
+	int nresults = rc = 0;
+	while (rc == 0 && sqlite3_step(stmt) == SQLITE_ROW) {
 		nresults++;
 		callback_args.section = get_stmt_col_text(stmt, 0);
 		name_temp = get_stmt_col_text(stmt, 1);
@@ -725,11 +725,11 @@ execute_search_query(sqlite3 *db, char *
 		}
 		callback_args.name = name;
 		callback_args.other_data = args->callback_data;
-		(args->callback)(&callback_args);
+		rc = (args->callback)(&callback_args);
 		free(name);
 	}
 	sqlite3_finalize(stmt);
-	return nresults;
+	return (rc < 0) ? rc : nresults;
 }
 
 
@@ -752,9 +752,9 @@ run_query_internal(sqlite3 *db, const ch
 		return -1;
 	}
 
-	execute_search_query(db, query, args);
+	int rc = execute_search_query(db, query, args);
 	sqlite3_free(query);
-	return *(args->errmsg) == NULL ? 0 : -1;
+	return (rc < 0 || *(args->errmsg) != NULL) ? -1 : 0;
 }
 
 static char *
@@ -845,10 +845,10 @@ callback_html(query_callback_args *callb
 	callback_args->snippet = qsnippet;
 	callback_args->snippet_length = length;
 	callback_args->other_data = orig_data->data;
-	(*callback)(callback_args);
+	int rc = (*callback)(callback_args);
 	free(qsnippet);
 	free(qname_description);
-	return 0;
+	return rc;
 }
 
 /*
@@ -968,12 +968,12 @@ callback_pager(query_callback_args *call
 	callback_args->snippet = psnippet;
 	callback_args->snippet_length = psnippet_length;
 	callback_args->other_data = orig_data->data;
-	(orig_data->callback)(callback_args);
+	int rc = (orig_data->callback)(callback_args);
 	free(ul_section);
 	free(ul_name);
 	free(ul_name_desc);
 	free(psnippet);
-	return 0;
+	return rc;
 }
 
 struct term_args {
@@ -1013,11 +1013,11 @@ callback_term(query_callback_args *callb
 	callback_args->name = ul_name;
 	callback_args->name_desc = ul_name_desc;
 	callback_args->other_data = orig_data->data;
-	(orig_data->callback)(callback_args);
+	int rc = (orig_data->callback)(callback_args);
 	free(ul_section);
 	free(ul_name);
 	free(ul_name_desc);
-	return 0;
+	return rc;
 }
 
 /*

Index: src/usr.sbin/makemandb/apropos.c
diff -u src/usr.sbin/makemandb/apropos.c:1.25 src/usr.sbin/makemandb/apropos.c:1.26
--- src/usr.sbin/makemandb/apropos.c:1.25	Tue May 17 00:21:22 2022
+++ src/usr.sbin/makemandb/apropos.c	Thu May 19 04:08:03 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: apropos.c,v 1.25 2022/05/17 00:21:22 gutteridge Exp $	*/
+/*	$NetBSD: apropos.c,v 1.26 2022/05/19 04:08:03 gutteridge Exp $	*/
 /*-
  * Copyright (c) 2011 Abhinav Upadhyay <er.abhinav.upadh...@gmail.com>
  * All rights reserved.
@@ -31,9 +31,10 @@
  */
 
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: apropos.c,v 1.25 2022/05/17 00:21:22 gutteridge Exp $");
+__RCSID("$NetBSD: apropos.c,v 1.26 2022/05/19 04:08:03 gutteridge Exp $");
 
 #include <err.h>
+#include <signal.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -223,6 +224,10 @@ main(int argc, char *argv[])
 		const char *pager = getenv("PAGER");
 		if (pager == NULL)
 			pager = _PATH_PAGER;
+
+		/* Don't get killed by a broken pipe */
+		signal(SIGPIPE, SIG_IGN);
+
 		/* Open a pipe to the pager */
 		if ((cbdata.out = popen(pager, "w")) == NULL) {
 			close_db(db);
@@ -270,10 +275,12 @@ main(int argc, char *argv[])
 	if (pc == -1)
 		err(EXIT_FAILURE, "pclose error");
 
-	if (rc < 0) {
-		/* Something wrong with the database. Exit */
+	/* 
+	 * Something wrong with the database, writing output, or a non-existent
+	 * pager.
+	 */
+	if (rc < 0)
 		exit(EXIT_FAILURE);
-	}
 
 	if (cbdata.count == 0) {
 		warnx("No relevant results obtained.\n"
@@ -286,7 +293,7 @@ main(int argc, char *argv[])
 /*
  * query_callback --
  *  Callback function for run_query.
- *  It simply outputs the results from do_query. If the user specified the -p
+ *  It simply outputs the results from run_query. If the user specified the -p
  *  option, then the output is sent to a pager, otherwise stdout is the default
  *  output stream.
  */
@@ -308,7 +315,7 @@ query_callback(query_callback_args *qarg
 		    fprintf(out, "<tr><td colspan=2>%s</td></tr>\n", qargs->snippet);
 	}
 
-	return 0;
+	return fflush(out);
 }
 
 #include "stopwords.c"

Reply via email to