RFC: deprecate sys/sysmacros.h inclusion from sys/types.h

Message ID 564D4C62.3090404@panix.com
State Superseded
Headers

Commit Message

Zack Weinberg Nov. 19, 2015, 4:13 a.m. UTC
  Andreas may still be running whole-distro rebuild tests, but enough
results came back that I feel fairly confident saying that option B
(remove the #include <sys/types.h> from stdlib.h) is a non-starter.
There are too many (sloppily coded, yes) programs that include stdlib.h
and expect it to expose all the POSIX foo_t types.  That leaves us with
option A (remove the #include <sys/sysmacros.h> from sys/types.h) and
even that is going to break stuff.  So we need a deprecation period.

The attached, lightly tested, patch sets up that deprecation period.
From an application's perspective, it works like this:

* If you include <sys/sysmacros.h> directly, you get major(), minor(),
and makedev() macros and everything works as it did before, regardless
of whether you also include <sys/types.h> and in what order.

* If you define _SYS_TYPES_NO_SYSMACROS before including any headers,
then <sys/types.h> does not include <sys/sysmacros.h> at all.

* If you include <sys/types.h>, you don't include <sys/sysmacros.h>, and
you don't define _SYS_TYPES_NO_SYSMACROS, then you still get major(),
minor(), and makedev() macros, but they trigger a deprecation warning if
you *use* them.  This warning contains a lengthy explanation of what is
about to change and suggests either including <sys/sysmacros.h> or
defining _SYS_TYPES_NO_SYSMACROS, depending on whether you actually
wanted the dev_t manipulators.

The implementation of all that is regrettably messy, but it works.  I
also took the opportunity to genericize some of the code involved;
sys/sysmacros.h and makedev.c both now live in misc/ instead of
sysdeps/, and there's a new 'bits' header that encapsulates the only
thing that varies between Linux and non-, which is the actual encoding
of a dev_t.  (I'd appreciate extra-careful review of the arithmetic in
the new bits headers; I'm not sure it was ever 100% correct, I may have
messed it up, and there don't seem to be any tests.)

I deliberately didn't say "in the next release" in the deprecation
message, because we might want to give this more than one cycle to bake.

zw
  

Comments

Zack Weinberg Dec. 7, 2015, 2:03 p.m. UTC | #1
On 11/18/2015 11:13 PM, Zack Weinberg wrote:
> Andreas may still be running whole-distro rebuild tests, but enough
> results came back that I feel fairly confident saying that option B
> (remove the #include <sys/types.h> from stdlib.h) is a non-starter.
> There are too many (sloppily coded, yes) programs that include stdlib.h
> and expect it to expose all the POSIX foo_t types.  That leaves us with
> option A (remove the #include <sys/sysmacros.h> from sys/types.h) and
> even that is going to break stuff.  So we need a deprecation period.
> 
> The attached, lightly tested, patch sets up that deprecation period.

Ping.  The patch at
<https://sourceware.org/ml/libc-alpha/2015-11/msg00452.html> is awaiting
review.

zw
  
Zack Weinberg Dec. 21, 2015, 8:31 p.m. UTC | #2
On Mon, Dec 7, 2015 at 9:03 AM, Zack Weinberg <zackw@panix.com> wrote:
> On 11/18/2015 11:13 PM, Zack Weinberg wrote:
>> Andreas may still be running whole-distro rebuild tests, but enough
>> results came back that I feel fairly confident saying that option B
>> (remove the #include <sys/types.h> from stdlib.h) is a non-starter.
>> There are too many (sloppily coded, yes) programs that include stdlib.h
>> and expect it to expose all the POSIX foo_t types.  That leaves us with
>> option A (remove the #include <sys/sysmacros.h> from sys/types.h) and
>> even that is going to break stuff.  So we need a deprecation period.
>>
>> The attached, lightly tested, patch sets up that deprecation period.
>
> Ping.  The patch at
> <https://sourceware.org/ml/libc-alpha/2015-11/msg00452.html> is awaiting
> review.

Ping.

zw
  
Mike Frysinger Dec. 29, 2015, 8:42 p.m. UTC | #3
On 18 Nov 2015 23:13, Zack Weinberg wrote:
> Andreas may still be running whole-distro rebuild tests, but enough
> results came back that I feel fairly confident saying that option B
> (remove the #include <sys/types.h> from stdlib.h) is a non-starter.
> There are too many (sloppily coded, yes) programs that include stdlib.h
> and expect it to expose all the POSIX foo_t types.  That leaves us with
> option A (remove the #include <sys/sysmacros.h> from sys/types.h) and
> even that is going to break stuff.  So we need a deprecation period.

i'm just going to drop it in Gentoo and let people fix the build failures
-mike
  
Zack Weinberg Dec. 29, 2015, 9:56 p.m. UTC | #4
On Tue, Dec 29, 2015 at 12:42 PM, Mike Frysinger <vapier@gentoo.org> wrote:
> On 18 Nov 2015 23:13, Zack Weinberg wrote:
>> Andreas may still be running whole-distro rebuild tests, but enough
>> results came back that I feel fairly confident saying that option B
>> (remove the #include <sys/types.h> from stdlib.h) is a non-starter.
>> There are too many (sloppily coded, yes) programs that include stdlib.h
>> and expect it to expose all the POSIX foo_t types.  That leaves us with
>> option A (remove the #include <sys/sysmacros.h> from sys/types.h) and
>> even that is going to break stuff.  So we need a deprecation period.
>
> i'm just going to drop it in Gentoo and let people fix the build failures

Well, if you're going to do that, option B might be better (or both!)
but I don't see it as a viable approach for upstream...

zw
  
Mike Frysinger Dec. 29, 2015, 10:45 p.m. UTC | #5
On 29 Dec 2015 13:56, Zack Weinberg wrote:
> On Tue, Dec 29, 2015 at 12:42 PM, Mike Frysinger wrote:
> > On 18 Nov 2015 23:13, Zack Weinberg wrote:
> >> Andreas may still be running whole-distro rebuild tests, but enough
> >> results came back that I feel fairly confident saying that option B
> >> (remove the #include <sys/types.h> from stdlib.h) is a non-starter.
> >> There are too many (sloppily coded, yes) programs that include stdlib.h
> >> and expect it to expose all the POSIX foo_t types.  That leaves us with
> >> option A (remove the #include <sys/sysmacros.h> from sys/types.h) and
> >> even that is going to break stuff.  So we need a deprecation period.
> >
> > i'm just going to drop it in Gentoo and let people fix the build failures
> 
> Well, if you're going to do that, option B might be better (or both!)
> but I don't see it as a viable approach for upstream...

one at a time :).  the impact of sysmacros.h is significantly lower than
the impact of sys/types.h.  although people have been building Gentoo
against other C libs, so we are prob better protected against that.
-mike
  
Zack Weinberg Jan. 11, 2016, 3:16 p.m. UTC | #6
On 12/21/2015 03:31 PM, Zack Weinberg wrote:
> On Mon, Dec 7, 2015 at 9:03 AM, Zack Weinberg <zackw@panix.com> wrote:
>> On 11/18/2015 11:13 PM, Zack Weinberg wrote:
>>> Andreas may still be running whole-distro rebuild tests, but enough
>>> results came back that I feel fairly confident saying that option B
>>> (remove the #include <sys/types.h> from stdlib.h) is a non-starter.
>>> There are too many (sloppily coded, yes) programs that include stdlib.h
>>> and expect it to expose all the POSIX foo_t types.  That leaves us with
>>> option A (remove the #include <sys/sysmacros.h> from sys/types.h) and
>>> even that is going to break stuff.  So we need a deprecation period.
>>>
>>> The attached, lightly tested, patch sets up that deprecation period.
>>
>> Ping.  The patch at
>> <https://sourceware.org/ml/libc-alpha/2015-11/msg00452.html> is awaiting
>> review.
> 
> Ping.

Ping.

My hacking time is very limited right now. With the freeze looming, I
would appreciate a definitive yes-or-no answer to whether this is wanted
in the next release (possibly with some concrete list of changes) so I
know whether I need to find time in the near future.

zw
  
Carlos O'Donell Jan. 11, 2016, 3:27 p.m. UTC | #7
On 01/11/2016 10:16 AM, Zack Weinberg wrote:
> On 12/21/2015 03:31 PM, Zack Weinberg wrote:
>> On Mon, Dec 7, 2015 at 9:03 AM, Zack Weinberg <zackw@panix.com> wrote:
>>> On 11/18/2015 11:13 PM, Zack Weinberg wrote:
>>>> Andreas may still be running whole-distro rebuild tests, but enough
>>>> results came back that I feel fairly confident saying that option B
>>>> (remove the #include <sys/types.h> from stdlib.h) is a non-starter.
>>>> There are too many (sloppily coded, yes) programs that include stdlib.h
>>>> and expect it to expose all the POSIX foo_t types.  That leaves us with
>>>> option A (remove the #include <sys/sysmacros.h> from sys/types.h) and
>>>> even that is going to break stuff.  So we need a deprecation period.
>>>>
>>>> The attached, lightly tested, patch sets up that deprecation period.
>>>
>>> Ping.  The patch at
>>> <https://sourceware.org/ml/libc-alpha/2015-11/msg00452.html> is awaiting
>>> review.
>>
>> Ping.
> 
> Ping.
> 
> My hacking time is very limited right now. With the freeze looming, I
> would appreciate a definitive yes-or-no answer to whether this is wanted
> in the next release (possibly with some concrete list of changes) so I
> know whether I need to find time in the near future.

I would like this to go into 2.24.

The reason I say this is that we're very close to a Fedora release and
I would like time to put the deprecation code into Rawhide to get the
developers to cleanup their code there.

For example, 2.23 would go out without these patches, then after we reopen
for 2.24 (Feb), we put the patches in, then we get 6 months of cleanup in
Rawhide, and 2.24 goes out the door with the deprecation macros.
Then 2.25 has the changes made in complete.

Thoughts?

I appreciate the consideration you'd be giving to the Fedora distribution
schedule.

Cheers,
Carlos.
  
Zack Weinberg Jan. 11, 2016, 6:02 p.m. UTC | #8
On Mon, Jan 11, 2016 at 10:27 AM, Carlos O'Donell <carlos@redhat.com> wrote:
>
> I would like this to go into 2.24.
>
> The reason I say this is that we're very close to a Fedora release and
> I would like time to put the deprecation code into Rawhide to get the
> developers to cleanup their code there.

I'm happy to have this go in on whatever schedule is most convenient
for the community at large.  Perhaps we should check whether your
proposed schedule is also good for other distributions?

(also, still waiting for any feedback at all on the content of the changes ;-)

zw
  
Carlos O'Donell Jan. 11, 2016, 8:50 p.m. UTC | #9
On 01/11/2016 01:02 PM, Zack Weinberg wrote:
> On Mon, Jan 11, 2016 at 10:27 AM, Carlos O'Donell <carlos@redhat.com> wrote:
>>
>> I would like this to go into 2.24.
>>
>> The reason I say this is that we're very close to a Fedora release and
>> I would like time to put the deprecation code into Rawhide to get the
>> developers to cleanup their code there.
> 
> I'm happy to have this go in on whatever schedule is most convenient
> for the community at large.  Perhaps we should check whether your
> proposed schedule is also good for other distributions?
> 
> (also, still waiting for any feedback at all on the content of the changes ;-)

I'm buying myself time to review :}

The other distributions are listed on MAINTAINERS and their respective
glibc developers should follow this list, even orthogonally, and if we
make this change it will go into the release-specific wiki page documenting
distribution changes (like we did for DEFAULT_SOURCE and your other change).
So they should have visibility just before the release.

Cheers,
Carlos.
  
Mike Frysinger Feb. 19, 2016, 8:56 p.m. UTC | #10
On 29 Dec 2015 17:45, Mike Frysinger wrote:
> On 29 Dec 2015 13:56, Zack Weinberg wrote:
> > On Tue, Dec 29, 2015 at 12:42 PM, Mike Frysinger wrote:
> > > On 18 Nov 2015 23:13, Zack Weinberg wrote:
> > >> Andreas may still be running whole-distro rebuild tests, but enough
> > >> results came back that I feel fairly confident saying that option B
> > >> (remove the #include <sys/types.h> from stdlib.h) is a non-starter.
> > >> There are too many (sloppily coded, yes) programs that include stdlib.h
> > >> and expect it to expose all the POSIX foo_t types.  That leaves us with
> > >> option A (remove the #include <sys/sysmacros.h> from sys/types.h) and
> > >> even that is going to break stuff.  So we need a deprecation period.
> > >
> > > i'm just going to drop it in Gentoo and let people fix the build failures
> > 
> > Well, if you're going to do that, option B might be better (or both!)
> > but I don't see it as a viable approach for upstream...
> 
> one at a time :).  the impact of sysmacros.h is significantly lower than
> the impact of sys/types.h.  although people have been building Gentoo
> against other C libs, so we are prob better protected against that.

i've deployed this in Gentoo now, but only to limited testers.
i'll open it up when glibc-2.22 goes stable in like ~30 days.
-mike
  
Mike Frysinger April 20, 2016, 5:36 p.m. UTC | #11
On 18 Nov 2015 23:13, Zack Weinberg wrote:
> Andreas may still be running whole-distro rebuild tests, but enough
> results came back that I feel fairly confident saying that option B
> (remove the #include <sys/types.h> from stdlib.h) is a non-starter.
> There are too many (sloppily coded, yes) programs that include stdlib.h
> and expect it to expose all the POSIX foo_t types.  That leaves us with
> option A (remove the #include <sys/sysmacros.h> from sys/types.h) and
> even that is going to break stuff.  So we need a deprecation period.
> 
> The attached, lightly tested, patch sets up that deprecation period.
> From an application's perspective, it works like this:
> 
> * If you include <sys/sysmacros.h> directly, you get major(), minor(),
> and makedev() macros and everything works as it did before, regardless
> of whether you also include <sys/types.h> and in what order.
> 
> * If you define _SYS_TYPES_NO_SYSMACROS before including any headers,
> then <sys/types.h> does not include <sys/sysmacros.h> at all.
> 
> * If you include <sys/types.h>, you don't include <sys/sysmacros.h>, and
> you don't define _SYS_TYPES_NO_SYSMACROS, then you still get major(),
> minor(), and makedev() macros, but they trigger a deprecation warning if
> you *use* them.  This warning contains a lengthy explanation of what is
> about to change and suggests either including <sys/sysmacros.h> or
> defining _SYS_TYPES_NO_SYSMACROS, depending on whether you actually
> wanted the dev_t manipulators.
> 
> The implementation of all that is regrettably messy, but it works.  I
> also took the opportunity to genericize some of the code involved;
> sys/sysmacros.h and makedev.c both now live in misc/ instead of
> sysdeps/, and there's a new 'bits' header that encapsulates the only
> thing that varies between Linux and non-, which is the actual encoding
> of a dev_t.  (I'd appreciate extra-careful review of the arithmetic in
> the new bits headers; I'm not sure it was ever 100% correct, I may have
> messed it up, and there don't seem to be any tests.)
> 
> I deliberately didn't say "in the next release" in the deprecation
> message, because we might want to give this more than one cycle to bake.

shall we move forward with this ?  i've been sending patches to upstreams
and they've been taking them.
-mike
  
Zack Weinberg April 20, 2016, 5:58 p.m. UTC | #12
On Wed, Apr 20, 2016 at 1:36 PM, Mike Frysinger <vapier@gentoo.org> wrote:
> On 18 Nov 2015 23:13, Zack Weinberg wrote:
>>
>> The attached, lightly tested, patch sets up that deprecation period.
>
> shall we move forward with this ?  i've been sending patches to upstreams
> and they've been taking them.

I'm going to be on vacation the last two weeks in May, and I've got a
lot on my plate between now and then.  I can probably find time to
revise the patch *once* before June, but it would be ideal to get a
comprehensive list of changes you want me to make ASAP.

zw
  
Mike Frysinger April 20, 2016, 6:11 p.m. UTC | #13
On 20 Apr 2016 13:58, Zack Weinberg wrote:
> On Wed, Apr 20, 2016 at 1:36 PM, Mike Frysinger wrote:
> > On 18 Nov 2015 23:13, Zack Weinberg wrote:
> >> The attached, lightly tested, patch sets up that deprecation period.
> >
> > shall we move forward with this ?  i've been sending patches to upstreams
> > and they've been taking them.
> 
> I'm going to be on vacation the last two weeks in May, and I've got a
> lot on my plate between now and then.  I can probably find time to
> revise the patch *once* before June, but it would be ideal to get a
> comprehensive list of changes you want me to make ASAP.

assuming it works as advertised, i didn't see anything wrong with this
version as-is.  Carlos said he wanted to take a peek though ...
-mike
  
Roland McGrath April 21, 2016, 7:31 p.m. UTC | #14
This patch has no ChangeLog entries.

Please drop the clang-related changes to sys/cdefs.h in this patch.
Adding __attribute_deprecated_msg__ here is OK, but other changes to
sys/cdefs.h belong in a separate change.

> --- /dev/null
> +++ b/include/sys/sysmacros.h
> @@ -0,0 +1,3 @@
> +#ifndef _SYS_SYSMACROS_H
> +#include <misc/sys/sysmacros.h>
> +#endif

No #ifndef here.  include/ files should be nothing but direct
wrappers when that works, as it should here.

> --- /dev/null
> +++ b/misc/makedev.c

Moving this file to OS-independent place means you also need to add
the functions to misc/Versions.  Since they didn't exist before on
non-Linux configurations, misc/Versions should list them under
GLIBC_2.24.  The existing sysdeps/unix/sysv/linux/Versions entries
will give them the old symbol version in Linux configurations.

> --- /dev/null
> +++ b/misc/sys/sysmacros.h

Throughout this file you should indent nested preprocessor
directives, e.g.:

#ifdef foo
# define bar ...
#endif


> +#define __INCLUSION_DEPRECATION_MSG(symbol)                                  \

Use a name that starts with "__SYSMACROS_".

> +  "\n  The macro `" #symbol "' is defined by <sys/sysmacros.h>."             \
> +  "\n  For compatibility with BSD, it is currently defined by <sys/types.h>" \
> +  "\n  as well, but we plan to remove this soon.  To use `" #symbol "',"     \
> +  "\n  include <sys/sysmacros.h> directly.  If you did not intend to use"    \
> +  "\n  a system-defined macro `" #symbol "', you can suppress it by "        \
> +  "\n  defining the macro _SYS_TYPES_NO_SYSMACROS (with any value) before "  \
> +  "\n  including any system headers."

Say "historical compatibility" rather than "compatibility with BSD".

I'm not convinced that we should support the _SYS_TYPES_NO_SYSMACROS
macro at all.  If we advise applications to define that, then it will
litter random sources for years to come.  But it serves only a brief
transitional purpose.  And IMHO there is really no need for that
option at all.  Things will continue to work as they did today with
no warnings for applications that were not using these symbols.

> +#ifdef __USE_EXTERN_INLINES
> +#define __SYSMACRO_IMPL(rtype, name, proto, expr) \

An example of unintended preprocessor directives.

> +  __SYSMACRO_DECL(rtype, name, proto) \

Space before paren here.

> +__SYSMACRO_IMPL(unsigned int, major, (__dev_t __dev), __dev_major (__dev))
> +__SYSMACRO_IMPL(unsigned int, minor, (__dev_t __dev), __dev_minor (__dev))
> +__SYSMACRO_IMPL(__dev_t, makedev,
> +                (unsigned int __major, unsigned int __minor),
> +                __dev_makedev (__major, __minor))

Space before parens here.

Also, make all these macros __SYSMACROS_* instead of _SYSMACRO_* (so
the prefix matches the name of the header file).

> +#ifdef _DEPRECATED_INCLUSION_OF_SYS_SYSMACROS_H
> +#define major(dev) gnu_dev_major_from_sys_types (dev)
> +#define minor(dev) gnu_dev_minor_from_sys_types (dev)
> +#define makedev(maj, min) gnu_dev_makedev_from_sys_types (maj, min)

I think these compat wrapper functions should have __ names.


Thanks,
Roland
  
Zack Weinberg April 21, 2016, 8:59 p.m. UTC | #15
Thanks for the review. I will make revisions this weekend.

On Thu, Apr 21, 2016 at 3:31 PM, Roland McGrath <roland@hack.frob.com> wrote:
> This patch has no ChangeLog entries.

I'll add those after all revisions are complete.

> Please drop the clang-related changes to sys/cdefs.h in this patch.
> Adding __attribute_deprecated_msg__ here is OK, but other changes to
> sys/cdefs.h belong in a separate change.

OK, I'll split it.

>> --- /dev/null
>> +++ b/include/sys/sysmacros.h
>> @@ -0,0 +1,3 @@
>> +#ifndef _SYS_SYSMACROS_H
>> +#include <misc/sys/sysmacros.h>
>> +#endif
>
> No #ifndef here.  include/ files should be nothing but direct
> wrappers when that works, as it should here.

OK.

>> --- /dev/null
>> +++ b/misc/makedev.c
>
> Moving this file to OS-independent place means you also need to add
> the functions to misc/Versions.  Since they didn't exist before on
> non-Linux configurations, misc/Versions should list them under
> GLIBC_2.24.  The existing sysdeps/unix/sysv/linux/Versions entries
> will give them the old symbol version in Linux configurations.

OK.

>> --- /dev/null
>> +++ b/misc/sys/sysmacros.h
>
> Throughout this file you should indent nested preprocessor
> directives, e.g.:
>
> #ifdef foo
> # define bar ...
> #endif

OK.

>> +#define __INCLUSION_DEPRECATION_MSG(symbol)                                  \
>
> Use a name that starts with "__SYSMACROS_".

OK.

>> +  "\n  For compatibility with BSD, it is currently defined by <sys/types.h>" \
>> +  "\n  as well, but we plan to remove this soon.  To use `" #symbol "',"     \
>> +  "\n  include <sys/sysmacros.h> directly.  If you did not intend to use"    \
>> +  "\n  a system-defined macro `" #symbol "', you can suppress it by "        \
>> +  "\n  defining the macro _SYS_TYPES_NO_SYSMACROS (with any value) before "  \
>> +  "\n  including any system headers."
>
> Say "historical compatibility" rather than "compatibility with BSD".

OK.

> I'm not convinced that we should support the _SYS_TYPES_NO_SYSMACROS
> macro at all.  If we advise applications to define that, then it will
> litter random sources for years to come.  But it serves only a brief
> transitional purpose.  And IMHO there is really no need for that
> option at all.  Things will continue to work as they did today with
> no warnings for applications that were not using these symbols.

Hmm, good point.  The macro was for programs that *are* being broken
because they didn't expect sys/types.h to define major/minor/makedev,
and advising such programs to #undef those symbols is better advice,
since that will work on *BSDs that still define them there.

>> +#ifdef __USE_EXTERN_INLINES
>> +#define __SYSMACRO_IMPL(rtype, name, proto, expr) \
>
> An example of unintended preprocessor directives.

I assume you meant unindented.

>> +  __SYSMACRO_DECL(rtype, name, proto) \
>
> Space before paren here.

Doh.  (I've been working mostly on programs where the preferred style
is different, lately.)

>> +__SYSMACRO_IMPL(unsigned int, major, (__dev_t __dev), __dev_major (__dev))
>> +__SYSMACRO_IMPL(unsigned int, minor, (__dev_t __dev), __dev_minor (__dev))
>> +__SYSMACRO_IMPL(__dev_t, makedev,
>> +                (unsigned int __major, unsigned int __minor),
>> +                __dev_makedev (__major, __minor))
>
> Space before parens here.
>
> Also, make all these macros __SYSMACROS_* instead of _SYSMACRO_* (so
> the prefix matches the name of the header file).

I think singular is more appropriate because it expands to the
implementation of *one* sysmacro.

>> +#ifdef _DEPRECATED_INCLUSION_OF_SYS_SYSMACROS_H
>> +#define major(dev) gnu_dev_major_from_sys_types (dev)
>> +#define minor(dev) gnu_dev_minor_from_sys_types (dev)
>> +#define makedev(maj, min) gnu_dev_makedev_from_sys_types (maj, min)
>
> I think these compat wrapper functions should have __ names.

OK.

zw
  
Roland McGrath April 21, 2016, 9:11 p.m. UTC | #16
> Hmm, good point.  The macro was for programs that *are* being broken
> because they didn't expect sys/types.h to define major/minor/makedev,
> and advising such programs to #undef those symbols is better advice,
> since that will work on *BSDs that still define them there.

Yes, that is harmless now and will be harmless in the future and does not
look like gratuitous cruft in the same way.

> >> +#ifdef __USE_EXTERN_INLINES
> >> +#define __SYSMACRO_IMPL(rtype, name, proto, expr) \
> >
> > An example of unintended preprocessor directives.
> 
> I assume you meant unindented.

Indeed.  Typing is hard.

> > Also, make all these macros __SYSMACROS_* instead of _SYSMACRO_* (so
> > the prefix matches the name of the header file).
> 
> I think singular is more appropriate because it expands to the
> implementation of *one* sysmacro.

"sysmacro" is not a thing.  "sysmacros" is the name of the file, and hence
the moniker for its private namespace.
  

Patch

 include/sys/sysmacros.h                  |  3 +
 misc/Makefile                            |  5 +-
 misc/makedev.c                           | 40 ++++++++++++++
 misc/sys/cdefs.h                         | 21 ++++++-
 misc/sys/sysmacros.h                     | 95 ++++++++++++++++++++++++++++++++
 posix/Makefile                           |  2 +-
 posix/sys/types.h                        | 13 ++++-
 sysdeps/generic/bits/sysmacros.h         | 30 ++++++++++
 sysdeps/generic/sys/sysmacros.h          | 30 ----------
 sysdeps/unix/sysv/linux/Makefile         |  2 +-
 sysdeps/unix/sysv/linux/bits/sysmacros.h | 39 +++++++++++++
 sysdeps/unix/sysv/linux/makedev.c        | 40 --------------
 sysdeps/unix/sysv/linux/sys/sysmacros.h  | 65 ----------------------
 13 files changed, 243 insertions(+), 142 deletions(-)
 create mode 100644 include/sys/sysmacros.h
 create mode 100644 misc/makedev.c
 create mode 100644 misc/sys/sysmacros.h
 create mode 100644 sysdeps/generic/bits/sysmacros.h
 delete mode 100644 sysdeps/generic/sys/sysmacros.h
 create mode 100644 sysdeps/unix/sysv/linux/bits/sysmacros.h
 delete mode 100644 sysdeps/unix/sysv/linux/makedev.c
 delete mode 100644 sysdeps/unix/sysv/linux/sys/sysmacros.h

diff --git a/include/sys/sysmacros.h b/include/sys/sysmacros.h
new file mode 100644
index 0000000..a986710
--- /dev/null
+++ b/include/sys/sysmacros.h
@@ -0,0 +1,3 @@ 
+#ifndef _SYS_SYSMACROS_H
+#include <misc/sys/sysmacros.h>
+#endif
diff --git a/misc/Makefile b/misc/Makefile
index 2f5edf6..14b16ff 100644
--- a/misc/Makefile
+++ b/misc/Makefile
@@ -34,7 +34,8 @@  headers	:= sys/uio.h bits/uio.h sys/ioctl.h bits/ioctls.h bits/ioctl-types.h \
 	   regexp.h bits/select.h bits/mman.h sys/xattr.h \
 	   syslog.h sys/syslog.h \
 	   bits/syslog.h bits/syslog-ldbl.h bits/syslog-path.h bits/error.h \
-	   bits/select2.h bits/hwcap.h sys/auxv.h
+	   bits/select2.h bits/hwcap.h sys/auxv.h \
+	   sys/sysmacros.h bits/sysmacros.h
 
 routines := brk sbrk sstk ioctl \
 	    readv writev preadv preadv64 pwritev pwritev64 \
@@ -67,7 +68,7 @@  routines := brk sbrk sstk ioctl \
 	    getloadavg getclktck \
 	    fgetxattr flistxattr fremovexattr fsetxattr getxattr \
 	    listxattr lgetxattr llistxattr lremovexattr lsetxattr \
-	    removexattr setxattr getauxval ifunc-impl-list
+	    removexattr setxattr getauxval ifunc-impl-list makedev
 
 generated += tst-error1.mtrace tst-error1-mem.out
 
diff --git a/misc/makedev.c b/misc/makedev.c
new file mode 100644
index 0000000..d17deec
--- /dev/null
+++ b/misc/makedev.c
@@ -0,0 +1,40 @@ 
+/* Definitions of functions to access `dev_t' values.
+   Copyright (C) 2003-2015 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <features.h>
+#undef __USE_EXTERN_INLINES
+#include <sys/sysmacros.h>
+#include <sys/types.h>
+
+unsigned int
+gnu_dev_major (dev_t dev)
+{
+  return __dev_major (dev);
+}
+
+unsigned int
+gnu_dev_minor (dev_t dev)
+{
+  return __dev_minor (dev);
+}
+
+dev_t
+gnu_dev_makedev (unsigned int major, unsigned int minor)
+{
+  return __dev_makedev (major, minor);
+}
diff --git a/misc/sys/cdefs.h b/misc/sys/cdefs.h
index 99e94cc..e613a64 100644
--- a/misc/sys/cdefs.h
+++ b/misc/sys/cdefs.h
@@ -77,6 +77,15 @@ 
 
 #endif	/* GCC.  */
 
+/* Compilers that are not clang may object to
+       #if defined __clang__ && __has_extension(...)
+   even though they do not need to evaluate the right-hand side of the &&. */
+#ifdef __clang__
+# define __clang_has_extension__(ext) __has_extension(ext)
+#else
+# define __clang_has_extension__(ext) 0
+#endif
+
 /* These two macros are not used in glibc anymore.  They are kept here
    only because some other projects expect the macros to be defined.  */
 #define __P(args)	args
@@ -249,13 +258,23 @@ 
 # define __attribute_noinline__ /* Ignore */
 #endif
 
-/* gcc allows marking deprecated functions.  */
+/* gcc has supported marking deprecated functions since 3.2, but the
+   ability to specify a message was only added in 4.5.  clang claims
+   to be gcc 4.2, but may support messages anyway.  */
 #if __GNUC_PREREQ (3,2)
 # define __attribute_deprecated__ __attribute__ ((__deprecated__))
 #else
 # define __attribute_deprecated__ /* Ignore */
 #endif
 
+#if __GNUC_PREREQ (4,5) || \
+    __clang_has_extension__ (__attribute_deprecated_with_message__)
+# define __attribute_deprecated_msg__(msg) \
+         __attribute__ ((__deprecated__ (msg)))
+#else
+# define __attribute_deprecated_msg__(msg) __attribute_deprecated__
+#endif
+
 /* At some point during the gcc 2.8 development the `format_arg' attribute
    for functions was introduced.  We don't want to use it unconditionally
    (although this would be possible) since it generates warnings.
diff --git a/misc/sys/sysmacros.h b/misc/sys/sysmacros.h
new file mode 100644
index 0000000..15f0692
--- /dev/null
+++ b/misc/sys/sysmacros.h
@@ -0,0 +1,95 @@ 
+/* Definitions of macros to access `dev_t' values.
+   Copyright (C) 1996-2015 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _SYS_SYSMACROS_H
+
+#ifndef _DEPRECATED_INCLUSION_OF_SYS_SYSMACROS_H
+# define _SYS_SYSMACROS_H	1
+#endif
+
+/* If <sys/sysmacros.h> is included after <sys/types.h>, these macros
+   will already be defined, and we need to redefine them without the
+   deprecation warnings.  (If they are included in the opposite order,
+   the outer #ifndef will suppress this entire file and the macros
+   will be usable without warnings.)  */
+#undef major
+#undef minor
+#undef makedev
+
+#ifndef _SYS_SYSMACROS_H_INNER
+#define _SYS_SYSMACROS_H_INNER 1
+
+#include <features.h>
+#include <bits/types.h>
+#include <bits/sysmacros.h>
+
+#define __INCLUSION_DEPRECATION_MSG(symbol)                                  \
+  "\n  The macro `" #symbol "' is defined by <sys/sysmacros.h>."             \
+  "\n  For compatibility with BSD, it is currently defined by <sys/types.h>" \
+  "\n  as well, but we plan to remove this soon.  To use `" #symbol "',"     \
+  "\n  include <sys/sysmacros.h> directly.  If you did not intend to use"    \
+  "\n  a system-defined macro `" #symbol "', you can suppress it by "        \
+  "\n  defining the macro _SYS_TYPES_NO_SYSMACROS (with any value) before "  \
+  "\n  including any system headers."
+
+#define __SYSMACRO_DECL(rtype, name, proto) \
+  extern rtype gnu_dev_##name proto __THROW __attribute_const__; \
+  extern rtype __REDIRECT_NTH (gnu_dev_##name##_from_sys_types, proto, \
+                               gnu_dev_##name) \
+       __attribute_const__ \
+       __attribute_deprecated_msg__ (__INCLUSION_DEPRECATION_MSG (name)); \
+
+#ifdef __USE_EXTERN_INLINES
+#define __SYSMACRO_IMPL(rtype, name, proto, expr) \
+  __SYSMACRO_DECL(rtype, name, proto) \
+  __extension__ __extern_inline __attribute_const__ rtype \
+  __NTH (gnu_dev_##name proto) { return expr; } \
+  __extension__ __extern_inline __attribute_const__ rtype \
+  __NTH (gnu_dev_##name##_from_sys_types proto) { return expr; }
+#else
+#define __SYSMACRO_IMPL(rtype, name, proto, expr) \
+  __SYSMACRO_DECL(rtype, name, proto)
+#endif
+
+__BEGIN_DECLS
+
+__SYSMACRO_IMPL(unsigned int, major, (__dev_t __dev), __dev_major (__dev))
+__SYSMACRO_IMPL(unsigned int, minor, (__dev_t __dev), __dev_minor (__dev))
+__SYSMACRO_IMPL(__dev_t, makedev,
+                (unsigned int __major, unsigned int __minor),
+                __dev_makedev (__major, __minor))
+
+__END_DECLS
+
+#undef __SYSMACRO_IMPL
+#undef __SYSMACRO_DECL
+#undef __INCLUSION_DEPRECATION_MESSAGE
+
+#endif /* _SYS_SYSMACROS_H_INNER */
+
+#ifdef _DEPRECATED_INCLUSION_OF_SYS_SYSMACROS_H
+#define major(dev) gnu_dev_major_from_sys_types (dev)
+#define minor(dev) gnu_dev_minor_from_sys_types (dev)
+#define makedev(maj, min) gnu_dev_makedev_from_sys_types (maj, min)
+#else
+#define major(dev) gnu_dev_major (dev)
+#define minor(dev) gnu_dev_minor (dev)
+#define makedev(maj, min) gnu_dev_makedev (maj, min)
+#endif
+
+#endif /* sys/sysmacros.h */
diff --git a/posix/Makefile b/posix/Makefile
index aeb9890..e2835c3 100644
--- a/posix/Makefile
+++ b/posix/Makefile
@@ -29,7 +29,7 @@  headers	:= sys/utsname.h sys/times.h sys/wait.h sys/types.h unistd.h	      \
 	   bits/local_lim.h tar.h bits/utsname.h bits/confname.h	      \
 	   bits/waitflags.h bits/waitstatus.h sys/unistd.h sched.h	      \
 	   bits/sched.h re_comp.h wait.h bits/environments.h cpio.h	      \
-	   sys/sysmacros.h spawn.h bits/unistd.h
+	   spawn.h bits/unistd.h
 
 routines :=								      \
 	uname								      \
diff --git a/posix/sys/types.h b/posix/sys/types.h
index bf30873..74eb558 100644
--- a/posix/sys/types.h
+++ b/posix/sys/types.h
@@ -218,8 +218,17 @@  typedef int register_t __attribute__ ((__mode__ (__word__)));
 /* It also defines `fd_set' and the FD_* macros for `select'.  */
 # include <sys/select.h>
 
-/* BSD defines these symbols, so we follow.  */
-# include <sys/sysmacros.h>
+/* BSD defines `major', `minor', and `makedev' in this header.
+   However, these symbols are likely to collide with user code, so we
+   are going to remove them in an upcoming release.  Code that needs
+   these macros should include <sys/sysmacros.h> directly.  Code that
+   does not need these macros may define _SYS_TYPES_NO_SYSMACROS to
+   insulate itself from them.  */
+# ifndef _SYS_TYPES_NO_SYSMACROS
+#  define _DEPRECATED_INCLUSION_OF_SYS_SYSMACROS_H
+#  include <sys/sysmacros.h>
+#  undef _DEPRECATED_INCLUSION_OF_SYS_SYSMACROS_H
+# endif /* No sysmacros.  */
 #endif /* Use misc.  */
 
 
diff --git a/sysdeps/generic/bits/sysmacros.h b/sysdeps/generic/bits/sysmacros.h
new file mode 100644
index 0000000..1022d48
--- /dev/null
+++ b/sysdeps/generic/bits/sysmacros.h
@@ -0,0 +1,30 @@ 
+/* Definitions of macros to access `dev_t' values.
+   Copyright (C) 1996-2015 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _BITS_SYSMACROS_H
+#define _BITS_SYSMACROS_H	1
+
+#ifndef _SYS_SYSMACROS_H_INNER
+# error "Never include <bits/sysmacros.h> directly; use <sys/sysmacros.h> instead."
+#endif
+
+#define __dev_major(dev) ((dev) >> 8) & 0xff))
+#define __dev_minor(dev) ((dev)       & 0xff))
+#define __dev_makedev(major, minor) (((major) << 8) | (minor & 0xff))
+
+#endif /* bits/sysmacros.h */
diff --git a/sysdeps/generic/sys/sysmacros.h b/sysdeps/generic/sys/sysmacros.h
deleted file mode 100644
index 06e5d70..0000000
--- a/sysdeps/generic/sys/sysmacros.h
+++ /dev/null
@@ -1,30 +0,0 @@ 
-/* Definitions of macros to access `dev_t' values.
-   Copyright (C) 1996-2015 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, see
-   <http://www.gnu.org/licenses/>.  */
-
-#ifndef _SYS_SYSMACROS_H
-#define _SYS_SYSMACROS_H	1
-
-/* For compatibility we provide alternative names.
-
-   The problem here is that compilers other than GCC probably don't
-   have the `long long' type and so `dev_t' is actually an array.  */
-#define major(dev) ((int)(((unsigned int) (dev) >> 8) & 0xff))
-#define minor(dev) ((int)((dev) & 0xff))
-#define makedev(major, minor) (((major) << 8) | (minor))
-
-#endif /* sys/sysmacros.h */
diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile
index d6cc529..551c4ee 100644
--- a/sysdeps/unix/sysv/linux/Makefile
+++ b/sysdeps/unix/sysv/linux/Makefile
@@ -15,7 +15,7 @@  ifeq ($(subdir),misc)
 include $(firstword $(wildcard $(sysdirs:=/sysctl.mk)))
 
 sysdep_routines += clone llseek umount umount2 readahead \
-		   setfsuid setfsgid makedev epoll_pwait signalfd \
+		   setfsuid setfsgid epoll_pwait signalfd \
 		   eventfd eventfd_read eventfd_write prlimit
 
 CFLAGS-gethostid.c = -fexceptions
diff --git a/sysdeps/unix/sysv/linux/bits/sysmacros.h b/sysdeps/unix/sysv/linux/bits/sysmacros.h
new file mode 100644
index 0000000..da37e28
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/bits/sysmacros.h
@@ -0,0 +1,39 @@ 
+/* Definitions of macros to access `dev_t' values.
+   Copyright (C) 1996-2015 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _BITS_SYSMACROS_H
+#define _BITS_SYSMACROS_H	1
+
+#ifndef _SYS_SYSMACROS_H_INNER
+# error "Never include <bits/sysmacros.h> directly; use <sys/sysmacros.h> instead."
+#endif
+
+/* dev_t in glibc is a 64-bit quantity, encoded as MMMM Mmmm mmmM MMmm,
+   where M is a hex digit of the major number and m is a hex digit of
+   the minor number.  Linux-the-kernel only uses the low 32 bits.  */
+
+#define __dev_major(dev) \
+  ((((dev) >> 8) & 0xfff) | (((unsigned int) ((dev) >> 32)) & ~0xfff))
+#define __dev_minor(dev) \
+  (((dev) & 0xff) | (((unsigned int) ((dev) >> 12) & ~0xff)))
+#define __dev_makedev(major, minor) \
+  (((minor) & 0xff) | (((major) & 0xfff) << 8) \
+   | (((__dev_t) ((minor) & ~0xff)) << 12) \
+   | (((__dev_t) ((major) & ~0xff)) << 32))
+
+#endif /* bits/sysmacros.h */
diff --git a/sysdeps/unix/sysv/linux/makedev.c b/sysdeps/unix/sysv/linux/makedev.c
deleted file mode 100644
index bd9666f..0000000
--- a/sysdeps/unix/sysv/linux/makedev.c
+++ /dev/null
@@ -1,40 +0,0 @@ 
-/* Definitions of functions to access `dev_t' values.
-   Copyright (C) 2003-2015 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, see
-   <http://www.gnu.org/licenses/>.  */
-
-#include <endian.h>
-#include <sys/sysmacros.h>
-
-unsigned int
-gnu_dev_major (unsigned long long int dev)
-{
-  return ((dev >> 8) & 0xfff) | ((unsigned int) (dev >> 32) & ~0xfff);
-}
-
-unsigned int
-gnu_dev_minor (unsigned long long int dev)
-{
-  return (dev & 0xff) | ((unsigned int) (dev >> 12) & ~0xff);
-}
-
-unsigned long long int
-gnu_dev_makedev (unsigned int major, unsigned int minor)
-{
-  return ((minor & 0xff) | ((major & 0xfff) << 8)
-	  | (((unsigned long long int) (minor & ~0xff)) << 12)
-	  | (((unsigned long long int) (major & ~0xfff)) << 32));
-}
diff --git a/sysdeps/unix/sysv/linux/sys/sysmacros.h b/sysdeps/unix/sysv/linux/sys/sysmacros.h
deleted file mode 100644
index a4fbd47..0000000
--- a/sysdeps/unix/sysv/linux/sys/sysmacros.h
+++ /dev/null
@@ -1,65 +0,0 @@ 
-/* Definitions of macros to access `dev_t' values.
-   Copyright (C) 1996-2015 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, see
-   <http://www.gnu.org/licenses/>.  */
-
-#ifndef _SYS_SYSMACROS_H
-#define _SYS_SYSMACROS_H	1
-
-#include <features.h>
-
-__BEGIN_DECLS
-
-__extension__
-extern unsigned int gnu_dev_major (unsigned long long int __dev)
-     __THROW __attribute_const__;
-__extension__
-extern unsigned int gnu_dev_minor (unsigned long long int __dev)
-     __THROW __attribute_const__;
-__extension__
-extern unsigned long long int gnu_dev_makedev (unsigned int __major,
-					       unsigned int __minor)
-     __THROW __attribute_const__;
-
-#ifdef __USE_EXTERN_INLINES
-__extension__ __extern_inline __attribute_const__ unsigned int
-__NTH (gnu_dev_major (unsigned long long int __dev))
-{
-  return ((__dev >> 8) & 0xfff) | ((unsigned int) (__dev >> 32) & ~0xfff);
-}
-
-__extension__ __extern_inline __attribute_const__ unsigned int
-__NTH (gnu_dev_minor (unsigned long long int __dev))
-{
-  return (__dev & 0xff) | ((unsigned int) (__dev >> 12) & ~0xff);
-}
-
-__extension__ __extern_inline __attribute_const__ unsigned long long int
-__NTH (gnu_dev_makedev (unsigned int __major, unsigned int __minor))
-{
-  return ((__minor & 0xff) | ((__major & 0xfff) << 8)
-	  | (((unsigned long long int) (__minor & ~0xff)) << 12)
-	  | (((unsigned long long int) (__major & ~0xfff)) << 32));
-}
-#endif
-__END_DECLS
-
-/* Access the functions with their traditional names.  */
-#define major(dev) gnu_dev_major (dev)
-#define minor(dev) gnu_dev_minor (dev)
-#define makedev(maj, min) gnu_dev_makedev (maj, min)
-
-#endif /* sys/sysmacros.h */
-- 
2.6.2