aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorIngo Schwarze <schwarze@openbsd.org>2015-04-01 12:48:33 +0000
committerIngo Schwarze <schwarze@openbsd.org>2015-04-01 12:48:33 +0000
commit0fa412f32faf6969057d9e796beabcbf0413f279 (patch)
treeb4df0433aeaa3b8ae7c5639579c6e91b3fc55882
parent8ed0e0c9bf0dda6d753339d28f81747e661233a1 (diff)
downloadmandoc-0fa412f32faf6969057d9e796beabcbf0413f279.tar.gz
mandoc-0fa412f32faf6969057d9e796beabcbf0413f279.tar.zst
mandoc-0fa412f32faf6969057d9e796beabcbf0413f279.zip
Let man(1) and apropos(1) work even when the current directory
is unusable: Only change back to the current directory when the directory was changed before and the next path is relative. This is now more similar to what makewhatis(8) does. Issue reported by espie@.
-rw-r--r--mansearch.c70
1 files changed, 34 insertions, 36 deletions
diff --git a/mansearch.c b/mansearch.c
index af103963..417bd11d 100644
--- a/mansearch.c
+++ b/mansearch.c
@@ -1,4 +1,4 @@
-/* $Id: mansearch.c,v 1.56 2015/03/27 17:37:25 schwarze Exp $ */
+/* $Id: mansearch.c,v 1.57 2015/04/01 12:48:33 schwarze Exp $ */
/*
* Copyright (c) 2012 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2013, 2014, 2015 Ingo Schwarze <schwarze@openbsd.org>
@@ -163,7 +163,6 @@ mansearch(const struct mansearch *search,
int argc, char *argv[],
struct manpage **res, size_t *sz)
{
- int fd, rc, c, indexbit;
int64_t pageid;
uint64_t outbit, iterbit;
char buf[PATH_MAX];
@@ -177,23 +176,20 @@ mansearch(const struct mansearch *search,
struct ohash htab;
unsigned int idx;
size_t i, j, cur, maxres;
+ int c, chdir_status, getcwd_status, indexbit;
+
+ if (argc == 0 || (e = exprcomp(search, argc, argv)) == NULL) {
+ *sz = 0;
+ return(0);
+ }
info.calloc = hash_calloc;
info.alloc = hash_alloc;
info.free = hash_free;
info.key_offset = offsetof(struct match, pageid);
- *sz = cur = maxres = 0;
- sql = NULL;
+ cur = maxres = 0;
*res = NULL;
- fd = -1;
- e = NULL;
- rc = 0;
-
- if (0 == argc)
- goto out;
- if (NULL == (e = exprcomp(search, argc, argv)))
- goto out;
if (NULL != search->outkey) {
outbit = TYPE_Nd;
@@ -210,19 +206,18 @@ mansearch(const struct mansearch *search,
outbit = 0;
/*
- * Save a descriptor to the current working directory.
- * Since pathnames in the "paths" variable might be relative,
- * and we'll be chdir()ing into them, we need to keep a handle
- * on our current directory from which to start the chdir().
+ * Remember the original working directory, if possible.
+ * This will be needed if the second or a later directory
+ * is given as a relative path.
+ * Do not error out if the current directory is not
+ * searchable: Maybe it won't be needed after all.
*/
- if (NULL == getcwd(buf, PATH_MAX)) {
- perror("getcwd");
- goto out;
- } else if (-1 == (fd = open(buf, O_RDONLY, 0))) {
- perror(buf);
- goto out;
- }
+ if (getcwd(buf, PATH_MAX) == NULL) {
+ getcwd_status = 0;
+ (void)strlcpy(buf, strerror(errno), sizeof(buf));
+ } else
+ getcwd_status = 1;
sql = sql_statement(e);
@@ -234,15 +229,23 @@ mansearch(const struct mansearch *search,
* scan it for our match expression.
*/
+ chdir_status = 0;
for (i = 0; i < paths->sz; i++) {
- if (-1 == fchdir(fd)) {
- perror(buf);
- free(*res);
- break;
- } else if (-1 == chdir(paths->paths[i])) {
+ if (chdir_status && paths->paths[i][0] != '/') {
+ if ( ! getcwd_status) {
+ fprintf(stderr, "%s: getcwd: %s\n",
+ paths->paths[i], buf);
+ continue;
+ } else if (chdir(buf) == -1) {
+ perror(buf);
+ continue;
+ }
+ }
+ if (chdir(paths->paths[i]) == -1) {
perror(paths->paths[i]);
continue;
}
+ chdir_status = 1;
c = sqlite3_open_v2(MANDOC_DB, &db,
SQLITE_OPEN_READONLY, NULL);
@@ -370,17 +373,12 @@ mansearch(const struct mansearch *search,
break;
}
qsort(*res, cur, sizeof(struct manpage), manpage_compare);
- rc = 1;
-out:
- if (-1 != fd) {
- if (-1 == fchdir(fd))
- perror(buf);
- close(fd);
- }
+ if (chdir_status && getcwd_status && chdir(buf) == -1)
+ perror(buf);
exprfree(e);
free(sql);
*sz = cur;
- return(rc);
+ return(1);
}
void