<div dir="ltr"><div dir="ltr"><br></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Fri, Aug 27, 2021 at 3:21 PM Rich Felker <<a href="mailto:dalias@libc.org">dalias@libc.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">On Fri, Aug 27, 2021 at 10:21:51AM -0500, Rob Landley wrote:<br>
> On 8/27/21 8:56 AM, Rich Felker wrote:<br>
> > On Thu, Aug 26, 2021 at 03:56:47PM -0700, enh wrote:<br>
> >> On Thu, Aug 26, 2021 at 2:34 PM Rob Landley <<a href="mailto:rob@landley.net" target="_blank">rob@landley.net</a>> wrote:<br>
> > <br>
> > Rob asked me for some input on this:<br>
> > <br>
> >> > In my private emails somebody is trying to make the last aboriginal linux<br>
> >> > release work and the old busybox isn't building anymore because makedev()<br>
> >> > used<br>
> >> > to be in #include <sys/types.h> and now it's moved to <sys/sysmacros.h>.<br>
> >> > (Why? I<br>
> >> > dunno. Third base.)<br>
> > <br>
> > This was glibc bug #19239, and clearly needed to be fixed. Generic<br>
> > lowercase macro names like "major" and "minor" are *extreme* namespace<br>
> > pollution for a standard header to be doing.<br>
> <br>
> I stared at that a bit before figuring out you were objecting because they're<br>
> MACROS. (Generic words being FUNCTION names from headers is common: stdio.h<br>
> defines remove(), rename(), rewind()... stdlib.h has random(), free(), abort(),<br>
> exit()...)<br>
<br>
Because those names are defined as being there by the C language and<br>
expected to be there by anyone writing programs in C. Indeed, it makes<br>
it far *worse* that major and minor were macros, since they break<br>
things in more contexts, but if they were functions it would still be<br>
inappropriate for sys/types.h to be exposing them.<br>
<br>
> > sys/sysmacros.h was<br>
> > always the correct way to get these macros on glibc, but for whatever<br>
> > reason (compatibility with some ancient historic unices?) glibc was<br>
> > making sys/types.h include sys/sysmacros.h implicitly, at least under<br>
> > some profiles.<br>
> <br>
> The problem is the man page said to #include <sys/types.h> to get it, so that's<br>
> what people did.<br>
<br>
That's unfortunate. There's been a lot of wrong stuff in man pages<br>
but Michael is very good about taking reports and getting it<br>
corrected.<br></blockquote><div><br></div><div>i think the problem is that it _said_ that, not that it says that now:</div><div><br></div><div>SYNOPSIS<br>       #include <sys/sysmacros.h><br></div><div><br></div><div><a href="https://man7.org/linux/man-pages/man3/major.3.html">https://man7.org/linux/man-pages/man3/major.3.html</a></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
> And even today the man page doesn't particularly call them out<br>
> as macros, it gives them function prototypes and even calls them functions:<br>
> <br>
>   The  major()  and  minor() functions perform the converse task: given a<br>
>   device ID, they return, respectively, the major and  minor  components.<br>
<br>
Yes. Historically they were always macros, but glibc made the macros<br>
wrap functions because they did something more elaborate with munging<br>
the bits to fit major and minor numbers larger than 8 bits, splitting<br>
the extra ones across the high 48 bits...<br></blockquote><div><br></div><div>he's said he's not against pointing out differences between glibc and other C libraries, but i haven't actually tried to send him any such changes yet (that i recall).</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
> I thought it was like getc() being officially undecided about whether or not<br>
> it's a macro. (Could be either way.)<br>
<br>
Generally it's assumed that the standard headers may (at least in C,<br>
and for standard functions) additionally define a macro anywhere a<br>
function is specified as long as it doesn't evaluate arguments the<br>
wrong number of times. Where the spec explicitly mentions a macro,<br>
that means there's no obligation to avoid multiple evaluation. However<br>
there are good reasons not to do this (breaking C++ callers, and when<br>
the name is not a standard function, just breaking programs that don't<br>
expect it to be there and which use the name for something else<br>
locally.<br>
<br>
> > What made this even worse was that, under BSD or GNU profile<br>
> > (including by default), glibc's stdlib.h included sys/types.h. This<br>
> > meant anything using stdlib.h got the namespace breakage.<br>
> <br>
> Is it "breakage" if it's the standard for Linux and has been for years?<br>
<br>
Yes.<br>
<br>
> I had a function called throw() in a turbo C++ program I wrote for DOS back in<br>
> college and a compiler upgrade turned that into a keyword and broke my stuff<br>
> because they'd decided to gratuitously add stuff to the language AFTER I wrote<br>
> my code. If it had been "compiling it on Linux behaves differently" I wouldn't<br>
> have minded so much, it was a version upgrade of the same THING breaking stuff<br>
> that bothered me.<br>
<br>
That's why we're careful to honor the implementation's obligations on<br>
namespace (fully in plain C or POSIX profile, and modulo well-known<br>
extension functions in default/BSD profile). Avoiding this kind of<br>
breakage requires both sides (implementation and application) to honor<br>
their obligations though. If either doesn't, upgrades can break stuff.<br>
<br>
> > In commit f552c792c7ce5a560f214e1104d93ee5b0833967 (2011) musl<br>
> > emulated this glibc behavior in _GNU_SOURCE profile, but commit<br>
> > a31a30a0076c284133c0f4dfa32b8b37883ac930 (2019) removed it since glibc<br>
> > had already fixed the problem and pushed applications still depending<br>
> > on the wrong behavior to fix their stuff.<br>
> <br>
> So sys/types.h couldn't have prototyped the functions (inside #ifndef if<br>
> necessary) and sys/macros.h couldn't have defined faster macro vesions then, and<br>
> you get whichever one you #include first?<br>
> <br>
> Eh, water over the bridge. Glibc decided to break userspace and musl fell in<br>
> line a few years later. I'm just not convinced glibc made a good call.<br>
<br>
No, we did something awful as a glibc compat hack back in 2011, only<br>
in _GNU_SOURCE mode because it was so awful, and removed it after it<br>
was no longer providing any glibc-compat. That type of hack would not<br>
be approved to begin with nowadays.<br>
<br>
Rich<br>
</blockquote></div></div>