if you build glibc-2.9 against kernel headers older than 2.6.27, then the
resulting libc code can easily break when running on a kernel 2.6.27 or newer.
for example, this simple code will result in popen() failing with ENOSYS:
if (!popen("ls", "r"))
this is because __have_pipe2 is defined to __have_sock_cloexec in
include/unistd.h. sock_cloexec is tested at runtime using defines that are
completely contained within glibc and so works properly regardless of the
version of kernel headers built against and the kernel version run on. pipe2
however requires __NR_pipe2 to be defined in the kernel headers otherwise glibc
creates an ENOSYS stub for it.
so in the previous example, if we run on linux-2.6.27 or newer, getgrnam()
recurses into socket() with SOCK_CLOEXEC and detects that it works, and so it
sets __have_sock_cloexec to 1. but when we call popen(), it sees that
__have_pipe2 is set to 1 (since it is defined to __have_sock_cloexec), and so
only calls pipe2() (which is an ENOSYS stub) and things fail.
if we give __have_pipe2 dedicated storage, then things work properly --
SOCK_CLOEXEC is detected independent of pipe2().
i wrote a patch here, but i imagine drepper will simply say it's "wrong" and do
whatever else, so no point in writing a ChangeLog/etc...
further, assuming sock_cloexec and pipe2 support were added at the same time is
invalid for all arches, so they'll need separate storage anyways. the assumption
is only valid for a subset of architectures.
The only architectures of interest are those in the main tree. Anything else
must be handled elsewhere. So, which architecture do you think doesn't work?
sysdeps/unix/sysv/linux/kernel-features.h omits __sh__ from the list as it does
have pipe2 in linux-2.6.27, but that's a different issue
the point of the way glibc is laid out is for arches to control features like
this. by binding sock_cloexec and pipe2 together without any sort of recourse,
you're basically saying that all other arches will be broken and there's nothing
they can do about it (regardless of whether they're in the "main" set of ports).
if you want to add another define like __ASSUME_SOCK_CLOEXEC_AND_PIPE2 and key
the __have_pipe2->__have_sock_cloexec define off of that vs dedicated storage,
then that would work as the other arches would be able to disable it.
You're wrong. Architectures simply have to define the __ASSUME_* macros when
all the features they represent are available.
umm, there's two parts here: first, the original report where glibc is broken on
*all* arches, even when you want to put on your "supported" goggles. second:
you're turning the __ASSUME_XXX code into "only works on supported arches". yes,
other arches can disable the __ASSUME_XXX stuff completely, but that sort of
defeats the entire purpose of it.
even if you choose to wrongly ignore the second part (which i imagine you will),
there's still the matter of the first
when i think about it some more, your latest statements are irrelevant. the
problem here is that if the __ASSUME_xxx defines are not defined, then glibc
falls back to the runtime test. as i illustrated in the original summary, this
will create a broken glibc if the linux-headers do not contain the pipe2 syscall
number. the arch in question is irrelevant. that means that the linux-headers
have to be very recent (and in some cases, not even available today let alone at
the time of the glibc-2.9 release).
committed @ http://sourceware.org/ml/libc-alpha/2012-08/msg00424.html