summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Pinto <danielpinto52@gmail.com>2021-03-25 01:23:04 +0000
committerDaniel Pinto <danielpinto52@gmail.com>2021-03-26 01:56:07 +0000
commit36768b5756f05774258ca9c5db6379f74dfd6586 (patch)
tree585e647de12258daf6b4b902bbeb620588d69bcf
parentc359c3056b2dbf17987a8955af30884ee438108e (diff)
downloadtor-36768b5756f05774258ca9c5db6379f74dfd6586.tar.gz
tor-36768b5756f05774258ca9c5db6379f74dfd6586.zip
Fix glob processing on BSD systems. #40318
On Linux systems, glob automatically ignores the errors ENOENT and ENOTDIR because they are expected during glob expansion. But BSD systems do not ignore these, resulting in glob failing when globs expand to invalid paths. This is fixed by adding a custom error handler that ignores only these two errors and removing the GLOB_ERR flag as it makes glob fail even if the error handler ignores the error and is unnecessary as the error handler will make glob fail on all other errors anyway.
-rw-r--r--changes/bug403184
-rw-r--r--src/lib/fs/path.c20
2 files changed, 22 insertions, 2 deletions
diff --git a/changes/bug40318 b/changes/bug40318
new file mode 100644
index 0000000000..cc02f08ca0
--- /dev/null
+++ b/changes/bug40318
@@ -0,0 +1,4 @@
+ o Minor bugfixes (configuration tests bsd):
+ - Fix glob processing errors when globs expand to invalid paths on
+ BSD systems. Fixes bug 40318; bugfix on 0.4.5.1-alpha. Patch by
+ Daniel Pinto.
diff --git a/src/lib/fs/path.c b/src/lib/fs/path.c
index c2fdddb9db..81960bd69a 100644
--- a/src/lib/fs/path.c
+++ b/src/lib/fs/path.c
@@ -571,6 +571,19 @@ wrap_closedir(void *arg)
{
closedir(arg);
}
+
+/** Function passed to glob to handle processing errors. <b>epath</b> is the
+ * path that caused the error and <b>eerrno</b> is the errno set by the
+ * function that failed. We want to ignore ENOENT and ENOTDIR because, in BSD
+ * systems, these are not ignored automatically, which makes glob fail when
+ * globs expand to non-existing paths and GLOB_ERR is set.
+ */
+static int
+glob_errfunc(const char *epath, int eerrno)
+{
+ (void)epath;
+ return eerrno == ENOENT || eerrno == ENOTDIR ? 0 : -1;
+}
#endif /* defined(HAVE_GLOB) */
/** Return a new list containing the paths that match the pattern
@@ -591,7 +604,7 @@ tor_glob(const char *pattern)
tor_free(pattern_normalized);
#elif HAVE_GLOB /* !(defined(_WIN32)) */
glob_t matches;
- int flags = GLOB_ERR | GLOB_NOSORT;
+ int flags = GLOB_NOSORT;
#ifdef GLOB_ALTDIRFUNC
/* use functions that call sandbox_intern_string */
flags |= GLOB_ALTDIRFUNC;
@@ -604,7 +617,10 @@ tor_glob(const char *pattern)
matches.gl_stat = &prot_stat;
matches.gl_lstat = &prot_lstat;
#endif /* defined(GLOB_ALTDIRFUNC) */
- int ret = glob(pattern, flags, NULL, &matches);
+ // use custom error handler to workaround BSD quirks and do not set GLOB_ERR
+ // because it would make glob fail on error even if the error handler ignores
+ // the error
+ int ret = glob(pattern, flags, glob_errfunc, &matches);
if (ret == GLOB_NOMATCH) {
return smartlist_new();
} else if (ret != 0) {