Em Wed, Jun 08, 2016 at 06:30:30PM +0900, Masami Hiramatsu escreveu:
> +char *build_id_cache__origname(const char *sbuild_id)
> +{
> +     char *linkname;
> +     char buf[PATH_MAX];
> +     char *ret = NULL, *p;
> +     size_t offs = 5;        /* == strlen("../..") */
> +
> +     linkname = build_id_cache__linkname(sbuild_id, NULL, 0);
> +     if (!linkname)
> +             return NULL;
> +
> +     if (readlink(linkname, buf, PATH_MAX) < 0)
> +             goto out;
> +     /* The link should be "../..<origpath>/<sbuild_id>" */
> +     p = strrchr(buf, '/');  /* Cut off the "/<sbuild_id>" */
> +     if (p && (p > buf + offs)) {
> +             *p = '\0';
> +             if (buf[offs + 1] == '[')
> +                     offs++; /*
> +                              * This is a DSO name, like [kernel.kallsyms].
> +                              * Skip the first '/', since this is not the
> +                              * cache of a regular file.
> +                              */
> +             ret = strdup(buf + offs);       /* Skip "../..[/]" */

strdup can fail.

> +     }
> +out:
> +     free(linkname);
> +     return ret;
> +}
> +
>  static const char *build_id_cache__basename(bool is_kallsyms, bool is_vdso)
>  {
>       return is_kallsyms ? "kallsyms" : (is_vdso ? "vdso" : "elf");
> @@ -390,6 +419,59 @@ void disable_buildid_cache(void)
>       no_buildid_cache = true;
>  }
>  
> +int build_id_cache__list_all(struct strlist **result)
> +{
> +     struct strlist *toplist, *list, *bidlist;
> +     struct str_node *nd, *nd2;
> +     char *topdir, *linkdir;
> +     char sbuild_id[SBUILD_ID_SIZE];
> +     int ret = 0;
> +
> +     /* Open the top-level directory */
> +     if (asprintf(&topdir, "%s/.build-id/", buildid_dir) < 0)
> +             return -errno;

Wouldn't be better to just return -1 and leave the caller to look at
errno? I know that there is code that does that, but better stick to the
errno convention?

> +     toplist = lsdir(topdir, lsdir_no_dot_filter);
> +     if (!toplist) {
> +             pr_debug("Failed to opendir %s\n", topdir);
> +             ret = -errno;

ditto

> +             goto out;
> +     }
> +     bidlist = strlist__new(NULL, NULL);
> +     strlist__for_each(nd, toplist) {
> +             if (asprintf(&linkdir, "%s/%s", topdir, nd->s) < 0) {
> +                     ret = -errno;
> +                     goto out;
> +             }
> +             /* Open the lower-level directory */
> +             list = lsdir(linkdir, lsdir_no_dot_filter);
> +             if (!list) {
> +                     pr_debug("Failed to open %s: %d\n", linkdir, -errno);
> +                     goto next;
> +             }
> +             strlist__for_each(nd2, list) {
> +                     ret = snprintf(sbuild_id, SBUILD_ID_SIZE, "%s%s",
> +                                     nd->s, nd2->s);
> +                     if (ret != SBUILD_ID_SIZE - 1) {
> +                             pr_debug("%s/%s is not buildid cache\n",
> +                                     nd->s, nd2->s);
> +                             continue;
> +                     }
> +                     strlist__add(bidlist, sbuild_id);

strlist__add() can fail, please check its result.

> +             }
> +             strlist__delete(list);
> +next:
> +             free(linkdir);
> +     }
> +
> +     *result = bidlist;
> +out:
> +     if (toplist)
> +             strlist__delete(toplist);

No need for checking toplist.

> +     free(topdir);
> +
> +     return ret;
> +}

<SNIP>

- Arnaldo

Reply via email to