The _KERNEL define is overloaded to mean two things, which results in frequent errors. 1. It means we are compiling the kernel. 2. It means we are compiling a userland program that looks at kernel data structures.
Just because we need data structures doesn't mean we want everything else in the kernel. In particular, the kernel environment uses different headers to declare common features like NULL and types, so a header that thinks it's in the kernel will subinclude different headers, breaking userland. Here's the start of a fix. A new define, _KERNEL_INTERFACE, is used to indicate that we are specifically asking for data structures. It doesn't export functions or macros that aren't used in userland. I tweaked one header file, sys/file.h, to use this interface. This reduces the amount of extraneous material exposed to userland, like extern int maxfiles; /* kernel limit on number of open files */ Userland cannot access the kernel variable maxfiles simply by declaring it extern, so this is useless and can only cause conflict. Next, I looked at netstat. Turns out netstat is defining _KERNEL in some places it doesn't even need to, so I deleted them. Then I changed the one place that did need _KERNEL to _KERNEL_INTERFACE before including file.h. Index: sys/sys/file.h =================================================================== RCS file: /cvs/src/sys/sys/file.h,v retrieving revision 1.38 diff -u -p -r1.38 file.h --- sys/sys/file.h 23 Aug 2016 23:28:02 -0000 1.38 +++ sys/sys/file.h 9 Sep 2016 13:50:09 -0000 @@ -57,6 +57,31 @@ struct fileops { int (*fo_close)(struct file *, struct proc *); }; +#define FIF_HASLOCK 0x01 /* descriptor holds advisory lock */ +#define FIF_LARVAL 0x02 /* not fully constructed, don't use */ + +#define FILE_IS_USABLE(fp) \ + (((fp)->f_iflags & FIF_LARVAL) == 0) + +#define FREF(fp) do { (fp)->f_count++; } while (0) +#define FRELE(fp,p) (--(fp)->f_count == 0 ? fdrop(fp, p) : 0) + +#define FILE_SET_MATURE(fp,p) do { \ + (fp)->f_iflags &= ~FIF_LARVAL; \ + FRELE(fp, p); \ +} while (0) + +int fdrop(struct file *, struct proc *); + +LIST_HEAD(filelist, file); +extern struct filelist filehead; /* head of list of open files */ +extern int maxfiles; /* kernel limit on number of open files */ +extern int numfiles; /* actual number of open files */ +extern struct fileops vnops; /* vnode operations for files */ + +#endif /* _KERNEL */ + +#if defined(_KERNEL) || defined(_KERNEL_INTERFACE) /* * Kernel descriptor table. * One entry for each open kernel vnode and socket. @@ -81,27 +106,4 @@ struct file { u_int64_t f_rbytes; /* total bytes read */ u_int64_t f_wbytes; /* total bytes written */ }; - -#define FIF_HASLOCK 0x01 /* descriptor holds advisory lock */ -#define FIF_LARVAL 0x02 /* not fully constructed, don't use */ - -#define FILE_IS_USABLE(fp) \ - (((fp)->f_iflags & FIF_LARVAL) == 0) - -#define FREF(fp) do { (fp)->f_count++; } while (0) -#define FRELE(fp,p) (--(fp)->f_count == 0 ? fdrop(fp, p) : 0) - -#define FILE_SET_MATURE(fp,p) do { \ - (fp)->f_iflags &= ~FIF_LARVAL; \ - FRELE(fp, p); \ -} while (0) - -int fdrop(struct file *, struct proc *); - -LIST_HEAD(filelist, file); -extern struct filelist filehead; /* head of list of open files */ -extern int maxfiles; /* kernel limit on number of open files */ -extern int numfiles; /* actual number of open files */ -extern struct fileops vnops; /* vnode operations for files */ - -#endif /* _KERNEL */ +#endif Index: usr.bin/netstat/inet.c =================================================================== RCS file: /cvs/src/usr.bin/netstat/inet.c,v retrieving revision 1.151 diff -u -p -r1.151 inet.c --- usr.bin/netstat/inet.c 2 Sep 2016 09:39:32 -0000 1.151 +++ usr.bin/netstat/inet.c 9 Sep 2016 13:52:18 -0000 @@ -37,9 +37,9 @@ #include <sys/domain.h> #include <sys/protosw.h> #include <sys/sysctl.h> -#define _KERNEL +#define _KERNEL_INTERFACE #include <sys/file.h> -#undef _KERNEL +#undef _KERNEL_INTERFACE #include <net/route.h> #include <netinet/in.h> Index: usr.bin/netstat/route.c =================================================================== RCS file: /cvs/src/usr.bin/netstat/route.c,v retrieving revision 1.100 diff -u -p -r1.100 route.c --- usr.bin/netstat/route.c 27 Aug 2016 04:13:43 -0000 1.100 +++ usr.bin/netstat/route.c 9 Sep 2016 13:51:56 -0000 @@ -38,10 +38,8 @@ #include <net/if.h> #include <net/if_dl.h> #include <net/if_types.h> -#define _KERNEL #include <net/route.h> #include <netinet/ip_ipsp.h> -#undef _KERNEL #include <netinet/in.h> #include <arpa/inet.h> Index: usr.bin/netstat/unix.c =================================================================== RCS file: /cvs/src/usr.bin/netstat/unix.c,v retrieving revision 1.29 diff -u -p -r1.29 unix.c --- usr.bin/netstat/unix.c 27 Aug 2016 04:07:42 -0000 1.29 +++ usr.bin/netstat/unix.c 9 Sep 2016 13:53:29 -0000 @@ -41,10 +41,10 @@ #include <sys/time.h> #include <sys/un.h> #include <sys/unpcb.h> -#define _KERNEL #include <sys/ucred.h> +#define _KERNEL_INTERFACE #include <sys/file.h> -#undef _KERNEL +#undef _KERNEL_INTERFACE #include <netinet/in.h>