Use strlcpy with >=glibc-2.38
thesamesam opened this issue · 9 comments
glibc-2.38 includes strlcpy (and strlcat), musl has both for quite some time as well, but Makefile.linux
currently unconditionally builds missing/strlcpy.c
on Linux.
Please consider detecting a system implementation of strlcpy and using that if available.
It appears that RedHat submitted this change but after the EL 9 release! This is a shame because it means that RedHat based systems won't get this feature for another 3-4 years.
Thanks for pointing this out, I will wait to see how other projects handle this.
Reopening. strlcpy(3) is becoming more widely available (Fedora 39 for example). I'll investigate the best way to detect the system implementation.
It appears that the _DEFAULT_SOURCE
macro was defined for using BSD/misc functions
https://sourceware.org/git/?p=glibc.git;a=commit;h=c688b4196014e0162a1ff11120f6c9516be0c6cb
musl still needs _GNU_SOURCE
or _BSD_SOURCE
for it for now (until it's in a POSIX release officially), so I'd just use _GNU_SOURCE
still for now?
@thesamesam thanks for tip! I'll add _GNU_SOURCE
back to the build
Alpine Linux 3.19.0 does not seem to need _GNU_SOURCE
. Is there something Alpine does differently to enable this feature in musl?
alpine:~/git/entr$ ldd entr
/lib/ld-musl-x86_64.so.1 (0x7fc6356bb000)
libc.musl-x86_64.so.1 => /lib/ld-musl-x86_64.so.1 (0x7fc6356bb000)
I think gcc
and clang
default to -std=gnu11
(or gnu17
) which implicitly enables _GNU_SOURCE
.
If you try with make CFLAGS="-std=c99"
or similar, you should get a failure. Adding _GNU_SOURCE
fixes that.
For me, Clang does this on musl:
# printf '#include <string.h>\r\nint main() {}' | clang-x c -E - -O2 -dM | grep -i _SOURCE
#define _BSD_SOURCE 1
#define _XOPEN_SOURCE 700
musl's features.h
does:
#if defined(_ALL_SOURCE) && !defined(_GNU_SOURCE)
#define _GNU_SOURCE 1
#endif
#if defined(_DEFAULT_SOURCE) && !defined(_BSD_SOURCE)
#define _BSD_SOURCE 1
#endif
#if !defined(_POSIX_SOURCE) && !defined(_POSIX_C_SOURCE) \
&& !defined(_XOPEN_SOURCE) && !defined(_GNU_SOURCE) \
&& !defined(_BSD_SOURCE) && !defined(__STRICT_ANSI__)
#define _BSD_SOURCE 1
#define _XOPEN_SOURCE 700
#endif
So, if nothing is defined, it does _BSD_SOURCE
and _XOPEN_SOURCE 700
by default. Maybe we're fine then :)
(It's probably better to explicitly state what we want though with _GNU_SOURCE
as that covers both musl and glibc and any -std=
value the compiler might default to.)
Ah exactly right.
In this case I also want to add -D_GNU_SOURCE
to the configure script. Also should probably use cc
as the compiler