the kernel wrongly expects the cmsg length field to be size_t instead
of socklen_t. in order to work around the issue, we have to impose a
length limit and copy to a local buffer. the length limit should be
more than sufficient for any real-world use; these headers are only
used for passing file descriptors and permissions between processes
over unix sockets.
on arm, the location of the saved-signal-mask flag and mask were off
by one between sigsetjmp and siglongjmp, causing incorrect behavior
restoring the signal mask. this is because the siglongjmp code assumed
an extra slot was in the non-sig jmp_buf for the flag, but arm did not
have this. now, the extra slot is removed for all archs since it was
useless.
also, arm eabi requires jmp_buf to have 8-byte alignment. we achieve
that using long long as the type rather than with non-portable gcc
attribute tags.
on old kernels, there's no way to detect errors; we must assume
negative syscall return values are pgrp ids. but if the F_GETOWN_EX
fcntl works, we can get a reliable answer.
this is actually rather ugly, and would get even uglier if we ever
want to support further feature test macros. at some point i may
factor the bits headers into separate files for C base, POSIX base,
and nonstandard extensions (the only distinctions that seem to matter
now) and then the logic for which to include can go in the main header
rather than being duplicated for each arch. the downside of this is
that it would result in more files having to be opened during
compilation, so as long as the ugliness does not grow, i'm inclined to
leave it alone for now.
fcntl values 1024 and up are universal, arch-independent. later I'll
add some of the other linux-specific ones for notify, leases, pipe
size, etc. here too.
DECIMAL_DIG is not the same as LDBL_DIG
type_DIG is the maximimum number of decimal digits that can survive a
round trip from decimal to type and back to decimal.
DECIMAL_DIG is the minimum number of decimal digits required in order
for any floating point type to survive the round trip to decimal and
back, and it is generally larger than LDBL_DIG. since the exact
formula is non-trivial, and defining it larger than necessary may be
legal but wasteful, just define the right value in bits/float.h.
the old abi was intended to duplicate glibc's abi at the expense of
being ugly and slow, but it turns out glib was not even using that abi
except on non-gcc-compatible compilers (which it doesn't even support)
and was instead using an exceptions-in-c/unwind-based approach whose
abi we could not duplicate anyway without nasty dwarf2/unwind
integration.
the new abi is copied from a very old glibc abi, which seems to still
be supported/present in current glibc. it avoids all unwinding,
whether by sjlj or exceptions, and merely maintains a linked list of
cleanup functions to be called from the context of pthread_exit. i've
made some care to ensure that longjmp out of a cleanup function should
work, even though it is not required to.
this change breaks abi compatibility with programs which were using
pthread cancellation, which is unfortunate, but that's why i'm making
the change now rather than later. considering that most pthread
features have not been usable until recently anyway, i don't see it as
a major issue at this point.
it's a keyword in c++ (wtf). i'm not sure this is the cleanest
solution; it might be better to avoid ever defining __NEED_wchar_t on
c++. but in any case, this works for now.
actually this is just to avoid gcc being stupid and refusing to inline
the function version, even when the size cost is essentially identical
whether it's inlined or not.
the arm syscall abi requires 64-bit arguments to be aligned on an even
register boundary. these new macros facilitate meeting the abi
requirement without imposing significant ugliness on the code.
really wchar_t should never vary, but the ARM EABI defines it as an
unsigned 32-bit int instead of a signed one, and gcc follows this
nonsense. thus, to give a conformant environment, we have to follow
(otherwise L""[0] and L'\0' would be 0U rather than 0, but the
application would be unaware due to a mismatched definition for
WCHAR_MIN and WCHAR_MAX, and Bad Things could happen with respect to
signed/unsigned comparisons, promotions, etc.).
fortunately no rules are imposed by the C standard on the relationship
between wchar_t and wint_t, and WEOF has type wint_t, so we can still
make wint_t always-signed and use -1 for WEOF.
this port assumes eabi calling conventions, eabi linux syscall
convention, and presence of the kernel helpers at 0xffff0f?0 needed
for threads support. otherwise it makes very few assumptions, and the
code should work even on armv4 without thumb support, as well as on
systems with thumb interworking. the bits headers declare this a
little endian system, but as far as i can tell the code should work
equally well on big endian.
some small details are probably broken; so far, testing has been
limited to qemu/aboriginal linux.