From 08805f093f5c6b11e631c6729726ec0da4eb1589 Mon Sep 17 00:00:00 2001 From: Erik Hansson Date: Thu, 15 May 2025 14:36:10 +0200 Subject: [PATCH] Replace `POSIXLY_CORRECT` for `getopt_long` * Removes the use of `POSIXLY_CORRECT` environment variable in favor of passing this directive in the optstring. This should solve issues for users of muslc (aka Alpine Linux). --- src/bin/pg_autoctl/cli_common.c | 31 +------------------------ src/bin/pg_autoctl/cli_create_node.c | 8 +++---- src/bin/pg_autoctl/cli_do_azure.c | 10 -------- src/bin/pg_autoctl/cli_do_demoapp.c | 10 -------- src/bin/pg_autoctl/cli_do_root.c | 10 -------- src/bin/pg_autoctl/cli_do_tmux.c | 10 -------- src/bin/pg_autoctl/cli_drop_node.c | 2 +- src/bin/pg_autoctl/cli_enable_disable.c | 18 ++++---------- src/bin/pg_autoctl/cli_formation.c | 4 ++-- src/bin/pg_autoctl/cli_perform.c | 12 +--------- src/bin/pg_autoctl/cli_root.c | 2 +- src/bin/pg_autoctl/cli_service.c | 2 +- src/bin/pg_autoctl/cli_show.c | 8 +++---- src/bin/pg_autoctl/cli_systemd.c | 2 +- src/bin/pg_autoctl/cli_watch.c | 2 +- src/bin/pg_autoctl/main.c | 14 ----------- 16 files changed, 21 insertions(+), 124 deletions(-) diff --git a/src/bin/pg_autoctl/cli_common.c b/src/bin/pg_autoctl/cli_common.c index a08b8509b..20cd93dc1 100644 --- a/src/bin/pg_autoctl/cli_common.c +++ b/src/bin/pg_autoctl/cli_common.c @@ -1075,16 +1075,6 @@ cli_getopt_pgdata(int argc, char **argv) }; optind = 0; - /* - * The only command lines that are using keeper_cli_getopt_pgdata are - * terminal ones: they don't accept subcommands. In that case our option - * parsing can happen in any order and we don't need getopt_long to behave - * in a POSIXLY_CORRECT way. - * - * The unsetenv() call allows getopt_long() to reorder arguments for us. - */ - unsetenv("POSIXLY_CORRECT"); - while ((c = getopt_long(argc, argv, "D:JVvqh", long_options, &option_index)) != -1) { @@ -1450,16 +1440,6 @@ cli_print_version_getopts(int argc, char **argv) }; optind = 0; - /* - * The only command lines that are using keeper_cli_getopt_pgdata are - * terminal ones: they don't accept subcommands. In that case our option - * parsing can happen in any order and we don't need getopt_long to behave - * in a POSIXLY_CORRECT way. - * - * The unsetenv() call allows getopt_long() to reorder arguments for us. - */ - unsetenv("POSIXLY_CORRECT"); - while ((c = getopt_long(argc, argv, "JVvqh", long_options, &option_index)) != -1) { @@ -1802,7 +1782,7 @@ cli_node_metadata_getopts(int argc, char **argv) optind = 0; - while ((c = getopt_long(argc, argv, "D:n:H:p:JVvqh", + while ((c = getopt_long(argc, argv, "+D:n:H:p:JVvqh", long_options, &option_index)) != -1) { switch (c) @@ -1962,15 +1942,6 @@ cli_get_name_getopts(int argc, char **argv) optind = 0; - /* - * The only command lines that are using keeper_cli_getopt_pgdata are - * terminal ones: they don't accept subcommands. In that case our option - * parsing can happen in any order and we don't need getopt_long to behave - * in a POSIXLY_CORRECT way. - * - * The unsetenv() call allows getopt_long() to reorder arguments for us. - */ - unsetenv("POSIXLY_CORRECT"); while ((c = getopt_long(argc, argv, "D:f:g:n:Vvqh", long_options, &option_index)) != -1) diff --git a/src/bin/pg_autoctl/cli_create_node.c b/src/bin/pg_autoctl/cli_create_node.c index 8ef2e8643..c698e1dc6 100644 --- a/src/bin/pg_autoctl/cli_create_node.c +++ b/src/bin/pg_autoctl/cli_create_node.c @@ -354,7 +354,7 @@ cli_create_postgres_getopts(int argc, char **argv) int optind = cli_create_node_getopts(argc, argv, long_options, - "C:D:H:p:l:U:A:SLd:a:n:f:m:MI:RVvqhP:r:xsN", + "+C:D:H:p:l:U:A:SLd:a:n:f:m:MI:RVvqhP:r:xsN", &options); /* publish our option parsing in the global variable */ @@ -452,7 +452,7 @@ cli_create_coordinator_getopts(int argc, char **argv) int optind = cli_create_node_getopts(argc, argv, long_options, - "C:D:H:p:l:U:A:SLd:a:n:f:m:MRVvqhzZ:P:r:xsN", + "+C:D:H:p:l:U:A:SLd:a:n:f:m:MRVvqhzZ:P:r:xsN", &options); options.groupId = 0; @@ -562,7 +562,7 @@ cli_create_worker_getopts(int argc, char **argv) int optind = cli_create_node_getopts(argc, argv, long_options, - "C:D:H:p:l:y:zZ:U:A:SLd:a:n:f:m:MRVvqhzP:r:xsN", + "+C:D:H:p:l:y:zZ:U:A:SLd:a:n:f:m:MRVvqhzP:r:xsN", &options); if (options.groupId == 0) @@ -821,7 +821,7 @@ cli_create_monitor_getopts(int argc, char **argv) optind = 0; - while ((c = getopt_long(argc, argv, "C:D:p:n:l:A:SVvqhxNs", + while ((c = getopt_long(argc, argv, "+C:D:p:n:l:A:SVvqhxNs", long_options, &option_index)) != -1) { switch (c) diff --git a/src/bin/pg_autoctl/cli_do_azure.c b/src/bin/pg_autoctl/cli_do_azure.c index 6a218849f..e5858e93d 100644 --- a/src/bin/pg_autoctl/cli_do_azure.c +++ b/src/bin/pg_autoctl/cli_do_azure.c @@ -91,16 +91,6 @@ cli_do_azure_getopts(int argc, char **argv) strlcpy(options.prefix, "ha-demo", sizeof(options.prefix)); - /* - * The only command lines that are using keeper_cli_getopt_pgdata are - * terminal ones: they don't accept subcommands. In that case our option - * parsing can happen in any order and we don't need getopt_long to behave - * in a POSIXLY_CORRECT way. - * - * The unsetenv() call allows getopt_long() to reorder arguments for us. - */ - unsetenv("POSIXLY_CORRECT"); - while ((c = getopt_long(argc, argv, "p:n:l:N:MAWSTVvqh", long_options, &option_index)) != -1) { diff --git a/src/bin/pg_autoctl/cli_do_demoapp.c b/src/bin/pg_autoctl/cli_do_demoapp.c index 971175233..fd87b31c6 100644 --- a/src/bin/pg_autoctl/cli_do_demoapp.c +++ b/src/bin/pg_autoctl/cli_do_demoapp.c @@ -222,16 +222,6 @@ cli_do_demoapp_getopts(int argc, char **argv) } } - /* - * The only command lines that are using cli_do_demoapp_getopts are - * terminal ones: they don't accept subcommands. In that case our option - * parsing can happen in any order and we don't need getopt_long to behave - * in a POSIXLY_CORRECT way. - * - * The unsetenv() call allows getopt_long() to reorder arguments for us. - */ - unsetenv("POSIXLY_CORRECT"); - while ((c = getopt_long(argc, argv, "D:p:Vvqh", long_options, &option_index)) != -1) { diff --git a/src/bin/pg_autoctl/cli_do_root.c b/src/bin/pg_autoctl/cli_do_root.c index dacf9792e..5b8215015 100644 --- a/src/bin/pg_autoctl/cli_do_root.c +++ b/src/bin/pg_autoctl/cli_do_root.c @@ -630,16 +630,6 @@ keeper_cli_keeper_setup_getopts(int argc, char **argv) { NULL, 0, NULL, 0 } }; - /* - * The only command lines that are using keeper_cli_getopt_pgdata are - * terminal ones: they don't accept subcommands. In that case our option - * parsing can happen in any order and we don't need getopt_long to behave - * in a POSIXLY_CORRECT way. - * - * The unsetenv() call allows getopt_long() to reorder arguments for us. - */ - unsetenv("POSIXLY_CORRECT"); - int optind = cli_common_keeper_getopts(argc, argv, long_options, "C:D:H:p:l:U:A:SLd:n:f:m:MRVvqhP:r:xsN", diff --git a/src/bin/pg_autoctl/cli_do_tmux.c b/src/bin/pg_autoctl/cli_do_tmux.c index a871ddc57..f9f847c48 100644 --- a/src/bin/pg_autoctl/cli_do_tmux.c +++ b/src/bin/pg_autoctl/cli_do_tmux.c @@ -489,16 +489,6 @@ cli_do_tmux_script_getopts(int argc, char **argv) exit(EXIT_CODE_INTERNAL_ERROR); } - /* - * The only command lines that are using keeper_cli_getopt_pgdata are - * terminal ones: they don't accept subcommands. In that case our option - * parsing can happen in any order and we don't need getopt_long to behave - * in a POSIXLY_CORRECT way. - * - * The unsetenv() call allows getopt_long() to reorder arguments for us. - */ - unsetenv("POSIXLY_CORRECT"); - while ((c = getopt_long(argc, argv, "D:p:Vvqh", long_options, &option_index)) != -1) { diff --git a/src/bin/pg_autoctl/cli_drop_node.c b/src/bin/pg_autoctl/cli_drop_node.c index 3ecefffc6..20238cabe 100644 --- a/src/bin/pg_autoctl/cli_drop_node.c +++ b/src/bin/pg_autoctl/cli_drop_node.c @@ -120,7 +120,7 @@ cli_drop_node_getopts(int argc, char **argv) options.listen_notifications_timeout = PG_AUTOCTL_LISTEN_NOTIFICATIONS_TIMEOUT; - while ((c = getopt_long(argc, argv, "D:dn:p:Vvqh", + while ((c = getopt_long(argc, argv, "+D:dn:p:Vvqh", long_options, &option_index)) != -1) { switch (c) diff --git a/src/bin/pg_autoctl/cli_enable_disable.c b/src/bin/pg_autoctl/cli_enable_disable.c index 5dbb56590..0540bb3ed 100644 --- a/src/bin/pg_autoctl/cli_enable_disable.c +++ b/src/bin/pg_autoctl/cli_enable_disable.c @@ -172,7 +172,7 @@ cli_secondary_getopts(int argc, char **argv) optind = 0; - while ((c = getopt_long(argc, argv, "D:f:Vvqh", + while ((c = getopt_long(argc, argv, "+D:f:Vvqh", long_options, &option_index)) != -1) { switch (c) @@ -359,7 +359,7 @@ cli_maintenance_getopts(int argc, char **argv) optind = 0; - while ((c = getopt_long(argc, argv, "D:f:AVvqh", + while ((c = getopt_long(argc, argv, "+D:f:AVvqh", long_options, &option_index)) != -1) { switch (c) @@ -703,7 +703,7 @@ cli_ssl_getopts(int argc, char **argv) optind = 0; - while ((c = getopt_long(argc, argv, "D:VvqhNs", + while ((c = getopt_long(argc, argv, "+D:VvqhNs", long_options, &option_index)) != -1) { switch (c) @@ -1283,16 +1283,6 @@ cli_enable_monitor_getopts(int argc, char **argv) optind = 0; - /* - * The only command lines that are using keeper_cli_getopt_pgdata are - * terminal ones: they don't accept subcommands. In that case our option - * parsing can happen in any order and we don't need getopt_long to behave - * in a POSIXLY_CORRECT way. - * - * The unsetenv() call allows getopt_long() to reorder arguments for us. - */ - unsetenv("POSIXLY_CORRECT"); - while ((c = getopt_long(argc, argv, "D:m:AVvqh", long_options, &option_index)) != -1) { @@ -1530,7 +1520,7 @@ cli_disable_monitor_getopts(int argc, char **argv) optind = 0; - while ((c = getopt_long(argc, argv, "D:FVvqh", + while ((c = getopt_long(argc, argv, "+D:FVvqh", long_options, &option_index)) != -1) { switch (c) diff --git a/src/bin/pg_autoctl/cli_formation.c b/src/bin/pg_autoctl/cli_formation.c index 09d546dd1..4300595ee 100644 --- a/src/bin/pg_autoctl/cli_formation.c +++ b/src/bin/pg_autoctl/cli_formation.c @@ -131,7 +131,7 @@ keeper_cli_formation_getopts(int argc, char **argv) optind = 0; - while ((c = getopt_long(argc, argv, "D:f:Vvqh", + while ((c = getopt_long(argc, argv, "+D:f:Vvqh", long_options, &option_index)) != -1) { switch (c) @@ -282,7 +282,7 @@ keeper_cli_formation_create_getopts(int argc, char **argv) /* set defaults for formations */ options.formationHasSecondary = true; - while ((c = getopt_long(argc, argv, "D:f:k:sSVvqhn:", + while ((c = getopt_long(argc, argv, "+D:f:k:sSVvqhn:", long_options, &option_index)) != -1) { switch (c) diff --git a/src/bin/pg_autoctl/cli_perform.c b/src/bin/pg_autoctl/cli_perform.c index f3fd6415e..d2589c67b 100644 --- a/src/bin/pg_autoctl/cli_perform.c +++ b/src/bin/pg_autoctl/cli_perform.c @@ -108,7 +108,7 @@ cli_perform_failover_getopts(int argc, char **argv) optind = 0; - while ((c = getopt_long(argc, argv, "D:f:g:n:Vvqh", + while ((c = getopt_long(argc, argv, "+D:f:g:n:Vvqh", long_options, &option_index)) != -1) { switch (c) @@ -343,16 +343,6 @@ cli_perform_promotion_getopts(int argc, char **argv) optind = 0; - /* - * The only command lines that are using keeper_cli_getopt_pgdata are - * terminal ones: they don't accept subcommands. In that case our option - * parsing can happen in any order and we don't need getopt_long to behave - * in a POSIXLY_CORRECT way. - * - * The unsetenv() call allows getopt_long() to reorder arguments for us. - */ - unsetenv("POSIXLY_CORRECT"); - while ((c = getopt_long(argc, argv, "D:f:g:n:Vvqh", long_options, &option_index)) != -1) { diff --git a/src/bin/pg_autoctl/cli_root.c b/src/bin/pg_autoctl/cli_root.c index 386716b98..073d00e59 100644 --- a/src/bin/pg_autoctl/cli_root.c +++ b/src/bin/pg_autoctl/cli_root.c @@ -162,7 +162,7 @@ root_options(int argc, char **argv) optind = 0; - while ((c = getopt_long(argc, argv, "JVvqh", + while ((c = getopt_long(argc, argv, "+JVvqh", long_options, &option_index)) != -1) { switch (c) diff --git a/src/bin/pg_autoctl/cli_service.c b/src/bin/pg_autoctl/cli_service.c index 33a95ce8f..b330055c3 100644 --- a/src/bin/pg_autoctl/cli_service.c +++ b/src/bin/pg_autoctl/cli_service.c @@ -296,7 +296,7 @@ cli_getopt_pgdata_and_mode(int argc, char **argv) optind = 0; - while ((c = getopt_long(argc, argv, "D:fiVvqh", + while ((c = getopt_long(argc, argv, "+D:fiVvqh", long_options, &option_index)) != -1) { switch (c) diff --git a/src/bin/pg_autoctl/cli_show.c b/src/bin/pg_autoctl/cli_show.c index 8bfdf2a35..954650f08 100644 --- a/src/bin/pg_autoctl/cli_show.c +++ b/src/bin/pg_autoctl/cli_show.c @@ -204,7 +204,7 @@ cli_show_state_getopts(int argc, char **argv) optind = 0; - while ((c = getopt_long(argc, argv, "D:f:g:n:Vvqh", + while ((c = getopt_long(argc, argv, "+D:f:g:n:Vvqh", long_options, &option_index)) != -1) { switch (c) @@ -711,7 +711,7 @@ cli_show_standby_names_getopts(int argc, char **argv) optind = 0; - while ((c = getopt_long(argc, argv, "D:f:g:n:Vvqh", + while ((c = getopt_long(argc, argv, "+D:f:g:n:Vvqh", long_options, &option_index)) != -1) { switch (c) @@ -942,7 +942,7 @@ cli_show_uri_getopts(int argc, char **argv) optind = 0; - while ((c = getopt_long(argc, argv, "D:Vvqh", + while ((c = getopt_long(argc, argv, "+D:Vvqh", long_options, &option_index)) != -1) { switch (c) @@ -1362,7 +1362,7 @@ cli_show_file_getopts(int argc, char **argv) optind = 0; - while ((c = getopt_long(argc, argv, "D:acsipCVvqh", + while ((c = getopt_long(argc, argv, "+D:acsipCVvqh", long_options, &option_index)) != -1) { switch (c) diff --git a/src/bin/pg_autoctl/cli_systemd.c b/src/bin/pg_autoctl/cli_systemd.c index 4ebdb83b2..b42d6f7d2 100644 --- a/src/bin/pg_autoctl/cli_systemd.c +++ b/src/bin/pg_autoctl/cli_systemd.c @@ -62,7 +62,7 @@ cli_systemd_getopt(int argc, char **argv) optind = 0; - while ((c = getopt_long(argc, argv, "D:Vvqh", + while ((c = getopt_long(argc, argv, "+D:Vvqh", long_options, &option_index)) != -1) { switch (c) diff --git a/src/bin/pg_autoctl/cli_watch.c b/src/bin/pg_autoctl/cli_watch.c index 607c0a64e..3dd3d6e01 100644 --- a/src/bin/pg_autoctl/cli_watch.c +++ b/src/bin/pg_autoctl/cli_watch.c @@ -84,7 +84,7 @@ cli_watch_getopts(int argc, char **argv) optind = 0; - while ((c = getopt_long(argc, argv, "D:f:g:n:Vvqh", + while ((c = getopt_long(argc, argv, "+D:f:g:n:Vvqh", long_options, &option_index)) != -1) { switch (c) diff --git a/src/bin/pg_autoctl/main.c b/src/bin/pg_autoctl/main.c index a49dae7ed..c1a4583d8 100644 --- a/src/bin/pg_autoctl/main.c +++ b/src/bin/pg_autoctl/main.c @@ -97,20 +97,6 @@ main(int argc, char **argv) } } - /* - * We need to follow POSIX specifications for argument parsing, in - * particular we want getopt() to stop as soon as it reaches a non option - * in the command line. - * - * GNU and modern getopt() implementation will reorder the command - * arguments, making a mess of our nice subcommands facility. - * - * Note that we call unsetenv("POSIXLY_CORRECT"); before parsing options - * for commands that are the final sub-command of their chain and when we - * might mix options and arguments. - */ - setenv("POSIXLY_CORRECT", "1", 1); - /* * Stash away the argv[0] used to run this program and compute the realpath * of the program invoked, which we need at several places including when