[Toybox] [musl] [PATCH 0/4] Fix function definitions.

Rob Landley rob at landley.net
Fri Mar 9 07:11:05 PST 2012


On 03/09/2012 03:16 AM, Georgi Chorbadzhiyski wrote:
> On 3/9/12 10:33 AM, Rich Felker wrote:
>> On Fri, Mar 09, 2012 at 10:21:04AM +0200, Georgi Chorbadzhiyski wrote:
>>> Subject: Re: [musl] [PATCH 0/4] Fix function definitions.
>>
>> I think you mean declarations. :-)
>>
>>> Hmm...it seems this is not enough. See include/unistd.h
>>>
>>> #ifdef _GNU_SOURCE
>>> int brk(void *);
>>> void *sbrk(intptr_t);
>>> pid_t forkall(void);
>>> int vhangup(void);
>>> int getpagesize(void);
>>> int usleep(unsigned);
>>> unsigned ualarm(unsigned, unsigned);
>>> int setgroups(size_t, const gid_t []);
>>> int setresuid(uid_t, uid_t, uid_t);
>>> int setresgid(gid_t, gid_t, gid_t);
>>> char *get_current_dir_name(void);
>>> #endif

Why are you doing feature test macros at _all_ in a 2012 Linux libc?  If
you don't #define any of them (which most code doesn't), you get (from
/usr/lib/features.h):

/* If nothing (other than _GNU_SOURCE) is defined,
   define _BSD_SOURCE and _SVID_SOURCE.  */
#if (!defined __STRICT_ANSI__ && !defined _ISOC99_SOURCE && \
     !defined _POSIX_SOURCE && !defined _POSIX_C_SOURCE && \
     !defined _XOPEN_SOURCE && !defined _XOPEN_SOURCE_EXTENDED && \
     !defined _BSD_SOURCE && !defined _SVID_SOURCE)
# define _BSD_SOURCE    1
# define _SVID_SOURCE   1
#endif

and then a bit later...

/* If none of the ANSI/POSIX macros are defined, use POSIX.1 and POSIX.2
   (and IEEE Std 1003.1b-1993 unless _XOPEN_SOURCE is defined).  */
#if ((!defined __STRICT_ANSI__ || (_XOPEN_SOURCE - 0) >= 500) && \
     !defined _POSIX_SOURCE && !defined _POSIX_C_SOURCE)
# define _POSIX_SOURCE  1
# if defined _XOPEN_SOURCE && (_XOPEN_SOURCE - 0) < 500
#  define _POSIX_C_SOURCE       2
# elif defined _XOPEN_SOURCE && (_XOPEN_SOURCE - 0) < 600
#  define _POSIX_C_SOURCE       199506L
# elif defined _XOPEN_SOURCE && (_XOPEN_SOURCE - 0) < 700
#  define _POSIX_C_SOURCE       200112L
# else
#  define _POSIX_C_SOURCE       200809L
# endif
# define __USE_POSIX_IMPLICITLY 1
#endif

I.E. you get _BSD_SOURCE, _SVID_SOURCE, _POSIX_SOURCE, and
_POSIX_C_SOURCE=200809L all #defined _FOR_ you if you just avoid
mentioning any of these macros ever.

And that's exactly what my code did before Georgi tried to build it
against musl and suddenly that didn't work anymore because musl is weird.

(A sane development team would have implemented _negative_ macros, ala
_ANSI_ONLY, to switch stuff _off_.)

>>> Most of the above according to their man pages should be defined if
>>> _BSD_SOURCE is set.
>>
>> At present musl makes no attempt to support(*) the _BSD_SOURCE or
>> _SVID_SOURCE feature test macros; every nonstandard (non-POSIX)
>> extention offered by glibc is grouped together under _GNU_SOURCE, and
>> this works for musl because (unlike with glibc), musl's _GNU_SOURCE
>> only enables features; it does not alter standard interfaces like
>> strerror_r or basename to be broken GNU versions of the functions.

A lot of those "nonstandard" things were in BSD circa 1982, before the
FSF even existed.

I do not write code for Gnu Hurd.  I write code for Linux.  Saying
"GNU/Linux" is an obvious oxymoron because the licenses aren't even
compatible: GNU is GPLv3 (only), Linux is GPLv2 (only), they can't share
code with each other.

I don't care about granularity, I just want my code to work.  But I
refuse to #define _ALL_HAIL_RICHARD_STALLMAN as a condition of using
standard Linux functions.

I will not say _GNU_SOURCE when implementing a project that has nothing
whatsoever to do with the FSF's GNU project, and acts to replace large
chunks of its' userspace.

>> I think there's a good (nontrivial) discussion to be had about whether
>> it's worthwhile to have the _BSD_SOURCE and _SVID_SOURCE feature test
>> macros supported in musl.

Given that the "nothing is #defined" behavior gives you most of this
anyway on both glibc and uClibc, why musl is bothering with it at _all_
is kinda inexplicable to me.

Yes, I'm aware that Posix 2008 mentions feature test macros:

http://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html#tag_15_02

And silently ignoring them is reasonably compliant behavior.  (You can
even be technically compliant with Item 3 under _POSIX_C_SOURCE if you
consider __linux__ a feature test macro.  It's got the double underscore!)

>> The main benefit I can see is that
>> applications which define _BSD_SOURCE or _SVID_SOURCE in their default
>> CFLAGS for the sake of getting certain important traditional
>> interfaces (like MAP_ANONYMOUS) but without bringing in broken GNU
>> behavior could perhaps be made to work out-of-the-box on musl without
>> manually adding -D_GNU_SOURCE to the CFLAGS. On the other hand, since
>> musl's _GNU_SOURCE is "non-destructive", I'm not sure that's a huge
>> benefit.

It's not non-destructive to a program that didn't #define _any_ of this
stuff.  It requires you to #define stuff other libc's don't to get what
should be default behavior.

>> (*) _BSD_SOURCE appears in some places in musl's headers now, but that
>> was due to a (rather ill-thought-out) attempt to add some BSD
>> functions like strlcpy which glibc refuses to support, and avoid
>> making them visible when just _GNU_SOURCE is used. I'm largely
>> convinced this approach was a mistake, but how it should work is still
>> a topic for discussion...
> 
> Umm, like I expected all those declarations open a big can of worms :(

Allow me to introduce you to:

  cc -E -dM - < /dev/null

Which shows you all the compiler builtin #defines.  See __linux__ in
that list?  If you _have_ to test for something, what's wrong with
testing for __linux__?

>>> Should the headers be filled with feature checks (that would make them
>>> quite ugly) or assume we have _GNU_SOURCE defined and remove any
>>> _GNU_SOURCE
>>> checks?
>>
>> I'm confused what you mean by "assume we have _GNU_SOURCE defined".
> 
> Well, ignore my suggestion. I was thinking of removing most _GNU_SOURCE
> checks in headers (except for pure GNU extensions) but reading what you
> wrote above I remembered what PITA feature_macros were. Unfortunately
> it seems that defining _GNU_SOURCE to get the kitchen sink is easier...

It's also wrong.  And it means that Musl can't build code that not just
glibc and uClibc can build out of the box, but BSD can too.  (chroot()
was _not_ invented by the gnu/dammit project.)

The feature test macros actually means that musl goes out of its _way_
not to build them. You have extra code that's just there to break stuff.

Rob



More information about the Toybox mailing list