Hi, On Sat, Mar 21, 2020 at 9:40 PM Laurent Bercot <ska-skaw...@skarnet.org> wrote: > > >For s6 latest release 2.9.1.0, I fail to build it on GNU/Hurd. > > Hi Shengjing, > Thanks for the report! > > It's a bug indeed - and a pretty tricky one. In order to work around > POSIX violations by some systems, skalibs provides certain headers that > need to be included *before* system headers, and other headers that > need to be included *after* system headers. That goes against the > principle of header independence and orthogonality, but unfortunately > there's no other way to catch stuff like, for instance, EPROTO > definition missing. (Which, despite their efforts towards compliance > in the past few years, is still a thing in 2020 in the BSDs.) > > skalibs also tries to provide self-contained headers, i.e. which > include everything they need. In particular, skalibs/bytestr.h uses > strnlen in one of its macros, so it needs to make sure to include the > header that defines strnlen. (So the user can just > #include <skalibs/bytestr.h> and not worry about anything breaking when > they use something declared by bytestr.h.) > > The problem is that strnlen, despite being defined by POSIX, is *not* > declared by every system out there. Almost, but not quite - I don't > remember whether it's Solaris or MacOS or something that fails to > declare > it. So, skalibs declares strnlen in the skalibs/posixishard.h header, > which is the posix-violation-correction header that needs to be included > *after* system headers. And to be self-contained, bytestr.h included > posixishard.h. > > But as shown by your report, it was a mistake. Here several rules are > conflicting, and bytestr.h did not resolve the conflict properly: as > your report shows, bytestr.h can be included *before* all necessary > system headers, like errno.h, are included - so posixishard.h misses > the EPROTO definition and incorrectly triggers the workaround (which is > to define it as EPROTOTYPE), and a subsequent inclusion of errno.h > exposes the problem. > > The correct way to handle this is to explicitly *avoid* including > exceptional headers such as skalibs/nonposix.h and skalibs/posixishard.h > in other headers; they should only be used in .c files where header > inclusion is controlled. The fix is to remove the > #include <skalibs/posixishard.h> > line from bytestr.h in skalibs. And if someone uses the str_nlen macro, > it is their responsibility to also #include <skalibs/posixishard.h> in > their source file to get the strnlen definition even on non-compliant > systems. >
Thanks for this detail explanation! -- Shengjing Zhu