tech-pkg archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Some rambling about strdup()'s standard and other standards issues (was: CVS commit: pkgsrc/security/mit-krb5)



Tobias Nygren <tnn%NetBSD.org@localhost> wrote:
>
> On modern Linux it will fail due to missing strdup(3) if you set
> strict C99 mode. It needs to be either gnu99 or c99 with -D_GNU_SOURCE

I can understand the need for '-D_GNU_SOURCE' and/or some equivalent of
the standard POSIX visibility macros, but how can "-std=gnu99" alone
make any difference?  I have a suspicion!

They could be triggering the difference in default visibility based on
__STRICT_ANSI__ being defined or not.  (it's not with -std=gnuNN, but it
is define with -std=cNN)

There's also a _DEFAULT_SOURCE macro for glibc, but there's a caveat
about "a strict conformance option" that may cause some features to be
disabled.

So, maybe on linux turning on "-std=c99", and thus implicitly defining
__STRICT_ANSI__, also changes the default for _DEFAULT_SOURCE to the
effect that it kills off visibility of POSIX extensions, i.e. those
(g)libc things beyond ISO C?


The rest is mostly rambling, so TL/DR it if you wish....  Except maybe
the very last bit.


At Thu, 01 May 2025 07:47:18 -0400, Greg Troxel <gdt%lexort.com@localhost> wrote:
Subject: Re: CVS commit: pkgsrc/security/mit-krb5
>
> Strictly, a package that uses POSIX should define some POSIX visibility
> define, but that hides everything else, and the right set of defines is
> non-portable and that gets silly fast.  My view is that some fairly
> recent POSIX (but not necessarily the very latest) should be available
> by default,

On NetBSD POSIX compatibility is available by default because by default
_NETBSD_SOURCE is defined, right?  (and NetBSD by default offers POSIX
stuff) That seems to be what <sys/featuretest.h> says.

(Probably intro(3) should say things about _NETBSD_SOURCE and its more
official siblings -- maybe along the lines of what the glibc
documentation says about such things, or at least what's in the comments
in <sys/featuretest.h>.)

Should code expect a system default to be "POSIX", or should it be
explicit?

I suppose that means code that hopes to be portable has to define both
the "standard" feature test macros, as well as all those system-specific
ones for all the systems it expects to work on.


> and that it's seriously buggy of Linux to hide strdup(3), required
> since 2001. I really don't understand what the rationale is.

Regarding the "required since 2001" part vs. what linux/glibc does --
It's also very confusing to me!

Strdup() arguably goes further back than 2001, though there seems to be
some confusion as to whether it may have been an X/Open extension (in
"standards" terms) or not.

strdup() is in the SVID, as of Issue#4, dated June 15, 1995, and is
there as a primary "Level 1" interface in string(BA_LIB) for <string.h>

    http://www.sco.com/developers/devspecs/vol1a.pdf

The "The Single UNIX Specification, Version 2", which seems to mostly
correspond to POSIX.1-1996 has strdup() also right in there with no
caveats, and also no history or rationale -- this definitely also
predates POSIX.1-2001.

    https://pubs.opengroup.org/onlinepubs/7908799/index.html

However I don't think strdup() was in pure POSIX.1-1996.  It's hard to
tell for sure as I don't have a real copy, but FIPS-151 doesn't mention
it.

In any case the OpenGroup "Issue 6" spec definitely has strdup(), and it
refers to "IEEE Std 1003.1-2001" as the origin of this definition.
However they say it was moved from being an _XOPEN_SOURCE extension
"first released in Issue 4, Version 2", and "Moved to BASE" in the
previous version, "Issue 5".

    https://pubs.opengroup.org/onlinepubs/007904975/functions/strdup.html

Hmmm....

In the current edition, "Issue 8", aka "IEEE Std 1003.1-2024 Edition"
there is a change history section, but it seems self-contradictory:

    https://pubs.opengroup.org/onlinepubs/9699919799/
    https://pubs.opengroup.org/onlinepubs/9799919799/functions/strdup.html

How can it be "moved to [the] base" twice?  (Once in OpenGroup and once
in the source IEEE docs?)

Anyway, some of this confusion may be why the linux manual page seems to
point to POSIX.1-2008 (>=200809L)....

   strdup():
            _XOPEN_SOURCE >= 500
                || /* Since glibc 2.12: */ _POSIX_C_SOURCE >= 200809L
                || /* glibc <= 2.19: */ _BSD_SOURCE || _SVID_SOURCE

   STANDARDS
        strdup()
        strndup()
               POSIX.1-2008.

    HISTORY
        strdup()
               SVr4, 4.3BSD-Reno, POSIX.1-2001.

They seem to limit strdup() to X/Open > Issue 5 or P1003.1 >= 2008.
Perhaps that's one way to read what's in the latest OpenGroup doc?



As an even deeper digression I note that NetBSD's strdup(3) history is
wrong in claiming 4.4BSD origins, perhaps because the final 4.4BSD
version of strdup(3) makes the same mistake.  strdup() was added to
strings.h on 12/12/88, so the linux manual page is more correct there.
(Dunno why they specify "-Reno" -- it would have been in all 4.3
releases.)  OpenBSD's manual page dives deeper into the history:

    A strdup() macro was first used in the 4.1cBSD debugger, dbx.  It
    was rewritten as a C function for the 4.3BSD inetd(8) and first
    appeared in the C library of 4.3BSD-Reno.


> I find it odd and not really ok that gnu99 turns on strdup.  That's a
> standard library procedure, not a language feature.

The whole point of these "libc" feature test macros is to allow backward
compatibility for older code that might use newer reserved symbols for
internal purposes -- but it is a stretch to expect legacy code to use
them as that means that it then has to somehow know that it has to
define some macro to protect itself from the future.

Glibc seems to take the conservative approach and starts out at the
oldest supported standard and only exposes newer symbols IFF the code
declares it's ready for them.  That seems to follow the rationale given
in their documentation.


> I also find it odd and not really ok that gcc15 is defaulting to C23 (or
> probably gnu23).

That's not surprising to me -- GCC developers seem to like other people
to (also) eat their dog's breakfast on their behalf / along with them.

"Obviously if you're using this new compiler you're working with the
latest and greatest of everything, right?"


>  Any program that needs C23 needs to check --std=c23
> and add it, to built with other than gcc15, and such aggressive
> defaulting only serves to encourage people that don't pay attention and
> code to the environment in front of them.  But we of course can't fix
> that.

Maybe GCC should be taught to just throw an error if there's no '-std='
given!  :-)

I wonder what the ISO committee would think of that requirement.  It
probably wouldn't survive first reading as it seems the committee is
ruled by compiler developers these days.


But note NetBSD defauls to defining _NETBSD_SOURCE, so isn't that also
"aggressive defaulting"?  :-)

Should NetBSD kill off _NETBSD_SOURCE if __STRICT_ANSI__ is defined?  Is
that really a good hint that the code will also define something like
_POSIX_SOURCE if it also wants to use POSIX "extensions"?

--
					Greg A. Woods <gwoods%acm.org@localhost>

Kelowna, BC     +1 250 762-7675           RoboHack <woods%robohack.ca@localhost>
Planix, Inc. <woods%planix.com@localhost>     Avoncote Farms <woods%avoncote.ca@localhost>

Attachment: pgpsntq1hn0ZO.pgp
Description: OpenPGP Digital Signature



Home | Main Index | Thread Index | Old Index