Synchronizing Headers
A number of glibc headers have equivalent header in Linux kernel space. While is is generally not a good idea to mix usage of kernel space and user space headers in a program, it is often unavoidable due to decisions made by library developers. The kernel and user space headers can define the same structures, with the resulting conflicts causing errors during compilation. Ideally, we would like to synchronize the kernel UAPI header and the libc headers so either one can be used and both can be included in any order.
Fixing Compatibility
The Linux kernel provides a <linux/libc-compat.h> header that allows defining guard macros to prevent conflicting definitions. The general approach to follow is:
- Synchronize the Linux UAPI header with the libc header so that either one can be used while conserving ABI in both projects.
- In the Linux source:
- Include the libc-compat header in the UAPI header as early as possible.
- In libc-compat.h detect whether the conflicting libc header has been included first.
Define guards in the form __UAPI_DEF_FOO and set these to 1 or 0 if the userspace header has been included respectively.
In the UAPI header, guard the definitions with #if __UAPI_DEF_FOO ...
In the glibc userspace header, guard the definitions with #if !__UAPI_DEF_FOO etc.
Point #2 fixes the case where the userspace header is included before the kernel space header, and point #3 fixes the other way.
Example
Example patches fixing the inclusion of both <netinet/in.h> and <linux/in6.h>:
Known Pairs of Headers that Conflict
<linux/ptrace.h> and <sys/ptrace.h> (Note: temporarily worked around by commit 9341dde4)
<linux/ax25.h> and <netax25/ax25.h> (Note: no workaround)
<linux/if.h> and <net/if.h> (Note: no workaround)
<linux/in.h> and <netinet/in.h> (Note: no workaround)
<linux/xfrm.h> and <netdb.h> (Note: no workaround)
<linux/ipx.h> and <netipx/ipx.h> (Note: no workaround)
<linux/stat.h> and <sys/stat.h> (Note: no workaround)
<linux/time.h> and <sys/time.h> (Note: no workaround)
<linux/mount.h> and <sys/mount.h> (Note: no workaround)
Fixed Conflicts
<netinet/in.h> and <linux/in6.h> - glibc commit 6c82a2f8, linux commit cfd280c9
<linux/xattr.h> and <sys/xattr.h> - glibc commit fdbe8eae, linux commit ea1a8217