Skip to content

Fix compilation on systems with old scandir prototype

The prototype of scandir has changed over time. In OS X 10.8 and later it is:

    int
    scandir(const char *dirname, struct dirent ***namelist,
        int (*select)(const struct dirent *),
        int (*compar)(const struct dirent **, const struct dirent **));

while in Mac OS X 10.7 and earlier it was:

    int
    scandir(const char *dirname, struct dirent ***namelist,
        int (*select)(struct dirent *),
        int (*compar)(const void *, const void *));

pdfgrep is written for the more modern scandir prototype, therefore it fails to build on Mac OS X 10.7 with an error message like this:

cache.cc:113:10: error: no matching function for call to 'scandir'
        int n = scandir(cache, &namelist, agefilter, agesort);
                ^~~~~~~
/usr/include/dirent.h:128:5: note: candidate function not viable: no known conversion from 'int (const struct dirent *)' to 'int (*)(struct dirent *)' for 3rd argument
int scandir(const char *, struct dirent ***,
    ^
1 error generated.

A solution I have seen in employed other software is to use different prototypes depending on known system versions. This PR implements that method for macOS.

This PR only fixes the problem for old macOS. It does not attempt to fix the problem for old other operating systems. In my brief research, it seems there are more than two different prototypes for scandir so a complete solution that fixes all operating systems would be more involved.

A different approach could be to write a configure test to determine which prototype to use. However that is not my area of expertise so I leave that to someone else.

Merge request reports