From 3f7d2f029de0c1171ccb03b90461489edf1084b6 Mon Sep 17 00:00:00 2001 From: Roy Marples Date: Tue, 2 Jun 2026 11:19:21 +0100 Subject: [PATCH 1/4] compat: add support for getprogname(3) --- compat/getprogname.c | 92 ++++++++++++++++++++++++++++++++++++++++++++ compat/getprogname.h | 35 +++++++++++++++++ configure | 21 ++++++++++ 3 files changed, 148 insertions(+) create mode 100644 compat/getprogname.c create mode 100644 compat/getprogname.h diff --git a/compat/getprogname.c b/compat/getprogname.c new file mode 100644 index 00000000..759cda54 --- /dev/null +++ b/compat/getprogname.c @@ -0,0 +1,92 @@ +/* + * getprogname: Portable + * SPDX-License-Identifier: BSD-2-Clause + * Copyright (c) 2006-2025 Roy Marples + * All rights reserved + + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include +#include + +#include "common.h" +#include "defs.h" +#include "getprogname.h" + +static char *progname; +static bool progname_free; +static bool progname_atexit; + +static void +freeprogname(void) +{ + if (progname_free) + free(progname); + progname = NULL; +} + +const char * +getprogname(void) +{ +#if defined(__linux__) + const char *p; + + /* Use PATH_MAX + 1 to avoid truncation. */ + if (progname == NULL) { + /* readlink(2) does not append a NULL byte, + * so zero the buffer. */ + if ((progname = calloc(1, PATH_MAX + 1)) == NULL) + return NULL; + progname_free = true; + if (!progname_atexit) { + atexit(freeprogname); + progname_atexit = true; + } + if (readlink("/proc/self/exe", progname, PATH_MAX + 1) == -1) { + free(progname); + progname = NULL; + return NULL; + } + } + if (progname[0] == '[') + return NULL; + p = strrchr(progname, '/'); + if (p == NULL) + return progname; + return p + 1; +#else +#warning "no OS support for getprogname(3)" + UNUSED(progname_atexit); + return PACKAGE; +#endif +} + +void +setprogname(const char *name) +{ + freeprogname(); + progname = UNCONST(name); + progname_free = false; +} diff --git a/compat/getprogname.h b/compat/getprogname.h new file mode 100644 index 00000000..dbbd2b83 --- /dev/null +++ b/compat/getprogname.h @@ -0,0 +1,35 @@ +/* + * getprogname: Portable + * SPDX-License-Identifier: BSD-2-Clause + * Copyright (c) 2006-2025 Roy Marples + * All rights reserved + + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef GETPROGNAME_H +#define GETPROGNAME_H + +const char *getprogname(void); +void setprogname(const char *); + +#endif diff --git a/configure b/configure index b041bfbb..f0025e12 100755 --- a/configure +++ b/configure @@ -1075,6 +1075,27 @@ else fi fi +if [ -z "$GETPROCNAME" ]; then + printf "Testing for getprogname ... " + cat << EOF >_getprogname.c +#include +int main(void) { + return getprogname() ? 0 : 1; +} +EOF + if $XCC _getprogname.c -o _getprogname 2>&3; then + GETPROCNAME=yes + else + GETPROCNAME=no + fi + echo "$GETPROCNAME" + rm -rf _getprogname.* _getprogname +fi +if [ "$GETPROCNAME" = no ]; then + echo "COMPAT_SRCS+= compat/getprogname.c" >>$CONFIG_MK + echo "#include \"compat/getprogname.h\"" \ >>$CONFIG_H +fi + if [ -z "$SETPROCTITLE" ]; then printf "Testing for setproctitle ... " cat << EOF >_setproctitle.c From 113a8253a6ef7824d7940783722d39fc38a02cc2 Mon Sep 17 00:00:00 2001 From: Roy Marples Date: Tue, 2 Jun 2026 11:19:42 +0100 Subject: [PATCH 2/4] Adapt to getprogname being present --- compat/setproctitle.c | 9 +-------- compat/setproctitle.h | 14 -------------- src/logerr.c | 34 +--------------------------------- 3 files changed, 2 insertions(+), 55 deletions(-) diff --git a/compat/setproctitle.c b/compat/setproctitle.c index 322b13fa..dc0e96be 100644 --- a/compat/setproctitle.c +++ b/compat/setproctitle.c @@ -165,7 +165,7 @@ spt_copyargs(int argc, char *argv[]) void setproctitle_init(int argc, char *argv[], char *envp[]) { - char *base, *end, *nul, *tmp; + char *base, *end, *nul; int i, envc, error; /* Try to make sure we got called with main() arguments. */ @@ -200,13 +200,6 @@ setproctitle_init(int argc, char *argv[], char *envp[]) return; } - tmp = strdup(getprogname()); - if (tmp == NULL) { - SPT.error = errno; - return; - } - setprogname(tmp); - error = spt_copyenv(envc, envp); if (error) { SPT.error = error; diff --git a/compat/setproctitle.h b/compat/setproctitle.h index 173e88a4..fb32118e 100644 --- a/compat/setproctitle.h +++ b/compat/setproctitle.h @@ -34,20 +34,6 @@ #endif #endif /* !__printflike */ -/* WEXITSTATUS is defined in stdlib.h which defines free() */ -#ifdef WEXITSTATUS -static inline const char * -getprogname(void) -{ - return "dhcpcd"; -} -static inline void -setprogname(char *name) -{ - free(name); -} -#endif - void setproctitle_init(int, char *[], char *[]); __printflike(1, 2) void setproctitle(const char *, ...); void setproctitle_fini(void); diff --git a/src/logerr.c b/src/logerr.c index c2d318f9..f7e4bfd7 100644 --- a/src/logerr.c +++ b/src/logerr.c @@ -39,6 +39,7 @@ #include #include +#include "config.h" #include "logerr.h" #ifndef LOGERR_SYSLOG_FACILITY @@ -74,35 +75,6 @@ static struct logctx _logctx = { .log_pid = 0, }; -#if defined(__linux__) -/* Poor man's getprogname(3). */ -static char *_logprog; -static const char * -getprogname(void) -{ - const char *p; - - /* Use PATH_MAX + 1 to avoid truncation. */ - if (_logprog == NULL) { - /* readlink(2) does not append a NULL byte, - * so zero the buffer. */ - if ((_logprog = calloc(1, PATH_MAX + 1)) == NULL) - return NULL; - if (readlink("/proc/self/exe", _logprog, PATH_MAX + 1) == -1) { - free(_logprog); - _logprog = NULL; - return NULL; - } - } - if (_logprog[0] == '[') - return NULL; - p = strrchr(_logprog, '/'); - if (p == NULL) - return _logprog; - return p + 1; -} -#endif - #ifndef SMALL /* Write the time, syslog style. month day time - */ static int @@ -518,10 +490,6 @@ logclose(void) #endif closelog(); -#if defined(__linux__) - free(_logprog); - _logprog = NULL; -#endif #ifndef SMALL if (ctx->log_file == NULL) return; From 20718c0119287410d16b89fbba3981518e970d2d Mon Sep 17 00:00:00 2001 From: Roy Marples Date: Tue, 2 Jun 2026 11:56:59 +0100 Subject: [PATCH 3/4] Every linux libc seems to support program_invocation_short_name. --- compat/getprogname.c | 53 ++++++++------------------------------------ configure | 28 ++++++++++++++++++----- 2 files changed, 31 insertions(+), 50 deletions(-) diff --git a/compat/getprogname.c b/compat/getprogname.c index 759cda54..3c213889 100644 --- a/compat/getprogname.c +++ b/compat/getprogname.c @@ -26,67 +26,32 @@ * SUCH DAMAGE. */ -#include -#include -#include -#include +#include +#include "config.h" #include "common.h" #include "defs.h" #include "getprogname.h" static char *progname; -static bool progname_free; -static bool progname_atexit; - -static void -freeprogname(void) -{ - if (progname_free) - free(progname); - progname = NULL; -} const char * getprogname(void) { -#if defined(__linux__) - const char *p; - - /* Use PATH_MAX + 1 to avoid truncation. */ - if (progname == NULL) { - /* readlink(2) does not append a NULL byte, - * so zero the buffer. */ - if ((progname = calloc(1, PATH_MAX + 1)) == NULL) - return NULL; - progname_free = true; - if (!progname_atexit) { - atexit(freeprogname); - progname_atexit = true; - } - if (readlink("/proc/self/exe", progname, PATH_MAX + 1) == -1) { - free(progname); - progname = NULL; - return NULL; - } - } - if (progname[0] == '[') - return NULL; - p = strrchr(progname, '/'); - if (p == NULL) - return progname; - return p + 1; +#if defined(HAVE_PROGRAM_INVOCATION_SHORT_NAME) + if (progname == NULL) + progname = program_invocation_short_name; + return progname; #else #warning "no OS support for getprogname(3)" - UNUSED(progname_atexit); - return PACKAGE; + if (progname == NULL) + progname = PACKAGE; + return progname; #endif } void setprogname(const char *name) { - freeprogname(); progname = UNCONST(name); - progname_free = false; } diff --git a/configure b/configure index f0025e12..e9b8b850 100755 --- a/configure +++ b/configure @@ -1075,7 +1075,7 @@ else fi fi -if [ -z "$GETPROCNAME" ]; then +if [ -z "$GETPROGNAME" ]; then printf "Testing for getprogname ... " cat << EOF >_getprogname.c #include @@ -1084,16 +1084,32 @@ int main(void) { } EOF if $XCC _getprogname.c -o _getprogname 2>&3; then - GETPROCNAME=yes + GETPROGNAME=yes else - GETPROCNAME=no + GETPROGNAME=no fi - echo "$GETPROCNAME" + echo "$GETPROGNAME" rm -rf _getprogname.* _getprogname fi -if [ "$GETPROCNAME" = no ]; then +if [ "$GETPROGNAME" = no ]; then echo "COMPAT_SRCS+= compat/getprogname.c" >>$CONFIG_MK - echo "#include \"compat/getprogname.h\"" \ >>$CONFIG_H + echo "#include \"compat/getprogname.h\"" >>$CONFIG_H + + printf "Testing for program_invocation_short_name ... " + cat << EOF >_getprognameshort.c +#include +int main(void) { + return program_invocation_short_name ? 0 : 1; +} +EOF + if $XCC _getprognameshort.c -o _getprognameshort 2>&3; then + GETPROGNAMESHORT=yes + echo "#define HAVE_PROGRAM_INVOCATION_SHORT_NAME" >>$CONFIG_H + else + GETPROGNAMESHORT=no + fi + echo "$GETPROGNAMESHORT" + rm -rf _getprognameshort.* _getprognameshort fi if [ -z "$SETPROCTITLE" ]; then From 28858df26abbab08e0db7ba9d5234b5d0778e18e Mon Sep 17 00:00:00 2001 From: Roy Marples Date: Tue, 2 Jun 2026 12:45:30 +0100 Subject: [PATCH 4/4] Simplify --- compat/getprogname.c | 8 ++++---- compat/getprogname.h | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/compat/getprogname.c b/compat/getprogname.c index 3c213889..afded20f 100644 --- a/compat/getprogname.c +++ b/compat/getprogname.c @@ -1,5 +1,5 @@ /* - * getprogname: Portable + * getprogname: compat * SPDX-License-Identifier: BSD-2-Clause * Copyright (c) 2006-2025 Roy Marples * All rights reserved @@ -27,13 +27,13 @@ */ #include +#include #include "config.h" -#include "common.h" #include "defs.h" #include "getprogname.h" -static char *progname; +static const char *progname; const char * getprogname(void) @@ -53,5 +53,5 @@ getprogname(void) void setprogname(const char *name) { - progname = UNCONST(name); + progname = name; } diff --git a/compat/getprogname.h b/compat/getprogname.h index dbbd2b83..bf52eee3 100644 --- a/compat/getprogname.h +++ b/compat/getprogname.h @@ -1,5 +1,5 @@ /* - * getprogname: Portable + * getprogname: compat * SPDX-License-Identifier: BSD-2-Clause * Copyright (c) 2006-2025 Roy Marples * All rights reserved