Build fails because portage-utils implicitly uses d_reclen, whereas it should use the _DIRENT_HAVE_D_NAMLEN / _DIRENT_HAVE_D_RECLEN defines accordingly. make[2]: Entering directory `/j/var/tmp/portage/app-portage/portage-utils-0.30/work/portage-utils-0.30' CC q-main.o In file included from libq/libq.c:37:0, from main.c:98: libq/scandirat.c: In function 'scandirat': libq/scandirat.c:42:30: error: 'struct dirent' has no member named 'd_reclen' In file included from libq/libq.c:38:0, from main.c:98: libq/prelink.c: In function 'is_prelink_elf': libq/prelink.c:106:33: warning: unused parameter 'fd' [-Wunused-parameter] libq/prelink.c:106:49: warning: unused parameter 'filename' [-Wunused-parameter] In file included from libq/libq.c:42:0, from main.c:98: libq/vdb.c: In function 'q_vdb_foreach_pkg_sorted': libq/vdb.c:302:2: warning: passing argument 5 of 'scandirat' from incompatible pointer type [enabled by default] libq/scandirat.c:18:12: note: expected 'int (*)(const struct dirent **, const struct dirent **)' but argument is of type 'int (*)(const void *, const void *)' libq/vdb.c:308:3: warning: passing argument 5 of 'scandirat' from incompatible pointer type [enabled by default] libq/scandirat.c:18:12: note: expected 'int (*)(const struct dirent **, const struct dirent **)' but argument is of type 'int (*)(const void *, const void *)' main.c: In function 'get_vdb_atoms': main.c:1269:2: warning: passing argument 5 of 'scandirat' from incompatible pointer type [enabled by default] libq/scandirat.c:18:12: note: expected 'int (*)(const struct dirent **, const struct dirent **)' but argument is of type 'int (*)(const void *, const void *)' main.c:1273:3: warning: passing argument 5 of 'scandirat' from incompatible pointer type [enabled by default] libq/scandirat.c:18:12: note: expected 'int (*)(const struct dirent **, const struct dirent **)' but argument is of type 'int (*)(const void *, const void *)' In file included from include_applets.h:16:0, from main.c:1339: qcache.c: In function 'qcache_traverse': qcache.c:555:4: warning: passing argument 4 of 'scandir' from incompatible pointer type [enabled by default] /usr/include/sys/dirent.h:122:12: note: expected 'int (*)(const void *, const void *)' but argument is of type 'int (*)(const struct dirent **, const struct dirent **)' make[2]: *** [q-main.o] Error 1 make[2]: Leaving directory `/j/var/tmp/portage/app-portage/portage-utils-0.30/work/portage-utils-0.30' make[1]: *** [all-recursive] Error 1 make[1]: Leaving directory `/j/var/tmp/portage/app-portage/portage-utils-0.30/work/portage-utils-0.30' make: *** [all] Error 2 emake failed
you can try this (no idea if it works): --- a/libq/scandirat.c +++ b/libq/scandirat.c @@ -15,6 +15,12 @@ #if !defined(HAVE_SCANDIRAT) +#if defined(_DIRENT_HAVE_D_RECLEN) +# define reclen(de) ((de)->d_reclen) +#else +# define reclen(de) (sizeof(*(de))) +#endif + static int scandirat(int dir_fd, const char *dir, struct dirent ***dirlist, int (*filter)(const struct dirent *), int (*compar)(const struct dirent **, const struct dirent **)) @@ -39,7 +45,7 @@ continue; ret = realloc(ret, sizeof(*ret) * (cnt + 1)); - ret[cnt++] = xmemdup(de, de->d_reclen); + ret[cnt++] = xmemdup(de, reclen(de)); } *dirlist = ret;
committed. you can see if the next release works for you. http://sources.gentoo.org/gentoo-projects/portage-utils/libq/scandirat.c?r1=1.4&r2=1.5
This didn't work, but I fixed it in r1.7: scandirat: copy enough bytes to get the filename Solaris is a platform without d_reclen. sizeof(struct dirent) is not enough to get the whole of d_name contents, since the struct uses char[1] as workaround to specify a variable size length end of struct member. Index: libq/scandirat.c =================================================================== RCS file: /var/cvsroot/gentoo-projects/portage-utils/libq/scandirat.c,v retrieving revision 1.6 retrieving revision 1.7 diff -u -r1.6 -r1.7 --- libq/scandirat.c 29 Sep 2013 10:25:25 -0000 1.6 +++ libq/scandirat.c 17 Nov 2013 10:26:53 -0000 1.7 @@ -18,7 +18,7 @@ #if defined(_DIRENT_HAVE_D_RECLEN) # define reclen(de) ((de)->d_reclen) #else -# define reclen(de) (sizeof(*(de))) +# define reclen(de) (sizeof(*(de)) + strlen((de)->d_name)) #endif static int scandirat(int dir_fd, const char *dir, struct dirent ***dirlist,
(In reply to Fabian Groffen from comment #3) should there be a +1 at the end there for the NUL byte ?
(In reply to SpanKY from comment #4) > (In reply to Fabian Groffen from comment #3) > > should there be a +1 at the end there for the NUL byte ? In my case this was not necessary, because the struct defines an array (minsize 1), thus that space is already catered for. However, the just adding one more byte to be on the safe side probably doesn't hurt.