 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

