summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorColin Watson <cjwatson@debian.org>2019-01-29 11:50:05 +0000
committerColin Watson <cjwatson@debian.org>2019-01-29 11:50:05 +0000
commit7b19a3463542ec989df9eb10af455b28476f0b6f (patch)
tree0237d1cdbbd5d9870e0fe174345a0b5a1e2eb272 /lib
parentb74c839eaa5000a18d1c396e995eca85b0e9464b (diff)
Port order_files and look_for_file to gl_list
This gets rid of some particularly awful allocation spaghetti in src/globbing.c. * bootstrap.conf (gnulib_modules): Add rbtree-list. * lib/orderfiles.c (compare_physical_offsets): Expect arguments to be const char * rather than const char **. (order_files): Convert to taking a gl_list_t as an input/output argument rather than an array. In the HAVE_LINUX_FIEMAP_H case, we produce a new sorted list. * lib/orderfiles.h (order_files): Update prototype. * src/globbing.c (clear_glob): Remove. (match_in_directory): Convert to gl_list. Remove inter-call allocation and cleanup machinery. (look_for_file): Convert to gl_list. Remove glob_t cleanup machinery; the caller is now responsible for freeing the returned list. * src/globbing.h (look_for_file): Update prototype. * src/check_mandirs.c (add_dir_entries, count_glob_matches, purge_normal): Convert to gl_list. * src/straycats.c (check_for_stray): Likewise. * src/check_mandirs.c (purge_whatis, purge_missing): Convert to gl_list. Free list returned by look_for_file. * src/globbing_test.c (main): Likewise. * src/man.c (try_section, do_global_apropos_section): Likewise. * src/zsoelim.l (zsoelim_open_file): Likewise.
Diffstat (limited to 'lib')
-rw-r--r--lib/orderfiles.c45
-rw-r--r--lib/orderfiles.h4
2 files changed, 31 insertions, 18 deletions
diff --git a/lib/orderfiles.c b/lib/orderfiles.c
index d67f4d8f..a7c84ac5 100644
--- a/lib/orderfiles.c
+++ b/lib/orderfiles.c
@@ -44,8 +44,12 @@
#include <string.h>
#include <unistd.h>
+#include "gl_rbtree_list.h"
+#include "gl_xlist.h"
+
#include "manconfig.h"
+#include "glcontainers.h"
#include "hashtable.h"
struct hashtable *physical_offsets = NULL;
@@ -53,8 +57,8 @@ struct hashtable *physical_offsets = NULL;
#if defined(HAVE_LINUX_FIEMAP_H)
int compare_physical_offsets (const void *a, const void *b)
{
- const char *left = *(const char **) a;
- const char *right = *(const char **) b;
+ const char *left = (const char *) a;
+ const char *right = (const char *) b;
uint64_t *left_offset_p = hashtable_lookup (physical_offsets,
left, strlen (left));
uint64_t *right_offset_p = hashtable_lookup (physical_offsets,
@@ -70,12 +74,13 @@ int compare_physical_offsets (const void *a, const void *b)
return 0;
}
-void order_files (const char *dir, char **basenames, size_t n_basenames)
+void order_files (const char *dir, gl_list_t *basenamesp)
{
+ gl_list_t basenames = *basenamesp, sorted_basenames;
int dir_fd_open_flags;
int dir_fd;
struct statfs fs;
- size_t i;
+ const char *name;
dir_fd_open_flags = O_SEARCH | O_DIRECTORY;
#ifdef O_PATH
@@ -97,14 +102,17 @@ void order_files (const char *dir, char **basenames, size_t n_basenames)
* assumption for manual pages.
*/
physical_offsets = hashtable_create (&free);
- for (i = 0; i < n_basenames; ++i) {
+ sorted_basenames = gl_list_create_empty (GL_RBTREE_LIST,
+ string_equals, string_hash,
+ plain_free, false);
+ GL_LIST_FOREACH_START (basenames, name) {
struct {
struct fiemap fiemap;
struct fiemap_extent extent;
} fm;
int fd;
- fd = openat (dir_fd, basenames[i], O_RDONLY);
+ fd = openat (dir_fd, name, O_RDONLY);
if (fd < 0)
continue;
@@ -117,24 +125,27 @@ void order_files (const char *dir, char **basenames, size_t n_basenames)
if (ioctl (fd, FS_IOC_FIEMAP, (unsigned long) &fm) == 0) {
uint64_t *offset = XMALLOC (uint64_t);
*offset = fm.fiemap.fm_extents[0].fe_physical;
- hashtable_install (physical_offsets, basenames[i],
- strlen (basenames[i]), offset);
+ hashtable_install (physical_offsets, name,
+ strlen (name), offset);
}
close (fd);
- }
- qsort (basenames, n_basenames, sizeof *basenames,
- compare_physical_offsets);
+ gl_sortedlist_add (sorted_basenames, compare_physical_offsets,
+ xstrdup (name));
+ } GL_LIST_FOREACH_END (basenames);
hashtable_free (physical_offsets);
physical_offsets = NULL;
close (dir_fd);
+ gl_list_free (basenames);
+ *basenamesp = sorted_basenames;
}
#elif defined(HAVE_POSIX_FADVISE)
-void order_files (const char *dir, char **basenames, size_t n_basenames)
+void order_files (const char *dir, gl_list_t *basenamesp)
{
+ gl_list_t basenames = *basenamesp;
int dir_fd_open_flags;
int dir_fd;
- size_t i;
+ const char *name;
dir_fd_open_flags = O_SEARCH | O_DIRECTORY;
#ifdef O_PATH
@@ -147,18 +158,18 @@ void order_files (const char *dir, char **basenames, size_t n_basenames)
/* While we can't actually order the files, we can at least ask the
* kernel to preload them.
*/
- for (i = 0; i < n_basenames; ++i) {
- int fd = openat (dir_fd, basenames[i], O_RDONLY | O_NONBLOCK);
+ GL_LIST_FOREACH_START (basenames, name) {
+ int fd = openat (dir_fd, name, O_RDONLY | O_NONBLOCK);
if (fd >= 0) {
posix_fadvise (fd, 0, 0, POSIX_FADV_WILLNEED);
close (fd);
}
- }
+ } GL_LIST_FOREACH_END (basenames);
close (dir_fd);
}
#else
-void order_files (const char *dir, char **basenames, size_t n_basenames)
+void order_files (const char *dir, gl_list_t *basenamesp)
{
}
#endif
diff --git a/lib/orderfiles.h b/lib/orderfiles.h
index b4e66897..dae41cca 100644
--- a/lib/orderfiles.h
+++ b/lib/orderfiles.h
@@ -20,4 +20,6 @@
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-void order_files (const char *dir, char **basenames, size_t n_basenames);
+#include "gl_list.h"
+
+void order_files (const char *dir, gl_list_t *basenamesp);