commit:     248e2d0ba29dad806840b151ae80d4c0fe728724
Author:     Mike Frysinger <vapier <AT> gentoo <DOT> org>
AuthorDate: Sat Jun  6 05:33:49 2015 +0000
Commit:     Mike Frysinger <vapier <AT> gentoo <DOT> org>
CommitDate: Sat Jun  6 05:33:49 2015 +0000
URL:        https://gitweb.gentoo.org/proj/portage-utils.git/commit/?id=248e2d0b

qsearch: update cache handling

The cache rewrite dropped the implicit chdir (by design), but the qsearch
code was still relying on that.  Update qsearch to use *at style functions
and also convert the fgets usage to getline.

URL: https://bugs.gentoo.org/551206
Reported-by: Guilherme Amadio <amadio <AT> gentoo.org>

 qsearch.c | 61 +++++++++++++++++++++++++++++++++++++++----------------------
 1 file changed, 39 insertions(+), 22 deletions(-)

diff --git a/qsearch.c b/qsearch.c
index ce36df2..05a54e6 100644
--- a/qsearch.c
+++ b/qsearch.c
@@ -34,15 +34,14 @@ static const char * const qsearch_opts_help[] = {
 int qsearch_main(int argc, char **argv)
 {
        FILE *fp;
-       char buf[_Q_PATH_MAX];
-       char ebuild[_Q_PATH_MAX];
+       char *ebuild = NULL;
        char last[126] = "";
        char *p, *q, *str;
        char *search_me = NULL;
        char show_homepage = 0, show_name_only = 0;
        char search_desc = 0, search_all = 0, search_name = 1, search_cache = 
CACHE_EBUILD;
        const char *search_vars[] = { "DESCRIPTION=", "HOMEPAGE=" };
-       size_t search_len;
+       size_t search_len, ebuild_len;
        int i, idx=0;
 
        DBG("argc=%d argv[0]=%s argv[1]=%s",
@@ -92,9 +91,14 @@ int qsearch_main(int argc, char **argv)
        if (!fp)
                return 1;
 
+       int portdir_fd = open(portdir, O_RDONLY|O_CLOEXEC|O_PATH);
+       if (portdir_fd < 0)
+               errp("open(%s) failed", portdir);
+
+       q = NULL; /* Silence a gcc warning. */
        search_len = strlen(search_vars[idx]);
 
-       while (fgets(ebuild, sizeof(ebuild), fp) != NULL) {
+       while (getline(&ebuild, &ebuild_len, fp) != -1) {
                if ((p = strchr(ebuild, '\n')) != NULL)
                        *p = 0;
                if (!ebuild[0])
@@ -139,35 +143,46 @@ int qsearch_main(int argc, char **argv)
                                        }
                                }
 
-                               if ((ebuildfp = fopen(ebuild, "r")) != NULL) {
-                                       while (fgets(buf, sizeof(buf), 
ebuildfp) != NULL) {
-                                               if (strlen(buf) <= search_len)
-                                                       continue;
-                                               if (strncmp(buf, 
search_vars[idx], search_len) == 0) {
-                                                       if ((q = strrchr(buf, 
'"')) != NULL)
-                                                               *q = 0;
-                                                       if (strlen(buf) <= 
search_len)
-                                                               break;
-                                                       q = buf + search_len + 
1;
-                                                       if (!search_all && 
!search_name && rematch(search_me, q, REG_EXTENDED | REG_ICASE) != 0)
-                                                               break;
-                                                       show_it = true;
-                                                       break;
-                                               }
+                               int fd = openat(portdir_fd, ebuild, 
O_RDONLY|O_CLOEXEC);
+                               if (fd != -1) {
+                                       ebuildfp = fdopen(fd, "r");
+                                       if (ebuildfp == NULL) {
+                                               close(fd);
+                                               continue;
                                        }
-                                       fclose(ebuildfp);
                                } else {
                                        if (!reinitialize)
                                                warnfp("(cache update pending) 
%s", ebuild);
                                        reinitialize = 1;
+                                       goto no_cache_ebuild_match;
+                               }
+
+                               char *buf = NULL;
+                               size_t buflen;
+                               while (getline(&buf, &buflen, ebuildfp) != -1) {
+                                       if (strlen(buf) <= search_len)
+                                               continue;
+                                       if (strncmp(buf, search_vars[idx], 
search_len) != 0)
+                                               continue;
+                                       if ((q = strrchr(buf, '"')) != NULL)
+                                               *q = 0;
+                                       if (strlen(buf) <= search_len)
+                                               break;
+                                       q = buf + search_len + 1;
+                                       if (!search_all && !search_name && 
rematch(search_me, q, REG_EXTENDED | REG_ICASE) != 0)
+                                               break;
+                                       show_it = true;
+                                       break;
                                }
 
                                if (show_it) {
-                                       const char *b = basename(p);
                                        printf("%s%s/%s%s%s %s\n",
-                                               BOLD, dirname(p), BLUE, b, NORM,
+                                               BOLD, dirname(p), BLUE, 
basename(p), NORM,
                                                (show_name_only ? "" : q ? : 
"<no DESCRIPTION found>"));
                                }
+
+                               free(buf);
+                               fclose(ebuildfp);
                        }
 no_cache_ebuild_match:
                        free(str);
@@ -176,6 +191,8 @@ no_cache_ebuild_match:
                } /* case CACHE_EBUILD */
                } /* switch (search_cache) */
        }
+       free(ebuild);
+       close(portdir_fd);
        fclose(fp);
        return EXIT_SUCCESS;
 }

Reply via email to