diff options
author | Colin Watson <cjwatson@debian.org> | 2019-01-29 11:50:05 +0000 |
---|---|---|
committer | Colin Watson <cjwatson@debian.org> | 2019-01-29 11:50:05 +0000 |
commit | 7b19a3463542ec989df9eb10af455b28476f0b6f (patch) | |
tree | 0237d1cdbbd5d9870e0fe174345a0b5a1e2eb272 /lib | |
parent | b74c839eaa5000a18d1c396e995eca85b0e9464b (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.c | 45 | ||||
-rw-r--r-- | lib/orderfiles.h | 4 |
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); |