Why is the getprogname() function declared in "getprogname.h"? All platforms that have this function — Mac OS X, FreeBSD, NetBSD, OpenBSD >= 5.4, Solaris >= 11, Cygwin, Android API level >= 21 — declare it in <stdlib.h>. It thus appears very unlikely that, if glibc ever adds this function, they would choose to declare it in a header file other than <stdlib.h>.
I can find no rationale in the mailing list archive from 2016. So, it makes sense to move the declaration of this function to <stdlib.h>. For a transition period, "getprogname.h" can continue to exist, but will emit a deprecation warning. 2023-01-21 Bruno Haible <br...@clisp.org> getprogname: Move declaration from "getprogname.h" to <stdlib.h>. * lib/stdlib.in.h (getprogname): New declaration. * lib/getprogname.h: Add deprecation warning. (getprogname): Remove declaration. * lib/getprogname.c: Include <stdlib.h> instead of getprogname.h. * m4/stdlib_h.m4 (gl_STDLIB_H): Test whether getprogname is declared. (gl_STDLIB_H_REQUIRE_DEFAULTS): Initialize GNULIB_GETPROGNAME. (gl_STDLIB_H_DEFAULTS): Initialize HAVE_GETPROGNAME. * m4/getprogname.m4 (gl_PREREQ_GETPROGNAME): New macro, extracted from gl_FUNC_GETPROGNAME. Set HAVE_GETPROGNAME. (gl_FUNC_GETPROGNAME): Remove code that was moved to gl_PREREQ_GETPROGNAME. * modules/stdlib (Makefile.am): Substitute GNULIB_GETPROGNAME and HAVE_GETPROGNAME. * modules/getprogname (Depends-on): Add stdlib. (configure.ac): Define a module indicator. Invoke gl_PREREQ_GETPROGNAME. (Makefile.am): Don't compile getprogname.c if not needed. (Include): List <stdlib.h> instead of getprogname.h. * tests/test-getprogname.c: Include <stdlib.h> instead of getprogname.h. * NEWS: Mention the change. * lib/argmatch.c: Don't include getprogname.h. * lib/c-stack.c: Likewise. * lib/error.c: Likewise. * lib/git-merge-changelog.c: Likewise. diff --git a/NEWS b/NEWS index b54781a6f8..e8cc0c4ae7 100644 --- a/NEWS +++ b/NEWS @@ -74,6 +74,9 @@ User visible incompatible changes Date Modules Changes +2023-01-21 getprogname The include file is changed from "getprogname.h" + to <stdlib.h>. + 2023-01-15 stdalign This module is deprecated. Use alignasof instead. 2023-01-07 timer_time Link with $(TIMER_TIME_LIB) instead of diff --git a/lib/argmatch.c b/lib/argmatch.c index 1e5b77bf32..9cddb37d69 100644 --- a/lib/argmatch.c +++ b/lib/argmatch.c @@ -32,7 +32,6 @@ #include "error.h" #include "quotearg.h" -#include "getprogname.h" #if USE_UNLOCKED_IO # include "unlocked-io.h" diff --git a/lib/c-stack.c b/lib/c-stack.c index 079d86846d..f0078d51ad 100644 --- a/lib/c-stack.c +++ b/lib/c-stack.c @@ -52,7 +52,6 @@ #include <sigsegv.h> #include "exitfail.h" -#include "getprogname.h" #include "idx.h" #include "ignore-value.h" diff --git a/lib/error.c b/lib/error.c index 6875f134ed..ef4372875f 100644 --- a/lib/error.c +++ b/lib/error.c @@ -42,8 +42,6 @@ # define USE_UNLOCKED_IO 0 # define _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD(a, b) # define _GL_ARG_NONNULL(a) -#else -# include "getprogname.h" #endif #if USE_UNLOCKED_IO diff --git a/lib/getprogname.c b/lib/getprogname.c index 32c96043b0..279d79f012 100644 --- a/lib/getprogname.c +++ b/lib/getprogname.c @@ -16,11 +16,10 @@ #include <config.h> -/* Specification. */ -#include "getprogname.h" +/* Specification. Also get __argv declaration. */ +#include <stdlib.h> #include <errno.h> /* get program_invocation_name declaration */ -#include <stdlib.h> /* get __argv declaration */ #ifdef _AIX # include <unistd.h> @@ -53,13 +52,12 @@ #if defined __SCO_VERSION__ || defined __sysv5__ # include <fcntl.h> -# include <stdlib.h> # include <string.h> #endif #include "basename-lgpl.h" -#ifndef HAVE_GETPROGNAME /* not Mac OS X, FreeBSD, NetBSD, OpenBSD >= 5.4, Cygwin */ +#ifndef HAVE_GETPROGNAME /* not Mac OS X, FreeBSD, NetBSD, OpenBSD >= 5.4, Solaris >= 11, Cygwin, Android API level >= 21 */ char const * getprogname (void) { diff --git a/lib/getprogname.h b/lib/getprogname.h index 4b9126f9d7..13314f21e2 100644 --- a/lib/getprogname.h +++ b/lib/getprogname.h @@ -19,22 +19,8 @@ #include <stdlib.h> -#ifdef __cplusplus -extern "C" { -#endif - -/* Return the base name of the executing program. - On native Windows this will usually end in ".exe" or ".EXE". */ -#ifndef HAVE_GETPROGNAME -extern char const *getprogname (void) -# ifdef HAVE_DECL_PROGRAM_INVOCATION_NAME - _GL_ATTRIBUTE_PURE -# endif - ; -#endif - -#ifdef __cplusplus -} +#if __GNUC__ || (__clang_major__ >= 4) +# warning "The include file getprogname.h is deprecated. Use <stdlib.h> instead." #endif #endif diff --git a/lib/git-merge-changelog.c b/lib/git-merge-changelog.c index 5708dd5eac..67a932c5df 100644 --- a/lib/git-merge-changelog.c +++ b/lib/git-merge-changelog.c @@ -176,7 +176,6 @@ #include "minmax.h" #include "c-strstr.h" #include "fwriteerror.h" -#include "getprogname.h" #define ASSERT(expr) \ do \ diff --git a/lib/stdlib.in.h b/lib/stdlib.in.h index b79e5f7096..55f31feb42 100644 --- a/lib/stdlib.in.h +++ b/lib/stdlib.in.h @@ -430,6 +430,26 @@ _GL_WARN_ON_USE (getloadavg, "getloadavg is not portable - " # endif #endif +#if @GNULIB_GETPROGNAME@ +/* Return the base name of the executing program. + On native Windows this will usually end in ".exe" or ".EXE". */ +# if !@HAVE_GETPROGNAME@ +# ifdef HAVE_DECL_PROGRAM_INVOCATION_NAME +_GL_FUNCDECL_SYS (getprogname, const char *, (void) _GL_ATTRIBUTE_PURE); +# else +_GL_FUNCDECL_SYS (getprogname, const char *, (void)); +# endif +# endif +_GL_CXXALIAS_SYS (getprogname, const char *, (void)); +_GL_CXXALIASWARN (getprogname); +#elif defined GNULIB_POSIXCHECK +# undef getprogname +# if HAVE_RAW_DECL_GETPROGNAME +_GL_WARN_ON_USE (getprogname, "getprogname is unportable - " + "use gnulib module getprogname for portability"); +# endif +#endif + #if @GNULIB_GETSUBOPT@ /* Assuming *OPTIONP is a comma separated list of elements of the form "token" or "token=value", getsubopt parses the first of these elements. diff --git a/m4/getprogname.m4 b/m4/getprogname.m4 index 7c306c80a9..0a4b9c874a 100644 --- a/m4/getprogname.m4 +++ b/m4/getprogname.m4 @@ -5,12 +5,19 @@ # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 5 +# serial 6 AC_DEFUN([gl_FUNC_GETPROGNAME], [ - AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS]) gl_CHECK_FUNCS_ANDROID([getprogname], [[#include <stdlib.h>]]) + if test $ac_cv_func_getprogname = no; then + HAVE_GETPROGNAME=0 + fi +]) + +AC_DEFUN([gl_PREREQ_GETPROGNAME], +[ + AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS]) AC_CHECK_FUNCS_ONCE([getexecname]) ac_found=0 AC_CHECK_DECLS([program_invocation_name], [ac_found=1], [], diff --git a/m4/stdlib_h.m4 b/m4/stdlib_h.m4 index e96be22f58..f1f2d04047 100644 --- a/m4/stdlib_h.m4 +++ b/m4/stdlib_h.m4 @@ -1,4 +1,4 @@ -# stdlib_h.m4 serial 66 +# stdlib_h.m4 serial 67 dnl Copyright (C) 2007-2023 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -23,7 +23,7 @@ AC_DEFUN_ONCE([gl_STDLIB_H], # include <random.h> #endif ]], [_Exit aligned_alloc atoll canonicalize_file_name free - getloadavg getsubopt grantpt + getloadavg getprogname getsubopt grantpt initstate initstate_r mbtowc mkdtemp mkostemp mkostemps mkstemp mkstemps posix_memalign posix_openpt ptsname ptsname_r qsort_r random random_r reallocarray realpath rpmatch secure_getenv setenv @@ -73,6 +73,7 @@ AC_DEFUN([gl_STDLIB_H_REQUIRE_DEFAULTS], gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_CANONICALIZE_FILE_NAME]) gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FREE_POSIX]) gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_GETLOADAVG]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_GETPROGNAME]) gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_GETSUBOPT]) gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_GRANTPT]) gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MALLOC_GNU]) @@ -130,6 +131,7 @@ AC_DEFUN([gl_STDLIB_H_DEFAULTS], HAVE_DECL_FCVT=1; AC_SUBST([HAVE_DECL_FCVT]) HAVE_DECL_GCVT=1; AC_SUBST([HAVE_DECL_GCVT]) HAVE_DECL_GETLOADAVG=1; AC_SUBST([HAVE_DECL_GETLOADAVG]) + HAVE_GETPROGNAME=1; AC_SUBST([HAVE_GETPROGNAME]) HAVE_GETSUBOPT=1; AC_SUBST([HAVE_GETSUBOPT]) HAVE_GRANTPT=1; AC_SUBST([HAVE_GRANTPT]) HAVE_INITSTATE=1; AC_SUBST([HAVE_INITSTATE]) diff --git a/modules/getprogname b/modules/getprogname index 94e55186d5..dadbffbbd6 100644 --- a/modules/getprogname +++ b/modules/getprogname @@ -7,18 +7,26 @@ lib/getprogname.c m4/getprogname.m4 Depends-on: -basename-lgpl -extensions -open +stdlib +basename-lgpl [test $HAVE_GETPROGNAME = 0] +extensions [test $HAVE_GETPROGNAME = 0] +open [test $HAVE_GETPROGNAME = 0] configure.ac: gl_FUNC_GETPROGNAME +gl_CONDITIONAL([GL_COND_OBJ_GETPROGNAME], [test $HAVE_GETPROGNAME = 0]) +AM_COND_IF([GL_COND_OBJ_GETPROGNAME], [ + gl_PREREQ_GETPROGNAME +]) +gl_STDLIB_MODULE_INDICATOR([getprogname]) Makefile.am: -lib_SOURCES += getprogname.h getprogname.c +if GL_COND_OBJ_GETPROGNAME +lib_SOURCES += getprogname.c +endif Include: -"getprogname.h" +<stdlib.h> License: LGPLv2+ diff --git a/modules/stdlib b/modules/stdlib index 45d8f59331..1e6e18f53c 100644 --- a/modules/stdlib +++ b/modules/stdlib @@ -42,6 +42,7 @@ stdlib.h: stdlib.in.h $(top_builddir)/config.status $(CXXDEFS_H) \ -e 's/@''GNULIB_CANONICALIZE_FILE_NAME''@/$(GNULIB_CANONICALIZE_FILE_NAME)/g' \ -e 's/@''GNULIB_FREE_POSIX''@/$(GNULIB_FREE_POSIX)/g' \ -e 's/@''GNULIB_GETLOADAVG''@/$(GNULIB_GETLOADAVG)/g' \ + -e 's/@''GNULIB_GETPROGNAME''@/$(GNULIB_GETPROGNAME)/g' \ -e 's/@''GNULIB_GETSUBOPT''@/$(GNULIB_GETSUBOPT)/g' \ -e 's/@''GNULIB_GRANTPT''@/$(GNULIB_GRANTPT)/g' \ -e 's/@''GNULIB_MALLOC_GNU''@/$(GNULIB_MALLOC_GNU)/g' \ @@ -91,6 +92,7 @@ stdlib.h: stdlib.in.h $(top_builddir)/config.status $(CXXDEFS_H) \ -e 's|@''HAVE_DECL_FCVT''@|$(HAVE_DECL_FCVT)|g' \ -e 's|@''HAVE_DECL_GCVT''@|$(HAVE_DECL_GCVT)|g' \ -e 's|@''HAVE_DECL_GETLOADAVG''@|$(HAVE_DECL_GETLOADAVG)|g' \ + -e 's|@''HAVE_GETPROGNAME''@|$(HAVE_GETPROGNAME)|g' \ -e 's|@''HAVE_GETSUBOPT''@|$(HAVE_GETSUBOPT)|g' \ -e 's|@''HAVE_GRANTPT''@|$(HAVE_GRANTPT)|g' \ -e 's|@''HAVE_INITSTATE''@|$(HAVE_INITSTATE)|g' \ diff --git a/tests/test-getprogname.c b/tests/test-getprogname.c index 0c1f1fcfa7..168c0cb91c 100644 --- a/tests/test-getprogname.c +++ b/tests/test-getprogname.c @@ -16,7 +16,8 @@ #include <config.h> -#include "getprogname.h" +#include <stdlib.h> + #include <string.h> #include <assert.h>