diff mbox series

[libgpiod,v2,1/2] tools: use getprogname() when available to remove dependency on glibc

Message ID 20230225031235.3886280-2-benl@squareup.com
State New
Headers show
Series tools: fix compile issues when GNU extensions are not present | expand

Commit Message

Benjamin Li Feb. 25, 2023, 3:12 a.m. UTC
Platforms like Bionic libc don't have program_invocation_[short_]name,
which is a GNU extension. Use getprogname() from stdlib.h, another
widely agreed extension, when it's available.

It seemed a little heavyweight to add gnulib to this project's autotools
set-up just for making one function portable, so I've just added the
portabilty shim to tools-common.c for the moment.

Signed-off-by: Benjamin Li <benl@squareup.com>
---
 configure.ac         | 11 ++++++++---
 tools/gpiodetect.c   |  4 ++--
 tools/gpioget.c      |  4 ++--
 tools/gpioinfo.c     |  4 ++--
 tools/gpiomon.c      |  4 ++--
 tools/gpionotify.c   |  4 ++--
 tools/gpioset.c      |  4 ++--
 tools/tools-common.c | 16 +++++++++-------
 tools/tools-common.h |  4 +++-
 9 files changed, 32 insertions(+), 23 deletions(-)

Comments

Benjamin Li Feb. 27, 2023, 9 p.m. UTC | #1
On 2/25/23 4:12 AM, andy.shevchenko@gmail.com wrote:
>>  	printf("%s (libgpiod) v%s\n",
>> -	       program_invocation_short_name, gpiod_api_version());
>> +	       getprogname(), gpiod_api_version());
> 
> Now this can be a single line.
> 
>   	printf("%s (libgpiod) v%s\n", getprogname(), gpiod_api_version());
> 

Thanks, will collapse.

On 2/25/23 10:36 AM, Bartosz Golaszewski wrote:
> This is only relevant for gpio-tools so maybe instead of relying on
> either a GNU or BSD extension, let's just ditch both (and the checking
> infrastructure) and introduce our own local helpers:
> 
> void set_prog_name(const char *name);
> const char *get_prog_name(void);
> const char *get_prog_shortname(void);
> 
> And call set_prog_name(argv[0]) at the start of each program?
> Alternatively we can just use prctl() like libgpiosim does for tests
> but then we'd lose the potential info about the executable path.
> 
> I'm thinking this is better than relying on extensions as I've already
> had to stop using twalk_r() due to it being a GNU extension not
> provided by musl (not by bionic as I can see).
> 
> Bart

Sure, that sounds like a better solution. Will make the change.

Ben
diff mbox series

Patch

diff --git a/configure.ac b/configure.ac
index 0a56074..7a77151 100644
--- a/configure.ac
+++ b/configure.ac
@@ -117,9 +117,14 @@  AM_CONDITIONAL([WITH_GPIOSET_INTERACTIVE],
 AS_IF([test "x$with_tools" = xtrue],
 	[# These are only needed to build tools
 	AC_CHECK_FUNC([daemon], [], [FUNC_NOT_FOUND_TOOLS([daemon])])
-	AC_CHECK_FUNC([asprintf], [], [FUNC_NOT_FOUND_LIB([asprintf])])
-	AC_CHECK_FUNC([scandir], [], [FUNC_NOT_FOUND_LIB([scandir])])
-	AC_CHECK_FUNC([alphasort], [], [FUNC_NOT_FOUND_LIB([alphasort])])
+	AC_CHECK_FUNC([asprintf], [], [FUNC_NOT_FOUND_TOOLS([asprintf])])
+	AC_CHECK_FUNC([scandir], [], [FUNC_NOT_FOUND_TOOLS([scandir])])
+	AC_CHECK_FUNC([alphasort], [], [FUNC_NOT_FOUND_TOOLS([alphasort])])
+	AC_CHECK_FUNC([getprogname],
+		[AC_DEFINE([HAVE_GETPROGNAME], 1, [Define to 1 if getprogname() is available.])],
+		[AC_CHECK_DECL([program_invocation_short_name], [],
+			[FUNC_NOT_FOUND_TOOLS([getprogname or program_invocation_short_name])],
+			[#include <errno.h>])])
 	AS_IF([test "x$with_gpioset_interactive" = xtrue],
 		[PKG_CHECK_MODULES([LIBEDIT], [libedit >= 3.1])])
 	])
diff --git a/tools/gpiodetect.c b/tools/gpiodetect.c
index f0211da..f5bdc01 100644
--- a/tools/gpiodetect.c
+++ b/tools/gpiodetect.c
@@ -12,7 +12,7 @@ 
 
 static void print_help(void)
 {
-	printf("Usage: %s [OPTIONS] [chip]...\n", get_progname());
+	printf("Usage: %s [OPTIONS] [chip]...\n", getprogname());
 	printf("\n");
 	printf("List GPIO chips, print their labels and number of GPIO lines.\n");
 	printf("\n");
@@ -51,7 +51,7 @@  static int parse_config(int argc, char **argv)
 			print_version();
 			exit(EXIT_SUCCESS);
 		case '?':
-			die("try %s --help", get_progname());
+			die("try %s --help", getprogname());
 		default:
 			abort();
 		}
diff --git a/tools/gpioget.c b/tools/gpioget.c
index 08c17e6..43abdf0 100644
--- a/tools/gpioget.c
+++ b/tools/gpioget.c
@@ -26,7 +26,7 @@  struct config {
 
 static void print_help(void)
 {
-	printf("Usage: %s [OPTIONS] <line>...\n", get_progname());
+	printf("Usage: %s [OPTIONS] <line>...\n", getprogname());
 	printf("\n");
 	printf("Read values of GPIO lines.\n");
 	printf("\n");
@@ -120,7 +120,7 @@  static int parse_config(int argc, char **argv, struct config *cfg)
 			print_version();
 			exit(EXIT_SUCCESS);
 		case '?':
-			die("try %s --help", get_progname());
+			die("try %s --help", getprogname());
 		case 0:
 			break;
 		default:
diff --git a/tools/gpioinfo.c b/tools/gpioinfo.c
index 1ec7f63..960f661 100644
--- a/tools/gpioinfo.c
+++ b/tools/gpioinfo.c
@@ -20,7 +20,7 @@  struct config {
 
 static void print_help(void)
 {
-	printf("Usage: %s [OPTIONS] [line]...\n", get_progname());
+	printf("Usage: %s [OPTIONS] [line]...\n", getprogname());
 	printf("\n");
 	printf("Print information about GPIO lines.\n");
 	printf("\n");
@@ -83,7 +83,7 @@  static int parse_config(int argc, char **argv, struct config *cfg)
 			print_version();
 			exit(EXIT_SUCCESS);
 		case '?':
-			die("try %s --help", get_progname());
+			die("try %s --help", getprogname());
 		case 0:
 			break;
 		default:
diff --git a/tools/gpiomon.c b/tools/gpiomon.c
index 93ff463..69ec2c1 100644
--- a/tools/gpiomon.c
+++ b/tools/gpiomon.c
@@ -34,7 +34,7 @@  struct config {
 
 static void print_help(void)
 {
-	printf("Usage: %s [OPTIONS] <line>...\n", get_progname());
+	printf("Usage: %s [OPTIONS] <line>...\n", getprogname());
 	printf("\n");
 	printf("Wait for events on GPIO lines and print them to standard output.\n");
 	printf("\n");
@@ -195,7 +195,7 @@  static int parse_config(int argc, char **argv, struct config *cfg)
 			print_version();
 			exit(EXIT_SUCCESS);
 		case '?':
-			die("try %s --help", get_progname());
+			die("try %s --help", getprogname());
 		case 0:
 			break;
 		default:
diff --git a/tools/gpionotify.c b/tools/gpionotify.c
index a0976f7..9242ae8 100644
--- a/tools/gpionotify.c
+++ b/tools/gpionotify.c
@@ -27,7 +27,7 @@  struct config {
 
 static void print_help(void)
 {
-	printf("Usage: %s [OPTIONS] <line>...\n", get_progname());
+	printf("Usage: %s [OPTIONS] <line>...\n", getprogname());
 	printf("\n");
 	printf("Wait for changes to info on GPIO lines and print them to standard output.\n");
 	printf("\n");
@@ -144,7 +144,7 @@  static int parse_config(int argc, char **argv, struct config *cfg)
 			print_version();
 			exit(EXIT_SUCCESS);
 		case '?':
-			die("try %s --help", get_progname());
+			die("try %s --help", getprogname());
 		case 0:
 			break;
 		default:
diff --git a/tools/gpioset.c b/tools/gpioset.c
index a7084a3..291f727 100644
--- a/tools/gpioset.c
+++ b/tools/gpioset.c
@@ -36,7 +36,7 @@  struct config {
 
 static void print_help(void)
 {
-	printf("Usage: %s [OPTIONS] <line=value>...\n", get_progname());
+	printf("Usage: %s [OPTIONS] <line=value>...\n", getprogname());
 	printf("\n");
 	printf("Set values of GPIO lines.\n");
 	printf("\n");
@@ -212,7 +212,7 @@  static int parse_config(int argc, char **argv, struct config *cfg)
 			print_version();
 			exit(EXIT_SUCCESS);
 		case '?':
-			die("try %s --help", get_progname());
+			die("try %s --help", getprogname());
 		case 0:
 			break;
 		default:
diff --git a/tools/tools-common.c b/tools/tools-common.c
index 0a54571..67530a9 100644
--- a/tools/tools-common.c
+++ b/tools/tools-common.c
@@ -20,17 +20,19 @@ 
 
 #include "tools-common.h"
 
-const char *get_progname(void)
+#ifndef HAVE_GETPROGNAME
+const char *getprogname(void)
 {
-	return program_invocation_name;
+	return program_invocation_short_name;
 }
+#endif
 
 void print_error(const char *fmt, ...)
 {
 	va_list va;
 
 	va_start(va, fmt);
-	fprintf(stderr, "%s: ", program_invocation_name);
+	fprintf(stderr, "%s: ", getprogname());
 	vfprintf(stderr, fmt, va);
 	fprintf(stderr, "\n");
 	va_end(va);
@@ -41,7 +43,7 @@  void print_perror(const char *fmt, ...)
 	va_list va;
 
 	va_start(va, fmt);
-	fprintf(stderr, "%s: ", program_invocation_name);
+	fprintf(stderr, "%s: ", getprogname());
 	vfprintf(stderr, fmt, va);
 	fprintf(stderr, ": %s\n", strerror(errno));
 	va_end(va);
@@ -52,7 +54,7 @@  void die(const char *fmt, ...)
 	va_list va;
 
 	va_start(va, fmt);
-	fprintf(stderr, "%s: ", program_invocation_name);
+	fprintf(stderr, "%s: ", getprogname());
 	vfprintf(stderr, fmt, va);
 	fprintf(stderr, "\n");
 	va_end(va);
@@ -65,7 +67,7 @@  void die_perror(const char *fmt, ...)
 	va_list va;
 
 	va_start(va, fmt);
-	fprintf(stderr, "%s: ", program_invocation_name);
+	fprintf(stderr, "%s: ", getprogname());
 	vfprintf(stderr, fmt, va);
 	fprintf(stderr, ": %s\n", strerror(errno));
 	va_end(va);
@@ -76,7 +78,7 @@  void die_perror(const char *fmt, ...)
 void print_version(void)
 {
 	printf("%s (libgpiod) v%s\n",
-	       program_invocation_short_name, gpiod_api_version());
+	       getprogname(), gpiod_api_version());
 	printf("Copyright (C) 2017-2023 Bartosz Golaszewski\n");
 	printf("License: GPL-2.0-or-later\n");
 	printf("This is free software: you are free to change and redistribute it.\n");
diff --git a/tools/tools-common.h b/tools/tools-common.h
index 434e5ba..3aebef0 100644
--- a/tools/tools-common.h
+++ b/tools/tools-common.h
@@ -78,7 +78,9 @@  struct line_resolver {
 	struct resolved_line lines[];
 };
 
-const char *get_progname(void);
+#ifndef HAVE_GETPROGNAME
+const char *getprogname(void);
+#endif
 void print_error(const char *fmt, ...) PRINTF(1, 2);
 void print_perror(const char *fmt, ...) PRINTF(1, 2);
 void die(const char *fmt, ...) NORETURN PRINTF(1, 2);