tools: remove dependency on glibc program_invocation_[short_]name
authorBenjamin Li <benl@squareup.com>
Mon, 6 Mar 2023 18:45:44 +0000 (10:45 -0800)
committerBartosz Golaszewski <bartosz.golaszewski@linaro.org>
Sun, 12 Mar 2023 13:23:34 +0000 (14:23 +0100)
Platforms like Bionic libc don't have program_invocation_[short_]name,
which is a GNU extension. It does have getprogname(), a BSD extension,
but rather than supporting multiple extensions let's just introduce
our own local helpers.

We derive the short name ourselves rather than calling basename(),
as the POSIX version takes char *, not const char *, and is thus
not guaranteed to avoid modifying its input. (The GNU version does
take const char * but we are avoiding extensions here.)

Signed-off-by: Benjamin Li <benl@squareup.com>
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
tools/gpiodetect.c
tools/gpioget.c
tools/gpioinfo.c
tools/gpiomon.c
tools/gpionotify.c
tools/gpioset.c
tools/tools-common.c
tools/tools-common.h

index f0211dab2f7b25dbec8a0707cf866ed376813d60..0a3461ba4a977a44c605ea051c0c61826910e186 100644 (file)
@@ -12,7 +12,7 @@
 
 static void print_help(void)
 {
-       printf("Usage: %s [OPTIONS] [chip]...\n", get_progname());
+       printf("Usage: %s [OPTIONS] [chip]...\n", get_prog_name());
        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", get_prog_name());
                default:
                        abort();
                }
@@ -89,6 +89,7 @@ int main(int argc, char **argv)
        int num_chips, i, ret = EXIT_SUCCESS;
        char **paths, *path;
 
+       set_prog_name(argv[0]);
        i = parse_config(argc, argv);
        argc -= i;
        argv += i;
index 08c17e67d13c13e5067eabcd6db79b01ea71e945..f6117378dc7bac5f4ba5ced066a60c61153acfb2 100644 (file)
@@ -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", get_prog_name());
        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", get_prog_name());
                case 0:
                        break;
                default:
@@ -146,6 +146,7 @@ int main(int argc, char **argv)
        struct config cfg;
        const char *fmt;
 
+       set_prog_name(argv[0]);
        i = parse_config(argc, argv, &cfg);
        argc -= i;
        argv += i;
index 1ec7f63f00e4b078cb7136f4ea3bd49b6b76b96f..44d1c8c77f8fde5c995237a22205ad05339aeea5 100644 (file)
@@ -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", get_prog_name());
        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", get_prog_name());
                case 0:
                        break;
                default:
@@ -228,6 +228,7 @@ int main(int argc, char **argv)
        struct config cfg;
        char **paths;
 
+       set_prog_name(argv[0]);
        i = parse_config(argc, argv, &cfg);
        argc -= i;
        argv += i;
index 93ff4639a4ae3e66a65c138d69fdaff51cfa0db8..ec177dfdbf21005d986eb6fc23b2edc5172235f7 100644 (file)
@@ -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", get_prog_name());
        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", get_prog_name());
                case 0:
                        break;
                default:
@@ -360,6 +360,7 @@ int main(int argc, char **argv)
        struct config cfg;
        int ret, i, j;
 
+       set_prog_name(argv[0]);
        i = parse_config(argc, argv, &cfg);
        argc -= i;
        argv += i;
index a0976f7224246e11e21bb80ae731369a904fa577..990ca04519b5d1182f1fd8fbe2784b907a737402 100644 (file)
@@ -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", get_prog_name());
        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", get_prog_name());
                case 0:
                        break;
                default:
@@ -370,6 +370,7 @@ int main(int argc, char **argv)
        struct pollfd *pollfds;
        struct config cfg;
 
+       set_prog_name(argv[0]);
        i = parse_config(argc, argv, &cfg);
        argc -= optind;
        argv += optind;
index a7084a3e2f4196209b0ed4dab8b77f23cc5769e7..9dc5aeb8b28661ed87efccaf00ba600ad01a51aa 100644 (file)
@@ -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", get_prog_name());
        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", get_prog_name());
                case 0:
                        break;
                default:
@@ -876,6 +876,7 @@ int main(int argc, char **argv)
        struct config cfg;
        char **lines;
 
+       set_prog_name(argv[0]);
        i = parse_config(argc, argv, &cfg);
        argc -= i;
        argv += i;
index a0080fcdae1f727000d635a9291d75f5caed04ec..e5f6fc1b221cbaa12a0cb554b3fcc8661bbf903a 100644 (file)
 
 #include "tools-common.h"
 
-const char *get_progname(void)
+static const char *prog_name = NULL;
+static const char *prog_short_name = NULL;
+
+void set_prog_name(const char *name)
+{
+       prog_name = name;
+       prog_short_name = name;
+       while (*name) {
+               if (*name++ == '/') {
+                       prog_short_name = name;
+               }
+       }
+}
+
+const char *get_prog_name(void)
+{
+       return prog_name;
+}
+
+const char *get_prog_short_name(void)
 {
-       return program_invocation_name;
+       return prog_short_name;
 }
 
 void print_error(const char *fmt, ...)
@@ -29,7 +48,7 @@ void print_error(const char *fmt, ...)
        va_list va;
 
        va_start(va, fmt);
-       fprintf(stderr, "%s: ", program_invocation_name);
+       fprintf(stderr, "%s: ", get_prog_name());
        vfprintf(stderr, fmt, va);
        fprintf(stderr, "\n");
        va_end(va);
@@ -40,7 +59,7 @@ void print_perror(const char *fmt, ...)
        va_list va;
 
        va_start(va, fmt);
-       fprintf(stderr, "%s: ", program_invocation_name);
+       fprintf(stderr, "%s: ", get_prog_name());
        vfprintf(stderr, fmt, va);
        fprintf(stderr, ": %s\n", strerror(errno));
        va_end(va);
@@ -51,7 +70,7 @@ void die(const char *fmt, ...)
        va_list va;
 
        va_start(va, fmt);
-       fprintf(stderr, "%s: ", program_invocation_name);
+       fprintf(stderr, "%s: ", get_prog_name());
        vfprintf(stderr, fmt, va);
        fprintf(stderr, "\n");
        va_end(va);
@@ -64,7 +83,7 @@ void die_perror(const char *fmt, ...)
        va_list va;
 
        va_start(va, fmt);
-       fprintf(stderr, "%s: ", program_invocation_name);
+       fprintf(stderr, "%s: ", get_prog_name());
        vfprintf(stderr, fmt, va);
        fprintf(stderr, ": %s\n", strerror(errno));
        va_end(va);
@@ -74,8 +93,7 @@ void die_perror(const char *fmt, ...)
 
 void print_version(void)
 {
-       printf("%s (libgpiod) v%s\n",
-              program_invocation_short_name, gpiod_api_version());
+       printf("%s (libgpiod) v%s\n", get_prog_short_name(), 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");
index 434e5ba5d271373eb76753758756b4ab36ea2255..c82317afe3357f029a262782016e447912d772ea 100644 (file)
@@ -78,7 +78,9 @@ struct line_resolver {
        struct resolved_line lines[];
 };
 
-const char *get_progname(void);
+void set_prog_name(const char *name);
+const char *get_prog_name(void);
+const char *get_prog_short_name(void);
 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);