eradman/entr

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

Implemented in commit 1d7e1f3

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